我正在尝试编写一个简单的模块,根据四个输入信号的值输出一个14位数。我的尝试如下所示。
module select_size(
input a,
input b,
input c,
input d,
output [13:0] size
);
if (a) begin
assign size = 14'h2222;
end
else begin
if (b) begin
assign size = 14'h1111;
end
else begin
if (c) begin
assign size = 14'h0777;
end
else begin
assign size = 14'h0333;
end
end
end
endmodule
编译后,我收到以下错误:
错误:HDLCompiler:44 - 第67行:c不是常数
我不明白为什么如果前面的另外两个if语句不起作用的话。我已经尝试将条件更改为
if (c == 1) begin
但无济于事。
有人知道如何解决这个错误吗?谢谢!
答案 0 :(得分:6)
两个问题:
1)您需要将if
语句放在always
块中。
如果您使用verilog-2001,则可以使用
always @*
if ....
end
end
否则指定灵敏度列表中的所有输入:
always @(a or b or c or d)
if ....
end
end
<小时/> 2)if语句中不允许进行常量赋值。
从assign
块中的任何语句中删除if
关键字:
if (a) begin
size = 14'h2222;
end
您还必须将尺寸声明为reg
类型。
但是我的偏好是用条件运算符重写整个模块,我觉得它更适合阅读。以下模块实现了相同的结果:
module select_size(
input a,
input b,
input c,
input d,
output [13:0] size
);
assign size = a ? 14'h2222 :
b ? 14'h1111 :
c ? 14'h0777 :
14'h0333 ;
endmodule
答案 1 :(得分:1)
@Tim已经使用reg
块内的always
类型或wire
assign
来回答。
更容易维护代码将降低拥有成本,并且只要它不会导致更大的合成设计,通常是首选。
我的实现是使用casez,(?不关心)。我发现每个值的优先级更容易看/调试。
module select_size(
input a,
input b,
input c,
input d,
output logic [13:0] size //logic (SystemVerilog) or reg type
);
always @* begin
casez ({a,b,c})
3'b1?? : size = 14'h2222 ;
3'b01? : size = 14'h1111 ;
3'b001 : size = 14'h0777 ;
3'b000 : size = 14'h0333 ;
default: size = 'bx ;
endcase
end
endmodule