I am trying to write a simple module to output a 14-bit number based on the value of four input signals. My attempt is shown below.
我尝试编写一个简单的模块,根据四个输入信号的值输出一个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
Upon compilation, I receive the following error:
在编译时,我收到以下错误:
ERROR:HDLCompiler:44 - Line 67: c is not a constant
错误:HDLCompiler:44 - Line 67: c不是常量。
I don't understand why that particular if-statement isn't working if the other two preceding it are. I have tried changing the condition to
我不明白为什么这个特定的if语句在前面的两个是无效的。我已经试过把条件改为。
if (c == 1) begin
but to no avail.
但无济于事。
Does anybody know how to solve this error? Thank you!
有人知道怎么解决这个错误吗?谢谢你!
2 个解决方案
#1
6
Two problems:
两个问题:
1) You need to put if
statements inside an always
block.
你需要把if语句放在一个总是块中。
If you use verilog-2001, you can use
如果您使用verilog-2001,您可以使用。
always @*
if ....
end
end
Otherwise specify all the inputs in the sensitivity list:
否则,请指定敏感列表中的所有输入:
always @(a or b or c or d)
if ....
end
end
2) Constant assignments are not allowed inside if statements.
Remove the assign
keyword from any statements inside the if
block:
从if块内的任何语句中删除assign关键字:
if (a) begin
size = 14'h2222;
end
You will also have to declare size as a reg
type.
您还必须声明大小为reg类型。
However my preference would be to rewrite the entire module with conditional operator, I find it much preferrable to read. This following module achieves the same result:
然而,我的首选是用条件操作符重写整个模块,我发现它更适合阅读。该模块实现了相同的结果:
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
#2
1
As @Tim has already answered, using reg
types inside always
blocks or wire
with assign
.
正如@Tim已经回答的那样,使用reg类型的内部总是块或线的分配。
@Tim has also described the nested ternary assignments, while in the example are written very well, they are generally seen as bad practice. They imply a very long combinatorial path and can be hard to maintain. The combinatorial path may be optimised by synthesis which should imply a mux with optimised selection logic.
@Tim还描述了嵌套的三元分配,而在例子中写得很好,它们通常被认为是糟糕的实践。它们意味着一个非常长的组合路径,并且很难维护。组合路径可以通过合成来优化,这意味着一个具有优化选择逻辑的mux。
Easier to maintain code will have a lower cost of ownership, and as long as it does not lead to a larger synthesised design it is normally preferred.
更容易维护的代码将拥有更低的所有权成本,而且只要它不导致更大的合成设计,它通常是首选的。
My implementation would be to use a casez, (? are don't cares). I find the precedence of each value easier to see/debug.
我的实现将是使用一个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
#1
6
Two problems:
两个问题:
1) You need to put if
statements inside an always
block.
你需要把if语句放在一个总是块中。
If you use verilog-2001, you can use
如果您使用verilog-2001,您可以使用。
always @*
if ....
end
end
Otherwise specify all the inputs in the sensitivity list:
否则,请指定敏感列表中的所有输入:
always @(a or b or c or d)
if ....
end
end
2) Constant assignments are not allowed inside if statements.
Remove the assign
keyword from any statements inside the if
block:
从if块内的任何语句中删除assign关键字:
if (a) begin
size = 14'h2222;
end
You will also have to declare size as a reg
type.
您还必须声明大小为reg类型。
However my preference would be to rewrite the entire module with conditional operator, I find it much preferrable to read. This following module achieves the same result:
然而,我的首选是用条件操作符重写整个模块,我发现它更适合阅读。该模块实现了相同的结果:
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
#2
1
As @Tim has already answered, using reg
types inside always
blocks or wire
with assign
.
正如@Tim已经回答的那样,使用reg类型的内部总是块或线的分配。
@Tim has also described the nested ternary assignments, while in the example are written very well, they are generally seen as bad practice. They imply a very long combinatorial path and can be hard to maintain. The combinatorial path may be optimised by synthesis which should imply a mux with optimised selection logic.
@Tim还描述了嵌套的三元分配,而在例子中写得很好,它们通常被认为是糟糕的实践。它们意味着一个非常长的组合路径,并且很难维护。组合路径可以通过合成来优化,这意味着一个具有优化选择逻辑的mux。
Easier to maintain code will have a lower cost of ownership, and as long as it does not lead to a larger synthesised design it is normally preferred.
更容易维护的代码将拥有更低的所有权成本,而且只要它不导致更大的合成设计,它通常是首选的。
My implementation would be to use a casez, (? are don't cares). I find the precedence of each value easier to see/debug.
我的实现将是使用一个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