当前位置: 首页 > news >正文

FPGA基础 -- cocotb仿真之任务调度cocotb.start_soon与asyncio的使用注意事项

为什么在 cocotb 里不要asyncio、而要用 cocotb.start_soon()”讲透彻——从调度机制、时间语义、线程安全、异常传播与收尾、以及可替代方案全覆盖。

结论先行

  • cocotb 有自己的协程调度器,由仿真器(VPI/VHPI/FLI)事件驱动;不是 asyncio 的事件循环。
  • 仿真时间≠真实时间cocotb.Timer("10 ns") 推进的是模拟时间asyncio.sleep() 走的是墙钟时间,与仿真推进完全脱钩。
  • cocotb.start_soon() 把协程注册到 cocotb 调度器,能感知 RisingEdge/ReadOnly/ReadWrite仿真相位asyncio 完全不知道这些相位。
  • 生命周期与异常start_soon() 启的任务在测试结束会被自动取消/收尾、异常会正确上抛asyncio 任务不会被 cocotb 管理,容易泄漏、卡住、吞异常
  • 单线程要求:大多数仿真器 API 只能在主仿真线程调用。asyncio 常见的跑法(单独事件循环/线程)会越线程调用仿真对象,直接未定义行为。

1) 调度模型:两个“世界”的事件循环不兼容

  • cocotb 调度器:当你 await RisingEdge(sig)await Timer(10, "ns")await ReadOnly() 时,本质是把协程挂到仿真器的事件队列上。仿真器到点触发回调,cocotb 才恢复协程。唯一时基模拟时间/相位
  • asyncio 调度器:管理 Future/Task 的是 Python 的墙钟事件循环。它既不认识 RisingEdge,也不认识 ReadOnly/ReadWrite,更无法在NBA 提交后保证你再读取信号。

结果:你用 asyncio.create_task() 启的任务无法由仿真事件唤醒;反之,awaitRisingEdge 的 cocotb 协程也不会被 asyncio 驱动。两边是两套互不相干的“时空”


2) 时间语义:模拟时间 vs 真实时间

  • Timer(100, "ns"):推进仿真 100ns,期间墙钟可能 0ms(Verilator 的零延时步进)或若干 ms。
  • asyncio.sleep(0.1)墙钟 100ms,仿真时间可能没动(尤其是事件驱动仿真)。
    → 常见灾难:你在 asyncio.sleep() 等“1ms 后再读数据”,但仿真里下一拍都没到;或者你在 monitor 里用 asyncio.sleep(0) 当让步,结果仍在错相位读取,读不到 SOT/DT 等一次性字样。

3) 仿真相位:ReadOnly/ReadWrite 只能由 cocotb 感知

  • 你已经踩过一次坑:不加 ReadOnly() 在 NBA 落地前读取 hs_data_out,错过 0xB8B8B8B8
  • 这些相位触发(ReadOnly/ReadWrite/NextTimeStep)是 cocotb 对仿真器调度队列的包装;asyncio 完全不认识,无法保证“在 NBA 之后读”、“在驱动区写”。

4) 线程与仿真器 API:只能主线程

  • 大多数 VPI/VHPI/FLI 后端必须在仿真主线程调用信号读写。
  • asyncio 常见做法是起一个独立 loop(甚至独立线程)→ 这会导致你在非仿真线程里碰 dut.sig.value未定义行为(轻则读脏,重则崩仿真)。

5) 生命周期与异常传播

  • cocotb.start_soon(coro) → 返回 cocotb.task.Task

    • 随测试生命周期自动管理:测试结束时自动取消未结束的子任务;
    • 子任务抛出的异常会关联到当前测试,让回归正确 fail
    • 你还能 await task显式 join
  • asyncio.create_task(coro)

    • cocotb 看不见它,测试结束不回收
    • 异常可能被吞或仅在 Task 回收时打印 warning;
    • 容易在 CI 里造成间歇性挂死/泄漏

6) 可观测性与可重复性

  • cocotb 的调度顺序(不同 Trigger、不同 Task 之间)是为可重复/可验证设计的;
  • asyncio 的调度顺序受墙钟/事件循环实现影响,不可复现→ 回归不稳定。

7) 正确并发姿势:cocotb.start_soon() 模式

典型写法(也是你项目里应该遵循的套路):

