UFPEcin.ufpe.br/~dllaa/relatorio.doc  · Web view- CENTRO DE INFORMÁTICA - PROFA. DRA. EDNA...

92
UNIVERSIDADE FEDERAL DE PERNAMBUCO - CENTRO DE INFORMÁTICA - PROFA. DRA. EDNA NATIVIDADE BARROS CADEIRA DE INFRA-ESTRUTURA DE HARDWARE RELATÓRIO DE DESENVOLVIMENTO: CPU ARQUITETURA MIPS, 32 BITS Sumário

Transcript of UFPEcin.ufpe.br/~dllaa/relatorio.doc  · Web view- CENTRO DE INFORMÁTICA - PROFA. DRA. EDNA...

UNIVERSIDADE FEDERAL DE PERNAMBUCO

- CENTRO DE INFORMÁTICA -

PROFA. DRA. EDNA NATIVIDADE BARROS

CADEIRA DE INFRA-ESTRUTURA DE HARDWARE

Instruction

Registers

Write

register

Read

data1

Read

data2

Read

register1

Read

register2

Write

data

RegWrite

Instruction

Registers

Write

register

Read

data1

Read

data2

Read

register1

Read

register2

Write

data

RegWrite

RELATÓRIO DE DESENVOLVIMENTO:

CPU ARQUITETURA MIPS, 32 BITS

Sumário

1.Equipe de desenvolvimento

2.Concepção do Projeto

2.1 Introdução

2.2 Objetivos

2.3 Recursos Utilizados

2.3.1 Recursos Humanos

2.3.2 Recursos de Software

2.3.3 Recursos de Hardware

3.Especificação do Projeto

3.1 Repertório de Instruções

3.2 Formato das Instruções

3.2.1 Formato F1

3.2.2 Formato F2

3.2.3 Formato F3

4.Unidade de Processamento

4.1 Módulos concedidos

4.1.1 Memória 256 bytes

4.1.2Banco de Registradores

4.1.3Registrador de Instruções

4.1.4Registrador de Deslocamento

4.1.5Unidade Lógica e Aritmética

4.1.6 Registrador comum de dados, 32 bits

4.1.7 RegistradorDesl

4.2 Módulos Desenvolvidos:

4.2.1 Desl2vezes26

4.2.2 Desl2vezes32

4.2.3 ExtensorLUI

4.2.4 Extensor1

4.2.5 Extensor5

4.2.6 Extensor8

4.2.7 Extensor16

4.2.8 StoreBH

4.2.9 MultDiv

4.3 Módulos Auxiliares

4.3.1 mux21

4.3.2 Mux21Cond

4.3.3 mux2_Ndesl

4.3.4 mux21Ext8

4.3.5 mux41

4.3.6 mux41_RegWrite

4.3.7 mux41Ext16

4.3.8 mux81

4.4 Mapeamento da Unidade de Processamento

4.4.1 Codificação do Mapeamento da CPU

4.4.2 Unidade de Controle

5. Referências

1.Equipe de desenvolvimento

__________________________________Rebeka Gomes de Oliveira

- Ciências da Computação

__________________________________

Durval Augusto Lira Queiroz dos Santos

< [email protected] > - Ciências da Computação

__________________________________

David Levy Lucena Alves Aragão

< [email protected] > - Ciências da Computação

__________________________________

Viviane Eugênia Siqueira de Souza

< [email protected] > - Ciências da Computação

2. Concepção do Projeto

2.1 Introdução

O projeto aqui apresentado refere-se à implementação de uma unidade central de processamento de 32 bits, baseada na arquitetura MIPS. Para o desenvolvimento deste projeto fez-se uso da ferramenta QUARTUS II 3.0 da Altera, utilizando a linguagem VHDL (Very High Speed Integrated Circuit Hardware Description Language), a qual descreve o comportamento e a arquitetura do hardware.

A arquitetura MIPS tem sido usada em larga escala por empresas de grande porte da área de sistemas embarcados como BroadCom, Cisco, Sony, NEC, Phillips e Toshiba. Como exemplo A MIPS Technologies, uma das líderes da indústria de arquitetura de processadores para aplicações residenciais e comerciais, anunciou ontem que a arquitertura do seu processador MIPS64 foi licenciada pela Sony Computer Entertainment Inc. (SCEI). Como já é fato, a SCEI sempre foi uma das maiores usuárias da tecnologia MIPS, usada largamente nos produtos da série PlayStation. O PlayStation 2, por exemplo, possui dois processadores desse tipo, incluindo o EmotionEngine de 128-Bits.

Uma das maiores características do processador MIPS é a regularidade, fator que contribui para sua relativa simplicidade.

Essa simplicidade da arquitetura MIPS, um reconhecimento no âmbito comercial, fazendo com que vertentes comerciais façam relevantes investimentos no tocante a desenvolvimentos baseados na mesma.

Dentre outras, algumas caracteristicas pode-se ser ressaltadas, tais como:viabilidade econômica, baixo consumo de potência, eficiência em aplicações pesadas de software e compatibilidade com sistemas de tempo real.

Portanto, este material apesar da natureza acadêmica, reflete uma realidade que pode ser aproveitada num contexto comercial.

2.2 Objetivos

O seguinte projeto, é referente à implementação de um processador MIPS, requerido para avaliação da disciplina de Graduação Infra Estrutura de Hardware, ministrada pela professora Dra. Edna Natividade Barros.

O desenvolvimento do mesmo possibilita o aprendizado, na prática, de uma tecnologia brevemente elucidada na introdução. E, através desse relatório, são apresentadas de maneira detalhada todas as atividades realizadas, bem como os componentes desenvolvidos. É também detalhada a maneira com a qual o processador funciona e seus principais fundamentos..

2.3 Recursos utilizados

2.3.1- Recursos Humanos:

O pessoal alocado para o desenvolvimento do projeto contemplou a prof. Dra. Edna Natividade Barros, com o acompanhamentos periodicos, o monitor Cássio e a seguinte equipe de graduandos em Ciências da Computação:

Rebeka Gomes de Oliveira

Viviane Souza

David Aragão

Durval Augusto Lira

2.3.2 - Recursos de Software:

Microsoft Windows XP Professional - Microsoft Word

Quartus II 3.0

3.Especificação do Projeto

O trabalho consiste na implementação de um Sistema que simule uma CPU,na arquitetura MIPS. O sistema consiste de 32 registradores de 32 bits cada, organizados em uma estrutura a qual se convencionou chamar Banco de Registradores. É fornecido um componente de Memória, com a capacidade de armazenamento de 256 bytes; a palavra de processamento no sistema é um vetor de 32 bits; todas as instruções com que trabalha o processador têm comprimento de 32 bits; a entidade a ser produzida deve processar números de 32 bits, escritos na notação complemento a dois; deve haver suporte a tratamento de exceções; deve haver suporte a rotinas reentrantes e recursivas por meio de utilização do apontador da pilha.

A parte que começa a partir de agora, considerará todos os aspectos mencionados na sucinta descrição de acima. Imediatamente a seguir, foi colocada uma descrição particular e pormenorizada de cada instrução implementada pela unidade central de processamento. Logo após, os formatos de instrução permitidos são especificados em detalhes, contribuindo positivamente especificação da atividade realizada.

3.1Repertório de Instruções

O repertório de instruções a ser implementado é um subconjunto da definição amplamente conhecida do MIPS. Concentra-se nas instruções básicas de referência à memória, operações lógico-aritméticas, desvio e deslocamento. Foram exigidas as operações de multiplicação e divisão para inteiros, não se tornando obrigatório, porém, o suporte ao trabalho com números de ponto-flutuante. As tabelas abaixo apresentam de forma breve o conjunto de instruções em consideração. Em sua estrutura, é apresentado o nome da instrução, seu mnemônico assembly para a maioria dos compiladores de linguagem de máquina, o resumo de sua atividade em notação matemática informal e a descrição breve de sua atuação em linguagem humana escrita.

Descrição geral das instruções implementadas

No Operation

nop: no operation

Executa nenhuma operação por ocasião de sua chamada. Durante um ciclo inteiro de relógio, o dispositivo permanece inerte. Útil em diversos contextos, é instrução fundamental, presente no desenvolvimento de qualquer processador.

Load Word

Lw reg, desl(reg_base): reg = (Memory[reg_base + desl])

Carrega o conteúdo de memória à posição indicada pelo conteúdo do registrador base somado do deslocamento passado como constante no registrador cujo número é especificado.

Store Word

sw reg, desl(reg_base): Memory[reg_base + desl] = reg

Armazena o conteúdo do registrador cujo número é especificado na posição de memória indicada pelo conteúdo do registrador base somado do deslocamento passado como constante.

Load Byte

lb reg, desl(reg_base): reg[7-0] = (Memory[reg_base + desl][7-0])

Carrega byte mais significativo do conteúdo de memória à posição indicada pelo conteúdo do registrador base somado do deslocamento passado como constante no registrador cujo número é especificado.

Load Half

lh reg, desl(reg_base): reg[15-0] = (Memory[reg_base + desl][15-0])

Carrega a meia palavra mais significativa do conteúdo de memória à posição indicada pelo conteúdo do registrador base somado do deslocamento passado como constante no registrador cujo número é especificado.

Store Byte

sb reg, desl(reg_base): Memory[reg_base + desl][7-0] = reg[7-0]

Armazena o byte mais significativo do conteúdo do registrador cujo número é especificado na posição de memória indicada pelo conteúdo do registrador base somado do deslocamento passado como constante.

Store Half

sh reg, desl(reg_base): Memory[reg_base + desl][15-0] = reg[15-0]

Armazena a meia palavra mais significativa do conteúdo do registrador cujo número é especificado na posição de memória indicada pelo conteúdo do registrador base somado do deslocamento passado como constante.

