一个完整的 cocotb 验证 阶乘计算模块(factorial)
的例子,涵盖:
- Verilog RTL 设计(组合/时序可选)
- cocotb Python 验证平台(含随机激励、断言、日志)
- 仿真运行说明(使用
iverilog + gtkwave
)
1. Verilog RTL:阶乘计算器(同步启动、串行计算)
// factorial.v
module factorial (
input clk,
input rst_n,
input start,
input [3:0] n, // 最大支持 15!(4位)
output reg done,
output reg [31:0] result
);
reg [3:0] i;
reg [31:0] acc;
reg busy;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
acc <= 1;
i <= 0;
busy <= 0;
done <= 0;
result <= 0;
end else begin
if (start && !busy) begin
acc <= 1;
i <= n;
busy <= 1;
done <= 0;
end else if (busy) begin
if (i > 1) begin
acc <= acc * i;
i <= i - 1;
end else begin
result <= acc;
busy <= 0;
done <= 1;
end
end else begin
done <= 0;
end
end
end
endmodule
2. cocotb 测试代码:测试随机 0~12 的阶乘
# test_factorial.py
import cocotb
from cocotb.triggers import RisingEdge, Timer
from cocotb.clock import Clock
import random
import math
@cocotb.test()
async def test_factorial(dut):
"""随机测试多组阶乘计算"""
# 创建时钟 10ns 周期
cocotb.start_soon(Clock(dut.clk, 10, units="ns").start())
# 初始化
dut.rst_n.value = 0
dut.start.value = 0
dut.n.value = 0
await RisingEdge(dut.clk)
dut.rst_n.value = 1
await RisingEdge(dut.clk)
for trial in range(10):
x = random.randint(0, 12)
expected = math.factorial(x)
# 启动计算
dut.n.value = x
dut.start.value = 1
await RisingEdge(dut.clk)
dut.start.value = 0
# 等待 done
for _ in range(50):
await RisingEdge(dut.clk)
if dut.done.value:
break
else:
assert False, f"Timeout: DUT failed to complete for n={x}"
got = dut.result.value.integer
assert got == expected, f"Failed: {x}! = {got}, expected {expected}"
dut._log.info(f"PASS: {x}! = {got}")
3. 仿真运行说明(以 Icarus Verilog + cocotb
为例)
文件结构
project/
├── factorial.v
├── test_factorial.py
├── Makefile
Makefile 示例(适配 Icarus)
TOPLEVEL_LANG = verilog
VERILOG_SOURCES = $(PWD)/factorial.v
TOPLEVEL = factorial
MODULE = test_factorial
SIM = icarus
include $(shell cocotb-config --makefiles)/Makefile.sim
4. 运行与结果
make
输出类似:
[INFO] cocotb.regression Test Passed: test_factorial
PASS: 5! = 120
PASS: 0! = 1
PASS: 7! = 5040
...
5. 优点总结(相比纯 Verilog TB)
项目 | cocotb 测试优势 |
---|---|
语言友好 | 使用 Python 写用例、随机测试、断言都非常简单 |
数学函数丰富 | 可直接调用 math.factorial 做黄金模型 |
日志与报错 | assert + dut._log.info 提供直观日志 |
脚本化测试 | 易于与 GitLab CI / pytest 等整合 |
如需扩展:
- 加入 边界值测试(如 n = 12、15)
- 测试 非法输入行为(如 n > 15)
- 加入 波形支持:
vcd
输出可通过$dumpfile
查看