RISC-V MCU中文社区

【分享】 仿真学习

发表于 全国大学生集成电路创新创业大赛 2023-05-31 22:37:23
2
771
1

仿真Testcase学习

完成工作

1、阅读相关文档和文件,研究了仿真命令的执行过程,以及具体的仿真代码。

2、观察了rv32um-p-mul的波形,分析了testcase的执行情况。

具体细节

从命令行到仿真

与仿真有关指令均在以下目录中执行:

${PWD}/n200_rls_pkg/n200/vsim

其中${PWD}代表存放项目的目录。

根据Nuclei_Processor_Integration_Guide.pdf文档中的说明,在执行仿真之前,我们需要执行make install指令与make compile指令,最后才执行仿真指令make run_test TESTNAME=rv32um-p-mul

所以如果需要了解指令执行过程就需要阅读vsim/Makefilevsim/run/Makefile中的内容。

/vsim/Makefile
SIM_DIR     := ${PWD}
RUN_DIR      := ${PWD}/run
CORE        := n200
TESTNAME     := rv${XLEN}ui-p-lb
TESTCASE     := ${RUN_DIR}/../../riscv-tests/isa/generated/${TESTNAME}

    ...

defines: ${SIM_DIR}/../design/core/*_defines.v
    python bin/v2h.py $< ${core_name}_$@.h
    cp $< ${SIM_DIR}/../tb/${core_name}_$@.v

install: ${RUN_DIR} defines
    mkdir -p ${SIM_DIR}/install/tb
    cp ${SIM_DIR}/../tb/* ${SIM_DIR}/install/tb/ -rf
    find ${SIM_DIR}/../design/ -name *.v >& ${RUN_DIR}/rtlonly_flist
    find ${SIM_DIR}/../design/core/ -name *.v >& ${RUN_DIR}/core_flist

compile: ${RUN_DIR}
    make compile CORE=${CORE} RUN_DIR=${RUN_DIR} -C ${RUN_DIR} TESTCASE=${TESTCASE} COVERAGE=${COVERAGE}

wave: ${RUN_DIR}
    make wave CORE=${CORE} TESTCASE=${TESTCASE} RUN_DIR=${RUN_DIR} -C ${RUN_DIR} 

run_test: compile
    make run CORE=${CORE} WFI_FORCE_IRQ=${WFI_FORCE_IRQ} FORCE_DELAY=${FORCE_DELAY} FORCE_IRQ=${FORCE_IRQ} FORCE_ECC=${FORCE_ECC} DUMPWAVE=${DUMPWAVE} TESTCASE=${TESTCASE} SEED=${SEED} RUN_DIR=${RUN_DIR} -C ${RUN_DIR} COVERAGE=${COVERAGE}

    ...
/vsim/run/Makefile
RUN_DIR      := ${PWD}
TESTCASE     := ${RUN_DIR}/../../riscv-tests/isa/generated/${TESTNAME}
SIM_TOOL      := vcs
SIM_OPTIONS   := +v2k -sverilog -notice -q +lint=all,noSVA-NSVU,noPCTIO-L,noVCDE,noUI,noSVA-CE,noSVA-DIU,noPORTFRC,noSVA-ICP,noNS  -debug_access+all -full64 -timescale=1ns/10ps 
SIM_OPTIONS   += +incdir+${VSRC_DIR}/core+${VSRC_DIR}/soc+${VTB_DIR}
SIM_OPTIONS   += +define+DISABLE_SV_ASSERTION
SIM_OPTIONS   += -l compile.log
SIM_EXEC      := ${RUN_DIR}/simv +plusarg_save +ntb_random_seed=${SEED} 
ifeq ($(WAVEFSDB),1)
WAV_TOOL      := verdi
else
WAV_TOOL      := dve
endif
WAV_OPTIONS   := +v2k -sverilog  
ifeq ($(WAVEFSDB),1)
WAV_PFIX      := fsdb
else
WAV_PFIX      := vpd
endif
TESTNAME     := $(notdir $(patsubst %.dump,%,${TESTCASE}.dump))
TEST_RUNDIR  := ${TESTNAME}

    ...

compile.flg: ${RTL_V_FILES} ${TB_V_FILES} 
    @-rm -rf compile.flg
    ${SIM_TOOL} ${SIM_OPTIONS} ${RTL_V_FILES} ${TB_V_FILES} ;
    touch compile.flg

compile: compile.flg 

wave: 
    gvim  ${TESTCASE}.dump &
ifeq ($(WAVEFSDB), 1)
    ${WAV_TOOL} ${WAV_OPTIONS} +incdir+"${VSRC_DIR}/core"+"${VSRC_DIR}/soc"+"${VTB_DIR}"  ${RTL_V_FILES} ${TB_V_FILES} -ssf ${TEST_RUNDIR}/tb_top.${WAV_PFIX} -top tb_top -nologo & 
else
    ${WAV_TOOL}  -vpd ${TEST_RUNDIR}/tb_top.${WAV_PFIX} &
endif

run: compile
    rm -rf ${TEST_RUNDIR}
    mkdir -p ${TEST_RUNDIR}
    cd ${TEST_RUNDIR}; ${SIM_EXEC} ${SIMV_FLAGS} +WFI_FORCE_IRQ=${WFI_FORCE_IRQ} +FORCE_DELAY=${FORCE_DELAY}  +FORCE_IRQ=${FORCE_IRQ} +FORCE_ECC=${FORCE_ECC} +FORCE_RESP_ERR=${FORCE_RESP_ERR}  +DUMPWAVE=${DUMPWAVE} +WAVEFSDB=${WAVEFSDB} +TESTCASE=${TESTCASE} +SEED=${SEED}  |& tee ${TESTNAME}.log; cd ${RUN_DIR}; 

    ...

make install指令创建了${RUN_DIR}地址,利用python代码defines.v生成defines.h文件,将testbench文件复制到/vsim/install/tb目录下,并将n200的verilog源码链接到${RUN_DIR}下。

make compile指令执行的地址位于${RUN_DIR}下。执行make compile首先要生成compile.flg文件,在生成compile.flg文件过程中设置好仿真工具${SIM_TOOL}、仿真参数${SIM_OPTIONS}、n200核心rtl文件${RTL_V_FILES}、以及testbench文件${TB_V_FILES},最后修改compile.flg文件的时间属性。

make run_test TESTNAME=rv32um-p-mul仿真指令执行的地址同样位于${RUN_DIR}下。相当于执行了/vsim/run/Makefile内的run伪指令。此指令可以创建测试地址${TEST_RUNDIR}并在此地址下利用${SIM_EXEC}执行仿真。最后将屏幕上的打印信息保存到n200.log内。

如果继续执行make wave TESTNAME=rv32um-p-mul仿真指令则可以将run_test生成的波形信息利用${WAV_TOOL}显示出来。

从testcase源码到.dump/.verilog文件

Nuclei_Processor_Integration_Guide.pdf文档中可以得知,testcase的源码位于如下位置:

${PWD}/n200_rls_pkg/n200/riscv-tests/isa_origs/rv32um/

其中${PWD}代表存放项目的目录。

在此路径下,mul.S文件就是rv32um-p-mul的源码了。

/rv32um/mul.S
# See LICENSE for license details.

#*****************************************************************************
# mul.S
#-----------------------------------------------------------------------------
#
# Test mul instruction.
#

#include "riscv_test.h"
#include "test_macros.h"
#include "test_register.h"

RVTEST_RV32U
RVTEST_CODE_BEGIN

  #-------------------------------------------------------------
  # Arithmetic tests
  #-------------------------------------------------------------
  #li  t3, 0x0;
  #li  t4, 0x2;

#ifndef N200_CFG_NO_MULDIV
test_start:
  TEST_RR_OP(32,  mul, 0x00001200, 0x00007e00, 0xb6db6db7 );
  TEST_RR_OP(33,  mul, 0x00001240, 0x00007fc0, 0xb6db6db7 );

  TEST_RR_OP( 2,  mul, 0x00000000, 0x00000000, 0x00000000 );
  TEST_RR_OP( 3,  mul, 0x00000001, 0x00000001, 0x00000001 );
  TEST_RR_OP( 4,  mul, 0x00000015, 0x00000003, 0x00000007 );

  TEST_RR_OP( 5,  mul, 0x00000000, 0x00000000, 0xffff8000 );
  TEST_RR_OP( 6,  mul, 0x00000000, 0x80000000, 0x00000000 );
  TEST_RR_OP( 7,  mul, 0x00000000, 0x80000000, 0xffff8000 );

  TEST_RR_OP(30,  mul, 0x0000ff7f, 0xaaaaaaab, 0x0002fe7d );
  TEST_RR_OP(31,  mul, 0x0000ff7f, 0x0002fe7d, 0xaaaaaaab );

  TEST_RR_OP(34,  mul, 0x00000000, 0xff000000, 0xff000000 );

  TEST_RR_OP(35,  mul, 0x00000001, 0xffffffff, 0xffffffff );
  TEST_RR_OP(36,  mul, 0xffffffff, 0xffffffff, 0x00000001 );
  TEST_RR_OP(37,  mul, 0xffffffff, 0x00000001, 0xffffffff );

  #-------------------------------------------------------------
  # Source/Destination tests
  #-------------------------------------------------------------

  TEST_RR_SRC1_EQ_DEST( 8, mul, 143, 13, 11 );
  TEST_RR_SRC2_EQ_DEST( 9, mul, 154, 14, 11 );
  TEST_RR_SRC12_EQ_DEST( 10, mul, 169, 13 );

  #-------------------------------------------------------------
  # Bypassing tests
  #-------------------------------------------------------------

  TEST_RR_DEST_BYPASS( 11, 0, mul, 143, 13, 11 );
  TEST_RR_DEST_BYPASS( 12, 1, mul, 154, 14, 11 );
  TEST_RR_DEST_BYPASS( 13, 2, mul, 165, 15, 11 );

  TEST_RR_SRC12_BYPASS( 14, 0, 0, mul, 143, 13, 11 );
  TEST_RR_SRC12_BYPASS( 15, 0, 1, mul, 154, 14, 11 );
  TEST_RR_SRC12_BYPASS( 16, 0, 2, mul, 165, 15, 11 );
  TEST_RR_SRC12_BYPASS( 17, 1, 0, mul, 143, 13, 11 );
  TEST_RR_SRC12_BYPASS( 18, 1, 1, mul, 154, 14, 11 );
  TEST_RR_SRC12_BYPASS( 19, 2, 0, mul, 165, 15, 11 );

  TEST_RR_SRC21_BYPASS( 20, 0, 0, mul, 143, 13, 11 );
  TEST_RR_SRC21_BYPASS( 21, 0, 1, mul, 154, 14, 11 );
  TEST_RR_SRC21_BYPASS( 22, 0, 2, mul, 165, 15, 11 );
  TEST_RR_SRC21_BYPASS( 23, 1, 0, mul, 143, 13, 11 );
  TEST_RR_SRC21_BYPASS( 24, 1, 1, mul, 154, 14, 11 );
  TEST_RR_SRC21_BYPASS( 25, 2, 0, mul, 165, 15, 11 );

  TEST_RR_ZEROSRC1( 26, mul, 0, 31 );
  TEST_RR_ZEROSRC2( 27, mul, 0, 32 );
  TEST_RR_ZEROSRC12( 28, mul, 0 );
  TEST_RR_ZERODEST( 29, mul, 33, 34 );

#  SWITCH_TO_UMODE(mstatus , mepc , 0xffffffff, 0xff);
#check_mode:
#  addi t3, t3, 1;
#  bne  t4, t4, test_start;

#endif 
  j pass

  TEST_PASSFAIL

RVTEST_CODE_END

  .data
RVTEST_DATA_BEGIN

  TEST_DATA

RVTEST_DATA_END

从文件中可以看出测试从大分类上一共分为了三个方面Arithmetic tests、Source/Destination tests、Bypassing tests。在此文件中用了许多宏定义的功能,比如TEST_RR_OP,此类宏定义可以在#include "test_macros.h"中查找其源码。

test_macros.h
#define TEST_CASE( testnum, testreg, correctval, code... ) \
test_ ## testnum: \
    code; \
    li  a0, MASK_XLEN(correctval); \
    li  TESTNUM, testnum; \
    bne testreg, a0, fail;

    ...

#define TEST_RR_OP( testnum, inst, result, val1, val2 ) \
    TEST_CASE( testnum, a1, result, \
      li  x1, MASK_XLEN(val1); \
      li  a2, MASK_XLEN(val2); \
      inst a1, x1, a2; \
    )

#define TEST_RR_SRC1_EQ_DEST( testnum, inst, result, val1, val2 ) \
    TEST_CASE( testnum, x1, result, \
      li  x1, MASK_XLEN(val1); \
      li  a2, MASK_XLEN(val2); \
      inst x1, x1, a2; \
    )

#define TEST_RR_SRC2_EQ_DEST( testnum, inst, result, val1, val2 ) \
    TEST_CASE( testnum, a2, result, \
      li  x1, MASK_XLEN(val1); \
      li  a2, MASK_XLEN(val2); \
      inst a2, x1, a2; \
    )

#define TEST_RR_SRC12_EQ_DEST( testnum, inst, result, val1 ) \
    TEST_CASE( testnum, x1, result, \
      li  x1, MASK_XLEN(val1); \
      inst x1, x1, x1; \
    )

#define TEST_RR_DEST_BYPASS( testnum, nop_cycles, inst, result, val1, val2 ) \
    TEST_CASE( testnum, x6, result, \
      li  x4, 0; \
1:    li  x1, MASK_XLEN(val1); \
      li  a2, MASK_XLEN(val2); \
      inst a1, x1, a2; \
      TEST_INSERT_NOPS_ ## nop_cycles \
      addi  x6, a1, 0; \
      addi  x4, x4, 1; \
      li  x5, 2; \
      bne x4, x5, 1b \
    )

#define TEST_RR_SRC12_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \
    TEST_CASE( testnum, a1, result, \
      li  x4, 0; \
1:    li  x1, MASK_XLEN(val1); \
      TEST_INSERT_NOPS_ ## src1_nops \
      li  a2, MASK_XLEN(val2); \
      TEST_INSERT_NOPS_ ## src2_nops \
      inst a1, x1, a2; \
      addi  x4, x4, 1; \
      li  x5, 2; \
      bne x4, x5, 1b \
    )

#define TEST_RR_SRC21_BYPASS( testnum, src1_nops, src2_nops, inst, result, val1, val2 ) \
    TEST_CASE( testnum, a1, result, \
      li  x4, 0; \
1:    li  a2, MASK_XLEN(val2); \
      TEST_INSERT_NOPS_ ## src1_nops \
      li  x1, MASK_XLEN(val1); \
      TEST_INSERT_NOPS_ ## src2_nops \
      inst a1, x1, a2; \
      addi  x4, x4, 1; \
      li  x5, 2; \
      bne x4, x5, 1b \
    )

#define TEST_RR_ZEROSRC1( testnum, inst, result, val ) \
    TEST_CASE( testnum, a2, result, \
      li x1, MASK_XLEN(val); \
      inst a2, x0, x1; \
    )

#define TEST_RR_ZEROSRC2( testnum, inst, result, val ) \
    TEST_CASE( testnum, a2, result, \
      li x1, MASK_XLEN(val); \
      inst a2, x1, x0; \
    )

#define TEST_RR_ZEROSRC12( testnum, inst, result ) \
    TEST_CASE( testnum, x1, result, \
      inst x1, x0, x0; \
    )

#define TEST_RR_ZERODEST( testnum, inst, val1, val2 ) \
    TEST_CASE( testnum, x0, 0, \
      li x1, MASK_XLEN(val1); \
      li a2, MASK_XLEN(val2); \
      inst x0, x1, a2; \
    )

    ...

#-----------------------------------------------------------------------
# Pass and fail code (assumes test num is in TESTNUM)
#-----------------------------------------------------------------------

#define TEST_PASSFAIL \
        bne x0, TESTNUM, pass; \
fail: \
        RVTEST_FAIL; \
pass: \
        RVTEST_PASS \

在随后生成的.dump文件中,mul.S内宏定义的功能都会被替换为test_macros.h内的代码。包括最后的TEST_PASSFAIL也会被替换。所以可以看到在.dump文件内的内容如下:

.dump

RVTEST_RV32U
RVTEST_CODE_BEGIN
80000000:    7d0023f3              csrr    t2,0x7d0
80000004:    2003f393              andi    t2,t2,512
80000008:    00039a63              bnez    t2,8000001c 
8000000c:    342023f3              csrr    t2,mcause
80000010:    7ff3f393              andi    t2,t2,2047
80000014:    0013c393              xori    t2,t2,1
80000018:    22038863              beqz    t2,80000248 

8000001c :
8000001c:    4081                    li    ra,0
8000001e:    4101                    li    sp,0
80000020:    4181                    li    gp,0
80000022:    4201                    li    tp,0
80000024:    4281                    li    t0,0
80000026:    4315                    li    t1,5
80000028:    4399                    li    t2,6
8000002a:    441d                    li    s0,7
8000002c:    44a1                    li    s1,8
8000002e:    4525                    li    a0,9
80000030:    45a9                    li    a1,10
80000032:    462d                    li    a2,11
80000034:    46b1                    li    a3,12
80000036:    4735                    li    a4,13
80000038:    47b9                    li    a5,14
8000003a:    483d                    li    a6,15
8000003c:    48c1                    li    a7,16
8000003e:    4945                    li    s2,17
80000040:    49c9                    li    s3,18
80000042:    4a4d                    li    s4,19
80000044:    4ad1                    li    s5,20
80000046:    4b55                    li    s6,21
80000048:    4bd9                    li    s7,22
8000004a:    4c5d                    li    s8,23
8000004c:    4ce1                    li    s9,24
8000004e:    4d65                    li    s10,25
80000050:    4de9                    li    s11,26
80000052:    4e6d                    li    t3,27
80000054:    4ef1                    li    t4,28
80000056:    4ff5                    li    t6,29
80000058:    0c40106f              j    8000111c 

    ...

#ifndef N200_CFG_NO_MULDIV
test_start:
  TEST_RR_OP(32,  mul, 0x00001200, 0x00007e00, 0xb6db6db7 );
800012ca:    000080b7              lui    ra,0x8
800012ce:    e0008093              addi    ra,ra,-512 # 7e00 <__stack_size+0x7600>
800012d2:    b6db7637              lui    a2,0xb6db7
800012d6:    db760613              addi    a2,a2,-585 # b6db6db7 <_sp+0x36da6db7>
800012da:    02c085b3              mul    a1,ra,a2
800012de:    00001537              lui    a0,0x1
800012e2:    20050513              addi    a0,a0,512 # 1200 <__stack_size+0xa00>
800012e6:    02000213              li    tp,32
800012ea:    36a59d63              bne    a1,a0,80001664 

    ...

80001416 :

  #-------------------------------------------------------------
  # Source/Destination tests
  #-------------------------------------------------------------

  TEST_RR_SRC1_EQ_DEST( 8, mul, 143, 13, 11 );
80001416:    40b5                    li    ra,13
80001418:    462d                    li    a2,11
8000141a:    02c080b3              mul    ra,ra,a2
8000141e:    08f00513              li    a0,143
80001422:    4221                    li    tp,8
80001424:    24a09063              bne    ra,a0,80001664 

80001428 :
  TEST_RR_SRC2_EQ_DEST( 9, mul, 154, 14, 11 );
80001428:    40b9                    li    ra,14
8000142a:    462d                    li    a2,11
8000142c:    02c08633              mul    a2,ra,a2
80001430:    09a00513              li    a0,154
80001434:    4225                    li    tp,9
80001436:    22a61763              bne    a2,a0,80001664 

8000143a :
  TEST_RR_SRC12_EQ_DEST( 10, mul, 169, 13 );
8000143a:    40b5                    li    ra,13
8000143c:    021080b3              mul    ra,ra,ra
80001440:    0a900513              li    a0,169
80001444:    4229                    li    tp,10
80001446:    20a09f63              bne    ra,a0,80001664 

8000144a :

  #-------------------------------------------------------------
  # Bypassing tests
  #-------------------------------------------------------------

  TEST_RR_DEST_BYPASS( 11, 0, mul, 143, 13, 11 );
8000144a:    4201                    li    tp,0
8000144c:    40b5                    li    ra,13
8000144e:    462d                    li    a2,11
80001450:    02c085b3              mul    a1,ra,a2
80001454:    00058313              mv    t1,a1
80001458:    0205                    addi    tp,tp,1
8000145a:    4289                    li    t0,2
8000145c:    fe5218e3              bne    tp,t0,8000144c 
80001460:    08f00513              li    a0,143
80001464:    422d                    li    tp,11
80001466:    1ea31f63              bne    t1,a0,80001664 

8000146a :
  TEST_RR_DEST_BYPASS( 12, 1, mul, 154, 14, 11 );
8000146a:    4201                    li    tp,0
8000146c:    40b9                    li    ra,14
8000146e:    462d                    li    a2,11
80001470:    02c085b3              mul    a1,ra,a2
80001474:    0001                    nop
80001476:    00058313              mv    t1,a1
8000147a:    0205                    addi    tp,tp,1
8000147c:    4289                    li    t0,2
8000147e:    fe5217e3              bne    tp,t0,8000146c 
80001482:    09a00513              li    a0,154
80001486:    4231                    li    tp,12
80001488:    1ca31e63              bne    t1,a0,80001664 

8000148c :
  TEST_RR_DEST_BYPASS( 13, 2, mul, 165, 15, 11 );
8000148c:    4201                    li    tp,0
8000148e:    40bd                    li    ra,15
80001490:    462d                    li    a2,11
80001492:    02c085b3              mul    a1,ra,a2
80001496:    0001                    nop
80001498:    0001                    nop
8000149a:    00058313              mv    t1,a1
8000149e:    0205                    addi    tp,tp,1
800014a0:    4289                    li    t0,2
800014a2:    fe5216e3              bne    tp,t0,8000148e 
800014a6:    0a500513              li    a0,165
800014aa:    4235                    li    tp,13
800014ac:    1aa31c63              bne    t1,a0,80001664 

800014b0 :

  TEST_RR_SRC12_BYPASS( 14, 0, 0, mul, 143, 13, 11 );
800014b0:    4201                    li    tp,0
800014b2:    40b5                    li    ra,13
800014b4:    462d                    li    a2,11
800014b6:    02c085b3              mul    a1,ra,a2
800014ba:    0205                    addi    tp,tp,1
800014bc:    4289                    li    t0,2
800014be:    fe521ae3              bne    tp,t0,800014b2 
800014c2:    08f00513              li    a0,143
800014c6:    4239                    li    tp,14
800014c8:    18a59e63              bne    a1,a0,80001664 

800014cc :
  TEST_RR_SRC12_BYPASS( 15, 0, 1, mul, 154, 14, 11 );
800014cc:    4201                    li    tp,0
800014ce:    40b9                    li    ra,14
800014d0:    462d                    li    a2,11
800014d2:    0001                    nop
800014d4:    02c085b3              mul    a1,ra,a2
800014d8:    0205                    addi    tp,tp,1
800014da:    4289                    li    t0,2
800014dc:    fe5219e3              bne    tp,t0,800014ce 
800014e0:    09a00513              li    a0,154
800014e4:    423d                    li    tp,15
800014e6:    16a59f63              bne    a1,a0,80001664 

800014ea :
  TEST_RR_SRC12_BYPASS( 16, 0, 2, mul, 165, 15, 11 );
800014ea:    4201                    li    tp,0
800014ec:    40bd                    li    ra,15
800014ee:    462d                    li    a2,11
800014f0:    0001                    nop
800014f2:    0001                    nop
800014f4:    02c085b3              mul    a1,ra,a2
800014f8:    0205                    addi    tp,tp,1
800014fa:    4289                    li    t0,2
800014fc:    fe5218e3              bne    tp,t0,800014ec 
80001500:    0a500513              li    a0,165
80001504:    4241                    li    tp,16
80001506:    14a59f63              bne    a1,a0,80001664 

8000150a :
  TEST_RR_SRC12_BYPASS( 17, 1, 0, mul, 143, 13, 11 );
8000150a:    4201                    li    tp,0
8000150c:    40b5                    li    ra,13
8000150e:    0001                    nop
80001510:    462d                    li    a2,11
80001512:    02c085b3              mul    a1,ra,a2
80001516:    0205                    addi    tp,tp,1
80001518:    4289                    li    t0,2
8000151a:    fe5219e3              bne    tp,t0,8000150c 
8000151e:    08f00513              li    a0,143
80001522:    4245                    li    tp,17
80001524:    14a59063              bne    a1,a0,80001664 

80001528 :
  TEST_RR_SRC12_BYPASS( 18, 1, 1, mul, 154, 14, 11 );
80001528:    4201                    li    tp,0
8000152a:    40b9                    li    ra,14
8000152c:    0001                    nop
8000152e:    462d                    li    a2,11
80001530:    0001                    nop
80001532:    02c085b3              mul    a1,ra,a2
80001536:    0205                    addi    tp,tp,1
80001538:    4289                    li    t0,2
8000153a:    fe5218e3              bne    tp,t0,8000152a 
8000153e:    09a00513              li    a0,154
80001542:    4249                    li    tp,18
80001544:    12a59063              bne    a1,a0,80001664 

80001548 :
  TEST_RR_SRC12_BYPASS( 19, 2, 0, mul, 165, 15, 11 );
80001548:    4201                    li    tp,0
8000154a:    40bd                    li    ra,15
8000154c:    0001                    nop
8000154e:    0001                    nop
80001550:    462d                    li    a2,11
80001552:    02c085b3              mul    a1,ra,a2
80001556:    0205                    addi    tp,tp,1
80001558:    4289                    li    t0,2
8000155a:    fe5218e3              bne    tp,t0,8000154a 
8000155e:    0a500513              li    a0,165
80001562:    424d                    li    tp,19
80001564:    10a59063              bne    a1,a0,80001664 

80001568 :

  TEST_RR_SRC21_BYPASS( 20, 0, 0, mul, 143, 13, 11 );
80001568:    4201                    li    tp,0
8000156a:    462d                    li    a2,11
8000156c:    40b5                    li    ra,13
8000156e:    02c085b3              mul    a1,ra,a2
80001572:    0205                    addi    tp,tp,1
80001574:    4289                    li    t0,2
80001576:    fe521ae3              bne    tp,t0,8000156a 
8000157a:    08f00513              li    a0,143
8000157e:    4251                    li    tp,20
80001580:    0ea59263              bne    a1,a0,80001664 

80001584 :
  TEST_RR_SRC21_BYPASS( 21, 0, 1, mul, 154, 14, 11 );
80001584:    4201                    li    tp,0
80001586:    462d                    li    a2,11
80001588:    40b9                    li    ra,14
8000158a:    0001                    nop
8000158c:    02c085b3              mul    a1,ra,a2
80001590:    0205                    addi    tp,tp,1
80001592:    4289                    li    t0,2
80001594:    fe5219e3              bne    tp,t0,80001586 
80001598:    09a00513              li    a0,154
8000159c:    4255                    li    tp,21
8000159e:    0ca59363              bne    a1,a0,80001664 

800015a2 :
  TEST_RR_SRC21_BYPASS( 22, 0, 2, mul, 165, 15, 11 );
800015a2:    4201                    li    tp,0
800015a4:    462d                    li    a2,11
800015a6:    40bd                    li    ra,15
800015a8:    0001                    nop
800015aa:    0001                    nop
800015ac:    02c085b3              mul    a1,ra,a2
800015b0:    0205                    addi    tp,tp,1
800015b2:    4289                    li    t0,2
800015b4:    fe5218e3              bne    tp,t0,800015a4 
800015b8:    0a500513              li    a0,165
800015bc:    4259                    li    tp,22
800015be:    0aa59363              bne    a1,a0,80001664 

800015c2 :
  TEST_RR_SRC21_BYPASS( 23, 1, 0, mul, 143, 13, 11 );
800015c2:    4201                    li    tp,0
800015c4:    462d                    li    a2,11
800015c6:    0001                    nop
800015c8:    40b5                    li    ra,13
800015ca:    02c085b3              mul    a1,ra,a2
800015ce:    0205                    addi    tp,tp,1
800015d0:    4289                    li    t0,2
800015d2:    fe5219e3              bne    tp,t0,800015c4 
800015d6:    08f00513              li    a0,143
800015da:    425d                    li    tp,23
800015dc:    08a59463              bne    a1,a0,80001664 

800015e0 :
  TEST_RR_SRC21_BYPASS( 24, 1, 1, mul, 154, 14, 11 );
800015e0:    4201                    li    tp,0
800015e2:    462d                    li    a2,11
800015e4:    0001                    nop
800015e6:    40b9                    li    ra,14
800015e8:    0001                    nop
800015ea:    02c085b3              mul    a1,ra,a2
800015ee:    0205                    addi    tp,tp,1
800015f0:    4289                    li    t0,2
800015f2:    fe5218e3              bne    tp,t0,800015e2 
800015f6:    09a00513              li    a0,154
800015fa:    4261                    li    tp,24
800015fc:    06a59463              bne    a1,a0,80001664 

80001600 :
  TEST_RR_SRC21_BYPASS( 25, 2, 0, mul, 165, 15, 11 );
80001600:    4201                    li    tp,0
80001602:    462d                    li    a2,11
80001604:    0001                    nop
80001606:    0001                    nop
80001608:    40bd                    li    ra,15
8000160a:    02c085b3              mul    a1,ra,a2
8000160e:    0205                    addi    tp,tp,1
80001610:    4289                    li    t0,2
80001612:    fe5218e3              bne    tp,t0,80001602 
80001616:    0a500513              li    a0,165
8000161a:    4265                    li    tp,25
8000161c:    04a59463              bne    a1,a0,80001664 

80001620 :

  TEST_RR_ZEROSRC1( 26, mul, 0, 31 );
80001620:    40fd                    li    ra,31
80001622:    02100633              mul    a2,zero,ra
80001626:    4501                    li    a0,0
80001628:    4269                    li    tp,26
8000162a:    02a61d63              bne    a2,a0,80001664 

8000162e :
  TEST_RR_ZEROSRC2( 27, mul, 0, 32 );
8000162e:    02000093              li    ra,32
80001632:    02008633              mul    a2,ra,zero
80001636:    4501                    li    a0,0
80001638:    426d                    li    tp,27
8000163a:    02a61563              bne    a2,a0,80001664 

8000163e :
  TEST_RR_ZEROSRC12( 28, mul, 0 );
8000163e:    020000b3              mul    ra,zero,zero
80001642:    4501                    li    a0,0
80001644:    4271                    li    tp,28
80001646:    00a09f63              bne    ra,a0,80001664 

8000164a :
  TEST_RR_ZERODEST( 29, mul, 33, 34 );
8000164a:    02100093              li    ra,33
8000164e:    02200613              li    a2,34
80001652:    02c08033              mul    zero,ra,a2
80001656:    4501                    li    a0,0
80001658:    4275                    li    tp,29
8000165a:    00a01563              bne    zero,a0,80001664 
#check_mode:
#  addi t3, t3, 1;
#  bne  t4, t4, test_start;

#endif 
  j pass
8000165e:    a801                    j    8000166e 

  TEST_PASSFAIL
80001660:    00401763              bne    zero,tp,8000166e 

80001664 :
80001664:    0ff0000f              fence
80001668:    4201                    li    tp,0
8000166a:    00000073              ecall

8000166e :
8000166e:    0ff0000f              fence
80001672:    0000f297              auipc    t0,0xf
80001676:    98e28293              addi    t0,t0,-1650 # 80010000 <_sp>
8000167a:    8116                    mv    sp,t0
8000167c:    4185                    li    gp,1
8000167e:    00000073              ecall
80001682:    0001                    nop
80001684:    0001                    nop
80001686:    0001                    nop
80001688:    0001                    nop
8000168a:    0001                    nop

.dump/.verilog文件均为mul.S文件所生成,.verilog文件可以被仿真verilog代码读取。

从testcase到testbench

testbench中最顶层文件为tb_top.v

tb_top.v负责例化n200_core,并将JTAG从n200_core中连接出来。

tb_monitor.v负责监视testcase的运行情况,在testcase运行完毕后,如果x3为1则运行成功输出pass,否则输出fail。在终端输出的pass与fail均为tb_monitor.v的输出结果,Makefile中的命令将终端的输出结果保存于.log文件。

tb_mem_init负责初始化运行程序的存储,其中有一行代码为:

$readmemh({testcase, ".verilog"}, ilm_mem);

负责将.verilog二进制文件读入mem内部,从而可以执行汇编程序。

波形生成

首先在观察波形之前,需要找到相关寄存器所在位置。由于随机SEED种子的原因,很多地方名字不易辨析,但是最终找到了相关的寄存器位置。如下图所示:

image-20211102141059203

现在观察相关波形,首先观察pc的运行:

image-20211102141143325

pc从0跳到1000,然后跳到1004,接着从8000_0000执行程序。

以下部分对应于li赋值代码:

image-20211102141226473

观察testcase测试部分的波形

从8000_12ca开始的test部分:

image-20211102141327715

源码如下:

test_start:
  TEST_RR_OP(32,  mul, 0x00001200, 0x00007e00, 0xb6db6db7 );
800012ca:    000080b7              lui    ra,0x8
800012ce:    e0008093              addi    ra,ra,-512 # 7e00 <__stack_size+0x7600>
800012d2:    b6db7637              lui    a2,0xb6db7
800012d6:    db760613              addi    a2,a2,-585 # b6db6db7 <_sp+0x36da6db7>
800012da:    02c085b3              mul    a1,ra,a2
800012de:    00001537              lui    a0,0x1
800012e2:    20050513              addi    a0,a0,512 # 1200 <__stack_size+0xa00>
800012e6:    02000213              li    tp,32
800012ea:    36a59d63              bne    a1,a0,80001664 

ra在执行完两个指令后变为了7e00,a2在执行完两个指令后变为了0xb6db7,接下来的乘法指令运行了17个周期,并最终在a1中得到了1200。接下来的两个指令将a0赋值为1200,最后做了比较判断。

从8000_1416开始的test部分:

image-20211102142209016

源码如下:

  TEST_RR_SRC1_EQ_DEST( 8, mul, 143, 13, 11 );
80001416:    40b5                    li    ra,13
80001418:    462d                    li    a2,11
8000141a:    02c080b3              mul    ra,ra,a2
8000141e:    08f00513              li    a0,143
80001422:    4221                    li    tp,8
80001424:    24a09063              bne    ra,a0,80001664 

在经过一个指令后ra赋值为13,在经过一个指令后a2赋值为11。接下来的乘法指令执行了17个周期并最终将计算结果赋值为ra=8f。下一个指令将a0赋值为8f,最后比较判断。

从8000_15e0开始的test部分:

image-20211102142918577

源码如下:

  TEST_RR_SRC21_BYPASS( 24, 1, 1, mul, 154, 14, 11 );
800015e0:    4201                    li    tp,0
800015e2:    462d                    li    a2,11
800015e4:    0001                    nop
800015e6:    40b9                    li    ra,14
800015e8:    0001                    nop
800015ea:    02c085b3              mul    a1,ra,a2
800015ee:    0205                    addi    tp,tp,1
800015f0:    4289                    li    t0,2
800015f2:    fe5218e3              bne    tp,t0,800015e2 
800015f6:    09a00513              li    a0,154
800015fa:    4261                    li    tp,24
800015fc:    06a59463              bne    a1,a0,80001664 

在插入nop指令后,在第四个指令ra才变为14。同时,由于这个乘法指令需要执行两遍,所以可以看到两条8000_15ea指令。

上次的问题

给ISA扩展留出了足够空间

最基础的RV32I指令集只使用了32位指令字中的编码空间的不到1/8。如果仅仅计算op_code为11/128,没有算上func_code。

同时,RV32I中的共同数据通路的指令的操作码位有尽可能多的位的值是一样的,简化了逻辑控制。

lui与auipc指令的引入

作用:1、大范围PC跳转

​ 2、构造大立即数

image-20211102150242430

喜欢1
用户评论 (2)
李昌昱

李昌昱 实名认证

懒的都不写签名

积分
问答
粉丝
关注
  • RV-STAR 开发板
  • RISC-V处理器设计系列课程
  • 培养RISC-V大学土壤 共建RISC-V教育生态
RV-STAR 开发板