我在system-verilog中有一个32x32的乘法器,还有一台fsm风格的机器,基本上可以像在学校一样做长乘法。
我两天前测试过了,它工作得很好。但是,突然,甚至没有更改代码,其中一个输出就无缘无故地停留在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,尽管您可以看到加法器值发生了变化。

编辑:代码的其余部分(fsm和tb)
FSM部件:
// 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组合机:
// 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测试工作台:
// 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发布于 2021-01-05 02:21:38
你的逻辑里有个bug。您的代码始终至少执行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这使upd优先于clr (如果这是您的意图)。
https://stackoverflow.com/questions/65567583
复制相似问题