Sle*_*der 3 hardware verilog fpga sequential
我正在为数据路径电路实现FSM控制器.控制器在内部递增计数器.当我模拟下面的程序时,计数器从未更新过.
reg[3:0] counter;
//incrementing counter in combinational block
counter = counter + 4'b1;
Run Code Online (Sandbox Code Playgroud)
但是,在创建额外变量counter_next时,如Verilog Best Practice中所述 - 递增变量并仅在顺序块中递增计数器,计数器会递增.
reg[3:0] counter, counter_next;
//sequential block
always @(posedge clk)
counter <= counter_next;
//combinational block
counter_next = counter + 4'b1;
Run Code Online (Sandbox Code Playgroud)
为什么计数器在前一种情况下不会增加?我缺少什么?
好.我假设你从第一个例子中留下了一些代码,因为它甚至不应该编译.但是,我想我无论如何都可以为你解释这个问题.
在一个看起来像这样的块:
always @(*) begin // or always @(counter)
counter = counter + 4'b1;
end
Run Code Online (Sandbox Code Playgroud)
有两个问题.
1)计数器永远不会初始化.所有'reg'类型变量在模拟时间开始时都是X,因此在X中加1是X.
2)这被认为是一个组合循环.该块对"计数器"的变化很敏感,因此即使假设"计数器"初始化为0,模拟器也会永远循环更新"计数器",模拟时间永远不会超前.即
always block executes -> counter = 1
counter has changed
always block executes -> counter = 2
counter has changed
and so on...
Run Code Online (Sandbox Code Playgroud)
如果你在那里放一个$ display语句,你可以看到这个循环发生了.否则它只会显示模拟器挂起并且不会写入波形.
第二个例子工作的原因是你有一个触发器打破了组合循环.在每个时钟边沿,'counter'用'counter_next'的当前值更新.然后组合块执行一次(并且仅执行一次)以计算"counter_next"的新版本.
由于完整性,你仍然缺少通过reset子句或初始语句初始化'counter'.
reg [3:0] counter;
reg [3:0] counter_next;
always @(*) begin
counter_next = counter + 1;
end
always @(posedge clk or negedge rst_l) begin
if (!rst_l)
counter <= 4'b0;
else
counter <= counter_next;
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
20429 次 |
| 最近记录: |