aboutsummaryrefslogtreecommitdiff
path: root/src/rtl/modexpa7_wrapper.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/rtl/modexpa7_wrapper.v')
-rw-r--r--src/rtl/modexpa7_wrapper.v130
1 files changed, 88 insertions, 42 deletions
diff --git a/src/rtl/modexpa7_wrapper.v b/src/rtl/modexpa7_wrapper.v
index 3b749be..090ea8d 100644
--- a/src/rtl/modexpa7_wrapper.v
+++ b/src/rtl/modexpa7_wrapper.v
@@ -35,7 +35,6 @@ module modexpa7_wrapper #
parameter OPERAND_ADDR_WIDTH = 5,
parameter SYSTOLIC_ARRAY_POWER = 2
)
-
(
input clk,
input rst_n,
@@ -62,7 +61,7 @@ module modexpa7_wrapper #
/*
* Output Mux
*/
- wire [31: 0] read_data_regs;
+ reg [31: 0] read_data_regs;
wire [31: 0] read_data_core;
@@ -75,27 +74,31 @@ 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_MODE = 'h10; // {crt, dummy}
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 [OPERAND_ADDR_WIDTH+1:0] ADDR_ARRAY_BITS = 'h14; // number of bits in systolic array
localparam CONTROL_INIT_BIT = 0;
localparam CONTROL_NEXT_BIT = 1;
localparam STATUS_READY_BIT = 0;
- localparam STATUS_VALID_BIT = 1;
+ localparam STATUS_VALID_BIT = 1;
+
+ localparam MODE_DUMMY_BIT = 0;
+ localparam MODE_CRT_BIT = 1;
localparam CORE_NAME0 = 32'h6D6F6465; // "mode"
localparam CORE_NAME1 = 32'h78706137; // "xpa7"
- localparam CORE_VERSION = 32'h302E3230; // "0.10"
+ localparam CORE_VERSION = 32'h302E3230; // "0.20"
/*
* Registers
*/
- reg [ 1:0] reg_control;
+ reg [ 1:0] reg_control;
+ reg [ 1:1] reg_mode;
reg [OPERAND_ADDR_WIDTH+5:0] reg_modulus_bits;
reg [OPERAND_ADDR_WIDTH+5:0] reg_exponent_bits;
@@ -142,34 +145,53 @@ module modexpa7_wrapper #
.bus_data_wr (write_data),
.bus_data_rd (read_data_core)
);
-
-
- /*
- * Read Latch
- */
-
- reg [31: 0] read_data_regs;
/*
* Write Checker
*/
-
- // largest supported operand width
- localparam [OPERAND_ADDR_WIDTH+5:0] BUFFER_BITS = {1'b1, {OPERAND_ADDR_WIDTH+4{1'b0}}};
+
+ // largest supported operand width
+ localparam [OPERAND_ADDR_WIDTH+5:0] EXPONENT_MIN_BITS = {{OPERAND_ADDR_WIDTH+4{1'b0}}, 2'b10};
+ localparam [OPERAND_ADDR_WIDTH+5:0] EXPONENT_MAX_BITS = {1'b1, {OPERAND_ADDR_WIDTH+5{1'b0}}};
+
+ localparam [OPERAND_ADDR_WIDTH+5:0] MODULUS_MIN_BITS = {{OPERAND_ADDR_WIDTH-1{1'b0}}, 7'b1000000};
+ localparam [OPERAND_ADDR_WIDTH+5:0] MODULUS_MAX_BITS = {1'b1, {OPERAND_ADDR_WIDTH+5{1'b0}}};
- // check_modulus_bits
+ //
+ // Limits on modulus_bits:
+ //
+ // Must be 64 .. BUFFER_BITS in steps of 32
+ //
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;
- //
+
+ // store input value
+ check_modulus_bits = num_bits;
+
+ // must be multiple of 32
+ check_modulus_bits[4:0] = {5{1'b0}};
+ if (check_modulus_bits < num_bits)
+ check_modulus_bits = check_modulus_bits + 6'd32;
+
+ // too large?
+ if (check_modulus_bits > MODULUS_MAX_BITS)
+ check_modulus_bits = MODULUS_MAX_BITS;
+
+ // too small?
+ if (check_modulus_bits < MODULUS_MIN_BITS)
+ check_modulus_bits = MODULUS_MIN_BITS;
+
end
endfunction
+ //
+ // Limits on exponent_bits:
+ //
+ // Must be 2 .. BUFFER_BITS;
+ //
+ //
function [OPERAND_ADDR_WIDTH+5:0] check_exponent_bits;
input [OPERAND_ADDR_WIDTH+5:0] num_bits;
begin
@@ -178,12 +200,12 @@ module modexpa7_wrapper #
check_exponent_bits = num_bits;
// too large?
- if (num_bits > BUFFER_BITS)
- check_exponent_bits = BUFFER_BITS;
+ if (check_exponent_bits > EXPONENT_MAX_BITS)
+ check_exponent_bits = EXPONENT_MAX_BITS;
// too small?
- if (num_bits == {OPERAND_ADDR_WIDTH+5{1'b0}})
- num_bits = {{OPERAND_ADDR_WIDTH+4{1'b0}}, 1'b1};
+ if (check_exponent_bits < EXPONENT_MIN_BITS)
+ check_exponent_bits = EXPONENT_MIN_BITS;
//
end
@@ -194,9 +216,24 @@ module modexpa7_wrapper #
* Internal Quantities Generator
*/
- function [OPERAND_ADDR_WIDTH-1:0] modulus_num_words_core;
- input [OPERAND_ADDR_WIDTH+5:0] num_bits;
+
+ function [OPERAND_ADDR_WIDTH-1:0] get_modulus_num_words_core;
+ input [OPERAND_ADDR_WIDTH+5:0] num_bits;
+ reg [OPERAND_ADDR_WIDTH+5:0] num_words_checked;
begin
+
+ // check number of bits
+ num_words_checked = check_modulus_bits(num_bits);
+
+ // reduce by 1
+ num_words_checked = {{5{1'b0}}, num_words_checked[OPERAND_ADDR_WIDTH+5:5]};
+
+ // reduce by 1
+ num_words_checked = num_words_checked - 1'b1;
+
+ // return
+ get_modulus_num_words_core = num_words_checked[OPERAND_ADDR_WIDTH-1:0];
+
end
endfunction
@@ -205,14 +242,19 @@ module modexpa7_wrapper #
reg [OPERAND_ADDR_WIDTH+5:0] num_bits_checked;
begin
- // check number of bits (not too large, not too small)
+ // check number of bits
num_bits_checked = check_exponent_bits(num_bits);
- // de
+ // reduce by 1
+ num_bits_checked = num_bits_checked - 1'b1;
+
+ // return
+ get_exponent_num_bits_core = num_bits_checked[OPERAND_ADDR_WIDTH+4:0];
+
end
endfunction
-
+
/*
* Write Interface (External Registers)
*/
@@ -229,7 +271,8 @@ module modexpa7_wrapper #
//
case (address_lsb)
//
- ADDR_CONTROL: reg_control <= write_data[ 1: 0];
+ ADDR_CONTROL: reg_control <= write_data[ 1: 0];
+ ADDR_MODE: reg_mode <= write_data[MODE_CRT_BIT];
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]);
//
@@ -265,17 +308,20 @@ module modexpa7_wrapper #
//
case (address_lsb)
//
- ADDR_NAME0: tmp_read_data <= CORE_NAME0;
- ADDR_NAME1: tmp_read_data <= CORE_NAME1;
- ADDR_VERSION: tmp_read_data <= CORE_VERSION;
+ ADDR_NAME0: read_data_regs <= CORE_NAME0;
+ ADDR_NAME1: read_data_regs <= CORE_NAME1;
+ ADDR_VERSION: read_data_regs <= CORE_VERSION;
- ADDR_CONTROL: tmp_read_data <= {{30{1'b0}}, reg_control};
- ADDR_STATUS: tmp_read_data <= {{30{1'b0}}, reg_status};
+ ADDR_CONTROL: read_data_regs <= {{30{1'b0}}, reg_control};
+ ADDR_MODE: read_data_regs <= {{30{1'b0}}, reg_mode, 1'b0};
+ ADDR_STATUS: read_data_regs <= {{30{1'b0}}, reg_status};
- ADDR_MODULUS_BITS: tmp_read_data <= {{19{1'b0}}, reg_modulus_bits};
- ADDR_EXPONENT_BITS: tmp_read_data <= {{19{1'b0}}, reg_exponent_bits};
+ ADDR_MODULUS_BITS: read_data_regs <= {{19{1'b0}}, reg_modulus_bits};
+ ADDR_EXPONENT_BITS: read_data_regs <= {{19{1'b0}}, reg_exponent_bits};
+ ADDR_BUFFER_BITS: read_data_regs <= {{26-OPERAND_ADDR_WIDTH {1'b0}}, 1'b1, { OPERAND_ADDR_WIDTH+5{1'b0}}};
+ ADDR_ARRAY_BITS: read_data_regs <= {{26-SYSTOLIC_ARRAY_POWER{1'b0}}, 1'b1, {SYSTOLIC_ARRAY_POWER+5{1'b0}}};
//
- default: tmp_read_data <= {32{1'b0}};
+ default: read_data_regs <= {32{1'b0}};
//
endcase
@@ -294,7 +340,7 @@ module modexpa7_wrapper #
always @(*)
//
- case (address_msb_last)
+ case (address_msb_dly)
ADDR_MSB_REGS: read_data_mux = read_data_regs;
ADDR_MSB_CORE: read_data_mux = read_data_core;
endcase