Verilog 如何将默认值分配给组合always块中的输出,以便在使用else语句时即使不完整也不会推断锁存
假设我想写一个使用4个输入和3个输出的组合模块。为了模拟我的逻辑,我做了如下操作:Verilog 如何将默认值分配给组合always块中的输出,以便在使用else语句时即使不完整也不会推断锁存,verilog,Verilog,假设我想写一个使用4个输入和3个输出的组合模块。为了模拟我的逻辑,我做了如下操作: module ifelse ( input wire a, input wire b, input wire c, input wire d, output reg y1, output reg y2, output reg y3 ); always @* begin if (a==1'b1
module ifelse (
input wire a,
input wire b,
input wire c,
input wire d,
output reg y1,
output reg y2,
output reg y3
);
always @* begin
if (a==1'b1 && b==1'b0) begin
y1 = 1'b0;
y3 = 1'b1;
end
else if (a==1'b0 && c==1'b1 && d==1'b0) begin
y2 = 1'b1;
y1 = 1'b1;
end
else if (a==1'b0 && c==1'b0) begin
y3 = 1'b0;
y2 = 1'b0;
end
end
endmodule
module ifelse (
input wire a,
input wire b,
input wire c,
input wire d,
output reg y1,
output reg y2,
output reg y3
);
always @* begin
if (a==1'b1 && b==1'b0) begin
y1 = 1'b0;
y3 = 1'b1;
y2 = 1'bx;
end
else if (a==1'b0 && c==1'b1 && d==1'b0) begin
y2 = 1'b1;
y1 = 1'b1;
y3 = 1'bx;
end
else if (a==1'b0 && c==1'b0) begin
y3 = 1'b0;
y2 = 1'b0;
y1 = 1'bx;
end
else begin
y1 = 1'bx;
y2 = 1'bx;
y3 = 1'bx;
end
end
endmodule
module ifelse(
input wire a,
input wire b,
input wire c,
input wire d,
output reg y1,
output reg y2,
output reg y3
);
always @* begin
if (a==1'b1 && b==1'b0) begin
y1 = 1'b0;
y3 = 1'b1;
end
else if (a==1'b0 && c==1'b1 && d==1'b0) begin
y2 = 1'b1;
y1 = 1'b1;
end
else if (a==1'b0 && c==1'b0) begin
y3 = 1'b0;
y2 = 1'b0;
end
@* = x; // unassigned outputs receive a default value of "dont care"
end
endmodule
好的,我知道此代码将推断出y1
、y2
和y3
的锁存,避免这种情况的方法是在每个if else
块中始终为每个LH分配一个值,如下所示:
module ifelse (
input wire a,
input wire b,
input wire c,
input wire d,
output reg y1,
output reg y2,
output reg y3
);
always @* begin
if (a==1'b1 && b==1'b0) begin
y1 = 1'b0;
y3 = 1'b1;
end
else if (a==1'b0 && c==1'b1 && d==1'b0) begin
y2 = 1'b1;
y1 = 1'b1;
end
else if (a==1'b0 && c==1'b0) begin
y3 = 1'b0;
y2 = 1'b0;
end
end
endmodule
module ifelse (
input wire a,
input wire b,
input wire c,
input wire d,
output reg y1,
output reg y2,
output reg y3
);
always @* begin
if (a==1'b1 && b==1'b0) begin
y1 = 1'b0;
y3 = 1'b1;
y2 = 1'bx;
end
else if (a==1'b0 && c==1'b1 && d==1'b0) begin
y2 = 1'b1;
y1 = 1'b1;
y3 = 1'bx;
end
else if (a==1'b0 && c==1'b0) begin
y3 = 1'b0;
y2 = 1'b0;
y1 = 1'bx;
end
else begin
y1 = 1'bx;
y2 = 1'bx;
y3 = 1'bx;
end
end
endmodule
module ifelse(
input wire a,
input wire b,
input wire c,
input wire d,
output reg y1,
output reg y2,
output reg y3
);
always @* begin
if (a==1'b1 && b==1'b0) begin
y1 = 1'b0;
y3 = 1'b1;
end
else if (a==1'b0 && c==1'b1 && d==1'b0) begin
y2 = 1'b1;
y1 = 1'b1;
end
else if (a==1'b0 && c==1'b0) begin
y3 = 1'b0;
y2 = 1'b0;
end
@* = x; // unassigned outputs receive a default value of "dont care"
end
endmodule
但是现在,假设有很多if-else
块(我试图描述一个说教微处理器的控制单元),并且有很多输出来自这个模块(微处理器数据路径中所有寄存器的控制线)。必须为每个if-else
块中的每个输出分配一个值肯定会导致一个不可读和不可维护的代码,因为我总是在中包含的每个新输出都必须包含在所有if-else
块中
然后,我的问题是:我是否必须明确地为我在特定if-else块中未使用的所有输出指定一个值。对于组合始终
块中未更新的信号,是否有类似于“默认值”的东西,以便在计算始终
块后,所有未分配的输出恢复为默认值或“不在乎”值
到目前为止,我已经找到了一个解决办法,似乎很有效:
module ifelse(
input wire a,
input wire b,
input wire c,
input wire d,
output reg y1,
output reg y2,
output reg y3
);
always @* begin
// default values
y1 = 1'bx;
y2 = 1'bx;
y3 = 1'bx;
if (a==1'b1 && b==1'b0) begin
y1 = 1'b0;
y3 = 1'b1;
end
else if (a==1'b0 && c==1'b1 && d==1'b0) begin
y2 = 1'b1;
y1 = 1'b1;
end
else if (a==1'b0 && c==1'b0) begin
y3 = 1'b0;
y2 = 1'b0;
end
end
endmodule
但是我想要更优雅的东西,就像Verilog 2001处理组合总是的敏感度列表一样,类似这样:
module ifelse (
input wire a,
input wire b,
input wire c,
input wire d,
output reg y1,
output reg y2,
output reg y3
);
always @* begin
if (a==1'b1 && b==1'b0) begin
y1 = 1'b0;
y3 = 1'b1;
end
else if (a==1'b0 && c==1'b1 && d==1'b0) begin
y2 = 1'b1;
y1 = 1'b1;
end
else if (a==1'b0 && c==1'b0) begin
y3 = 1'b0;
y2 = 1'b0;
end
end
endmodule
module ifelse (
input wire a,
input wire b,
input wire c,
input wire d,
output reg y1,
output reg y2,
output reg y3
);
always @* begin
if (a==1'b1 && b==1'b0) begin
y1 = 1'b0;
y3 = 1'b1;
y2 = 1'bx;
end
else if (a==1'b0 && c==1'b1 && d==1'b0) begin
y2 = 1'b1;
y1 = 1'b1;
y3 = 1'bx;
end
else if (a==1'b0 && c==1'b0) begin
y3 = 1'b0;
y2 = 1'b0;
y1 = 1'bx;
end
else begin
y1 = 1'bx;
y2 = 1'bx;
y3 = 1'bx;
end
end
endmodule
module ifelse(
input wire a,
input wire b,
input wire c,
input wire d,
output reg y1,
output reg y2,
output reg y3
);
always @* begin
if (a==1'b1 && b==1'b0) begin
y1 = 1'b0;
y3 = 1'b1;
end
else if (a==1'b0 && c==1'b1 && d==1'b0) begin
y2 = 1'b1;
y1 = 1'b1;
end
else if (a==1'b0 && c==1'b0) begin
y3 = 1'b0;
y2 = 1'b0;
end
@* = x; // unassigned outputs receive a default value of "dont care"
end
endmodule
因此,如果我修改此始终以添加仅在几个块中更新的新输出,我不必将其也包括在“默认”块中,同样的方式,我不必将其包括在灵敏度列表中
那么,Verilog中是否存在这样的功能?实际上,我的解决方法是这样做的,还是有更优雅的解决方案
非常感谢:)执行此操作的方法是在启动块的begin
之后,在第一个if
语句之前,为每个reg
指定一个默认值。如果你想合成一个信号,你不能给它分配1'bx
。你希望得到什么样的硬件?请记住,出现在信号上的x
是一个未知值,而不是一个不关心的条件。我认为使用块顶部的默认值解决问题是正确的解决方案。我不知道有哪种语法不需要为每个信号显式指定默认值。哦!然后我误读了我的Verilog手册:我认为“x”代表“不在乎”。我希望它能够作为一个纯粹的组合模块进行综合,而“不在乎”是为了帮助综合工具优化逻辑。实际上,对于控制单元,我不想要“不在乎”,而是想要“0”,以便停用我不更新的每个控制信号。x
只能在if
和case
语句中用作“不在乎”。将值x
(未知)分配给reg或导线在语法上是正确的,但不可合成。