• Nenhum resultado encontrado

Processador MIPS

N/A
N/A
Protected

Academic year: 2022

Share "Processador MIPS"

Copied!
1
0
0

Texto

(1)

. . . . . . . . . .

... ...

... .

Universidade Federal de Pernambuco

Centro de Informática – Cin

Processador MIPS

Projeto de Infra-Estrutura de

Hardware

(2)

. . . . . . . . . .

... ...

... .

Lista de Autores...5

Introdução...6

Objetivos...6

Especificações do Sistema...7

Formato 1...8

Modelo da instrução F1...8

Representação da instrução F1...8

Formato 2...9

Modelo da instrução F2...9

Representação da instrução F2...10

Formato 3...10

Modelo da instrução F3...10

Representação da instrução F3...11

Dispositivos Oferecidos...12

ULA...12

Banco de Registradores...13

Registrador de 32 bits...13

Memória...13

(3)

Shift N... 17

Mult / Div...18

Memory Data Register...18

PreStore...19

Desloc Const...19

Unidade de Controle...19

Notas de Design...21

Diagrama de Fluxo...21

Máquina de Estados...21

Simulação...23

Simulação de Exceções...25

Tratamento de Exceções...32

controlunit.vhd...35

desloc_const...53

ex_adr_sel...53

extensao_sinal.vhd...53

instr_reg.vhd...54

mdr.vhd...55

multidiv.vhd...57

prestore.vhd...62

processor.vhd...63

sel_ld_pc.vhd...83

shift_left.vhd...83

shift_left_26bits.vhd...83

shiftleft2.vhd...84

shiftn.vhd...84

banco_reg.vhd...86

memoria.vhd...90

(4)

registrador.vhd...97

Ula32.vhd...98

mux21_4bits.vhd...103

mux21_32bits.vhd...103

mux31_32bits_adr.vhd...103

mux41_5bits.vhd...104

mux41_28bits.vhd...104

mux41_32.vhd...105

mux41_32bitsnor.vhd...105

mux81.vhd...106

mux81_pc.vhd...107

(5)

Lista de Autores

Allan Diego Silva Lima

Curso de Ciência da Computação – CIn/UFPE [email protected]

Cléviton Vinicius Fonseca Monteiro

Curso de Ciência da Computação – CIn/UFPE [email protected]

Jobson Ronam Jerônimo Silva

Curso de Ciência da Computação – CIn/UFPE [email protected]

Osmany Barros de Freitas

Curso de Ciência da Computação – CIn/UFPE [email protected]

Paulo Henrique Padovan

Curso de Ciência da Computação – CIn/UFPE

[email protected]

(6)

Definições do Projeto

“... a melhor oportunidade para dominar o funcionamento e

implementação da arquitetura RISC e do processador MIPS...”.

Introdução

Com o objetivo aprimorar o ensino da disciplina de Infra-Estrutura de Hardware e levar o aluno à prática do conteúdo trabalhado em sala de aula, a Dra. Edna Barros, do Centro de Informática da Universidade Federal de Pernambuco, aplica semestralmente o projeto de implementação de um subconjunto de instruções do núcleo básico do MIPS.

Por ser uma arquitetura RISC (Reduced Instruction Set Computer) o MIPS, oriundo de um projeto da Universidade de Stanford, se caracteriza pela simplicidade de sua arquitetura interna, podendo ser implementado com o estado da arte em tecnologia e com menor gasto de área. Isto implica em uma relação custo/desempenho bem melhor que a dos microprocessadores convencionais, que consomem mais área e, devido à complexidade de projeto, não conseguem acompanhar o último passo em termos de tecnologia de fabricação.

Tendo em vista suas aplicações comerciais (principalmente em sistemas embarcados) e na adequação à didática de microprocessadores, este projeto constitui a melhor oportunidade para dominar o funcionamento e implementação da arquitetura RISC e do processador MIPS oferecida ao aluno de graduação em Ciência e Engenharia da Computação.

Objetivos

Vamos projetar uma implementação que inclui um subconjunto das instruções do núcleo básico do

MIPS. Esse conjunto não inclui todas as instruções inteiras nem quaisquer das instruções de ponto

flutuante. No entanto, todos os princípios fundamentais do projeto de um caminho de dados e de uma

unidade de controle são trabalhados nesse projeto.

(7)

Especificações

Especificações do Sistema

A arquitetura proposta trabalha através da manipulação direta de registradores. Possuindo 32 registradores de propósito geral, cada um de 32 bits, nosso processador possui um conjunto de 34 instruções, veja tabela 1, cada uma de 32 bits e apresentam-se sob três formas distintas.

Instrução Opcode Funct Descrição

nop 000000 000000 No operation (todos os outros campos são zero).

lw reg,

desl(reg_base) 100011 Carrega palavra localizada a partir do endereço dado por (reg_base + desl) no registrador reg.

sw reg,

desl(reg_base) 101011 Escreve registrador reg a partir do endereço de memória dado por (reg_base + desl).

lb reg,

desl(reg_base) 100000 Carrega byte localizado no endereço dado por (reg_base + desl) no byte menos significativo do registrador reg. O sinal deve ser extendido.

lh reg,

desl(reg_base) 100001 Carrega meia palavra localizada a partir do endereço (reg_base + desl) na parte menos significativa do registrador reg. O sinal deve ser extendido.

