如何在COCOTB中生成仅用于测试、不连接DUT的时钟
解决COCOTB中测试流程专用独立时钟的问题
你的代码报错核心原因有两个:
- 混淆了
Clock对象和可驱动的信号:Clock是辅助生成时钟的工具类,不是可赋值的信号变量,不能直接传给驱动函数使用。 - 错误访问
dut.sim_clk:你要的是测试专用的独立时钟,DUT中并没有这个端口,自然会因找不到信号而报错。
以下是两种可行的实现方案:
方案一:创建独立测试信号并驱动
直接在测试函数内定义一个独立的测试信号(无需关联DUT),编写时钟驱动逻辑后,监听该信号的上升沿执行测试操作:
import cocotb from cocotb.triggers import Timer, RisingEdge from cocotb.handle import SimHandleBase async def generate_test_clock(sim_clk, period_ms): """驱动测试专用的独立时钟""" while True: sim_clk.value = 0 await Timer(period_ms // 2, units="ms") sim_clk.value = 1 await Timer(period_ms // 2, units="ms") @cocotb.test() async def top(dut): # 创建独立测试信号,与DUT无关联 sim_clk = SimHandleBase(name="sim_test_clk") # 启动时钟驱动任务 cocotb.start_soon(generate_test_clock(sim_clk, 22)) # 监听测试时钟上升沿,执行测试逻辑 for _ in range(5): await RisingEdge(sim_clk) # 这里写入你的测试操作,例如控制DUT输入 dut.some_input.value = 1 cocotb.log.info("测试时钟上升沿触发,执行测试操作")
方案二:无需实体时钟,定时循环执行测试
如果不需要实体时钟信号,仅需固定周期执行测试操作,可直接用循环加Timer实现,更轻量化:
import cocotb from cocotb.triggers import Timer @cocotb.test() async def top(dut): test_period_ms = 22 for _ in range(5): # 等待半个周期,模拟"上升沿"触发时机 await Timer(test_period_ms // 2, units="ms") # 执行测试操作 dut.some_input.value = 0 cocotb.log.info("测试周期触发,执行操作") # 等待剩余半个周期,完成完整周期 await Timer(test_period_ms // 2, units="ms")
方案对比
- 方案一适合需要和DUT时钟触发逻辑保持一致的场景,可复用
RisingEdge/FallingEdge触发器,代码风格更统一。 - 方案二更简洁,无需维护额外信号,适合简单定时测试场景。
内容的提问来源于stack exchange,提问作者Sameh
相关产品推荐
相关产品推荐

