Compartilhamento de tecnologia

Teste de conformidade para arquitetura Riscv

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

A razão pela qual nos concentramos diretamente no riscv-arch-test é porque a estrutura de teste RISCOF usa riscv-arch-test.
Insira a descrição da imagem aqui

1. O teste arquitetônico

Um teste de arquitetura é um teste único que representa o menor código de teste que pode ser compilado e executado. Ele está escrito em código assembly e seu produto é uma assinatura de teste. Um teste de arquitetura pode consistir em vários casos de teste.

2. O pool de testes arquitetônicos RISC-V

O pool de testes arquitetônicos RISC-V consiste em todos os testes arquitetônicos aprovados que podem ser compilados pela estrutura de teste em um conjunto de testes arquitetônicos. As bibliotecas de teste da arquitetura RISC-V devem ser independentes do alvo de teste (e, portanto, devem ser executadas corretamente em qualquer alvo compatível). Observe que este teste não funcional não substitui a verificação ou teste do dispositivo.

2.1 Estrutura do pool de testes

architectural-tests-suite (root)
|-- <architecture>_<mode>/<feature(s)>, where
<architecture> is [ RV32I | RV64I | RV32E ]
<mode> is [ M | MU | MS | MSU ], where
   M   Machine      mode tests - tests execute in M-mode only
   MU  Machine/User mode tests - tests execute in both M- & U-modes (S-mode may exist)
   MS  Machine/Supv mode tests - tests execute in both M- & S-modes (not U-mode)
   MSU All          mode tests - tests execute in all of M-, S-, & U-Modes
<feature(s)> are the lettered extension [A | B | C | M ...] or subextension [Zifencei | Zam | ...] when the tests involve extensions, or more general names when tests cut across extension definitionss (e.g. Priv, Interrupt, Vm). The feature string consists of an initial capital letter, followed by any further letters in lower case.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Registro de características do conjunto de instruções do processador no modo máquina (MISA)
misa = 0x800000000094112f
Representação binária: 100000000000000000000000000000000000100101000001000100101111
Insira a descrição da imagem aqui

teste-de-arquitetura-riscv/conjunto-de-testes-riscv$ ls
env/ Makefile.include README.md rv32e_m/ rv32i_m/ rv64i_m/
teste-de-arquitetura-riscv/conjunto-de-testes-riscv/rv64i_m$ ls
A/ B/ C/ CMO/ D/ F/ I/ K/ M/ privilégio/ P_não ratificado/ Zfh/ Zfinx/ Zicond/ Zifencei/

3. O conjunto de testes arquitetônicos RISC-V

O conjunto de testes arquitetônicos RISC-V é um conjunto de testes selecionados do pool de testes arquitetônicos para testar a conformidade de uma configuração RISC-V específica. Os resultados dos testes são obtidos na forma de assinatura do conjunto de testes. A seleção do teste é baseada na configuração de asserção, especificação, ambiente de execução ou requisitos da plataforma do destino. Um processador ou modelo de processador compatível deve exibir a mesma assinatura Gold Reference Test Suite que a configuração específica que está sendo testada.

4. O caso de teste

Os casos de teste fazem parte dos testes de arquitetura e testam apenas uma função da especificação.
Nota: Um teste pode conter vários casos de teste e cada caso de teste possui suas próprias condições de inclusão de teste (definidas pelo parâmetro cond_str da macro RVTEST_CASE).

4.1 Nomenclatura de teste

<test objective>-<test number>.S
  • 1

