Mudancas Recentes - Buscar:

Principal

 Objetivos  
 Ementa  
 Livros 

OAC

LOAC

Professores:

  JOSEANA
  ELMAR

CONTATO

CRÉDITOS

editar



Guia de Laboratório RISC-V

Observações

É precisa descompactar o arquivo riscv1.zip.

Os arquivos dentro do .zip contém Systemverilog que compila e funciona, mas só tem algumas funções bem básicas como por exemplo o program counter.

Todos os parâmetros e variáveis necessários estão definidos e a muitas variáveis e atribuído o valor zero ou -1 em algum lugar do código para sugerir um lugar onde você deve fazer a atribuição do valor correto. Algumas vezes o valor correto não é um só, é preciso usar um if ou um case para pegar o valor certo em cada condição de instrução. Não faça um único case enorme.

O livro de Harris é essencial para conseguir fazer esses laboratórios. Se você ficar com dúvida sobre um determinado sinal, clique no esquemático com o botão direito do mouse e escolha View Image. Em seguida dê dois cliques com botão esquerdo do mouse e tecle Ctrl-C. Abra o livro da disciplina e faça Ctrl-F e dentro do campo de busca Ctrl-V.

Dentro de um esquemático, como é o caso de SystemVerilog, sinais e barramentos tem escopo local. Por exemplo o barramento RD da memória de instruções, o barramento RD do banco de registradores e o barramento RD do datapath nada tem a ver um com o outro. Porém, sinais e barramentos podem ser conectados um com outro. Assim por exemplo o barramento RD do controlador está conectado com o barramento RD do processador o qual está conectado com o barramento RD do datapath. Neste caso, o barramento RD do datapath sempre está com o mesmo valor do barramento RD do controlador.

Diferenças entre o livro de Harris e o RISC-V dessa guia:

  • dados e endereços de 8 bits no lugar de 32 bits

Diferença entre o RISC-V de Andrew Waterman, Design of the RISC-V Instruction Set Architecture, 2016 e o RISC-V dessa guia:

  • dados e endereços de 8 bits no lugar de 32 bits

PC e Memória de Instruções

LCD

PCInstrução - - --
 - -  - -  - -  - -  - - --

A instrução addi

LCD

PCInstrução - - --
SrcASrcBALUResult - -  - - --

Centavos

primeira instrução addi correta aparece no LCD15
SrcA igual a zero5
SrcB correto10
ALUResult correto10
resultado da primeira instrução addi dentro do registrador correto15
segunda instrução addi correta aparece no LCD10
SrcA diferente de 0 no segundo addi10
resultado da segunda instrução addi dentro do registrador correto5

A instrução lw

LCD

PCInstrução - - --
SrcASrcBALUResultResultReadDataMemtoReg-

A instrução lw funcionando junto com addi

LCD

PCInstrução - - --
SrcASrcBALUResultResultReadDataMemtoReg-

A instrução sw

LCD

PCInstruçãoWriteDataMemWrite-
SrcASrcBALUResult - -  - - --

Centavos

lw: ReadData diferente de zero10
lw: 70hex < ReadData < 7Ahex *+5
lw: MemtoReg ativado10
lw: RegWrite ativado10
lw: valor que estava em ReadData entra em um registrador10
addi: depois lw funciona+15
sw: 10hex < WriteData < 60hex5
sw: MemWrite acionado, RegWrite desativado, nenhum registrador alterado15
segundo lw depois sw: valor que foi escrito aparece em outro registrador15

* consulte o arquivo memo.mif para saber em quais endereços da memória estão armazenados valores nesta faixa

A instrução beq

O sinal PC' do esquemático aparece no Systemverilog com nome pc_.

LCD

PCInstruçãoWriteDataMemWriteBranch
SrcASrcBALUResultResultReadDataMemtoRegRegWrite

Centavos

pula15
pula para a instrução correta10
RegWrite desativado no beq10
RegWrite ativado no addi e addi funciona10
pula para valores>0 nos registradores da condição *15
não pula se a condição for falsa5
laço10
lw ainda funciona10
sw ainda funciona10

* ULA faz subtração no caso do beq, mas faz soma no caso do addi

Chamada de uma sub-rotina

(Quem quer ser chique chama "sub-rotina" de "método")

Pesquise no guia de programação em C:

  1. Como é feita a chamada da sub-rotina lupi ?
  2. Como é realizado o retorno da sub-rotina lupi para o main ?

Dica: observe tanto os arquivos lupi_main_pc.s e lupi.s para RISC-V como a execução do simulador ISA RISC-V no modo passo-a-passo.

Escreve o seguinte código assembly no seu arquivo inst.s):
.section .text
.globl main
main:   addi t3, zero, 0x67   /* uma instrução qualquer, ela não precisa funcionar, só precisa avançar o PC */
        ???? lupi             /* a chamada da sub-rotina lupi */
        addi t3, zero, 0x67   /* uma instrução qualquer, ela não precisa funcionar, só precisa avançar o PC */
        addi t3, zero, 0x67   /* uma instrução qualquer, ela não precisa funcionar, só precisa avançar o PC */
        addi t3, zero, 0x67   /* você deve ter uma quantidade de instruções aqui diferente da quantidade do seu vizinho */
lupi:   addi t3, zero, 33     /* esta instrução seria o miolo da sub-rotina lupi */
        ????                  /* o retorno da sub-rotina lupi */

Faça este código funcionar no seu processador RISC-V.

