aboutsummaryrefslogtreecommitdiff
path: root/rtl/modexpng_wrapper.v
diff options
context:
space:
mode:
authorPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2019-10-21 15:13:01 +0300
committerPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2019-10-21 15:13:01 +0300
commit584393ac5fc9bbe80887702ec2fc97bee999c5e7 (patch)
treeffda0852ba561ca13ee07ef6147225a38d809151 /rtl/modexpng_wrapper.v
parent69b5d9f65cf49adbc1c1850fa2c4757199008717 (diff)
Further work:
- added core wrapper - fixed module resets across entire core (all the resets are now consistently active-low) - continued refactoring
Diffstat (limited to 'rtl/modexpng_wrapper.v')
-rw-r--r--rtl/modexpng_wrapper.v393
1 files changed, 393 insertions, 0 deletions
diff --git a/rtl/modexpng_wrapper.v b/rtl/modexpng_wrapper.v
new file mode 100644
index 0000000..687a963
--- /dev/null
+++ b/rtl/modexpng_wrapper.v
@@ -0,0 +1,393 @@
+//======================================================================
+//
+// Copyright (c) 2019, NORDUnet A/S All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// - Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// - Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// - Neither the name of the NORDUnet nor the names of its contributors may
+// be used to endorse or promote products derived from this software
+// without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+//======================================================================
+
+module modexpng_wrapper
+(
+ input clk,
+ input rst_n,
+
+ input clk_core,
+
+ input cs,
+ input we,
+
+ input [11:0] address,
+ input [31:0] write_data,
+ output [31:0] read_data
+);
+
+ //
+ // Headers
+ //
+ `include "modexpng_parameters.vh"
+
+
+ //
+ // Address Decoder
+ //
+ localparam ADDR_MSB_WRAP = 2'b00;
+
+ wire [1:0] addr_msb = address[11:10];
+ wire [9:0] addr_lsb = address[ 9: 0];
+
+ wire addr_msb_is_wrap = addr_msb == ADDR_MSB_WRAP;
+
+
+ //
+ // Register Addresses
+ //
+ localparam ADDR_NAME0 = 10'h000;
+ localparam ADDR_NAME1 = 10'h001;
+ localparam ADDR_VERSION = 10'h002;
+
+ localparam ADDR_CONTROL = 10'h008; // {next, init}
+ localparam ADDR_STATUS = 10'h009; // {valid, ready}
+ localparam ADDR_MODE = 10'h010; // {crt, dummy}
+ localparam ADDR_MODULUS_BITS = 10'h011; // number of bits in modulus
+ localparam ADDR_EXPONENT_BITS = 10'h012; // number of bits in exponent
+ localparam ADDR_BANK_BITS = 10'h013; // largest supported number of bits
+ localparam ADDR_NUM_MULTS = 10'h014; // number of parallel multipliers
+
+
+ //
+ // Register Bits
+ //
+
+ // localparam CONTROL_INIT_BIT = 0; -- not used
+ localparam CONTROL_NEXT_BIT = 1;
+
+ // localparam STATUS_READY_BIT = 0; -- hardcoded to always read 1
+ localparam STATUS_VALID_BIT = 1;
+
+ // localparam MODE_FASTUNSAFE_BIT = 0; - not used
+ localparam MODE_FULLCRT_BIT = 1;
+
+
+ //
+ // Default Values
+ //
+ `define MODEXPNG_DEFAULT_NAME0 32'h6D6F6465
+ `define MODEXPNG_DEFAULT_NAME1 32'h78706E67
+ `define MODEXPNG_DEFAULT_VERSION 32'h302E3130
+
+ `define MODEXPNG_DEFAULT_CONTROL 1'b0
+ `define MODEXPNG_DEFAULT_MODE 1'b0
+
+ `define MODEXPNG_DEFAULT_MODULUS_BITS 13'd1024
+ `define MODEXPNG_DEFAULT_EXPONENT_BITS 13'd17
+
+
+ //
+ // Handy Values
+ //
+ localparam MIN_OP_W = 2 * NUM_MULTS * WORD_W * 2;
+ localparam MIN_EXP_W = 2 * 2;
+ localparam ZEROES_BIT_INDEX_W = 1 + cryptech_clog2(NUM_MULTS) + cryptech_clog2(WORD_W);
+
+
+ //
+ // Register Values
+ //
+ localparam CORE_NAME0 = `MODEXPNG_DEFAULT_NAME0; // "mode"
+ localparam CORE_NAME1 = `MODEXPNG_DEFAULT_NAME1; // "xpng"
+ localparam CORE_VERSION = `MODEXPNG_DEFAULT_VERSION; // "0.10"
+
+
+ //
+ // Registers
+ //
+ reg wrap_reg_control = `MODEXPNG_DEFAULT_CONTROL;
+ reg sync_reg_control = `MODEXPNG_DEFAULT_CONTROL;
+ reg sync_reg_control_dly = `MODEXPNG_DEFAULT_CONTROL;
+ reg core_reg_control = `MODEXPNG_DEFAULT_CONTROL;
+ reg wrap_reg_mode = `MODEXPNG_DEFAULT_MODE;
+ reg sync_reg_mode;
+ reg core_reg_mode;
+
+ reg [BIT_INDEX_W:ZEROES_BIT_INDEX_W] wrap_modulus_bits_msb;
+ reg [BIT_INDEX_W: 0] wrap_exponent_bits;
+
+ initial write_modulus_bits(`MODEXPNG_DEFAULT_MODULUS_BITS);
+ initial write_exponent_bits(`MODEXPNG_DEFAULT_EXPONENT_BITS);
+
+ wire sync_reg_control_rising = sync_reg_control & ~sync_reg_control_dly;
+
+
+ //
+ // Wires
+ //
+ reg wrap_reg_status = 1'b1;
+ reg sync_reg_status = 1'b1;
+ wire core_reg_status;
+
+ always @(posedge clk or negedge rst_n)
+ //
+ if (!rst_n) {wrap_reg_status, sync_reg_status} <= { 1'b1, 1'b1};
+ else {wrap_reg_status, sync_reg_status} <= {sync_reg_status, core_reg_status};
+
+
+ //
+ // Output Mux
+ //
+ reg [31: 0] wrap_read_data;
+ wire [31: 0] core_read_data;
+
+
+ //
+ // Reset Resync
+ //
+ wire core_rst_n;
+
+ reg [15: 0] core_rst_shreg = {16{1'b0}};
+
+ always @(posedge clk_core or negedge rst_n)
+ //
+ if (!rst_n) core_rst_shreg <= {16{1'b0}};
+ else core_rst_shreg <= {core_rst_shreg[14:0], 1'b1};
+
+ assign core_rst_n = core_rst_shreg[15];
+
+
+ //
+ // Parameters Resync
+ //
+ reg [OP_ADDR_W -1:0] wrap_word_index_last_n;
+ reg [OP_ADDR_W -1:0] wrap_word_index_last_pq;
+
+ reg [BIT_INDEX_W -1:0] wrap_bit_index_last_n;
+ reg [BIT_INDEX_W -1:0] wrap_bit_index_last_pq;
+
+ reg [OP_ADDR_W -1:0] sync_word_index_last_n;
+ reg [OP_ADDR_W -1:0] sync_word_index_last_pq;
+
+ reg [BIT_INDEX_W -1:0] sync_bit_index_last_n;
+ reg [BIT_INDEX_W -1:0] sync_bit_index_last_pq;
+
+ reg [OP_ADDR_W -1:0] core_word_index_last_n;
+ reg [OP_ADDR_W -1:0] core_word_index_last_pq;
+
+ reg [BIT_INDEX_W -1:0] core_bit_index_last_n;
+ reg [BIT_INDEX_W -1:0] core_bit_index_last_pq;
+
+ always @(posedge clk_core) begin
+ //
+ sync_reg_mode <= wrap_reg_mode;
+ //
+ sync_word_index_last_n <= wrap_word_index_last_n;
+ sync_word_index_last_pq <= wrap_word_index_last_pq;
+ //
+ sync_bit_index_last_n <= wrap_bit_index_last_n;
+ sync_bit_index_last_pq <= wrap_bit_index_last_pq;
+ //
+ end
+
+ always @(posedge clk_core)
+ //
+ if (sync_reg_control_rising) begin
+ //
+ core_reg_mode <= sync_reg_mode;
+ //
+ core_word_index_last_n <= sync_word_index_last_n;
+ core_word_index_last_pq <= sync_word_index_last_pq;
+ //
+ core_bit_index_last_n <= sync_bit_index_last_n;
+ core_bit_index_last_pq <= sync_bit_index_last_pq;
+ //
+ end
+
+
+ //
+ // Trigger Logic
+ //
+ always @(posedge clk_core or negedge rst_n)
+ //
+ if (!rst_n) {sync_reg_control_dly, sync_reg_control} <= {`MODEXPNG_DEFAULT_CONTROL, `MODEXPNG_DEFAULT_CONTROL};
+ else {sync_reg_control_dly, sync_reg_control} <= { sync_reg_control, wrap_reg_control};
+
+ always @(posedge clk_core or negedge rst_n)
+ //
+ if (!rst_n) core_reg_control <= `MODEXPNG_DEFAULT_CONTROL;
+ else core_reg_control <= sync_reg_control_rising;
+
+
+ //
+ // ModExpNG
+ //
+ modexpng_core_top modexpng
+ (
+ .clk (clk_core),
+ .clk_bus (clk),
+
+ .rst_n (core_rst_n),
+
+ .next (core_reg_control),
+ .valid (core_reg_status),
+
+ .crt_mode (core_reg_mode),
+
+ .word_index_last_n (core_word_index_last_n),
+ .word_index_last_pq (core_word_index_last_pq),
+
+ .bit_index_last_n (core_bit_index_last_n),
+ .bit_index_last_pq (core_bit_index_last_pq),
+
+ .bus_cs (cs),
+ .bus_we (we),
+ .bus_addr (address),
+ .bus_data_wr (write_data),
+ .bus_data_rd (core_read_data)
+ );
+
+
+ //
+ // Write Interface
+ //
+ always @(posedge clk or negedge rst_n)
+ //
+ if (!rst_n) begin
+ //
+ wrap_reg_control <= `MODEXPNG_DEFAULT_CONTROL;
+ wrap_reg_mode <= `MODEXPNG_DEFAULT_MODE;
+ //
+ write_modulus_bits(`MODEXPNG_DEFAULT_MODULUS_BITS);
+ write_exponent_bits(`MODEXPNG_DEFAULT_EXPONENT_BITS);
+ //
+ end else if (cs && we && addr_msb_is_wrap)
+ //
+ case (addr_lsb)
+ ADDR_CONTROL: wrap_reg_control <= write_data[CONTROL_NEXT_BIT];
+ ADDR_MODE: wrap_reg_mode <= write_data[MODE_FULLCRT_BIT];
+ ADDR_MODULUS_BITS: write_modulus_bits(write_data[BIT_INDEX_W:0]);
+ ADDR_EXPONENT_BITS: write_exponent_bits(write_data[BIT_INDEX_W:0]);
+ endcase
+
+
+ //
+ // Update modulus width
+ //
+ function [BIT_INDEX_W:ZEROES_BIT_INDEX_W] fix_modulus_bits;
+ input [BIT_INDEX_W: 0] width;
+ if (width < MIN_OP_W) fix_modulus_bits = MIN_OP_W[BIT_INDEX_W:ZEROES_BIT_INDEX_W];
+ else if (width > MAX_OP_W) fix_modulus_bits = MAX_OP_W[BIT_INDEX_W:ZEROES_BIT_INDEX_W];
+ else fix_modulus_bits = width [BIT_INDEX_W:ZEROES_BIT_INDEX_W];
+ endfunction
+
+ function [OP_ADDR_W-1: 0] calc_modulus_num_words_n;
+ input [BIT_INDEX_W:ZEROES_BIT_INDEX_W] width;
+ calc_modulus_num_words_n = {width, {(ZEROES_BIT_INDEX_W-WORD_MUX_W){1'b0}}} - 1'b1; // truncates msb
+ endfunction
+
+ function [OP_ADDR_W-1: 0] calc_modulus_num_words_pq;
+ input [BIT_INDEX_W:ZEROES_BIT_INDEX_W] width;
+ calc_modulus_num_words_pq = {width, {(ZEROES_BIT_INDEX_W-WORD_MUX_W-1){1'b0}}} - 1'b1; // fits exactly
+ endfunction
+
+ task write_modulus_bits;
+ input [BIT_INDEX_W:0] width;
+ begin
+ wrap_modulus_bits_msb <= fix_modulus_bits(width);
+ wrap_word_index_last_n <= calc_modulus_num_words_n(fix_modulus_bits(width));
+ wrap_word_index_last_pq <= calc_modulus_num_words_pq(fix_modulus_bits(width));
+ end
+ endtask
+
+
+ //
+ // Update exponent width
+ //
+ function [BIT_INDEX_W:0] fix_exponent_bits;
+ input [BIT_INDEX_W:0] width;
+ if (width < MIN_EXP_W) fix_exponent_bits = MIN_EXP_W;
+ else if (width > MAX_OP_W ) fix_exponent_bits = MAX_OP_W;
+ else fix_exponent_bits = width;
+ endfunction
+
+ function [BIT_INDEX_W-1:0] calc_exponent_num_bits_n;
+ input [BIT_INDEX_W :0] width;
+ calc_exponent_num_bits_n = width - 1'b1; // truncates msb
+ endfunction
+
+ function [BIT_INDEX_W-1:0] calc_exponent_num_bits_pq;
+ input [BIT_INDEX_W: 0] width;
+ calc_exponent_num_bits_pq = width[BIT_INDEX_W:1] - 1'b1; // fits exactly
+ endfunction
+
+ task write_exponent_bits;
+ input [BIT_INDEX_W:0] width;
+ begin
+ wrap_exponent_bits <= fix_exponent_bits(width);
+ wrap_bit_index_last_n <= calc_exponent_num_bits_n(fix_exponent_bits(width));
+ wrap_bit_index_last_pq <= calc_exponent_num_bits_pq(fix_exponent_bits(width));
+ end
+ endtask
+
+
+ //
+ // Read Interface
+ //
+ always @(posedge clk)
+ //
+ if (cs && addr_msb_is_wrap)
+ //
+ case (address)
+ //
+ ADDR_NAME0: wrap_read_data <= CORE_NAME0;
+ ADDR_NAME1: wrap_read_data <= CORE_NAME1;
+ ADDR_VERSION: wrap_read_data <= CORE_VERSION;
+ ADDR_CONTROL: wrap_read_data <= {{30{1'b0}}, wrap_reg_control, 1'b0};
+ ADDR_STATUS: wrap_read_data <= {{30{1'b0}}, wrap_reg_status, 1'b1};
+ //
+ ADDR_MODE: wrap_read_data <= {{30{1'b0}}, wrap_reg_mode, 1'b0};
+ ADDR_MODULUS_BITS: wrap_read_data <= {{(31-BIT_INDEX_W){1'b0}}, wrap_modulus_bits_msb, {ZEROES_BIT_INDEX_W{1'b0}}};
+ ADDR_EXPONENT_BITS: wrap_read_data <= {{(31-BIT_INDEX_W){1'b0}}, wrap_exponent_bits};
+ ADDR_BANK_BITS: wrap_read_data <= MAX_OP_W;
+ ADDR_NUM_MULTS: wrap_read_data <= NUM_MULTS;
+ //
+ default: wrap_read_data <= 32'h00000000;
+ //
+ endcase
+
+
+ //
+ // Register / Core Memory Selector
+ //
+ reg [1:0] addr_msb_last;
+
+ wire addr_msb_last_is_wrap = addr_msb_last == ADDR_MSB_WRAP;
+
+ always @(posedge clk)
+ addr_msb_last <= addr_msb;
+
+ assign read_data = addr_msb_last_is_wrap ? wrap_read_data : core_read_data;
+
+
+endmodule