teste-de-arquitetura-riscv/conjunto-de-testes-riscv/rv64i_m/I/src$ ls
add-01.S e-01.S bge-01.S bne-01.S lb-align-01.S lhu-align-01.S misalign1-jalr-01.S sd-align-01.S slliw-01.S sltiu-01.S sraiw-01.S srliw-01.S sw-align-01.S
addi-01.S andi-01.S bgeu-01.S fence-01.S lbu-align-01.S lui-01.S or-01.S sh-align-01.S sllw-01.S sltu-01.S sraw-01.S srlw-01.S xor-01.S
addiw-01.S auipc-01.S blt-01.S jal-01.S ld-align-01.S lw-align-01.S ori-01.S sll-01.S slt-01.S sra-01.S srl-01.S sub-01.S xori-01.S
addw-01.S beq-01.S bltu-01.S jalr-01.S lh-align-01.S lwu-align-01.S sb-align-01.S slli-01.S slti-01.S srai-01.S srli-01.S subw-01.S

5. Infraestrutura de teste de montagem (tome ./rv32i_m/I/src/add-01.S como exemplo)

//
// This assembly file tests the add instruction of the RISC-V I extension for the add covergroup.
// 
#include "model_test.h"
#include "arch_test.h"
RVTEST_ISA("RV32I")

.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN

#ifdef TEST_CASE_1

RVTEST_CASE(0,"//check ISA:=regex(.*32.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;",add)

RVTEST_SIGBASE( x3,signature_x3_1)

inst_0:
// rs2 == rd != rs1, rs1==x4, rs2==x24, rd==x24, rs1_val > 0 and rs2_val > 0, rs2_val == 1, rs1_val == (2**(xlen-1)-1), rs1_val != rs2_val, rs1_val == 2147483647
// opcode: add ; op1:x4; op2:x24; dest:x24; op1val:0x7fffffff;  op2val:0x1
TEST_RR_OP(add, x24, x4, x24, 0x80000000, 0x7fffffff, 0x1, x3, 0, x18)

inst_1:
// rs1 == rs2 != rd, rs1==x10, rs2==x10, rd==x28, rs1_val > 0 and rs2_val < 0, rs2_val == -257, rs1_val == 131072
// opcode: add ; op1:x10; op2:x10; dest:x28; op1val:0x20000;  op2val:0x20000
TEST_RR_OP(add, x28, x10, x10, 0x40000, 0x20000, 0x20000, x3, 4, x18)

inst_2:
// rs1 == rs2 == rd, rs1==x21, rs2==x21, rd==x21, rs1_val < 0 and rs2_val < 0, rs1_val == -16777217
// opcode: add ; op1:x21; op2:x21; dest:x21; op1val:-0x1000001;  op2val:-0x1000001
TEST_RR_OP(add, x21, x21, x21, 0xfdfffffe, -0x1000001, -0x1000001, x3, 8, x18)
......
......
......
RVTEST_CODE_END
RVMODEL_HALT

RVTEST_DATA_BEGIN
.align 4

rvtest_data:
.word 0xbabecafe
.word 0xbabecafe
.word 0xbabecafe
.word 0xbabecafe
RVTEST_DATA_END

RVMODEL_DATA_BEGIN
rvtest_sig_begin:
sig_begin_canary:
CANARY;

signature_x3_0:
    .fill 0*(XLEN/32),4,0xdeadbeef

signature_x3_1:
    .fill 17*(XLEN/32),4,0xdeadbeef

signature_x8_0:
    .fill 16*(XLEN/32),4,0xdeadbeef

signature_x1_0:
    .fill 512*(XLEN/32),4,0xdeadbeef

signature_x1_1:
    .fill 43*(XLEN/32),4,0xdeadbeef

#ifdef rvtest_mtrap_routine

tsig_begin_canary:
CANARY;
mtrap_sigptr:
    .fill 64*(XLEN/32),4,0xdeadbeef
tsig_end_canary:
CANARY;

#endif

#ifdef rvtest_gpr_save

gpr_save:
    .fill 32*(XLEN/32),4,0xdeadbeef

#endif

sig_end_canary:
CANARY;
rvtest_sig_end:
RVMODEL_DATA_END
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91

Uma breve explicação do código assembly acima é a seguinte:

  1. Cabeçalho para incluir comentários

#Este arquivo de montagem testa a instrução add da extensão RISC-V I para o covergroup add.

  1. Inclui arquivos de cabeçalho

