前言

P4 开始,我们就告别 logisim,进入 verilog 的领域了。

P4 要做的事情很简单,使用 verilog 实现单周期 CPUP4 的任务实际上就是要把 P3CPU 翻译到 verilog 语言。

根据不同的实现细节,在 P4 会需要数百行的码量。P4 的任务相对不难。在编写代码的时候要有良好的代码风格,遵循命名规范。

CPU 设计

在设计上可以完全照搬 P3 中用 logisim 实现的 CPU。另外建议进行模块化设计。P3 的模块 P4 里最好都继承(或改编)过来,P3 中没有综合成模块的地方视情况也可以综合为模块。

命名规范

verilog 中遵循一套自己的命名规范是很重要的。无论是驼峰法还是下划线法还是其他的规范,必须在整个代码中遵循同一套命名规范才能利于自己写代码。许多同学在大一的时候没有特意培养自己的代码风格。我的建议是可以在计组实验里开始初步培养代码风格,而不是等到下学期的 OO

此外,能够让代码更美观的办法比如对齐等。举个例子:

1
2
3
assign RegWrite = Add | Sub | And | Or  | Sll |
Srl | Lw | Lui | Ori | Jal |
Andi| 1'b0;

如果将大量堆到一行里或者行之间不对齐都会导致代码的可读性降低。因此,培养良好的代码风格,从 P4 开始!

初始化

在有时序功能模块中记得将寄存器初始化。GRF 模块可以直接申请一个寄存器堆,在初始化的时候使用 for 循环初始化。要特别注意 GRF0 号寄存器的值始终为1。

另外特殊的 IM 模块的初始化要使用 $readmemh()

信号的产生

关于 Controller 中信号的产生,可以使用宏定义的方式,或使用 wire 定义的方式。我个人采用了 wire 生成信号,距离如下:

1
2
3
wire Ori = op == 6'b001101 ? 1'b1 : 1'b0;
wire Lw = op == 6'b100011 ? 1'b1 : 1'b0;
wire Sw = op == 6'b101011 ? 1'b1 : 1'b0;

如此生成对应指令的信号。在使用的时候相当于直接将线接到对应的位置上。

上机

P4 的上机难度和 P3 相当,也不是很困难。

小提示:要提前留好给课上用的接口。这样会方便于通过课上。

结语

单周期 CPU 的绝大多数难点重点工作在 P3 中其实都已经设计完了。在 P4 中你所需要做的只有耐心的翻译代码。

话虽如此,P4 必须要认真搭建,P4 的单周期 CPU 是接下来几个 P 的起点,也是熟练 verilog 语法的机会。