sb reg,

desl(reg_base) 101000 Escreve byte menos significativo do registrador reg no endereço de memória dado por (reg_base + desl). Somente um byte é escrito na memória.

sh reg,

desl(reg_base) 101001

Escreve meia palavra menos significativa do registrador reg a partir do endereço de memória dado por (reg_base + desl). Somente dois bytes são escritos na memória.

lui reg, constante 001111 Carrega constante na parte mais significativa do registrador reg = constante, os demais bits são iguais a zero.

mfhi rd 000000 010000 Carrega reg hi para rd.

mflo rd 000000 010010 Carrega reg lo para rd.

add regi, regj, regk 000000 100000 regi = regj + regk (com overflow).

addi regi, regj, cte 001000 regi = regj + cte (com overflow).

sub regi, regj, regk 000000 100010 regi = regj – regk (com underflow).

addu regi, regj,

regk 000000 100001 regi = regj + regk (sem overflow).

addiu regi, regj,

cte 001001 regi = regj + cte.

subu regi, regj,

regk 000000 100011 regi = regj – regk.

and regi, regj, regk 000000 100100 regi = regj and regk.

andi regi, regj, cte 001101 regi = regj and cte.

xor regi, regj, regk 000000 100110 regi = regj xor regk.

xori regi, regj, cte 001110 regi = regj xor cte.

(8)

divisão

sra regd, regs, n 000000 000011 Desloca registrador regs para a direita n vezes (aritmético) e armazena o valor deslocado no registrador regd.

srlregd, regs, n 000000 000010 Desloca registrador regs para a esquerda n vezes (lógico) e armazena o valor deslocado no registrador regd.

sll regd, regs, n 000000 000000 Desloca registrador regs para a esquerda n vezes e armazena o valor deslocado no registrador regd.

beq regi, regj, desl 000100 PC = PC + (desl * 4) se regi == regj.

bne regi, regj, desl 000101 PC = PC + (desl * 4) se regi <> regj.

slt regi, regj, regk 000000 101010 regi = 1 se regj < regk, senão regi = 0.

slti regi, regj, cte 001010 regi = 1 se regj < cte, senão regi = 0.

j end 000010 Desvio para end (PC = end).

jr regi 000000 001000 PC = regi.

jal end 000011 $31 = PC; PC = end.

ret 010000 010000 Retorno de exceção

break 000000 001101 Pára a execução do programa.

Tabela 1: Repertório de Instruções.

As instruções descritas na tabela estão classificadas em três tipos de formatos reconhecidos pela Unidade de Controle

Formato 1

 Instruções aritméticas (add e sub), lógicas (xor e and), comparativas (stl – set less than), deslocamento (sra e sll) e jr (jump register).

Modelo da instrução F1

Opcode RS1 RS2 RD Count Funct

6 bits 5 bits 5 bits 5 bits 5 bits 6 bits

Representação da instrução F1

Instruções aritméticas, lógicas e SLT (Set Less Than).

Opcode

Especifica o código da instrução a ser executada. Em caso de opcodes idênticos, o Controle prepara o mesmo comportamento para essas instruções modificando, então, apenas as

(9)

Instruções de deslocamento Opcode Especifica o código da instrução a ser executada.

RS1 Informa o registrador que contém o valor a ser deslocado.

RS2 Informa o registrador que conterem o resultado do deslocamento.

RD Não é utilizado nesse formato.

Count É aquele onde está a quantidade de vezes que será realizado um shift (left ou right).

Funct Diferencia as instruções dentro do seu formato (F1).

Instruções de jump register Opcode Especifica o código instrução que será efetuada.

RS1 Informa qual o registrador que contém o valor que será armazenado em PC.

RS2 Informam os dois registradores que devem ser lidos ou sobre os quais uma operação lógica, aritmética ou um SLT será executada.

RD Especifica o registrador de destino, que armazenará o resultado de uma operação realizada.

Count Não é utilizado nesse formato.

Funct Diferencia as instruções dentro do seu formato (F1).

As instruções de multiplicação e divisão possuem o formato F1 e permitem a multiplicação ou divisão dos registradores rs e rt. O resultado é

armazenado em dois registradores internos hi e lo. Para permitir a leitura de tais registradores existem as instruções mfhi e mflo, responsáveis pelo carregamento do registrador hi ou lo no registrador rd, respectivamente.

As instruções mfhi e mflo possuem formato F1. A instrução de divisão realiza a operação entre os valores armazenados em rs e rt e armazena o quociente no registrador interno mflo, o resto da divisão fica armazenado no registrador mfhi..

Formato 2

 Instruções de acesso à memória (lw, sw, lb, sb, lh e sh) e as de desvio condicional (beq e bne).

 Instruções, addi, andi, xori e slti, as instruções aritméticas, lógicas e a de comparação onde um dos operadores é uma constante.

 Instrução lui (load upper immediate), que carrega uma constante em um registrador.

Modelo da instrução F2

Opcode RB RD Deslocamento 6 bits 5 bits 5 bits 16 bits

Representação da instrução F2

(10)

RB Especifica o registrador base, que é somado ao deslocamento para o cálculo do endereço onde será lido.

