Verilog中的逻辑问题

Verilog中的逻辑问题,verilog,Verilog,我正试着根据一个设计写一个乘法器。它由两个16位输入组成,一个加法器用于计算部分积。一个输入的LSB与另一个输入的16位进行AND运算,AND门的输出被重复地添加到先前的输出中。下面是它的Verilog代码,但我似乎很难让输出正常工作 module datapath(output reg [31:15]p_high, output reg [14:0]p_low, input [15:0]x, y,

我正试着根据一个设计写一个乘法器。它由两个16位输入组成,一个加法器用于计算部分积。一个输入的LSB与另一个输入的16位进行AND运算,AND门的输出被重复地添加到先前的输出中。下面是它的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
模块数据路径(输出寄存器[31:15]p_高,
输出调节[14:0]p_低,
输入[15:0]x,y,
输入时钟);//重置,启动,x_ce,y_ce,y_加载,p_重置,
//完成输出);
reg[15:0]q0;
reg[15:0]q1;
reg[15:0]和_输出;
注册[16:0]和,上一个和;
reg d_in;
注册[3:0]计数;
最初的
开始

计数\u er您在同一顺序
始终
块中混合了阻塞和非阻塞分配,这可能会导致意外结果:

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

d_in您似乎没有正确地重置所有需要的信号,或者您似乎混淆了非阻塞分配的工作方式

初始开始后:

  • sum
    为0
  • prev_sum
    为0
  • 和_输出
    为X
在第一条正边之后:

  • sum
    是X,因为
    和_output
    是X,X+0返回X。在这一点上,sum永远保持X,因为X+某物总是X
您正在为设计中的几乎每个信号创建一个寄存器,这意味着没有一个信号会立即更新。您需要区分要注册的信号和只是组合术语的信号。让寄存器在
posedge时钟
上使用非阻塞语句进行更新,并通过将组合项放入
always@*
块中立即更新

我不知道您试图使用的算法,所以我不能说哪一行应该是哪一行,但我真的怀疑您是否打算用一个时钟周期将
x/y
传播到
q0/q1
,用另一个周期将
q
传播到
并输出
,还有另一个时钟周期,从
到_输出
再到求和


对更新代码的评论:


  • 组合块应该使用阻塞分配,而不是非阻塞分配。使用
    =
    而不是
    “无法使输出正常工作”。你能说得更具体些吗?如果我们一开始就知道哪里出了问题,那么调试就更容易了。我添加了更多的内容。我对其进行了修改,但没有任何积极的结果,但感谢您指出。我已经更新了代码,但不确定注释是否能够容纳修改后的代码。我还将链接粘贴到了我试图实现的电路上。更新代码:,设计:@GamingX-我对你的新代码添加了一些评论,希望这能让你开始。如果您仍然有问题,请尝试在模拟器中跟踪信号,以查看问题所在。我认为您所做的更改没有保存。一旦你做了更改,它可能会创建一个新的链接。我的意思是我编辑了上面的文章,我没有在粘贴栏上做任何事情。请看上面我回答文章的最后几点@GamingXI做了您建议的所有更改,但没有任何运气。我仍然从它开始,所以不完全确定调试步骤
    
    p_low[14]   <= d_in;
    p_low[13:0] <= p_low >> 1;