繁体   English   中英

在verilog中增加计数器变量:组合或顺序

[英]Incrementing a counter variable in verilog: combinational or sequential

我正在为数据路径电路实现FSM控制器。 控制器在内部递增计数器。 当我模拟下面的程序时,计数器从未更新过。

reg[3:0] counter;

//incrementing counter in combinational block
counter = counter + 4'b1;

但是,在创建额外变量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;

为什么计数器在前一种情况下不会增加? 我缺少什么?

好。 我假设你从第一个例子中留下了一些代码,因为它甚至不应该编译。 但是,我想我无论如何都可以为你解释这个问题。

在一个看起来像这样的块:

always @(*) begin // or always @(counter)
    counter = counter + 4'b1;
end

有两个问题。

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...

如果你在那里放一个$ 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM