Technologieaustausch

Konformitätstests für die Riscv-Architektur

2024-07-12

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

Der Grund, warum wir uns direkt auf riscv-arch-test konzentrieren, liegt darin, dass das RISCOF-Testframework riscv-arch-test verwendet.
Fügen Sie hier eine Bildbeschreibung ein

1. Der Architekturtest

Ein Architekturtest ist ein einzelner Test, der den kleinsten Testcode darstellt, der kompiliert und ausgeführt werden kann. Es ist im Assembler-Code geschrieben und sein Produkt ist eine Testsignatur. Ein Architekturtest kann aus mehreren Testfällen bestehen.

2. Der RISC-V-Architektur-Testpool

Der RISC-V-Architekturtestpool besteht aus allen genehmigten Architekturtests, die vom Testframework zu einer Architekturtestsuite zusammengestellt werden können. Testbibliotheken für die RISC-V-Architektur müssen testzielunabhängig sein (und sollten daher auf jedem kompatiblen Ziel ordnungsgemäß ausgeführt werden). Bitte beachten Sie, dass dieser nicht funktionale Test kein Ersatz für eine Verifizierung oder einen Gerätetest ist.

2.1 Testpoolstruktur

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

Machine Mode Processor Instruction Set Characteristics Register (MISA)
misa = 0x800000000094112f
Binäre Darstellung: 100000000000000000000000000000000000000100101000001000100101111
Fügen Sie hier eine Bildbeschreibung ein

riscv-arch-test/riscv-test-suite$ ls
env/ Makefile.include README.md rv32e_m/ rv32i_m/ rv64i_m/
riscv-arch-test/riscv-test-suite/rv64i_m$ ls
A/ B/ C/ CMO/ D/ F/ I/ K/ M/ Privileg/ P_nicht ratifiziert/ Zfh/ Zfinx/ Zicond/ Zifencei/

3. Die RISC-V-Architektur-Testsuite

Die RISC-V-Architekturtestsuite besteht aus einer Reihe von Tests, die aus dem Architekturtestpool ausgewählt werden, um die Konformität einer bestimmten RISC-V-Konfiguration zu testen. Testergebnisse werden in Form einer Testsuite-Signatur erhalten. Die Testauswahl basiert auf der Assertionskonfiguration, der Spezifikation, der Ausführungsumgebung oder den Plattformanforderungen des Ziels. Ein kompatibler Prozessor oder ein kompatibles Prozessormodell sollte dieselbe Gold Reference Test Suite-Signatur aufweisen wie die spezifische getestete Konfiguration.

4. Der Testfall

Testfälle sind Teil des Architekturtests und testen nur eine Funktion der Spezifikation.
Hinweis: Ein Test kann mehrere Testfälle enthalten und jeder Testfall hat seine eigenen Testeinschlussbedingungen (definiert durch den Parameter cond_str des Makros RVTEST_CASE).

4.1 Benennung testen

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

riscv-arch-test/riscv-test-suite/rv64i_m/I/src$ ls
add-01.S und-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 oder-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. Assembly-Test-Infrastruktur (nehmen Sie ./rv32i_m/I/src/add-01.S als Beispiel)

//
// 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

Eine kurze Erklärung des obigen Assemblercodes lautet wie folgt:

  1. Kopfzeile zum Einschließen von Kommentaren

#Diese Assemblydatei testet den Add-Befehl der RISC-V I-Erweiterung für die Add-Covergroup.

  1. Enthält Headerdateien

#include „model_test.h“
#include „arch_test.h“

Jeder Test sollte nur die folgenden Header-Dateien enthalten:
model_test.h – definiert zielspezifische Makros, einschließlich erforderlicher und optionaler Makros: (z. B. RVMODEL_xxx)
arch_test.h – definiert vordefinierte Testmakros, einschließlich erforderlicher Makros und optionaler Makros: (z. B. RVTEST_xxx)

  1. Stellen Sie den TVM des Tests ein

RVTEST_ISA("RV32I")

  1. Zielspezifischen Bootcode testen

RVMODEL_BOOT

  1. Beginn der GPR-Initialisierungsroutine und des Testcodes

RVTEST_CODE_BEGIN

  1. Definieren Sie die Zeichenfolge und Bedingungen für RVTEST_CASE

