技術共有

Riscv アーキテクチャのコンプライアンス テスト

2024-07-12

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

私たちが riscv-arch-test に直接注目する理由は、RISCOF テスト フレームワークが riscv-arch-test を使用しているためです。
ここに画像の説明を挿入します

1. 建築テスト

アーキテクチャ テストは、コンパイルして実行できる最小のテスト コードを表す単一のテストです。これはアセンブリコードで書かれており、その生成物はテスト署名です。アーキテクチャ テストは複数のテスト ケースで構成される場合があります。

2. RISC-Vアーキテクチャテストプール

RISC-V アーキテクチャ テスト プールは、テスト フレームワークによってアーキテクチャ テスト スイートにコンパイルできる、承認されたすべてのアーキテクチャ テストで構成されます。 RISC-V アーキテクチャ テスト ライブラリは、テスト ターゲットに依存しない必要があります (したがって、準拠したターゲット上で正しく実行される必要があります)。この非機能テストは検証やデバイスのテストに代わるものではないことに注意してください。

2.1 テストプールの構造

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

マシンモードプロセッサ命令セット特性レジスタ (MISA)
ミサ = 0x800000000094112f
バイナリ表現: 100000000000000000000000000000000000000100101000001000100101111
ここに画像の説明を挿入します

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/ 特権/ P_未批准/ Zfh/ Zfinx/ Zicond/ Zifencei/

3. RISC-Vアーキテクチャテストスイート

RISC-V アーキテクチャ テスト スイートは、特定の RISC-V 構成の適合性をテストするためにアーキテクチャ テスト プールから選択された一連のテストです。テスト結果は、テスト スイートの署名の形式で取得されます。テストの選択は、ターゲットのアサーション構成、仕様、実行環境、またはプラットフォーム要件に基づいて行われます。準拠したプロセッサーまたはプロセッサー モデルには、テスト対象の特定の構成と同じ Gold Reference Test Suite シグネチャが表示される必要があります。

4. テストケース

テスト ケースはアーキテクチャ テストの一部であり、仕様の 1 つの機能のみをテストします。
注: テストには複数のテスト ケースを含めることができ、それぞれに独自のテスト包含条件 (RVTEST_CASE マクロの cond_str パラメーターで定義) があります。

4.1 テストの名前付け

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

riscv-arch-test/riscv-test-suite/rv64i_m/I/src$ ls
add-01.S and-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. アセンブリ テスト インフラストラクチャ (./rv32i_m/I/src/add-01.S を例にします)

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

上記のアセンブリ コードを簡単に説明すると、次のとおりです。

  1. コメントを含めるヘッダー

#このアセンブリ ファイルは、add カバーグループの RISC-V I 拡張の add 命令をテストします。

  1. ヘッダーファイルを含む

#include “model_test.h”
#include “arch_test.h”

各テストには次のヘッダー ファイルのみを含める必要があります。
model_test.h - 必須およびオプションのマクロを含む、ターゲット固有のマクロを定義します: (例: RVMODEL_xxx)
Arch_test.h - 必須マクロおよびオプション マクロを含む、事前定義されたテスト マクロを定義します: (RVTEST_xxx など)

  1. テストのTVMを設定する

RVTEST_ISA(“RV32I”)

  1. ターゲット固有のブートコードをテストする

RVモデル_ブート

  1. GPR初期化ルーチンとテストコードの開始

RVTEST_CODE_BEGIN

  1. RVTEST_CASE文字列と条件を定義する

#ifdef テストケース1
// このテストはrv32I拡張を実装したデバイスを対象としており、コンパイルを有効にする必要があります
// マクロ TEST_CASE_1。このテストは、「add」カバレッジ ラベルに貢献します。
RVTEST_CASE(0,“//チェックISA:=regex(.32.);ISA:=regex( をチェックします。私。);def TEST_CASE_1=True;”、追加)

  1. 署名領域へのポインタを初期化する

RVTEST_SIGBASE( x16,signature_x16_1) // x16は署名領域内のsignature_x16_1ラベルを指します

  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)
...
...
  • 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. 署名ベースレジスタの変更
// 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. テストを終了し、テスト対象を停止します
RVTEST_CODE_END
RVMODEL_HALT
  • 1
  • 2
  1. テスト入力データセクションを作成する
RVTEST_DATA_BEGIN
rvtest_data:
.word 0xbabecafe
RVTEST_DATA_END
  • 1
  • 2
  • 3
  • 4
  1. 事前にロードされた署名領域を作成する
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. テストケースの署名

テスト ケースのシグネチャは、単一または複数の値で表されます。値は、RVMODEL_DATA_BEGIN で指定されたアドレスから始まり、RVMODEL_DATA_END で指定されたアドレスで終わるメモリに書き込まれます。署名は RVTEST_SIGUPD マクロを使用して簡単に生成できます。

7. テスト署名

テスト シグネチャは、アーキテクチャ テストの実行によって生成される特性値です。テスト署名は、テストの名前とそのバージョンを示す一意の値を含む別の行が接頭辞として付けられた複数のテスト ケース署名で構成されている場合があります。テスト ターゲットは、フレームワークによって提供されるメタデータを使用し、RVMODEL_DATA_BEGIN マクロと RVMODEL_DATA_END マクロを使用して、メモリから値を抽出し、それらを適切にフォーマットする必要があります。テスト ケースの署名値は、左側の最上位バイトから開始して、次の形式で行に書き込まれます。<hex_value> 、値の長さは 32 ビット (つまり 8 文字) になりますが、実際のテスト計算では値の長さは考慮されません。ファイルは、署名の最下位アドレスの値から開始して保存する必要があります (つまり、RVMODEL_DATA_BEGIN から RVMODEL_DATA_END まで)。さらに、署名は常に 16 バイト (128 ビット) 境界で始まり、署名のサイズは 4 バイトの倍数である必要があります (つまり、署名も 4 バイト境界で終わる必要があります)。

