问题描述
我是SystemVerilog的新手,我想知道在always_comb块中如何处理对同一信号的多次分配。
我正在分析某人编写的FSM,如果所有if语句为真,我不知道哪个将是下一个状态(名为“ ctrl_fsm_ns”的信号)。在google上搜索时,我发现这里使用了阻塞分配,因此我希望最后一个if语句将决定下一个状态(因此就像为每个if语句分配了一定的优先级)。但是,如果在每个if块中声明不同的信号怎么办?例如,即使下一个状态将是最后一个状态,它们都将被断言?
这是我不懂的代码。
always_comb
begin
...
unique case (ctrl_fsm_cs)
...
FIRST_FETCH:
begin
is_decoding_o = 1'b0;
// Stall because of IF miss
if ((id_ready_i == 1'b1) )
begin
ctrl_fsm_ns = DECODE;
end
// handle interrupts
if (irq_req_ctrl_i & irq_enable_int) begin
// This assumes that the pipeline is always flushed before
// going to sleep.
ctrl_fsm_ns = IRQ_TAKEN_IF;
halt_if_o = 1'b1;
halt_id_o = 1'b1;
end
if ((debug_req_pending || trigger_match_i) & (~debug_mode_q))
begin
ctrl_fsm_ns = DBG_TAKEN_IF;
halt_if_o = 1'b1;
halt_id_o = 1'b1;
end
end
解决方法
对于always_comb块中的每个变量,最后一个赋值是最终值。该工具分析过程流,以确保要分配的每个变量在通过代码的每种可能流中都至少具有一个分配。如果有可能在不写入变量的情况下读取变量,则认为该行为是闩锁行为,并且对于always_comb块是非法的。
您需要查看case语句之前或之后的代码,以查看是否对halt_
变量进行了其他分配。
基于您的评论的示例:
always_comb begin
A = 0; B = 1; C = 2;
if (I) A = X;
if (J) B = Y;
if (K) begin B = Z; C = Z; end
end
相当于这三个连续的作业:
assign A = I ? X : 0;
assign B = K ? Z : (J ? Y : 1 );
assign C = K ? Z : 2;
每个if
语句成为一个多路复用器,后面的语句具有更高的优先级。
您对上面代码的问题是一般的编程问题,而不是特定于Verilog的问题。因为只使用阻塞分配,所以代码完全是过程性的。
由于代码未使用“ if-else-if”序列,而仅使用“ if-if-if”,因此所有“ if”条件都将按ORDER进行求值,所有赋值均将按ORDER进行,因此最终的任务将获胜(如戴夫所说)。
在上面的评论中,您询问(A_expr,B_expr,C_expr)是否全部正确?然后(A,B,C)都将设置为1。
A_expr=1; B_expr=1; C_expr=1;
if (A_expr) A = 1;
if (B_expr) B = 1;
if (C_expr) C = 1;