// designed by Sergey Suslov // // pipelined integer multiplier // takes in 2 arguments of adjustable width (parameters op_A_width, op_B_width) // and multiply the first one by the second treating them either signed or unsigned depending on op_type input // with op_B_width clock cycles of initial latency, provided that stall_n signal is deasserted //`include "definitions.v" //`ifndef SYNTHESYS // timeunit `verification_time_unit; // timeprecision `verification_time_resolution; //`endif module mul #( parameter op_A_width=32, parameter op_B_width=op_A_width, parameter rez_width=op_A_width+op_B_width ) ( input bit clk, input bit op_type,//1 - signed, 0 - unsigned input bit signed [op_A_width-1:0] op_A, input bit signed [op_B_width-1:0] op_B, output bit signed [rez_width-1:0] rez, input bit stall_n ); localparam op_Br_width=op_B_width+1; //localparam rez_width=op_A_width+op_B_width; reg signed [rez_width-1:0] op_Ar [op_B_width-1:0]; reg signed [op_Br_width-1:0] op_Br [op_B_width-1:0]; reg signed [rez_width-1:0] rez_r [op_B_width-1:0]; assign rez=rez_r[op_B_width-1]; wire [op_A_width:0]op_A_shifted; wire [op_A_width-1:0]op_A_unsigned; assign op_A_unsigned=op_A; assign op_A_shifted[op_A_width:1]=op_A; assign op_A_shifted[0]=0; always_ff @(posedge clk) begin if (stall_n==1'b1) begin if ((op_A[op_A_width-1])&&(op_type==1))for (int k=rez_width-1;k>=rez_width-2;k=k-1)op_Ar[0][k]<=1; else op_Ar[0][rez_width-1:rez_width-2]<=0; op_Ar[0][rez_width-3:op_B_width-2]<=op_A; op_Ar[0][op_B_width-3:0]<=0; op_Br[0][op_B_width:2]<=op_B[op_B_width-2:0]; op_Br[0][1:0]<=0; if ((op_B[op_B_width-1])&&(~op_B[op_B_width-2])) begin if (op_type)rez_r[0][rez_width-1:op_B_width-1]<=0-op_A; else rez_r[0][rez_width-1:op_B_width-1]<=op_A_shifted-op_A; rez_r[0][op_B_width-2:0]<=0; end if ((~op_B[op_B_width-1])&&(op_B[op_B_width-2])) begin if ((op_A[op_A_width-1])&&(op_type==1)) rez_r[0][rez_width-1]<=1; else rez_r[0][rez_width-1]<=0; rez_r[0][rez_width-2:op_B_width-1]<=op_A; rez_r[0][op_B_width-2:0]<=0; end if (~(op_B[op_B_width-1]^op_B[op_B_width-2])) begin if (op_type) begin rez_r[0]<=0; end else begin if (op_B[op_B_width-1]) begin rez_r[0][rez_width-1:op_B_width-1]<=op_A_shifted; rez_r[0][op_B_width-2:0]<=0; end else rez_r[0]<=0; end end for (int k=0; k>>1; op_Br[k+1]<=op_Br[k]<<1; if ((op_Br[k][op_B_width])&&(~op_Br[k][op_B_width-1])) rez_r[k+1]<=rez_r[k]-op_Ar[k]; if ((~op_Br[k][op_B_width])&&(op_Br[k][op_B_width-1])) rez_r[k+1]<=rez_r[k]+op_Ar[k]; if (~(op_Br[k][op_B_width]^op_Br[k][op_B_width-1])) rez_r[k+1]<=rez_r[k]; end //pipeline_stage_forwarding(op_Ar[k],op_Br[k],op_Ar[k+1],op_Br[k+1],rez_r[k],rez_r[k+1]); end end endmodule