当前位置:网站首页>RISC-V工具链编译笔记
RISC-V工具链编译笔记
2022-07-26 22:49:00 【Time Flies Fang】
前言
RISC-V指令集由于其开源而精简的优点,目前正在越来越广泛地在业界中使用。本文以一个开源项目蜂鸟E200 RISC-V SoC为例,分析整理了该项目中自测试用例的测试方法与过程,希望可以给同样在探究学习RISC-V的小伙伴们一些帮助。
一、E200 RV工具链文件结构
E200的工具链放在riscv-tests文件夹下,该文件夹下的工具链可以把汇编指令(.S文件)编译成二进制文件(存放在genreated文件夹下),编译过程也会include在/env与/isa/macros下面的一些宏定义以复用一些标准的汇编程序
二、addi.S汇编程序
本节以addi.S,即立即数加法指令为例,分析e200 SoC的自测试用例的测试方法,这也可以帮助大家理解从软件到硬件的映射过程。
1.源代码
#*****************************************************************************
# addi.S
#-----------------------------------------------------------------------------
#
# Test addi instruction.
#
#include "riscv_test.h"
#include "test_macros.h"
RVTEST_RV64U
RVTEST_CODE_BEGIN
#-------------------------------------------------------------
# Arithmetic tests
#-------------------------------------------------------------
TEST_IMM_OP( 2, addi, 0x00000000, 0x00000000, 0x000 );
TEST_IMM_OP( 3, addi, 0x00000002, 0x00000001, 0x001 );
TEST_IMM_OP( 4, addi, 0x0000000a, 0x00000003, 0x007 );
TEST_IMM_OP( 5, addi, 0xfffffffffffff800, 0x0000000000000000, 0x800 );
TEST_IMM_OP( 6, addi, 0xffffffff80000000, 0xffffffff80000000, 0x000 );
TEST_IMM_OP( 7, addi, 0xffffffff7ffff800, 0xffffffff80000000, 0x800 );
TEST_IMM_OP( 8, addi, 0x00000000000007ff, 0x00000000, 0x7ff );
TEST_IMM_OP( 9, addi, 0x000000007fffffff, 0x7fffffff, 0x000 );
TEST_IMM_OP( 10, addi, 0x00000000800007fe, 0x7fffffff, 0x7ff );
TEST_IMM_OP( 11, addi, 0xffffffff800007ff, 0xffffffff80000000, 0x7ff );
TEST_IMM_OP( 12, addi, 0x000000007ffff7ff, 0x000000007fffffff, 0x800 );
TEST_IMM_OP( 13, addi, 0xffffffffffffffff, 0x0000000000000000, 0xfff );
TEST_IMM_OP( 14, addi, 0x0000000000000000, 0xffffffffffffffff, 0x001 );
TEST_IMM_OP( 15, addi, 0xfffffffffffffffe, 0xffffffffffffffff, 0xfff );
TEST_IMM_OP( 16, addi, 0x0000000080000000, 0x7fffffff, 0x001 );
2.预定义文件
从源码中我们可以看到,汇编语言中include了riscv_test.h和test_macros.h两个文件,在riscv_test.h中的代码主要定义的是SoC的启动代码,当顶层汇编调用RVTEST_CODE_BEGIN宏定义时,替换为以下的代码(节选)
可以看到,启动代码部分主要对SoC的异常,中断等机制进行初始化设置,此部分内容如果后续有机会学习的话会再详细分析。对于所有自测试用例,该部分代码都是一样的。
在test_macros.h文件中,定义的是自测试用例的一些测试函数,以addi.S为例,TEST_IMM_OP就是一个test_macros.h中的宏定义,其相关代码为:
#define TEST_CASE( testnum, testreg, correctval, code... ) \ test_ ## testnum: \ code; \ li x29, MASK_XLEN(correctval); \ li TESTNUM, testnum; \ bne testreg, x29, fail;
//......
#define TEST_IMM_OP( testnum, inst, result, val1, imm ) \ TEST_CASE( testnum, x30, result, \ li x1, MASK_XLEN(val1); \ inst x30, x1, SEXT_IMM(imm); \ )
我们以:
TEST_IMM_OP( 4, addi, 0x0000000a, 0x00000003, 0x007 );
这条代码为例,在功能上,就是这是第四条测试指令(testnum),测试的是addi指令(inst),正确结果是0xa(result),操作数与立即数(val1, imm)分别为0x3和0x7。那么,在汇编指令尺度,或者说在硬件尺度上,是如何验证这个“3+7=10”测试的正确的呢?
我们看test_macros.h中的宏定义,如果将相关的宏定义全部转为汇编代码,这一条测试函数的汇编代码可以写为:
li x1, 0x3;
addi x30, x1, 0x7;
li x29, 0xa;
li TESTNUM, 4;
bne x30, x29, fail;
经过简化和分析,上述汇编代码已经十分简单了,li在RV中是加载立即数(load immediate)的意思,bne是RV中的分支跳转指令,当两个寄存器存储的值不相等时使得程序计数器(PC)跳转。上述代码的作用就是把运算结果存储在x30寄存器中,把正确结果存储在x29寄存器中,并判断两个寄存器的值是否相等。
为了验证我们的分析是否正确,我们还可以进入文件结构中/isa/generated中,找到以.dump为后缀的文件,这部分文件又被成为反汇编文件,可以直接用文本编辑器打开,可以把工具链编译出来的二进制文件重新反汇编为汇编语言,来帮助开发者看清编译器工作是否正常,找到该部分的反汇编代码为:
//rv32ui-p-addi.dump
8000027e <test_4>:
8000027e: 408d li ra,3
80000280: 00708f13 addi t5,ra,7
80000284: 4ea9 li t4,10
80000286: 4191 li gp,4
80000288: 1ddf1763 bne t5,t4,80000456 <fail>
上述代码最左边一列为指令地址,中间一列为16进制的指令内容,最右边一列为反汇编代码,可以看到编译器重新分配了地址空间与命名符,但是具体功能与我们的分析是一致的
总结
自顶向下地探究从软件到硬件的过程十分重要,可以帮助我们理解处理器的设计与验证流程。后续我也将继续更深入地以e200蜂鸟SoC框架为例来归纳整理软硬件协同的工作流程。
边栏推荐
- TCP的三次握手与四次挥手(简述)
- C语言——赋值运算符、复合的赋值运算符、自增自减运算符、逗号运算符、条件运算符、goto语句、注释
- Codeforces Round #809 (Div. 2), problem: (C) Qpwoeirut And The City
- Lora网关节点汇聚传感器数据
- Codeforces Round #810 (Div. 2), problem: (B) Party
- Solution: various error reporting and pit stepping and pit avoiding records encountered in the alchemist cultivation plan pytoch+deeplearning (III)
- VLAN原理简述、具体实验配置
- 第三讲--GPIO输入输出库函数使用以及相关例程
- TCP's three handshakes and four waves (brief introduction)
- 6.29 Zhong'an Summer Internship
猜你喜欢

