编程随笔(三)

Verilog 是一门非常宽松的语言。但这并不是件好事。

有时我会在写 Verilog 的时候犯一些语法错误,我以为编译器会报警告,但是并没有。于是我就要花大力气去排查错误,最后为自己的粗心大意搭上好多时间。我觉得,如果编译器为此而报错,确实不太合适,但好歹报个警告吧?可是 Verilog 是一门非常宽松的语言,于是编译器就会偷偷地做隐式类型转换。实在是烦死了!

在我写 P5 的时候,有一些模块间的接线忘记定义了。Verilog 没有报错误或警告,而是直接把它们当作了 1 位的 wire。不过幸运的是,这其中有些变量应该是多位的,在连接时产生了位宽不匹配的警告,这才使我注意到这个失误。

Verilog 自动生成变量的行为是可以关闭的,使用预处理指令 `default_nettype none 即可禁用其下方的自动生成。但是,某些依赖自动生成的地方也会受到影响(比如 inputoutput)。此时我们需要限定禁用自动生成的范围。以下是一个示例:

1
2
3
4
5
6
7
8
9
10
module Example (
input ...,
output ...
);

`default_nettype none
...
`default_nettype wire

endmodule

转眼到了 P6。我从周六晚上开始写 P6,一直写到凌晨两点;第二天起床接着写,一直写到快要吃晚饭才写完。当时测试样例过了,但是弱测没过。眼看着时间快不够了,我三两下吃完了晚饭,然后就蹬着单车直接去找助教了。(其实助教推荐的做法是自己构造测试数据,然后通过官方的 Analyzer 来评判测试数据的强度,从而不断改进测试数据,最终找出 CPU 中的 bug。)

助教帮我从八点 de 到九点,de 出了两个特别低级的错误。一是我将转发信号常量(常量写在 constants.v 里)从两位扩展到了三位,但是相应的接口都还是两位。于是在作比较的时候发生了隐式转换,最高位被裁掉了。二是我的 DM 有一个接口没有接线,当时预留了接口却没有准备好有关的信号,等到准备好信号之后却把接线的事情忘了。出人意料的是,仿真时 ISE 没有报一个警告。

当助教帮我 de 完 bug 的时候,教室里就剩一两个人了,助教们要收工了。看助教忙到这么晚,我感觉有些对不起助教。于是我问助教如何才能让 ISE 的语法检查更严一些。助教告诉我,可以试试综合。于是我试着点了一下综合,结果五彩斑斓的调试信息夹杂着花式警告顿时喷涌而出。但是呢,综合的缺点是耗时比较长,所以助教建议在 P8 以前不要综合。

我去隔壁宿舍请教了一位大佬,大佬说他知道的唯一的办法也是综合 orz


周六下午,我的室友发微信问我有关转发的事情。原来他正在重写 P5 课下。当时正巧我也在重构 P5,于是就和他讨论了起来。

所以他为什么要重写呢?其实他在周一的时候已经重构过一遍了,但是对代码质量仍然不满意,于是他拿着之前的设计文档,花了一个下午加晚上,一共五六个小时,重写了一遍。但是重写以后通不过测试了,于是他又开始 debug。

我对他说,我非常不建议他重写,因为如果在重写时遇到了 bug 就要花好多时间去 de,如果 de 不出来只能周日晚上去求助助教。如果万不得已要重写的话,最好进行“忒修斯之船”式的重写,一次只重写一小部分,然后过一遍弱测中测强测。

打包、弱测、中测、强测的过程十分麻烦,于是我整了一个小脚本,挺好用的。贴在下面:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
# 部分代码由 ChatGPT 生成。

if [ -f "./P5.zip" ]
then
echo "错误:文件 'P5.zip' 已存在。"
else
zip -j ./P5.zip ./P5_L0_weak_2023/src/*.v
co-submit 1124-1245 ./P5.zip
co-submit 1124-1006 ./P5.zip
co-submit 1124-1204 ./P5.zip
fi