Race condition in Verilog
According to the Verilog standard, the execution of two always blocks can be scheduled in any order. This is known as a race condition. 比如我们想交换reg a和b的值,这样是不行的:
always @(posedge clk) a = b;
always @(posedge clk) b = a;
需要这样:
module test; reg a, b; wire clk; always @(posedge clk) begin // b_old = b a <= b; // a_new = b_old end // a = a_new always @(posedge clk) begin // a_old = a b <= a; // b_new = a_old end // b = b_new endmodule
这个例子不是我胡诌的,是从本好书里抄来的,把entry换成了old, exit换成了new而已。本例clk是真是假不影响讨论。仿真器如何实现这样的功能?我们来看下Icarus Verilog的输出片段:
v000001bb63fb6fd0_0 .var "a", 0 0; v000001bb63fd2cb0_0 .var "b", 0 0; o000001bb64007008 .functor BUFZ 1, C4<z>; HiZ drive v000001bb63fd2d50_0 .net "clk", 0 0, o000001bb64007008; 0 drivers E_000001bb64005450 .event posedge, v000001bb63fd2d50_0; .scope S_000001bb63fd2b20; T_0 ; %wait E_000001bb64005450; %load/vec4 v000001bb63fd2cb0_0; %assign/vec4 v000001bb63fb6fd0_0, 0; %jmp T_0; .thread T_0; .scope S_000001bb63fd2b20; T_1 ; %wait E_000001bb64005450; %load/vec4 v000001bb63fb6fd0_0; %assign/vec4 v000001bb63fd2cb0_0, 0; %jmp T_1; .thread T_1;
可以看到和猜到:每个always块对应一个thread(并不是每个thread对应一个操作系统里的thread)。@([sensitivity-list])变成了wait_event. 一个event可以有多个thread在wait. event发生时,随机选择一个thread执行。thread执行到要assign时就暂停执行,调度下一个也就绪的thread执行。
clk是个buf functor. The buf functor changes the z bits to x bits in the vector it passes, and propagate the result. 被wait的event是E_000001bb64005450,它与v000001bb63fd2d50_0即clk相关。
%load/vec4 <var-label> loads a vector value from the given functor node and pushes it onto the vec4 stack. 每个reg是个二进制位的向量(vector). 向量的每个元素有0, 1, x, z共4种取值。x=don't care; z=高阻抗。高阻状态的电路就像是没有接入。The %assign/vec4 instruction is a non-blocking assignment. The <delay> is the number of clock ticks in the future where the assignment should schedule, and the value to assign is pulled from the vec4 stack. 每个thread有自己的vec4 stack. a_old和b_old保存在其中。
1. 希望没有猜错。2. 本贴没啥新内容,大概其别的帖子里都说过了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?