From f96ad01980fc4d0ed40f6ffb0fbb7c2006421c18 Mon Sep 17 00:00:00 2001 From: "Pavel V. Shatov (Meister)" Date: Sun, 6 Aug 2017 21:46:35 +0300 Subject: * Moved systolic processing element array into a separate module. * Finished top-level wrapper module. --- src/rtl/modexpa7_wrapper.v | 130 ++++++++++++++++++++++++++++++--------------- 1 file changed, 88 insertions(+), 42 deletions(-) (limited to 'src/rtl/modexpa7_wrapper.v') 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 -- cgit v1.2.3