向量的值不会更新

问题描述

我在 system-verilog 中有一个 32x32 乘法器,带有 fsm 风格的机器,基本上可以像在学校一样进行长乘法。

我 2 天前对其进行了测试,结果很好。但是,突然之间甚至没有更改代码,其中一个输出就无缘无故地保持为 0。 代码如下:

// 32X32 Multiplier arithmetic unit template
module mult32x32_arith (
    input logic clk,// Clock
    input logic reset,// Reset
    input logic [31:0] a,// Input a
    input logic [31:0] b,// Input b
    input logic a_sel,// Select one byte from A
    input logic b_sel,// Select one 2-byte word from B
    input logic [1:0] shift_sel,// Select output from shifter
    input logic upd_prod,// Update the product register
    input logic clr_prod,// Clear the product register
    output logic [63:0] product  // Miltiplication product
);

// Put your code here
// ------------------
logic [15:0] mux2to1a;
logic [15:0] mux2to1b;
logic [31:0] mul;
logic [63:0] shift0;
logic [63:0] shift16;
logic [63:0] shift32;
logic [63:0] mux4to1;
logic [63:0] adder;
always_comb begin
    if(a_sel==1'b1)begin
         mux2to1a=a[31:16];
    end
    else begin
         mux2to1a=a[15:0];
    end
    
    if(b_sel==1'b1)begin
         mux2to1b=b[31:16];
    end
    else begin
         mux2to1b=b[15:0];
    end
    
    mul=mux2to1a*mux2to1b;
    
    shift0=mul;
    
    shift16= mul << 16;
    shift32= mul << 32;
    
    if(shift_sel[0]==1'b0&&shift_sel[1]==1'b0)begin
        mux4to1=shift0;
    end
    else if(shift_sel[0]==1'b1&&shift_sel[1]==1'b0)begin
        mux4to1=shift16;
    end
    else if(shift_sel[0]==1'b0&&shift_sel[1]==1'b1)begin
        mux4to1=shift32;
    end
    else begin
        mux4to1=0;
    end
    
    adder=mux4to1+product;
    
end

always_ff @(posedge clk,posedge reset)begin
                if(reset)begin
                    product<=0;
                end
                
                else begin
                    if(upd_prod==1'b1)begin
                        product<=adder;
                    end
                    else begin
                        product<=product;
                    end     
                    
                    if(clr_prod==1'b1)begin
                        product<=0;
                    end
                    else begin
                        product<=product;
                    end
                end
    end
// End of your code

endmodule

由于某种原因,尽管您可以看到加法器值发生变化,但乘积输出仍为 0。

enter image description here

编辑: 其余代码(fsm 和 tb)

FSM 部分:

// 32X32 Multiplier FSM
module mult32x32_fsm (
    input logic clk,// Reset
    input logic start,// Start signal
    output logic busy,// Multiplier busy indication
    output logic a_sel,// Select one byte from A
    output logic b_sel,// Select one 2-byte word from B
    output logic [1:0] shift_sel,// Select output from shifter
    output logic upd_prod,// Update the product register
    output logic clr_prod         // Clear the product register
);

// Put your code here
// ------------------
typedef enum {idle,a0b0,a0b1,a1b0,a1b1} sm_type;

sm_type current,next;

always_ff @(posedge clk,posedge reset) begin
    if(reset) begin
        current<=idle;
    end
    else begin
        current<=next;
    end
end

always_comb begin
    next=idle;
    busy=1'b1;
    a_sel=1'b0;
    b_sel=1'b0;
    shift_sel={1'b0,1'b1};
    upd_prod=1'b1;
    clr_prod=1'b0;
    case(current)
        idle: if(start==1'b1) begin
                next=a0b0;
                busy=1'b0;
                upd_prod=1'b0;
                clr_prod=1'b1;
            end 
            else begin
                next=idle;
                busy=1'b0;
                upd_prod=1'b0;
            end
        a0b0: begin 
            next=a0b1;
            shift_sel={1'b0,1'b0};
            end
        
        a0b1: begin
            next=a1b0;
            b_sel=1'b1;
            end
        a1b0: begin
            next=a1b1;
            a_sel=1'b1;
            end
        a1b1: begin
            a_sel=1'b1;
            b_sel=1'b1;
            shift_sel={1'b1,1'b0};
            end
    endcase
end
// End of your code

endmodule

组合机:

// 32X32 Iterative Multiplier template
module mult32x32 (
    input logic clk,// Start signal
    input logic [31:0] a,// Input b
    output logic busy,// Multiplier busy indication
    output logic [63:0] product // Miltiplication product
);
// Put your code here
// ------------------
        
 logic a_sel;       
 logic b_sel;         
 logic [1:0] shift_sel; 
 logic upd_prod;      
 logic clr_prod; 
 
mult32x32_fsm fsm(
    .busy(busy),.a_sel(a_sel),.b_sel(b_sel),.shift_sel(shift_sel),.upd_prod(upd_prod),.clr_prod(clr_prod),.clk(clk),.reset(reset),.start(start)
    );
mult32x32_arith arith(
    .product(product),.a(a),.b(b),.clr_prod(clr_prod)
);

// End of your code
endmodule

测试台:

// 32X32 Multiplier test template
module mult32x32_tb;

logic clk;            // Clock
logic reset;          // Reset
logic start;          // Start signal
logic [31:0] a;       // Input a
logic [31:0] b;       // Input b
logic busy;           // Multiplier busy indication
logic [63:0] product; // Miltiplication product

// Put your code here
// ------------------

mult32x32 uut(
    .busy(busy),.product(product),.start(start),.b(b)
);

initial begin
    clk=1'b1;
end
always begin
    #1 clk=~clk;
end

initial begin
    reset=1'b1;
    a=0;
    b=0;
    start=1'b0;
    repeat (4) begin
        @(posedge clk);
    end
    reset=1'b0;
    @(posedge clk);
    a=32'd211578794;
    b=32'd212209639;
    start=1'b1;
    #2;
    start=1'b0;
    @(negedge busy);
end
// End of your code

endmodule

解决方法

你的逻辑有问题。您的代码始终至少执行 2 个 product<=product; 行中的一个,因为它们位于单独的 if/else 语句中。

这有效:

always_ff @(posedge clk,posedge reset) begin
    if (reset) begin
        product<=0;
    end else if (upd_prod) begin
        product<=adder;
    end else if (clr_prod) begin
        product<=0;
    end
end

这将更新优先于 clr(如果这是您的意图)。