双周期乘法器

问题描述 投票:0回答:1

我正在做两个周期乘法器,我有一个 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
verilog
1个回答
0
投票

您遇到的一个问题是错误使用阻塞

=
和非阻塞
<=
赋值。

一般建议在建模同步逻辑(触发器、寄存器等)时使用非阻塞赋值

<=
,在建模组合逻辑时使用阻塞赋值
=

此信息已广为人知。参考 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
© www.soinside.com 2019 - 2024. All rights reserved.