建房子,先打地基
在开始动手写第一行代码之前,我想在此再详细介绍一下需要准备的一些材料。这些前期准备越充分,后面的工作就会相对越顺畅。当然这一部分也可以快速略过。如果你还不放心,可以跟着一起看。
材料准备
-
操作系统
- 这个不限,Linux或者Windows都可以。此处选用的Ubuntu 16.04,配合VMWare 15 pro使用。
-
编译仿真软件
- 这个是开工的基础,随个人喜好选择,Windows下有Modelsim可选,或者FPGA开发软件也可以满足要求。本人比较偏向于Linux,在Linux下可选用的软件比较多,这个需要大家自己掌握,网上资料还是蛮多的。
-
蜂鸟E200
- 这个准备纯粹是为了**使用其开发环境。**我们当然可以从头开始写makefile,但是对于许多初学者来说,容易在支线上消耗大量的精力,得不偿失。站在前人的基础上,关注最重要的部分,不失为一个明智的选择。鉴于github时常出现访问非常卡的情况,我将蜂鸟开源的代码传到了码云上,在这里
-
gcc-riscv工具链
-
git bash工具
-
虽说个人开发,本地保存基本可以满足需求。但是作为专业的版本管理工具,建议大家还是学习一下。这个入门比价简单,官方有中文版的学习手册,常用命令大概半天学习即可满足要求。当然,如果你觉得不需要,也可以不看。这个完全不影响开发进度。
另外,svn也是个类似的工具,如果你更习惯svn,也是完全没问题的。
-
-
没有了😃
环境准备
从这一刻开始,我们将正式进入riscv的世界。不过就像高楼大厦一样,越是基础的部分越关键,因此虽说我们已经迈入了riscv的世界大门,但是首先要做的,还是搭建自己的环境。不过好在很大一部分工作蜂鸟的作者已经给我们做好了。我们只需要借用过来就可以。**这一部分大家还是需要注意,否则一不小心就会出现各种乱七八糟的错误。**首先介绍一下本项目的工程目录结构,如下所示:
- xf100
|-- design // 设计相关的文件
|--- core // 核心相关的设计文件
|---- ifu // IFU模块设计文件
|---- exu // EXU模块设计文件
|---- lsu // LSU模块设计文件
|---- top // 顶层核心模块设计文件
|--- misc // 周边必须设备,例如本地存储器
|-- verify // 验证相关文件
|--- prebuilt_tools
|---- prefix // 编译链接工具
|--- riscv-tools // 标准测试样例
|--- tb // testbench
|--- vsim // 测试脚本
-
gcc-riscv工具链
-
原始路径随意(避免出现中文字符),但是需要用
ln
命令链接到./xf100/verify/prebuilt_tools/prefix/bin
下,命令如下cd prefix ln -s real_path_of_your_gcc_riscv_tools/bin .
如果执行成功,在
prefix
下执行ls -l
命令会看到详细的链接关系。如果链接关系显示为红色,则表示链接失效,需要重新链接。
-
-
官方测试样例
- 官方测试样例用于测试基本的riscv功能,是一些汇编语言编写的测试代码。这里直接用蜂鸟的测试样例,将
e200/riscv-tools
文件里的内容拷贝到同名riscv-tools
的路径下。
- 官方测试样例用于测试基本的riscv功能,是一些汇编语言编写的测试代码。这里直接用蜂鸟的测试样例,将
-
源代码文件结构
- 源码文件的话目前按模块分了四个,对应各个不同的大块。后文再详细介绍这些。
-
测试脚本
- 测试脚本主要包含测试平台
tb
和脚本vsim/makefile
之类的。其中vsim
是将e200/vsim/bin
和e200/vsim/Makefile
拷贝过来的。后期会修改这些文件。
- 测试脚本主要包含测试平台
第一行代码
有了上面的准备,就可以真正开始第一行代码的编写了。不过工欲善其事,必先利其器,最先开始的,往往是一些边边角角的工作。那么我们的第一行代码,动在tb/tb_top.v
文件里。
//
// tb_top.v
// designer: ICLiker
//
`timescale 1ns/100ps
module tb_top;
reg sys_clk;
reg rst_n;
initial begin
sys_clk = 1'b0;
while (1) begin
#10 sys_clk = ~sys_clk;
end
end
initial begin
rst_n = 1'b0;
while(1) begin
#2500 rst_n = 1'b1;
end
end
//
// this will be our main task. but not now.
//
xf100_soc u_xf100_soc(
.sysclk(sys_clk),
.rst_n(rst_n)
);
// here we can add some system function such as $finish(),
// for avoid of long waiting.
endmodule
这个testbench目前就实现两个功能:
-
产生全局时钟 sys_clk:注意由于xf100是一个入门级的核,为简化设计,所有模块都在同一个时钟域中,也就是说,这完全是一个同步时序逻辑,没有跨时钟域的逻辑。
-
产生全局复位rst_n:全局复位,模拟CPU核的上电复位情况。同样为了简化设计,所有模块共用一个复位信号。
惊喜,我们已经看到soc出现了,没错,后续我们会慢慢实现它。
运行起来
tb_top
已经是一个可以编译仿真的模块了,只不过到目前为止没有任何其他模块与之产生联系。它就是一个台子,正式的演员还在幕后准备,不过我们已经能捕捉到那么一丝信息了。在深入到xf100_soc
内部之前,我们还有两个任务还没完成,第一个就是让这个tb在我们自己的环境下运行起来。按以下步骤进行
-
进入
vsim
目录下,修改Makefile文件。在Makefile文件的install部分,改成如下install: mkdir -p ${SIM_DIR}/install/tb cp ${SIM_DIR}/../tb/tb_top.v ${SIM_DIR}/install/tb/ -rf
这个命令的作用是将
./xf100/verify/tb/tb_top.v
复制到指定路径下,用于后续编译。注意确保tb_top.v
文件的路径正确。修改完之后就可以在
vsim
下运行make install
。 -
编译工程
- 此处不用修改代码,直接运行
make compile
。
- 此处不用修改代码,直接运行
-
运行
- 此处不用修改代码,直接运行
make run_test
。
- 此处不用修改代码,直接运行
-
查看波形
- 此处不用修改代码,直接运行
make wave
。
- 此处不用修改代码,直接运行
期望波形是一个跳变的sys_clk信号和一个上跳变rst_n。如果成功,那么恭喜你,可以进入下一节了。
同系列文章首发于微信公众号:ICLiker,愿逢有缘人