/// This is mostly used for testing the static guarantees currently. /// A realistic implementation would probably take four cycles. module pipelined_mult #( parameter WIDTH = 32 ) ( input wire clk, input wire reset, // inputs input wire [WIDTH-1:0] left, input wire [WIDTH-1:0] right, // The input has been committed output wire [WIDTH-1:0] out ); logic [WIDTH-1:0] buff0, buff1, buff2, buff3, tmp_prod; assign out = buff3; assign tmp_prod = left * right; always_ff @(posedge clk) begin if (reset) begin buff0 <= 0; buff1 <= 0; buff2 <= 0; buff3 <= 0; end else begin buff0 <= tmp_prod; buff1 <= buff0; buff2 <= buff1; buff3 <= buff2; end end endmodule /// module pipelined_fp_smult #( parameter WIDTH = 32, parameter INT_WIDTH = 16, parameter FRAC_WIDTH = 16 )( input wire clk, input wire reset, // inputs input wire [WIDTH-1:0] left, input wire [WIDTH-1:0] right, // The input has been committed output wire [WIDTH-1:0] out ); logic [WIDTH-1:0] lt, rt, buff0, buff1, buff2; logic [(WIDTH << 1) - 1:0] tmp_prod; assign out = buff2; assign tmp_prod = $signed( { {WIDTH{lt[WIDTH-1]}}, lt} * { {WIDTH{rt[WIDTH-1]}}, rt} ); always_ff @(posedge clk) begin if (reset) begin lt <= 0; rt <= 0; buff0 <= 0; buff1 <= 0; buff2 <= 0; end else begin lt <= $signed(left); rt <= $signed(right); buff0 <= tmp_prod[(WIDTH << 1) - INT_WIDTH - 1 : WIDTH - INT_WIDTH]; buff1 <= buff0; buff2 <= buff1; end end endmodule