# 时钟
cocotb.start_soon(Clock(dut.tx_byte_clk, 8, units="ns").start())
cocotb.start_soon(Clock(dut.pixclk_o,   13.888, units="ns").start())# Monitor(注意每拍 ReadOnly)
async def hs_monitor(dut, out_q):prev_active = Falsecur = []while True:await RisingEdge(dut.tx_byte_clk)await ReadOnly()active = int(dut.txclk_hsen.value) and (int(dut.txclk_hsgate.value) == 0)if active:cur.append(int(dut.hs_data_out.value))if prev_active and not active and cur:await out_q.put(cur)  # cocotb.queue.Queuecur = []prev_active = activemon_task = cocotb.start_soon(hs_monitor(dut, my_queue))# Driver(注意 ReadWrite/相位)
async def driver(dut):await RisingEdge(dut.tx_byte_clk)  # 对齐# 驱动 fv/lv/dvalid/pixdata...# 写之前可 await ReadWrite();或直接赋值,让 cocotb 放到写相位
drv_task = cocotb.start_soon(driver(dut))# 等待或 join
await Timer(200, "us")
for t in (mon_task, drv_task):t.kill()  # 或 await t

8) 如果你必须asyncio(极少见)的替代方案

有些人想在 TB 里连网络/串口/文件异步 IO。建议:

  1. 子线程跑 asyncio loop,与 cocotb 通过线程安全队列通信;
  2. 子线程禁止直接读写 dut;把需要的操作封装成回调,回到主仿真线程用 cocotb 触发(例如 cocotb.triggers.Timer(0) 安排一个“下一拍执行”的安全回调);
  3. 或者更简单:把外部 IO 做成同步阻塞,丢给 cocotb.extern 包一层,到主线程里再 await 返回值(仍需谨慎,避免卡住仿真推进)。

总之:任何触达仿真对象的操作都必须回到 cocotb 的调度上下文


9) 历史兼容:fork vs start_soon

  • 旧 API cocotb.fork() 早期就能用,但不返回 Task 对象(可控性差);
  • 新 API cocotb.start_soon() 返回 Task,支持 join()/kill()更安全、可管理
  • 现在统一用 start_soon()

小结

asyncio 和 cocotb 是两台互不连接的引擎:一个按墙钟调度,另一个按仿真事件调度。把 TB 的并发交给 cocotb.start_soon(),才能获得正确的相位语义、可重复的调度、可控的生命周期与异常传播
当你采样像 0xB8B8B8B8 这种“一拍即逝”的字样时,RisingEdge + ReadOnly 搭配 start_soon() 的监控模式,才是可靠的专业做法。

http://www.dtcms.com/a/483901.html

相关文章:

  • 图片生成网站建站之星多语言
  • 镇江牛吧企业网站建设与推广公司谷歌推广新手教程
  • 免费扑克网站域名查询官网入口
  • Grafana图表与电话交换机的结合
  • 【vue】NoticeBar:滚动通知栏组件手动实现(内容、速度、循环间隔可配置)
  • 绘制网站地图施工企业的施工生产计划与建设
  • 电子商务平台网站建造温州网站开发定制
  • 永康市网站建设关键词排名优化网站建设公司哪家好
  • 花卉网站建设的总结与杂志制作 wordpress主题
  • 外卖网站那家做的好个人网站设计论文范文
  • 【数位dp】3704. 统计和为 N 的无零数对|2419
  • 快速学制作网站株洲seo优化公司
  • 【Datawhale组队学习】math-for-ai TASK01
  • 个人网站主页模板wp用户前端化专业版wordpress插件[中英双语]
  • 看设计比较好的网站在线装修设计平台
  • 网站建设目标分析学校网站建设工作方案
  • 【Linux】Linux驱动开发与BSP开发:嵌入式系统的两大基石
  • 郑州机械网站建设张家港网站制作服务
  • 动叫建个网站刷排名郑州高端做网站
  • 波矢 行波 和 相速度推导
  • LeetCode算法日记 - Day 72: 下降路径最小和、珠宝的最高价值
  • 天津专业智能建站wordpress 转换app
  • 周口市住房和城乡建设局门户网站wordpress邮件服务器怎么设置
  • 新版 网站在建设中...工信部 网站 备案
  • Flutter---showCupertinoDialog
  • 万州做网站seo优化一般包括哪些
  • 网站建设优化兼职在家漯河网站建设费用
  • 学校网站的英文一个人如何注册公司
  • 哪些网站用php余姚网站建设设计服务
  • PS成长之路⑧:如何判断生成何种需求类型满足场景需求