C语言——数据类型、基本数据类型的取值范围

lvs+keepalived项目实战

定时器中断实验

Test and open basic daily question brushing (continuous updating...)

OSPF static experiment
![Unity Huatuo revolutionary hot update series [1]](/img/bc/ed480fc979c08c362784a3956d7fe2.jpg)
Unity Huatuo revolutionary hot update series [1]

HCIA Basics (1)

The latest C language introduction and advanced - the most complete and detailed C language tutorial in history!! Section 1 - overview of C language

Dynamic routing ofps protocol configuration

C语言——数组、字符串处理函数、strlen、strcpy和strncpy、strcat和strncat、strcmp和strncmp
随机推荐
Experiment exercise of two-layer packaging technology (HDLC, ppp--pap\chap, GRE)
广域网技术实验
C语言——while语句、dowhile语句、for循环和循环结构、break语句和continue语句
HCIA Basics (1)
[MySQL] MySQL startup and shutdown commands and some error reports to solve problems
Educational Codeforces Round 132 (Rated for Div. 2), problem: (D) Rorororobot
RS-485总线通信应用
TCP的三次握手与四次断开
[详解C语言]一文带你玩转函数
Three methods that can effectively fuse text and image information -- feature stitching, cross modal attention, conditional batch normalization
静态路由缺省路由vlan实验
mgre的全连和星型拓扑实验
HCIA动态路由RIP基础实验
Codeforces Round #796 (Div. 2), problem: (1688C) Manipulating History
Lora通信应用开发
数字集成电路:CMOS反相器(一)静态特性
WAN technology experiment
OSPF configuration in mGRE environment and LSA optimization - reduce the amount of LSA updates (summary, special areas)
[explain C language in detail] this article takes you to know C language and makes you impressed
Unity Huatuo revolutionary hot update series [1]