【RISC-V设计-13】- RISC-V处理器设计K0A之指令测试
文章目录
- 【RISC-V设计-13】- RISC-V处理器设计K0A之指令测试
- 1.简介
- 2.验证用例
- 3.指令代码
- 4.链接脚本
- 5.编译脚本
- 6.仿真结果
- 6.1 复位结束
- 6.2 运行成功
- 6.3 终端打印
- 7.总结
1.简介
借助上一篇文章所提及的验证环境,在本篇文章中,将会阐述如何增添一个用例来验证指令集,以及怎样运用编译器编译汇编代码,并生成二进制的 Bin 文件。针对 RISC-V 所使用的编译器,这里采用的是“山河编译器”。山河编译器(MounRiver Studio)是一款国产的集成开发环境(IDE),官网地址:http://www.mounriver.com,可自行下载对应版本,并将编译器路径添加到环境变量中。
2.验证用例
// -------------------------------------------------------------------------------------------------
// Copyright 2024 Kearn Chen, kearn.chen@aliyun.com
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -------------------------------------------------------------------------------------------------
// Description :
// 1. Instr smoke test
// -------------------------------------------------------------------------------------------------task initcase;load_instr("instr_smoke_test/instr_smoke_test.bin");endtasktask testcase;#1_000_000;endtask
在验证用例中,任务initcase
加载Bin文件到仿真模型中,任务testcase
延迟1毫秒,等待CPU执行完软件指令。
3.指令代码
/*Copyright 2018-2021 T-Head Semiconductor Co., Ltd.Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
.text
.align 1
.global _start
_start:#---------------------------------------#
# main execution routine #
#---------------------------------------#
#---------------------------------------#
# RV32I instructions #
#---------------------------------------#
#---------------------------------------#
# Int Reg-imm Ins #
#---------------------------------------#
#ADDi
ADDI:#func 1 test basic#-1 +5li x5, 0x4li x4, 0x5addi x4, x4, 0xffffffffbne x4, x5, TEST_FAIL#2047+2047li x5, 0xffeli x4, 0x7ffaddi x4, x4, 0x7ffbne x4, x5, TEST_FAIL#-2048+-2048li x5, 0xfffff000li x4, 0xfffff800addi x4, x4, 0xfffff800bne x4, x5, TEST_FAIL#func 2 test MVaddi x4, x4, 0x123addi x5, x4, 0x0bne x4, x5, TEST_FAIL#func 3 test nopli x5, 0x0addi x5, x5, 0x0addi x0, x0, 0x0addi x0, x0, 0x5bne x5, x0, TEST_FAIL#SLTI
SLTI:li x4, 0x1#signed compare 0xfff compare with 0xffffffff(imm expand)li x5, 0xfffslti x5, x5, 0xffffffffbne x5, x0, TEST_FAIL#signed compare 0xfff compare with 0x1(imm not expand)li x5, 0xfffslti x5, x5, 0x1bne x5, x0, TEST_FAIL#signed compare 0xffffffff compare with 0x1 li x5, 0xffffffffslti x5, x5, 0x1bne x5, x4, TEST_FAIL#signed compare 0x1 compare with 0x1li x5, 0x1slti x5, x5, 0x1bne x5, x0, TEST_FAIL#SLTIU
SLTIU:li x4, 0x1#0xffffffff compare with 0xfffli x5, 0xffffffffsltiu x5, x5, 0x7ffbne x5, x0, TEST_FAIL#0xfff compare with 0x1li x5, 0xfffsltiu x5, x5, 0x1bne x5, x0, TEST_FAIL#0x1 compare with 0xfff(no sign extend)li x5, 0x1sltiu x5, x5, 0x7ffbne x5, x4, TEST_FAIL#ANDI
ANDI:#0xaaaaaaaa andi 0xfff(sign extend)li x4, 0xaaaaaaaali x5, 0xaaaaaaaaandi x5, x5, 0xffffffffbne x4, x5, TEST_FAIL#0xaaaaaaaa andi 0x7ff(sign extend)li x4, 0x2aali x5, 0xaaaaaaaaandi x5, x5, 0x7ffbne x4, x5, TEST_FAIL#0xaaaaaaaa andi 0x0li x4, 0x0li x5, 0xaaaaaaaaandi x5, x5, 0x0bne x4, x5, TEST_FAIL#ORI
ORI:#0xaaaaaaaa ori 0xffffffff(sign extend)li x4, 0xffffffffli x5, 0xaaaaaaaaori x5, x5, 0xffffffffbne x4, x5, TEST_FAIL#0xaaaaaaaa ori 0x7ff(sign extend)li x4, 0x2aali x5, 0xaaaaaaaaori x5, x5, 0x7ffbeq x4, x5, TEST_FAIL#0xaaaaaaaa ori 0x0li x4, 0xaaaaaaaali x5, 0xaaaaaaaaori x5, x5, 0x0bne x4, x5, TEST_FAIL#XORI
XORI:#notli x4, 0xabcdabcdxori x5, x4, -1not x6, x4bne x6, x5, TEST_FAIL#0xfli x4, 0xabcdffffli x6, 0xabcdfff0xori x5, x4, 0xfbne x6, x5, TEST_FAIL#0x0li x4, 0xabcdabcdli x6, 0xabcdabcdxori x5, x4, 0x0bne x6, x5, TEST_FAIL#SLLI
SLLI:li x4, 0xabcd1234slli x2, x4, 0 #IMM5 = 0, x2 = x4bne x2, x4, TEST_FAILli x4, 0xabcd1234slli x2, x4, 31 #IMM5 = 31, x2 = 0li x3, 0x0bne x2, x3, TEST_FAILli x4, 0xaaaaaaaaslli x2, x4, 8 #IMM5 = 8, x2 = 0xaaaaaali x3, 0xaaaaaa00bne x2, x3, TEST_FAIL#SRLI
SRLI:li x2, 0xabcd1234srli x3, x2, 0 #IMM5 = 0, r2 = r1bne x2, x3, TEST_FAILli x2, 0xaaaaaaaasrli x3, x2, 31 #IMM5 = 31, r2 = 1li x4, 0x1bne x3, x4, TEST_FAILli x2, 0xaaaaaaaasrli x2, x2, 1 #IMM5 = 1, r2 = 0x55555555li x3, 0x55555555bne x2, x3, TEST_FAIL#SRAI
SRAI:li x2, 0xaaaaaaaasrai x2, x2, 31 #IMM5 = 31,sign=1, x2 = 0xffffffffli x3, 0xffffffffbne x2, x3, TEST_FAILli x2, 0x55555555srai x2, x2, 31 #IMM5=31, sign=0, x2 = 0li x3, 0bne x2, x3, TEST_FAILli x2, 0x55555555srai x2, x2, 1 #IMM5=1 , x2 = 2aaaaaaali x3, 0x2aaaaaaabne x2, x3, TEST_FAILli x2, 0xabcd1234srai x2, x2, 0 # /IMM5=0, r2 = abcd1234li x3, 0xabcd1234bne x2, x3, TEST_FAIL#LUI
LUI:lui x2, 0x7bcd1 li x3, 0x7bcd1000bne x2, x3, TEST_FAILlui x2, 0x89abc li x3, 0x89abc000bne x2, x3, TEST_FAIL#AUIPC
AUIPC:auipc x2, 0x0li x3, 0xa010add x2, x3, x2auipc x4, 0xabne x2, x4, TEST_FAILauipc x2, 0x0li x3, 0x80000010add x2, x3, x2auipc x4, 0x80000bne x2, x4, TEST_FAIL#---------------------------------------#
# Int Reg-Reg Ins #
#---------------------------------------#
#ADD
ADD:#-1+ -1li x3, 0xffffffffli x4, 0xffffffffadd x5, x3, x4li x6, 0xfffffffebne x5, x6, TEST_FAIL#0x8000000+ 0x80000000li x3, 0x80000000li x4, 0x80000000add x5, x3, x4li x6, 0x0bne x5, x6, TEST_FAIL#0x7fffffff+ 0x7fffffffli x3, 0x7fffffffli x4, 0x7fffffffadd x5, x3, x4li x6, 0xfffffffebne x5, x6, TEST_FAIL#SUB
SUB:#0x80000000- 0x7fffffffli x3, 0x80000000li x4, 0x7fffffffsub x5, x3, x4li x6, 0x1bne x5, x6, TEST_FAIL#0x7fffffff - 0x80000000li x3, 0x7fffffffli x4, 0x80000000sub x5, x3, x4li x6, 0xffffffffbne x5, x6, TEST_FAIL#0xf - 0x2li x3, 0xfli x4, 0x2sub x5, x3, x4li x6, 0xdbne x5, x6, TEST_FAIL#SLT
SLT:li x3, 0x1li x4, 0x0li x5, 0x80000000li x6, 0xffffffff#1 / 1slt x7, x3, x3bne x7, x4, TEST_FAIL#1 / 0slt x7, x3, x4bne x7, x4, TEST_FAIL#0 / 1slt x7, x4, x3bne x7, x3, TEST_FAIL#0x80000000/ 0x1 # -max /1slt x7, x5, x3bne x7, x3, TEST_FAIL#SLTU
SLTU:li x3, 0x1li x4, 0x0li x5, 0x80000000li x6, 0xffffffff#1 / 1sltu x7, x3, x3bne x7, x4, TEST_FAIL#1 / 0sltu x7, x3, x4bne x7, x4, TEST_FAIL#0 / 1sltu x7, x4, x3bne x7, x3, TEST_FAIL#0x80000000/0x1 sltu x7, x5, x3bne x7, x4, TEST_FAIL#AND
AND:li x3, 0x0li x4, 0xffffffff#0xabcdabcd 0xffffffffli x5, 0xabcdabcdand x6, x5, x4bne x6, x5, TEST_FAIL#0xabcdabcd 0x0 li x5, 0xabcdabcdand x6, x5, x3bne x6, x3, TEST_FAIL#OR
OR:li x3, 0x0li x4, 0xffffffff#0xabcdabcd | 0xffffffffli x5, 0xabcdabcdor x6, x5, x4bne x6, x4, TEST_FAIL#0xabcdabcd | 0x0 li x5, 0xabcdabcdor x6, x5, x3bne x6, x5, TEST_FAIL#XOR
XOR:li x3, 0x0li x4, 0xffffffff#0xabcd | 0xffffffff #notli x5, 0xabcdabcdxor x6, x5, x4not x5, x5bne x6, x5, TEST_FAIL#0xabcd | 0x0 li x5, 0xabcdabcdxor x6, x5, x3bne x6, x5, TEST_FAIL#SLL
SLL:li x4, 0xabcd1234sll x2, x4, x0 #IMM5 = 0, x2 = x4bne x2, x4, TEST_FAILli x4, 0xabcd1234li x5, 31sll x2, x4, x5 #IMM5 = 31, x2 = 0li x3, 0x0bne x2, x3, TEST_FAILli x4, 0xaaaaaaaali x5, 0x8sll x2, x4, x5 #IMM5 = 8, x2 = 0xaaaaaali x3, 0xaaaaaa00bne x2, x3, TEST_FAILli x4, 0xaaaaaaaali x5, 0x21sll x2, x4, x5 #IMM5 = 0x1, x2 = 0x55555554li x3, 0x55555554bne x2, x3, TEST_FAIL#SRL
SRL:li x2, 0xabcd1234srl x3, x2, x0 #IMM5 = 0, r2 = r1bne x2, x3, TEST_FAILli x2, 0xaaaaaaaali x5, 31srl x3, x2, x5 #IMM5 = 31, r2 = 1li x4, 0x1bne x3, x4, TEST_FAILli x2, 0xaaaaaaaali x5, 0x1srl x2, x2, x5 #IMM5 = 1, r2 = 0x55555555li x3, 0x55555555bne x2, x3, TEST_FAILli x2, 0xaaaaaaaali x5, 0x21srl x2, x2, x5 #IMM5 = 0x1, x2 = 0x55555555li x3, 0x55555555bne x2, x3, TEST_FAIL#SRA
SRA:li x2, 0xaaaaaaaali x5, 0x1fsra x2, x2, x5 #IMM5 = 31,sign=1, x2 = 0xffffffffli x3, 0xffffffffbne x2, x3, TEST_FAILli x2, 0x55555555li x5, 0x1fsra x2, x2, x5 #IMM5=31, sign=0, x2 = 0li x3, 0bne x2, x3, TEST_FAILli x2, 0x55555555li x5, 0x1sra x2, x2, x5 #IMM5=1 , x2 = 2aaaaaaali x3, 0x2aaaaaaabne x2, x3, TEST_FAILli x2, 0x55555555li x5, 0x21sra x2, x2, x5 #IMM5=1 , x2 = 2aaaaaaali x3, 0x2aaaaaaabne x2, x3, TEST_FAILli x2, 0xabcd1234sra x2, x2, x0 # /IMM5=0, r2 = abcd1234li x3, 0xabcd1234bne x2, x3, TEST_FAIL######################################################
# RV32I
#######################################################*****************************************************
# store and load
#*****************************************************#r1 is link reg ,r2 is stack reg#r0 = 0#r3 = ffffffffli x3,0xffffffffli x8,0xaaaaaaaa#x3 = ffffffff#addr is in x4#sw and lw li x4,0x0000a000 #x4 = 0000a000sw x8,0xfffffffc(x4) #mem[0x0000affc] = 0xaaaaaaaalw x5,0xfffffffc(x4) # x5 = aaaaaaaabne x8,x5,TEST_FAIL sw x8,0x7fc(x4) #mem[0x0000a7fc] = 0xaaaaaaaalw x5,0x7fc(x4) # x5 = aaaaaaaabne x8,x5,TEST_FAIL sw x3,0x0(x4) #mem[0x0000a000] = 0xfffffffflw x5,0x0(x4) # x5 = 0xffffffffbne x3,x5,TEST_FAIL li x6,0xffff8000 #x6 = 0xffff_8000li x8,0x00008000 #x8 cmp reg = 0000_8000li x9,0xaaaaaaaali x10,0xaaaa8000#sh and lhsw x9,0x0(x4) #mem[0x0000a000] = 0xaaaaaaaash x6,0x0(x4) #mem[0x0000a000] = 0xaaaa_8000lhu x7,0x0(x4) # x7 = 0x0000_8000 zeroextendlh x5,0x0(x4) #x5 = 0xffff_8000 signextendlw x11,0x0(x4) bne x7,x8,TEST_FAILbne x6,x5,TEST_FAILbne x11,x10,TEST_FAILsh x6,0xfffffffe(x4) #mem[0x0000affe] = 0x8000lhu x7,0xfffffffe(x4) # x7 = 0x0000_8000 zeroextendlh x5,0xfffffffe(x4) #x5 = 0xffff_8000 signextendbne x7,x8,TEST_FAILbne x6,x5,TEST_FAILsh x6,0x7fe(x4) #mem[0x0000a7fe] = 0x8000lhu x7,0x7fe(x4) # x7 = 0x0000_8000 zeroextendlh x5,0x7fe(x4) #x5 = 0xffff_8000 signextendbne x7,x8,TEST_FAILbne x6,x5,TEST_FAIL#sb and lbli x8,0x000000ffli x9,0xaaaaaaaali x10,0xaaaaaaffsw x9,0x0(x4) #mem[0x0000a000] = 0xaaaaaaaasb x3,0x0(x4) #mem[0x0000a000] = 0xaaaaaafflbu x7,0x0(x4) # x7 = 0x0000_00ff zeroextendlb x5,0x0(x4) #x5 = 0xffff_ffff signextendlw x11,0x0(x4) bne x7,x8,TEST_FAILbne x3,x5,TEST_FAILbne x10,x11,TEST_FAILsb x3,0xffffffff(x4) #mem[0x0000afff] = fflbu x7,0xffffffff(x4) # x7 = 0x0000_00ff zeroextendlb x5,0xffffffff(x4) #x5 = 0xffff_ffff signextendbne x7,x8,TEST_FAILbne x3,x5,TEST_FAILsb x3,0x7ff(x4) #mem[0x0000a7ff] = fflbu x7,0x7ff(x4) # x7 = 0x0000_00ff zeroextendlb x5,0x7ff(x4) #x5 = 0xffff_ffff signextendbne x7,x8,TEST_FAILbne x3,x5,TEST_FAIL#*************************************************
# jmp
#**************************************************jal x1, BRANCH_LABEL
A:jal x0,JREG_LABEL #j#***********************************************************
# branch
#r0 = 0
#r3 = ffff_ffff
#r4 = 8000_0000
#*************************************************************BRANCH_LABEL:li x4,0x80000000
#beq beq x0,x4,TEST_FAILbeq x4,x4,BNE_LABEL beq x0,x0,TEST_FAIL #not execute#bne
BNE_LABEL:bne x4,x4,TEST_FAILbne x0,x4,BLT_LABEL beq x0,x0,TEST_FAIL #not execute#blt
BLT_LABEL: blt x0,x4,TEST_FAILblt x4,x4,TEST_FAILblt x4,x0,BGE_LABELbeq x0,x0,TEST_FAIL #not execute#bge
BGE_LABEL:bge x4,x3,TEST_FAILbge x3,x4,BGEE_LABELbeq x0,x0,TEST_FAIL #not executeBGEE_LABEL: #equalbge x3,x3,BGEU_LABELbeq x0,x0,TEST_FAIL #not execute#bgeu
BGEU_LABEL:bgeu x4,x3,TEST_FAILbgeu x3,x4,BGEUE_LABELbeq x0,x0,TEST_FAIL #not executeBGEUE_LABEL:bgeu x3,x3,BLTU_LABELbeq x0,x0,TEST_FAIL #not execute#bltu
BLTU_LABEL:bltu x4,x0,TEST_FAILbltu x4,x4,TEST_FAILbltu x0,x4,J_LABELbeq x0,x0,TEST_FAIL #not executeJ_LABEL:jalr x1,x1,0x0 #jump to AB:jal x0,TEST_PASSJREG_LABEL:jalr x0,x1,0x0 #jr jump to B#---------------------------------------#
#exit
#---------------------------------------#
TEST_PASS:la a0, 0xC0000la a1, 0x54 // 'T'sw a1, (a0)la a1, 0x65 // 'e'sw a1, (a0)la a1, 0x73 // 's'sw a1, (a0)la a1, 0x74 // 't'sw a1, (a0)la a1, 0x20 // ' 'sw a1, (a0)la a1, 0x70 // 'p'sw a1, (a0)la a1, 0x61 // 'a'sw a1, (a0)la a1, 0x73 // 's'sw a1, (a0)la a1, 0x73 // 's'sw a1, (a0)la a1, 0x21 // '!'sw a1, (a0)la a1, 0x0a // '\n'sw a1, (a0)
1:j 1b#---------------------------------------#
#fail
#---------------------------------------#
TEST_FAIL:la a0, 0xC0000la a1, 0x54 // 'T'sw a1, (a0)la a1, 0x65 // 'e'sw a1, (a0)la a1, 0x73 // 's'sw a1, (a0)la a1, 0x74 // 't'sw a1, (a0)la a1, 0x20 // ' 'sw a1, (a0)la a1, 0x66 // 'f'sw a1, (a0)la a1, 0x61 // 'a'sw a1, (a0)la a1, 0x6a // 'i'sw a1, (a0)la a1, 0x6c // 'l'sw a1, (a0)la a1, 0x21 // '!'sw a1, (a0)la a1, 0x0a // '\n'sw a1, (a0)
1:j 1b
上述测试指令来源于平头哥的玄铁E902的冒烟测试用例,对其做了大量修改,删去了压缩指令集部分。在所有指令都执行正确后,会跳转到TEST_PASS
代码段,并在终端上打印"Test pass!"
,然后等待仿真结束。在进行指令测试时,任意指令执行错误,都会跳转到TEST_FAIL
代码段,并在终端上打印"Test fail!"
,然后等待结束仿真。
4.链接脚本
OUTPUT_ARCH( "riscv" )
ENTRY(_start)SECTIONS
{. = 0x00000000;.text.init : { *(.text.init) }. = ALIGN(0x1000);.tohost : { *(.tohost) }. = ALIGN(0x1000);.text : { *(.text) }. = ALIGN(0x1000);.data : { *(.data) }.bss : { *(.bss) }_end = .;
}
5.编译脚本
# -------------------------------------------------------------------------------------------------
# Copyright 2024 Kearn Chen, kearn.chen@aliyun.com
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# -------------------------------------------------------------------------------------------------PREFIX := riscv-none-embed-LINKER := link.ldOBJECT += instr_smoke.oCFLAGS := -march=rv32e -mabi=ilp32eLFLAGS := -march=rv32e -mabi=ilp32e -T$(LINKER) -nostartfiles -nostdlibTARGET := $(notdir $(shell pwd))all : $(TARGET).asm $(TARGET).bin%.bin : %.elf$(PREFIX)objcopy -Obinary $< $@%.asm : %.elf$(PREFIX)objdump -D $< > $@%.elf : $(OBJECT)$(PREFIX)gcc $(LFLAGS) -o $@ $^%.o : %.S$(PREFIX)gcc $(CFLAGS) -c -o $@ $<clean :@rm -rf *.o *.elf *.asm *.bin.PHONY: clean all.SECONDARY:
6.仿真结果
6.1 复位结束
6.2 运行成功
6.3 终端打印
*Verdi* : Create FSDB file 'novas.fsdb'
*Verdi* : Begin traversing the scopes, layer (0).
*Verdi* : End of traversing.
[MCU_INFO] : Test pass!
$finish called from file "../env/test_top.v", line 78.
$finish at simulation time 1001000
7.总结
本文介绍了指令集的验证流程以及一个基本的指令冒烟用例,通过精心设计的指令码,能够有效地支持自动比对功能的实现。