Dicas:

  • veja primeiro se sua instrução addi avança corretamente o PC. Ela deve mudar o conteúdo de t3, mas não precisa ser o valor correto.
  • use Ctrl-F na tese do RISC-V
  • IMM <= instruction[27:22]<<2; // embora não está correto no caso do addi, use mesmo assim também para o addi
  • não mexe na variável pc_, trabalhe com a variável ppc
  • para a chamada, use o barramento pclink e o sinal de controle link
  • pode usar os sinais de controle ju e jr
  • para a volta, use o barramento PCReg
  • para a volta, não é preciso observar IMM

Centavos

assembly correto10
pula10
pula para a instrução correta5
armazena o endereço de retorno10
na volta, pula10
na volta pula para a instrução correta15
além de tudo isso, addi funciona corretamente15

Unidade de Entrada/Saída

Para encaminhar um valor para a saída usa-se a intrução sw, para pegar um valor de entrada usa-se a instrução lw.

A entrada EN habilita o resgistrador.

Notas

instrução lw correta para acessar entrada10
último endereço do espaço de endereçamento aparece em ALUResult5
valor de SWI[4:0] aparece em ReadData20
valor de SWI[4:0] aparece no registrador correto15
instrução sw correta para acessar saida10
valor correto aparece no WriteData10
valor correto aparece nos LED[4:0]20
valor permanece nos LED[4:0] até que um novo sw para a saída for realizado10
lw e sw para memória continuam funcionando20

Valores maiores do que 4 devem ser usados para entrada e saída. Valores e registradores usados devem ser diferentes daqueles do seu vizinho.

Interrupção

O registrador SEPC é um registro de controle e status (Control/Status Register). A instrução CSRR serve para ler um registro de controle e status (Control/Status Register Read).

A especificação para a instrução CSSRS está no documento riscv-priv-spec-1.7.pdf

O opcode da instrução CSSRS é o mesmo de ECALL e EBREAK.

O formato da instrução CSSRS é parecido ao tipo I, sendo que o campo IMM é usado para indicar qual registro de controle e status a instrução deve usar. O número que indica o registador SEPC é 0x141. O valor do campo funct3 é 2 (010 em binário). O campo RS1 aponta para o registrador zero no caso da instrução CSSR.

Centavos

programa de software correto*10
PC avança normalmente enquanto não houver interrupção5
pula10
pula somente depois de uma mudança na entrada5
pula para a a rotina da atendimento à interrupção5
armazena o endereço de retorno15
na volta, pula5
na volta pula para a instrução correta20
a rotina da atendimento à interrupção recolhe o valor da entrada, some 3 e coloca o resultado na saída35
*Na rotina principal deve ter uma série de pelo menos 5 instruções addi diferentes entre eles e diferentes das do seu vizinho.

Privilégio

RISC-V define quatro níveis de privilégio, na nossa implementação usaremos só dois: 0=User, 1=Supervisor.

O nível de privilégio está no registrador mstatus. No RISC-V este registrador tem 32 bits, mas na nossa implementação este registrador tem só 1 bit. O registrador fica dentro do controller. Na nossa implementação mstatus é resetado para 0.

A unidade de gerenciamento de memória do RISC-V possibilita reservar determinadas faixas de endereços para poderem ser acessados somente no modo Supervisor. Na nossa implementação, no modo User, nem sw nem lw podem ser executados. Executando sw ou lw em modo User deve causar uma exceção chamada "Environment Call exception". Na nossa implementação, a "Environment Call exception" deve pular para o endereço 0x3C. Na nossa implementação, para simplificar, não iremos colocar nenhuma instrução específica naquele endereço. Se o PC chegar naquele endereço, o experimento está encerrado (pode travar o clock).

Para poder acessar a memória a partir do modo User, é necessário executar um ECALL (funct12=000000000000, funct3=privilégio_desejado). Esta instrução copia o privilégio desejado de funct3 (na nossa implementação o bit 12 da instrução) para mstatus. Na nossa implementação, a instrução ECALL sempre pula para o endereço 0x30. O endereço de retorno do ECALL deve ser guardado no registrador sepc.

A volta do ECALL é feita através da instrução SRET (mesmo opcode de ECALL, funct12=000100000010). Além de resetar o privilégio no registrador mstatus, a instrução SRET do RISC-V também coloca o valor de sepc de volta no PC. Na nossa implementação, SRET somente precisa resetar mstatus. As instruções csrr e jr podem ser usados para voltar da chamada do ECALL.

Notas

lw causa Environment Call exception4
ECALL (antes do lw) pula para 0x305
lw funciona normalmente6
SRET é executado7
volta do ECALL8
lw causa Environment Call exception9
ECALL com privilégio desejado igual a zero causa Environment Call exception no lw10

Recomenda-se para este exercício desabilitar a interrupção, deixando o sinal interrupt sempre igual a 0.

Cache

Instancie a cache descrita no arquivo cache.sv e faça testes para demonstrar seu funcionamento. Cada teste diferente vale 1 ponto de nota. O teste precisa estar explicado em comentário e todos os registradores e valores usados precisam ser diferentes daqueles usados por seu vizinho, do lado, da frente, de trás e da mesma bancada.

© 2008 Profs. Elmar Melcher e Joseana Fechine. Monitores: Sergio Espinola e Fabricio Lelis - DSC/UFCG
Modificada em March 22, 2022, at 10:59 AM