aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2017-07-25 01:21:28 +0300
committerPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2017-07-25 01:21:28 +0300
commitbd6c4a9b916cd36890ebec72fae50555dfe6e7ba (patch)
tree9ab163d65bbd0c90f016abe4325685fb463d0b5c
parentc4326507c85196bd30adb4d20ce07448a8306066 (diff)
Trying to fix the bug during calculation of SN in systolic multiplier.
-rw-r--r--src/rtl/modexpa7_simple_fifo.v141
-rw-r--r--src/rtl/modexpa7_systolic_multiplier.v51
-rw-r--r--src/rtl/modexpa7_wrapper.v73
-rw-r--r--src/rtl/pe/modexpa7_primitive_switch.v2
-rw-r--r--src/tb/tb_exponentiator.v2
-rw-r--r--src/tb/tb_systolic_multiplier.v6
-rw-r--r--src/tb/tb_wrapper.v44
7 files changed, 124 insertions, 195 deletions
diff --git a/src/rtl/modexpa7_simple_fifo.v b/src/rtl/modexpa7_simple_fifo.v
index 1580e38..5f61d13 100644
--- a/src/rtl/modexpa7_simple_fifo.v
+++ b/src/rtl/modexpa7_simple_fifo.v
@@ -45,8 +45,8 @@ module modexpa7_simple_fifo #
//
always @(posedge clk)
//
- if (rst) ptr_wr <= PTR_ZERO;
- else if (wr_en) ptr_wr <= ptr_wr + 1'b1;
+ if (wr_en) ptr_wr <= ptr_wr + 1'b1;
+ else if (rst) ptr_wr <= PTR_ZERO;
//
// Read Pointer
@@ -69,142 +69,7 @@ module modexpa7_simple_fifo #
//
always @(posedge clk)
//
- if (!rst && wr_en) fifo[ptr_wr] <= d_in;
+ if (wr_en) fifo[ptr_wr] <= d_in;
-/*
-generic_dpram #(aw,dw) u0(
- .rclk( clk ),
- .rrst( !rst ),
- .rce( 1'b1 ),
- .oe( 1'b1 ),
- .raddr( rp ),
- .do( dout ),
- .wclk( clk ),
- .wrst( !rst ),
- .wce( 1'b1 ),
- .we( we ),
- .waddr( wp ),
- .di( din )
- );
-
-////////////////////////////////////////////////////////////////////
-//
-// Misc Logic
-//
-
-always @(posedge clk `SC_FIFO_ASYNC_RESET)
- if(!rst) wp <= #1 {aw{1'b0}};
- else
- if(clr) wp <= #1 {aw{1'b0}};
- else
- if(we) wp <= #1 wp_pl1;
-
-assign wp_pl1 = wp + { {aw-1{1'b0}}, 1'b1};
-assign wp_pl2 = wp + { {aw-2{1'b0}}, 2'b10};
-
-always @(posedge clk `SC_FIFO_ASYNC_RESET)
- if(!rst) rp <= #1 {aw{1'b0}};
- else
- if(clr) rp <= #1 {aw{1'b0}};
- else
- if(re) rp <= #1 rp_pl1;
-
-assign rp_pl1 = rp + { {aw-1{1'b0}}, 1'b1};
-
-////////////////////////////////////////////////////////////////////
-//
-// Combinatorial Full & Empty Flags
-//
-
-assign empty = ((wp == rp) & !gb);
-assign full = ((wp == rp) & gb);
-
-// Guard Bit ...
-always @(posedge clk `SC_FIFO_ASYNC_RESET)
- if(!rst) gb <= #1 1'b0;
- else
- if(clr) gb <= #1 1'b0;
- else
- if((wp_pl1 == rp) & we) gb <= #1 1'b1;
- else
- if(re) gb <= #1 1'b0;
-
-////////////////////////////////////////////////////////////////////
-//
-// Registered Full & Empty Flags
-//
-
-// Guard Bit ...
-always @(posedge clk `SC_FIFO_ASYNC_RESET)
- if(!rst) gb2 <= #1 1'b0;
- else
- if(clr) gb2 <= #1 1'b0;
- else
- if((wp_pl2 == rp) & we) gb2 <= #1 1'b1;
- else
- if((wp != rp) & re) gb2 <= #1 1'b0;
-
-always @(posedge clk `SC_FIFO_ASYNC_RESET)
- if(!rst) full_r <= #1 1'b0;
- else
- if(clr) full_r <= #1 1'b0;
- else
- if(we & ((wp_pl1 == rp) & gb2) & !re) full_r <= #1 1'b1;
- else
- if(re & ((wp_pl1 != rp) | !gb2) & !we) full_r <= #1 1'b0;
-
-always @(posedge clk `SC_FIFO_ASYNC_RESET)
- if(!rst) empty_r <= #1 1'b1;
- else
- if(clr) empty_r <= #1 1'b1;
- else
- if(we & ((wp != rp_pl1) | gb2) & !re) empty_r <= #1 1'b0;
- else
- if(re & ((wp == rp_pl1) & !gb2) & !we) empty_r <= #1 1'b1;
-
-////////////////////////////////////////////////////////////////////
-//
-// Combinatorial Full_n & Empty_n Flags
-//
-
-assign empty_n = cnt < n;
-assign full_n = !(cnt < (max_size-n+1));
-assign level = {2{cnt[aw]}} | cnt[aw-1:aw-2];
-
-// N entries status
-always @(posedge clk `SC_FIFO_ASYNC_RESET)
- if(!rst) cnt <= #1 {aw+1{1'b0}};
- else
- if(clr) cnt <= #1 {aw+1{1'b0}};
- else
- if( re & !we) cnt <= #1 cnt + { {aw{1'b1}}, 1'b1};
- else
- if(!re & we) cnt <= #1 cnt + { {aw{1'b0}}, 1'b1};
-
-////////////////////////////////////////////////////////////////////
-//
-// Registered Full_n & Empty_n Flags
-//
-
-always @(posedge clk `SC_FIFO_ASYNC_RESET)
- if(!rst) empty_n_r <= #1 1'b1;
- else
- if(clr) empty_n_r <= #1 1'b1;
- else
- if(we & (cnt >= (n-1) ) & !re) empty_n_r <= #1 1'b0;
- else
- if(re & (cnt <= n ) & !we) empty_n_r <= #1 1'b1;
-
-always @(posedge clk `SC_FIFO_ASYNC_RESET)
- if(!rst) full_n_r <= #1 1'b0;
- else
- if(clr) full_n_r <= #1 1'b0;
- else
- if(we & (cnt >= (max_size-n) ) & !re) full_n_r <= #1 1'b1;
- else
- if(re & (cnt <= (max_size-n+1)) & !we) full_n_r <= #1 1'b0;
-*/
-
-
endmodule
diff --git a/src/rtl/modexpa7_systolic_multiplier.v b/src/rtl/modexpa7_systolic_multiplier.v
index 378dc63..f53354e 100644
--- a/src/rtl/modexpa7_systolic_multiplier.v
+++ b/src/rtl/modexpa7_systolic_multiplier.v
@@ -49,7 +49,7 @@ module modexpa7_systolic_multiplier #
//
// Explain.
//
- parameter SYSTOLIC_ARRAY_POWER = 2
+ parameter SYSTOLIC_ARRAY_POWER = 1
)
(
input clk,
@@ -597,12 +597,13 @@ module modexpa7_systolic_multiplier #
//
// Systolic Array of Processing Elements
//
- reg [31: 0] pe_a [0:SYSTOLIC_ARRAY_LENGTH-1];
- reg [31: 0] pe_b [0:SYSTOLIC_ARRAY_LENGTH-1];
- wire [31: 0] pe_t [0:SYSTOLIC_ARRAY_LENGTH-1];
- wire [31: 0] pe_c_in [0:SYSTOLIC_ARRAY_LENGTH-1];
- wire [31: 0] pe_p [0:SYSTOLIC_ARRAY_LENGTH-1];
- wire [31: 0] pe_c_out[0:SYSTOLIC_ARRAY_LENGTH-1];
+ reg [31: 0] pe_a [0:SYSTOLIC_ARRAY_LENGTH-1];
+ reg [31: 0] pe_b [0:SYSTOLIC_ARRAY_LENGTH-1];
+ wire [31: 0] pe_t [0:SYSTOLIC_ARRAY_LENGTH-1];
+ wire [31: 0] pe_c_in [0:SYSTOLIC_ARRAY_LENGTH-1];
+ wire [31: 0] pe_p [0:SYSTOLIC_ARRAY_LENGTH-1];
+ wire [31: 0] pe_c_out [0:SYSTOLIC_ARRAY_LENGTH-1];
+ reg [31: 0] pe_c_out_dly[0:SYSTOLIC_ARRAY_LENGTH-1];
//
@@ -657,34 +658,6 @@ module modexpa7_systolic_multiplier #
.d_out (fifo_t_dout)
);
- /*
- ip_fifo_t fifo_t
- (
- .clk (clk),
- .srst (fifo_t_rst),
- .wr_en (fifo_t_wren),
- .din (fifo_t_din),
- .rd_en (fifo_t_rden),
- .dout (fifo_t_dout),
- .full (),
- .empty ()
- );
- */
-
- /**/
- /*
- ip_fifo_c fifo_c
- (
- .clk (clk),
- .srst (fifo_c_rst),
- .wr_en (fifo_c_wren),
- .din (fifo_c_din),
- .rd_en (fifo_c_rden),
- .dout (fifo_c_dout),
- .full (debug_fifo_full),
- .empty (debug_fifo_empty)
- );*/
-
generate for (i=0; i<SYSTOLIC_ARRAY_LENGTH; i=i+1)
begin : modexpa7_systolic_pe_multiplier
modexpa7_systolic_pe systolic_pe_inst
@@ -699,7 +672,8 @@ module modexpa7_systolic_multiplier #
);
assign pe_c_in[i] = fifo_c_dout[32 * (i + 1) - 1 -: 32];
assign pe_t[i] = fifo_t_dout[32 * (i + 1) - 1 -: 32];
- assign fifo_c_din[32 * (i + 1) - 1 -: 32] = pe_c_out[i];
+ assign fifo_c_din[32 * (i + 1) - 1 -: 32] = pe_c_out_dly[i];
+ always @(posedge clk) pe_c_out_dly[i] <= pe_c_out[i];
end
endgenerate
@@ -814,11 +788,10 @@ module modexpa7_systolic_multiplier #
always @(posedge clk)
shreg_now_unloading_dly <= shreg_now_unloading;
- assign fifo_c_wren = shreg_now_unloading;
+ assign fifo_c_wren = shreg_now_unloading_dly;
assign fifo_c_rden = shreg_now_loading;
- assign fifo_t_wren = shreg_now_unloading_dly;
-
+ assign fifo_t_wren = shreg_now_unloading_dly;
assign fifo_t_rden = shreg_now_loading;
diff --git a/src/rtl/modexpa7_wrapper.v b/src/rtl/modexpa7_wrapper.v
index 35be61e..3b749be 100644
--- a/src/rtl/modexpa7_wrapper.v
+++ b/src/rtl/modexpa7_wrapper.v
@@ -76,9 +76,10 @@ module modexpa7_wrapper #
localparam [OPERAND_ADDR_WIDTH+1:0] ADDR_CONTROL = 'h08; // {next, init}
localparam [OPERAND_ADDR_WIDTH+1:0] ADDR_STATUS = 'h09; // {valid, ready}
// localparam [OPERAND_ADDR_WIDTH+1:0] ADDR_MODE // NOT USED ANYMORE
- localparam [OPERAND_ADDR_WIDTH+1:0] ADDR_MODULUS_BITS = 'h11; //
- localparam [OPERAND_ADDR_WIDTH+1:0] ADDR_EXPONENT_BITS = 'h12; //
- localparam [OPERAND_ADDR_WIDTH+1:0] ADDR_OPERAND_BITS = 'h13; //
+ localparam [OPERAND_ADDR_WIDTH+1:0] ADDR_MODULUS_BITS = 'h11; // number of bits in modulus
+ localparam [OPERAND_ADDR_WIDTH+1:0] ADDR_EXPONENT_BITS = 'h12; // number of bits in exponent
+ localparam [OPERAND_ADDR_WIDTH+1:0] ADDR_BUFFER_BITS = 'h13; // largest supported number of bits
+ localparam [OPERAND_ADDR_WIDTH+1:0] ADDR_ARRAY_BITS = 'h15; // number of bits in systolic array
localparam CONTROL_INIT_BIT = 0;
localparam CONTROL_NEXT_BIT = 1;
@@ -153,21 +154,64 @@ module modexpa7_wrapper #
/*
* Write Checker
*/
-
+
// largest supported operand width
- localparam [OPERAND_ADDR_WIDTH+5:0] MAX_BITS = {1'b1, {OPERAND_ADDR_WIDTH+4{1'b0}}};
+ localparam [OPERAND_ADDR_WIDTH+5:0] BUFFER_BITS = {1'b1, {OPERAND_ADDR_WIDTH+4{1'b0}}};
- // limit operand width to max supported
- function [OPERAND_ADDR_WIDTH+5:0] write_check_bits;
+ // check_modulus_bits
+ function [OPERAND_ADDR_WIDTH+5:0] check_modulus_bits;
input [OPERAND_ADDR_WIDTH+5:0] num_bits;
begin
+ //
+ //t = num_bits[]
+ //if (num_bits > MAX_BITS) write_check_bits = MAX_BITS;
+ //else write_check_bits = num_bits;
//
- if (num_bits > MAX_BITS) write_check_bits = MAX_BITS;
- else write_check_bits = num_bits;
+ end
+ endfunction
+
+ function [OPERAND_ADDR_WIDTH+5:0] check_exponent_bits;
+ input [OPERAND_ADDR_WIDTH+5:0] num_bits;
+ begin
+
+ // store input value
+ check_exponent_bits = num_bits;
+
+ // too large?
+ if (num_bits > BUFFER_BITS)
+ check_exponent_bits = BUFFER_BITS;
+
+ // too small?
+ if (num_bits == {OPERAND_ADDR_WIDTH+5{1'b0}})
+ num_bits = {{OPERAND_ADDR_WIDTH+4{1'b0}}, 1'b1};
+
//
end
endfunction
+
+ /*
+ * Internal Quantities Generator
+ */
+
+ function [OPERAND_ADDR_WIDTH-1:0] modulus_num_words_core;
+ input [OPERAND_ADDR_WIDTH+5:0] num_bits;
+ begin
+ end
+ endfunction
+
+ function [OPERAND_ADDR_WIDTH+4:0] get_exponent_num_bits_core;
+ input [OPERAND_ADDR_WIDTH+5:0] num_bits;
+ reg [OPERAND_ADDR_WIDTH+5:0] num_bits_checked;
+ begin
+
+ // check number of bits (not too large, not too small)
+ num_bits_checked = check_exponent_bits(num_bits);
+
+ // de
+ end
+ endfunction
+
/*
* Write Interface (External Registers)
@@ -186,8 +230,8 @@ module modexpa7_wrapper #
case (address_lsb)
//
ADDR_CONTROL: reg_control <= write_data[ 1: 0];
- ADDR_MODULUS_BITS: reg_modulus_bits <= write_check_bits(write_data[OPERAND_ADDR_WIDTH+5:0]);
- ADDR_EXPONENT_BITS: reg_exponent_bits <= write_check_bits(write_data[OPERAND_ADDR_WIDTH+5:0]);
+ ADDR_MODULUS_BITS: reg_modulus_bits <= check_modulus_bits(write_data[OPERAND_ADDR_WIDTH+5:0]);
+ ADDR_EXPONENT_BITS: reg_exponent_bits <= check_exponent_bits(write_data[OPERAND_ADDR_WIDTH+5:0]);
//
endcase
@@ -202,8 +246,11 @@ module modexpa7_wrapper #
//
case (address_lsb)
//
- ADDR_MODULUS_BITS: modulus_num_words_core <= //modulus_num_words_int;
- ADDR_EXPONENT_BITS: exponent_num_bits_core <= //exponent_num_bits_int;
+ ADDR_MODULUS_BITS: modulus_num_words_core <=
+ get_modulus_num_words_core(write_data[OPERAND_ADDR_WIDTH+5:0]);
+
+ ADDR_EXPONENT_BITS: exponent_num_bits_core <=
+ get_exponent_num_bits_core(write_data[OPERAND_ADDR_WIDTH+5:0]);
//
endcase
diff --git a/src/rtl/pe/modexpa7_primitive_switch.v b/src/rtl/pe/modexpa7_primitive_switch.v
index 3551d7a..d38069b 100644
--- a/src/rtl/pe/modexpa7_primitive_switch.v
+++ b/src/rtl/pe/modexpa7_primitive_switch.v
@@ -1,4 +1,4 @@
-`define USE_VENDOR_PRIMITIVES
+//`define USE_VENDOR_PRIMITIVES
`ifdef USE_VENDOR_PRIMITIVES
diff --git a/src/tb/tb_exponentiator.v b/src/tb/tb_exponentiator.v
index c854e65..c9a9f7e 100644
--- a/src/tb/tb_exponentiator.v
+++ b/src/tb/tb_exponentiator.v
@@ -207,7 +207,7 @@ module tb_exponentiator;
rst_n = 1'b1;
#100;
- test_exponent_384(M_384, D_384, FACTOR_384, N_384, N_COEFF_384, S_384);
+ //test_exponent_384(M_384, D_384, FACTOR_384, N_384, N_COEFF_384, S_384);
test_exponent_512(M_512, D_512, FACTOR_512, N_512, N_COEFF_512, S_512);
end
diff --git a/src/tb/tb_systolic_multiplier.v b/src/tb/tb_systolic_multiplier.v
index 33d1e01..61dc6f3 100644
--- a/src/tb/tb_systolic_multiplier.v
+++ b/src/tb/tb_systolic_multiplier.v
@@ -57,7 +57,7 @@ module tb_systolic_multiplier;
//
// Model Settings
//
- localparam NUM_ROUNDS = 10;
+ localparam NUM_ROUNDS = 43;
//
@@ -152,7 +152,7 @@ module tb_systolic_multiplier;
modexpa7_systolic_multiplier #
(
.OPERAND_ADDR_WIDTH (4), // 32 * (2**4) = 512-bit operands
- .SYSTOLIC_ARRAY_POWER (2) // 2 ** 2 = 4-tap array
+ .SYSTOLIC_ARRAY_POWER (3) // 2 ** 2 = 4-tap array
)
uut
(
@@ -193,7 +193,7 @@ module tb_systolic_multiplier;
#100;
test_systolic_multiplier_384(M_384, N_384, N_COEFF_384, FACTOR_384, COEFF_384);
- test_systolic_multiplier_512(M_512, N_512, N_COEFF_512, FACTOR_512, COEFF_512);
+ //test_systolic_multiplier_512(M_512, N_512, N_COEFF_512, FACTOR_512, COEFF_512);
end
diff --git a/src/tb/tb_wrapper.v b/src/tb/tb_wrapper.v
new file mode 100644
index 0000000..bd8dbf1
--- /dev/null
+++ b/src/tb/tb_wrapper.v
@@ -0,0 +1,44 @@
+`timescale 1ns / 1ps
+
+module tb_wrapper;
+
+ // Inputs
+ reg clk;
+ reg rst_n;
+ reg cs;
+ reg we;
+ reg [7:0] address;
+ reg [31:0] write_data;
+
+ // Outputs
+ wire [31:0] read_data;
+
+ // Instantiate the Unit Under Test (UUT)
+ modexpa7_wrapper uut (
+ .clk(clk),
+ .rst_n(rst_n),
+ .cs(cs),
+ .we(we),
+ .address(address),
+ .write_data(write_data),
+ .read_data(read_data)
+ );
+
+ initial begin
+ // Initialize Inputs
+ clk = 0;
+ rst_n = 0;
+ cs = 0;
+ we = 0;
+ address = 0;
+ write_data = 0;
+
+ // Wait 100 ns for global reset to finish
+ #100;
+
+ // Add stimulus here
+
+ end
+
+endmodule
+