Load Upper Immediate

Lui reg, constante: reg[31-16] = constante

Carrega o valor constante de 16 bits passado como parâmetro na metade mais significativa do registrador cujo número é indicado.

Move High

mfhi rd: rd = (reg_hi)

Move o conteúdo do registrador específico REG_HI, de 32 bits, para o registrador cujo número é indicado como parâmetro da instrução.

Move Low

mflo rd: rd = (reg_lo)

Move o conteúdo do registrador específico REG_LO, de 32 bits, para o registrador cujo número é indicado como parâmetro da instrução.

Addition

add regi, regj, regk: regi = (regj) + (regk)

Coloca no registrador cujo número é passado inicialmente, o resultado da soma do conteúdo dos registradores cujos números são indicados em posição posterior. A Unidade de Controle é sensível ao caso de estouro de caixa, conhecido pela expressão inglesa overflow.

Subtraction

sub regi, regj, regk: regi = (regj) - (regk)

Coloca no registrador cujo número é passado inicialmente, o resultado da operação de subtração entre o conteúdo dos registradores cujos números são indicados em posição posterior. A Unidade de Controle é sensível ao caso de estouro de caixa, conhecido pela expressão inglesa overflow.

Xor Operation

xor regi, regj, regk: regi = (regj) xor (regk)

Coloca no registrador cujo número é passado inicialmente, o resultado da operação de OU exclusivo lógico entre o conteúdo dos registradores cujos números são indicados em posição posterior.

And Operation

and regi, regj, regk: regi = (regj) and (regk)

Coloca no registrador cujo número é passado inicialmente, o resultado da operação de AND lógico entre o conteúdo dos registradores cujos números são indicados em posição posterior.

Addition Unsigned

addu regi, regj, regk: regi = (regj) + (regk)

Coloca no registrador cujo número é passado inicialmente, o resultado da operação aritmética de adição entre o conteúdo dos registradores cujos números são indicados em posição posterior. A Unidade de Controle não considera o caso de estouro de caixa, conhecido pela expressão inglesa overflow.

Subtraction Unsigned

subu regi, regj, regk: regi = (regj) - (regk)

Coloca no registrador cujo número é passado inicialmente, o resultado da operação aritmética de subtração entre o conteúdo dos registradores cujos números são indicados em posição posterior. A Unidade de Controle não considera o caso de estouro de caixa, overflow.

Addition Immediate

addi regi, regj, constant: regi = (regj) + constant

Coloca no registrador cujo número é passado inicialmente, o resultado da operação aritmética de adição entre o conteúdo do registrador passado em segundo lugar e o valor constante passado como parâmetro da instrução. A Unidade de Controle é sensível ao caso de estouro de caixa, overflow.

Addition Immediate Unsigned

addiu regi, regj, constant: regi = (regj) + Constant

Coloca no registrador cujo número é passado inicialmente, o resultado da operação aritmética de adição entre o conteúdo do registrador passado em segundo lugar e o valor constante passado como parâmetro da instrução. A Unidade de Controle não considera o caso de estouro de caixa, overflow.

And Operation Immediate

andi regi, regj, constant: regi = (regj) and constant

Coloca no registrador cujo número é passado inicialmente, o resultado da operação de AND lógico entre o conteúdo do registrador passado em segundo lugar e o valor constante passado como parâmetro da instrução.

Xor Operation Immediate

xori regi, regj, constant: regi = (regj) xori Constant

Coloca no registrador cujo número é passado inicialmente, o resultado da operação de OU exclusivo lógico entre o conteúdo do registrador passado em segundo lugar e o valor constante passado como parâmetro da instrução.

Multiplication

mult rs, rt: reg_hi=reg_lo = rs x rt

Coloca nos registradores específicos REG_HI e REG_LO, respectivamente, a parte mais significativa e a menos significativa da operação aritmética de multiplicação entre o conteúdo dos registradores cujos números são passados como parâmetros da instrução.

Division

Div rs, rt: reg_hi = rs/rt (quociente), reg_lo = (resto da divisão)

Coloca nos registradores específicos REG_HI e REG_LO, respectivamente, o quociente e o resto da operação aritmética de divisão inteira entre o conteúdo dos registradores cujos números são passados como parâmetros da instrução.

Shift Right Artithmetic

Sra regd, regd, n: rd = shift(regs, n)

Coloca no registrador cujo número é passado inicialmente, o resultado da operação de deslocamento aritmético à direita no vetor de 32 bits contido no registrador cujo número é indicado. O número de deslocamentos a serem realizados, contido no intervalo fechado de 0 a 32, é passado como o terceiro parâmetro da instrução.

Shift Right Logical

srl regd, regd, n: rd = shift(regs, n)

Coloca no registrador cujo número é passado inicialmente, o resultado da operação de deslocamento lógico à direita no vetor de 32 bits contido no registrador cujo número é indicado. O número de deslocamentos a serem realizados, contido no intervalo fechado de 0 a 32, é passado como o terceiro parâmetro da instrução.

Shift Left Logical

sll regd, regd, n: rd = shift(regs, n)

Coloca no registrador cujo número é passado inicialmente, o resultado da operação de deslocamento lógico à esquerda no vetor de 32 bits contido no registrador cujo número é indicado. O número de deslocamentos a serem realizados, contido no intervalo fechado de 0 a 32, é passado como o terceiro parâmetro da instrução.

Branch on Equal

beq regi, regj, desl: PC = PC + (desl * 4) (if regj = regk)

Implementa o desvio condicional do contador do programa. Caso o conteúdo dos registradores cujos números são passados como parâmetro for igual, o registrador contador do programa é desviado de tantas instruções quanto o número indicado no conteúdo constante do campo deslocamento, de 16 bits, passado como parâmetro.

Branch if Not Equal

bne regi, regj, desl: PC = PC + (desl * 4) (if regj != regk)

Implementa de outra forma o desvio condicional do contador do programa. Caso os conteúdos dos registradores cujos números são passados como parâmetro forem iguais, o registrador contador do programa é desviado de tantas instruções quanto o número indicado no conteúdo constante do campo deslocamento, de 16 bits, passado como parâmetro.

Set if Less Than

slt regi, regj, regk: regi = 1 if regj < regk and regi = 0 otherwise

Marca o registrador cujo número é indicado inicialmente com o valor 1, caso os registradores cujos números indicados posteriormente contiverem valores iguais e com 0, caso contrário.

Set if Less Than Immediate

slti regi, regj, constant: regi = 1 if regj < constant and regi = 0 otherwise

Marca o registrador cujo número é indicado inicialmente com o valor 1, caso o registrador cujo número é indicado posteriormente contiver valor igual ao da constante passada como parâmetro da instrução e com 0, caso contrário.

Jump

J end: PC = end

Implementa o desvio absoluto do contador do programa. A chamada a jump faz com que o registrador contador do programa receba o valor de 26 bits passado como parâmetro da instrução. Embora o desvio seja absoluto, os 4 bits mais significativos do contador do programa são mantidos. A instrução jump, portanto, não utiliza todo o potencial de endereçamento de memória de 232 referências, utilizando, apenas, um espaço de 226 posições de grupo.

Return from Exception

rte: retorna ao ponto do programa onde houve uma exceção

Dada a ocorrência de uma exceção, o processador faz o registrador contador do programa apontar para uma posição de memória fixa que armazena o endereço efetivo das rotinas específicas de tratamento de exceção. Cada exceção exige uma rotina particular. Ao término da execução desses procedimentos compensatórios, o processador deve retornar ao exato ponto do programa em que ocorreu a exceção. Esse retorno é executado pela chamada da instrução rte.

Break

break: pára a execução do programa (desativa o processador)

A chamada break implementa a saída do caso de exceção impensada, não tratável e crítica do processador. Realiza a parada abrupta da execução de um programa, colocando o dispositivo em um estado de inatividade contínua, do qual se retira apenas pelo reinício das atividades de todo o sistema, indicado pela negação da energia motriz. Por ser também útil em circunstâncias diversas, é padrão na arquitetura de computadores.

Jump Register

j reg: PC = (reg)

Implementa o desvio absoluto completo do contador do programa. A chamada a jump register faz com que o registrador contador do programa receba o valor de 32 bits contido no registrador cujo número é passado como parâmetro da instrução. Neste caso, todo o espaço de endereçamento é utilizado, sendo claramente possível a realização de 232 referências a endereços de memória. Observação importante: não é seguro realizar-se referências aleatórias a posições de memória mediante a permuta e uso das instruções jump e jump register.

Jump and Link

jal end: R31 = PC; PC = end

Implementa outra forma de desvio absoluto completo do contador do programa. A chamada a jump and link permite que o registrador contador do programa receba o valor constante de 26 bits passado como parâmetro da instrução, exatamente como no caso da instrução jump. A diferença significativa encontra-se unicamente no fato de que, neste caso, o valor atual do registrador contador do programa é salvo no registrador específico de número 31, da arquitetura. Essa medida facilita a implementação de chamadas seriais e reentrantes de alto nível de grau 1.

3.2Formato das Instruções

A máquina colocada em funcionamento seguiu o padrão internacional MIPS para formatos de instruções. Segundo essa especificação clara, visando ao favorecimento da regularidade, e tendo em vista que uma boa arquitetura demanda compromisso, todas as instruções devem conter o mesmo tamanho de 32 bits. Os seis bits iniciais são impreterivelmente reservados para a indicação do código da operação, conhecido mais amplamente pelo designativo abreviado”opcode” (do inglês, operation code). Essa medida proporciona extrema simplicidade ao processo interno de decodificação das instruções, reduzindo significativamente a complexidade, tamanho e custo da unidade de processamento e de controle.

