我无法理解斯图尔特萨瑟兰(和公司)的SystemVerilog设计书中的例子10-3。
见第232行:
下面是代码片段。我的问题会跟进。
bit [0:NumRx-1] RoundRobin;
always_ff @(posedge clk, posedge reset) begin: FSM
bit breakVar;
if (reset) begin: reset_logic
Rxready <= '1;
Txvalid <= '0;
Txsel_out <= '0;
SquatState <= wait_rx_valid;
forward <= 0;
RoundRobin = 1;
end: reset_logic
else begin: FSM_sequencer
unique case (SquatState)
wait_rx_valid: begin: rx_valid_state
Rxready <= '1;
breakVar = 1;
for (int j=0; j<NumRx; j+=1) begin: loop1
for (int i=0; i<NumRx; i+=1) begin: loop2
if (Rxvalid[i] && RoundRobin[i] && breakVar)
begin: match
ATMcell <= RxATMcell[i];
Rxready[i] <= 0;
SquatState <= wait_rx_not_valid;
breakVar = 0;
end: match
end: loop2
if (breakVar)
RoundRobin={RoundRobin[1:$bits(RoundRobin)-1],
RoundRobin[0]};
end: loop1
end: rx_valid_state
具体来说,我的问题是关于breakVar
和RoundRobin
的阻塞分配。我在某个地方读到变量是在本地评估的,但我无法从门的角度来描绘逻辑是如何被合成的。RoundRobin
是否被合成到状态寄存器中?
大多数准则都规定永远不要混淆阻塞和非阻塞分配。有更好的方法来代表这样的东西吗?在SystemVerilog设计中,考虑到它在always_ff
块中,混合两种类型的赋值可以吗?
发布于 2014-06-13 14:32:47
不要将阻塞和非阻塞分配混合到同一个变量中。breakVar
是一个临时变量,它将被合成成组合逻辑,因为它总是先写入,然后读取。没有状态需要保存。RoundRobin
是一个局部变量,用作中间变量和状态变量。但是,因为它只能从always_ff
块中访问,所以不存在出现争用状态的危险。
一个临时变量只是一种象征性的方式来表示一个方程的一部分。这里有一个不同但更简单的例子:
always_ff @(posedge clock)
begin
full = (counter == 10);
brimming = (counter > 7);
hold <= brimming && !full;
if (full)
counter <= counter + 1;
else
counter < = 0;
end
这相当于编写以下内容(但可能更难理解)
always_ff @(posedge clock)
begin
hold <= (counter > 7) && !(counter == 10);
if (counter == 10)
counter <= counter + 1;
else
counter < = 0;
end
在上面的两个示例中,counter
将始终被合成为寄存器,因为它是在写入之前读取的。如果我们使用阻塞或非阻塞赋值,这并不重要,因为在编写完counter
之后,我们从未阅读过它。在这个always_ff
块中不存在使用阻塞分配的争用条件,但是如果有另一个always_ff
块试图读取它,则可能存在这种情况。由于full
和brimming
是在读取之前编写的,因此不必注册。
总之,如果这些条件中的任何一个为真,则将变量合成为寄存器。
always_ff
块中写入并在该块外部读取。发布于 2020-10-17 06:13:09
完全同意@jonathan的回答。
您应该始终在always_comb块中拆分逻辑元素,在always_ff块中拆分顺序元素。
现在,就阻塞和非阻塞语句的使用而言,我认为辩论现在结束了。现在,在always_comb块中使用阻塞语句而在always_ff块中使用非阻塞语句更多地是一条规则,而不是一条准则。
然而,对您所有问题的回答在Clifford E Cummings 非阻塞分配在Verilog合成,编码样式,杀死!的这篇精彩论文中作了解释。
如果你对verilog /系统verilog设计还是新手的话,我建议你阅读他们所有的论文,它们非常有用,为RTL设计工程师奠定了一个良好的基础。
此外,这里可能说得太多了,但是如果您正在研究如何在组合框和顺序块中隔离代码,您可以查看蓝语生成的代码。
信号名称很难一蹴而就就能理解,但是如果你仔细看一看,代码在逻辑上是非常整洁的,不会留下任何关于模拟和合成工具的怪念头。
https://stackoverflow.com/questions/24199587
复制相似问题