#incluir “model_test.h”
#incluir “arch_test.h”

Cada teste deve incluir apenas os seguintes arquivos de cabeçalho:
model_test.h - define macros específicas do alvo, incluindo macros obrigatórias e opcionais: (por exemplo, RVMODEL_xxx)
arch_test.h - define macros de teste predefinidas, incluindo macros obrigatórias e macros opcionais: (como RVTEST_xxx)

  1. Defina o TVM do teste

RVTEST_ISA(“RV32I”)

  1. Código de inicialização específico do alvo de teste

RVMODEL_BOOT

  1. Início da rotina de inicialização do GPR e código de teste

RVTEST_CÓDIGO_INÍCIO

  1. Defina a string RVTEST_CASE e as condições

#ifdef CASO_DE_TESTE_1
// este teste é destinado a dispositivos que implementam a extensão rv32I e requer a habilitação da compilação
// macro TEST_CASE_1. Este teste contribuirá para o rótulo de cobertura “add”.
RVTEST_CASE(0,“//verificar ISA:=regex(.32.);verifique ISA:=regex(.EU.);def TEST_CASE_1=Verdadeiro;”,adicionar)

  1. Inicializar ponteiro para a região de assinatura

RVTEST_SIGBASE( x16,signature_x16_1) // x16 apontará para o rótulo signature_x16_1 na região da assinatura

  1. Defina os casos de teste
inst_0:
// rs2 == rd != rs1, rs1==x4, rs2==x24, rd==x24, rs1_val > 0 and rs2_val > 0, rs2_val == 1, rs1_val == (2**(xlen-1)-1), rs1_val != rs2_val, rs1_val == 2147483647
// opcode: add ; op1:x4; op2:x24; dest:x24; op1val:0x7fffffff;  op2val:0x1
TEST_RR_OP(add, x24, x4, x24, 0x80000000, 0x7fffffff, 0x1, x3, 0, x18)

inst_1:
// rs1 == rs2 != rd, rs1==x10, rs2==x10, rd==x28, rs1_val > 0 and rs2_val < 0, rs2_val == -257, rs1_val == 131072
// opcode: add ; op1:x10; op2:x10; dest:x28; op1val:0x20000;  op2val:0x20000
TEST_RR_OP(add, x28, x10, x10, 0x40000, 0x20000, 0x20000, x3, 4, x18)
...
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
//Tests for a instructions with register-register operand
#define TEST_RR_OP(inst, destreg, reg1, reg2, correctval, val1, val2, swreg, offset, testreg) 
    TEST_CASE(testreg, destreg, correctval, swreg, offset, 
      LI(reg1, MASK_XLEN(val1))                        ;
      LI(reg2, MASK_XLEN(val2))                        ;
      inst destreg, reg1, reg2                        ;
    )
#define TEST_CASE(testreg, destreg, correctval, swreg, offset, code... )        ;
    code                                ;
    RVTEST_SIGUPD(swreg,destreg,offset)        ;
    RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval)

 /* automatically adjust base and offset if offset gets too big, resetting offset                                 */
 /* RVTEST_SIGUPD(basereg, sigreg)          stores sigreg at offset(basereg) and updates offset by regwidth         */
 /* RVTEST_SIGUPD(basereg, sigreg,newoff) stores sigreg at newoff(basereg) and updates offset to regwidth+newoff */
#define RVTEST_SIGUPD(_BR,_R,...)                        ;
  .if NARG(__VA_ARGS__) == 1                                ;
        .set offset,_ARG1(__VA_OPT__(__VA_ARGS__,0))        ;
  .endif                                                ;
  CHK_OFFSET(_BR, REGWIDTH,0)                                ;
  SREG _R,offset(_BR)                                        ;
  .set offset,offset+REGWIDTH
  
  RVMODEL_IO_ASSERT_GPR_EQ 定义在target的model_test.h中```

在咱们得model_test.h中将RVMODEL_IO_ASSERT_GPR_EQ 宏定义如下:比较错误的话,往0xF00000801

```c
#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I)  
    li _S, 0xF0000080;         
    mv t0, _R;                 
    li t3, _I;                 
    beq t0, t3, 1f;            
    li t2, 1;                  
    sw t2, 0(_S);              
    j 2f;                      