De acordo com a definição, há três formatos possíveis de dados nas instruções implementadas pela arquitetura. Em todos os casos, os campos reservados para se fazer referência a registradores específicos do banco de registradores são secções com o comprimento de 5 bits. Trata-se de algo somente esperado, uma vez que o número total de registradores no banco é 32. No tocante a outros campos em particular, há explicações específicas para cada caso; serão consideradas, portanto, as situações individualmente.

3.2.1 Formato F1

O primeiro formato de instruções apresenta a seguinte disposição:

6 bits

5 bits

5 bits

5 bits

5 bits

6 bits

opcode

Rs1

rs2

rd

shamt

funct

Utilizado em todas as instruções aritméticas e lógicas que não envolvam constantes, instruções de deslocamento, de desvio absoluto completo (jump register) e nas instruções de carregamento dos registradores REG_HI e REG_LO (mfhi e mflo), o formato F1 apresenta a disposição mais geral para as instruções implementadas.

Nas instruções aritméticas e lógicas, o campo rs1 indica o número do primeiro registrador operando, o campo rs2 o número do segundo registrador operando e o campo rd o número do registrador destino da operação. Em seu conteúdo será colocado o resultado do que foi analisado pela instrução.

O campo shamt é somente utilizado pelas instruções de deslocamento em vetores de bits, sendo representativo do número de deslocamentos a serem realizados na especificação do projeto esse campo possui 5 bits mas poderia inclusive possuir menos bits.

Em todo caso de instruções aritméticas, deve ser analisado o campo funct pela Unidade de Controle. Indicando a funcionalidade, estabelece a diferença para os casos de instruções com o mesmo código de operação. Trata-se de uma decisão de implementação por parte dos projetistas do MIPS: todas as instruções aritméticas possuem o mesmo código de operação. A distinção se dá pelo campo da funcionalidade.

3.2.2 Formato F2

O segundo possível para a cadeia de bits recebida como instrução por parte do processador implementado é o seguinte:

6 bits

5 bits

5 bits

16 bits

opcode

rs1

rs2

Deslocamento

As instruções que utilizam o formato F2 são todas as de referência à memória, todas as que manipulam constantes e as de desvio condicional relativo (beq e bne).

No caso das que fazem referência à memória para carregamento em registrador (load word, load byte, load half), o campo rs1 indica o número do registrador base da operação e o campo rs2 o número do registrador no qual se deseja carregar o valor armazenado na memória; o campo deslocamento, de 16 bits, armazena o número a ser somado ao valor contido no registrador base para que se encontre a posição de memória na qual há o dado a ser carregado para o registrador. Para as instruções de referência à memória para escrita (store word, store byte, store half) rs2 indica o registrador fonte dos dados para escrita.

A manipulação de constantes é feita por meio do campo deslocamento, sendo nele colocado o dado a ser tratado.

Quanto às instruções de desvio condicional, rs1 indica o número do registrador que armazena o primeiro valor operando para a verificação, rs2 o número do segundo registrador operando e deslocamento o número de instruções a serem desviadas caso o resultado da análise seja positivo.

3.2.3 Formato F3

O terceiro e último formato permitido para instruções na arquitetura em consideração é o seguinte:

6 bits

26 bits

opcode

Deslocamento

O formato F3 é utilizado para a representação de instruções de desvio absoluto incompleto (instruções jump e jump and link).

Em ambos os casos, o campo deslocamento é utilizado para armazenar o número constante passado como parâmetro para o qual deve apontar o registrador contador do programa (program counter, PC). Visto que PC possui, como todo registrador da arquitetura, 32 bits, a estratégia para implementação dessas instruções consiste em estender os 26 bits recebidos para 28, por meio da operação de deslocamento duplo à esquerda (o equivalente à multiplicação por quatro do valor decimal) e concatená-los aos 4 bits mais significativos do PC.

Desse modo, o formato de instrução F3 é o de menor amplitude dentre os três.

4. Unidade de Processamento

A parte inicial do projeto consistiu da estruturação completa da unidade de processamento do sistema a ser implementado incluindo seus componentes. O grupo recebeu da equipe coordenadora uma versão significativamente limitada do datapath a ser produzido. A estrutura fornecida implementava 6 (seis) instruções da arquitetura MIPS. Como primeira etapa, o grupo deveria estendê-la de modo a que fosse capaz de executar todas as 34 apresentadas na especificação oficial fazendo as alterações nescessárias..

De acordo com a orientação a descrição foi realizada nos moldes tradicionais, escrita por lápis em papel cartolina e apresentada como desenho preliminar à equipe de ensino da cadeira vinculada ao trabalho, do Centro de Informática da UFPE. A metodologia sugerida mostrou-se efetivamente prática, dado que o trabalho de construção realizado dessa forma proporciona um nível agradável de abstração quanto à complexidade do modelo teórico de um computador, a saber, o conceito de uma máquina de estados relativamente grande. De modo o trabalho se deu da seguinte forma:

- tomou-se o modelo inicial e limitado de projeto da arquitetura MIPS fornecido pela equipe de ensino (veja a figura 2.1);

- como forma de estudo da versão limitada da unidade de processamento concedida, analisou-se cuidadosamente o fluxo de execução de cada instrução implementada pela estrutura concedida;

- ao término da análise, tomou-se o repertório de instruções extras a serem implementadas e verificou-se, uma a uma, quais as alterações necessárias a serem produzidas na estrutura fornecida para que todas pudessem ser executadas quando o sistema fosse posto em funcionamento.

S

h

i

f

t

l

e

f

t

2

P

C

M

u

x

0

1

R

e

g

i

s

t

e

r

s

W

r

i

t

e

r

e

g

i

s

t

e

r

W

r

i

t

e

d

a

t

a

R

e

a

d

d

a

t

a

1

R

e

a

d

d

a

t

a

2

R

e

a

d

r

e

g

i

s

t

e

r

1

R

e

a

d

r

e

g

i

s

t

e

r

2

I

n

s

t

r

u

c

t

i

o

n

[

1

5

1

1

]

M

u

x

0

1

M

u

x

0

1

4

I

n

s

t

r

u

c

t

i

o

n

[

1

5

0

]

S

i

g

n

e

x

t

e

n

d

3

2

1

6

I

n

s

t

r

u

c

t

i

o

n

[

2

5

2

1

]

I

n

s

t

r

u

c

t

i

o

n

[

2

0

1

6

]

I

n

s

t

r

u

c

t

i

o

n

[

1

5

0

]

I

n

s

t

r

u

c

t

i

o

n

r

e

g

i

s

t

e

r

A

L

U

c

o

n

t

r

o

l

A

L

U

r

e

s

u

l

t

A

L

U

Z

e

r

o

M

e

m

o

r

y

d

a

t

a

r

e

g

i

s

t

e

r

A

B

I

o

r

D

M

e

m

R

e

a

d

M

e

m

W

r

i

t

e

M

e

m

t

o

R

e

g

P

C

W

r

i

t

e

C

o

n

d

P

C

W

r

i

t

e

I

R

W

r

i

t

e

A

L

U

O

p

A

L

U

S

r

c

B

A

L

U

S

r

c

A

R

e

g

D

s

t

P

C

S

o

u

r

c

e

R

e

g

W

r

i

t

e

C

o

n

t

r

o

l

O

u

t

p

u

t

s

O

p

[

5

0

]

I

n

s

t

r

u

c

t

i

o

n

[

3

1

-

2

6

]

I

n

s

t

r

u

c

t

i

o

n

[

5

0

]

M

u

x

0

2

J

u

m

p

a

d

d

r

e

s

s

[

3

1

-

0

]

I

n

s

t

r

u

c

t

i

o

n

[

2

5

0

]

2

6

2

8

S

h

i

f

t

l

e

f

t

2

P

C

[

3

1

-

2

8

]

1

1

M

u

x

0

3

2

M

u

x

0

1

A

L

U

O

u

t

M

e

m

o

r

y

M

e

m

D

a

t

a

W

r

i

t

e

d

a

t

a

A

d

d

r

e

s

s

Figura 2.1 Unidade de Processamento parcial, concedida.

4.1 Módulos concedidos

A seção que se inicia apresentará exatamente quais blocos da unidade foram concedidos à equipe de desenvolvimento. Neste sentido, ficará completamente evidente a qualquer observador atento o caráter eminentemente didático do trabalho.

Contudo, é fundamental que seja colocado que o espaço de tempo exigido para a conclusão geral das atividades foi de um mês, incluso neste intervalo toda as atividades de análise, projeto, implementação e testes, bem como a edição deste relatório de desenvolvimento. Fica claro, portanto, que a disposição dos módulos expostos a seguir não é informação que restringe o grupo de capacidades ou operabilidades. Trata-se de necessidade puramente situacional.

4.1.1 Memória 256 bytes

O componente representativo da Memória Principal de um sistema de computação concedido para a implementação sistema que inclui a Unidade Central de Processamento em desenvolvimento trabalha com palavras de 32 bits e possui endereçamento por byte. Apesar de o endereço possuir 32 bits, a memória só possui 256 bytes. As entradas e saídas da memória são: a entrada de dados da memória (32 bits), utilizada para o procedimento de escrita; o endereço de entrada da memória (32 bits), colocado para o recebimento do conteúdo à posição indicada; o sinal de escrita, que informa se o procedimento ativo é leitura ou escrita no componente; o clock do sistema; e a saída de Dados da memória (32 bits), informando o conteúdo à posição indicada.

A

B

S

Z

N

O

EQ

LT

GT

ALU

32

32

32

Figura 2.2 Memória 256 bytes com endereçamento por byte

O código VHDL da Memória é apresentado logo a seguir.

--------------------------------------------------------------------------------

-- Title

: Memória da CPU

-- Project

: CPU Multi-ciclo

