summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bram_1rw_1ro_readfirst.v101
-rw-r--r--curve25519_modular_multiplier.v624
-rw-r--r--lowlevel/generic/adder32_generic.v67
-rw-r--r--lowlevel/generic/adder47_generic.v64
-rw-r--r--lowlevel/generic/mac16_generic.v74
-rw-r--r--lowlevel/generic/subtractor32_generic.v67
-rw-r--r--mod_adder.v304
-rw-r--r--mod_subtractor.v298
-rw-r--r--mw_mover.v170
9 files changed, 624 insertions, 1145 deletions
diff --git a/bram_1rw_1ro_readfirst.v b/bram_1rw_1ro_readfirst.v
deleted file mode 100644
index db62726..0000000
--- a/bram_1rw_1ro_readfirst.v
+++ /dev/null
@@ -1,101 +0,0 @@
-//======================================================================
-//
-// Copyright (c) 2015, 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.
-//
-//======================================================================
-
-`timescale 1ns / 1ps
-
-module bram_1rw_1ro_readfirst
- #(parameter MEM_WIDTH = 32,
- parameter MEM_ADDR_BITS = 8)
- (
- input wire clk,
-
- input wire [MEM_ADDR_BITS-1:0] a_addr,
- input wire a_wr,
- input wire [MEM_WIDTH-1:0] a_in,
- output wire [MEM_WIDTH-1:0] a_out,
-
- input wire [MEM_ADDR_BITS-1:0] b_addr,
- output wire [MEM_WIDTH-1:0] b_out
- );
-
-
- //
- // BRAM
- //
- (* RAM_STYLE="BLOCK" *)
- reg [MEM_WIDTH-1:0] bram[0:(2**MEM_ADDR_BITS)-1];
-
-
- //
- // Initialization
- //
- /**
- integer c;
- initial begin
- for (c=0; c<(2**MEM_ADDR_BITS); c=c+1)
- bram[c] = {MEM_WIDTH{1'b0}};
- end
- **/
-
-
-
- //
- // Output Registers
- //
- reg [MEM_WIDTH-1:0] bram_reg_a;
- reg [MEM_WIDTH-1:0] bram_reg_b;
-
- assign a_out = bram_reg_a;
- assign b_out = bram_reg_b;
-
-
- //
- // Read-Write Port A
- //
- always @(posedge clk) begin
- //
- bram_reg_a <= bram[a_addr];
- //
- if (a_wr) bram[a_addr] <= a_in;
- //
- end
-
-
- //
- // Read-Only Port B
- //
- always @(posedge clk)
- //
- bram_reg_b <= bram[b_addr];
-
-
-endmodule
diff --git a/curve25519_modular_multiplier.v b/curve25519_modular_multiplier.v
new file mode 100644
index 0000000..6ce0525
--- /dev/null
+++ b/curve25519_modular_multiplier.v
@@ -0,0 +1,624 @@
+//------------------------------------------------------------------------------
+//
+// Curve25519_modular_multiplier.v
+// -----------------------------------------------------------------------------
+// Curve25519 Modular Multiplier.
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 2015-2016, 2018 NORDUnet A/S
+//
+// 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 curve25519_modular_multiplier
+(
+ clk, rst_n,
+ ena, rdy,
+ a_addr, b_addr, p_addr, p_wren,
+ a_din, b_din, p_dout
+);
+
+
+ //
+ // Settings
+ //
+ `include "cryptech_primitive_switch.vh"
+
+
+ //
+ // Constants
+ //
+ localparam integer OPERAND_NUM_WORDS = 8;
+ localparam integer WORD_COUNTER_WIDTH = 3;
+
+
+ //
+ // Handy Numbers
+ //
+ localparam [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_ZERO = 0;
+ localparam [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_LAST = OPERAND_NUM_WORDS - 1;
+
+
+ //
+ // Handy Functions
+ //
+ function [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_NEXT_OR_ZERO;
+ input [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_CURRENT;
+ begin
+ WORD_INDEX_NEXT_OR_ZERO = (WORD_INDEX_CURRENT < WORD_INDEX_LAST) ?
+ WORD_INDEX_CURRENT + 1'b1 : WORD_INDEX_ZERO;
+ end
+ endfunction
+
+ function [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_PREVIOUS_OR_LAST;
+ input [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_CURRENT;
+ begin
+ WORD_INDEX_PREVIOUS_OR_LAST = (WORD_INDEX_CURRENT > WORD_INDEX_ZERO) ?
+ WORD_INDEX_CURRENT - 1'b1 : WORD_INDEX_LAST;
+ end
+ endfunction
+
+
+ //
+ // Ports
+ //
+ input clk; // system clock
+ input rst_n; // active-low async reset
+
+ input ena; // enable input
+ output rdy; // ready output
+
+ output [WORD_COUNTER_WIDTH-1:0] a_addr; // index of current A word
+ output [WORD_COUNTER_WIDTH-1:0] b_addr; // index of current B word
+ output [WORD_COUNTER_WIDTH-1:0] p_addr; // index of current P word
+
+ output p_wren; // store current P word now
+
+ input [31:0] a_din; // current word of A
+ input [31:0] b_din; // current word of B
+ output [31:0] p_dout; // current word of P
+
+
+ //
+ // Word Indices
+ //
+ reg [WORD_COUNTER_WIDTH-1:0] index_a;
+ reg [WORD_COUNTER_WIDTH-1:0] index_b;
+
+ // map registers to output ports
+ assign a_addr = index_a;
+ assign b_addr = index_b;
+
+
+ //
+ // FSM
+ //
+
+
+ localparam integer PHASE_INCREMENT_INDEX_A_OFFSET = 0;
+ localparam integer PHASE_INCREMENT_INDEX_A_DURATION = OPERAND_NUM_WORDS;
+
+ localparam integer PHASE_DECREMENT_INDEX_B_OFFSET = PHASE_INCREMENT_INDEX_A_DURATION;
+ localparam integer PHASE_DECREMENT_INDEX_B_DURATION = OPERAND_NUM_WORDS * 2;
+
+ localparam integer PHASE_STORE_MSB_SI_OFFSET = PHASE_DECREMENT_INDEX_B_OFFSET + 2;
+ localparam integer PHASE_STORE_MSB_SI_DURATION = OPERAND_NUM_WORDS * 2 - 1;
+
+ localparam integer PHASE_STORE_LSB_SI_OFFSET = PHASE_STORE_MSB_SI_OFFSET +
+ PHASE_STORE_MSB_SI_DURATION;
+ localparam integer PHASE_STORE_LSB_SI_DURATION = 1;
+
+ localparam integer PHASE_SHIFT_SI_OFFSET = PHASE_STORE_LSB_SI_OFFSET + 1;
+ localparam integer PHASE_SHIFT_SI_DURATION = OPERAND_NUM_WORDS * 2 - 1;
+
+ localparam integer PHASE_MASK_SUM_CW1_OFFSET = PHASE_SHIFT_SI_OFFSET + 1;
+ localparam integer PHASE_MASK_SUM_CW1_DURATION = 1;
+
+ localparam integer PHASE_STORE_LSB_C_OFFSET = PHASE_MASK_SUM_CW1_OFFSET + 1;
+ localparam integer PHASE_STORE_LSB_C_DURATION = OPERAND_NUM_WORDS;
+
+ localparam integer PHASE_STORE_MSB_C_OFFSET = PHASE_STORE_LSB_C_OFFSET +
+ PHASE_STORE_LSB_C_DURATION;
+ localparam integer PHASE_STORE_MSB_C_DURATION = OPERAND_NUM_WORDS;
+
+ localparam integer PHASE_MASK_B_R3_OFFSET = PHASE_STORE_MSB_C_OFFSET + 3;
+ localparam integer PHASE_MASK_B_R3_DURATION = 1;
+
+ localparam integer PHASE_CALCULATE_CARRY_MSB_S1_OFFSET = PHASE_STORE_MSB_C_OFFSET +
+ PHASE_STORE_MSB_C_DURATION + 4;
+ localparam integer PHASE_CALCULATE_CARRY_MSB_S1_DURATION = 1;
+
+ localparam integer PHASE_STORE_LSB_S1_OFFSET = PHASE_STORE_MSB_C_OFFSET + 4;
+ localparam integer PHASE_STORE_LSB_S1_DURATION = OPERAND_NUM_WORDS;
+
+ localparam integer PHASE_SHIFT_S1_OFFSET = PHASE_STORE_LSB_S1_OFFSET +
+ PHASE_STORE_LSB_S1_DURATION + 1;
+ localparam integer PHASE_SHIFT_S1_DURATION = OPERAND_NUM_WORDS;
+
+ localparam integer PHASE_CHANGE_LSB_B_P_OFFSET = PHASE_SHIFT_S1_OFFSET;
+ localparam integer PHASE_CHANGE_LSB_B_P_DURATION = 1;
+
+ localparam integer PHASE_SELECT_S2_OR_PN_OFFSET = PHASE_SHIFT_S1_OFFSET +
+ PHASE_SHIFT_S1_DURATION + 1;
+ localparam integer PHASE_SELECT_S2_OR_PN_DURATION = 1;
+
+ localparam integer PHASE_UPDATE_P_DOUT_OFFSET = PHASE_SHIFT_S1_OFFSET +
+ PHASE_SHIFT_S1_DURATION + 2;
+ localparam integer PHASE_UPDATE_P_DOUT_DURATION = OPERAND_NUM_WORDS;
+
+
+
+ localparam integer FSM_SHREG_WIDTH = PHASE_INCREMENT_INDEX_A_DURATION +
+ PHASE_DECREMENT_INDEX_B_DURATION +
+ 1 +
+ PHASE_STORE_LSB_SI_DURATION +
+ PHASE_SHIFT_SI_DURATION +
+ -1 +
+ PHASE_STORE_LSB_S1_DURATION +
+ PHASE_CALCULATE_CARRY_MSB_S1_DURATION +
+ PHASE_SHIFT_S1_DURATION +
+ 1 +
+ PHASE_SELECT_S2_OR_PN_DURATION +
+ PHASE_UPDATE_P_DOUT_DURATION +
+ 2;
+
+ localparam [FSM_SHREG_WIDTH-1:0] FSM_SHREG_INIT = {{(FSM_SHREG_WIDTH-1){1'b0}}, 1'b1};
+
+ reg [FSM_SHREG_WIDTH-1:0] fsm_shreg = FSM_SHREG_INIT;
+
+ assign rdy = fsm_shreg[0];
+
+
+
+
+
+
+
+ wire [PHASE_INCREMENT_INDEX_A_DURATION -1:0] fsm_shreg_increment_index_a = fsm_shreg[FSM_SHREG_WIDTH - PHASE_INCREMENT_INDEX_A_OFFSET - 1 -: PHASE_INCREMENT_INDEX_A_DURATION];
+ wire [PHASE_DECREMENT_INDEX_B_DURATION -1:0] fsm_shreg_decrement_index_b = fsm_shreg[FSM_SHREG_WIDTH - PHASE_DECREMENT_INDEX_B_OFFSET - 1 -: PHASE_DECREMENT_INDEX_B_DURATION];
+ wire [PHASE_STORE_MSB_SI_DURATION -1:0] fsm_shreg_store_msb_si = fsm_shreg[FSM_SHREG_WIDTH - PHASE_STORE_MSB_SI_OFFSET - 1 -: PHASE_STORE_MSB_SI_DURATION];
+ wire [PHASE_STORE_LSB_SI_DURATION -1:0] fsm_shreg_store_lsb_si = fsm_shreg[FSM_SHREG_WIDTH - PHASE_STORE_LSB_SI_OFFSET - 1 -: PHASE_STORE_LSB_SI_DURATION];
+ wire [PHASE_SHIFT_SI_DURATION -1:0] fsm_shreg_shift_si = fsm_shreg[FSM_SHREG_WIDTH - PHASE_SHIFT_SI_OFFSET - 1 -: PHASE_SHIFT_SI_DURATION];
+ wire [PHASE_MASK_SUM_CW1_DURATION -1:0] fsm_shreg_mask_sum_cw1 = fsm_shreg[FSM_SHREG_WIDTH - PHASE_MASK_SUM_CW1_OFFSET - 1 -: PHASE_MASK_SUM_CW1_DURATION];
+ wire [PHASE_STORE_LSB_C_DURATION -1:0] fsm_shreg_store_lsb_c = fsm_shreg[FSM_SHREG_WIDTH - PHASE_STORE_LSB_C_OFFSET - 1 -: PHASE_STORE_LSB_C_DURATION];
+ wire [PHASE_STORE_MSB_C_DURATION -1:0] fsm_shreg_store_msb_c = fsm_shreg[FSM_SHREG_WIDTH - PHASE_STORE_MSB_C_OFFSET - 1 -: PHASE_STORE_MSB_C_DURATION];
+ wire [PHASE_MASK_B_R3_DURATION -1:0] fsm_shreg_mask_b_r3 = fsm_shreg[FSM_SHREG_WIDTH - PHASE_MASK_B_R3_OFFSET - 1 -: PHASE_MASK_B_R3_DURATION];
+ wire [PHASE_CALCULATE_CARRY_MSB_S1_DURATION-1:0] fsm_shreg_calculate_carry_msb_s1 = fsm_shreg[FSM_SHREG_WIDTH - PHASE_CALCULATE_CARRY_MSB_S1_OFFSET - 1 -: PHASE_CALCULATE_CARRY_MSB_S1_DURATION];
+ wire [PHASE_STORE_LSB_S1_DURATION -1:0] fsm_shreg_store_lsb_s1 = fsm_shreg[FSM_SHREG_WIDTH - PHASE_STORE_LSB_S1_OFFSET - 1 -: PHASE_STORE_LSB_S1_DURATION];
+ wire [PHASE_SHIFT_S1_DURATION -1:0] fsm_shreg_shift_s1 = fsm_shreg[FSM_SHREG_WIDTH - PHASE_SHIFT_S1_OFFSET - 1 -: PHASE_SHIFT_S1_DURATION];
+ wire [PHASE_CHANGE_LSB_B_P_DURATION -1:0] fsm_shreg_change_lsb_b_p = fsm_shreg[FSM_SHREG_WIDTH - PHASE_CHANGE_LSB_B_P_OFFSET - 1 -: PHASE_CHANGE_LSB_B_P_DURATION];
+ wire [PHASE_SELECT_S2_OR_PN_DURATION -1:0] fsm_shreg_select_s2_or_pn = fsm_shreg[FSM_SHREG_WIDTH - PHASE_SELECT_S2_OR_PN_OFFSET - 1 -: PHASE_SELECT_S2_OR_PN_DURATION];
+ wire [PHASE_UPDATE_P_DOUT_DURATION -1:0] fsm_shreg_update_p_dout = fsm_shreg[FSM_SHREG_WIDTH - PHASE_UPDATE_P_DOUT_OFFSET - 1 -: PHASE_UPDATE_P_DOUT_DURATION];
+
+ wire flag_increment_index_a = |fsm_shreg_increment_index_a;
+ wire flag_decrement_index_b = |fsm_shreg_decrement_index_b;
+ wire flag_store_msb_si = |fsm_shreg_store_msb_si;
+ wire flag_store_lsb_si = |fsm_shreg_store_lsb_si;
+ wire flag_shift_si = |fsm_shreg_shift_si;
+ wire flag_mask_sum_cw1 = |fsm_shreg_mask_sum_cw1;
+ wire flag_store_lsb_c = |fsm_shreg_store_lsb_c;
+ wire flag_store_msb_c = |fsm_shreg_store_msb_c;
+ wire flag_mask_b_r3 = |fsm_shreg_mask_b_r3;
+ wire flag_calculate_carry_msb_s1 = |fsm_shreg_calculate_carry_msb_s1;
+ wire flag_store_lsb_s1 = |fsm_shreg_store_lsb_s1;
+ wire flag_shift_s1 = |fsm_shreg_shift_s1;
+ wire flag_change_lsb_b_p = |fsm_shreg_change_lsb_b_p;
+ wire flag_select_s2_or_pn = |fsm_shreg_select_s2_or_pn;
+ wire flag_update_p_dout = |fsm_shreg_update_p_dout;
+
+ reg flag_store_word_a = 0;
+ reg flag_enable_mac_ab = 0;
+ reg flag_delay_msb_c = 0;
+ reg flag_mask_a_s2 = 0;
+ reg flag_mask_b_out_p = 0;
+ reg flag_store_s2 = 0;
+ reg flag_store_pn = 0;
+
+ always @(posedge clk) begin
+ flag_store_word_a <= flag_increment_index_a;
+ flag_enable_mac_ab <= flag_decrement_index_b;
+ flag_delay_msb_c <= flag_store_msb_c;
+ flag_mask_a_s2 <= flag_calculate_carry_msb_s1;
+ flag_mask_b_out_p <= flag_change_lsb_b_p;
+ flag_store_s2 <= flag_shift_s1;
+ flag_store_pn <= flag_store_s2;
+ end
+
+
+ //
+ // FSM Logic
+ //
+ always @(posedge clk or negedge rst_n)
+ //
+ if (rst_n == 1'b0)
+ //
+ fsm_shreg <= FSM_SHREG_INIT;
+ //
+ else begin
+ //
+ if (rdy) fsm_shreg <= {ena, {FSM_SHREG_WIDTH-2{1'b0}}, ~ena};
+ else fsm_shreg <= {1'b0, fsm_shreg[FSM_SHREG_WIDTH-1:1]};
+ end
+
+
+ //
+ // A Word Index Increment Logic
+ //
+ always @(posedge clk)
+ //
+ if (rdy) index_a <= WORD_INDEX_ZERO;
+ else if (flag_increment_index_a) index_a <= WORD_INDEX_NEXT_OR_ZERO(index_a);
+
+
+ //
+ // B Word Index Decrement Logic
+ //
+ always @(posedge clk)
+ //
+ if (rdy) index_b <= WORD_INDEX_LAST;
+ else if (flag_decrement_index_b && !index_b_ff) index_b <= WORD_INDEX_PREVIOUS_OR_LAST(index_b);
+
+
+ //
+ // Wide Operand Buffer
+ //
+ reg [255:0] buf_a_wide;
+
+
+
+ //
+ // B Word Splitter
+ //
+
+ /*
+ * 0: store the upper 16-bit part of the current B word
+ * 1: store the lower 16-bit part of the current B word
+ */
+
+ reg index_b_ff = 1'b0;
+
+ always @(posedge clk)
+ //
+ if (flag_decrement_index_b) index_b_ff <= ~index_b_ff;
+ else index_b_ff <= 1'b0;
+
+
+ //
+ // Narrow Operand Buffer
+ //
+ reg [15:0] buf_b_narrow;
+
+ always @(posedge clk)
+ //
+ if (flag_decrement_index_b) buf_b_narrow <= !index_b_ff ? b_din[31:16] : b_din[15:0];
+
+
+ //
+ // MAC Clear Logic
+ //
+ reg [15:0] mac_clear;
+
+ always @(posedge clk)
+ //
+ if (!flag_enable_mac_ab) mac_clear <= {16{1'b1}};
+ else begin
+ if (mac_clear[0]) mac_clear <= 16'b0000000000000010;
+ else if (mac_clear[15]) mac_clear <= 16'b1111111111111111;
+ else mac_clear <= {mac_clear[14:0], 1'b0};
+ end
+
+
+ //
+ // MAC Array
+ //
+ wire [46:0] mac_accum[0:15];
+
+ genvar i;
+
+ generate for (i=0; i<16; i=i+1)
+ //
+ begin : gen_mac16_array
+ //
+ `CRYPTECH_PRIMITIVE_MAC16 mac16_inst
+ (
+ .clk (clk),
+ .ce (flag_enable_mac_ab),
+
+ .clr (mac_clear[i]),
+
+ .a (buf_a_wide[16 * i +: 16]),
+ .b (buf_b_narrow),
+ .s (mac_accum[i])
+ );
+ //
+ end
+ //
+ endgenerate
+
+
+ //
+ // Intermediate Words
+ //
+ reg [47*(2*OPERAND_NUM_WORDS-1)-1:0] si_msb;
+ reg [47*(2*OPERAND_NUM_WORDS-0)-1:0] si_lsb;
+
+ wire [47*(2*OPERAND_NUM_WORDS-1)-1:0] si_msb_new;
+ wire [47*(2*OPERAND_NUM_WORDS-0)-1:0] si_lsb_new;
+
+ generate for (i=0; i<16; i=i+1)
+ begin : gen_si_lsb_new
+ assign si_lsb_new[47*i+:47] = mac_accum[15-i];
+ end
+ endgenerate
+
+ generate for (i=1; i<16; i=i+1)
+ begin : gen_si_msb_new
+ assign si_msb_new[47*(15-i)+:47] = mac_clear[i] ? mac_accum[i] : si_msb[47*(15-i)+:47];
+ end
+ endgenerate
+
+ always @(posedge clk)
+ //
+ if (flag_shift_si) begin
+ si_msb <= {{2*47{1'b0}}, si_msb[15*47-1:2*47]};
+ si_lsb <= {si_msb[2*47-1:0], si_lsb[16*47-1:2*47]};
+ end else begin
+ if (flag_store_msb_si) si_msb <= si_msb_new;
+ if (flag_store_lsb_si) si_lsb <= si_lsb_new;
+ end
+
+
+ //
+ // Accumulators
+ //
+ wire [46:0] add47_cw0_s;
+ wire [46:0] add47_cw1_s;
+ wire [14:0] add47_cw1_s_masked = flag_mask_sum_cw1 ? {15{1'b0}} : add47_cw1_s[32+:15];
+
+ wire [46:0] add47_r3_b_masked = {{32{1'b0}}, flag_mask_b_r3 ? {15{1'b0}} : add47_r3_s[46:32]};
+
+
+ //
+ // cw0, cw1
+ //
+ reg [30: 0] si_prev_dly;
+ reg [15: 0] si_next_dly;
+
+ always @(posedge clk)
+ //
+ if (flag_shift_si) si_prev_dly <= si_lsb[93:63];
+ else si_prev_dly <= {31{1'b0}};
+
+ always @(posedge clk)
+ //
+ si_next_dly <= si_lsb[47+:16];
+
+ wire [46:0] add47_cw0_a = si_lsb[46:0];
+ wire [46:0] add47_cw0_b = {{16{1'b0}}, si_prev_dly};
+
+ wire [46:0] add47_cw1_a = add47_cw0_s;
+ wire [46:0] add47_cw1_b = {{15{1'b0}}, si_next_dly, 1'b0, add47_cw1_s_masked};
+
+ `CRYPTECH_PRIMITIVE_ADD47 add47_cw0_inst
+ (
+ .clk (clk),
+ .a (add47_cw0_a),
+ .b (add47_cw0_b),
+ .s (add47_cw0_s)
+ );
+
+ `CRYPTECH_PRIMITIVE_ADD47 add47_cw1_inst
+ (
+ .clk (clk),
+ .a (add47_cw1_a),
+ .b (add47_cw1_b),
+ .s (add47_cw1_s)
+ );
+
+
+ //
+ // Full-Size Product
+ //
+ wire [31:0] c_word_lower = add47_cw1_s[31:0];
+
+
+ wire [46:0] add47_r0_s;
+ wire [46:0] add47_r1_s;
+ wire [46:0] add47_r2_s;
+ wire [46:0] add47_r3_s;
+
+ reg [255:0] c_lsb_s1_shreg;
+ reg [ 31:0] c_msb_latch;
+
+
+
+
+
+ always @(posedge clk)
+ //
+ if (flag_store_msb_c) c_msb_latch <= c_word_lower;
+ else c_msb_latch <= {32{1'b0}};
+
+
+ reg [4:0] c_msb_latch_upper_dly;
+ reg [31:0] c_lsb_shreg_lower_dly;
+
+ always @(posedge clk)
+ //
+ if (flag_delay_msb_c) c_msb_latch_upper_dly <= c_msb_latch[31:27];
+ else c_msb_latch_upper_dly <= {5{1'b0}};
+
+
+ always @(posedge clk)
+ //
+ if (flag_store_msb_c) c_lsb_shreg_lower_dly <= c_lsb_s1_shreg[31:0];
+ else c_lsb_shreg_lower_dly <= {32{1'b0}};
+
+
+
+ reg [11:0] carry_msb_s1;
+
+ always @(posedge clk)
+ //
+ if (flag_calculate_carry_msb_s1) carry_msb_s1 <= {{6{1'b0}}, 6'd38} * {{6{1'b0}}, add47_r3_s[5:0]};
+
+
+ wire [46:0] add47_s2_a_masked = {{32{1'b0}}, flag_mask_a_s2 ? {3'b000, carry_msb_s1} : add47_s2_s[46:32]};
+
+ `CRYPTECH_PRIMITIVE_ADD47 add47_r0
+ (
+ .clk (clk),
+ .a ({{15{1'b0}}, c_msb_latch[30:0], c_msb_latch_upper_dly[4]}),
+ .b ({{15{1'b0}}, c_msb_latch[29:0], c_msb_latch_upper_dly[4:3]}),
+ .s (add47_r0_s)
+ );
+ `CRYPTECH_PRIMITIVE_ADD47 add47_r1
+ (
+ .clk (clk),
+ .a ({{15{1'b0}}, c_msb_latch[26:0], c_msb_latch_upper_dly[4:0]}),
+ .b ({{15{1'b0}}, c_lsb_shreg_lower_dly}),
+ .s (add47_r1_s)
+ );
+ `CRYPTECH_PRIMITIVE_ADD47 add47_r2
+ (
+ .clk (clk),
+ .a (add47_r0_s),
+ .b (add47_r1_s),
+ .s (add47_r2_s)
+ );
+ `CRYPTECH_PRIMITIVE_ADD47 add47_r3
+ (
+ .clk (clk),
+ .a (add47_r2_s),
+ .b (add47_r3_b_masked),
+ .s (add47_r3_s)
+ );
+
+
+
+ wire [46:0] add47_s2_s;
+ `CRYPTECH_PRIMITIVE_ADD47 add47_s2
+ (
+ .clk (clk),
+ .a (add47_s2_a_masked),
+ .b ({{15{1'b0}}, c_lsb_s1_shreg[31:0]}),
+ .s (add47_s2_s)
+ );
+
+
+ reg sub32_b_bit;
+
+ wire [31:0] sub32_b = {{26{1'b1}}, // ...*11*1*
+ sub32_b_bit, {2{1'b1}}, sub32_b_bit, 1'b1, sub32_b_bit};
+
+ always @(posedge clk)
+ //
+ if (!fsm_shreg_change_lsb_b_p) sub32_b_bit <= 1'b1;
+ else sub32_b_bit <= 1'b0;
+
+ wire [31:0] sub32_pn_d;
+ wire sub32_b_in;
+ wire sub32_b_out;
+
+ assign sub32_b_in = sub32_b_out & !flag_mask_b_out_p;
+
+ `CRYPTECH_PRIMITIVE_SUB32 sub32_pn
+ (
+ .clk (clk),
+ .a (add47_s2_s[31:0]),
+ .b (sub32_b),
+ .d (sub32_pn_d),
+ .b_in (sub32_b_in),
+ .b_out (sub32_b_out)
+ );
+
+
+ wire [31:0] add47_r3_s_lower = add47_r3_s[31:0];
+
+
+ always @(posedge clk)
+ //
+ if (flag_store_word_a) buf_a_wide <= {buf_a_wide[16+:256-3*16], {a_din[15:0], a_din[31:16]}, buf_a_wide[256-2*16+:16]};
+ else if (flag_enable_mac_ab) buf_a_wide <= {buf_a_wide[256-(16+1):0], buf_a_wide[256-16+:16]};
+ else if (flag_store_s2) buf_a_wide <= {add47_s2_s[31:0], buf_a_wide[255:32]};
+ else if (flag_update_p_dout) buf_a_wide <= {{32{1'bX}}, buf_a_wide[255:32]};
+
+
+ always @(posedge clk)
+ //
+ if (flag_store_lsb_c) c_lsb_s1_shreg <= {c_word_lower, c_lsb_s1_shreg[255:32]};
+ else if (flag_store_lsb_s1) c_lsb_s1_shreg <= {add47_r3_s_lower, c_lsb_s1_shreg[255:32]};
+ else if (flag_store_pn) c_lsb_s1_shreg <= {sub32_pn_d, c_lsb_s1_shreg[255:32]};
+ else if (flag_store_msb_c || flag_shift_s1) c_lsb_s1_shreg <= {{32{1'b0}}, c_lsb_s1_shreg[255:32]};
+ else if (flag_update_p_dout) c_lsb_s1_shreg <= {{32{1'b0}}, c_lsb_s1_shreg[255:32]};
+
+
+ reg sel_pn; // 0: output in S2, 1: output in PN
+
+ always @(posedge clk)
+ //
+ if (flag_select_s2_or_pn) sel_pn <= sub32_b_out & add47_s2_s[0];
+
+
+ reg [31:0] p_dout_reg;
+
+ assign p_dout = p_dout_reg;
+
+ always @(posedge clk)
+ //
+ if (flag_update_p_dout) p_dout_reg <= sel_pn ? c_lsb_s1_shreg[31:0] : buf_a_wide[31:0];
+ else p_dout_reg <= {32{1'bX}};
+
+
+ reg p_wren_reg = 0;
+
+ assign p_wren = p_wren_reg;
+
+ always @(posedge clk)
+ //
+ p_wren_reg <= flag_update_p_dout;
+
+
+ reg [WORD_COUNTER_WIDTH-1:0] p_addr_reg;
+
+ assign p_addr = p_addr_reg;
+
+ always @(posedge clk)
+ //
+ if (p_wren_reg) p_addr_reg <= WORD_INDEX_NEXT_OR_ZERO(p_addr_reg);
+ else p_addr_reg <= WORD_INDEX_ZERO;
+
+
+endmodule
+
+
+//------------------------------------------------------------------------------
+// End-of-File
+//------------------------------------------------------------------------------
diff --git a/lowlevel/generic/adder32_generic.v b/lowlevel/generic/adder32_generic.v
deleted file mode 100644
index eadfb6f..0000000
--- a/lowlevel/generic/adder32_generic.v
+++ /dev/null
@@ -1,67 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// adder32_generic.v
-// -----------------------------------------------------------------------------
-// Generic 32-bit adder.
-//
-// Authors: Pavel Shatov
-//
-// Copyright (c) 2016, NORDUnet A/S
-//
-// 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 adder32_generic
- (
- input clk, // clock
- input [31: 0] a, // operand input
- input [31: 0] b, // operand input
- output [31: 0] s, // sum output
- input c_in, // carry input
- output c_out // carry output
- );
-
- //
- // Sum
- //
- reg [32: 0] s_int;
-
- always @(posedge clk)
- s_int <= {1'b0, a} + {1'b0, b} + {{32{1'b0}}, c_in};
-
- //
- // Output
- //
- assign s = s_int[31:0];
- assign c_out = s_int[32];
-
-endmodule
-
-//------------------------------------------------------------------------------
-// End-of-File
-//------------------------------------------------------------------------------
diff --git a/lowlevel/generic/adder47_generic.v b/lowlevel/generic/adder47_generic.v
deleted file mode 100644
index 406c175..0000000
--- a/lowlevel/generic/adder47_generic.v
+++ /dev/null
@@ -1,64 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// adder47_generic.v
-// -----------------------------------------------------------------------------
-// Generic 47-bit adder.
-//
-// Authors: Pavel Shatov
-//
-// Copyright (c) 2016, NORDUnet A/S
-//
-// 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 adder47_generic
- (
- input clk, // clock
- input [46: 0] a, // operand input
- input [46: 0] b, // operand input
- output [46: 0] s // sum output
- );
-
- //
- // Sum
- //
- reg [46: 0] s_int;
-
- always @(posedge clk)
- s_int <= a + b;
-
- //
- // Output
- //
- assign s = s_int;
-
-endmodule
-
-//------------------------------------------------------------------------------
-// End-of-File
-//------------------------------------------------------------------------------
diff --git a/lowlevel/generic/mac16_generic.v b/lowlevel/generic/mac16_generic.v
deleted file mode 100644
index 6d120a3..0000000
--- a/lowlevel/generic/mac16_generic.v
+++ /dev/null
@@ -1,74 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// mac16_generic.v
-// -----------------------------------------------------------------------------
-// Generic 16-bit multiplier and 47-bit accumulator.
-//
-// Authors: Pavel Shatov
-//
-// Copyright (c) 2016, NORDUnet A/S
-//
-// 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 mac16_generic
- (
- input clk, // clock
- input clr, // clear accumulator (active-high)
- input ce, // enable clock (active-high)
- input [15: 0] a, // operand input
- input [15: 0] b, // operand input
- output [46: 0] s // sum output
- );
-
- //
- // Multiplier
- //
- wire [31: 0] p = {{16{1'b0}}, a} * {{16{1'b0}}, b};
- wire [46: 0] p_ext = {{15{1'b0}}, p};
-
- //
- // Accumulator
- //
- reg [46: 0] s_int;
-
- always @(posedge clk)
- //
- if (ce) s_int <= clr ? p_ext : p_ext + s_int;
-
- //
- // Output
- //
- assign s = s_int;
-
-endmodule
-
-
-//------------------------------------------------------------------------------
-// End-of-File
-//------------------------------------------------------------------------------
diff --git a/lowlevel/generic/subtractor32_generic.v b/lowlevel/generic/subtractor32_generic.v
deleted file mode 100644
index 5137ace..0000000
--- a/lowlevel/generic/subtractor32_generic.v
+++ /dev/null
@@ -1,67 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// subtractor32_generic.v
-// -----------------------------------------------------------------------------
-// Generic 32-bit subtractor.
-//
-// Authors: Pavel Shatov
-//
-// Copyright (c) 2016, NORDUnet A/S
-//
-// 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 subtractor32_generic
- (
- input clk,
- input [31: 0] a,
- input [31: 0] b,
- output [31: 0] d,
- input b_in,
- output b_out
- );
-
- //
- // Difference
- //
- reg [32: 0] d_int;
-
- always @(posedge clk)
- d_int <= {1'b0, a} - {1'b0, b} - {{32{1'b0}}, b_in};
-
- //
- // Output
- //
- assign d = d_int[31:0];
- assign b_out = d_int[32];
-
-endmodule
-
-//------------------------------------------------------------------------------
-// End-of-File
-//------------------------------------------------------------------------------
diff --git a/mod_adder.v b/mod_adder.v
deleted file mode 100644
index e6e0db8..0000000
--- a/mod_adder.v
+++ /dev/null
@@ -1,304 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// mod_adder.v
-// -----------------------------------------------------------------------------
-// Modular adder.
-//
-// Authors: Pavel Shatov
-//
-// Copyright (c) 2016, NORDUnet A/S
-//
-// 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 mod_adder
- (
- clk, rst_n,
- ena, rdy,
- ab_addr, n_addr, s_addr, s_wren,
- a_din, b_din, n_din, s_dout
- );
-
-
- //
- // Settings
- //
-`include "ed25519_settings.vh"
-
-
- //
- // Parameters
- //
- parameter OPERAND_NUM_WORDS = 8;
- parameter WORD_COUNTER_WIDTH = 3;
-
-
- //
- // Handy Numbers
- //
- localparam [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_ZERO = 0;
- localparam [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_LAST = OPERAND_NUM_WORDS - 1;
-
-
- //
- // Handy Functions
- //
- function [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_NEXT_OR_ZERO;
- input [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_CURRENT;
- begin
- WORD_INDEX_NEXT_OR_ZERO = (WORD_INDEX_CURRENT < WORD_INDEX_LAST) ?
- WORD_INDEX_CURRENT + 1'b1 : WORD_INDEX_ZERO;
- end
- endfunction
-
-
- //
- // Ports
- //
- input wire clk; // system clock
- input wire rst_n; // active-low async reset
-
- input wire ena; // enable input
- output wire rdy; // ready output
-
- output wire [WORD_COUNTER_WIDTH-1:0] ab_addr; // index of current A and B words
- output wire [WORD_COUNTER_WIDTH-1:0] n_addr; // index of current N word
- output wire [WORD_COUNTER_WIDTH-1:0] s_addr; // index of current S word
- output wire s_wren; // store current S word now
-
- input wire [ 31:0] a_din; // A
- input wire [ 31:0] b_din; // B
- input wire [ 31:0] n_din; // N
- output wire [ 31:0] s_dout; // S = (A + B) mod N
-
-
- //
- // Word Indices
- //
- reg [WORD_COUNTER_WIDTH-1:0] index_ab;
- reg [WORD_COUNTER_WIDTH-1:0] index_n;
- reg [WORD_COUNTER_WIDTH-1:0] index_s;
-
- /* map registers to output ports */
- assign ab_addr = index_ab;
- assign n_addr = index_n;
- assign s_addr = index_s;
-
-
- //
- // Adder
- //
- wire [31: 0] add32_s;
- wire add32_c_in;
- wire add32_c_out;
-
- `ED25519_ADD32_PRIMITIVE adder32
- (
- .clk (clk),
- .a (a_din),
- .b (b_din),
- .s (add32_s),
- .c_in (add32_c_in),
- .c_out (add32_c_out)
- );
-
-
- //
- // Subtractor
- //
- wire [31: 0] sub32_d;
- wire sub32_b_in;
- wire sub32_b_out;
-
- `ED25519_SUB32_PRIMITIVE subtractor32
- (
- .clk (clk),
- .a (add32_s),
- .b (n_din),
- .d (sub32_d),
- .b_in (sub32_b_in),
- .b_out (sub32_b_out)
- );
-
-
- //
- // FSM
- //
-
- localparam FSM_SHREG_WIDTH = 2*OPERAND_NUM_WORDS + 5;
-
- reg [FSM_SHREG_WIDTH-1:0] fsm_shreg;
-
- assign rdy = fsm_shreg[0];
-
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_ab = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 1) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 0)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_n = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 2) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 1)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_store_sum_ab = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 3) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 2)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_store_sum_ab_n = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 4) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 3)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_store_data_s = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 4) : FSM_SHREG_WIDTH - (2 * OPERAND_NUM_WORDS + 3)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_s = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 5) : FSM_SHREG_WIDTH - (2 * OPERAND_NUM_WORDS + 4)];
-
- wire fsm_latch_msb_carry = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 2)];
- wire fsm_latch_msb_borrow = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 3)];
-
- wire inc_index_ab = |fsm_shreg_inc_index_ab;
- wire inc_index_n = |fsm_shreg_inc_index_n;
- wire store_sum_ab = |fsm_shreg_store_sum_ab;
- wire store_sum_ab_n = |fsm_shreg_store_sum_ab_n;
- wire store_data_s = |fsm_shreg_store_data_s;
- wire inc_index_s = |fsm_shreg_inc_index_s;
-
- always @(posedge clk or negedge rst_n)
- //
- if (rst_n == 1'b0)
- //
- fsm_shreg <= {{FSM_SHREG_WIDTH-1{1'b0}}, 1'b1};
- //
- else begin
- //
- if (rdy) fsm_shreg <= {ena, {FSM_SHREG_WIDTH-2{1'b0}}, ~ena};
- //
- else fsm_shreg <= {1'b0, fsm_shreg[FSM_SHREG_WIDTH-1:1]};
- //
- end
-
-
-
-
-
-
-
- //
- // Carry & Borrow Masking Logic
- //
- reg add32_c_mask;
- reg sub32_b_mask;
-
- always @(posedge clk) begin
- //
- add32_c_mask <= (index_ab == WORD_INDEX_ZERO) ? 1'b1 : 1'b0;
- sub32_b_mask <= (index_n == WORD_INDEX_ZERO) ? 1'b1 : 1'b0;
- //
- end
-
- assign add32_c_in = add32_c_out & ~add32_c_mask;
- assign sub32_b_in = sub32_b_out & ~sub32_b_mask;
-
-
- //
- // Carry & Borrow Latch Logic
- //
- reg add32_carry_latch;
- reg sub32_borrow_latch;
-
- always @(posedge clk) begin
- //
- if (fsm_latch_msb_carry) add32_carry_latch <= add32_c_out;
- if (fsm_latch_msb_borrow) sub32_borrow_latch <= sub32_b_out;
- //
- end
-
-
- //
- // Intermediate Results
- //
- reg [32*OPERAND_NUM_WORDS-1:0] s_ab;
- reg [32*OPERAND_NUM_WORDS-1:0] s_ab_n;
-
- always @(posedge clk)
- //
- if (store_data_s) begin
- //
- s_ab <= {{32{1'bX}}, s_ab[32*OPERAND_NUM_WORDS-1:32]};
- s_ab_n <= {{32{1'bX}}, s_ab_n[32*OPERAND_NUM_WORDS-1:32]};
- //
- end else begin
- //
- if (store_sum_ab) s_ab <= {add32_s, s_ab[32*OPERAND_NUM_WORDS-1:32]};
- if (store_sum_ab_n) s_ab_n <= {sub32_d, s_ab_n[32*OPERAND_NUM_WORDS-1:32]};
- //
- end
-
-
- //
- // Word Index Increment Logic
- //
- always @(posedge clk)
- //
- if (rdy) begin
- //
- index_ab <= WORD_INDEX_ZERO;
- index_n <= WORD_INDEX_ZERO;
- index_s <= WORD_INDEX_ZERO;
- //
- end else begin
- //
- if (inc_index_ab) index_ab <= WORD_INDEX_NEXT_OR_ZERO(index_ab);
- if (inc_index_n) index_n <= WORD_INDEX_NEXT_OR_ZERO(index_n);
- if (inc_index_s) index_s <= WORD_INDEX_NEXT_OR_ZERO(index_s);
- //
- end
-
-
- //
- // Output Sum Selector
- //
- wire mux_select_ab = sub32_borrow_latch && !add32_carry_latch;
-
-
- //
- // Output Data and Write Enable Logic
- //
- reg s_wren_reg;
- reg [31: 0] s_dout_reg;
- wire [31: 0] s_dout_mux = mux_select_ab ? s_ab[31:0] : s_ab_n[31:0];
-
- assign s_wren = s_wren_reg;
- assign s_dout = s_dout_reg;
-
- always @(posedge clk)
- //
- if (rdy) begin
- //
- s_wren_reg <= 1'b0;
- s_dout_reg <= {32{1'bX}};
- //
- end else begin
- //
- s_wren_reg <= store_data_s;
- s_dout_reg <= store_data_s ? s_dout_mux : {32{1'bX}};
- //
- end
-
-
-endmodule
-
-
-//------------------------------------------------------------------------------
-// End-of-File
-//------------------------------------------------------------------------------
diff --git a/mod_subtractor.v b/mod_subtractor.v
deleted file mode 100644
index 9b4b7e9..0000000
--- a/mod_subtractor.v
+++ /dev/null
@@ -1,298 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// mod_subtractor.v
-// -----------------------------------------------------------------------------
-// Modular subtractor.
-//
-// Authors: Pavel Shatov
-//
-// Copyright (c) 2016, NORDUnet A/S
-//
-// 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 mod_subtractor
- (
- clk, rst_n,
- ena, rdy,
- ab_addr, n_addr, d_addr, d_wren,
- a_din, b_din, n_din, d_dout
- );
-
-
- //
- // Settings
- //
- `include "ed25519_settings.vh"
-
-
- //
- // Parameters
- //
- parameter OPERAND_NUM_WORDS = 8;
- parameter WORD_COUNTER_WIDTH = 3;
-
-
- //
- // Handy Numbers
- //
- localparam [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_ZERO = 0;
- localparam [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_LAST = OPERAND_NUM_WORDS - 1;
-
-
- //
- // Handy Functions
- //
- function [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_NEXT_OR_ZERO;
- input [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_CURRENT;
- begin
- WORD_INDEX_NEXT_OR_ZERO = (WORD_INDEX_CURRENT < WORD_INDEX_LAST) ?
- WORD_INDEX_CURRENT + 1'b1 : WORD_INDEX_ZERO;
- end
- endfunction
-
-
- //
- // Ports
- //
- input wire clk; // system clock
- input wire rst_n; // active-low async reset
-
- input wire ena; // enable input
- output wire rdy; // ready output
-
- output wire [WORD_COUNTER_WIDTH-1:0] ab_addr; // index of current A and B words
- output wire [WORD_COUNTER_WIDTH-1:0] n_addr; // index of current N word
- output wire [WORD_COUNTER_WIDTH-1:0] d_addr; // index of current D word
- output wire d_wren; // store current D word now
-
- input wire [ 31:0] a_din; // A
- input wire [ 31:0] b_din; // B
- input wire [ 31:0] n_din; // N
- output wire [ 31:0] d_dout; // D = (A - B) mod N
-
-
- //
- // Word Indices
- //
- reg [WORD_COUNTER_WIDTH-1:0] index_ab;
- reg [WORD_COUNTER_WIDTH-1:0] index_n;
- reg [WORD_COUNTER_WIDTH-1:0] index_d;
-
- /* map registers to output ports */
- assign ab_addr = index_ab;
- assign n_addr = index_n;
- assign d_addr = index_d;
-
-
- //
- // Subtractor
- //
- wire [31: 0] sub32_d;
- wire sub32_b_in;
- wire sub32_b_out;
-
- `ED25519_SUB32_PRIMITIVE subtractor32
- (
- .clk (clk),
- .a (a_din),
- .b (b_din),
- .d (sub32_d),
- .b_in (sub32_b_in),
- .b_out (sub32_b_out)
- );
-
-
- //
- // Adder
- //
- wire [31: 0] add32_s;
- wire add32_c_in;
- wire add32_c_out;
-
- `ED25519_ADD32_PRIMITIVE adder32
- (
- .clk (clk),
- .a (sub32_d),
- .b (n_din),
- .s (add32_s),
- .c_in (add32_c_in),
- .c_out (add32_c_out)
- );
-
-
- //
- // FSM
- //
-
- localparam FSM_SHREG_WIDTH = 2*OPERAND_NUM_WORDS + 5;
-
- reg [FSM_SHREG_WIDTH-1:0] fsm_shreg;
-
- assign rdy = fsm_shreg[0];
-
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_ab = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 1) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 0)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_n = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 2) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 1)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_store_dif_ab = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 3) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 2)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_store_dif_ab_n = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 4) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 3)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_store_data_d = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 4) : FSM_SHREG_WIDTH - (2 * OPERAND_NUM_WORDS + 3)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_d = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 5) : FSM_SHREG_WIDTH - (2 * OPERAND_NUM_WORDS + 4)];
-
- wire fsm_latch_msb_borrow = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 2)];
-
- wire inc_index_ab = |fsm_shreg_inc_index_ab;
- wire inc_index_n = |fsm_shreg_inc_index_n;
- wire store_dif_ab = |fsm_shreg_store_dif_ab;
- wire store_dif_ab_n = |fsm_shreg_store_dif_ab_n;
- wire store_data_d = |fsm_shreg_store_data_d;
- wire inc_index_d = |fsm_shreg_inc_index_d;
-
- always @(posedge clk or negedge rst_n)
- //
- if (rst_n == 1'b0)
- //
- fsm_shreg <= {{FSM_SHREG_WIDTH-1{1'b0}}, 1'b1};
- //
- else begin
- //
- if (rdy) fsm_shreg <= {ena, {FSM_SHREG_WIDTH-2{1'b0}}, ~ena};
- //
- else fsm_shreg <= {1'b0, fsm_shreg[FSM_SHREG_WIDTH-1:1]};
- //
- end
-
-
- //
- // Borrow & Carry Masking Logic
- //
- reg sub32_b_mask;
- reg add32_c_mask;
-
-
- always @(posedge clk) begin
- //
- sub32_b_mask <= (index_ab == WORD_INDEX_ZERO) ? 1'b1 : 1'b0;
- add32_c_mask <= (index_n == WORD_INDEX_ZERO) ? 1'b1 : 1'b0;
- //
- end
-
- assign sub32_b_in = sub32_b_out & ~sub32_b_mask;
- assign add32_c_in = add32_c_out & ~add32_c_mask;
-
-
-
- //
- // Borrow & Carry Latch Logic
- //
- reg sub32_borrow_latch;
-
- always @(posedge clk) begin
- //
- if (fsm_latch_msb_borrow) sub32_borrow_latch <= sub32_b_out;
- //
- end
-
-
- //
- // Intermediate Results
- //
- reg [32*OPERAND_NUM_WORDS-1:0] d_ab;
- reg [32*OPERAND_NUM_WORDS-1:0] d_ab_n;
-
- always @(posedge clk)
- //
- if (store_data_d) begin
- //
- d_ab <= {{32{1'bX}}, d_ab[32*OPERAND_NUM_WORDS-1:32]};
- d_ab_n <= {{32{1'bX}}, d_ab_n[32*OPERAND_NUM_WORDS-1:32]};
- //
- end else begin
- //
- if (store_dif_ab) d_ab <= {sub32_d, d_ab[32*OPERAND_NUM_WORDS-1:32]};
- if (store_dif_ab_n) d_ab_n <= {add32_s, d_ab_n[32*OPERAND_NUM_WORDS-1:32]};
- //
- end
-
-
- //
- // Word Index Increment Logic
- //
- always @(posedge clk)
- //
- if (rdy) begin
- //
- index_ab <= WORD_INDEX_ZERO;
- index_n <= WORD_INDEX_ZERO;
- index_d <= WORD_INDEX_ZERO;
- //
- end else begin
- //
- if (inc_index_ab) index_ab <= WORD_INDEX_NEXT_OR_ZERO(index_ab);
- if (inc_index_n) index_n <= WORD_INDEX_NEXT_OR_ZERO(index_n);
- if (inc_index_d) index_d <= WORD_INDEX_NEXT_OR_ZERO(index_d);
- //
- end
-
-
- //
- // Output Sum Selector
- //
- wire mux_select_ab_n = sub32_borrow_latch;
-
-
- //
- // Output Data and Write Enable Logic
- //
- reg d_wren_reg;
- reg [31: 0] d_dout_reg;
- wire [31: 0] d_dout_mux = mux_select_ab_n ? d_ab_n[31:0] : d_ab[31:0];
-
- assign d_wren = d_wren_reg;
- assign d_dout = d_dout_reg;
-
- always @(posedge clk)
- //
- if (rdy) begin
- //
- d_wren_reg <= 1'b0;
- d_dout_reg <= {32{1'bX}};
- //
- end else begin
- //
- d_wren_reg <= store_data_d;
- d_dout_reg <= store_data_d ? d_dout_mux : {32{1'bX}};
- //
- end
-
-
-endmodule
-
-
-//------------------------------------------------------------------------------
-// End-of-File
-//------------------------------------------------------------------------------
diff --git a/mw_mover.v b/mw_mover.v
deleted file mode 100644
index 9a88150..0000000
--- a/mw_mover.v
+++ /dev/null
@@ -1,170 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// mw_mover.v
-// -----------------------------------------------------------------------------
-// Multi-word data mover.
-//
-// Authors: Pavel Shatov
-//
-// Copyright (c) 2015-2016, NORDUnet A/S
-//
-// 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 mw_mover
-(
- clk, rst_n,
- ena, rdy,
- x_addr, y_addr, y_wren,
- x_din, y_dout
-);
-
-
- //
- // Parameters
- //
- parameter WORD_COUNTER_WIDTH = 3;
- parameter OPERAND_NUM_WORDS = 8;
-
-
- //
- // Handy Numbers
- //
- localparam [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_ZERO = 0;
- localparam [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_LAST = OPERAND_NUM_WORDS - 1;
-
-
- //
- // Handy Functions
- //
- function [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_NEXT_OR_ZERO;
- input [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_CURRENT;
- begin
- WORD_INDEX_NEXT_OR_ZERO = (WORD_INDEX_CURRENT < WORD_INDEX_LAST) ?
- WORD_INDEX_CURRENT + 1'b1 : WORD_INDEX_ZERO;
- end
- endfunction
-
-
- //
- // Ports
- //
- input clk; // system clock
- input rst_n; // active-low async reset
-
- input ena; // enable input
- output rdy; // ready output
-
- output [WORD_COUNTER_WIDTH-1:0] x_addr; // address of current X word
- output [WORD_COUNTER_WIDTH-1:0] y_addr; // address of current Y word
- output y_wren; // store current Y word
-
- input [ 32-1:0] x_din; // current X word
- output [ 32-1:0] y_dout; // current Y word
-
-
- //
- // Word Indices
- //
- reg [WORD_COUNTER_WIDTH-1:0] index_x;
- reg [WORD_COUNTER_WIDTH-1:0] index_y;
-
-
- //
- // Output Mapping
- //
- assign x_addr = index_x;
- assign y_addr = index_y;
-
-
- //
- // FSM
- //
- localparam FSM_SHREG_WIDTH = 1 * OPERAND_NUM_WORDS + 2;
- localparam [FSM_SHREG_WIDTH-1:0] FSM_SHREG_INIT = {{(FSM_SHREG_WIDTH-1){1'b0}}, 1'b1};
-
- reg [FSM_SHREG_WIDTH-1:0] fsm_shreg = FSM_SHREG_INIT;
-
- assign rdy = fsm_shreg[0];
-
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_x = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 1) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 0)];
- wire [OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_y = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 2) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 1)];
-
- wire inc_index_x = |fsm_shreg_inc_index_x;
- wire inc_index_y = |fsm_shreg_inc_index_y;
- wire store_word_y = |fsm_shreg_inc_index_x;
-
-
- always @(posedge clk or negedge rst_n)
- //
- if (rst_n == 1'b0) fsm_shreg <= FSM_SHREG_INIT;
- else begin
- if (rdy) fsm_shreg <= {ena, {FSM_SHREG_WIDTH-2{1'b0}}, ~ena};
- else fsm_shreg <= {1'b0, fsm_shreg[FSM_SHREG_WIDTH-1:1]};
- end
-
-
- //
- // Word Index Increment Logic
- //
- always @(posedge clk)
- //
- if (rdy) begin
- index_x <= WORD_INDEX_ZERO;
- index_y <= WORD_INDEX_ZERO;
- end else begin
- if (inc_index_x) index_x <= WORD_INDEX_NEXT_OR_ZERO(index_x);
- if (inc_index_y) index_y <= WORD_INDEX_NEXT_OR_ZERO(index_y);
- end
-
-
- //
- // Write Enable Logic
- //
- reg y_wren_reg;
-
- assign y_wren = y_wren_reg;
-
- always @(posedge clk)
- //
- if (rdy) y_wren_reg <= 1'b0;
- else y_wren_reg <= store_word_y;
-
-
- //
- // Output Logic
- //
- assign y_dout = x_din;
-
-
-endmodule
-
-
-//------------------------------------------------------------------------------
-// End-of-File
-//------------------------------------------------------------------------------