RD Especifica o registrador de destino, que armazenará o conteúdo do endereço de memória fornecido pelo registrador base mais o deslocamento.

Deslocamento Constante que será somada ao registrador base para o cálculo do endereço.

Instruções de Store Opcode Especifica o código da instrução a ser executada.

RB Especifica o registrador base, que é somado ao deslocamento para o cálculo do endereço onde será escrito.

RD Especifica o registrador de destino, que armazenará o conteúdo que será armazenado na memória

Deslocamento Constante que será somada ao registrador base para o cálculo do endereço.

instruções aritméticas, lógicas e a de comparação onde um dos operandos é uma constante Opcode Especifica o código da instrução a ser executada.

RB Registrador que contém um dos valores utilizado na operação que será realizada pela ULA.

RD Indica o registrador no qual será colocado o resultado da operação.

Deslocamento Possui o valor da constante a ser operada.

Instrução lui Opcode Especifica o código da instrução a ser executada.

RB Registrador no qual é carregado o valor da constante.

RD

Não é

utilizado

nessa instrução

.

Deslocamento Registrador onde será carregado o valor da constante na sua parte mais significativa, sendo os demais bits iguais a zero.

Instruções de desvio condicional Opcode Especifica o código da instrução a ser executada.

RB 1º registrador a ser comparado.

RD 2º registrador a ser comparado.

Deslocamento

No caso da instrução beq, esse vetor de bits indica para qual instrução o PC deve pular. No caso da instrução bne, o mesmo vai ocorrer, de forma que os conteúdos dos registradores são diferentes.

Formato 3

 Instruções de jump (j, jal)

(11)

Instruções de jump and link Opcode Especifica o código da instrução a ser executada.

Endereço

Contém o valor de memória (endereço é absoluto) para o qual a execução do programa é desviada. O endereço da instrução seguinte é armazenado num registrador para que o programa possa retornar à execução após terminar a rotina especificada no jal sendo o valor do PC guardado no R31.

(12)

Dispositivos Internos

Dispositivos Oferecidos

Lista dos componentes oferecidos para o desenvolvimento do projeto que foram utilizados no mesmo.

ULA

A Unidade Aritmética e Lógica (UAL) é um circuito combinacional com:

 2 entradas de dados de 32bits

 1 entrada de controle F de 3bits

 1 saída de dados de 32bits

 6 saídas de 1bit (flags)

Flag Função

A B

S

N Z EQ O GT LT

ALU 32 32

32

Z Zero

N Negativo

O Overflow

EQ Equal

LT Less Than

GT Greater Than

Figura 1: ALU.

A UAL permite a operação com números de 32 bits na notação complemento a dois. A funcionalidade é especificada pela entrada F conforme descrito na tabela abaixo.

F Operação Descrição Flags Afetados

000 S = A A Z,N

S = A + B Soma Z,N,O

(13)

Banco de Registradores

O banco de registradores é composto por 32 registradores de 32 bits cada. Dois registradores podem ser visíveis simultaneamente e carregados nos registradores A e B. A leitura dos registradores é combinacional, isto é, se os valores nas entradas ReadRegister1 ou ReadRegister 2 forem alteradas, os valores nas saídas ReadData1 ou ReadData2 podem ser alterados. O registrador a ser escrito é selecionado pela entrada WriteRegister e quando a entrada RegWrite é ativada (igual a 1) o registrador selecionado recebe o conteúdo da entrada WriteData. O sinal de reset limpa todos os registradores e é assíncrono. Os registradores A e B também possuem reset. Este componente deve ser descrito no domínio comportamental.

Figura 2: Banco de Registradores.

Registrador de 32 bits

Para armazenar instruções e dados, bem como os endereços das instruções serão utilizados registradores de 32 bits, conforme ilustrado na figura abaixo.

Reg8

load clock

clear

Reg32

load clock

clear

Figura 3: Registrador de 32 bits.

Memória

A memória usada no projeto possuir palavras de 32 bits com endereçamento por byte. Apesar de o endereço possuir 32 bits, a memória só possui 256 bytes.

ram8

add

Data_in

Data_out

clock

wr

Ram32

add

Data_in

Data_out

clock

wr Instruction

Registers Write

register

data 1Read

data 2Read Readregister 1

Readregister 2

Write data

RegWrite Instruction

Registers Write

register

data 1Read

data 2Read Readregister 1

Readregister 2

Write data

RegWrite

(14)

Entradas e Saídas da Memória

Memória Entradas

Data_In 32 bits Entrada de Dados da memória.

Add 32 bits O endereço de entrada da memória.

Wr 1 bit Seleciona entre ler (0) ou escrever (1).

Clock 1 bit Comum a todo computador síncrono.

Saída

Data_out 32 bits Saída de dados da memória.

Peculiaridades da Memória

1. Enquanto o bit "wr" estiver com o valor zero (0) ele está lendo, quando estiver com o valor um (1) ele estará escrevendo.

2. A memória está trigada na subida do clock.

3. Ao se fazer uma requisição de leitura, o valor pedido só estará disponível dois ciclos de clock após o clock onde foi feito a requisição.

4. A escrita leva um ciclo.

(15)

Dispositivos Adicionais

Lista dos componentes extras que foram adicionados durante o desenvolvimento do projeto e que fazem parte do mesmo.

PC - Program Counter

