Introdução Ao Rocket Chip
A ferramenta Rocket Chip permite gerar diferentes configurações de RISC-V para diferentes ambientes SoC.
Essas configurações são especificadas por meio de parâmetros em linguagem Chisel (Constructing Hardware In a Scala Embedded Language) que podem ser alterados livremente e com isso, pode-se selecionar o que se quer gerar como chip em nosso projeto almejado.
Assim, utiliza-se de um emulador C++ de RLT (Register transfer level).
Rocket Chip é formado por vários submódulos:
- Chisel: Linguagem HDL para desenvolvimento de RTL;
- Rocket: Código-fonte dos cores e caches do Rocket;
- Dramsim2: Simulador de tempos de acesso à DRAM;
- Entre outros.
Algumas configurações possíveis:
- Quantidade memória física;
- Quantidade de bits do endereço virtual;
- Parâmetros de interface de memória;
- E outros.
Simulando Uma Configuração Predefinida No Rocket Chip
Entre os vários diretórios de pastas do projeto, o emulador C++ RTL é executado do diretório /emulator. Um comando de execução default já é conhecido e possui a seguinte sintaxe
make run-asm-tests.
Com este comando, o emulador realizará emulações sobre o assembly realizando testes assim como é possível realizar em benchmarks usando o comando
make run-bmark-tests.
Desta forma, será executado uma emulação de um projeto que esteja em suas configurações padrões sobre o comando escolhido.
Podemos também construir itens com configurações de pequeno porte utilizando
make CONFIG=ExampleSmallConfig.
E para testar, utiliza-se
make CONFIG=ExampleSmallConfig run-asm-tests.
Simulando Uma Nova Configuração No Rocket Chip
Como exemplo, será exibido o procedimento para fazer uma configuração de um sistema de médio porte. Assim:
“Queremos o dobro de números de caminhos em caches L1 I e D sobre uma configuração de pequeno porte”
class MediumConfig extends SmallConfig{ override val knobValues:Any=>Any = { case "L1D_WAYS" => 2 case "L1I_WAYS" => 2 } } class ExampleMediumConfig extends ChiselConfig( new MediumConfig ++ new DefaultConfig)
Esse código especifica que existirá 2 (ao invés de 1) caminhos em cache para L1D e L1I em comparação à configuração SmallConfig. É criado uma nova classe, extendendo a partir da classe SmallConfig. Com isso, haverá uma sobrescrita sobre alguns valores que nos quais foram especificados pelas suas etiquetas e os respectivos novos valores.
Ao final, é instanciado a nova classe MediumConfig como a nova DefaultConfig.
Para realizar a configuração, basta usar o comando especificando o nome da classe que acabamos de criar (ExampleMediumConfig)
make CONFIG=ExampleMediumConfig
e como já ressaltado, para testar utiliza-se do comando
make CONFIG=ExampleMediumConfig run-asm-tests
Sobre Configurações Mais Complexas
Adicionando Novos Parâmetros Ao Rocket Chip
É informado que parâmetros amplamente utilizados pelos projetistas podem ser adicionados à configuração default. Eles são disponibilizados por meio de parâmetros Chisel à implementação.
Adicionando Aceleradores E Sobre Seus Parâmetros
Módulos como aceleradores devem ter seus próprios parâmetros declarados em suas próprias pastas fontes e este será abordado mais a seguir.
Extensões Do ISA E O RoCC
Esclarecendo Conceitos
Para entendermos os tópicos seguintes, é necessário esclarecer alguns termos comumente utilizados por projetistas que utilizam o RISC-V e Rocket Chip.
O primeiro termo é accelerators. Basicamente, aceleradores são procedimentos para execução de dados paralelos num software. Este detalhe no projeto RISC-V é tão importante que os mesmos projetistas deste mencionam que o V do seu nome dá-se também pelo numeral Romano V para significar ‘variantes’ e ‘vetores’ pois seu projeto possui suporte a uma gama de arquiteturas de pesquisas além de vários aceleradores de dados paralelos, entre outros.
Um exemplo disso é a existência de uma extensão própria para a realização de operações de multiplicação e divisão. Nisso é possível que o ISA base seja enxuto para pequenos projeto e que a extensão de operações matemáticas seja independente o suficiente para conter otimizações como aceleradores conectados.
Outro item importante é o RoCC. RoCC é a abreviação de Rocket Custom Coprocessor e é definido para simplificar a adição de aceleradores customizados ao core do Rocket. Rocket e a interface RoCC são usado extensivamente
Este assunto é amplamente abordado no Capítulo 9 do manual ISA (disponível em: https://www2.eecs.berkeley.edu/Pubs/TechRpts/2014/EECS-2014-54.pdf).
Para isso, existe quatro conjuntos de opcodes para extensões não padronizadas e eles são exibidos a seguir. Nela, devemos atentar às lacunas com etiquetas chamadas custom onde são enumeradas de 0 (zero) à 3 (três).
- Dois para operandos source;
- Um para operando destination; e
- Sete bits para campo de função.
- Três bits determinam se a instrução usa o registrador de operandos, também para valores passivos dentro dos registradores rs1 e rs2 ou escrita em respostas no registrador rd.
Sabe-se que, dependendo do acelerador, esses podem ser sempre reaproveitados desde que a instrução também seja enviada por meio da interface RoCC. A instrução pode ser vista como a seguir
Aceleradores RoCC
Implementar a interface RoCC é talvez a maneira mais simplista de criar uma nova extensão para o RISC-V. A cadeia de ferramentas já suporta customizações e não é necessário modificar tal se a modificação encaixa na interface. Além disso, também não é necessário a implementação da interface RoCCIO. Tudo isso está localizado no diretório rocket/src/main/scala/rocc.scala.
Visto de uma forma mais detalhada, a comunicação entre o Rocket e RoCC é exibida a seguir.
Extensões Sem Utilização Do RoCC
Também é possível estender o ISA de diferente forma sem a utilização do RoCC. Entretanto, como dito anteriormente, será exigido mais trabalho do projetista.
Em contrapartida, também existe um trade-off positivo nesta escolha. Isso permite que possa ter mais liberdade e uma integração mais condizente com o propósito final.
Para isso, deve-se realizar atualizações em vários locais como riscv-opcodes, riscv-gnu-toolchain, riscv-isa-sim e no rocket. Por exemplo, no riscv-opcodes é onde fica o repositório de todos as decodificações e também onde é gerado todos os arquivos cabeçalhos, tabela de manuais e outros. Para realizar a alteração, deve-se adicionar a instrução à uma dos arquivos opcodes e então realizar o comando
make install
para gerar novos arquivos de projeto. Desta mesma forma, os outros diretórios também necessitam de suas respectivas atualizações.
Vale relembrar que modificações são propensas a gerarem dependência de instruções. É mencionado que uma simples adição de um novo operando na ALU, requer várias mudanças em todo projeto e consequentemente, a complexidade da alteração de um item é relativamente à sua ‘grandiosidade’ de sua execução.
Linguagem HDL: Rocket Chip Verilog
Verilog Para CADs
O diretório /vsim contém scripts construtores que geram código em Verilog. Para gerar o código Verilog do projeto, basta utilizar o comando de geração make.
O diretório do código gerado contém:
- Códigos em Verilog;
- Conjunto de parâmetros exportados;
- Parâmetros de configuração de memória.
Os parâmetros de configuração de memória são usados em nosso projeto para descobrir qual memória SRAM será requisitada ou gerada.
Depois deste processo, o código em Verilog está pronto para ser utilizado em ferramentas CAD (Computer Aided Design) como simuladores.
Verilog Para FPGA
Da mesma forma que o diretório anterior (/vsim) era utilizado para geração de código de ferramentas CAD, existe outro para geração de código especificamente para hardware reconfiguráveis como o FPGA.
Este diretório encontra-se em /fsim e para gerar os códigos, basta utilizar o make como anteriormente. Ele também gera tipicamente os mesmos arquivos que da execução anterior e o código gerado está pronto para ser adaptado à placa a ser sintetizado.
Article Name: Breve Tutorial do RISC-V: Rocket Chip
Description: Gerenciamento da ferramenta Rocket Chip.
Author: Rodolfo Labiapari Mansur
Publisher Name: Laboratório iMobilis
Referência: http://www2.decom.ufop.br/imobilis/risc-v-rocket-chip/#google_vignette