考虑以下模块:
module power(input [11-1:0] xi,xq,output [22-1:0] y);
assign y = xi*xi + xq*xq;
endmodule
我知道我的单个任务实际上是由3个步骤分解的:2个方格和一个加法。我的问题是合成器将如何决定中间步骤xi*xi
和xq*xq
的位宽?
我注意到,当运行上述代码的逻辑等效电路(lec)时,它会造成麻烦,只能通过将单个分配分解为三个分配来解决,如下所示:
module power(input [11-1:0] xi,xq,output [22-1:0] yy);
wire [21-1:0] pi,pq;
assign pi = xi*xi;
assign pq = xq*xq;
assign yy = pi+pq;
endmodule
答案 0 :(得分:2)
以下是您的模拟器决定bitwith的中间结果。
Verilog Simulation
此表达式 - assign y = xi*xi + xq*xq;
- 是上下文确定表达式的示例。 Verilog模拟器采用表达式中最宽的所有网络或变量并使用它。因此,在您的代码中,最宽的是y
,宽度为22位,因此Verilog将始终使用22位。
VHDL模拟
VHDL模拟器的行为取决于所使用的包。如果您按照建议使用numeric_std
包,则需要遵守以下规则:
总和的宽度应该与两个操作数的宽度相同。 产品的宽度应该是操作数宽度的总和。
因此,如果直接翻译成VHDL,您的代码将被编译:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity power is
port (xi, xq : in signed(11-1 downto 0);
y : out signed(22-1 downto 0));
end entity power;
architecture A of power is
begin
y <= xi*xi + xq*xq;
end architecture A;
不应该签署所有内容吗?
鉴于您的模块(power
)和输入(xi
和xq
)的名称并且花了25年设计无线电系统,它们不应该是signed
?不应该是你的Verilog:
module power(input signed [11-1:0] xi,xq,output signed [22-1:0] y);
assign y = xi*xi + xq*xq;
endmodule
这就是为什么我从signed
选择了numeric_std
类型,而不是unsigned
类型。
<强>合成强>
好吧,我对模拟器很不满意,但是你问了合成。而且,坦率地说,我不知道合成器会做什么。但是,鉴于合成器的工作是设计一个行为与模拟完全相同的逻辑电路,您会认为任何自尊的合成器都会使用与模拟器相同的位宽。所以,我很确定这是你的答案。