O PC (Program Counter) é um registrador de 32 bits com:

Program Counter Entradas

PCWriteCond 1 bit Grava PC em condições de jump

PCWrite 1 bit Grava PC

PCReset 1 bit Reseta PC

PC_in 32 bits Novo valor a ser carregado Saída

PC_out 32 bits Endereço da instrução a ser executada.

O PC grava o endereço da próxima instrução a ser executada.

Instruction Register

Registrador de 32 bits que tem a função de armazenar o vetor que contém a palavra oriunda da memória.

Instruction Register Entradas

Clk 1 bit Clock do sistema.

Reset 1 bit Reset.

Load_ir 1 bit Ativa a carga do registrador de instruções.

Entrada 32 bits Instrução a ser carregada.

Saídas

Instr31_26 16 bits Bits 31 a 26 da instrução.

Instr25_21 5 bits Bits 25 a 21 da instrução.

Instr20_16 5 bits Bits 20 a 16 da instrução.

Instr15_0 6 bits Bits 15 a 0 da instrução.

EPC - Exception Program Counter

Registrador de 32 bits que tem a função de armazenar o valor do PC que gerou a exceção.

Veja também o tópico referente a exceções

(16)

Entradas

EPCLoad 1 bit Carrega o EPC EPCReset 1 bit Reseta o EPC

EPC_in 32 bits Endereço da instrução que gerou a exceção.

Saída

EPC_out 32 bits Novo endereço da instrução que gerou a exceção

Signal Extend

Elemento lógico que tem a função de estender o vetor de entrada de 16 para 32 bits.

Signal Extend Entradas

entrada 16 bits Vetor de 16 bits Saída

saída 32 bits Vetor de 32 bits estendido

Shift Left 2

Deslocamento lógico à esquerda. Têm por função de deslocar o vetor passado como entrada duas vezes para a esquerda.

Shift Left 2 Entradas

Entrada 32 bits Vetor de 32 bits Saída

saída 32 bits Vetor deslocado 2 vezes para a esquerda

ALU Out

Registrador de deslocamento que tem a função de armazenar o resultado de saída da ULA.

(17)

HI Entradas

Sys_clk 1 bit Clock do Sistema rset_HiLo 1 bit Reseta o HI e o LO

ld_HiLo 1 bit Carrega o HI e o LO

HI_in 32 bits Recebe o resultado da multiplicação ou divisão Saída

HI_out 32 bits Fornece o resultado da multiplicação ou divisão

O HI armazena o resto (no caso da divisão) ou os 32 primeiros bits (canônico) do produto (no caso da multiplicação)

LO

O LO é um registrador de 32 bits com:

LO Entradas

Sys_clk 1 bit Clock do Sistema rset_HiLo 1 bit Reseta o HI e o LO

ld_HiLo 1 bit Carrega o HI e o LO

HI_in 32 bits Recebe o resultado da multiplicação ou divisão Saída

HI_out 32 bits Fornece o resultado da multiplicação ou divisão

O LO armazena o quociente (no caso da divisão) ou os 32 últimos bits (canônico) do produto (no caso da multiplicação)

Shift N

Deslocamento lógico ou aritmético à esquerda. Têm por função de deslocar o vetor passado como entrada n vezes para a esquerda.

Shift N Entradas

Seleção 1 bit Seleção

N 5 bits Parâmetro que indica o número de vezes (entre zero e 32.) que a entrada deve ser deslocada.

Entrada 32 bits Vetor de 32 bits Saída

Saída 32 bits Vetor deslocado n vezes para a esquerda

Mult / Div

O Mult/Div é um circuito síncrono com:

(18)

clk 1 bit Clock do sistema

start 1 bit Ativa (1) ou Desativa (0) o dispositivo seleção 1 bit Seleciona entre Multiplicar (0) ou Dividir (1) entrada1 32 bits 1ª parcela

entrada2 32 bits 2ª parcela Saídas

HI 32 bits Armazena o resto (no caso da divisão) ou os 32 primeiros bits (canônico) do produto (no caso da multiplicação).

LO 32 bits Armazena o quociente (no caso da divisão) ou os 32 últimos bits (canônico) do produto (no caso da multiplicação).

divZero 1 bit Indica se houve divisão por zero.

terminou 1 bit Indica se a operação foi concluída.

O Mult/Div permite a operação com números de 32 bits na notação complemento a dois.

 Para efetuarmos uma multiplicação fazemos à seleção igual à zero (0). O resultado é armazenado em HI (32 primeiros bits) e LO (32 últimos bits) e o flag terminou passa a ser um (1).

 Para efetuarmos uma divisão fazemos à seleção igual a um (1). O quociente é armazenado em LO e o resto em HI e o flag terminou passa a ser um (1).

Memory Data Register

Entidade responsável pelo deslocamento de um vetor de 32 bits para a direita estendendo o sinal.

Memory Data Register Entradas

Clk 1 bit Clock do sistema

reset 1 bit Reset

load 1 bit Ativa o carregamento

N 2 bits Código / Deslocamento 00 0 01 8 10 16 11 24

entrada 32 bits Vetor a ser deslocado Saída

saida 32 bits Vetor deslocado

(19)

Saída

saida 32 bits Saída para memória

Desloc Const

Recebe uma constante de 16 bits e entrega um vetor de 32 bits com os 16 primeiros bits iguais à zero.

Desloc Const Entradas

entrada 16 bits Constante Saída

saída 32 bits Vetor com 32 bits que possui a constante

Unidade de Controle

Entidade responsável pela interpretação das instruções e pelo comando na execução das mesmas, através do envio de sinais de controle às unidades da central de processamento.

Memory Data Register Entradas

Clock 1 bit O relógio do processador Reset 1 bit Reseta a unidade de controle

Overflow 1 bit Flag da ULA que indica overflow da ULA Negativo 1 bit Sinaliza quando for negativo

Zero 1 bit Sinaliza quando S for zero Igual 1 bit Sinaliza se A = B Maior 1 bit Sinaliza se A > B Menor 1 bit Sinaliza se A < B

MultDivFinished 1 bit Indica o término da operação de multiplicação ou divisão DivByZero 1 bit Indica se exceção divByZero ocorreu

instruction 32 bits A instrução que irá ser analisada pela unidade de controle Saídas

MemoryIO 1 bit Indica se a memória será escrita (1) ou lida (0) IRWrite 1 bit Indica se uma nova instrução será decodificada ou não

reset_Bank 1 bit Indica a operação a ser realizada pelo banco de registradores leitura (0) escrita (1) RegWrite 1 bit Indica a operação a ser realizada pelo banco de registradores leitura (0) escrita (1) MultDivStart 1 bit Inicia a operação

MultDiv 1 bit Seleciona a multiplicação ou divisão

ALUSrcA 1 bit Controlam os Multiplexadores das entradas de ALU PCSource 1 bit Controla o valor a ser carregado no PC

IorD 1 bit Controla o multiplexador que seleciona o endereço de memória a ser lido ou escrito RegDst 1 bit Seleciona o registrador a ser gravado no banco de registradores

(20)

EXCode 1 bit Seleciona o multiplexador que possui constantes usadas no SLT, SLTI e Exceções.

LoadA 1 bit Carrega o registrador A ResetA 1 bit Reseta o registrador A

LoadB 1 bit Carrega o registrador B ResetB 1 bit Reseta o registrador B LoadALUOut 1 bit Carrega o registrador ALUOut ResetALUOut 1 bit Reseta o registrador ALUOut

LoadHiLo 1 bit Carrega os registradores HI e LO ResetHiLo 1 bit Reseta os registradores HI e LO PCWriteCond 1 bit Flag de controle de escrita no PC

PCWrite 1 bit Escreve no PC PCReset 1 bit Reseta o PC MdrLoad 1 bit Carrega o MDR MdrReset 1 bit Reseta o MDR

MdrType 1 bit Define a operação (byte, half, word) do MDR de acordo com o valor passado EPCLoad 1 bit Carrega o EPC

EPCReset 1 bit Reseta o EPC

controlWrite 2 bits Indica se o que deve ser guardado na memória é um byte (8 bits) , um half (16 bits) ou uma word (32 bits)

ShiftN 2 bits Indica o tipo do deslocamento

ALUSrcB 2 bits Controlam os Multiplexadores das entradas de ALU ALUOp 2 bits Seleciona a operação que a ALU irá realizar

MemToReg 2 bits Controla o mux que selecionará os dados a serem escritos no banco de registradores

Descrições do Design

Notas de Design

Numa implementação multiciclo, cada passo na execução de uma instrução gasta um único ciclo de

clock. A implementação multiciclo permite que uma unidade funcional seja utilizada mais de uma vez

(21)

ReadMemory1 Soma PC + 4

ReadMemory2 Espera que a memória seja lida LoadInstructionRegiste

r

Carrega o Instruction Register

LoadInstruction Aguarda o valor lido na memória ser liberado no instruction register Decoder Envia a instrução pra a unidade de controle e carrega A e B

Break Para execução do programa Mfhi Acesso ao registrador HI Mflo Acesso ao registrador LO

Slt Checa o flag “Menor” da ALU e seleciona o valor entre 0 e 1 LoadALUResult Carrega o resultado da ALU

OverflowHandler Verifica se a exceção de overflow deve ser lançada WaitMultDiv Espera a conclusão da operação de MULT ou DIV

Beq Instrução de pulo condicional Bne Instrução de pulo condicional

LoadPC Estado para escrever PC apos os jumps Jal Pulo não condicional

Jr Pulo não condicional

Load Estado genérico para a respectiva operação Store Estado genérico para a respectiva operação WriteRegister Realiza a escrita em um registrador

Beq2 Instrução de pulo condicional

WriteReg31 Estado para carregar o PC no registrador 31 WriteEPC Estado para carregar o EPC

Load1 Estado genérico para a respectiva operação WriteMemory Realiza escrita na memória

DivByZeroHandler Realiza tratamento de exceção para divisão por ZERO Beq3 Instrução de pulo condicional

LoadEPC Estado para carregar EPC

WaitReadMemory1 Estado genérico para a respectiva operação IdleState Estado de espera

WaitReadMemory2 Estado genérico para a respectiva operação LoadWord Estado de load

LoadHalf Estado de load LoadByte Estado de load

O esquemático da Máquina de Estados encontra-se no apêndice B.

(22)

Verificações e Testes

Simulação

