diff options
| author | 2022-10-29 22:20:15 -0400 | |
|---|---|---|
| committer | 2022-10-29 22:20:15 -0400 | |
| commit | 89acb17aa0ea50980a680c6fd7c30a05103e09bb (patch) | |
| tree | b374ffcb1cfe98116bc0e329534390b1d80b518b /boothmul.v | |
| parent | write arty SoC generator (diff) | |
succesfully synthesize design
Diffstat (limited to 'boothmul.v')
| -rw-r--r-- | boothmul.v | 59 |
1 files changed, 42 insertions, 17 deletions
@@ -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; |
