joe 发表于 2021-10-16 11:50:40

Chisel后篇-Riscv-Rocketchip使用介绍

参考博文:https://blog.csdn.net/a_weiming/article/details/84594781rocket-chip generator介绍   rocket-chip generator的一级目录结构:    bootrom : 在BootROM的bootloader第一阶段所使用的代码
    csrc Verilator: 仿真用的C代码
    emulator Verilator :用来编译和跑仿真的工作目录
    project Scala: 构建工具sbt用来构建Scala的工作目录
    regression: 定义的持续的整合和一套nightly regression
    scripts: 用来分析仿真的输出或者处理代码文件的内容
    vsim VCS: 用来编译和跑仿真的工作目录
    vsrc Verilog: 代码,包含接口、测试框架和Verilog过程接口VPI
    chisel3 :包含Chisel自定义的各种类和规则,用来生成RTL
    firrtl: 存放Chisel编译器处理代码而生成的一种中间表示,由中间表示能生成Verilog代码或C++代码
    hardfloat: 用chisel写成的浮点单元
    riscv-tools: 支持RISC-V的一套软件,与生成RTL有关
    torture: 用来生成压力测试所需的一些随机指令
  src/main/scala: 构筑rocket-chip的代码:    rocket-chip generator电路构筑代码的目录结构:amba amba: 协议的实现代码,包括AXI4,AHB-lite,APB    config: 提供能配置Generator的Scala的接口
    coreplex: 包含Rocket核、系统总线、coherence agents、debug设备、中断处理、面向外部的外设、时钟同步处理和TileLink到外设总线转换
    devices: 一些外设,包括debug模块和各种挂在TileLink的从设备
    diplomacy: 用来扩展Chisel,通过允许对硬件进行两个阶段的阐述,可以让参数在模块之间协调传递
    groundtest: 生成可综合的硬件测试平台,通过发出随机的访问存储器指令流,进行对核外的存储器系统进行压力测试
    jtag: 用来生成JTAG总线接口
    regmapper: 用来生成带有能访问内存映射寄存器的标准接口的从设备
    rocket: 用来生成顺序核Rocket、L1指令cache和L1数据cache
    tile: 包含可以与Rocket核组成tile的组件,如FPU和RoCC协处理器
    tilelink: 用来生成TileLink总线(协议),包含一些适配器和转其他总线(协议)的转换器
    system Rocket Chip的顶层代码包,同时也是用作测试的硬件平台的顶层代码包
    unittest: 用作生成硬件测试平台来测试单独的一个个模块
    util: 提供一些能被其他代码包调用的通用的Scala和Chisel结构如何配置一个自定义的rocket-chip?这节的主要内容是教大家如何自由配置一个rocket-chip。以下是我对rocket-chip修改后实现的特殊功能(部分我会以例子的形式进行说明):
