module multiplier(clk, rst, start, busy, multiplier, multiplicand, product); input clk, rst, start; input [31:0]multiplier; input [31:0]multiplicand; output busy; output [31:0]product; wire loadreg, shiftreg, addreg, count; reg [3:0]state; reg [3:0]next_state; // one-hot encoding parameter not_busy = 1; parameter load_regs = 2; parameter add_regs = 4; parameter shift_regs = 8; reg [31:0]regA; // this is an operand - multiplicand reg [31:0]regB; // this is an operand - multiplier reg [32:0]regC; // this is the partial sum reg [6:0]regD; // this is the counter // control lines assign loadreg = state[1]; assign addreg = state[2]; assign shiftreg = state[3]; assign count = state[3]; // module outputs assign busy = (!state[0]); assign product = regC[31:0]; always @(posedge clk or posedge rst) begin if (rst) regA <= 0; else if (loadreg) regA <= multiplicand; end always @(posedge clk or posedge rst) begin if (rst) regB <= 0; else if (loadreg) regB <= multiplier; else if (shiftreg) regB <= {regC, regB} >> 1; end always @(posedge clk or posedge rst) begin if (rst) regC <= 0; else if (loadreg) regC <= 0; else if (shiftreg) regC <= {regC[32], regC} >> 1; else if (addreg && regB[0]) regC <= regC + regA; end always @(posedge clk or posedge rst) begin if (rst) regD <= 0; else if (loadreg) regD <= 32; else if (count && regD > 0) regD <= regD - 1; end always @(posedge clk or posedge rst) begin if (rst) begin state <= not_busy; next_state <= not_busy; end else state <= next_state; end always @(state, start, regB, count) begin case (state) not_busy : begin if (start) next_state <= load_regs; end load_regs : begin next_state <= add_regs; end add_regs : begin next_state <= shift_regs; end shift_regs : begin if (!regD) next_state <= not_busy; else next_state <= add_regs; end default: next_state <= not_busy; endcase end endmodule module testbench; // The following code will generate a VCD file containing // all of the nets in the instance t.uut. "t" is the module name of the // testfixture, "uut" is the instance name // of the design being tested. reg clk, rst, start; reg [31:0]multiplier; reg [31:0]multiplicand; wire [31:0]product; wire busy; initial begin // Change filename as appropriate. $dumpfile("mult1.vcd"); $dumpvars(1, testbench.uut); // testbench code goes here $display("starting reset"); clk = 0; rst = 0; start = 0; multiplier = 0; multiplicand = 0; #10; rst = 1; #40; rst = 0; $display("reset done"); @(posedge clk && !busy); $display("starting multiply"); multiplier = 8; multiplicand = 22; start = 1; @(posedge busy); $display("busy is high"); start = 0; multiplier = 0; multiplicand = 0; @(negedge busy); $display("busy is low"); $finish; end always #10 begin clk = ~clk; end multiplier uut (clk, rst, start, busy, multiplier, multiplicand, product); endmodule