#ifdef TEST_CASE_1
// dieser Test ist für Geräte gedacht, die die rv32I-Erweiterung implementieren und erfordert die Aktivierung der Kompilierung
// Makro TEST_CASE_1. Dieser Test trägt zum Coverage-Label „add“ bei.
RVTEST_CASE(0,“//prüfe ISA:=regex(.32.);überprüfen Sie ISA:=regex(.ICH.);def TEST_CASE_1=True;”, hinzufügen)

  1. Zeiger auf den Signaturbereich initialisieren

RVTEST_SIGBASE( x16,signature_x16_1) // x16 zeigt auf das Label signature_x16_1 im Signaturbereich

  1. Definieren Sie die Testfälle
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. Signaturbasisregister ändern
// 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. Beenden Sie den Test und halten Sie das Testziel an
RVTEST_CODE_END
RVMODEL_HALT
  • 1
  • 2
  1. Abschnitt „Testeingabedaten erstellen“
RVTEST_DATA_BEGIN
rvtest_data:
.word 0xbabecafe
RVTEST_DATA_END
  • 1
  • 2
  • 3
  • 4
  1. Vorinstallierten Signaturbereich erstellen
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. Die Testfallsignatur

Eine Testfallsignatur wird durch einen einzelnen oder mehrere Werte dargestellt. Der Wert wird beginnend bei der durch RVMODEL_DATA_BEGIN angegebenen Adresse und endend bei der durch RVMODEL_DATA_END angegebenen Adresse in den Speicher geschrieben. Signaturen können ganz einfach mit dem Makro RVTEST_SIGUPD generiert werden.

7. Die Testsignatur

Die Testsignatur ist der charakteristische Wert, der durch den Architekturtestlauf generiert wird. Eine Testsignatur kann aus mehreren Testfallsignaturen bestehen, denen eine separate Zeile vorangestellt ist, die den Namen des Tests und einen eindeutigen Wert zur Angabe seiner Version enthält. Das Testziel ist dafür verantwortlich, die Werte aus dem Speicher zu extrahieren und sie mithilfe der vom Framework bereitgestellten Metadaten mithilfe der Makros RVMODEL_DATA_BEGIN und RVMODEL_DATA_END entsprechend zu formatieren.Der Testfallsignaturwert wird in Zeilen geschrieben, beginnend mit dem höchstwertigen Byte links im Format<hex_value> , wobei die Länge des Werts 32 Bit (also 8 Zeichen) beträgt, während die eigentliche Testberechnung die Länge des Werts nicht berücksichtigt. Dateien sollten beginnend mit dem Wert an der niedrigsten Adresse der Signatur gespeichert werden (d. h. von RVMODEL_DATA_BEGIN bis RVMODEL_DATA_END). Darüber hinaus sollte die Signatur immer an einer 16-Byte-Grenze (128-Bit) beginnen und die Größe der Signatur sollte ein Vielfaches von 4 Bytes sein (d. h. sie sollte auch an einer 4-Byte-Grenze enden).

8. Die Signatur der Testsuite

Eine Testsuite-Signatur ist als eine Reihe von Testsignaturen definiert, die für eine bestimmte architektonische Testsuite gültig sind. Es stellt die Testsignatur der Architekturtestsuite dar, die für eine bestimmte RISC-V-Konfiguration ausgewählt wurde.

9. RISCOF-Testrahmen

RISCOF – Das RISC-V-Kompatibilitätsframework ist ein Python-basiertes Framework, das die Verwendung einer Reihe von RISC-V-Architekturtestsätzen ermöglicht, um RISC-V-Ziele (Hardware- oder Softwareimplementierungen) auf Kompatibilität mit der standardmäßigen RISC-V Golden Reference zu testen Modelsex.
Fügen Sie hier eine Bildbeschreibung ein
RISC-V-Konfigurationsvalidator: RISCV-Config
Generator für RISC-V-Konformitätstests: RISC-V CTG
RISC-V ISA-Abdeckung: RISC-V ISAC
Damit RISCOF den Test normal ausführen kann, müssen die folgenden Inhalte bereitgestellt werden:

  • config.ini: Diese Datei ist eine grundlegende Konfigurationsdatei und folgt der INI-Syntax. Diese Datei erfasst Informationen wie: den Namen des DUT/Referenz-Plugins, den Pfad zum Plugin, den Pfad zur YAML-Datei basierend auf riscv-config usw.
  • dut-plugin-Verzeichnis: RISCOF erfordert, dass das getestete DUT-Modell in Form eines Python-Plug-ins bereitgestellt wird. Ein Python-Plug-in ist eigentlich eine Python-Datei, die bestimmte standardmäßige und definierte Funktionen zum Durchführen von Testkompilierungs-, Ausführungs- und Signaturextraktionsaktivitäten enthält. Dem Namen dieser Python-Datei muss riscof_ vorangestellt werden und sie muss im Verzeichnis dut-plugin vorhanden sein. Im Abschnitt „Python-Plug-in-Datei“ erfahren Sie, wie Sie diese Python-Datei schreiben.
    Dieses Verzeichnis muss auch die auf riscv-config basierenden isa- und Plattform-YAML-Dateien enthalten, die die Definition des DUT bereitstellen. Diese YAML-Dateien werden zum Filtern der Tests verwendet, die auf dem DUT ausgeführt werden müssen.
    Schließlich muss im dut-plugin-Verzeichnis ein env-Verzeichnis vorhanden sein, das Umgebungsdateien wie model_test.h enthält, die zum Kompilieren und Ausführen von Tests erforderlich sind. Definitionen von Makros, die in der Datei model_test.h verwendet werden können, finden Sie in der TestFormat-Spezifikation. Das env-Verzeichnis kann auch andere Dateien enthalten, z. B. Linker-Skripte und Nachbearbeitungsskripte, die Benutzer möglicherweise benötigen.
  • Referenz-Plugin-Verzeichnis: Ähnlich wie das DUT-Plugin erfordert auch RISCOF ein Referenzmodell-Plugin. Die Verzeichnis- und Dateistruktur entspricht der des DUT. Allerdings sind ISA- und Plattform-YAML-Dateien nicht erforderlich, da RISCOF immer YAML-Dateien für alle Zwecke aus dem DUT-Plug-in auswählt.
    Um den Vorgang zu vereinfachen, generiert RISCOF durch Einstellungsbefehle Standard-DUT- und Referenzmodell-Voreinstellungen für Benutzer, wie in der folgenden Abbildung dargestellt:

$ riscof setup --dutname=spike

Der obige Befehl generiert die folgenden Dateien und Verzeichnisse im aktuellen Verzeichnis:

├──config.ini # Konfigurationsdatei für riscof
├──spike/ # DUT-Plugin-Vorlagen
├── Umgebung
│ ├── link.ld # DUT-Linker-Skript
│ └── model_test.h # DUT-spezifische Header-Datei
├── riscof_spike.py # DUT-Python-Plugin
├── spike_isa.yaml # DUT ISA yaml basierend auf riscv-config
└── spike_platform.yaml # DUT-Plattform-YAML basierend auf Riscv-Konfiguration
├──sail_cSim/ # Referenz-Plugin-Vorlagen
├── Umgebung
│ ├── link.ld # Referenz-Linker-Skript
│ └── model_test.h # Referenzmodellspezifische Headerdatei
├── drin.py
└── riscof_sail_cSim.py # Referenzmodell-Python-Plugin.

Ändern Sie einfach den obigen Spike in das C920-Plugin. Natürlich müssen Sie jede Konfigurationsdatei und Python-Datei ändern.
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_platform.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

Durch Ausführen des folgenden Befehls wird die Fallliste aus test_list.yaml extrahiert und jeder Fall ausgeführt. Sie können einige davon auskommentieren und nur einige Fälle ausführen.

riscof run --config=config.ini
–suite=riscv-arch-test/riscv-test-suite/
–env=riscv-arch-test/riscv-test-suite/env
–testfile=riscof_work/test_list.yaml

Durch Ausführen des folgenden Befehls wird test_list.yaml generiert und die Regression ausgeführt

riscof run --config=config.ini
–suite=riscv-arch-test/riscv-test-suite/
–env=riscv-arch-test/riscv-test-suite/env

10. Testergebnisse

Fügen Sie hier eine Bildbeschreibung ein
Fehlerursachenanalyse:
Der erste:
Fügen Sie hier eine Bildbeschreibung ein
Dies liegt daran, dass beim Kompilieren ein Fehler aufgetreten ist

    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

Der zweite Typ:
Fügen Sie hier eine Bildbeschreibung ein
Es ist nur so, dass c920 einen bestimmten Befehl standardmäßig nicht aktiviert.
Fügen Sie hier eine Bildbeschreibung ein

11. rv64i_m/I/src/add-01.S Wellenform

Es gibt auch ein Makro in model_test.h für die Dump-Signatur und die Abschlusssimulation

// 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

Entsprechend 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

Der Inhalt von „riscof_work/rv64i_m/I/src/add-01.S/dut/DUT-c920.signature“ lautet wie folgt:

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

Fügen Sie hier eine Bildbeschreibung ein
Fügen Sie hier eine Bildbeschreibung ein