我无法在Stuart Sutherland(及其他人)的SystemVerilog For Design书中绕过例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是否被合成到状态寄存器?
大多数指南声明永远不要混合阻止和非阻止分配。有没有更好的方式来表示这样的事情。现在在SV-Design中可以混合两种类型的赋值,因为它是一个always_ff块吗?
答案 0 :(得分:3)
您绝不应将阻止和非阻止分配混合到相同的变量中。 breakVar
是一个临时变量,它将被合成为组合逻辑,因为它总是先写入,然后再读取。没有 state 可以保存。 RoundRobin
是一个局部变量,用作中间变量和状态变量。但是因为它只能从always_ff块中访问,所以没有竞争条件的危险。
答案 1 :(得分:0)
在过去的糟糕时期,在同一个流程块中混合阻塞和非阻塞分配是不好的,因为不同的工具在调度这些操作的方式上不一致。
新的SystemVerilog规范更明确地说明了如何订购这些事件的处理,所以现在它已经好了#34;混合阻塞和非阻塞分配,因为工具现在将保持一致。但是:
您将编写令人困惑且难以维护的代码,这会导致人们在查看堆栈溢出时提出问题。
您将嘲笑每位拥有超过10年经验的RTL开发人员。一旦你被模拟器/合成器不匹配烧毁,你就会对违规的编码风格产生强迫性厌恶。
我的经验法则是:除非逻辑是微不足道的,否则只使用阻塞赋值在always_comb块中完成所有复杂的工作。每个人都知道如何阅读顺序代码,它是可维护的,没有人会对它感到困惑。使用单独的always_ff进程除了将下一个状态变量锁存到当前状态变量之外什么都不做。
答案 2 :(得分:0)
完全同意@jonathan的答案。
您应始终将逻辑元素拆分为always_comb块,并将顺序元素拆分为always_ff块。
如果您编写的代码紧密结合在一起(两个组合 和顺序元素在同一块中),即使它是正确的,并且 符合系统Verilog规范,某些较旧版本的模拟器 或正在开发的较新的模拟器可能以错误的方式进行推断。
您的代码将不干净,不会被他人理解。
也可以通过上面的方式写,只是压实了 代码,即使逻辑保持不变。毫无意义 编写紧凑的代码,如果这样做会影响代码的可读性。
现在就阻塞和非阻塞语句的使用而言,我认为辩论现在已经结束。现在,在always_comb块中使用阻塞语句,在always_ff块中使用非阻塞语句,已不再是准则。
不过, Clifford E Cummings 在这篇精湛的论文中对所有问题的答案进行了解释 Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill!
如果您是Verilog /系统Verilog设计的新手,建议您阅读他们的所有文章,它们非常有用,并且为RTL设计工程师奠定了良好的基础。
在这里要说的也太多了,但是如果您正在寻找如何以组合块和顺序块的形式隔离代码,则可以看看bluespec
生成的代码很难一眼就理解信号名称,但是如果仔细观察,代码在逻辑上就非常整洁,不会在仿真和综合工具的兴致中留下任何东西。