【verilog开源鉴赏】An award-winning bit-serial RISC-V core —— SERV
项目概述
SERV是一个基于RISC-V指令集的串行CPU实现,一般来说追求简单和入门级的cpu核必然是指令串行结构,这样就避免了很多数据依赖、分支预期等难点。项目verilog含量高达77.4%,在github收获了1.3stars。
我们直奔rtl,看看代码可读性怎么样。文件层次与命名非常的清晰:
基本上一眼就能看出每个module是干嘛的,或者打开文件扫一扫也能分析出来。代码的易读性很高,信号命名非常清楚,缩进等细节也很用心:
更加可贵的是,代码的注释非常全面且细致,关键的地方都有清晰的注释(惭愧的低下了头):
//PC-relative operations
//True for jal, b* auipc, ebreak
//False for jalr, lui
wire co_ctrl_pc_rel = (opcode[2:0] == 3'b000) |
(opcode[1:0] == 2'b11) |
(opcode[4] & opcode[2]) & op20|
(opcode[4:3] == 2'b00);
//Write to RD
//True for OP-IMM, AUIPC, OP, LUI, SYSTEM, JALR, JAL, LOAD
//False for STORE, BRANCH, MISC-MEM
wire co_rd_op = (opcode[2] |
(!opcode[2] & opcode[4] & opcode[0]) |
(!opcode[2] & !opcode[3] & !opcode[0]));
/*
Bits 26, 22, 21 and 20 are enough to uniquely identify the eight supported CSR regs
mtvec, mscratch, mepc and mtval are stored externally (normally in the RF) and are
treated differently from mstatus, mie and mcause which are stored in serv_csr.
The former get a 2-bit address as seen below while the latter get a
one-hot enable signal each.
Hex|2 222|Reg |csr
adr|6 210|name |addr
---|-----|--------|----
300|0_000|mstatus | xx
304|0_100|mie | xx
305|0_101|mtvec | 01
340|1_000|mscratch| 00
341|1_001|mepc | 10
342|1_010|mcause | xx
343|1_011|mtval | 11
*/
只要对处理器的结构与要点有一定的了解,阅读起来困难都不是非常的大,推荐!
项目介绍
以下是项目README内容的中文翻译:
SERV是一款获奖的位串行RISC-V核心
事实上,获奖的SERV是世界最小的RISC-V CPU。当你需要一些计算能力并且硅片资源非常宝贵时,它是完美的伴侣。
它到底有多小呢?将SERV的最新版本以最简形式综合,对于一些流行的FPGA架构和典型的CMOS工艺,得到以下结果:
Lattice iCE40 | Intel Cyclone 10LP | AMD Artix-7 | CMOS |
---|---|---|---|
198 LUT | 239 LUT | 125 LUT | 2.1kGE |
164 FF | 164 FF | 164 FF |
如果你想更多地了解SERV,位串行CPU是什么以及它的用途,我建议从观看精彩的SERV短片开始:
所有SERV视频和更多内容也可以在这里找到。
除了是世界上最小的RISC-V CPU外,SERV还旨在成为文档最齐全的RISC-V CPU。为此,有一份官方的SERV用户手册,其中包含精确到门级、周期准确的时序图和深入的工作原理描述。
使用SERV的系统
SERV可以轻松集成到任何设计中,但如果你想快速尝试它,这里有一份已经使用SERV的系统列表:
Servant 是SERV的参考平台。这是一个非常基础的SoC,只包含运行Zephyr RTOS所需的内容。Servant旨在用于FPGA,并已移植到大约20种不同的FPGA板。它也用于运行RISC-V回归测试套件。
CoreScore 是一个为FPGA及其综合/P&R工具颁发的奖项基准。它测试了可以将多少SERV核心放入特定FPGA中。
Observer 是一个可配置和软件可编程的异构传感器聚合平台。
Subservient 是一个小型技术独立的基于SERV的SoC,旨在与单个端口SRAM一起用于ASIC实现。
Litex 是一个基于Python的框架,用于创建FPGA SoC。SERV是支持的30多个核心之一。使用Litex生成的SoC已用于在SERV上运行DooM。
开始使用
:o: 创建一个根目录,用来保存项目的所有不同部分。我们将从此以后称此目录为 $WORKSPACE
。
所有以下命令都将从这个目录运行,除非另有说明。
-
安装FuseSoC
$ pip install fusesoc
-
添加FuseSoC标准库
$ fusesoc library add fusesoc_cores https://github.com/fusesoc/fusesoc-cores
-
FuseSoC标准库已经包含了SERV的一个版本,但如果我们想对SERV进行更改,运行捆绑的示例或使用Zephyr支持,最好将SERV作为单独的库添加到工作空间中
$ fusesoc library add serv https://github.com/olofk/serv
:warning: SERV仓库现在将在
$WORKSPACE/fusesoc_libraries/serv
中可用。我们将从此以后称该目录为$SERV
。 -
安装最新版本的Verilator
-
(可选)为了支持RISC-V M扩展扩展,乘法和除法单元(MDU)可以作为单独的库包含在SERV中。
$ fusesoc library add mdu https://github.com/zeeshanrafique23/mdu
MDU将在
$WORKSPACE/fusesoc_libraries/mdu
中可用
我们现在准备开始使用SERV进行第一次练习。如果上述所有步骤都正确完成,我们可以使用Verilator作为linter来检查SERV源代码。
$ fusesoc run --target=lint serv
如果一切顺利,输出应该如下所示:
INFO: Preparing ::serv:1.2.1
INFO: Setting up project
INFO: Building simulation model
INFO: Running
完成上述所有步骤后,从 $WORKSPACE
的目录结构应该如下所示:
。
$WORKSPACE
│
├── build
│ └── ...
└── fusesoc_libraries
├── fusesoc_cores
│ └── ...
├── mdu
│ └── ...
└── serv
└── ...
运行预构建的测试软件
使用verilator构建并运行单线程的zephyr hello world示例(应该用Ctrl-C停止):
fusesoc run --target=verilator_tb servant --uart_baudrate=57600 --firmware=$SERV/sw/zephyr_hello.hex
...或者...多线程版本
fusesoc run --target=verilator_tb servant --uart_baudrate=57600 --firmware=$SERV/sw/zephyr_hello_mt.hex --memsize=16384
两者都应该以以下输出结束
***** Booting Zephyr OS zephyr-v1.14.1-4-gc7c2d62513fe *****
Hello World! service
对于更高级的示例,我们还可以运行Dining philosophers演示
fusesoc run --target=verilator_tb servant --uart_baudrate=57600 --firmware=$SERV/sw/zephyr_phil.hex --memsize=32768
...或者...同步示例
fusesoc run --target=verilator_tb servant --uart_baudrate=57600 --firmware=$SERV/sw/zephyr_sync.hex --memsize=16384
...或者...blinky示例(注意blinky测试不应定义 uart_baudrate
)
fusesoc run --target=verilator_tb servant --firmware=$SERV/sw/blinky.hex --memsize=16384
如果安装了工具链,可以通过编译汇编程序并使用在$SERV/sw
中找到的makehex.py转换为bin,然后转换为hex来测试其他应用程序。
:bulb:通过传递 --compressed=1
参数可以启用RISC-V压缩扩展。
验证
SERV使用RISC-V合规性测试来验证基础ISA(RV32I)和实现的扩展(M,C,Zicsr)。使用RISCOF框架运行合规性测试的说明在verif目录中给出。
其他目标
上述目标在servant SoC上运行,但也为CPU本身定义了一些目标。可以通过运行Verilator的lint模式来检查设计问题
fusesoc run --target=lint serv
还可以仅针对不同的目标进行综合,以检查资源使用情况等。对于iCE40设备,运行
fusesoc run --tool=icestorm serv --pnr=none
...或者使用vivado为Xilinx目标进行综合,运行
fusesoc run --tool=vivado serv --pnr =none
这将为默认的Vivado部件进行综合。要针对特定设备进行综合,运行例如
fusesoc run --tool=vivado serv --pnr=none --part=xc7a100tcsg324-1
Zephyr支持
SERV,或者更确切地说是Servant SoC,可以运行Zephyr RTOS。Servant特定的驱动程序和BSP位于SERV仓库的zephyr子目录中。要在Servant上使用Zephyr,必须设置一个项目目录结构,允许Zephyr将Servant特定文件作为模块加载。
首先,必须安装Zephyr SDK和“west”构建工具。Zephyr入门指南更详细地描述了这些步骤。
假设SERV已按照先决条件安装在 $WORKSPACE/fusesoc_libraries/serv
中,运行以下命令使工作空间也作为Zephyr工作空间工作。
west init
将SERV仓库指定为清单仓库,这意味着当Zephyr查找模块时,它将是主要入口点。
west config manifest.path $SERV
获取所有Zephyr子模块的正确版本
west update
现在应该可以在工作空间内为Servant SoC构建Zephyr应用程序。这可以通过构建Zephyr Hello world样本应用程序进行测试
cd zephyr/samples/hello_world
west build -b service
构建成功后,Zephyr将在 build/zephyr/zephyr.{elf,bin}
中创建应用程序的elf和bin文件。bin文件可以转换为Verilog hex文件,然后可以预加载到FPGA片上存储器并在目标板上运行,或者在运行模拟时加载到模拟RAM模型中。
要将新构建的hello world示例转换为Verilog hex文件,运行
python3 $SERV/sw/makehex.py zephyr/samples/hello_world/build/zephyr/zephyr.bin 4096 > hello.hex
4096是要写入的32位字的数量,必须至少是应用程序二进制文件的大小。hello.hex
是生成的hex文件。现在可以按照运行预构建的测试软件中描述的方式进行模拟,例如
fusesoc run --target=verilator_tb servant --uart_baudrate=57600 --firmware=/path/to/hello.hex
或者创建一个FPGA映像,将应用程序预加载到片上RAM中,例如针对Nexys A7板,运行
fusesoc run --target=nexys_a7 servant --memfile=/path/to/hello.hex
须知
不要在午夜后给serv提供任何非法指令。许多逻辑表达式是使用过时的方法在纸上使用Karnaugh图手动优化的,并且毫不羞耻地利用了一些操作码不应该出现的事实。由于serv是针对4输入LUT FPGA编写的,并且操作码是5位,这可以在解码器中节省相当多的资源。
总线接口有点类似于Wishbone,但移除了大多数信号。不过有一个重要的区别。除非serv通过提高cyc信号明确请求某物,否则不要在指令或数据总线上发送确认。否则serv会变得非常困惑。
不要随意更改运行Zephyr时的时钟频率。或者好吧,我想这也可以,但由于UART是bitbanged的,这也将改变波特率。截至撰写本文时,当CPU为32 MHz时,UART运行在115200波特率。驱动程序中有两条NOP来稍微减慢它的速度,所以如果那些被移除,我认为它可以在24MHz时钟上实现115200波特率...以防有人想尝试。
请注意,由于原文中包含了一些技术性的内容和特定的命令,翻译尽量保持了原文的准确性和专业性。如果需要进一步的解释或有特定的术语需要澄清,请告知。
项目地址
转载自:https://juejin.cn/post/7377208894550622217