Verilog中的逻辑问题

时间:2013-03-22 23:42:39

标签: verilog

我正在尝试根据设计编写乘数。它由两个16位输入组成,单个加法器用于计算部分乘积。一个输入的LSB与另一个输入的16位进行“与”运算,并且“与”门的输出重复添加到前一个输出。它的Verilog代码如下,但我似乎无法让输出工作。

module datapath(output reg [31:15]p_high,
                output reg [14:0]p_low,
                input [15:0]x, y,
                input clk); // reset, start, x_ce, y_ce, y_load_en, p_reset, 
               //output done);

reg [15:0]q0;
reg [15:0]q1;
reg [15:0]and_output;
reg [16:0]sum, prev_sum; 
reg d_in;
reg [3:0] count_er;

initial
 begin
      count_er <= 0;
      sum <= 17'b0;
      prev_sum <= 17'b0;
 end

always@(posedge clk)
begin
        q0 <= y;
        q1 <= x;
        and_output <= q0[count_er] & q1;
        sum <= and_output + prev_sum;    
        prev_sum <= sum;
        p_high <= sum;
        d_in <= p_high[15];
        p_low[14] <= d_in;
        p_low <= p_low >> 1;
        count_er <= count_er + 1;
 end
 endmodule

enter image description here 我创建了一个测试台来测试电路,我看到的第一个问题是,AND操作不能按我的意愿工作。 x操作数的16位和y操作数的LSB一起使用。在每个时钟周期之后,y操作数移位一位,并且通过连续添加部分乘积来计算最终乘积。

但是,我从sum和prev_sum行开始遇到问题,他们的输出显示为xxxxxxxxxxxx。

2 个答案:

答案 0 :(得分:1)

您似乎没有正确地重置所需的所有信号,或者您似乎对非阻塞分配的工作方式感到困惑。

初次开始后:

  • sum为0
  • prev_sum为0
  • and_output是X

在第一个正边缘之后:

  • sum是X,因为and_output是X,而X + 0返回X.此时,sum永远保持X,因为X +某些东西总是X.

您正在为设计中的几乎所有信号创建一个寄存器,这意味着您的所有信号都不会立即更新。您需要区分要注册的信号和仅仅是组合术语的信号。让寄存器使用posedge clock上的非阻塞语句进行更新,并通过将它们放在always @*块中立即更新组合术语。

我不知道您尝试使用的算法,所以我不能说哪些行应该是哪个,但我真的怀疑您打算花费一个时钟周期x/y传播到q0/q1,另一个周期q传播到and_output,另一个时钟周期从and_output传播到总和。


对更新代码的评论:

  • 组合块应使用阻止分配,而不是非阻塞分配。在always @ *块中使用=代替<=
  • sum <= and_output + sum;看起来不对,根据你的图片,它应该是sum = and_output + p_high[31:16]
  • 你在这里两次分配p_low [14]。使第二个语句仅显式设置位[13:0]:

    p_low[14]   <= d_in;
    p_low[13:0] <= p_low >> 1;
    

答案 1 :(得分:0)

您正在同一顺序always块中混合阻止和非阻止分配,这可能会导致意外结果:

d_in <= p_high[15];
p_low[14] = d_in;