Projeto 1 - Um simulador simples do procesador RISC-V¶
Nesse projeto, cada aluno deve implementar um simulador básico do processador RISC-V. A intenção é praticar conceitos de simulação de processadores, além de ter uma visão da eficiência desses algoritmos.
Objetivos¶
Para completar com sucesso esse projeto, é necessário:
- Ler uma representação de código de um programa
- Simular o processador
- Gerar um log de execução
Requisitos¶
O simulador pode ser implementado na sua linguagem de preferência. É importante que ela seja executável no computador do professor. Portanto, você deve fornecer documentação suficiente para a correta execução do código. Veja mais detalhes abaixo.
Especificação¶
Você deve implementar um simulador do processador RISC-V RV32IM, que significa a versão de 32 bits com as instruções básicas e também as instruções de multiplicação e divisão.
Você pode utilizar como referência o simulador Spike para verificar seu código.
As seguintes funcionalidades básicas são necessárias:
- Linha de log a cada instrução executada, veja a especificação do log desejado abaixo.
- Contagem de ciclos de execução: neste primeiro momento, considere que cada instrução gaste um ciclo para executar. É importante que você tenha uma infraestrutura que permita alterar estes valores pois essa é uma funcionalidade necessária em simuladores de processadores
- Você deve ser capaz de executar um programa saído de um compilador/linker. É opcional emular um sistema operacional. Você pode utilizar o objdump ou objcopy para converter os arquivos executáveis num formato mais direto seu. Neste caso, implemente esta ação através de um script já com as linhas de comando corretas
- Seu simulador deve ser capaz de executar todos os programas de inteiros do ACStone (isto significa que não precisa executar os programas de ponto flutuante).
- Seu simulador deve ser capaz de executar o DryStone e o CoreMark
- Encapsule todos os acessos à memória através de alguma função. Isso permite que você possa inserir temporização na memória alterando apenas essa função.
Entrega¶
A entrega será realizada através do GitHub Classroom, o link de submissão será colocado no Google Classrom para você entrar no projeto. Você deve preencher o README e complementar com mais informações sobre seu código.
Sua árvore de entrega deve ter uma pasta chamada test que contenha todos os códigos do ACStone e demais benchmarks necessários. Você deve partir do código fonte e ter um script que compile e gere os arquivos necessários para entrada do seu simulador.
Sua árvore de entrega deve ter uma pasta para o DryStone e outra para o CoreMark, realizando todas as etapas necessárias para compila-lo e gerar os arquivos necessários para entrada do seu simulador.
Você não deve, em hipótese alguma, submeter os arquivos binários dos programas de teste nem mesmo dos compiladores ou de outras ferramentas adicionais.
Você deve gerar um arquivo de log de saída para cada programa e trocar o tipo dele para .log. Por exemplo, o programa 000.main.c deve ter o log chamado 000.main.log. Você deve gerar um arquivo de log para cada programa de teste do ACStone.
Atualize o README.md do seu proejto para que contenha um relatório compacto sobre o seu projeto. O relatório deve conter:
- Descrição geral do seu projeto
- Descrição do seu ambiente de desenvolvimento
- Descrição do seu algoritmo de simulação
- Descrição de como você testou seu projeto
- Considerações gerais sobre seu aprendizado nesse projeto
- Desempenho do seu simulador conforme DryStone e CoreMark
Colocarei uma atividade no Google Classroom para entrega do link do repositório e do relatório. A entrega deve ser feita até o dia 31/08/2024.
Formato do Log de instruções¶
O log de instruções deverá ser conforme o padronizado abaixo. Cada instrução executada deve gerar uma linha de log. Cada campo da linha tem um tamanho fixo, exceto o último e deve ter um espaço entre cada campo. A linha possui 6 campos conforme abaixo
- Endereço do PC da instrução atual, em hexadecimal, com 8 dígitos. Ex: PC=00000100
- Instrução em hexadecimal. Apenas o valor em hexadecimal dos 32 bits da instrução entre colchetes. Ex.: [012345678]
- Valor do registrador de destino (rd) após a instrução. Ex.: considerando o registrador 15 como destino, x15=000AAA00. Note que nem todas as instruções escrevem num registrador, mas veja que os registradores estão sempre nos mesmos campos em bits nas instruções. Então você deve imprimir sempre o registrador indicado pelos bits 7-11 da instrução após a instrução. Veja sobre nomes dos registradores abaixo.
- Valor do registrador de origem 1 (rs1) antes da instrução. Ex.: considerando o registrador 3 como origem, x03=99988877. Observe o zero entre o x e o 3 para padronizar a formatação. Aqui você deve imprimir o registrador indicado pelos bits 15-19 da instrução, independente da instrução fazer uso desses bits para indexar um registrador. Veja sobre nomes dos registradores abaixo.
- Valor do registrador de origem 2 (rs2) antes da instrução. De forma similar ao item anterior, utilizando os bits 20-24. Veja sobre nomes dos registradores abaixo.
- Dissassembly da instrução. Imprima o mnemônico (sem pseudo instrução) com tamanho de 8 espaços, seguido dos registradores e campos de imediato conforme a sintaxe da instrução. Aqui você deve imprimir tudo em decimal, tomando cuidado para utilizar representação sinalizada onde for necessário. Utilize a nomenclatura conforme a ABI (dica: declare um vetor de nomes de registrador com o nome de cada um corretamente e apenas indexe com o índice do registrador). Aqui você não precisa adicionar zero à esquerda do registrador para escrever com dois dígitos.
Como sugestão de abordagem sobre a implementação, monte a linha de log numa estrutura de dados e passe para uma função fazer a impressão. Assim a saída ficará mais uniforme no seu código. Você pode fazer algo similar com o disassembly indicando o formato em que a instrução deve ser escrita na tela.
Avaliação¶
Cada arquivo dos programas de entrada será considerado na avaliação. O seu código será avaliado quanto a corretude dos logs de saída do seu simulador.
Sua nota nessa avaliação será dada pela seguinte fórmula:
Atenção
Caso neessário, o aluno será chamado para apresentar o código e explicar o funcionamento do mesmo, podendo impactar na nota acima.