You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移位相加型二进制乘法器reg2出现未知态(X)问题求助

移位相加型二进制乘法器Verilog实现中reg2出现未知态(X)的问题

我实现了一款移位相加型二进制乘法器,使用reg1存储部分积项,reg2存储中间结果(初始化为首个部分积数组m[0])。仿真过程中reg2多次出现未知态(X),例如当count变为1时,reg2本应保持之前的00001111值,却变为X,无法定位问题原因,特此求助。

实现代码

module bin_mult(
    output reg [7:0]mult,reg1,reg2,
    output reg [2:0]count,
    input [3:0]a,b,
    input load,clk);

    //reg [7:0]reg1,reg2;
    //reg [2:0]count;
    reg [3:0]m[3:0];
    integer i,j;
    
    // Partial product generation
    always@(*) begin
        for(i=0;i<4;i=i+1) begin
            for(j=0;j<4;j=j+1) begin
                m[i][j]=b[i]&a[j];
            end
        end
    end

    always@(posedge clk) begin
        if(load) begin
            reg1<=0;
            count<=0;
            reg2<={4'd0,m[0]};
        end
        else if(count==4'd3) count<=0;
        else begin
                count<=count+1;
                if(b[count+1]==1'b1) begin
                    reg1<={4'd0,m[count+1]}<<(count+1);
                    mult<=reg1+reg2;
                    reg2<=mult;
                end
                else if(b[count+1]==1'b0) reg2<=reg2;
        end
    end
endmodule

测试代码

module tb;
wire [7:0]mult,reg1,reg2;
wire [2:0]count;
reg [3:0]a,b;
reg load,clk;
bin_mult DUT(mult,reg1,reg2,count,a,b,load,clk);
always #5 clk=~clk;
initial begin
    $dumpfile("tb.vcd");
    $dumpvars(0,tb);
    $monitor("clk=%b load=%b a=%d b=%d count=%d reg1=%b reg2=%b mult=%d",clk,load,a,b,count,reg1,reg2,mult);
    {clk,load}=0;
    @(negedge clk) a=4'd15;b=4'd15;
    @(negedge clk) load=1'b1;
    @(negedge clk) load=1'b0;
    #100 $finish;
end
endmodule

仿真结果

VCD info: dumpfile tb.vcd opened for output.
clk=0 load=0 a= x b= x count=x reg1=xxxxxxxx reg2=xxxxxxxx mult=  x
clk=1 load=0 a= x b= x count=x reg1=xxxxxxxx reg2=xxxxxxxx mult=  x
clk=0 load=0 a=15 b=15 count=x reg1=xxxxxxxx reg2=xxxxxxxx mult=  x
clk=1 load=0 a=15 b=15 count=x reg1=xxxxxxxx reg2=xxxxxxxx mult=  x
clk=0 load=1 a=15 b=15 count=x reg1=xxxxxxxx reg2=xxxxxxxx mult=  x
clk=1 load=1 a=15 b=15 count=0 reg1=00000000 reg2=00001111 mult=  x
clk=0 load=0 a=15 b=15 count=0 reg1=00000000 reg2=00001111 mult=  x
clk=1 load=0 a=15 b=15 count=1 reg1=00011110 reg2=xxxxxxxx mult= 15
clk=0 load=0 a=15 b=15 count=1 reg1=00011110 reg2=xxxxxxxx mult= 15
clk=1 load=0 a=15 b=15 count=2 reg1=00111100 reg2=00001111 mult=  x
clk=0 load=0 a=15 b=15 count=2 reg1=00111100 reg2=00001111 mult=  x
clk=1 load=0 a=15 b=15 count=3 reg1=01111000 reg2=xxxxxxxx mult= 75
clk=0 load=0 a=15 b=15 count=3 reg1=01111000 reg2=xxxxxxxx mult= 75
clk=1 load=0 a=15 b=15 count=0 reg1=01111000 reg2=xxxxxxxx mult= 75
clk=0 load=0 a=15 b=15 count=0 reg1=01111000 reg2=xxxxxxxx mult= 75
clk=1 load=0 a=15 b=15 count=1 reg1=00011110 reg2=01001011 mult=  x
clk=0 load=0 a=15 b=15 count=1 reg1=00011110 reg2=01001011 mult=  x
clk=1 load=0 a=15 b=15 count=2 reg1=00111100 reg2=xxxxxxxx mult=105
clk=0 load=0 a=15 b=15 count=2 reg1=00111100 reg2=xxxxxxxx mult=105
clk=1 load=0 a=15 b=15 count=3 reg1=01111000 reg2=01101001 mult=  x
clk=0 load=0 a=15 b=15 count=3 reg1=01111000 reg2=01101001 mult=  x
clk=1 load=0 a=15 b=15 count=0 reg1=01111000 reg2=01101001 mult=  x
clk=0 load=0 a=15 b=15 count=0 reg1=01111000 reg2=01101001 mult=  x
clk=1 load=0 a=15 b=15 count=1 reg1=00011110 reg2=xxxxxxxx mult=225
clk=0 load=0 a=15 b=15 count=1 reg1=00011110 reg2=xxxxxxxx mult=225
clk=1 load=0 a=15 b=15 count=2 reg1=00111100 reg2=11100001 mult=  x
test.v:56: $finish called at 130 (1s)
clk=0 load=0 a=15 b=15 count=2 reg1=00111100 reg2=11100001 mult=  x

问题分析与修复

核心原因

  1. 赋值依赖未稳定信号:当b[count+1]==1'b1时,代码中reg2<=mult;,但mult是当前时钟沿新赋值的信号,它依赖reg1+reg2的计算结果,此时mult还未完成更新,导致reg2被赋值为不确定态。
  2. 不完全赋值分支:当count==4'd3时,仅对count赋值,未处理reg1、reg2、mult,Verilog中时序逻辑块若未覆盖所有分支的寄存器赋值,会导致寄存器进入未知态。

修复方案

  1. 直接用reg2当前值计算更新,避免依赖mult:
    if(b[count+1]==1'b1) begin
        reg1<={4'd0,m[count+1]}<<(count+1);
        reg2<=reg2 + {4'd0,m[count+1]}<<(count+1);
        mult<=reg2 + {4'd0,m[count+1]}<<(count+1);
    end
    
  2. 补全所有分支的寄存器赋值,确保每个寄存器在所有条件下都有明确操作:
    else if(count==4'd3) begin
        count<=0;
        reg1<=reg1;
        reg2<=reg2;
        mult<=reg2;
    end
    

修复后的核心时序块示例:

always@(posedge clk) begin
    if(load) begin
        reg1<=0;
        count<=0;
        reg2<={4'd0,m[0]};
        mult<=0;
    end
    else if(count==4'd3) begin
        count<=0;
        reg1<=reg1;
        reg2<=reg2;
        mult<=reg2;
    end
    else begin
        count<=count+1;
        if(b[count+1]==1'b1) begin
            reg1<={4'd0,m[count+1]}<<(count+1);
            reg2<=reg2 + {4'd0,m[count+1]}<<(count+1);
            mult<=reg2 + {4'd0,m[count+1]}<<(count+1);
        end
        else begin
            reg1<=reg1;
            reg2<=reg2;
            mult<=reg2;
        end
    end
end

内容的提问来源于stack exchange,提问作者Johonathan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 06:04:54