• Nenhum resultado encontrado

MIPS RISc architeture

No documento Processador MIPS (páginas 33-53)

KANE, Gerry.; HEINRICH, Joe.. MIPS RISc architecture. Upper Saddle River (NJ):

Prentice Hall PTR, c1992.. x-25 p. ISBN 0135904722.

Códigos

controlunit.vhd

entity controlUnit is port (

--- SINAIS

--- O relógio do processador.

clock : in bit;

-- Reseta a unidade de controle.

reset : in bit;

-- Flag da ULA que indica overflow da ULA !!

Overflow : in bit;

-- Flag Da Ula

Negativo : in bit;

-- Sinaliza quando S for zero

z : in bit;

-- Sinaliza se A=B

Igual : in bit;

-- Sinaliza se A>B

Maior : in bit;

-- Sinaliza se A<B

Menor : in bit;

-- Indica a operação a ser realizada pelo banco de registradores leitura (0) escrita (1).

reset_Bank : out bit;

RegWrite : out bit;

-- Indica o tipo do deslocamento

ShiftN : out bit_vector(1 downto 0);

-- Controla a caixa MULTDIV

MultDivStart : out bit; -- inicia a operacao

MultDiv : out bit; -- seleciona a mult ou div

DivByZero : in bit; -- indica se exceção divByZero occoreu MultDivFinished : in bit;

--- REGISTRADORES

--- Controla o registrador que guarda a primeira saída do banco de registradores.

LoadA : out bit;

ResetA : out bit;

-- Controla o registrador que guarda a segunda saída do banco de registradores.

LoadB : out bit;

ResetB : out bit;

-- Controla o registrador que guarda o resultado da ALU.

LoadALUOut : out bit;

ResetALUOut : out bit;

-- Registradores HI e LO

LoadHiLo : out bit;

ResetHiLo : out bit;

-- Saídas que controlam registrador que guarda PC (Program Counter).

PCWriteCond : out bit;

PCWrite : out bit;

PCReset : out bit;

-- Controla o Memory Data Register com Load, Reset e a operação a ser realizada(MdrType)

MdrLoad : out bit;

MdrReset : out bit;

MdrType : out bit_vector(1 downto 0); -- seta a operação(byte, half, word) do MDR de acordo com o valor passado

-- Registrador EPC que guarda onde houve erro (exceção) EPCLoad : out bit;

EPCReset : out bit;

--- MULTIPLEXADORES

-- Controlam os Multiplexadores das entradas de ALU.

ALUSrcA : out bit;

ALUSrcB : out bit_vector(1 downto 0);

-- Seleciona a operação que a ALU irá realizar.

ALUOp : out bit_vector(2 downto 0);

-- Controla o valor a ser carregado no PC.

PCSource : out bit_vector(2 downto 0);

-- Controla o mux que selecionará os dados a serem escritos no banco de registradores.

MemToReg : out bit_vector(2 downto 0);

-- Controla o mux que seleciona o endereço de memória a ser lido ou escrito.

IorD : out bit_vector(1 downto 0);

-- Seleciona o registrador a ser gravado no banco de registradores RegDst : out bit_vector(1 downto 0);

-- Seleciona o Mux que possui o valor da ULA e do Shift N

MuxOp : out bit;

-- -- Seleciona o Mux que possui constantes usadas no SLT, SLTI e Exceções.

EXCode : out bit_vector(1 downto 0)

);

end controlUnit;

architecture arqControlUnit of controlUnit is

type state is (resetCPU, -- Reseta a unidade de controle

Fetch, -- Carrega o novo valor de PC no seu registrador

ReadMemory1, -- Soma PC + 4

ReadMemory2,-- Espera que a memória seja lida LoadInstruction, -- Aguarda o valor lido na memória ser liberado no instruction register

LoadInstructionRegister, writeRegister, writememory,

-- decoder, -- Decodifica a instrução que será executada

DivByZeroHandler, WaitMultDiv, mult,

div,

shiftRightA, shiftRightL, shiftLeftL, -- Instruções de deslocamento

beq, bne1, bne2, bne3, -- Instruçoes de pulo condicional

slt, slti,

j, jr, jal, -- Pulo não condicional

LoadPC, --estado para escrever pc apos os jumps.

rte, -- Retorno de exceção loadPCEX,

writeReg31, --estado para carregar o pc no reg 31.

writeEPC0, writeEPC,

break -- Pára execução do programa

-- Nop -- Sem operacao

);

signal currentState : state;

