8-从零开始学RISC-V之指令集仿真

从零开始学RISC-V之指令集仿真

背景介绍

一个十分常见的情形是,我们需要确定CPU能正确执行我们的程序,例如对跳转之类的处理,这在应用程序中十分常见。或许可以在程序中增加自测试代码,但这无疑增加代码量并且属于无实际意义的代码量,并且由于不能实现指令级的检查,所以并不具备应用价值。因此需要一种标准的仿真器,这种仿真器独立于处理器微架构,用于模拟处理器在执行目标应用程序时的各种状态,包括执行结果,程序流以及CSR。如果当前设计的处理器在执行指定程序时,这三个指标与标准的仿真程序所呈现的结果不一致,则认为处理器设计存在问题,需要修正。对于RISCV处理器设计来讲,最常见的仿真工具是Spike。在github上有相应资源。关于Spike及其相关的工具链,大家可以自行查阅其他资料。本文的第一部分将着重介绍如何安装Spike仿真工具。

本文的第二部分将介绍一个常见的嵌入式测试应用程序Dhrystone(江湖戏称“干石头”,当然与之对应的还有“湿石头”,大家可以自行了解)。Dhrystone是于1984年由Reinhold P. Weicker设计的一套综合的基准程序,该程序用来测试处理器的整数计算性能。该程序用C语言编写,依赖编译器的编译设置。Dhrystone的计量单位为每秒计算多少次Dhrystone,或者称为Dhrystone MIPS(百万条指令每秒),此处有一个其他处理器跑分结果。本文选用该测试程序作为应用程序演示示例,并不能输出完整的处理器性能数据。不过不排除在后期对处理器完善之后实现该目标。

安装Spike工具链

以下涉及到的安装步骤都源自两个工具链的README文件(所以README是个好东西),经作者实践后所总结。

安装riscv-fesvr
  • 下载riscv-fesvr

    git clone --recursive https://github.com/riscv/riscv-tools.git
    
  • 设置RISCV环境变量

    RISCV=${HOME}/Software/rv_linux_bare_19-10-17-11-10/bin #riscv工具链的路径
    
  • 安装可能会有用的工具

    yum install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev libusb-1.0-0-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev device-tree-compiler pkg-config libexpat-dev
    #注意:这些工具并不要求都安装成功,视后续需求。此处为保险措施
    
  • 创建build文件夹

    在riscv-fesvr文件夹下创建新的build文件夹,用于生成编译

    mkdir build
    cd build
    
  • 配置并生成代码

     ../configure --prefix=$RISCV
    
  • 安装

make install

此时会看到大片的编译过程,如果没有报错,则安装成功,可以进入下一步,否则就要排错并重新安装。riscv-fesvr工具是安装spike所必需的工具。

安装Spike
  • 下载riscv-isa-sim

    git clone --recursive https://github.com/riscv/riscv-tools.git
    
  • 创建build文件夹

    在riscv-isa-sim文件夹下创建新的build文件夹,用于生成编译

    mkdir build
    cd build
    
  • 配置并生成代码

     ../configure --prefix=$RISCV --with-fesvr=$RISCV
    
  • 安装

    make install
    
  • 设置环境变量

    将生成的Spike工具添加到环境变量中,后续方便使用

    export spike='your_spike_path'
    

    如果没有报错,则安装成功,否则就要排错并重新安装。

编译Dhrystone

Dhrystone含有部分内建函数,需要与编译器匹配。为保证主线任务,此处直接采用开源蜂鸟版本的Dhrystone版本。将下载到的工程文件放到xf100/verify/riscv-tools/riscv-tests/benchmarks/路径下备用。并修改benchmarks/Makefile脚本文件:

  • 修改RISCV_PREFIX,使其指向正确的riscv-gcc工具地址。
  • 修改RISCV_GCC_OPTS,将-march=rv32imafdc改为-march=rv32im,将-mabi=ilp32f改为-mabi=ilp32
    • 改成这样的原因,是目前的xf100处理器,还不支持某些特性,例如原子指令(A),浮点指令(F/D)以及精简指令(C),因此需要告诉编译器,不要产生相关类型的指令。

完成上述修改后,直接在benchmarks/路径下运行make指令,即可看到编译后的benchmark代码。

Dhrystone的spike仿真

在任意终端界面下,运行spike即可看到与之相关的参数介绍。运行以下命令来进行Dhrystone的软仿真。

spike --isa=RV32IM -l dhrystone.riscv 

该命令的含义是:用spike工具,在指定指令集下运行dhrystone程序,并将运行的pc流打印出来。运行结果如下图:

在这里插入图片描述

从上图可以看出当一个功能正常的处理器在执行当前的程序时其PC的值,如果某个处理器在同样条件下运行同一套程序,但是有不同的PC值,这表明该处理器无法可信的执行任何一个程序,即当前设计的处理器功能有问题,需要进一步修改。如果将该仿真工具和UVM等验证平台结合起来,实时监测处理器运行时的各个状态信息,就是处理器验证工作的核心。

总结

从第一篇文章到现在,我们终于介绍完一个极简的处理器的设计过程。虽然它还不完善,没有什么实用性,但是通过此例,我们还是涉及到了以下几个关键部分:

  • 极简的处理器,还是包含了取指(IFU),译码(DEC),执行(EXU),访存(LSU)以及写回(WB)五个部分,麻雀虽小,五脏俱全。
  • 处理器不涉及流水线的设计,但这并不妨碍它能正常执行若干条指令。实际上,余下的指令都是可以实现的,只是性能和时序会受到诸多限制,但是功能一定是完备的。这也说明一点,流水线在处理器设计中并不是必需的。
  • 处理器虽然没有复杂的分支跳转预测与数据反馈机制,但是简单的流水线冲刷机制还是有的,并且依旧满足设计需求。
  • 截至目前有一个相对完整的处理器验证环境,这是以后复杂处理器设计的基础工作。

的。这也说明一点,流水线在处理器设计中并不是必需的。

  • 处理器虽然没有复杂的分支跳转预测与数据反馈机制,但是简单的流水线冲刷机制还是有的,并且依旧满足设计需求。
  • 截至目前有一个相对完整的处理器验证环境,这是以后复杂处理器设计的基础工作。

有了上述的基本框架,要设计一个能完整执行上述Dhrystone应用程序的处理器只是时间问题。后续文章将重点介绍余下工作中的难点部分,敬请期待。

同系列文章首发于微信公众号:ICLiker,愿逢有缘人

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值