Implementação de um soft-core em VHDL baseado - Projetos

Propaganda
UNIVERSIDADE FEDERAL DE SANTA CATARINA
DEPARTAMENTO DE INFORMÁTICA E
ESTATÍSTICA
CURSO DE CIÊNCIAS DA COMPUTAÇÃO
Rafael Vargas
Implementação de um soft-core em VHDL baseado
no conjunto de instruções MIPS-I
Prof. Dr. Antônio Augusto Fröhlich
Orientador
Florianópolis, agosto de 2006.
Objetivo
O objetivo principal é desenvolver um soft-core implementando um subconjunto
do conjunto de instruções MIPS-I [1]. Bem como os dispositivos periféricos necessários
para o acesso à memória e as operações de Entrada e Saída.
Este soft-core tem como objetivo final ser sintetizado em uma plataforma FPGA
como a Xilinx Multimedia FPGA Platform [2], juntamente com a aplicação e os demais
componentes periféricos.
Este trabalho tem como metas específicas:
-
Possibilitar que o código que será rodado no soft-core seja gerado pelo GCC;
Criar um sistema de Entrada e Saída completo, mapeado em memória e com
interrupções.
Características do Projeto
Arquitetura do conjunto de instruções
O conjunto de instruções MIPS-I foi escolhido por ser um conjunto de formato
fixo (32 bits), simples e bem conhecido, o que facilita a sua implementação. Sendo que
também é possível, no futuro, adicionar novas instruções, uma vez que existem também
os conjuntos de instruções subseqüentes dos quais MIPS-I acaba sendo um subconjunto.
As instruções implementadas podem ser divididas em três grupos: Load e Store, Lógicoaritmética e Jump e Branch. Os formatos de instruções e sua codificação podem ser vistos
no Apêndice A.
Estrutura do Processador
Figura 1: Estrutura da CPU
A figura 1 mostra a estrutura do processador, que será composto por um IP (do
inglês Intellectual Property) Mapeador de memória que será encarregado de mapear os
endereços de memória para os seus dispositivos correspondentes, como por exemplo, o
intervalo de endereços 0x10010000 até 0x1001FFFF, que pertence à área de dados,
definindo assim intervalo de 64 Kbytes. Isto possibilita que apesar de conceitualmente, de
acordo com a arquitetura Harvard, serem dispositivos separados, ambos os dispositivos
de memória estejam no mesmo dispositivo físico, de acordo com a arquitetura de Von
Neumann.
Também compõem o soft-core o núcleo de execução que e uma UART (do inglês
Universal Asynchronous Receiver-Transmitter), cuja função é executar as operações de
entrada e saída.
Núcleo de Execução
O núcleo de execução, que como previamente dito, implementa um subconjunto
do conjunto de instruções MIPS-I, é o coração do soft-core. Composto por 32
registradores de 32 bits cada. Este é o IP encarregado de executar as instruções contidas
na memória de instruções e a partir destas controlar o mapeador de memória para ler ou
escrever na memória de dados ou utilizar a UART como saída.
Registradores
Nome
Número
Uso
Constante zero
Dado temporário do montador (Assembler)
Valores para retorno de função e avaliação
de expressões
$a0-$a3 $4-$7
Parâmetros de funções
$t0-$t7 $8-$15
Temporários
$s0-$s7 $16-$23 Temporários salvos
$t8-$t9 $24-$25 Temporários
$k0-$k1 $26-$27 Reservado para o kernel do SO
$gp
$28
Global pointer
$sp
$29
Stack pointer
$fp
$30
Frame pointer
$ra
$31
Endereço de retorno
Tabela 1: Registradores da CPU
$zero
$0
$at
$1
$v0-$v1 $2-$3
Preservado após
uma chamada?
N/A
não
não
não
não
sim
não
não
sim
sim
sim
não
Como demonstrado pela tabela 1, a CPU é composta por 32 registradores, sendo
um deles contendo a constante zero (0) e os demais 31 são de uso geral.
Há, porém, uma convenção para a utilização destes registradores. De acordo com
esta convenção, os registradores marcados como “Preservado após uma chamada”,
mantém seu valor, mesmo após uma chamada normal de função (utilizando a instrução
jal) esta convenção diz que o registrador $at é reservado para utilização pelo montador
(Assembler) como para o armazenamento temporário de constantes ou a execução de
pseudo-instruções. Os registradores $v0 e $v1 devem ser utilizados para, ao final da
execução de uma função, armazenar os valores de retorno, como um endereço para um
array e seu tamanho. Por sua vez, do registrador $a0 ao $a3, devem ser armazenados
os parâmetros que serão passados à função que será chamada. Existem também dez
registradores para uso geral ($t0,$t1, ...,$t9). Há ainda, oito outros registradores para
uso geral ($s0-$s7). Há também dois registradores reservados para uso do kernel do SO
($k0 e $k1); além dos registradores para o Global Pointer ($gp), Stack Pointer ($sp)
e Frame Pointer ($fp); e um registrador destinado a conter o endereço da próxima
instrução a ser executada quando a função que está executando no momento terminar.
Figura 2: Datapath do núcleo de execução (atualizar imagem)
De acordo com Patterson e Hennessy [4], a execução da instrução se dá por meio dos
seguintes passos e ações. Cada instrução necessita de três a cinco destes passos:
1. Busca da instrução:
Busca a instrução da memória, apontada por PC, e calcula o endereço da próxima
instrução somando quatro ao valor atual de PC.
2. Decodificação da instrução e busca dos registradores:
São lidos os registradores identificados por rs e rt (e gravados em registradores
temorários A e B, respectivamente), supondo que a instrução seja do tipo R, pois caso
não seja, os valores desnecessários podem ser simplesmente descartados. Também é
calculado o possível valor da próxima instrução, caso esta seja um branch, que também
pode ser ignorado caso não seja.
3. Execução, computação do endereço de memória, ou término do branch:
Neste passo a ALU (do inglês Arithmetic and Logic Unit) executa uma, de quatro
funções, dependendo do tipo da instrução, podendo esta função ser:
• Endereço de memória:
O resultado será A somado do valor do campo “imediato” com o sinal
extendido para 32 bits.
•
Cálculo lógico-aritmético:
O resultado será A (operação) B, onde (operação) pode ser qualquer
operação da ALU.
•
Branch:
Subtrai B de A, e caso o valor seja igual a zero (valores iguais) atualiza o
valor de PC para o endereço calculado no ciclo anterior.
•
Jump:
Concatena os 3 bits de mais alta ordem do PC com os 26 bits de mais
baixa ordem da instrução deslocados 2 bits para a esquerda. E o valor
resultante é escrito em PC.
4. Acesso à memória ou término de instrução lógico-aritmética:
No caso de acesso á memória o endereço é determinado pela saída da ALU no
ciclo anterior. Para leitura, o valor lido é salvo para o próximo ciclo, e para gravação, é
gravado o dado de B.
Já no caso de instrução lógico-aritmética (tipo R) o registrador identificado por
rd é escrito com o valor da saída da ALU no ciclo anterior.
5. Término de leitura de memória:
Aqui, o valor lido da memória no ciclo anterior é escrito no registrador
identificado por rd.
Memória
Será utilizado um modelo flat de memória, dispensando assim a utilização de uma
complexa unidade de gerenciamento de memória (MMU, Memory Management Unit).
Haverá, porém, uma unidade de mapeamento de memória, cuja função será mapear as
leituras e escritas dos endereços “virtuais” para os endereços “físicos” dos dispositivos
periféricos ao núcleo de execução, como memória (tanto de dados como de instruções) e
UART.
UART
Este é o dispositivo encarregado pela parte de entrada e saída do processador, que foi
implementado para estabelecer um meio de comunicação com o meio externo ao softcore, utilizando uma interface RS-232.
Características da implementação
Linguagem VHDL
VHDL, do inglês Very-High-Speed Integrated Circuit Hardware Description
Language é uma linguagem de descrição de hardware originalmente desenvolvida para
documentar o comportamento de ASICs. Posteriormente foram criadas ferramentas
simuladoras e sintetizadoras que poderiam ler o VHDL e ter como saída uma definição de
uma implementação física de um circuito [5].
Existem também outras linguagens para descrição de hardware como Varilog,
porém o VHDL tem vantagens como o fato de ser uma linguagem fortemente tipada.
Polpeta [3] diz que em Verilog não há o conceito de pacotes, assim como não existem
diretivas para a configuração ou replicação de estruturas e o recurso de parametrização é
muito pobre, sendo assim, necessário sobrescrever constantes ao longo do processo de
síntese para que, deste modo, os componentes sejam pré-processados corretamente.
Referências
[01] MIPS Instruction Set. http://techpubs.sgi.com/library/manuals/2000/007-2597001/pdf/007-2597-001.pdf
[02] http://www.xilinx.com/products/boards/multimedia/
[03] Polpeta, Fauze V. Uma Estratégia para a Geração de Sistemas Embutidos
baseada na Metodologia Projeto de Sistemas Orientados à Aplicação. Dissertação de
mestrado, UFSC. 2006.
[04] Patterson, A. e Hennessy, J. L. Computer Organization and Design. Morgan
Kaufmann Publishers. 2nd Ed. 1997.
Apêndice A
Formatos das instruções do MIPS-I.
São três os formatos de instruções: o do tipo R, de registradores; do tipo I, de imediato; e
do tipo J, de jump.
Nome
Campos
Tamanho do campo 6 bits 5 bits 5 bits 5 bits 5 bits 6 bits
Formato R
op
rs
rt
rd
sa
funct
Formato I
op
rs
rt
imediato
Formato J
op
endereço
op
rs
rt
rd
sa
funct
imediato
endereço
opcode
source register
target register
destination register
shift amount
function
Comentário
32 bits por instrução
Instrução aritmética
Branch ou imediato
Jump
código da instrução
registrador fonte
registrador fonte no formato R e destino no formato I
registrador destino
quantificador de deslocamento
define a função que será utilizada para instruções cujo
código é SPECIAL.
valor imediato com sinal usado para: operadores
lógicos, operadores aritméticos com sinal,
deslocamento de endereço em load/store,
deslocamento de instruções relativo ao PC.
endereço que será deslocado 2 bits à esquerda para
suprir os 28 bits de endereço da instrução jump.
[CONTINUAR ESPECIFICAÇÃO DA LINGUAGEM DE MONTAGEM]
Download