Objetivos Ementa Livros Professores: JOSEANA ELMAR
|
Nesta página, veremos como programar em C, em Assembler e por fim em código de máquina mesmo. Primeiro iremos programar o processador Intel do seu PC, depois o processador RISC-V do Labarc. Para simular em casa siga estas instruções. Programar em CAqui usamos a linguagem C para desenvolver software. Mostramos várias formas como se pode testar o software e como compilar ele para linguagem assembly para finalmente carregá-lo na forma de código de máquina no nosso processador RISC-V que está implementado na placa de FPGA. Dica para quem não sabe usar Linux: selecione arrastando o botão esquerdo do mouse, cole com botão do meio (sim, mouse tem botão no meio, é o da rodinha!). Exemplo de código C (usa dois arquivos) int lupi(register int x, register int y) { register int s=0; do { s = s+x+y; x = x-y; } while (x>0); return s; } arquivo
Este código não tem o objetivo de implementar algum algorítmo específico, trata-se somente de um exemplo mesmo. Executar em PC com processador Intel e Sistema Operacional LinuxQueremos primeiro testar o nosso código C em um PC. Compilador para Arquitetura IntelCompilação para assembly do processador Intel para gerar o arquivo A opção Visualize o arquivo gerado: Para poder receber valores de entrada de uma linha de comando em Linux e poder devolver o resultado para a linha de comando é preciso uma casca ou envelope (wrapper) - arquivo #include "lupi.h" int main(int argc,char *argv[]) { register int x,y; x = argv[1][0]-'0'; // primeira letra do primeiro argumento convertida para valor entre 0 e 9 y = argv[2][0]-'0'; // primeira letra do segundo argumento return lupi(x,y); } Para deixar o código mais simples, só são possíveis valores de entrada de 0 a 9. O comando para compilar a casca é Assembler IntelChamamos o assembler para processador Intel, fornecendo os códigos assembly da casca e da subrotina lupi, para que seja gerado código de máquina: O arquivo executável ExecuçãoTestando no PC: Simular no simulador ISA RISC-VAgora queremos usar um simulador de ISA (Instruction Set Arquitecture) do RISC-V. Este simulador roda em PC e se chama spike.
No diretório do simulador de Ícaro encontra-se um rm *.sOs argumentos de linha de comando precisam ser passados dentra da variável ARGS : make isa ARGS="7 2" Dê Enter para avançar a simulação passo-a-passo. Observe os argumentos nos registradores Observe o resultado sendo formado no registrador Simular em simulador de placa FPGAAgora usamos software bare-metal, ou seja, sem sistema operacional e sem argumentos de linha de comando, para rodar-lo num processador RISC-V construído aqui no Labarc, em Systemverilog, ou seja, usando always_comb e always_ff. Para isso, a casca precisa ser diferente para usar a unidade de Entrada/Saída da nossa CPU - arquivo #include "lupi.h" void __attribute__ ((naked)) main() { // naked significa desconsiderar a pilha, nao precisa salvar nada na pilha volatile int * const io = (int *)(0x3F*4); // apontador para entrada/saida // o apontador aponta para algo que é volátil, ou seja, algo que pode mudar fora do controle do software // o valor do apontador é constante, ou seja, o endereço não pode mudar int x,y; x = *io; // primeiro pega x de SWI[4:0] y = *io; // no clock seguinte y *io = lupi(x,y); // resultado vai para saida - LED[4:0] } apague o arquivo RISCV_sim conforme instruções aqui e dê o comando./RISCV_sim Este último comando carrega automaticamente o arquivo Use a Com clock ativado e ainda com reset ativado, você precisa fornecer o primeiro argumento (nos exemplos acima usamos o valor 7 como primeiro argumento) em SWI[3:0]. ![]() Agora você pode desativar o reset, até que o primeiro argumento esteja carregado no registrador ![]() Ative novamente o clock e verifique que ![]() Rodar em processador RISC-V físicoCrie um .zip com os arquivos Programar um processador RISC-V em AssemblyAqui iniciamos escrevendo o software diretamente em linguagem de Assembly. Primeiro dê o comandomake isa-clean para apagar os arquivos C. Deve-se criar um arquivo contendo as instruções em assembly para serem geradas as instruções binárias, deve ser uma instrução por linha. O arquivo deve ter a extensão .s. Ex.: inst.s
O arquivo deve estar no mesmo diretório onde está o projeto e a descrição Verilog da memória de instruções.
- Um par de - Diretivas de assembly:
inst.s ): .section .text .globl main main: addi a2,zero,55 add a3,a2,a1 /* Iremos usar o registrador sp para fazer acessos à memória. Spike supõe RAM a partir do endereço 0x80000000. A instrução lui coloca este valor em sp. Não precisa usar esta instrução para a implementação FPGA. */ lui sp,0x80000 addi sp,sp,0x40 pula: lw a1,8(sp) sw a3,16(sp) bne a2,a3,pula fim: .skip 0x20 - (fim -main) /* cria espaço ate o endereço 0x20 */ lw t4, 48(s0) /* esta instrução ficará no endereço 0x20 */ Usar o simulador ISA para RISC-VNo diretório do simulador de Ícaro, dê o comando:make isa Agora é só dar Enter para executar uma instrução por vez. Observe que as instruções lw e sw só podem ser usados no spike com endereços múltiplos de 4 e maior do que 0x80000000. No caso da nossa implementação física do RISC-V, endereços de memória tem seus 24 bits mais significados cortados, assim o endereço 0x80000000 se torna 0x00. Usar o simulador de placa FPGA de ÍcaroDê os comandos:make inst.objdump ./RISCV_sim Rodar em processador RISC-V físicoCarregue o arquivo assembly no simulador remoto. Programar um processador RISC-V em código de máquinaAqui usamos código de máquina em notação binária mesmo. Primeiro dê o comandomake isa-clean para apagar os arquivos assembly. Use este exemplo completo (pode colocar num arquivo chamadoinst.101 ): ; para um comentario inicie a linha com ; ; campos da instrução tipo I ; imm rs1 funct3 rd opcode 0000 0100 0000 00000 000 00010 001 0011 ; addi sp,zero,0x40 0000 0001 0001 00000 000 01011 001 0011 ; addi a1,zero,0x11 0000 0010 0010 00000 000 01100 001 0011 ; addi a2,zero,0x22 ; campos da instrução tipo R ; funct7 rs2 rs1 funct3 rd opcode 0000 000 01011 01100 000 01101 011 0011 ; add a3,a2,a1 ; campos das instruções tipo S e SB ; imm rs2 rs1 funct3 imm opcode 0000 000 01101 00010 010 10000 010 0011 ; sw a3,16(sp) Usar o simulador ISA para RISC-VNo diretório do simulador de Ícaro, dê os comando:make isa Usar o simulador de FPGA de Ícaro
Este comando carrega automaticamente o arquivo Rodar em processador RISC-V físicoCarregue o arquivo Centavos
Só vale uma única execução para cada linha. Se fizer várias, vale a última. A linha correspondente da coluna resultado deve ser copiada sem tirar nada nem acrescentar nada para a linha de descrição (a segunda linha do arquivo). No caso de vários arquivos, nome e descrição devem constar no arquivo que contém o O código C, assembly ou binário pode ser qualquer coisa, não precisa ter uma função específica. Porém, tem que compilar/assemblar/disassemblar sem erro e entrar na memória de instruções da implementação RISC-V dentro da FPGA e ser realmente executado. Mais informações |