O seguinte programa foi usado para similar nosso projeto. Abaixo o código.

lui $2, 172 (decimal) srl $2, $2, 16

lui $7, 0x0032 (hexa-decimal) srl $7, $7, 16

xor $8,$8, $8 lui $8, 0xFFFF srl $8, $8, 16

lh $3,4($2)

sw $2, 0($29) addi $29, $29, -4

lw $5,0($2)

loop: lui $1,0 jal procure bne $1, $0, fim addi $5, $5, 1 addi $2, $2, 2 j loop

fim: addi $5, $5,1 addi $29,$29,4

lw $2, 0($29) mult $5, $2

mfhi $8 mflo $9 div $2, $5 mfhi $10 mflo $11

break

procure: lh $4, 6($2) and $6, $4, $8

(23)

End. numérico

End.simbólico Conteúdo memória

67

73 80 0 72

95 32 94

texto count 176

172

177 178 179 180 181 182 183 184 185 186

227

...

Pilha 82

32

69 69 70 83 00

Figura 7: Localização e valores iniciais das variáveis na memória.

O arquivo de simulação mostra os valores dos seguintes sinais: MDR, PC, IR, Regs. $1,$2,$3, $4, $5,

$6, $7, $8, $9, $10, $11, $29 e $31.

(24)

Simulação de Exceções

As três situações de exceção foram simuladas e para cada uma delas segue um arquivo de simulação.

Opcode Inexistente

(25)

Divisão por Zero

(26)

Overflow

(27)

Simulação Demais simulações:

Divisão

(28)
(29)

Multiplicação

(30)

Mdr

PreStore

SL

(31)

SRA

SRL

Exceções

Tratamento de Exceções

A implementação das exceções leva em consideração três tipos de exceções:

 Opcode inexistente

 Overflow

 Divisão por zero.

(32)

Na ocorrência de uma exceção, o endereço da instrução que causou a exceção é salvo no registrador EPC e o PC é carregado, com o valor do endereço da rotina de tratamento, cujo byte menos significativo está armazenado nos seguintes endereços de memória:

 253 – Opcode Inexistente

 254 – Overflow

 255 – Divisão por zero

A rotina de tratamento é armazenada entre os endereços 228 (decimal) até o endereço 251.

No caso de um opcode inexistente, o valor um (1) é armazenado no registrador 30 pela rotina de tratamento e o programa para a execução.

No caso de um overflow, o valor 2 é armazenado no registrador 30 pela rotina de tratamento e a execução do programa continua.

No caso de divisão por zero, o valor três (3) é armazenado no registrador 30 pela rotina de tratamento e o programa parar a execução.

Exceção Valor armazenado

no registrador 30 Execução do programa

Opcode inexistente 1 PARA

Overflow 2 CONTINUA

Divisão por zero 3 PARA

Tabela ??: Exceções.

(33)

Referências

Organização e projeto de computadores

HENNESSY, John L.; PATTERSON, David. A.; LARUS, James R.. Organização e projeto de computadores a interface hardware software. 2ª ed. Rio de Janeiro: Livros Técnicos e Científicos, c2000.. 551p. ISBN 8521612125.

Introdução a organização de computadores

MONTEIRO, Mario A. (Mario Antonio).. Introdução a organização de computadores.

2. ed. - Rio de Janeiro: LTC, c1995.. 393 p. ISBN 85-216-1032-7

Introdução à arquitetura e organização de computadores

LORIN, Harold.; REINPRECHT, Ricardo, trad.. Introdução à arquitetura e organização de computadores. Rio de Janeiro: Campus, 1985.. 362p. ISBN 85-7001- 191-1.

A guide to VHDL

MAZOR, Stanley.; LANGSTRAAT, Patricia, colab.. A guide to VHDL. 2. ed. - Bos- ton: Kluwer Academic, 1993.. 1v. (paginação irregular)

MIPS RISc architeture

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

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

(34)

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;

(35)

-- 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

(36)

-- 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

(37)

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';

(38)

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

(39)

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';

(40)

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 <=

(41)

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

---

(42)

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;

---

(43)

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

(44)

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";

(45)

-- 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 ---

(46)

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";

(47)

-- 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

(48)

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 =>

(49)

--- 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;

(50)

--- 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

(51)

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;

(52)

end arqControlUnit;

(53)

desloc_const

entity desloc_const is port (

entrada :in bit_vector(15 downto 0);

saida :out bit_vector(31 downto 0)

);

end desloc_const;

architecture behavioral_arc of desloc_const is begin

saida(15 downto 0) <= "0000000000000000";

saida(31 downto 16) <= entrada;

end behavioral_arc;

ex_adr_sel

entity ex_adr_sel is port(

selecao :in bit_vector(1 downto 0);

entradaDataOut :in bit_vector(31 downto 0);

saida :out bit_vector(7 downto 0)

);

end ex_adr_sel;

architecture behavioral_arc of ex_adr_sel is begin

process begin

case selecao is when "00" =>

saida <= entradaDataOut(7 downto 0);

when "01" =>

saida <= entradaDataOut(15 downto 8);

when "10" =>

saida <= entradaDataOut(23 downto 16);

when "11" =>

end case;

end process;

end behavioral_arc;

extensao_sinal.vhd

(54)

port(

entrada :in bit_vector(15 downto 0);

saida :out bit_vector(31 downto 0) );