1、 将reset_vector信号引到顶层,可以根据该信号使rocket-chip从不同地址启动。
2、 在rocket-chip的顶层引出一套采用Tilelink的SRAM,这套SRAM按物理地址访问。
3、 修改各总线(mem/MMIO)的物理访问地址。
4、 将各总线(mem/MMIO)的AXI4协议改为AHB协议。
5、 将local interrupt的信号引到rocket-chip的顶层,使除了PLIC外,还能使用local interrupt。
6、 修改ROCC的功能,扩展custom0、custom1、custom2和custom3的功能。
7、 加入DCache enable的CSR寄存器,并实现相应功能,使DCache的功能变为可选。现在先对rocket-chip的Scala代码进行简单的介绍。https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030165858174-101971349.png 我决定以从顶到底的方式解释rocket-chip的Scala代码,此外我不会每个Scala文件都一一说明,某些测试的Scala文件我会跳过的。首先说明的是/rocket-chip/src/main/scala/system目录:https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030165941979-843208397.png Generator.scala & RocketTestSuite.scala 这两个文件是测试相关的,所以我不做说明。第一个看的Scala文件是:TestHarness.scala带//注释的就是解释。https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030170028276-554048017.png下图是 TestHarness.scala 生成的连接图。https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030170149724-321612186.png第二个看的Scala文件是:ExampleRocketSystem.scala
可以知道 TestHarness.scala 就是testbench,而 ExampleRocketSystem.scala 生成的才是我们关注的SOC, ExampleRocketSystem.scala 包括Core以外的其他外设&总线。https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030170222646-1082358549.png https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030170245270-383106481.png 第三个看的Scala文件是:Configs.scalaTestHarness.scala 就是testbench,而 ExampleRocketSystem.scala 就是SOC的层次,包括Core以外的其他外设&总线,Configs.scala 就是核心Core的配置。Configs.scala 的配置比较多,我挑几个来说明。https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030170323509-150274243.pngrocket-chip generator使用在src/main/scala/coreplex/Configs.scala的类都是构筑rocket-chip的“部件”。需要在src/main/scala/system/Configs.scala中将“部件”类和“底板”类BaseConfig组合起来,每一个都是一种配置方案。具体的方法就是利用“++”这个函数,写法参考该文件的其他类写法即可。
生成Verilog代码及测试用的入口用到的命令:cd emulator
make CONFIG=DefaultConfig其中CONFIG=后面接的是在src/main/scala/system/Configs.scala写好的类名。若编译没有错误,则会生成以下文件和文件夹:
http://www.pianshen.com/images/687/7aa8bac03b3572671a34f5c4634f2367.pnggenerated-src文件夹包括生成的Verilog文件和一些测试用的文件,verilator文件夹包含仿真工具verilator的源码和安装文件。emulator-freechips.rocketchip.system-DefaultConfig是可执行文件,是测试程序的入口。图中圈着的文件夹是测试进行的环境,.v文件就是生成的rocket-chip的Verilog代码。
http://www.pianshen.com/images/92/c51e2f023168b09b4e20486c507e21bc.pngrocket-chip generator仿真C或C++程序1. 使用risc-v工具链编译仿真写好的一个测试的C或C++程序如下:
http://www.pianshen.com/images/658/3bd16559dc4a96cb8345dcca78c87c2a.png使用命令编译测试程序:riscv64-unknown-elf-gcc helloworld.c -o helloworld然后将生成的helloworld可执行文件放到emulator工作目录,再在emulator工作目录下执行命令:./emulator-freechips.rocketchip.system-DefaultConfig pk helloworld等待几分钟(具体等待时间取决于程序的大小)后,终端输出“Hello World”2.利用rocket的方法如下(比之前的跑的更快,而且能看波形)在rocket-chip/riscv-tools/riscv-tests/benchmarks中新建测试程序的文件夹helloworld,并在其中写好一个测试程序helloworld:http://www.pianshen.com/images/188/3694db50e0375c8aa608fb80b9b7f1c4.png修改在rocket-chip/riscv-tools/riscv-tests/benchmarks中的Makefile,修改其中的bmarks变量,使其新值为新建的文件夹名字helloworld:http://www.pianshen.com/images/195/550fdf17df1f809e5231a0be1495e13b.png退出到rocket-chip/riscv-tools/riscv-tests/benchmarks执行命令make,得到.riscv可执行文件:http://www.pianshen.com/images/738/077486b2bd89f69b8d990e33272ec2b2.png将.riscv文件移到rocket-chip/emulator文件夹中:http://www.pianshen.com/images/454/73b981ab571dbd9d7cd14b4c69107f46.png执行命令:./emulator-freechips.rocketchip.system-DefaultConfig helloworld.riscv等待少于一分钟的时间,得到输出:http://www.pianshen.com/images/195/bae7cd9119c9c888f8734d36e0ea2723.png执行命令:./emulator-freechips.rocketchip.system-DefaultConfig +max-cycles=100000000 +verbose helloworld.riscv 2> helloworld.riscv.out得到指令执行过程信息:http://www.pianshen.com/images/504/6dd736981d6db7e2186bc81504f586c0.pnghttp://www.pianshen.com/images/123/44e5809fc9f25d883ef4bb5235ba9e4b.png执行命令:./emulator-freechips.rocketchip.system-DefaultConfig-debug +max-cycles=100000000 --vcd=helloworld.riscv.vcd helloworld.riscv得到.vcd波形文件:http://www.pianshen.com/images/763/fc4f65c2c0c661f7d8ba6eb60a4f0fc3.png双击打开即可看到波形:http://www.pianshen.com/images/724/a26f1c0d0ec5bc0a14483f3442bb54fc.png附录:Chisel3 & Scala & Rocket-chip verilog的生成  Scala是一门多范式的编程语言,一种类似java的编程语言,设计初衷是实现可伸缩的语言、并集成面向对象编程和函数式编程的各种特性。  Chisel(Constructing Hardware In a Scala Embedded Language)是一种嵌入在高阶编程语言 Scala 中用来构造硬件的语言。Chisel实际上只是一组特殊的用Scala 事先定义的类、对象 和使用惯例,所以写一份Chisel程序的时候,你实际上在写一份Scala程序。  Rocket Chip is an open-source Sysem-on-Chip design generator that emits synthesizable RTL. It leverages the Chisel hardware construction language to compose a library of sophisticated generators for cores, caches, and interconnects into an integrated SoC.  由上面描述,应该可以知道,Rocket Chip是一个开源的SOC生成器,可以根据自己的配置生成不同的SOC(RTL),而Rocket Chip是基于Chisel完成的,最后Chisel是在Scala中定义的特殊类和对象,因此修改Rocket Chip的源代码就是修改Scala代码,利用Chisel编译出的文件为*.fir,要将*.fir转换为verilog RTL还需要firrtl这个工具。  Rocket Chip整个项目的Scala编译都基于sbt的,而sbt是基于java的,因此要生成Rocket-chip RTL,要先安装java,sbt,chisel3和firrtl。注意Rocket-chip RTL的生成不会用到工具链,需要编译工具链时才需要设置环境变量。Rocket-chip verilog RTL生成步骤:
1、 克隆项目:$git clone https://github.com/ucb−bar/rocket−chip.git $cd rocket-chip
$ git submodule update --init
2、 安装java,下面是以Ubuntu为例子。sudo apt-get install default-jdk
3、 安装sbt,安装sbt过程中可能因为网速或链接的问题会出现下载失败的现象,多试几次就好:echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 642AC823
sudo apt-get update
sudo apt-get install sbt
4、 下载Rocket Chip项目的sbt依赖库,下载过程中可能因为网速或链接的问题会出现下载失败的现象,多试几次就好:$cd rocket−chip$ sbt
直到弹出这样的提示就证明成功了,然后输入exit退出:sbt:rocketchip>
5、 编译&安装chisel3:<span class="MathJax" id="MathJax-Element-3-Frame" tabindex="0" data-mathml="cdrocket−chip/chisel3" role="presentation" style="display: inline; line-height: normal; word-spacing: normal; overflow-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; position: relative;">cdrocket−chip/chisel3cdrocket−chip/chisel3 sbt
直到弹出这样的提示就证明成功了,然后输入exit退出:sbt:chisel3>
6、 编译&安装firrtl:$cd rocket−chip/firrtl$ sbt
直到弹出这样的提示就证明成功了,然后输入exit退出:sbt:firrtl>
7、 生成rocket-chip verilog RTL$cd rocket−chip/vsim$ make verilog CONFIG=DefaultSmallConfig
漫长等待后,RTL生成$cd rocket-chip/vsim/generated-src
这个目录下有很多刚生成的东西,下面再对这个目录生成的文件进行说明。生成文件的说明:
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式文件说明https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030173527059-928606055.pngRISC-V编译环境搭建1. JTAG调试器设置
将JTAG调试器连接PC,并断开主机连接将其连接到UBUNTU虚拟机,运行lsusb应该有以下这个设备:Bus 002 Device 010: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC设置udev rules,使JTAG调试器可以被plugdev group访问sudo gedit /etc/udev/rules.d/99-vmware-scsi-udev.rules在里面添加ATTR{idVendor}=="0403", ATTR{idProduct}=="6010", MODE="660", GROUP="plugdev"使用如下命令查看该USB设备是否属于plugdev groupls -l / /dev/ttyUSB12. 将用户名添加到plugdev group中
whoami
sudo usermod -a -G plugdev username
确认自己的用户名是否属于plugdev groupgroups将gnu-mcu-eclipse-openocd-0.10.0-8-20180724-1118-centos64.tgz放到~/根目录下,并解压   cd ~/   tar -xzvf gnu-mcu-eclipse-openocd-0.10.0-8-20180724-1118-centos64.tgz      cd ~/e200_opensource/sirv-e-sdk/   mkdir -p work/build/opencd/prefix   cd work/build/opencd/prefix/   ln -s ~/gnu-mcu-eclipse/openocd/0.10.0-8-20180724-1118/bin/ bin   cd ~/e200_opensource/sirv-e-sdk/   mkdir -p work/build/riscv-gnu-toolchain/risc32-unknown-elf/prefix/   cd work/build/riscv-gnu-toolchain/risc32-unknown-elf/prefix/   ln -s ~/gnu-mcu-eclipse/riscv-none-gcc/7.2.0-2-20180111-2230/bin/ bin3. 编译demo_gpio程序,命令如下:cd ~/e200_opensource/sirv-e-sdk/make software PROGRAM=demo_gpio BOARD=sirv-e203-arty如何建立自己的RISC-V编译环境?1.RISC-V编译环境框架
这是我RISC-V编译环境的架构:build case common toolchain
https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194125869-592566729.png2.各目录内容介绍
2.1 toolchain:工具链目录我不打算介绍,如果有不明白的,可以看这个博客:
rocket-chip工具链的编译与使用(https://blog.csdn.net/a_weiming/article/details/84801051)2.2 project:这个目录就是放你的项目代码的。每个项目建立一个目录。在这个例子中,我放的是test目录,test的源代码如下(修改于/riscv-tests/benchmarks/vvadd):https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194217001-60375070.png 2.3 common:这个目录比较重要,而且改动的地方比较多。2.3.1 encoding.h:这个目录不解释,就是RISC-V各重要CSR寄存器的定义。2.3.2 program.ld:这个文件是修改于/riscv-tests/benchmarks/common/test.ld。https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194324661-270781883.png2.3.3 program.S:这个文件改动比较大(修改于/riscv-tests/benchmarks/common/crt.S),这个文件改动需要注意以下几点:1)扩展名必须为大写的S,大写的S可以使gcc自动识别汇编程序中的C预处理命令,像#include、#define、#ifdef、 #endif等,也就是说,使用gcc进行编译,你可以在汇编程序中使用C的预处理命令。
2)因为我生成的rocket-chip是不使用浮点的,不使用虚拟内存,不使用ROCC的,所以很多内容我直接删改了,而且栈和异常入口都是根据我生成的rocket-chip来设定的,大家可以根据自己的情况进行修改。https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194346949-678090669.png https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194416061-117968058.png https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194439651-809220423.png https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194459240-27157186.png 2.4 bulid:这个目录最主要的是Makefile脚本,用于调用工具链编译project。我只贴部分代码,是生成elf的代码,生成bin、hex和dump的方法大家参考/riscv-tests/benchmarks/Makefile。部分代码:https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194519386-547182293.png
自强不息~
源帖来自:https://www.cnblogs.com/gujiangtaoFuture/articles/11766114.html

joe 发表于 2021-10-16 11:58:50

上面所缺图片补上:生成文件的说明:
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式文件说明https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030173527059-928606055.pngRISC-V编译环境搭建1. JTAG调试器设置
将JTAG调试器连接PC,并断开主机连接将其连接到UBUNTU虚拟机,运行lsusb应该有以下这个设备:Bus 002 Device 010: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC设置udev rules,使JTAG调试器可以被plugdev group访问sudo gedit /etc/udev/rules.d/99-vmware-scsi-udev.rules在里面添加ATTR{idVendor}=="0403", ATTR{idProduct}=="6010", MODE="660", GROUP="plugdev"使用如下命令查看该USB设备是否属于plugdev groupls -l / /dev/ttyUSB12. 将用户名添加到plugdev group中
whoami
sudo usermod -a -G plugdev username
确认自己的用户名是否属于plugdev groupgroups将gnu-mcu-eclipse-openocd-0.10.0-8-20180724-1118-centos64.tgz放到~/根目录下,并解压   cd ~/   tar -xzvf gnu-mcu-eclipse-openocd-0.10.0-8-20180724-1118-centos64.tgz      cd ~/e200_opensource/sirv-e-sdk/   mkdir -p work/build/opencd/prefix   cd work/build/opencd/prefix/   ln -s ~/gnu-mcu-eclipse/openocd/0.10.0-8-20180724-1118/bin/ bin   cd ~/e200_opensource/sirv-e-sdk/   mkdir -p work/build/riscv-gnu-toolchain/risc32-unknown-elf/prefix/   cd work/build/riscv-gnu-toolchain/risc32-unknown-elf/prefix/   ln -s ~/gnu-mcu-eclipse/riscv-none-gcc/7.2.0-2-20180111-2230/bin/ bin3. 编译demo_gpio程序,命令如下:cd ~/e200_opensource/sirv-e-sdk/make software PROGRAM=demo_gpio BOARD=sirv-e203-arty如何建立自己的RISC-V编译环境?1.RISC-V编译环境框架
这是我RISC-V编译环境的架构:build case common toolchain
https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194125869-592566729.png2.各目录内容介绍
2.1 toolchain:工具链目录我不打算介绍,如果有不明白的,可以看这个博客:
rocket-chip工具链的编译与使用(https://blog.csdn.net/a_weiming/article/details/84801051)2.2 project:这个目录就是放你的项目代码的。每个项目建立一个目录。在这个例子中,我放的是test目录,test的源代码如下(修改于/riscv-tests/benchmarks/vvadd):https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194217001-60375070.png 2.3 common:这个目录比较重要,而且改动的地方比较多。2.3.1 encoding.h:这个目录不解释,就是RISC-V各重要CSR寄存器的定义。2.3.2 program.ld:这个文件是修改于/riscv-tests/benchmarks/common/test.ld。https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194324661-270781883.png2.3.3 program.S:这个文件改动比较大(修改于/riscv-tests/benchmarks/common/crt.S),这个文件改动需要注意以下几点:1)扩展名必须为大写的S,大写的S可以使gcc自动识别汇编程序中的C预处理命令,像#include、#define、#ifdef、 #endif等,也就是说,使用gcc进行编译,你可以在汇编程序中使用C的预处理命令。
2)因为我生成的rocket-chip是不使用浮点的,不使用虚拟内存,不使用ROCC的,所以很多内容我直接删改了,而且栈和异常入口都是根据我生成的rocket-chip来设定的,大家可以根据自己的情况进行修改。https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194346949-678090669.png https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194416061-117968058.png https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194439651-809220423.png https://img2018.cnblogs.com/blog/1186963/201910/1186963-20191030194459240-27157186.png 2.4 bulid:这个目录最主要的是Makefile脚本,用于调用工具链编译project。我只贴部分代码,是生成elf的代码,生成bin、hex和dump的方法大家参考/riscv-tests/benchmarks/Makefile。部分代码:
自强不息~

页: [1]
查看完整版本: Chisel后篇-Riscv-Rocketchip使用介绍