Added mul tb and fixed

This commit is contained in:
Joppe Blondel
2025-10-19 16:18:40 +02:00
parent eb7caaf2c5
commit b2858ac5ee
5 changed files with 136 additions and 17 deletions

View File

@@ -17,11 +17,11 @@ module mul_const_shiftadd#(
input wire signed [W-1:0] x,
output wire signed [2*W-1:0] y
);
// Absolute value and sign of C
localparam integer C_NEG = (C < 0) ? 1 : 0;
localparam integer C_ABS = (C < 0) ? -C : C;
// Sign and magnitude of constant
localparam integer C_NEG = (C < 0) ? 1 : 0;
localparam integer C_ABS = (C < 0) ? -C : C;
// Find MSB index of C_ABS to size the network
// MSB index of |C| (0-based). Keeps network minimal.
function integer msb_index;
input integer v;
integer i;
@@ -31,19 +31,26 @@ module mul_const_shiftadd#(
if (v >> i) msb_index = i;
end
endfunction
localparam integer I_MAX = (C_ABS == 0) ? 0 : msb_index(C_ABS);
// Partial products
wire signed [W+I_MAX:0] part [0:I_MAX];
// Width big enough for the largest partial product: W bits shifted by I_MAX
localparam integer PPW = W + I_MAX + 1;
// Pre-extend x to PPW so shifts dont truncate high/sign bits
wire signed [PPW-1:0] x_ext = {{(PPW-W){x[W-1]}}, x};
// Partial products (only where Cs bit is 1)
wire signed [PPW-1:0] part [0:I_MAX];
genvar i;
generate
for (i = 0; i <= I_MAX; i = i + 1) begin : GEN_PARTS
assign part[i] = (C_ABS[i]) ? ($signed(x) <<< i) : { (W+I_MAX+1){1'b0} };
assign part[i] = C_ABS[i] ? (x_ext <<< i) : {PPW{1'b0}};
end
endgenerate
// Adder chain (simple; replace with tree if you want higher performance)
wire signed [W+I_MAX:0] sum [0:I_MAX];
// Adder chain (you can replace with a balanced tree for speed)
wire signed [PPW-1:0] sum [0:I_MAX];
generate
if (I_MAX == 0) begin
assign sum[0] = part[0];
@@ -56,10 +63,9 @@ module mul_const_shiftadd#(
endgenerate
// Apply sign of C
wire signed [W+I_MAX:0] mag = (I_MAX==0) ? part[0] : sum[I_MAX];
wire signed [W+I_MAX:0] prod = C_NEG ? -mag : mag;
// Stretch to fixed y width (truncate/extend as you wish outside)
assign y = prod;
wire signed [PPW-1:0] mag = (I_MAX == 0) ? part[0] : sum[I_MAX];
wire signed [PPW-1:0] prod = C_NEG ? -mag : mag;
// Stretch/extend to 2W result width
assign y = {{((2*W)-PPW){prod[PPW-1]}}, prod};
endmodule