end extensao_sinal;

architecture behavioral_arch of extensao_sinal is begin

saida(15 downto 0) <= entrada;

with entrada(15) select

saida(31 downto 16) <= "0000000000000000" when '0', "1111111111111111" when '1';

end behavioral_arch;

instr_reg.vhd

--- -- Title : Registrador de Intruções

-- Project : CPU multi-ciclo

---

-- File : instr_reg.vhd

-- Author : Marcus Vinicius Lima e Machado ([email protected])

-- Paulo Roberto Santana Oliveira Filho

([email protected])

-- Viviane Cristina Oliveira Aureliano ([email protected]) -- Organization : Universidade Federal de Pernambuco

-- Created : 29/07/2002 -- Last update : 21/11/2002 -- Plataform: Flex10K

-- Simulators : Altera Max+plus II -- Synthesizers :

-- Targets :

-- Dependency :

--- -- Description : Entidade que registra a instrução a ser executada, modulando -- corretamente a saída de acordo com o layout padrão das intruções do Mips.

--- -- Copyright (c) notice

-- Universidade Federal de Pernambuco (UFPE).

-- CIn - Centro de Informatica.

(55)

entity Instr_reg is port(

Clk : in bit; -- Clock do sistema

Reset : in bit; -- Reset

Load_ir : in bit; -- Bit para ativar carga do registrador de intruções

Entrada : in bit_vector (31 downto 0); -- Intrução a ser carregada

Instr31_26 : out bit_vector (5 downto 0); -- Bits 31 a 26 da instrução

Instr25_21 : out bit_vector (4 downto 0); -- Bits 25 a 21 da instrução

Instr20_16 : out bit_vector (4 downto 0); -- Bits 20 a 16 da instrução

Instr15_0 : out bit_vector (15 downto 0) -- Bits 15 a 0 da instrução

);

end Instr_reg;

-- Arquitetura que define o comportamento interno do Registrador de Intruções -- Simulation

architecture behavioral_arch of Instr_reg is

signal saida : bit_vector (31 downto 0); -- Sinal interno que guarda a intrução a ser modulada

begin

-- Clocked process process (clk, Reset)

begin

if(reset = '1') then

saida <= "00000000000000000000000000000000";

