Architecture 1
`timescale 1ns / 1ps
module proposed_8x8_signed_multiplier_radix8 (
input [7:0] A,
input [7:0] B,
output [15:0] Z
);
// Sign determination
wire sign = A[7] ^ B[7];
// Magnitude calculation using B2C (two's complement negation for negatives)
wire [7:0] A_neg = ~A + 8'd1;
wire [7:0] B_neg = ~B + 8'd1;
wire [7:0] Ap = A[7] ? A_neg : A;
wire [7:0] Bp = B[7] ? B_neg : B;
// Special case for maximum magnitude (B = -128)
wire special = (Bp == 8'b10000000); // MSB=1 and others=0 for 8-bit
// X is the magnitude of A
wire [7:0] X = Ap;
wire [7:0] Ac = ~Ap + 8'd1; // Complement for special case
// Precomputation of non-trivial multiples (NT block)
// Extend to 10 bits to handle carry
wire [9:0] XX = {2'b00, X}; // 1X
wire [9:0] X2 = {1'b0, X, 1'b0}; // 2X
wire [9:0] X4 = {X, 2'b00}; // 4X
// Use adders for NT: P=3X, Q=5X, R=7X
wire [9:0] P = XX + X2; // 3X = 1X + 2X
wire [9:0] Q = XX + X4; // 5X = 1X + 4X
wire [9:0] R = X4 + X2 + XX; // 7X = 4X + 2X + 1X
wire [9:0] S1 = {P[8:0], 1'b0}; // 6X = 3X << 1 (no extra computation)
// 8:1 MUX for lower 3-bit group Bp[2:0]
reg [9:0] pp0;
always @(*) begin
case (Bp[2:0])
3'b000: pp0 = 10'b0; // 0
3'b001: pp0 = XX; // 1X
3'b010: pp0 = X2; // 2X
3'b011: pp0 = P; // 3X
3'b100: pp0 = X4; // 4X
3'b101: pp0 = Q; // 5X
3'b110: pp0 = S1; // 6X
3'b111: pp0 = R; // 7X
default: pp0 = 10'b0;
endcase
end
// 8:1 MUX for middle 3-bit group Bp[5:3]
reg [9:0] pp1;
always @(*) begin
case (Bp[5:3])
3'b000: pp1 = 10'b0; // 0
3'b001: pp1 = XX; // 1X
3'b010: pp1 = X2; // 2X
3'b011: pp1 = P; // 3X
3'b100: pp1 = X4; // 4X
3'b101: pp1 = Q; // 5X
3'b110: pp1 = S1; // 6X
3'b111: pp1 = R; // 7X
default: pp1 = 10'b0;
endcase
end
// Partial product for MSB bit Bp[6]
wire [14:0] pp2 = Bp[6] ? {X[7:0], 6'b000000} : 15'b0; // X << 6 if Bp[6]=1
// Stage 1: Sum pp0 + (pp1 << 3)
// To match the figure's optimized reduction with BEC and SQCS CLA, but here using behavioral +
// In synthesis, this can be mapped to specific adders
wire [12:0] pp1_shift = {pp1, 3'b000}; // pp1 << 3, 13 bits
wire [12:0] sum_stage1 = pp0 + pp1_shift; // 13-bit sum
// Extend for full addition
wire [14:0] sum_stage1_ext = {2'b00, sum_stage1};
// Stage 2: Add the third PP (pp2)
wire [14:0] product_mag = sum_stage1_ext + pp2;
// Handle special case: If B=-128 (max neg), product = A * (-128) = - (A << 7), but since signed,
magnitude X << 7, but adjusted
// In paper: Left shift Ac by N-1=7 bits
wire [14:0] special_mag = {Ac, 7'b0000000}; // Ac << 7
wire [14:0] mag = special ? special_mag : product_mag;
// Final product: Apply sign
wire [15:0] pos_prod = {1'b0, mag}; // Unsigned magnitude to 16-bit
wire [15:0] neg_prod = ~pos_prod + 16'd1; // Two's complement for negative
assign Z = sign ? neg_prod : pos_prod;
endmodule
module tb_proposed_8x8_signed_multiplier_radix8;
reg [7:0] A;
reg [7:0] B;
wire [15:0] Z;
proposed_8x8_signed_multiplier_radix8 dut (
.A(A),
.B(B),
.Z(Z)
);
initial begin
// Test 1: A=-5, B=6, Expected=-30
A = 8'b11111011; B = 8'b00000110; #10;
$display("Test 1: A=%d (%b), B=%d (%b), Z=%d (%b)", $signed(A), A, $signed(B), B, $signed(Z), Z);
// Test 2: A=5, B=6, Expected=30
A = 8'b00000101; B = 8'b00000110; #10;
$display("Test 2: A=%d (%b), B=%d (%b), Z=%d (%b)", $signed(A), A, $signed(B), B, $signed(Z), Z);
// Test 3: A=5, B=-6, Expected=-30
A = 8'b00000101; B = 8'b11111010; #10;
$display("Test 3: A=%d (%b), B=%d (%b), Z=%d (%b)", $signed(A), A, $signed(B), B, $signed(Z), Z);
// Test 4: A=-5, B=-6, Expected=30
A = 8'b11111011; B = 8'b11111010; #10;
$display("Test 4: A=%d (%b), B=%d (%b), Z=%d (%b)", $signed(A), A, $signed(B), B, $signed(Z), Z);
// Test 5: A=0, B=10, Expected=0
A = 8'b00000000; B = 8'b00001010; #10;
$display("Test 5: A=%d (%b), B=%d (%b), Z=%d (%b)", $signed(A), A, $signed(B), B, $signed(Z), Z);
// Test 6: A=127, B=1, Expected=127
A = 8'b01111111; B = 8'b00000001; #10;
$display("Test 6: A=%d (%b), B=%d (%b), Z=%d (%b)", $signed(A), A, $signed(B), B, $signed(Z), Z);
// Test 7: A=-128, B=1, Expected=-128
A = 8'b10000000; B = 8'b00000001; #10;
$display("Test 7: A=%d (%b), B=%d (%b), Z=%d (%b)", $signed(A), A, $signed(B), B, $signed(Z), Z);
// Test 8: A=1, B=-128, Expected=-128
A = 8'b00000001; B = 8'b10000000; #10;
$display("Test 8: A=%d (%b), B=%d (%b), Z=%d (%b)", $signed(A), A, $signed(B), B, $signed(Z), Z);
// Test 9: A=127, B=127, Expected=16129
A = 8'b01111111; B = 8'b01111111; #10;
$display("Test 9: A=%d (%b), B=%d (%b), Z=%d (%b)", $signed(A), A, $signed(B), B, $signed(Z), Z);
// Test 10: A=3, B=7, Expected=21
A = 8'b00000011; B = 8'b00000111; #10;
$display("Test 10: A=%d (%b), B=%d (%b), Z=%d (%b)", $signed(A), A, $signed(B), B, $signed(Z), Z);
end
endmodule