--------------------------------------------------------------------------------

-- File

: Memoria.vhd

-- Author

: Emannuel Gomes Macêdo

--

Fernando Raposo Camara da Silva

--

Pedro Machado Manhães de Castro

--

Rodrigo Alves Costa

-- Organization : Universidade Federal de Pernambuco

-- Created

: 26/07/2002

-- Last update: 23/11/2002

-- Plataform: Flex10K

-- Simulators: Altera Max+plus II

-- Synthesizers:

-- Targets

:

-- Dependency:

--------------------------------------------------------------------------------

-- Description: Entidade responsável pela leitura e escrita em memória.

--------------------------------------------------------------------------------

-- Copyright (c) notice

--

Universidade Federal de Pernambuco (UFPE).

--

CIn - Centro de Informatica.

--

Developed by computer science undergraduate students.

--

This code may be used for educational and non-educational purposes as

--

long as its copyright notice remains unchanged.

--------------------------------------------------------------------------------

-- Revisions

: 1

-- Revision Number: 1.0

-- Version

: 1.1

-- Date

: 23/11/2002

-- Modifier

: Marcus Vinicius Lima e Machado

--

Paulo Roberto Santana Oliveira Filho

--

Viviane Cristina Oliveira Aureliano

-- Description

:

--------------------------------------------------------------------------------

package ram_constants is

constant DATA_WIDTH : INTEGER := 8;

constant ADDR_WIDTH : INTEGER := 8;

constant INIT_FILE : STRING := "ram_instrucoes.mif";

end ram_constants;

--*************************************************************************

library IEEE;

use IEEE.std_logic_1164.all;

USE ieee.std_logic_arith.all;

library lpm;

use lpm.lpm_components.all;

library work;

use work.ram_constants.all;

--*************************************************************************

--Short name: mem

ENTITY Memoria IS

PORT(

Address: IN BIT_VECTOR(31 DOWNTO 0);-- Endereço de memória a ser lido

Clock: IN BIT;

-- Clock do sistema

Wr

: IN BIT;

-- Indica se a memória será lida (0) ou escrita (1)

Dataout: OUT BIT_VECTOR (31 DOWNTO 0);-- Valor a ser escrito quando Wr = 1

Datain: IN BIT_VECTOR(31 DOWNTO 0)-- Valor lido da memória quando Wr = 0

);

END Memoria;

-- Arquitetura que define o comportamento da memória

-- Simulation

ARCHITECTURE behavioral_arch OF Memoria IS

signal add

: bit_vector(7 downto 0);

signal addS0

: STD_LOGIC_VECTOR (ADDR_WIDTH-1 DOWNTO 0);

signal addS1

: STD_LOGIC_VECTOR (ADDR_WIDTH-1 DOWNTO 0);

signal addS2

: STD_LOGIC_VECTOR (ADDR_WIDTH-1 DOWNTO 0);

signal addS3

: STD_LOGIC_VECTOR (ADDR_WIDTH-1 DOWNTO 0);

signal dataoutS

: STD_LOGIC_VECTOR (31 DOWNTO 0);

signal datainS

: STD_LOGIC_VECTOR (31 DOWNTO 0);

signal dataoutS0: STD_LOGIC_VECTOR (DATA_WIDTH-1 DOWNTO 0);

signal dataoutS1: STD_LOGIC_VECTOR (DATA_WIDTH-1 DOWNTO 0);

signal dataoutS2: STD_LOGIC_VECTOR (DATA_WIDTH-1 DOWNTO 0);

signal dataoutS3: STD_LOGIC_VECTOR (DATA_WIDTH-1 DOWNTO 0);

signal datainS0

: STD_LOGIC_VECTOR (DATA_WIDTH-1 DOWNTO 0);

signal datainS1

: STD_LOGIC_VECTOR (DATA_WIDTH-1 DOWNTO 0);

signal datainS2

: STD_LOGIC_VECTOR (DATA_WIDTH-1 DOWNTO 0);

signal datainS3

: STD_LOGIC_VECTOR (DATA_WIDTH-1 DOWNTO 0);

signal wrS

: STD_LOGIC;

signal clockS

: STD_LOGIC;

signal add0

: integer;

signal add2

: integer;

signal add1

: integer;

signal add3

: integer;

signal addu

: unsigned(7 downto 0);

BEGIN

-- Usa apenas 8 bits menos significativos do endereço

add <= Address(7 downto 0);

-- Conversão de bit-vector em inteiro

addu(0) <= To_StdULogic(add(0));

addu(1) <= To_StdULogic(add(1));

addu(2) <= To_StdULogic(add(2));

addu(3) <= To_StdULogic(add(3));

addu(4) <= To_StdULogic(add(4));

addu(5) <= To_StdULogic(add(5));

addu(6) <= To_StdULogic(add(6));

addu(7) <= To_StdULogic(add(7));

-- Cálculo dos 4 endereços (inteiros) a serem lidos devido ao endereçamento por byte

add1 <= add0 + 1;

add2 <= add0 + 2;

add3 <= add0 + 3;

add0 <= CONV_INTEGER(addu);

-- Conversão dos endereços no formato STD_LOGIC_VECTOR

addS0 <= CONV_STD_LOGIC_VECTOR(add0, 8);

addS1 <= CONV_STD_LOGIC_VECTOR(add1, 8);

addS2 <= CONV_STD_LOGIC_VECTOR(add2, 8);

addS3 <= CONV_STD_LOGIC_VECTOR(add3, 8);

-- Conversão do dado (entrada) no formato STD_LOGIC_VECTOR

datainS <= To_StdLogicVector(datain);

wrS <= To_StdULogic(wr);

clockS <= To_StdULogic(clock);

-- Conversão de dado (saída) para bit_vector

dataout <= To_BitVector(dataoutS);

-- Distribuição dos vetores de dados para os bancos de memória

datainS0 <= datainS(7 downto 0);

datainS1 <= datainS(15 downto 8);

datainS2 <= datainS(23 downto 16);

datainS3 <= datainS(31 downto 24);

dataoutS(7 downto 0) <= dataoutS0;

dataoutS(15 downto 8) <= dataoutS1;

dataoutS(23 downto 16) <= dataoutS2;

dataoutS(31 downto 24) <= dataoutS3;

-- Bancos de memórias (cada banco possui 256 bytes)

MEM: lpm_ram_dq

GENERIC MAP (lpm_widthad => ADDR_WIDTH, lpm_width => DATA_WIDTH, lpm_file => INIT_FILE)

PORT MAP (data => datainS0, Address => addS0, we => wrS, inclock => clockS, outclock => clockS, q => dataoutS0);

MEM_plus_One: lpm_ram_dq

GENERIC MAP (lpm_widthad => ADDR_WIDTH, lpm_width => DATA_WIDTH, lpm_file => INIT_FILE)

PORT MAP (data => datainS1, Address => addS1, we => wrS, inclock => clockS, outclock => clockS, q => dataoutS1);

MEM_plus_Two: lpm_ram_dq

GENERIC MAP (lpm_widthad => ADDR_WIDTH, lpm_width => DATA_WIDTH, lpm_file => INIT_FILE)

PORT MAP (data => datainS2, Address => addS2, we => wrS, inclock => clockS, outclock => clockS, q => dataoutS2);

MEM_plus_Three: lpm_ram_dq

GENERIC MAP (lpm_widthad => ADDR_WIDTH, lpm_width => DATA_WIDTH, lpm_file => INIT_FILE)

PORT MAP (data => datainS3, Address => addS3, we => wrS, inclock => clockS, outclock => clockS, q => dataoutS3);

END behavioral_arch;

Código 4.1 Comportamental VHDL da Memória 256 bytes

4.1.2 Banco de Registradores

O módulo que se convencionou chamar banco de registradores é uma estrutura composta por 32 registradores de 32 bits cada. O componente possui duas saídas de 32 bits, apresentando o conteúdo de dois registradores simultaneamente.

O procedimento interno para a leitura do conteúdo dos registradores é puramente combinacional, isto é se os valores nas entradas ReadRegister1 ou ReadRegister2 forem alterados, os valores nas saídas ReadData1 ou ReadData2 podem ser alterados durante o mesmo ciclo de relógio.

O registrador a ser escrito é selecionado pela entrada WriteRegister. Quando a entrada RegWrite é ativada, com valor igual a 1, o registrador selecionado recebe o conteúdo da entrada WriteData.

É informação importante o fato de que o sinal de reset atribui valor zero a todos os registradores e é assíncrono.

Figura 2.3 Banco de Registradores

O código VHDL para o componente Banco de Registradores é apresentado logo em seguida. Verifique a especificação dos sinais de entrada e saída. Sua relação com os demais blocos do sistema será explicada dentro em breve.

--------------------------------------------------------------------------------

-- Title

: Banco de Registradores

-- Project

: CPU Multi-ciclo

--------------------------------------------------------------------------------

-- File

: Banco_reg.vhd

-- Author

: Emannuel Gomes Macêdo ([email protected])

--

Fernando Raposo Camara da Silva ([email protected])

--

Pedro Machado Manhães de Castro ([email protected])

--

