我是 Verilog 新手,我尝试根据 Robertson 的程序为乘法器制作 FSM,我测试了每个模块并且它们可以工作,但我似乎无法理解它们如何在 FSM 中一起工作
这是代码:
module robertson(
input clk,
input reset,
input [15:0] Q,
input [15:0] M,
output reg [31:0] z
);
parameter STATE_IDLE = 2'b00;
parameter STATE_PROCESS = 2'b01;
parameter STATE_DONE = 2'b10;
reg [1:0] state_reg;
reg [4:0] counter;
reg F;
wire overflow;
reg [15:0] A_reg;
wire [15:0] A_wire;
reg [15:0] Q_reg;
wire [15:0] Q_wire;
wire [15:0] M_neg;
wire [31:0] AQ_wire;
wire [3:0] moved_time_wire;
zero zero_i(.z(moved_time_wire));
noop noop_i(.x(M),.z(M_neg));
shifter shifter_i( .f(F),
.x({A_reg,Q_reg}),
.y(AQ_wire),
.counter(moved_time_wire));
CSkA CSkA_i(
.x(AQ_wire[31:16]),
.y(M),
.c_in(1'b0),
.z(A_wire),
.c_fin(overflow)
);
always @(posedge clk or negedge reset) begin
if (~reset) begin
state_reg <= STATE_IDLE;
counter <= 0;
F = 1'b0;
Q_reg = Q;
A_reg = 16'b0;
end else begin
case(state_reg)
STATE_IDLE: begin
state_reg <= STATE_PROCESS;
end
STATE_PROCESS: begin
if (counter == 15) begin
state_reg <= STATE_DONE;
end
end
STATE_DONE: begin
state_reg <= STATE_IDLE;
end
endcase
end
end
always @(posedge clk) begin
if (state_reg == STATE_PROCESS) begin
if(moved_time_wire != 0) begin
counter <= counter + moved_time_wire;
end
else begin
counter <= counter + 1;
end
A_reg <= A_wire;
Q_reg <= AQ_wire[15:0];
end
end
always @(posedge clk) begin
if (state_reg == STATE_DONE) begin
if(Q_reg[0] == 1'b1) begin
A_reg <= A_reg + M_neg;
Q_reg[0] <= 0;
z <= {A_reg,Q_reg};
end
else begin
z <= {A_reg,Q_reg};
end
end
end
endmodule
当我尝试查看得到的值时,它只是 x 代表 z 的一行,有人可以解释我做错了什么,或者我可以从哪里了解有关如何在 FSM 中使用模块的更多信息吗?
测试台:
module robertson_tb;
reg clk;
reg reset;
reg [15:0] Q;
reg [15:0] M;
wire [31:0] z;
robertson uut (
.clk(clk),
.reset(reset),
.Q(Q),
.M(M),
.z(z)
);
initial begin
Q = 0;
M = 0;
clk = 0;
reset = 1'b1;
#10;
reset = 1'b0;
Q = 16'b0000000000001111;
M = 16'b0000000000000011;
end
always #20 clk = ~clk;
initial begin
$display("Time, Q, M, Z");
repeat (50) begin
#20;
$display("%t, %b, %b, %b", $time, Q, M, z);
end
$finish;
end
endmodule