我正在做两个周期乘法器,我有一个 8 位
x
、y
和 15 位 z
的输出。现在我需要将 y 分别分成 [3:0]
和 [7:4]
。在第一个周期中,我将 x*y[3:0]
相乘并将其存储在 zd
中。第二个循环中,z
左移4位,与zd
相加。然而,这是不正确的。我怎样才能正确地做到这一点?
module Multiplier(out_st, cycle, in_st, clk, x, y, p, z);
output reg signed[15:0] z;
input in_st, clk, out_st;
input signed [7:0] x, y;
input cycle;
reg signed [15:0] zd;
always@( posedge clk )
begin
if ( out_st == 1'b1 )begin
z = x*y[3:0];
zd = z;
end
else if ( out_st == 1'b0 ) begin
z = x * y[7:4];
z = (z << 4 )+ zd;
end
end
endmodule
输入
x = 01010101
y = 10101010
正确输出
z = 1110001101110010
您遇到的一个问题是错误使用阻塞
=
和非阻塞 <=
赋值。
一般建议在建模同步逻辑(触发器、寄存器等)时使用非阻塞赋值
<=
,在建模组合逻辑时使用阻塞赋值 =
。
此信息已广为人知。参考 IEEE 1800-2017 第 10 节赋值语句,或搜索“Verilog 阻塞非阻塞”。这是搜索 Wikipedia
时出现的一个有用的结果您建模的逻辑是同步的,因此请使用非阻塞分配
always@( posedge clk )
begin
if ( out_st == 1'b1 )begin
z <= x*y[3:0]; // use non-blocking
zd <= z; // use non-blocking
end
else if ( out_st == 1'b0 ) begin
z <= x * y[7:4]; // use non-blocking
z <= (z << 4 )+ zd; // use non-blocking
end
end