Rodrigo Alves Costa ([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 armazena o conjunto de registradores da cpu, no

-- qual pode ser efetuado leitura e escrita de dados.

--------------------------------------------------------------------------------

-- Copyright (c) notice

--

Universidade Federal de Pernambuco (UFPE).

--

CIn - Centro de Informatica.

--

Developed by computer science undergraduate students.

--

This code may be used for educational and non-educational purposes as

--

long as its copyright notice remains unchanged.

--------------------------------------------------------------------------------

-- Revisions

: 1

-- Revision Number: 1.0

-- Version

: 1.1

-- Date

: 21/11/2002

-- Modifier

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

--

Paulo Roberto Santana Oliveira Filho ([email protected])

--

Viviane Cristina Oliveira Aureliano ([email protected])

-- Description

:

--------------------------------------------------------------------------------

--Short name: breg

ENTITY Banco_reg IS

PORT(

Clk

: INbit;

-- Clock do banco de registradores

Reset

: INbit;

-- Reinicializa o conteudo dos registradores

RegWrite: INbit;

-- Indica se a operação é de escrita ou leitura

ReadReg1: INbit_vector (4 downto 0);-- Indica o registrador #1 a ser lido

ReadReg2: INbit_vector (4 downto 0);-- Indica o registrador #2 a ser lido

WriteReg: INbit_vector (4 downto 0);-- Indica o registrador a ser escrito

WriteData : INbit_vector (31 downto 0);-- Indica o dado a ser escrito

ReadData1: OUTbit_vector (31 downto 0);-- Mostra a informaçao presente no registrador #1

ReadData2: OUTbit_vector (31 downto 0)-- Mostra a informação presente no registrador #2

);

END Banco_reg ;

-- Arquitetura que define comportamento do Banco de Registradores

-- Simulation

ARCHITECTURE behavioral_arch OF Banco_reg IS

SIGNAL Reg0

: bit_vector (31 downto 0);

-- Conjunto

SIGNAL Reg1

: bit_vector (31 downto 0);

-- das informações

SIGNAL Reg2

: bit_vector (31 downto 0);

-- pertencentes

SIGNAL Reg3

: bit_vector (31 downto 0);

-- aos registradores.

SIGNAL Reg4

: bit_vector (31 downto 0);

-- Esta CPU

SIGNAL Reg5

: bit_vector (31 downto 0);

-- possui

SIGNAL Reg6

: bit_vector (31 downto 0);

-- 32 registradores

SIGNAL Reg7

: bit_vector (31 downto 0);

-- de uso

SIGNAL Reg8

: bit_vector (31 downto 0);

-- comum.

SIGNAL Reg9 : bit_vector (31 downto 0);

SIGNAL Reg10: bit_vector (31 downto 0);

SIGNAL Reg11: bit_vector (31 downto 0);

SIGNAL Reg12: bit_vector (31 downto 0);

SIGNAL Reg13: bit_vector (31 downto 0);

SIGNAL Reg14: bit_vector (31 downto 0);

SIGNAL Reg15: bit_vector (31 downto 0);

SIGNAL Reg16: bit_vector (31 downto 0);

SIGNAL Reg17: bit_vector (31 downto 0);

SIGNAL Reg18: bit_vector (31 downto 0);

SIGNAL Reg19: bit_vector (31 downto 0);

SIGNAL Reg20: bit_vector (31 downto 0);

SIGNAL Reg21: bit_vector (31 downto 0);

SIGNAL Reg22: bit_vector (31 downto 0);

SIGNAL Reg23: bit_vector (31 downto 0);

SIGNAL Reg24: bit_vector (31 downto 0);

SIGNAL Reg25: bit_vector (31 downto 0);

SIGNAL Reg26: bit_vector (31 downto 0);

SIGNAL Reg27: bit_vector (31 downto 0);

SIGNAL Reg28: bit_vector (31 downto 0);

SIGNAL Reg29: bit_vector (31 downto 0);

SIGNAL Reg30: bit_vector (31 downto 0);

SIGNAL Reg31: bit_vector (31 downto 0);

BEGIN

-- selecao do primeiro registrador

WITH ReadReg1 SELECT

ReadData1 <= Reg0 WHEN "00000",-- acesso às informações do registrador correspondente

Reg1 WHEN "00001",

Reg2 WHEN "00010",

Reg3 WHEN "00011",

Reg4 WHEN "00100",

Reg5 WHEN "00101",

Reg6 WHEN "00110",

Reg7 WHEN "00111",

Reg8 WHEN "01000",

Reg9 WHEN "01001",

Reg10 WHEN "01010",

Reg11 WHEN "01011",

Reg12 WHEN "01100",

Reg13 WHEN "01101",

Reg14 WHEN "01110",

Reg15 WHEN "01111",

Reg16 WHEN "10000",

Reg17 WHEN "10001",

Reg18 WHEN "10010",

Reg19 WHEN "10011",

Reg20 WHEN "10100",

Reg21 WHEN "10101",

Reg22 WHEN "10110",

Reg23 WHEN "10111",

Reg24 WHEN "11000",

Reg25 WHEN "11001",

Reg26 WHEN "11010",

Reg27 WHEN "11011",

Reg28 WHEN "11100",

Reg29 WHEN "11101",

Reg30 WHEN "11110",

Reg31 WHEN "11111";

-- Clocked Process

process (Clk,Reset)

begin

------------------------------------------- Reset inicializa o conjunto de registradores

if(Reset = '1') then

Reg0 <= "00000000000000000000000000000000";

Reg1 <= "00000000000000000000000000000000";

Reg2 <= "00000000000000000000000000000000";

Reg3 <= "00000000000000000000000000000000";

Reg4 <= "00000000000000000000000000000000";

Reg5 <= "00000000000000000000000000000000";

Reg6 <= "00000000000000000000000000000000";

Reg7 <= "00000000000000000000000000000000";

Reg8 <= "00000000000000000000000000000000";

Reg9 <= "00000000000000000000000000000000";

Reg10 <= "00000000000000000000000000000000";

Reg11 <= "00000000000000000000000000000000";

Reg12 <= "00000000000000000000000000000000";

Reg13 <= "00000000000000000000000000000000";

Reg14 <= "00000000000000000000000000000000";

Reg15 <= "00000000000000000000000000000000";

Reg16 <= "00000000000000000000000000000000";

Reg17 <= "00000000000000000000000000000000";

Reg18 <= "00000000000000000000000000000000";

Reg19 <= "00000000000000000000000000000000";

Reg20 <= "00000000000000000000000000000000";

Reg21 <= "00000000000000000000000000000000";

Reg22 <= "00000000000000000000000000000000";

Reg23 <= "00000000000000000000000000000000";

Reg24 <= "00000000000000000000000000000000";

Reg25 <= "00000000000000000000000000000000";

Reg26 <= "00000000000000000000000000000000";

Reg27 <= "00000000000000000000000000000000";

Reg28 <= "00000000000000000000000000000000";

Reg29 <= "00000000000000000000000000000000";

Reg30 <= "00000000000000000000000000000000";

Reg31 <= "00000000000000000000000000000000";

------------------------------------------ Início do processo relacionado ao clock

elsif (Clk = '1' and clk'event) then

if(RegWrite = '1') then

case WriteReg is

when "00000" =>Reg0 <= WriteData;

when "00001" =>Reg1 <= WriteData;

when "00010" =>Reg2 <= WriteData;

when "00011" =>Reg3 <= WriteData;

when "00100" =>Reg4 <= WriteData;

when "00101" =>Reg5 <= WriteData;

when "00110" =>Reg6 <= WriteData;

when "00111" =>Reg7 <= WriteData;

when "01000" =>Reg8 <= WriteData;

when "01001" =>Reg9 <= WriteData;

when "01010" =>Reg10 <= WriteData;

when "01011" =>Reg11 <= WriteData;

when "01100" =>Reg12 <= WriteData;

when "01101" =>Reg13 <= WriteData;

when "01110" =>Reg14 <= WriteData;

when "01111" =>Reg15 <= WriteData;

when "10000" =>Reg16 <= WriteData;

when "10001" =>Reg17 <= WriteData;

when "10010" =>Reg18 <= WriteData;

when "10011" =>Reg19 <= WriteData;

when "10100" =>Reg20 <= WriteData;

when "10101" =>Reg21 <= WriteData;

when "10110" =>Reg22 <= WriteData;

when "10111" =>Reg23 <= WriteData;

when "11000" =>Reg24 <= WriteData;

when "11001" =>Reg25 <= WriteData;

when "11010" =>Reg26 <= WriteData;

when "11011" =>Reg27 <= WriteData;

when "11100" =>Reg28 <= WriteData;

when "11101" =>Reg29 <= WriteData;

when "11110" =>Reg30 <= WriteData;

when "11111" =>Reg31 <= WriteData;

end case;

end if;

end if;

------------------------------------------ Fim do processo relacionado ao clock

end process;

------------------------------------------ Fim da Arquitetura

END behavioral_arch;

Código 4.2 Descrição comportamental VHDL do Banco de Registradores

4.1.3 Registrador de Instruções

Componente fundamental para a ordem no procedimento de análise e decodificação da instrução, o Registrador de Instruções (mais conhecido pelo designativo inglês IR, de Instruction Register) recebe o dado diretamente da Memória e apresenta como saída os diversos campos especificados na definição dos formatos de instrução. Associado ao clock do sistema, possui um sinal de reset, como todo registrador e um sinal de escrita que habilita leitura de seu conteúdo ou carga em seu interior.

ram8

add

Data_in

Data_out

clock

wr

Ram32

add

Data_in

Data_out

clock

wr

Figura 2.4 Registrador de Instruções

O código VHDL do Registrador de Instruções é apresentado a seguir.

--------------------------------------------------------------------------------

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

--

Developed by computer science undergraduate students.

--

This code may be used for educational and non-educational purposes as

--

long as its copyright notice remains unchanged.

--------------------------------------------------------------------------------

-- Revisions

:

-- Revision Number:

-- Version

:

-- Date

:

-- Modifier

:

-- Description

:

--------------------------------------------------------------------------------

-- Short name: ir

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;

Código 4.3 Descrição comportamental VHDL do Registrador de Instruções

4.1.4 Registrador de Deslocamento

O registrador de deslocamento é um componente capaz de deslocar um número inteiro de 32 bits para esquerda e para a direita. No deslocamento à direita o sinal pode ser preservado ou não. O número de deslocamentos pode variar entre 0 e 7 e é especificado na entrada n (3 bits) do componente. A funcionalidade desejada do registrador de deslocamento é especificada na entrada shift (3 bits menos significativos) conforme figura abaixo. As atividades discriminadas na entrada shift são síncronas com o clock e o reset é assíncrono.

Reg8

load

clock

clear

Reg32

load

clock

clear

Figura 2.5 Registrador de Deslocamento

O código VHDL do Registrador de Deslocamento é apresentado logo a seguir.

--------------------------------------------------------------------------------

-- Title

: Registrador de Deslocamento

-- Project

: CPU Multi-ciclo

--------------------------------------------------------------------------------

-- File

: RegDesloc.vhd

-- Author

: Emannuel Gomes Macêdo

--

Fernando Raposo Camara da Silva

--

Pedro Machado Manhães de Castro

--

Rodrigo Alves Costa

-- Organization : Universidade Federal de Pernambuco

-- Created

: 10/07/2002

-- Last update: 26/11/2002

-- Plataform: Flex10K

-- Simulators: Altera Max+plus II

-- Synthesizers:

-- Targets

:

-- Dependency:

--------------------------------------------------------------------------------

-- Description: Entidade responsável pelo deslocamento de um vetor de 32

-- bits para a direita e para a esquerda.

--

Entradas:

--

* N: vetor de 3 bits que indica a quantidade de

--

deslocamentos

--

* Shift: vetor de 3 bits que indica a função a ser

--

realizada pelo registrador

--

Abaixo seguem os valores referentes à entrada shift e as

-- respectivas funções do registrador:

--

--

Shift

FUNÇÃO DO REGISTRADOR

--

000

faz nada

--

001

carrega vetor (sem deslocamentos)

--

010

deslocamento à esquerda n vezes

--

011

deslocamento à direita lógico n vezes

--

100

deslocamento à direita aritmético n vezes

--

101

rotação à direita n vezes

--

110

rotação à esquerda n vezes

--------------------------------------------------------------------------------

-- Copyright (c) notice

--

Universidade Federal de Pernambuco (UFPE).

--

CIn - Centro de Informatica.

--

Developed by computer science undergraduate students.

--

This code may be used for educational and non-educational purposes as

--

long as its copyright notice remains unchanged.

--------------------------------------------------------------------------------

-- Revisions

: 2

-- Revision Number: 2.0

-- Version

: 1.2

-- Date

: 26/11/2002

-- Modifier

: Marcus Vinicius Lima e Machado

--

Paulo Roberto Santana Oliveira Filho

--

Viviane Cristina Oliveira Aureliano

-- Description

:

--------------------------------------------------------------------------------

-- Short name: desl

ENTITY RegDesloc IS

PORT(

Clk

: INbit;-- Clock do sistema

Reset: INbit;-- Reset

Shift : INbit_vector (2 downto 0);-- Função a ser realizada pelo registrador

N

: INbit_vector (2 downto 0);-- Quantidade de deslocamentos

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

Saida: OUTbit_vector (31 downto 0)-- Vetor deslocado

);

END RegDesloc;

-- Arquitetura que define o comportamento do registrador de deslocamento

-- Simulation

ARCHITECTURE behavioral_arch OF RegDesloc IS

signal temp

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

begin

-- Clocked process

process (Clk, Reset)

begin

if(Reset = '1') then

temp <= "00000000000000000000000000000000";

elsif (Clk = '1' and Clk'event) then

case Shift is

when "000" =>

-- Faz nada

temp <= temp;

when "001" =>

-- Carrega vetor de entrada, não faz deslocamentos

temp <= Entrada;

when "010" =>

-- Deslocamento à esquerda N vezes

case N is

when "000" =>

-- Deslocamento à esquerda nenhuma vez

temp <= temp;

when "001" =>

-- Deslocamento à esquerda 1 vez

temp(0) <= '0';

temp(31 downto 1) <= temp(30 downto 0);

when "010" =>

-- Deslocamento à esquerda 2 vezes

temp(1 downto 0) <= "00";

temp(31 downto 2) <= temp(29 downto 0);

when "011" =>

-- Deslocamento à esquerda 3 vezes

temp(2 downto 0) <= "000";

temp(31 downto 3) <= temp(28 downto 0);

when "100" =>

-- Deslocamento à esquerda 4 vezes

temp(3 downto 0) <= "0000";

temp(31 downto 4) <= temp(27 downto 0);

when "101" =>

-- Deslocamento à esquerda 5 vezes

temp(4 downto 0) <= "00000";

temp(31 downto 5) <= temp(26 downto 0);

when "110" =>

-- Deslocamento à esquerda 6 vezes

temp(5 downto 0) <= "000000";

temp(31 downto 6) <= temp(25 downto 0);

when "111" =>

-- Deslocamento à esquerda 7 vezes

temp(6 downto 0) <= "0000000";

temp(31 downto 7) <= temp(24 downto 0);

end case;

-- Deslocamento à direita lógico N vezes

when "011" =>

case n is

when "000" =>

-- Deslocamento à direita lógico nenhuma vez

temp <= temp;

when "001" =>

-- Deslocamento à direita lógico 1 vez

temp(30 downto 0) <= temp(31 downto 1);

temp(31) <= '0';

when "010" =>

-- Deslocamento à direita lógico 2 vezes

temp(29 downto 0) <= temp(31 downto 2);

temp(31 downto 30) <= "00";

when "011" =>

-- Deslocamento à direita lógico 3 vezes

temp(28 downto 0) <= temp(31 downto 3);

temp(31 downto 29) <= "000";

when "100" =>

-- Deslocamento à direita lógico 4 vezes

temp(27 downto 0) <= temp(31 downto 4);

temp(31 downto 28) <= "0000";

when "101" =>

-- Deslocamento à direita lógico 5 vezes

temp(26 downto 0) <= temp(31 downto 5);

temp(31 downto 27) <= "00000";

when "110" =>

-- Deslocamento à direita lógico 6 vezes

temp(25 downto 0) <= temp(31 downto 6);

temp(31 downto 26) <= "000000";

when "111" =>

-- Deslocamento à direita lógico 7 vezes

temp(24 downto 0) <= temp(31 downto 7);

temp(31 downto 25) <= "0000000";

end case;

-- Deslocamento à direita aritmético N vezes

when "100" =>

case n is

when "000" =>

-- Deslocamento à direita aritmético nenhuma vez

temp <= temp;

when "001" =>

-- Deslocamento à direita aritmético 1 vezes

temp(30 downto 0) <= temp(31 downto 1);

temp(31) <= temp(31);

when "010" =>

-- Deslocamento à direita aritmético 2 vezes

temp(29 downto 0) <= temp(31 downto 2);

temp(30) <= temp(31);

temp(31) <= temp(31);

when "011" =>

-- Deslocamento à direita aritmético 3 vezes

temp(28 downto 0) <= temp(31 downto 3);

temp(29) <= temp(31);

temp(30) <= temp(31);

temp(31) <= temp(31);

when "100" =>

-- Deslocamento à direita aritmético 4 vezes

temp(27 downto 0) <= temp(31 downto 4);

temp(28) <= temp(31);

temp(29) <= temp(31);

temp(30) <= temp(31);

temp(31) <= temp(31);

when "101" =>

-- Deslocamento à direita aritmético 5 vezes

temp(26 downto 0) <= temp(31 downto 5);

temp(27) <= temp(31);

temp(28) <= temp(31);

temp(29) <= temp(31);

temp(30) <= temp(31);

temp(31) <= temp(31);

when "110" =>

-- Deslocamento à direita aritmético 6 vezes

temp(25 downto 0) <= temp(31 downto 6);

temp(26) <= temp(31);

temp(27) <= temp(31);

temp(28) <= temp(31);

temp(29) <= temp(31);

temp(30) <= temp(31);

temp(31) <= temp(31);

when "111" =>

-- Deslocamento à direita aritmético 7 vezes

temp(24 downto 0) <= temp(31 downto 7);

temp(25) <= temp(31);

temp(26) <= temp(31);

temp(27) <= temp(31);

temp(28) <= temp(31);

temp(29) <= temp(31);

temp(30) <= temp(31);

temp(31) <= temp(31);

end case;

-- Rotação à direita N vezes

when "101" =>

case n is

when "000" =>

-- Rotação à direita nenhuma vez

temp <= temp;

when "001" =>

-- Rotação à direita 1 vez

temp(30 downto 0) <= temp(31 downto 1);

temp(31) <= temp(0);

when "010" =>

-- Rotação à direita 2 vezes

temp(29 downto 0) <= temp(31 downto 2);

temp(31 downto 30) <= temp(1 downto 0);

when "011" =>

-- Rotação à direita 3 vezes

temp(28 downto 0) <= temp(31 downto 3);

temp(31 downto 29) <= temp(2 downto 0);

when "100" =>

-- Rotação à direita 4 vezes

temp(27 downto 0) <= temp(31 downto 4);

temp(31 downto 28) <= temp(3 downto 0);

when "101" =>

-- Rotação à direita 5 vezes

temp(26 downto 0) <= temp(31 downto 5);

temp(31 downto 27) <= temp(4 downto 0);

when "110" =>

-- Rotação à direita 6 vezes

temp(25 downto 0) <= temp(31 downto 6);

temp(31 downto 26) <= temp(5 downto 0);

when "111" =>

-- Rotação à direita 7 vezes

temp(24 downto 0) <= temp(31 downto 7);

temp(31 downto 25) <= temp(6 downto 0);

end case;

-- Rotação à esquerda N vezes

when "110" =>

case n is

when "000" =>

-- Rotação à esquerda nenhuma vez

temp <= temp;

when "001" =>

-- Rotação à esquerda 1 vez

temp(0) <= temp(31);

temp(31 downto 1) <= temp(30 downto 0);

when "010" =>

-- Rotação à esquerda 2 vezes

temp(1 downto 0) <= temp(31 downto 30);

temp(31 downto 2) <= temp(29 downto 0);

when "011" =>

-- Rotação à esquerda 3 vezes

temp(2 downto 0) <= temp(31 downto 29);

temp(31 downto 3) <= temp(28 downto 0);

when "100" =>

-- Rotação à esquerda 4 vezes

temp(3 downto 0) <= temp(31 downto 28);

temp(31 downto 4) <= temp(27 downto 0);

when "101" =>

-- Rotação à esquerda 5 vezes

temp(4 downto 0) <= temp(31 downto 27);

temp(31 downto 5) <= temp(26 downto 0);

when "110" =>

-- Rotação à esquerda 6 vezes

temp(5 downto 0) <= temp(31 downto 26);

temp(31 downto 6) <= temp(25 downto 0);

when "111" =>

-- Rotação à esquerda 7 vezes

temp(6 downto 0) <= temp(31 downto 25);

temp(31 downto 7) <= temp(24 downto 0);

end case;

-- Funcionalidade não definida

when others =>

-- Faz nada

end case;

end if;

Saida <= temp;

end process;

END behavioral_arch;

Código 4.4 Comportamental VHDL do componente

Registrador de Deslocamento.

4.1.5 Unidade Lógica e Aritmética

A Unidade Lógico e Aritmética (ALU, do inglês Arithmetic and Logic Unit) é um circuito combinacional que 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.

Figura 2.6 Unidade Lógica e Aritmética

F

Operação

Descrição

Flags afetados

000

S = A

Nenhum

Z,N

001

S = A + B

Soma

Z,N,O

010

S = A - B

Subtração

Z,N,O

011

S = A and B

And lógico

Z

100

S = inc A

Incremento

Z,N,O

101

S = not A

Complemento

Z

110

S = A xor B

Ou exclusivo

Z

111

S = A comp B

Comparação

EG,GT,LT

Tabela 2.1 Funcionalidades da Unidade Lógica e Aritmética

O código VHDL da Unidade de Lógica e Aritmética é apresentado a seguir.

--------------------------------------------------------------------------------

-- Title

: Unidade de Lógica e Aritmética

-- Project

: CPU multi-ciclo

--------------------------------------------------------------------------------

-- File

: ula32.vhd

-- Author

: Emannuel Gomes Macêdo ([email protected])

--

Fernando Raposo Camara da Silva ([email protected])

--

Pedro Machado Manhães de Castro ([email protected])

--

Rodrigo Alves Costa ([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 processa as operações lógicas e aritméticas da

-- cpu.

--------------------------------------------------------------------------------

-- Copyright (c) notice

--

Universidade Federal de Pernambuco (UFPE).

--

CIn - Centro de Informatica.

--

Developed by computer science undergraduate students.

--

This code may be used for educational and non-educational purposes as

--

long as its copyright notice remains unchanged.

--------------------------------------------------------------------------------

-- Revisions

: 1

-- Revision Number: 1

-- Version

: 1.1

-- Date

: 21/11/2002

-- Modifier

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

--

Paulo Roberto Santana Oliveira Filho ([email protected])

--

Viviane Cristina Oliveira Aureliano ([email protected])

-- Description

:

--------------------------------------------------------------------------------

-- Short name: ula

entity Ula32 is

port (

A

: in bit_vector (31 downto 0);-- Operando A da ULA

B

: in bit_vector (31 downto 0);-- Operando B da ULA

Seletor : in bit_vector(2 downto 0);-- Seletor da operação da ULA

S

: out bit_vector (31 downto 0);-- Resultado da operação (SOMA, SUB, AND, NOT, INCREMENTO, XOR)

Overflow : out bit;

-- Sinaliza overflow aritmético

Negativo: out bit;

-- Sinaliza valor negativo

z

: out bit;

-- Sinaliza quando S for zero

Igual

: out bit;

-- Sinaliza se A=B

Maior

: out bit;

-- Sinaliza se A>B

Menor

: out bit

-- Sinaliza se A

);

end Ula32;

-- Simulation

architecture behavioral of Ula32 is

signal s_temp

: bit_vector(31 downto 0);

-- Sinal que recebe valor temporário da operação realizada

signal soma_temp : bit_vector(31 downto 0);

-- Sinal que recebe o valor temporario da soma, subtração ou incremento

signal carry_temp: bit_vector (31 downto 0);

-- Vetor para auxílio no cálculo das operações e do overflow aritmético

signal novo_B

: bit_vector (31 downto 0);

-- Vetor que fornece o operando B, 1 ou not(B) para operações de soma, incremento ou subtração respectivamente

signal i_temp

: bit_vector(31 downto 0);

-- Vetor para calculo de incremento

signal igual_temp: bit;

-- Bit que armazena instancia temporária de igualdade

signal overflow_temp: bit;

-- Bit que armazena valor temporário do overflow

begin

with Seletor select

s_temp <= A

when "000", -- LOAD

soma_temp when "001",-- SOMA

soma_temp when "010",-- SUB

(A and B) when "011",-- AND

(A xor B) when "110", -- A XOR B

not(A) when "101",-- NOT A

soma_temp when "100",-- INCREMENTO

"00000000000000000000000000000000" when others;

-- NAO DEFINIDO

S <= s_temp;

Negativo <= s_temp(31);

i_temp <= "00000000000000000000000000000001";

z <= '1' when s_temp = "00000000000000000000000000000000" else '0';

--------------------------------------------------------------------------------

--

Regiao que calcula a soma, subtracao e incremento

--

--------------------------------------------------------------------------------

with Seletor select

novo_B <= B

when "001", -- Soma

i_temp when "100", -- Incremento

not(B) when others; -- Subtracao e outros

soma_temp(0) <= A(0) xor novo_B(0) xor seletor(1);

soma_temp(1) <= A(1) xor novo_B(1) xor carry_temp(0);

soma_temp(2) <= A(2) xor novo_B(2) xor carry_temp(1);

soma_temp(3) <= A(3) xor novo_B(3) xor carry_temp(2);

soma_temp(4) <= A(4) xor novo_B(4) xor carry_temp(3);

soma_temp(5) <= A(5) xor novo_B(5) xor carry_temp(4);

soma_temp(6) <= A(6) xor novo_B(6) xor carry_temp(5);

soma_temp(7) <= A(7) xor novo_B(7) xor carry_temp(6);

soma_temp(8) <= A(8) xor novo_B(8) xor carry_temp(7);

soma_temp(9) <= A(9) xor novo_B(9) xor carry_temp(8);

soma_temp(10) <= A(10) xor novo_B(10) xor carry_temp(9);

soma_temp(11) <= A(11) xor novo_B(11) xor carry_temp(10);

soma_temp(12) <= A(12) xor novo_B(12) xor carry_temp(11);

soma_temp(13) <= A(13) xor novo_B(13) xor carry_temp(12);

soma_temp(14) <= A(14) xor novo_B(14) xor carry_temp(13);

soma_temp(15) <= A(15) xor novo_B(15) xor carry_temp(14);

soma_temp(16) <= A(16) xor novo_B(16) xor carry_temp(15);

soma_temp(17) <= A(17) xor novo_B(17) xor carry_temp(16);

soma_temp(18) <= A(18) xor novo_B(18) xor carry_temp(17);

soma_temp(19) <= A(19) xor novo_B(19) xor carry_temp(18);

soma_temp(20) <= A(20) xor novo_B(20) xor carry_temp(19);

soma_temp(21) <= A(21) xor novo_B(21) xor carry_temp(20);

soma_temp(22) <= A(22) xor novo_B(22) xor carry_temp(21);

soma_temp(23) <= A(23) xor novo_B(23) xor carry_temp(22);

soma_temp(24) <= A(24) xor novo_B(24) xor carry_temp(23);

soma_temp(25) <= A(25) xor novo_B(25) xor carry_temp(24);

soma_temp(26) <= A(26) xor novo_B(26) xor carry_temp(25);

soma_temp(27) <= A(27) xor novo_B(27) xor carry_temp(26);

soma_temp(28) <= A(28) xor novo_B(28) xor carry_temp(27);

soma_temp(29) <= A(29) xor novo_B(29) xor carry_temp(28);

soma_temp(30) <= A(30) xor novo_B(30) xor carry_temp(29);

soma_temp(31) <= A(31) xor novo_B(31) xor carry_temp(30);

carry_temp(0) <= (seletor(1) and (A(0) or novo_B(0))) or (A(0) and novo_B(0));

carry_temp(1) <= (carry_temp(0) and (A(1) or novo_B(1))) or (A(1) and novo_B(1));

carry_temp(2) <= (carry_temp(1) and (A(2) or novo_B(2))) or (A(2) and novo_B(2));

carry_temp(3) <= (carry_temp(2) and (A(3) or novo_B(3))) or (A(3) and novo_B(3));

carry_temp(4) <= (carry_temp(3) and (A(4) or novo_B(4))) or (A(4) and novo_B(4));

carry_temp(5) <= (carry_temp(4) and (A(5) or novo_B(5))) or (A(5) and novo_B(5));

carry_temp(6) <= (carry_temp(5) and (A(6) or novo_B(6))) or (A(6) and novo_B(6));

carry_temp(7) <= (carry_temp(6) and (A(7) or novo_B(7))) or (A(7) and novo_B(7));

carry_temp(8) <= (carry_temp(7) and (A(8) or novo_B(8))) or (A(8) and novo_B(8));

carry_temp(9) <= (carry_temp(8) and (A(9) or novo_B(9))) or (A(9) and novo_B(9));

carry_temp(10) <= (carry_temp(9) and (A(10) or novo_B(10))) or (A(10) and novo_B(10));

carry_temp(11) <= (carry_temp(10) and (A(11) or novo_B(11))) or (A(11) and novo_B(11));

carry_temp(12) <= (carry_temp(11) and (A(12) or novo_B(12))) or (A(12) and novo_B(12));

carry_temp(13) <= (carry_temp(12) and (A(13) or novo_B(13))) or (A(13) and novo_B(13));

carry_temp(14) <= (carry_temp(13) and (A(14) or novo_B(14))) or (A(14) and novo_B(14));

carry_temp(15) <= (carry_temp(14) and (A(15) or novo_B(15))) or (A(15) and novo_B(15));

carry_temp(16) <= (carry_temp(15) and (A(16) or novo_B(16))) or (A(16) and novo_B(16));

carry_temp(17) <= (carry_temp(16) and (A(17) or novo_B(17))) or (A(17) and novo_B(17));

carry_temp(18) <= (carry_temp(17) and (A(18) or novo_B(18))) or (A(18) and novo_B(18));

carry_temp(19) <= (carry_temp(18) and (A(19) or novo_B(19))) or (A(19) and novo_B(19));

carry_temp(20) <= (carry_temp(19) and (A(20) or novo_B(20))) or (A(20) and novo_B(20));

carry_temp(21) <= (carry_temp(20) and (A(21) or novo_B(21))) or (A(21) and novo_B(21));

carry_temp(22) <= (carry_temp(21) and (A(22) or novo_B(22))) or (A(22) and novo_B(22));

carry_temp(23) <= (carry_temp(22) and (A(23) or novo_B(23))) or (A(23) and novo_B(23));

carry_temp(24) <= (carry_temp(23) and (A(24) or novo_B(24))) or (A(24) and novo_B(24));

carry_temp(25) <= (carry_temp(24) and (A(25) or novo_B(25))) or (A(25) and novo_B(25));

carry_temp(26) <= (carry_temp(25) and (A(26) or novo_B(26))) or (A(26) and novo_B(26));

carry_temp(27) <= (carry_temp(26) and (A(27) or novo_B(27))) or (A(27) and novo_B(27));

carry_temp(28) <= (carry_temp(27) and (A(28) or novo_B(28))) or (A(28) and novo_B(28));

carry_temp(29) <= (carry_temp(28) and (A(29) or novo_B(29))) or (A(29) and novo_B(29));

carry_temp(30) <= (carry_temp(29) and (A(30) or novo_B(30))) or (A(30) and novo_B(30));

carry_temp(31) <= (carry_temp(30) and (A(31) or novo_B(31))) or (A(31) and novo_B(31));

overflow_temp <= carry_temp(31) xor carry_temp(30);

Overflow <= overflow_temp;

--------------------------------------------------------------------------------

--

Regiao que calcula a comparação

--

--------------------------------------------------------------------------------

-- No codigo da comparacao (110) sera executada a subtracao na parte relativa

-- ao calculo da SOMA, SUBTRACAO e INCREMENTO.

igual_temp <= not(overflow_temp) when soma_temp = "00000000000000000000000000000000"

else '0'; -- Quando subtracao e zero

Igual <= igual_temp;

-- Se nao teve overflow -> resultado baseado no bit mais significativo de A - B.

-- Se teve overflow -> A e B possuem, necessariamente, sinais contrarios. Resultado

-- baseado no bit mais significativo de A.

-- Devemos tambem checar se A e B nao sao iguais

Maior <= ( (not(soma_temp(31)) and (not(overflow_temp)) )or (overflow_temp and (not(A(31))))) and (not(igual_temp));

-- Se nao teve overflow -> resultado baseado no bit mais significativo de A - B.

-- Se teve overflow -> A e B possuem, necessariamente, sinais contrarios. Resultado

-- baseado no bit mais significativo de A.

Menor <= ((soma_temp(31) and (not(overflow_temp))) or (overflow_temp and A(31)));

end behavioral;

Código 4.5 Comportamental VHDL da Unidade Lógica e Aritmética

4.1.6 Registrador comum de dados, 32 bits

Componente básico da arquitetura de qualquer computador, um registrador é um conjunto seqüencial de células de memória, conhecidas amplamente no domínio de desenvolvimento de sistemas digitais pelos termos ingleses latches e flip-flops. Conforme já explicado, por definição, no MIPS, todos os registradores de uso interno são componentes capazes de armazenar 32 bits de informação. Para armazenar instruções e dados, bem como o endereço de instruções, serão utilizados esses componentes.

Figura 2.7 Registrador de dados, 32 bits.

O código VHDL para o componente registrador é simples. Encontra-se apresentado abaixo.O registardor é peça fundamental de um processador e como tal é utilizado em várias vezes na nossa implementação.Utilizamos este componente da seguinte forma:Para armazenar a saída da ULA;Para armazenar os sinais HI e LO.Para armazenar os conteúdos que vem do banco de registradores em A e B no caso;Para guardar o PC.Para guardar o conteúdo que sai de MDR.Para guardar o PC atual em EPC.

--------------------------------------------------------------------------------

-- Title

: Registrador de Uso Geral

-- Project

: CPU Multi-ciclo

--------------------------------------------------------------------------------

-- File

: Registrador.vhd

-- Author

: Emannuel Gomes Macêdo ([email protected])

--

Fernando Raposo Camara da Silva ([email protected])

--

Pedro Machado Manhães de Castro ([email protected])

--

Rodrigo Alves Costa ([email protected])

-- Organization : Universidade Federal de Pernambuco

-- Created

: 11/07/2002

-- Last update: 21/11/2002

-- Plataform: Flex10K

-- Simulators: Altera Max+plus II

-- Synthesizers:

-- Targets

:

-- Dependency:

--------------------------------------------------------------------------------

-- Description: Entidade que representa a unidade básica de uma cpu ou um

-- circuito que armazena dados na forma de bits.

--------------------------------------------------------------------------------

-- Copyright (c) notice

--

Universidade Federal de Pernambuco (UFPE).

--

CIn - Centro de Informatica.

--

Developed by computer science undergraduate students.

--

This code may be used for educational and non-educational purposes as

--

long as its copyright notice remains unchanged.

--------------------------------------------------------------------------------

-- Revisions

: 1

-- Revision Number: 1.0

-- Version

: 1.1

-- Date

: 21/11/2002

-- Modifier

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

--

Paulo Roberto Santana Oliveira Filho ([email protected])

--

Viviane Cristina Oliveira Aureliano ([email protected])

-- Description

:

--------------------------------------------------------------------------------

--Short name: reg

ENTITY Registrador IS

PORT(

Clk

: INbit;

-- Clock do registrador

Reset: INbit;

-- Reinicializa o conteudo do registrador

Load: INbit;

-- Carrega o registrador com o vetor Entrada

Entrada : INbit_vector (31 downto 0);

-- Vetor de bits que possui a informação a ser carregada no registrador

Saida: OUTbit_vector (31 downto 0)

-- Vetor de bits que possui a informação já carregada no registrador

);

END Registrador;

-- Arquitetura que define comportamento do Registrador

-- Simulation

ARCHITECTURE behavioral_arch OF Registrador IS

begin

-- Clocked process

process (Clk, Reset)

begin

------------------------------------------- Reset inicializa o registrador comum

if(Reset = '1') then

Saida <= "00000000000000000000000000000000";

------------------------------------------- Início do processo relacionado ao clock

elsif (Clk = '1' and clk'event) then

if (Load = '1') then

Saida <= Entrada;

end if;

end if;

------------------------------------------- Fim do processo relacionado ao clock

end process;

------------------------------------------- Fim da Arquitetura

END behavioral_arch;

Código 4.6 Descrição comportamental VHDL do Registador 32 bits.

4.2 Módulos Desenvolvidos

Durante a análise do fluxo de execução das instruções implementadas pela estrutura fornecida, desenrolou-se um processo de compreensão profunda do sistema proposto a desenvolvimento. Visando à implementação de uma unidade de processamento capaz de implementar o repertório exigido, a equipe de desenvolvimento produziu módulos, componentes específicos e exclusivos e os alocou convenientemente à unidade parcial em mãos. Segue-se a descrição pormenorizada dos blocos internos desenvolvidos a que se faz referência.

4.2.1 RegistradorDesl

Entidade responsável pelo envio de um vetor que indica a quantidade de deslocamentos a ser realizada no registrador. Esta entidade possibilita que a quantidade de deslocamentos possíveis pelo registrador seja de até 32 deslocamentos. Pois a quantidade é informada por partes (em até 5 partes) para o registrador.

Entradas:

N: vetor de 5 bits que indica a quantidade de deslocamentos

Shift: vetor de 3 bits que indica a função a ser realizada pelo registrador.

Abaixo seguem os valores referentes à entrada shift e as respectivas funções do registrador:

Shift

FUNÇÃO DO REGISTRADOR

000

faz nada

001

carrega vetor (sem deslocamentos)

010

deslocamento à esquerda n vezes

011

deslocamento à direita lógico n vezes

100

deslocamento à direita aritmético n vezes

101

rotação à direita n vezes

110

rotação à esquerda n vezes

Nesta entidade só é utilizado a entrada 001 do Shift para verificar se foi introduzido alguma nova entrada no módulo a fim de zerar todos os sinais desta entidade.

Segue a descrição em VHDL do componente.

--------------------------------------------------------------------------------

-- Title

: Registrador de Deslocamento

-- Project

: CPU Multi-ciclo

--------------------------------------------------------------------------------

-- File

: RegDesloc.vhd

-- Author

: Emannuel Gomes Macêdo

--

Fernando Raposo Camara da Silva

--

Pedro Mach