From 584393ac5fc9bbe80887702ec2fc97bee999c5e7 Mon Sep 17 00:00:00 2001 From: "Pavel V. Shatov (Meister)" Date: Mon, 21 Oct 2019 15:13:01 +0300 Subject: Further work: - added core wrapper - fixed module resets across entire core (all the resets are now consistently active-low) - continued refactoring --- rtl/modexpng_wrapper.v | 393 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 393 insertions(+) create mode 100644 rtl/modexpng_wrapper.v (limited to 'rtl/modexpng_wrapper.v') 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 -- cgit v1.2.3