cvw/wally-pipelined/src/muldiv/mult_cs.sv

89 lines
2.4 KiB
Systemverilog
Raw Normal View History

module mult_cs #(parameter WIDTH = 8)
(a, b, tc, sum, carry);
input logic [WIDTH-1:0] a;
input logic [WIDTH-1:0] b;
input logic tc;
output logic [2*WIDTH-1:0] sum, carry;
// PP array
logic [2*WIDTH-1:0] pp_array [0:WIDTH-1];
logic [2*WIDTH-1:0] tmp_sum, tmp_carry;
logic [2*WIDTH-1:0] a_padded;
logic [2*WIDTH-1:0] b_padded;
logic [2*WIDTH-1:0] product;
assign a_padded = a;
assign b_padded = b;
always_comb
begin
logic [2*WIDTH-1:0] temp_pp_array [0 : WIDTH-1];
logic [2*WIDTH-1:0] next_pp_array [0 : WIDTH-1];
logic [2*WIDTH-1:0] temp_pp;
logic [2*WIDTH-1:0] tmp_pp_carry;
logic [WIDTH+2:0] temp_b_padded;
logic temp_bitgroup;
integer bit_pair, pp_count, i;
temp_pp_array[0] = {2*WIDTH{1'b0}};
// For each multiplicand
for (bit_pair=0; bit_pair < WIDTH; bit_pair=bit_pair+1)
begin
// Shift to the right multiplier
temp_b_padded = (b_padded >> (bit_pair));
temp_bitgroup = temp_b_padded[0];
// PP generation
case (temp_bitgroup)
1'b0 :
temp_pp = {2*WIDTH{1'b0}};
1'b1 :
temp_pp = a_padded;
default : temp_pp = {2*WIDTH{1'b0}};
endcase
// Shift to the left via P&H
temp_pp = temp_pp << (bit_pair);
temp_pp_array[bit_pair] = temp_pp;
end
pp_count = WIDTH;
// Wallace Tree (I do not think this is really a Wallace tree (misses HA))
while (pp_count > 2)
begin
for (i=0 ; i < (pp_count/3) ; i = i+1)
begin
next_pp_array[i*2] = temp_pp_array[i*3]^temp_pp_array[i*3+1]^temp_pp_array[i*3+2];
tmp_pp_carry = (temp_pp_array[i*3] & temp_pp_array[i*3+1]) |
(temp_pp_array[i*3+1] & temp_pp_array[i*3+2]) |
(temp_pp_array[i*3] & temp_pp_array[i*3+2]);
next_pp_array[i*2+1] = tmp_pp_carry << 1;
end
if ((pp_count % 3) > 0)
begin
for (i=0 ; i < (pp_count % 3) ; i=i+1)
next_pp_array[2 * (pp_count/3) + i] = temp_pp_array[3 * (pp_count/3) + i];
end
for (i=0 ; i < WIDTH ; i=i+1)
temp_pp_array[i] = next_pp_array[i];
pp_count = pp_count - (pp_count/3);
end
tmp_sum = temp_pp_array[0];
if (pp_count > 1)
tmp_carry = temp_pp_array[1];
else
tmp_carry = {2*WIDTH{1'b0}};
end
assign sum = tmp_sum;
assign carry = tmp_carry;
endmodule // mult_cs