signal SP : bit_vector(31 downto 0); -- Stack

point, posição do topo da pilha

signal next_of_next : state; -- State gambieirror pra fazer droga nenhuma e comer tempo !!

begin

process (clock, reset) begin

if (reset = '1') then

currentState <= resetCPU;

elsif (clock'event and clock = '1') then case currentState is

--- Idle state

when idleState =>

--IorD <= 0;

--MemWrite <= 0;

currentState <= next_of_next;

---when resetCPU =>

SP <= "00000000000000000000000011100011";

controlWrite <= "00";

IRWrite <= '0';

MemoryIO <= '0';

RegDst <= "00";

RegWrite <= '0';

MultDivStart <= '0';

MultDiv <= '0';

ResetA <= '1';

ResetB <= '1';

ResetHiLo <= '1';

reset_Bank <= '1';

ALUSrcA <= '0';

ALUSrcB <= "00";

MdrReset <= '1';

EPCLoad <= '0';

EPCReset <= '1';

ALUOp <= "000";

PCSource <= "000";

PCWrite <= '0';

PCWriteCond <= '0';

PCReset <= '1';

ShiftN <= "00";

MemToReg <= "000";

IorD <= "00";

MuxOp <= '0';

loadHiLo <= '0';

mdrLoad <= '0';

MdrType <= "00";

currentState <= Fetch;

--- Carrega PC e ativa leitura na memória

when Fetch =>

ResetA <= '0';

ResetB <= '0';

ResetALuOut <= '0';

ResetHilo <= '0';

PCReset <= '0';

MdrReset <= '0';

EPCReset <= '0';

reset_Bank <= '0';

mdrLoad <= '0';

LoadAluOut <= '0'; -- mantém valor no aluOut PCWrite <= '0'; -- mantém o valor de PC PcWriteCond <= '0'; -- mantém o valor de PC MemoryIO <= '0'; -- lê da memória IOrd <= "00"; -- MUX do PC e ALUout regWrite <= '0'; -- pra garantir que o

ALUSrcB <= "01"; -- seleciona 4 para somar com PC

PCSource <= "000"; -- deixa passar pelo multiplexador o valor da soma

PCWrite <= '0'; -- mantém o registrador que contém PC com o seu valor atual.00

currentState <= ReadMemory2;

--- Segundo estado de leitura da memória, teoricamente ao término desse o valor lido estará disponível

---- Grava novo valor no PC (PC + 4) when ReadMemory2 =>

IRWrite <= '1'; -- habilita carregamento de valor no IR

PCWrite <= '1';

--mdrLoad <= '1';

--mdrType <= "00";

currentState <= LoadInstructionRegister;

--- Aguarda o Intruction Register decompor o valor lido na memória e no próximo clock libera os resultados

when LoadInstructionRegister =>

PCWrite <= '0'; -- hold IRWrite <= '0'; -- hold

--mdrLoad <= '1';

currentState <= LoadInstruction;

--- Envia o valor lido da memória, já decomposto e carrega os valores do Registrador A e B

when LoadInstruction =>

-- Soma o valor do registradores para aumentar a perfomance de algumas intruções

loadA <= '1';

loadB <= '1';

ALUSrcA <= '1'; -- seleciona o

valor do registrador A

ALUSrcB <= "00"; -- seleciona o valor do registrador B

MuxOP <= '0'; -- seleciona o resultado ULA para ALUOut

ALUOP <= "001"; -- seleciona a SOMA na alu

currentState <= decoder;

--- Decodifica a instrução no Instruction Register a ser executada - Início do Big Ultra Monster CASE plus plus ++

---when decoder =>

IRWrite <= '0';

-- Carrega em aluOUt o resultado da soma realizada no ciclo anterior

-- LoadAluOut <= '0';

loadA <= '0';

loadB <= '0';

-- Decodifica a instrução

case instruction(31 downto 26) is -- checa o OP CODE when "000000" =>

case instruction(5 downto 0) is -- function when "000000" =>

if(instruction =

"00000000000000000000000000000000") then -- no operation

currentState <= Fetch;

else

shiftN <= "10";

muxOP <= '1';

memToReg <= "000";

RegDst <= "01";

--MultDiv <=

'1';

currentState <= loadALURe-sult;

end if;

---

--- mfhi

---

---when "010000" =>

MemToReg <=

"010";

RegDst <=

"01";

currentState <= WriteReg-ister;

---

--- mflo

---

---when "010010" =>

MemToReg <=

if(Overflow = '1') then

--PCSource <=

"101";-- seleciona posicao da memoria pra tratar o overflow

currentState <= Over-flowHandle;

else

LoadALUOut <=

'1';

MemtoReg <=

"000"; --seleciona valor a ser gravado

RegDst <=

"01"; -- registrador destino

currentState <= WriteReg-ister;

end if;

--- sub

---when "100010" =>

-- seleciona a subtração na ALU.

ALUOP <= "010";

MuxOp <= '0'; -- deixa passar o valor da ALU currentState <= OverflowHandle;

--- addu

---when "100001" =>

LoadALUOut <= '1';

MemtoReg <= "000";

RegDst <= "01";

MuxOp <= '0'; -- deixa passar o valor da ALU currentState <= writeRegister;

--- subu

---when "100011" =>

-- seleciona a subtração na ALU.

ALUOP <= "010";

MemtoReg <= "000"; --seleciona valor a ser gravado RegDst <= "01"; -- registrador destino

currentState <= loadALUResult;

--- and

---when "100100" =>

-- seleciona a operação de and na ULA ALUOP <= "011";

MemtoReg <= "000"; --seleciona valor a ser gravado RegDst <= "01"; -- registrador destino

currentState <= loadALUResult;

--- xor

---ALUOP <= "110";

MemtoReg <= "000"; --seleciona valor a ser gravado RegDst <= "01"; -- registrador destino

currentState <= loadALUResult;

--- Mult

---when "011000" =>

LoadA <= '0';

LoadB <= '0';

AlUSrcA <= '1'; -- seleciona o registrador A AlUSrcB <= "00"; --seleciona o registrador B currentState <= mult;

--- Div

---when "011010" =>

LoadA <= '0';

LoadB <= '0';

AlUSrcA <= '1'; -- seleciona o registrador A AlUSrcB <= "00"; --seleciona o registrador B currentState <= div;

--- Sra

---when "000011" =>

MemToReg <= "000";

shiftN <= "01";

RegDst <= "01";

MuxOp <= '1';

currentState <= loadALUResult;

--- Srl

---when "000010" =>

MemToReg <= "000";

RegDst <= "01";

shiftN <= "00";

MuxOp <= '1';

currentState <= loadALUResult;

---ALUOP <= "000"; --Seleciona carregar na saida da ula O reg. A.

MuxOP <= '0'; --seleciona muxOP para passar a saida da ULA.

currentState <= jr;

--- break

---when "001101" =>

currentState <= break;

when others =>

currentState <= resetCPU;-- ou LANÇAR EXCEÇÃO ??

end case; -- op CODE 000000

--- Load Word

---when "100011" =>

AluSrcA <= '1'; --seleciona a passagem do

Reg. a no mux ALUSrcA.

AluSrcB <= "10"; --seleciona a passagem do mdr no mux ALUSrcB.

ALUOP <= "001"; --seleciona a ula para somar.

next_of_next <= loadword; --estado padrao para os loads.

currentState <= load;

--- Load Byte

---when "100000" =>

ALUSrcA <= '1';

--seleciona a passagem do Reg. a no mux ALUSrcA.

ALUSrcB <= "10";

--seleciona a passagem do mdr no mux ALUSrcB.

ALUOP <= "001";

--seleciona a ula para somar.

next_of_next <= loadbyte; --estado padrao para os loads.

currentState <= load;

--- Load Half

---when "100001" =>

AluSrcA <= '1'; --eleciona a passagem do

Reg. a no mux ALUSrcA.

AluSrcB <= "10";

--seleciona a passagem do mdr no mux ALUSrcB.

ALUOP <= "001";

--seleciona a ula para somar.

next_of_next <= loadhalf; --estado padrao para os loads.

currentState <= load;

--- Store Word

---when "101011" =>

AluSrcA <= '1'; -- seleciona valor do registrador A e envia-o pra ULA

MuxOP <= '0'; --seleciona o conteúdo da ULA

controlwrite <= "00"; -- ajusta o preStore pra gravar a palavra inteira(o valor de entrada eh o registrador B)

-- next_of_next <= storeWord;

currentState <= store;

--- Store Byte

---when "101000" =>

AluSrcA <= '1'; -- seleciona valor do registrador A e envia-o pra ULA

AluSrcB <= "10"; -- seleciona o valor do Deslocamento

AluOp <= "001"; -- realiza soma na ULA

MuxOP <= '0'; --seleciona o

conteúdo da ULA

controlwrite <= "10"; -- manipula o byte menos significativo a ser gravado!

-- next_of_next <= storebyte;

currentState <= store;

--- Store Half

---when "101001" =>

AluSrcA <= '1'; -- seleciona valor do registrador A e envia-o pra ULA

AluSrcB <= "10"; -- seleciona o valor do Deslocamento

AluOp <= "001"; -- realiza soma na ULA

MuxOP <= '0'; --seleciona o

conteúdo da ULA

controlWrite <= "01"; -- manipula meia palavra pra ser gravada na memória

-- next_of_next <= storehalf;

currentState <= store;

--- Load upper Immediate

---when "001111" =>

regdst <= "00"; --seleciona o registrador destino memtoreg <= "111";

-- addiu

---when "001001" =>

ALUSrcB <= "10"; -- seleciona a constante ALUOP <= "001"; -- operação de add na ALU MemtoReg <= "000"; -- seleciona valor a ser gravado RegDst <= "00"; -- registrador destino

currentState <= writeRegister;

--- andi

---when "001101" =>

ALUSrcB <= "10"; -- seleciona a constante

ALUOP <= "011"; -- opreção de and na ALU

MemtoReg <= "000"; -- seleciona valor a ser gravado

RegDst <= "00"; -- registrador destino

currentState <= loadALUResult;

--- xori

---when "001110" =>

ALUSrcB <= "10" ; -- seleciona a constante

ALUOP <= "110" ; -- seleciona operação de xor na ALU

MemtoReg <= "000" ; -- seleciona valor a ser gravado

RegDst <= "00" ; -- registrador destino

currentState <= loadALUResult;

--- BEQ - ---

---when "000100" =>

AluSrcB <= "11"; -- seleciona o deslocamento

AluSrcA <= '0'; -- PC

ALUOP <= "001"; -- soma

loadAluOut <= '1'; -- carrega aluOut currentState <= beq;

--- BNE - ---

---when "000101" =>

AluSrcB <= "11"; -- seleciona o deslocamento

AluSrcA <= '0'; -- PC

ALUOP <= "001"; -- soma PC + deslocamento currentState <= bne1;

slti ---

---AluSrcA <= '1'; --seleciona o mux do reg. A para passar o valor do reg.

AluSrcB <= "10"; --seleciona o mux do reg. B para passar a constante com sinal extendido.

ALUOP <= "111"; --seleciona a ula para comparar.

currentState <= slti;

--- j --- ---

---when "000010" =>

PCSource <= "010"; --seleciona pcSource para passar o valor do pc.

currentState <= LoadPC;

--- jal --- ---

---when "000011" =>

ALUSrcA <= '0'; --seleciona o mux do reg. A para passar o valor do reg.

ALUOP <= "000"; --Seleciona a ULA para carregar A na saida (deixa passa A).

PcSource <= "010"; --seleciona pcSource para passar o valor do pc.

currentState <= jal;

--- rte --- ---

---when "010000" =>

PCSource <= "011"; -- seleciona valor do EPC pra o PC

PCwrite <= '1'; -- grava novo valor do PC

currentState <= fetch;

---UnKnow OpCode---

---when others =>

ALUSrcA <= '0';

ALUSrcB <= "01";

ALUOP <= "010";

-- tratamento de exceção de OverFlow if(Overflow = '1') then

-- seleciona posicao da memoria pra tratar o overflow

ALUSrcA <= '0';

ALUSrcB <= "01";

ALUOP <= "010";

muxOp <= '0'; -- seleciona o resultado da ULA

PCSource <= "100";

IorD <= "10";

MemoryIO <= '0';

EXCode <= "10";

PCSource <= "100";

currentState <= writeEPC0;

else

LoadALUOut <= '1';

MemtoReg <= "000"; --seleciona valor a ser gravado

--RegDst <= "01"; -- registrador destino

currentState <= WriteRegister;

end if;

--- Carrega o valor do resultado da ALU no registrador ALUout

---when loadALUResult =>

loadALUOut <= '1';

currentState <= writeRegister;

--- Reliza a gravavação no registrador.

---when WriteRegister =>

MdrLoad <= '0';

loadALUOut <= '0'; -- desabilita gravação do AluOut

regWrite <= '1';

currentState <= fetch;

--- Instruções de LOAD --- ---

---when load =>

Iord <= "01";

LoadAluOut <= '1';

currentState <= load1;

when load1 =>

MemoryIO <= '0';

currentState <= WaitReadMemory1;

--- Primeiro dos 2 ciclos de leitura da memória when WaitReadMemory1 =>

currentState <= WaitReadMemory2;

--- Último Ciclo de leitura da memória (ao término o valor da memória

MdrLoad <= '0';

currentState <= next_of_next;

--- Load Word --- ---

---when LoadWord =>

MdrLoad <= '1';

MdrType <= "00"; -- desabilita deslocamento

RegDst <= "00"; -- seleciona o registrador destino

MemtoReg <= "001"; -- seleciona valor lido da memória

currentState <= writeRegister;

--- Load Half --- ---

---when LoadHalf =>

MdrLoad <= '1';

MdrType <= "10"; -- Realiza 16 deslocamentos para a direita --OBS:Trocado por anti-patern

RegDst <= "00"; -- seleciona o registrador destino

MemtoReg <= "001"; -- seleciona valor lido da memória

currentState <= writeRegister;

--- Load Byte --- ---

---when LoadByte =>

MdrLoad <= '1';

MdrType <= "01"; -- Realiza 24 deslocamentos para a direita --OBS:Trocado por anti-patern

RegDst <= "00"; -- seleciona o registrador destino

MemtoReg <= "001"; -- seleciona valor lido da memória

currentState <= writeRegister;

--- Instruções de --- STORE---

---when store =>

--- Instruções de MULT/DIV ---

---when mult =>

MultDivStart <= '1';

MultDiv <= '0';

currentState <= WaitMultDiv;

when div =>

MultDivStart <= '1';

MultDiv <= '1';

currentState <= WaitMultDiv;

--- Wait Final Operation --- ---

---when WaitMultDiv =>

MultDivStart <= '0';

if(MultDivFinished = '1') then if(DivByZero = '1') then

currentState <= DivByZeroHandler; --trata-mento de exceção

else

LoadHiLo <='1';

currentState <= fetch;

end if;

else

currentState <= WaitMultDiv;

end if;

--- ESTADO DE TRATAMENTO DE EXCEÇÂO ---

---when DivByZeroHandler =>

-- seleciona posicao da memoria pra tratar a divisão por zero

ALUSrcA <= '0';

ALUSrcB <= "01";

ALUOP <= "010";

muxOp <= '0'; -- seleciona o resultado da ULA PCSource <= "100";

IorD <= "10";

MemoryIO <= '0';

EXCode <= "01";

PCSource <= "100";

currentState <= writeEPC0;

--- beq -- ---

---when beq =>

AluSrcA <= '1';

AluSrcB <= "00";

AluOp <= "010";

pcSource <= "001";

PcWriteCond <= '1';

currentState<= fetch;

---when bne1 =>

loadAluout <= '1';

currentState <= bne2;

when bne2 =>

loadAluout <= '0';

AluSrcA <= '1';

AluSrcB <= "00";

AluOp <= "111";

currentState <= bne3;

when bne3 =>

if(igual = '0') then

PCSource <="001";

PCWrite <= '1';

else PCWrite <= '0';

end if;

currentState <= fetch;

--- slt -- ---

---when slt =>

if(Menor = '1') then

MemToReg <= "101"; -- seleciona a entrada 5 do mux

else

MemToReg <= "100";

end if;

currentState <= writeRegister;

--- slti -- ---

---when slti =>

regDst <= "00"; --seleciona para passar o endereco do reg. a escrever.

if(Menor = '1') then

MemToReg <= "101"; -- seleciona a entrada 5 do mux

else

when LoadPC =>

LoadALUOut <= '0';

PCWrite <= '1';

currentState <= fetch;

--- jal -- ---

---when jal =>

LoadALUOut <= '1';

MemToReg <= "000";

RegDst <= "10";

PCWrite <= '1';

PCSource <= "010";

currentState <= writeReg31;

--- Write Reg31 --- ---

---when writeReg31 =>

PCWrite <= '0';

--PCSource <= "010";

LoadALUOut <= '0';

RegWrite <= '1';

currentState <= fetch;

--- break -- ---

---when break =>

currentState <= break; -- põe essa droga em Loop

--- WriteECP -- ---

---when writeEPC0 =>

-- EPCLoad <= '0';

currentState <= writeEPC;

--- WriteECP -- ---

---when writeEPC =>

EPCLoad <= '1';

currentState <= loadPCEX;

--- WriteECP -- ---

---when loadPCEX =>

EPCLoad <= '0';

PCWrite <= '1';

currentState <= fetch;

when others =>

currentState <= Fetch;

end case;

end if;

end arqControlUnit;

No documento Processador MIPS (páginas 33-53)

Documentos relacionados