是的,在同一个 always 块中,多个 if 控制同一个变量,在工程实践中被认为是不推荐甚至是非规范的写法。
规范写法应该做到:
对同一个变量只在一个 if-else 构造中赋值一次
或者先用中间变量组合逻辑,最后统一赋值
always @(posedge clk) begin
if (a)
x <= 1;
if (b)
x <= 2;
end
如果 a=1
且 b=1
,两个赋值都满足,但最后只有一个生效
编译器不会报错,但这个行为容易误解、难调试、RTL仿真可能与综合结果不一致
别人(包括未来的你)读代码的时候,难以判断:
哪个条件优先?
有没有遗漏情况?
会不会不小心“被覆盖”?
一些综合器可能无法很好优化这种“模棱两可”的赋值逻辑
极端情况下可能推导出锁存器,或者额外的多路选择器
if - else if - else
保证互斥性always @(posedge clk) begin
if (a)
x <= 1;
else if (b)
x <= 2;
else
x <= 0;
end
结构清晰:每次时钟沿只赋一次值
行为明确:a
、b
是优先级关系
不会冲突:只会满足一个分支
reg [7:0] x;
reg [7:0] x_next;
always @(*) begin
x_next = 0;
if (a)
x_next = 1;
if (b)
x_next = 2;
end
always @(posedge clk) begin
x <= x_next;
end
把所有条件的逻辑都集中在 always @(*)
中组合完,再同步更新 x
解耦逻辑和时序,便于复用、插入打拍
【verilog】always @(*) 是Verilog 中写组合逻辑
case
语句明确状态控制always @(posedge clk) begin
case ({a, b})
2'b10: x <= 1;
2'b01: x <= 2;
default: x <= 0;
endcase
end
清晰处理多个条件组合
有状态机风格,也方便做扩展
这是允许的,也是推荐的:
always @(posedge clk) begin
if (a)
x <= 1;
if (b)
y <= 2;
end
因为 x
和 y
是独立变量,不存在“赋值覆盖”的问题。
在 RTL 中,同一个变量最好只赋值一次,并通过互斥的结构(if-else / case)来清晰表达优先级和行为。
【verilog】Verilog 工程规范编码模板
Enable Ginger Cannot connect to Ginger Check your internet connection