1:                             
    li t2, 0;                  
    sw t2, 0(_S);              
2:                             
    nop;```

在tb.v中加入监测对AXI 写地址总线,地址0xF0000080的监测,如果出现fail_cnt >0,可以判断该testcase错误

```c
// RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) used to check destreg == correctval
// destreg != correctva write testreg 1, else write testreg 0
always @(posedge `CPU_CLK) begin
    if ((cpu_awaddr[31:0] == 32'hF000_0080) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) begin
       if(`SOC_TOP.biu_pad_wdata == 1'b1) begin
         fail_cnt ++;
       end
    end
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  1. Alterar registro de base de assinatura
// this will change the signature base register to x3. x3 will not point to signature_x3_0 in
// the signature region
RVTEST_SIGBASE( x3,signature_x3_0)

// continue with new test cases ..
TEST_RR_OP(add, x4, x24, x27, 0x55555955, 0x00000400, 0x55555555, x3, 0, x5)
...
...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  1. Finalize o teste e interrompa o teste-alvo
RVTEST_CODE_END
RVMODEL_HALT
  • 1
  • 2
  1. Criar seção de dados de entrada de teste
RVTEST_DATA_BEGIN
rvtest_data:
.word 0xbabecafe
RVTEST_DATA_END
  • 1
  • 2
  • 3
  • 4
  1. Criar região de assinatura pré-carregada
RVMODEL_DATA_BEGIN
rvtest_sig_begin:
sig_begin_canary:
CANARY;

signature_x3_0:
    .fill 0*(XLEN/32),4,0xdeadbeef

signature_x3_1:
    .fill 17*(XLEN/32),4,0xdeadbeef

signature_x8_0:
    .fill 16*(XLEN/32),4,0xdeadbeef

signature_x1_0:
    .fill 512*(XLEN/32),4,0xdeadbeef

signature_x1_1:
    .fill 43*(XLEN/32),4,0xdeadbeef

#ifdef rvtest_mtrap_routine

tsig_begin_canary:
CANARY;
mtrap_sigptr:
    .fill 64*(XLEN/32),4,0xdeadbeef
tsig_end_canary:
CANARY;

#endif

#ifdef rvtest_gpr_save

gpr_save:
    .fill 32*(XLEN/32),4,0xdeadbeef

#endif

sig_end_canary:
CANARY;
rvtest_sig_end:
RVMODEL_DATA_END
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

6. A assinatura do caso de teste

Uma assinatura de caso de teste é representada por um único ou vários valores. O valor será gravado na memória começando no endereço especificado por RVMODEL_DATA_BEGIN e terminando no endereço especificado por RVMODEL_DATA_END. As assinaturas são facilmente geradas usando a macro RVTEST_SIGUPD.

7. A assinatura do teste

A assinatura de teste é o valor característico gerado pela execução do teste de arquitetura. Uma assinatura de teste pode consistir em múltiplas assinaturas de casos de teste, prefixadas por uma linha separada contendo o nome do teste e um valor exclusivo indicando sua versão. O alvo de teste é responsável por extrair os valores da memória e formatá-los adequadamente, utilizando os metadados fornecidos pelo framework, utilizando as macros RVMODEL_DATA_BEGIN e RVMODEL_DATA_END.O valor da assinatura do caso de teste é escrito em linhas, começando no byte mais significativo à esquerda, no formato<hex_value> , onde o comprimento do valor será de 32 bits (ou seja, 8 caracteres), enquanto o cálculo do teste real não leva em consideração o comprimento do valor. Os arquivos devem ser armazenados a partir do valor do endereço de assinatura mais baixo (ou seja, de RVMODEL_DATA_BEGIN a RVMODEL_DATA_END). Além disso, a assinatura deve sempre começar em um limite de 16 bytes (128 bits) e o tamanho da assinatura deve ser um múltiplo de 4 bytes (ou seja, também deve terminar em um limite de 4 bytes).

8. A assinatura do conjunto de testes

Uma assinatura de conjunto de testes é definida como um conjunto de assinaturas de teste válidas para um determinado conjunto de testes de arquitetura. Representa a assinatura de teste do conjunto de testes arquitetônicos selecionado para uma configuração RISC-V específica.

9. Estrutura de teste RISCOF

RISCOF - O RISC-V Compatibility Framework é um framework baseado em Python que permite o uso de um conjunto de conjuntos de testes arquitetônicos RISC-V para testar alvos RISC-V (implementações de hardware ou software) quanto à compatibilidade com o padrão RISC-V Golden Reference Sexo modelo.
Insira a descrição da imagem aqui
Validador de configuração RISC-V: RISCV-Config
Gerador de teste de conformidade RISC-V: RISC-V CTG
Cobertura RISC-V ISA: RISC-V ISAC
Para que o RISCOF execute o teste normalmente, é necessário fornecer o seguinte conteúdo:

  • config.ini: Este arquivo é um arquivo de configuração básico e segue a sintaxe ini. Este arquivo irá capturar informações como: o nome do plugin DUT/referência, o caminho para o plugin, o caminho para o arquivo YAML baseado em riscv-config, etc.
  • Diretório dut-plugin: RISCOF requer que o modelo DUT testado seja fornecido na forma de um plug-in Python. Um plug-in Python é na verdade um arquivo Python que contém certas funções padrão e definidas para realizar atividades de compilação de teste, execução e extração de assinatura. O nome deste arquivo Python precisa ser prefixado com riscof_ e deve existir no diretório dut-plugin. Você pode consultar a seção do arquivo de plug-in Python para aprender como escrever esse arquivo Python.
    Este diretório também precisa conter os arquivos isa e YAML da plataforma baseados em riscv-config, que fornecem a definição do DUT. Esses arquivos YAML serão usados ​​para filtrar os testes que precisam ser executados no DUT.
    Finalmente, um diretório env precisa existir no diretório dut-plugin, que contém arquivos de ambiente, como model_test.h, que são necessários para compilar e executar testes. Consulte a especificação TestFormat para definições de macros que podem ser usadas no arquivo model_test.h. O diretório env também pode conter outros arquivos, como scripts de vinculador e scripts de pós-processamento que os usuários podem precisar.
  • diretório reference-plugin: semelhante ao plug-in DUT, o RISCOF também requer um plug-in de modelo de referência. A estrutura de diretórios e arquivos é a mesma do DUT. No entanto, os arquivos isa e YAML da plataforma não são necessários porque o RISCOF sempre selecionará arquivos YAML para todos os fins no plug-in DUT.
    Para simplificar a operação, o RISCOF gera DUT padrão e modelos predefinidos de modelo de referência para os usuários por meio de comandos de configuração, conforme mostrado na figura a seguir:

$ riscof setup --dutname=spike

O comando acima irá gerar os seguintes arquivos e diretórios no diretório atual:

├──config.ini # arquivo de configuração para riscof
├──spike/ # Modelos de plugin DUT
├── ambiente
│ ├── link.ld # script do vinculador DUT
│ └── model_test.h # arquivo de cabeçalho específico do DUT
├── riscof_spike.py # plugin python DUT
├── spike_isa.yaml # DUT ISA yaml baseado em riscv-config
└── spike_platform.yaml # Plataforma DUT yaml baseada em riscv-config
├──sail_cSim/ # modelos de plugin de referência
├── ambiente
│ ├── link.ld # Script de referência do vinculador
│ └── model_test.h # Arquivo de cabeçalho específico do modelo de referência
├── iniciar.py
└── riscof_sail_cSim.py # Plugin python do modelo de referência.

Basta alterar o pico acima para o plugin C920. Claro, você precisa modificar cada arquivo de configuração e arquivo python.
c920_isa.yaml

hart_ids: [0]
hart0:
  ISA: RV64IMAFDCVZicsr_Zicbom_Zicbop_Zicboz_Zihintpause_Zfh_Zca_Zcb_Zcd_Zba_Zbb_Zbc_Zbs
  physical_addr_sz: 40
  User_Spec_Version: "2.2"
  Privilege_Spec_Version: "1.10"
  hw_data_misaligned_support: false
  pmp_granularity: 4
  supported_xlen: [64]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

c920_plataforma.yaml

mtime:
  implemented: true
  address: 0xBFF8
mtimecmp:
  implemented: true
  address: 0x4000
nmi:
  label: nmi_vector
reset:
  address: 0x000000000 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

A execução do comando a seguir extrairá a lista de casos de test_list.yaml e executará cada caso. Você pode comentar alguns deles e executar apenas alguns casos.

riscof executar --config=config.ini
–suite=teste-de-arquitetura-riscv/conjunto-de-teste-riscv/
–env=teste-de-arquitetura-riscv/conjunto-de-testes-riscv/env
–testfile=riscof_work/test_list.yaml

A execução do comando a seguir gerará test_list.yaml e executará a regressão

riscof executar --config=config.ini
–suite=teste-de-arquitetura-riscv/conjunto-de-teste-riscv/
–env=teste-de-arquitetura-riscv/conjunto-de-testes-riscv/env

10. Resultados do teste

Insira a descrição da imagem aqui
Análise da causa do erro:
O primeiro:
Insira a descrição da imagem aqui
É porque foi encontrado um erro durante a compilação

    INFO | Compiling test: /ssd_fes/jiongz/desktop/github/c920_riscof1/riscv-arch-test/riscv-test-suite/rv64i_m/I/src/beq-01.S
   ERROR | /opt/picocom/ThirdParty_Libs/T-head/C920_R2S0P21/C920_R2S0_manuals_and_tools/manuals_and_tools/08_toolchain_900_series_cpu_toolchain/V2.8.0/Xuantie-900-gcc-elf-newlib-x86_64-V2.8.0/bin/../lib/gcc/riscv64-unknown-elf/10.4.0/../../../../riscv64-unknown-elf/bin/ld: main.elf section `.text' will not fit in region `MEM1'
collect2: error: ld returned 1 exit status
  • 1
  • 2
  • 3

O segundo tipo:
Insira a descrição da imagem aqui
Acontece que o c920 não habilita um determinado comando por padrão.
Insira a descrição da imagem aqui

11. forma de onda rv64i_m/I/src/add-01.S

Há também uma macro em model_test.h para assinatura de dump e simulação final

// This will dump the test results (signature) via the testbench dump module.
#define RVMODEL_HALT                                          
    signature_dump:                                           
      la   a0, begin_signature;                               
      la   a1, end_signature;                                 
      li   a2, 0xF0000040;                                    
    signature_dump_loop:                                      
      bge  a0, a1, signature_dump_end;                        
      lw   t0, 0(a0);                                         
      sw   t0, 0(a2);                                         
      addi a0, a0, 4;                                         
      j    signature_dump_loop;                               
    signature_dump_end:                                       
      nop;                                                    
    terminate_simulation:                                     
      li   a0, 0xF0000000;                                    
      li   a1, 0xCAFECAFE;                                    
      sw   a1, 0(a0);                                         
      j    terminate_simulation
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Correspondente a tb.v

always @(posedge `CPU_CLK or negedge `CPU_RST) begin
    if (!`CPU_RST) begin
        msi <= 1'b0;
        mei <= 1'b0;
        mti <= 1'b0;
    end else begin
        //if ((wb_cpu.cyc == 1'b1) && (wb_cpu.stb == 1'b1) && (wb_cpu.we == 1'b1) && (cpu_awaddr[31:0] == 32'hF000_0000)) begin
        if ((cpu_awaddr[31:0] == 32'hF000_0000) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) begin
            case (`SOC_TOP.biu_pad_wdata[31:0])
                32'hCAFE_CAFE: begin // end simulation
                    $display("Finishing simulation.");
                    #100;
                    if(fail_cnt >0) begin
                     $error("This case test failed!");
                    end
                    $finish;
                end
                ......
 end

// Signature Dump
int dump_file; // Declare file handle
always @(posedge `CPU_CLK) begin
    if ((cpu_awaddr[31:0] == 32'hF000_0040) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) begin
        if (!dump_file) begin // Check if file is already open
            dump_file = $fopen("DUT-c920.signature", "w"); // Open file if not already opened
        end
        //for (int i = 7; i >= 0; i--) begin
        //    $fwrite(dump_file, "%hn", `SOC_TOP.biu_pad_wdata[i*4 +: 4]); // Write data
        //end
        $fwrite(dump_file, "%hn", `SOC_TOP.biu_pad_wdata[31:0]); // Write data
    end
    else if((cpu_awaddr[31:0] == 32'hF000_0000) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) begin
        if (dump_file) begin // If file is open, close it
            $fclose(dump_file);
            dump_file = 0; // Reset file handle to 0 indicating file is closed
        end
    end
end

// RVMODEL_IO_ASSERT_GPR_EQ(testreg, destreg, correctval) used to check destreg == correctval
// destreg != correctva write testreg 1, else write testreg 0
always @(posedge `CPU_CLK) begin
    if ((cpu_awaddr[31:0] == 32'hF000_0080) && cpu_wvalid && `clk_en && (cpu_wstrb[15:0] == 16'hf)) begin
       if(`SOC_TOP.biu_pad_wdata == 1'b1) begin
         fail_cnt ++;
       end
    end
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
#include "model_test.h"
#include "arch_test.h"
RVTEST_ISA("RV64I")

.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN

#ifdef TEST_CASE_1

RVTEST_CASE(0,"//check ISA:=regex(.*64.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;",add)

RVTEST_SIGBASE( x8,signature_x8_1)

inst_0:
// rs1 == rs2 != rd, rs1==x0, rs2==x0, rd==x20, rs1_val > 0 and rs2_val > 0, rs1_val == 4, rs1_val==4 and rs2_val==6148914691236517206, rs1_val != rs2_val
// opcode: add ; op1:x0; op2:x0; dest:x20; op1val:0x0;  op2val:0x0
TEST_RR_OP(add, x20, x0, x0, 0x0, 0x0, 0x0, x8, 0, x16)

inst_1:
// rs2 == rd != rs1, rs1==x2, rs2==x26, rd==x26, rs1_val > 0 and rs2_val < 0, rs2_val == -1073741825
// opcode: add ; op1:x2; op2:x26; dest:x26; op1val:0x5;  op2val:-0x40000001
TEST_RR_OP(add, x26, x2, x26, 0xffffffffc0000004, 0x5, -0x40000001, x8, 8, x16)

inst_2:
// rs1 == rs2 == rd, rs1==x22, rs2==x22, rd==x22, rs1_val < 0 and rs2_val < 0, rs1_val == -8388609
// opcode: add ; op1:x22; op2:x22; dest:x22; op1val:-0x800001;  op2val:-0x800001
TEST_RR_OP(add, x22, x22, x22, 0xfffffffffefffffe, -0x800001, -0x800001, x8, 16, x16)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

O conteúdo de “riscof_work/rv64i_m/I/src/add-01.S/dut/DUT-c920.signature” é o seguinte:

e7d4b281
6f5ca309
00000000
00000000
c0000004
affffffff
tchau
affffffff
ffffffbf
007ffffff
00000080
00000000
66666665
e6666666
00000001
00000000
0001ffff
80000000
10000001
00000000
ffffffff

Insira a descrição da imagem aqui
Insira a descrição da imagem aqui