向量的值不会更新
Value of a vector won't update
我在 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。
编辑:
其余代码(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
你的逻辑有问题。您的代码始终至少执行 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(如果这是您的意图)。
我在 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。
编辑: 其余代码(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
你的逻辑有问题。您的代码始终至少执行 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(如果这是您的意图)。