I have a 32x32 multiplier in system-verilog with an fsm style machine that basically does long multiplication like in school.
I tested it 2 days ago, and it worked out fine. But, suddenly without even changing the code, one of the outputs just stays put at 0 for no reason. Here is the code:
// 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
For some reason the product output stays at 0 although you can see that the adder value changes.
EDIT: the rest of the code (fsm and tb)
FSM part:
// 32X32 Multiplier FSM
module mult32x32_fsm (
input logic clk, // Clock
input logic reset, // 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
Combined Machine:
// 32X32 Iterative Multiplier template
module mult32x32 (
input logic clk, // Clock
input logic reset, // Reset
input logic start, // Start signal
input logic [31:0] a, // Input a
input logic [31:0] b, // 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),
.clk(clk),
.reset(reset),
.a(a),
.b(b),
.a_sel(a_sel),
.b_sel(b_sel),
.shift_sel(shift_sel),
.upd_prod(upd_prod),
.clr_prod(clr_prod)
);
// End of your code
endmodule
Test Bench:
// 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),
.clk(clk),
.reset(reset),
.start(start),
.a(a),
.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