8. テストスイートのシグネチャ

テスト スイート署名は、特定のアーキテクチャ テスト スイートに対して有効なテスト署名のセットとして定義されます。これは、特定の RISC-V 構成用に選択されたアーキテクチャ テスト スイートのテスト シグネチャを表します。

9. RISCOF テストフレームワーク

RISCOF - RISC-V 互換性フレームワークは、RISC-V アーキテクチャ テスト セットのセットを使用して、標準 RISC-V ゴールデン リファレンスとの互換性について RISC-V ターゲット (ハードウェアまたはソフトウェア実装) をテストできるようにする Python ベースのフレームワークです。モデルセックス。
ここに画像の説明を挿入します
RISC-V 構成検証ツール: RISCV-Config
RISC-V コンプライアンス テスト ジェネレーター: RISC-V CTG
RISC-V ISA カバレッジ : RISC-V ISAC
RISCOF がテストを正常に実行するには、次のコンテンツを提供する必要があります。

  • config.ini: このファイルは基本的な構成ファイルであり、ini 構文に従います。このファイルは、DUT/リファレンス プラグインの名前、プラグインへのパス、riscv-config に基づく YAML ファイルへのパスなどの情報をキャプチャします。
  • dut-plugin ディレクトリ: RISCOF では、テストされる DUT モデルが Python プラグインの形式で提供されることが必要です。 Python プラグインは、実際には、テストのコンパイル、実行、シグネチャ抽出アクティビティを実行するための特定の標準関数と定義された関数を含む Python ファイルです。この Python ファイルの名前には riscof_ という接頭辞を付ける必要があり、dut-plugin ディレクトリに存在する必要があります。この Python ファイルの作成方法については、「Python プラグイン ファイル」セクションを参照してください。
    このディレクトリには、DUT の定義を提供する riscv-config に基づく isa およ​​びプラットフォーム YAML ファイルも含める必要があります。これらの YAML ファイルは、DUT で実行する必要があるテストをフィルタリングするために使用されます。
    最後に、env ディレクトリが dut-plugin ディレクトリに存在する必要があります。このディレクトリには、テストのコンパイルと実行に必要な model_test.h などの環境ファイルが含まれています。 model_test.h ファイルで使用できるマクロの定義については、TestFormat 仕様を参照してください。 env ディレクトリには、ユーザーが必要とするリンカー スクリプトや後処理スクリプトなどの他のファイルも含まれる場合があります。
  • Reference-plugin ディレクトリ: DUT プラグインと同様に、RISCOF にも参照モデル プラグインが必要です。ディレクトリおよびファイル構造は DUT と同じです。ただし、RISCOF は常に DUT プラグインからあらゆる目的で YAML ファイルを選択するため、isa およ​​びプラットフォーム YAML ファイルは必要ありません。
    操作を簡素化するために、RISCOF は、次の図に示すように、設定コマンドを通じてユーザー向けに標準 DUT と参照モデルのプリセット テンプレートを生成します。

$ riscof セットアップ --dutname=spike

上記のコマンドは、現在のディレクトリに次のファイルとディレクトリを生成します。

├──config.ini # riscofの設定ファイル
├──spike/ # DUTプラグインテンプレート
├── 環境
│ ├── link.ld # DUT リンカースクリプト
│ └── model_test.h # DUT固有のヘッダーファイル
├── riscof_spike.py # DUT Pythonプラグイン
├── spike_isa.yaml # riscv-config に基づく DUT ISA yaml
└── spike_platform.yaml # riscv-config に基づく DUT プラットフォーム yaml
├──sail_cSim/ # リファレンスプラグインテンプレート
├── 環境
│ ├── link.ld # 参照リンカースクリプト
│ └── model_test.h # 参照モデル固有のヘッダーファイル
├── 初期化.py
└── riscof_sail_cSim.py # リファレンスモデル Python プラグイン。

上記のスパイクを C920 プラグインに変更するだけです。 もちろん、各設定ファイルと 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_プラットフォーム.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

次のコマンドを実行すると、test_list.yaml からケースのリストが抽出され、各ケースが実行されます。一部のケースをコメント化して、一部のケースのみを実行できます。

riscof 実行 --config=config.ini
–suite=riscv-arch-test/riscv-test-suite/
–env=riscv-arch-test/riscv-test-suite/env
–テストファイル=riscof_work/テストリスト.yaml

次のコマンドを実行すると、test_list.yaml が生成され、回帰が実行されます。

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

10. テスト結果

ここに画像の説明を挿入します
エラー原因の分析:
最初:
ここに画像の説明を挿入します
コンパイル中にエラーが発生したためです

    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

2 番目のタイプ:
ここに画像の説明を挿入します
c920 はデフォルトでは特定のコマンドを有効にしていないだけです。
ここに画像の説明を挿入します

11. rv64i_m/I/src/add-01.S 波形

model_test.h には、署名をダンプしてシミュレーションを終了するためのマクロもあります。

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

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

「riscof_work/rv64i_m/I/src/add-01.S/dut/DUT-c920.signature」の内容は以下の通りです。

e7d4b281
6f5ca309
00000000
00000000
c0000004
ふぅふぅ
ふぅふぅ
ふぅふぅ
ふふふふ
007fffff
00000080
00000000
66666665
6666666
00000001
00000000
0001ffff
80000000
10000001
00000000
ふーふーふ

ここに画像の説明を挿入します
ここに画像の説明を挿入します