elsif (clk = '1' and clk'event) then if (load_ir = '1') then

saida (31 downto 0) <= entrada; -- Carrega instrução

end if;

end if;

end process;

Instr31_26 <= saida (31 downto 26); -- Modula instrução (31 a 26) Instr25_21 <= saida (25 downto 21); -- Modula instrução (25 a 21) Instr20_16 <= saida (20 downto 16); -- Modula instrução (20 a 16) Instr15_0 <= saida (15 downto 0); -- Modula instrução (15 a 0) end behavioral_arch;

mdr.vhd

(56)

-- Entradas:

-- * reset: bit que reseta o mdr

-- * load: bit que carrega o mdr

-- * N: vetor de 2 bits que indica a quantidade de

-- deslocamentos

-- Abaixo seguem os valores referentes à entrada shift e as

-- respectivas funções do registrador:

--

-- N pode ser deslocamentos de: 00 não desloca --

01 Deslocamento 8 vezes -- 10 Deslocamento 16 vezes -- 11 Deslocamento 24 vezes

--- ENTITY mdr IS

PORT(

Clk : IN bit; -- Clock do sistema

Reset : IN bit; -- Reset load : in bit; -- carrega

N : IN bit_vector (1 downto 0); --

Quantidade de deslocamentos

Entrada : IN bit_vector (31 downto 0); -- Vetor a ser deslocado

Saida : OUT bit_vector (31 downto 0) -- Vetor deslocado );

END mdr;

-- Arquitetura que define o comportamento do registrador de deslocamento -- Simulation

ARCHITECTURE behavioral_arch OF mdr IS

-- signal temp : bit_vector (31 downto 0); -- Vetor temporário begin

-- Clocked process process (Clk, Reset)

begin

if(Reset = '1') then

(57)

Saida (18) <= Entrada(15);

Saida (19) <= Entrada(15);

Saida (20) <= Entrada(15);

Saida (21) <= Entrada(15);

Saida (22) <= Entrada(15);

Saida (23) <= Entrada(15);

Saida (24) <= Entrada(15);

Saida (25) <= Entrada(15);

Saida (26) <= Entrada(15);

Saida (27) <= Entrada(15);

Saida (28) <= Entrada(15);

Saida (29) <= Entrada(15);

Saida (30) <= Entrada(15);

Saida (31) <= Entrada(15);

when "10" => --

Deslocamento à direita aritmético 24 vezes

Saida (7 downto 0) <=

Entrada(7 downto 0);

Saida (8) <= Entrada(7);

Saida (9) <= Entrada(7);

Saida (10) <= Entrada(7);

Saida (11) <= Entrada(7);

Saida (12) <= Entrada(7);

Saida (13) <= Entrada(7);

Saida (14) <= Entrada(7);

Saida (15) <= Entrada(7);

Saida (16) <= Entrada(7);

Saida (17) <= Entrada(7);

Saida (18) <= Entrada(7);

Saida (19) <= Entrada(7);

Saida (20) <= Entrada(7);

Saida (21) <= Entrada(7);

Saida (22) <= Entrada(7);

Saida (23) <= Entrada(7);

Saida (24) <= Entrada(7);

Saida (25) <= Entrada(7);

Saida (26) <= Entrada(7);

Saida (27) <= Entrada(7);

Saida (28) <= Entrada(7);

Saida (29) <= Entrada(7);

Saida (30) <= Entrada(7);

Saida (31) <= Entrada(7);

when others =>

end case;

end if;

end if;

--Saida <= temp;

end process;

END behavioral_arch;

(58)

multidiv.vhd

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

entity multiDiv is port(

clk :in bit;

start :in bit;

selecao :in bit;

entrada1 :in bit_vector(31 downto 0);

entrada2 :in bit_vector(31 downto 0);

Hi :out bit_vector(31 downto 0);

Lo :out bit_vector(31 downto 0);

divZero :out bit;

terminou :out bit );

end multiDiv;

architecture behavioral_arc of multiDiv is component ula32

port(

A :in bit_vector(31 downto 0);

B :in bit_vector(31 downto 0);

seletor :in bit_vector(2 downto 0);

S :out bit_vector(31 downto 0) );

end component;

type state is (inicio, --manda o sinal para o bit menos significativo teste, --testa o meio se for necessario, soma e subtrai

shiftR, --shift a direita logico, tb verifica se ja acabou os 32 bits(multiplicacao)

shiftL, --shift a esquerda do remainder todo

subtract, --subtrai o divisor da parte esq. do remainder testRem, --testa se o remainder < 0 e processa as operacoes de acordo com o resultado.

shiftGambiarra, --(vai mudar)

(59)

signal divMult : std_logic_vector(31 downto 0); --usado na multiplicacao e na divisao.Funciona como divisor

begin

--ou como multiplicando.

process(clk, start)

variable cont : integer;

begin

if(clk'event and clk = '1') then if (start = '1') then

if(entrada2(31 downto 0) = "00000000000000000000000000000000") then

divZero <= '1';

terminou <= '1';

current <= zerarTerminou;

else current <= inicio;

terminou <= '0';

divZero <= '0';

cont := 0;

end if;

else

case current is

when inicio => --estado inicial sempre

cont := 0;

if (selecao = '0') then prodRem(0) <= '0';

prodRem(64 downto 33) <=

"00000000000000000000000000000000";

prodRem(32 downto 1) <= To_StdLogicVector(en- trada2);

divMult <= To_StdLogicVector(entrada1);

current <= teste;

else

if(entrada1(31) = '1') then --***********verifica os sinais

if(entrada2(31) = '1') then current <= soRem;

else

current <= osDois;

end if;

else

if(entrada2(31) = '1') then current <= soQuo;

else

current <= shiftL;

end if;

end if;

prodRem(64 downto 33) <=

"00000000000000000000000000000000";

(60)

divMult <= To_StdLogicVector(entrada2);

end if;

when teste => --testa o meio ***********comeca os estados da multiplicacao

cont := cont + 1;

if (prodRem(1 downto 0) = "00" or prodRem(1 downto 0) = "11") then

current <= shiftR;

elsif (prodRem(1 downto 0) = "01") then

prodRem(64 downto 33) <= divMult + prodRem(64 downto 33);

current <= shiftR;

else

prodRem(64 downto 33) <= prodRem(64 downto 33) - divMult;

current <= shiftR;

end if;

when shiftR =>

prodRem(63 downto 0) <= prodRem(64 downto 1);

prodRem(64) <= prodRem(64);

if(cont = 32) then current <= fim;

else

current <= teste;

end if;

--********acaba os estados da multiplicacao

when shiftL => --

********comeca os estados da divisao

prodRem(64 downto 2) <= prodRem(63 downto 1);

prodRem(1) <= '0';

current <= subtract;

when subtract =>

cont := cont + 1;

prodRem(64 downto 33) <= prodRem(64 downto 33) - divMult;

current <= testRem;

when testRem =>

if(prodRem(64) = '0') then

Referências

Documentos relacionados

Tendo como base os resultados gerados pela execução da atividade de alocação de recursos humanos em um projeto de software através da ferramenta proposta neste

Logo, ao analisarmos os Princípios Constitucionais que formam o Estatuto Mínimo do Contribuinte, é necessário olharmos não apenas para a norma, mas também para a

Portanto, o trabalho proposto tem como objetivo demonstrar o estado nutricional de idosos hospitalizados, de ambos os sexos, com idade entre 60 a 95 anos, por meio da

O pagamento do valor da arrematação deverá ser efetuado à vista, ou parcelado mediante o pagamento de pelo menos 25,00% (vinte e cinco por cento) do lance à vista em até 48hs

Na Universidade do Sul de Santa Catarina – Unisul, a idéia principal do ensino destes sistemas consiste em estudar a integração das informações e processos entre as diversas

This data was used to determine the intra-observer (test-retest) reliability by calculating the Cohen’s Kappa (statistical measure for assessing the reliability of agreement

Para separação de água/óleo a membrana recoberta internamente com filme de PEBD contendo 5% de argila organofílica em peso se mostrou mais seletiva do que a

 Consistem na parte mais importante de uma estratégia de SEM, não apenas para a otimização interna do website como também para as estratégias de links patrocinados, na