Construindo um processador RISC-V em Verilog parte 1 - Conceitos iniciais

Construindo um processador RISC-V em Verilog parte 1 - Conceitos iniciais

Risco 5 Logo

Antes de tudo, você deve estar se perguntando, porque construir um processador do zero, principalmente em pleno 2024, onde temos dezenas de opções disponíveis no mercado. Bom, posso fornecer várias respostas para esse questionamento, mas dentre elas se destacam duas, a primeira é pela diversão/conhecimento, já a segunda é que nos tornamos programadores melhores quando temos pleno conhecimento de como as coisas funcionam por debaixo dos panos. Tendo informações de qual forma é realizado acesso à memória ou como as instruções são executadas se torna mais fácil construir programas mais complexos e otimizados, além de certas coisas também passarem a fazer mais sentido por serem da forma que são.

O processador

Processador simbolo

Antes de iniciar o desenvolvimento, creio ser necessário definir de forma resumida o que é um processador. De forma bem geral um processador é um grande circuito lógico composto por vários módulos, que é capaz de seguir um conjunto de instruções e realizar operações lógicas e aritméticas.

Ao longo desta sequência de posts estaremos desenvolvendo um processador multiciclo e sem pipeline (o motivo ficará mais claro conforme progredimos), baseando-se na arquitetura RISC-V, e teremos como objetivo executar o mesmo em simulações e em FPGA.

Para aqueles que forem seguir essa sequência de posts, é recomendado ter um certo conhecimento prévio sobre circuitos lógicos e verilog, no final do post vou estar recomendando algumas coisas sobre. Além disso a implementação completa deste processador já está disponível no Github: https://github.com/JN513/Risco-5 (caso você for dar uma espiadinha para ter um pouco de spoiler peço que deixe uma estrelinha no repositório, isso ajuda muito na divulgação do mesmo).

A arquitetura RISC-V

Riscv logo

Como pode ser visto no título do post e como dito anteriormente, iremos implementar um processador baseado na arquitetura RISC-V, possivelmente você deve estar se perguntando o que é uma arquitetura e o que é RISC-V.

Antes de nos aprofundarmos na definição de arquitetura, vamos introduzir um termo crucial: instruções. Processadores de propósito geral, como aqueles encontrados em computadores pessoais e microcontroladores, operam com base em instruções. Em resumo, você fornece uma instrução ao processador, e com base nessa instrução, ele executa uma tarefa, seja ela somar dois números ou realizar qualquer operação lógica.

Agora que entendemos como os computadores lidam com instruções, podemos definir mais claramente o que é arquitetura. Basicamente, uma arquitetura determina a organização interna dos componentes de um processador, incluindo o número de registradores, o modo como os dados são manipulados, o acesso à memória e aos periféricos, entre outras características. Além disso, uma arquitetura também especifica o conjunto de instruções que o processador pode executar. Esse conjunto de instruções é frequentemente referido como ISA (Instruction Set Architecture). Assim, todos os processadores que compartilham uma mesma arquitetura devem ser capazes de executar as mesmas instruções. Essa uniformidade é extremamente útil quando diferentes desenvolvedores criam processadores que precisam ser compatíveis com o mesmo sistema operacional ou software.

Assim, o RISC-V se destaca como apenas mais uma arquitetura, mas difere das demais em dois fatores fundamentais. Primeiramente, é uma arquitetura completamente aberta, permitindo seu uso para fins comerciais sem a necessidade de uma licença. Em segundo lugar, é uma arquitetura RISC, que significa Reduced Instruction Set Computer, ou seja, um conjunto de instruções reduzido.

As arquiteturas RISC têm como princípio que um conjunto de instruções menor e mais simples pode ter o mesmo desempenho que um conjunto de instruções grande com várias instruções complexas. Isso se deve principalmente ao fato de que instruções maiores exigem mais ciclos de clock para serem executadas e necessitam de um hardware maior para sua implementação. Isso acaba resultando na necessidade de operar com frequências de clock menores.

A linguagem Verilog HDL

Existem diversas formas de se realizar o design de circuito digital, isso pode ser feito de formas mais “antigas” como usar uma prancheta e caneta, pode ser feito utilizando ferramentas de “drag and drop” como a disponibilizada pelo software quartus da Altera/Intel FPGA ou pode ser feito através de linguagens de descrição de Hardware (HDL - Hardware Description Language) como VHDL, Verilog HDL e System Verilog. Para este projeto estaremos utilizando Verilog HDL para fazer a descrição do hardware, os principais motivos para esta escolha são: Atualmente verilog e a linguagem de de descrição de hardware mais utilizada para “Asic” e uma das mais utilizadas em FPGAs, e muito mais simples de se manter e escalar o projeto do que das outras formas, nos permite utilizar níveis de abstração maiores, não é uma linguagem com grande verbosidade, etc.

Para realizar o processo de síntese do nosso hardware descrito em Verilog, utilizaremos principalmente as ferramentas disponibilizadas pelo oss cad suite, sendo as principais o simulador IVerilog (Icarus Verilog), o sintetizador Yosys e a ferramenta de placement and route NextPnR. Para alguns casos como na utilização de FPGAs não suportadas pelo Yosys utilizaremos algumas outras ferramentas como o Xilinx Vivado, o principal motivo para a utilização do Oss cad suite e devido a todas as ferramentas contidas nele serem open source.

Como será realizado a descrição do Hardware

Circuito logico

É possível descrever um hardware em diversos níveis distintos, sendo os principais o Transistor-Level, onde o circuito é descrito em termos de transistores individuais, o Gate-Level, onde o circuito é descrito em nível de portas lógicas, e o nível RTL, onde descrevemos o circuito de forma comportamental. A linguagem Verilog nos permite descrever o circuito nos níveis de portas lógicas e RTL, e estaremos adotando o nível RTL. Níveis mais baixos, como o Gate-Level e o Transistor-Level, nos proporcionam um maior controle sobre como o hardware será feito. No entanto, em projetos mais complexos, torna-se extremamente difícil e complicado de manter e expandir. Por esse motivo, e para uma maior legibilidade do projeto, estaremos utilizando o nível RTL, no qual descreveremos o comportamento do circuito e uma ferramenta de síntese ficará encarregada de converter nossa descrição para os níveis mais baixos. Como um grande professor me disse uma vez: “A ferramenta dá conta, não precisa escovar bit por bit”.

Apenas para demonstração, estarei deixando duas descrições em anexo, uma em nível RTL e outra em Gate-Level, para que possam comparar e avaliar qual das duas é mais legível.

Próximas publicações

Nos próximos posts, estaremos realizando a implementação e teste de cada um dos módulos do processador. Após esta fase realizaremos a ligação de todos eles e realizaremos testes no processador como um todo.

Anexos


Comentarios: