众所周知,流水线CPU设计时GTKWave不能说不好用吧只能说是非常难用,所以我使用的是$display大法,直接输出所需信息。(用这种方法的似乎大有人在)
这里分享一些相关的代码片段和调试技巧。
RegFile
* RegFile.sv
1 | |
Memory操作
* Core.sv
1 | |
用于输出内存请求和响应的状态,方便调试内存访问问题。
UART 重定向
此外,我们的
Uart在被写入数据的时候会调用$display函数输出写入的值,起到调试的时候观看串口输出的效果。如果大家想要收集调试的输出,可以运行make kernel 2>log,然后所有的执行流会被保存到当前路径下的 log 文件中,而标准输出只会输出Uart被写入的值(即printk函数的输出),可以比较好地展示最后的效果。在验收时请以这种方式运行,以展示运行结果的正确性。
(p.s. 实际上是$write)
问题来了,我们的调试阶段也是需要用到 $display 输出的。为了不让这两种输出混起来,可以把Uart中的输出重定向到文件:
要修改的文件位于sys2-project/general/uart.sv
在约380行的位置处:
1 | |
具体要粘贴的内容:
1 | |
这样,Uart的输出就会被写入到output.txt文件中,而不是标准输出流里了。输出的这个文件位于src/project/build/verilate目录下。你也可以改成绝对地址。
使用.name()输出enum的名称
在Verilog/SystemVerilog中,enum类型的变量默认输出的是它们的整数值,而不是名称。为了在调试时更方便地查看enum变量的状态,可以使用SystemVerilog提供的.name()方法来输出enum的名称。
例如,对于
1 | |
在调试输出时,可以这样写:
1 | |
会更清楚一些。