aboutsummaryrefslogtreecommitdiffstats
path: root/boothmul.v
diff options
context:
space:
mode:
authorGravatar Peter McGoron @ planck 2022-10-29 22:20:15 -0400
committerGravatar Peter McGoron @ planck 2022-10-29 22:20:15 -0400
commit89acb17aa0ea50980a680c6fd7c30a05103e09bb (patch)
treeb374ffcb1cfe98116bc0e329534390b1d80b518b /boothmul.v
parentwrite arty SoC generator (diff)
succesfully synthesize design
Diffstat (limited to 'boothmul.v')
-rw-r--r--boothmul.v59
1 files changed, 42 insertions, 17 deletions
diff --git a/boothmul.v b/boothmul.v
index 0962b78..0c955d6 100644
--- a/boothmul.v
+++ b/boothmul.v
@@ -1,3 +1,4 @@
+`define DEBUG
/* Booth Multiplication v0.1
* Written by Peter McGoron, 2022.
*
@@ -29,6 +30,12 @@ module boothmul
input [A1_LEN-1:0] a1,
input [A2_LEN-1:0] a2,
output [A1_LEN+A2_LEN-1:0] outn,
+`ifdef DEBUG
+ output [A1_LEN+A2_LEN+1:0] debug_a,
+ output [A1_LEN+A2_LEN+1:0] debug_s,
+ output [A1_LEN+A2_LEN+1:0] debug_p,
+ output [A2LEN_SIZ-1:0] debug_state,
+`endif
output reg fin
);
@@ -36,8 +43,8 @@ module boothmul
* Booth Parameters
**********************/
-localparam OUT_LEN = A1_LEN + A2_LEN;
-localparam REG_LEN = OUT_LEN + 2;
+`define OUT_LEN (A1_LEN + A2_LEN)
+`define REG_LEN (`OUT_LEN + 2)
/* The Booth multiplication algorithm is a sequential algorithm for
* twos-compliment integers.
@@ -63,11 +70,26 @@ localparam REG_LEN = OUT_LEN + 2;
* [M][ A1_LEN ][ A2_LEN ][0]
*/
-reg signed [REG_LEN-1:0] a;
-reg signed [REG_LEN-1:0] s;
-reg signed [REG_LEN-1:0] p = 0;
+reg [A1_LEN-1:0] a1_reg;
+
+wire [`REG_LEN-1:0] a;
+assign a[A2_LEN:0] = 0;
+assign a[`REG_LEN-2:A2_LEN+1] = a1_reg;
+assign a[`REG_LEN-1] = a1_reg[A1_LEN-1];
+wire signed [`REG_LEN-1:0] a_signed;
+assign a_signed = a;
+
+wire [`REG_LEN-1:0] s;
+assign s[A2_LEN:0] = 0;
+assign s[`REG_LEN-1:A2_LEN+1] = ~{a1_reg[A1_LEN-1],a1_reg} + 1;
+wire signed [`REG_LEN-1:0] s_signed;
+assign s_signed = s;
+
+reg [`REG_LEN-1:0] p;
+wire signed [`REG_LEN-1:0] p_signed;
+assign p_signed = p;
-assign outn[OUT_LEN-1:0] = p[REG_LEN-2:1];
+assign outn = p[`REG_LEN-2:1];
/**********************
* Loop Implementation
@@ -75,6 +97,13 @@ assign outn[OUT_LEN-1:0] = p[REG_LEN-2:1];
reg[A2LEN_SIZ-1:0] loop_accul = 0;
+`ifdef DEBUG
+assign debug_a = a;
+assign debug_s = s;
+assign debug_p = p;
+assign debug_state = loop_accul;
+`endif
+
always @ (posedge clk) begin
if (!arm) begin
loop_accul <= 0;
@@ -82,18 +111,14 @@ always @ (posedge clk) begin
end else if (loop_accul == 0) begin
p[0] <= 0;
p[A2_LEN:1] <= a2;
- p[REG_LEN-1:A2_LEN+1] <= 0;
-
- a[A2_LEN:0] <= 0;
- a[REG_LEN-2:A2_LEN + 1] <= a1;
- a[REG_LEN-1] <= a1[A1_LEN-1]; // Sign extension
+ p[`REG_LEN-1:A2_LEN+1] <= 0;
- s[A2_LEN:0] <= 0;
- // Extend before negation to ensure size
- s[REG_LEN-1:A2_LEN+1] <= ~{a1[A1_LEN-1],a1} + 1;
+ a1_reg <= a1;
loop_accul <= loop_accul + 1;
+ /* verilator lint_off WIDTH */
end else if (loop_accul < A2_LEN + 1) begin
+ /* verilator lint_on WIDTH */
/* The loop counter starts from 1, so it must go to
* A2_LEN + 1 exclusive.
* (i = 0; i < len; i++)
@@ -101,9 +126,9 @@ always @ (posedge clk) begin
*/
loop_accul <= loop_accul + 1;
case (p[1:0])
- 2'b00, 2'b11: p <= p >>> 1;
- 2'b10: p <= (p + s) >>> 1;
- 2'b01: p <= (p + a) >>> 1;
+ 2'b00, 2'b11: p <= p_signed >>> 1;
+ 2'b10: p <= (p_signed + s_signed) >>> 1;
+ 2'b01: p <= (p_signed + a_signed) >>> 1;
endcase
end else begin
fin <= 1;