aboutsummaryrefslogtreecommitdiff
path: root/rtl
diff options
context:
space:
mode:
authorPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2018-12-19 15:34:55 +0300
committerPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2018-12-19 15:41:00 +0300
commitc617c0c711620f58eb3ead22edcdfe57fed06088 (patch)
tree8c15184d5ca6403ea01843560394f6d909a0986f /rtl
parentea4d251c81c8b53e0bbc71cd1719dfea4d0517c1 (diff)
* Rewritten from scratch, uses the same hardware architecture as the Ed25519HEADmaster
core for better timing performance * Removed custom modular inversion sub-module, now uses micro-coded modular inversion routine based on Fermat's little theorem (~10% faster) * Uses math primitives from core/lib * Added randomized test vector (see user/shatov/ecdsa_fpga_model/test_vectors/)
Diffstat (limited to 'rtl')
-rw-r--r--rtl/curve/curve_dbl_add_256.v893
-rw-r--r--rtl/curve/curve_mul_256.v719
-rw-r--r--rtl/curve/rom/brom_p256_delta.v68
-rw-r--r--rtl/curve/rom/brom_p256_g_x.v68
-rw-r--r--rtl/curve/rom/brom_p256_g_y.v68
-rw-r--r--rtl/curve/rom/brom_p256_h_x.v68
-rw-r--r--rtl/curve/rom/brom_p256_h_y.v68
-rw-r--r--rtl/curve/rom/brom_p256_one.v68
-rw-r--r--rtl/curve/rom/brom_p256_q.v68
-rw-r--r--rtl/curve/rom/brom_p256_zero.v70
-rw-r--r--rtl/ecdsa256.v160
-rw-r--r--rtl/ecdsa256_banks_array.v119
-rw-r--r--rtl/ecdsa256_base_point_multiplier.v310
-rw-r--r--rtl/ecdsa256_core_top.v150
-rw-r--r--rtl/ecdsa256_microcode_rom.v424
-rw-r--r--rtl/ecdsa256_operand_bank.v160
-rw-r--r--rtl/ecdsa256_uop_worker.v604
-rw-r--r--rtl/ecdsa256_wrapper.v72
-rw-r--r--rtl/modular/modular_multiplier_256.v402
-rw-r--r--rtl/modular/modular_reductor_256.v692
20 files changed, 1803 insertions, 3448 deletions
diff --git a/rtl/curve/curve_dbl_add_256.v b/rtl/curve/curve_dbl_add_256.v
deleted file mode 100644
index 1fb1bea..0000000
--- a/rtl/curve/curve_dbl_add_256.v
+++ /dev/null
@@ -1,893 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// curve_dbl_add_256.v
-// -----------------------------------------------------------------------------
-// Elliptic curve point adder and doubler.
-//
-// Authors: Pavel Shatov
-//
-// Copyright (c) 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 curve_dbl_add_256
- (
- clk, rst_n,
- ena, rdy,
- uop_addr, uop,
- px_addr, py_addr, pz_addr, rx_addr, ry_addr, rz_addr, q_addr, v_addr,
- rx_wren, ry_wren, rz_wren,
- px_din, py_din, pz_din,
- rx_din, ry_din, rz_din,
- rx_dout, ry_dout, rz_dout, q_din, v_din
- );
-
-
- //
- // Microcode
- //
-`include "../../../../math/ecdsalib/rtl/curve/uop_ecdsa.v"
-
-
- //
- // Constants
- //
- localparam WORD_COUNTER_WIDTH = 3; // 0 .. 7
- localparam OPERAND_NUM_WORDS = 8; // 8 * 32 = 256
-
-
- //
- // 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 reg [ 6-1: 0] uop_addr;
- input wire [20-1: 0] uop;
-
- output reg [WORD_COUNTER_WIDTH-1:0] px_addr;
- output reg [WORD_COUNTER_WIDTH-1:0] py_addr;
- output reg [WORD_COUNTER_WIDTH-1:0] pz_addr;
- output reg [WORD_COUNTER_WIDTH-1:0] rx_addr;
- output reg [WORD_COUNTER_WIDTH-1:0] ry_addr;
- output reg [WORD_COUNTER_WIDTH-1:0] rz_addr;
- output reg [WORD_COUNTER_WIDTH-1:0] v_addr;
- output wire [WORD_COUNTER_WIDTH-1:0] q_addr;
-
- output wire rx_wren;
- output wire ry_wren;
- output wire rz_wren;
-
- input wire [ 32-1:0] px_din;
- input wire [ 32-1:0] py_din;
- input wire [ 32-1:0] pz_din;
- input wire [ 32-1:0] rx_din;
- input wire [ 32-1:0] ry_din;
- input wire [ 32-1:0] rz_din;
- output wire [ 32-1:0] rx_dout;
- output wire [ 32-1:0] ry_dout;
- output wire [ 32-1:0] rz_dout;
- input wire [ 32-1:0] q_din;
- input wire [ 32-1:0] v_din;
-
-
- //
- // Microcode
- //
- wire [ 4: 0] uop_opcode = uop[19:15];
- wire [ 4: 0] uop_src_a = uop[14:10];
- wire [ 4: 0] uop_src_b = uop[ 9: 5];
- wire [ 2: 0] uop_dst = uop[ 4: 2];
- wire [ 1: 0] uop_exec = uop[ 1: 0];
-
-
- //
- // Multi-Word Comparator
- //
- wire mw_cmp_ena;
- wire mw_cmp_rdy;
-
- wire mw_cmp_out_l;
- wire mw_cmp_out_e;
- wire mw_cmp_out_g;
-
- wire [WORD_COUNTER_WIDTH-1:0] mw_cmp_addr_xy;
-
- wire [ 32-1:0] mw_cmp_din_x;
- wire [ 32-1:0] mw_cmp_din_y;
-
- // flags
- reg flag_pz_is_zero;
- reg flag_t1_is_zero;
- reg flag_t2_is_zero;
-
- mw_comparator #
- (
- .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH),
- .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS)
- )
- mw_comparator_inst
- (
- .clk (clk),
- .rst_n (rst_n),
-
- .ena (mw_cmp_ena),
- .rdy (mw_cmp_rdy),
-
- .xy_addr (mw_cmp_addr_xy),
- .x_din (mw_cmp_din_x),
- .y_din (mw_cmp_din_y),
-
- .cmp_l (mw_cmp_out_l),
- .cmp_e (mw_cmp_out_e),
- .cmp_g (mw_cmp_out_g)
- );
-
-
- //
- // Modular Adder
- //
- wire mod_add_ena;
- wire mod_add_rdy;
-
- wire [WORD_COUNTER_WIDTH-1:0] mod_add_addr_ab;
- wire [WORD_COUNTER_WIDTH-1:0] mod_add_addr_n;
- wire [WORD_COUNTER_WIDTH-1:0] mod_add_addr_s;
- wire mod_add_wren_s;
-
- wire [ 32-1:0] mod_add_din_a;
- wire [ 32-1:0] mod_add_din_b;
- wire [ 32-1:0] mod_add_din_n;
- wire [ 32-1:0] mod_add_dout_s;
-
- assign mod_add_din_n = q_din;
-
- modular_adder #
- (
- .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH),
- .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS)
- )
- modular_adder_inst
- (
- .clk (clk),
- .rst_n (rst_n),
-
- .ena (mod_add_ena),
- .rdy (mod_add_rdy),
-
- .ab_addr (mod_add_addr_ab),
- .n_addr (mod_add_addr_n),
- .s_addr (mod_add_addr_s),
- .s_wren (mod_add_wren_s),
-
- .a_din (mod_add_din_a),
- .b_din (mod_add_din_b),
- .n_din (mod_add_din_n),
- .s_dout (mod_add_dout_s)
- );
-
-
- //
- // Modular Subtractor
- //
- wire mod_sub_ena;
- wire mod_sub_rdy;
-
- wire [WORD_COUNTER_WIDTH-1:0] mod_sub_addr_ab;
- wire [WORD_COUNTER_WIDTH-1:0] mod_sub_addr_n;
- wire [WORD_COUNTER_WIDTH-1:0] mod_sub_addr_d;
- wire mod_sub_wren_d;
-
- wire [ 32-1:0] mod_sub_din_a;
- wire [ 32-1:0] mod_sub_din_b;
- wire [ 32-1:0] mod_sub_din_n;
- wire [ 32-1:0] mod_sub_dout_d;
-
- assign mod_sub_din_n = q_din;
-
- modular_subtractor #
- (
- .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH),
- .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS)
- )
- modular_subtractor_inst
- (
- .clk (clk),
- .rst_n (rst_n),
-
- .ena (mod_sub_ena),
- .rdy (mod_sub_rdy),
-
- .ab_addr (mod_sub_addr_ab),
- .n_addr (mod_sub_addr_n),
- .d_addr (mod_sub_addr_d),
- .d_wren (mod_sub_wren_d),
-
- .a_din (mod_sub_din_a),
- .b_din (mod_sub_din_b),
- .n_din (mod_sub_din_n),
- .d_dout (mod_sub_dout_d)
- );
-
-
- //
- // Modular Multiplier
- //
- wire mod_mul_ena;
- wire mod_mul_rdy;
-
- wire [WORD_COUNTER_WIDTH-1:0] mod_mul_addr_a;
- wire [WORD_COUNTER_WIDTH-1:0] mod_mul_addr_b;
- wire [WORD_COUNTER_WIDTH-1:0] mod_mul_addr_n;
- wire [WORD_COUNTER_WIDTH-1:0] mod_mul_addr_p;
- wire mod_mul_wren_p;
-
- wire [ 32-1:0] mod_mul_din_a;
- wire [ 32-1:0] mod_mul_din_b;
- wire [ 32-1:0] mod_mul_din_n;
- wire [ 32-1:0] mod_mul_dout_p;
-
- assign mod_mul_din_n = q_din;
-
- modular_multiplier_256 modular_multiplier_inst
- (
- .clk (clk),
- .rst_n (rst_n),
-
- .ena (mod_mul_ena),
- .rdy (mod_mul_rdy),
-
- .a_addr (mod_mul_addr_a),
- .b_addr (mod_mul_addr_b),
- .n_addr (mod_mul_addr_n),
- .p_addr (mod_mul_addr_p),
- .p_wren (mod_mul_wren_p),
-
- .a_din (mod_mul_din_a),
- .b_din (mod_mul_din_b),
- .n_din (mod_mul_din_n),
- .p_dout (mod_mul_dout_p)
- );
-
-
- //
- // Multi-Word Data Mover
- //
- wire mw_mov_ena;
- wire mw_mov_rdy;
-
- wire [WORD_COUNTER_WIDTH-1:0] mw_mov_addr_x;
- wire [WORD_COUNTER_WIDTH-1:0] mw_mov_addr_y;
- wire mw_mov_wren_y;
-
- wire [ 32-1:0] mw_mov_din_x;
- wire [ 32-1:0] mw_mov_dout_y;
-
- mw_mover #
- (
- .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH),
- .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS)
-
- )
- mw_mover_inst
- (
- .clk (clk),
- .rst_n (rst_n),
-
- .ena (mw_mov_ena),
- .rdy (mw_mov_rdy),
-
- .x_addr (mw_mov_addr_x),
- .y_addr (mw_mov_addr_y),
- .y_wren (mw_mov_wren_y),
-
- .x_din (mw_mov_din_x),
- .y_dout (mw_mov_dout_y)
- );
-
-
- //
- // ROMs
- //
- reg [WORD_COUNTER_WIDTH-1:0] brom_one_addr;
- //reg [WORD_COUNTER_WIDTH-1:0] brom_zero_addr;
- reg [WORD_COUNTER_WIDTH-1:0] brom_delta_addr;
- reg [WORD_COUNTER_WIDTH-1:0] brom_g_x_addr;
- reg [WORD_COUNTER_WIDTH-1:0] brom_g_y_addr;
- reg [WORD_COUNTER_WIDTH-1:0] brom_h_x_addr;
- reg [WORD_COUNTER_WIDTH-1:0] brom_h_y_addr;
-
- wire [ 32-1:0] brom_one_dout;
- wire [ 32-1:0] brom_zero_dout;
- wire [ 32-1:0] brom_delta_dout;
- wire [ 32-1:0] brom_g_x_dout;
- wire [ 32-1:0] brom_g_y_dout;
- wire [ 32-1:0] brom_h_x_dout;
- wire [ 32-1:0] brom_h_y_dout;
-
- (* ROM_STYLE="BLOCK" *) brom_p256_one brom_one_inst
- (.clk(clk), .b_addr(brom_one_addr), .b_out(brom_one_dout));
-
- brom_p256_zero brom_zero_inst
- (.b_out(brom_zero_dout));
-
- (* ROM_STYLE="BLOCK" *) brom_p256_delta brom_delta_inst
- (.clk(clk), .b_addr(brom_delta_addr), .b_out(brom_delta_dout));
-
- (* ROM_STYLE="BLOCK" *) brom_p256_g_x brom_g_x_inst
- (.clk(clk), .b_addr(brom_g_x_addr), .b_out(brom_g_x_dout));
-
- (* ROM_STYLE="BLOCK" *) brom_p256_g_y brom_g_y_inst
- (.clk(clk), .b_addr(brom_g_y_addr), .b_out(brom_g_y_dout));
-
- (* ROM_STYLE="BLOCK" *) brom_p256_h_x brom_h_x_inst
- (.clk(clk), .b_addr(brom_h_x_addr), .b_out(brom_h_x_dout));
-
- (* ROM_STYLE="BLOCK" *) brom_p256_h_y brom_h_y_inst
- (.clk(clk), .b_addr(brom_h_y_addr), .b_out(brom_h_y_dout));
-
-
- //
- // Temporary Variables
- //
- reg [WORD_COUNTER_WIDTH-1:0] bram_t1_wr_addr;
- reg [WORD_COUNTER_WIDTH-1:0] bram_t2_wr_addr;
- reg [WORD_COUNTER_WIDTH-1:0] bram_t3_wr_addr;
- reg [WORD_COUNTER_WIDTH-1:0] bram_t4_wr_addr;
-
- reg [WORD_COUNTER_WIDTH-1:0] bram_t1_rd_addr;
- reg [WORD_COUNTER_WIDTH-1:0] bram_t2_rd_addr;
- reg [WORD_COUNTER_WIDTH-1:0] bram_t3_rd_addr;
- reg [WORD_COUNTER_WIDTH-1:0] bram_t4_rd_addr;
-
- wire bram_t1_wr_en;
- wire bram_t2_wr_en;
- wire bram_t3_wr_en;
- wire bram_t4_wr_en;
-
- wire [ 32-1:0] bram_t1_wr_data;
- wire [ 32-1:0] bram_t2_wr_data;
- wire [ 32-1:0] bram_t3_wr_data;
- wire [ 32-1:0] bram_t4_wr_data;
-
- wire [ 32-1:0] bram_t1_rd_data;
- wire [ 32-1:0] bram_t2_rd_data;
- wire [ 32-1:0] bram_t3_rd_data;
- wire [ 32-1:0] bram_t4_rd_data;
-
- bram_1rw_1ro_readfirst #
- ( .MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)
- )
- bram_t1
- ( .clk (clk),
- .a_addr(bram_t1_wr_addr), .a_wr(bram_t1_wr_en), .a_in(bram_t1_wr_data), .a_out(),
- .b_addr(bram_t1_rd_addr), .b_out(bram_t1_rd_data)
- );
-
- bram_1rw_1ro_readfirst #
- ( .MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)
- )
- bram_t2
- ( .clk (clk),
- .a_addr(bram_t2_wr_addr), .a_wr(bram_t2_wr_en), .a_in(bram_t2_wr_data), .a_out(),
- .b_addr(bram_t2_rd_addr), .b_out(bram_t2_rd_data)
- );
-
- bram_1rw_1ro_readfirst #
- ( .MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)
- )
- bram_t3
- ( .clk (clk),
- .a_addr(bram_t3_wr_addr), .a_wr(bram_t3_wr_en), .a_in(bram_t3_wr_data), .a_out(),
- .b_addr(bram_t3_rd_addr), .b_out(bram_t3_rd_data)
- );
-
- bram_1rw_1ro_readfirst #
- ( .MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)
- )
- bram_t4
- ( .clk (clk),
- .a_addr(bram_t4_wr_addr), .a_wr(bram_t4_wr_en), .a_in(bram_t4_wr_data), .a_out(),
- .b_addr(bram_t4_rd_addr), .b_out(bram_t4_rd_data)
- );
-
-
- //
- // uOP Trigger Logic
- //
- (* EQUIVALENT_REGISTER_REMOVAL="NO" *) reg uop_trig_fsm;
- (* EQUIVALENT_REGISTER_REMOVAL="NO" *) reg uop_trig_cmp;
- (* EQUIVALENT_REGISTER_REMOVAL="NO" *) reg uop_trig_mov;
- (* EQUIVALENT_REGISTER_REMOVAL="NO" *) reg uop_trig_add;
- (* EQUIVALENT_REGISTER_REMOVAL="NO" *) reg uop_trig_sub;
- (* EQUIVALENT_REGISTER_REMOVAL="NO" *) reg uop_trig_mul;
-
- always @(posedge clk or negedge rst_n)
- //
- if (rst_n == 1'b0) begin
- uop_trig_fsm <= 1'b0;
- uop_trig_cmp <= 1'b0;
- uop_trig_mov <= 1'b0;
- uop_trig_add <= 1'b0;
- uop_trig_sub <= 1'b0;
- uop_trig_mul <= 1'b0;
- end else begin
- uop_trig_fsm <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0;
- uop_trig_cmp <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0;
- uop_trig_mov <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0;
- uop_trig_add <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0;
- uop_trig_sub <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0;
- uop_trig_mul <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0;
- end
-
-
- //
- // FSM
- //
- localparam [ 1: 0] FSM_STATE_STALL = 2'b00;
- localparam [ 1: 0] FSM_STATE_FETCH = 2'b01;
- localparam [ 1: 0] FSM_STATE_EXECUTE = 2'b10;
-
- reg [ 1: 0] fsm_state = FSM_STATE_STALL;
- wire [ 1: 0] fsm_state_next = (uop_opcode == OPCODE_RDY) ? FSM_STATE_STALL : FSM_STATE_FETCH;
-
-
- //
- // FSM Transition Logic
- //
- reg uop_done;
-
- always @(posedge clk or negedge rst_n)
- //
- if (rst_n == 1'b0) fsm_state <= FSM_STATE_STALL;
- else case (fsm_state)
- FSM_STATE_STALL: fsm_state <= ena ? FSM_STATE_FETCH : FSM_STATE_STALL;
- FSM_STATE_FETCH: fsm_state <= FSM_STATE_EXECUTE;
- FSM_STATE_EXECUTE: fsm_state <= (!uop_trig_fsm && uop_done) ? fsm_state_next : FSM_STATE_EXECUTE;
- default: fsm_state <= FSM_STATE_STALL;
- endcase
-
-
- //
- // uOP Address Increment Logic
- //
- always @(posedge clk)
- //
- if (fsm_state == FSM_STATE_STALL)
- uop_addr <= 5'd0;
- else if (fsm_state == FSM_STATE_EXECUTE)
- if (!uop_trig_fsm && uop_done)
- uop_addr <= (uop_opcode == OPCODE_RDY) ? 5'd0 : uop_addr + 1'b1;
-
-
- //
- // uOP Completion Logic
- //
- always @(*)
- //
- case (uop_opcode)
- OPCODE_CMP: uop_done = mw_cmp_rdy;
- OPCODE_MOV: uop_done = mw_mov_rdy;
- OPCODE_ADD: uop_done = mod_add_rdy;
- OPCODE_SUB: uop_done = mod_sub_rdy;
- OPCODE_MUL: uop_done = mod_mul_rdy;
- OPCODE_RDY: uop_done = 1'b1;
- default: uop_done = 1'b0;
- endcase
-
-
- //
- // Helper Modules Enable Logic
- //
- assign mw_cmp_ena = uop_opcode[0] & uop_trig_cmp;
- assign mw_mov_ena = uop_opcode[1] & uop_trig_mov;
- assign mod_add_ena = uop_opcode[2] & uop_trig_add;
- assign mod_sub_ena = uop_opcode[3] & uop_trig_sub;
- assign mod_mul_ena = uop_opcode[4] & uop_trig_mul;
-
-
- //
- // uOP Source Value Decoding Logic
- //
- reg [31: 0] uop_src_a_value;
-
- always @(*)
- //
- case (uop_src_a)
- UOP_SRC_PX: uop_src_a_value = px_din;
- UOP_SRC_PY: uop_src_a_value = py_din;
- UOP_SRC_PZ: uop_src_a_value = pz_din;
-
- UOP_SRC_RX: uop_src_a_value = rx_din;
- UOP_SRC_RY: uop_src_a_value = ry_din;
- UOP_SRC_RZ: uop_src_a_value = rz_din;
-
- UOP_SRC_T1: uop_src_a_value = bram_t1_rd_data;
- UOP_SRC_T2: uop_src_a_value = bram_t2_rd_data;
- UOP_SRC_T3: uop_src_a_value = bram_t3_rd_data;
- UOP_SRC_T4: uop_src_a_value = bram_t4_rd_data;
-
- UOP_SRC_ONE: uop_src_a_value = brom_one_dout;
- UOP_SRC_ZERO: uop_src_a_value = brom_zero_dout;
- UOP_SRC_DELTA: uop_src_a_value = brom_delta_dout;
-
- UOP_SRC_G_X: uop_src_a_value = brom_g_x_dout;
- UOP_SRC_G_Y: uop_src_a_value = brom_g_y_dout;
-
- UOP_SRC_H_X: uop_src_a_value = brom_h_x_dout;
- UOP_SRC_H_Y: uop_src_a_value = brom_h_y_dout;
-
- UOP_SRC_V: uop_src_a_value = v_din;
-
- default: uop_src_a_value = {32{1'bX}};
- endcase
-
-
- assign mw_cmp_din_x = uop_src_a_value;
- assign mw_mov_din_x = uop_src_a_value;
- assign mod_add_din_a = uop_src_a_value;
- assign mod_sub_din_a = uop_src_a_value;
- assign mod_mul_din_a = uop_src_a_value;
-
- reg [31: 0] uop_src_b_value;
-
- always @(*)
- //
- case (uop_src_b)
- UOP_SRC_PX: uop_src_b_value = px_din;
- UOP_SRC_PY: uop_src_b_value = py_din;
- UOP_SRC_PZ: uop_src_b_value = pz_din;
-
- UOP_SRC_RX: uop_src_b_value = rx_din;
- UOP_SRC_RY: uop_src_b_value = ry_din;
- UOP_SRC_RZ: uop_src_b_value = rz_din;
-
- UOP_SRC_T1: uop_src_b_value = bram_t1_rd_data;
- UOP_SRC_T2: uop_src_b_value = bram_t2_rd_data;
- UOP_SRC_T3: uop_src_b_value = bram_t3_rd_data;
- UOP_SRC_T4: uop_src_b_value = bram_t4_rd_data;
-
- UOP_SRC_ONE: uop_src_b_value = brom_one_dout;
- UOP_SRC_ZERO: uop_src_b_value = brom_zero_dout;
- UOP_SRC_DELTA: uop_src_b_value = brom_delta_dout;
-
- UOP_SRC_G_X: uop_src_b_value = brom_g_x_dout;
- UOP_SRC_G_Y: uop_src_b_value = brom_g_y_dout;
-
- UOP_SRC_H_X: uop_src_b_value = brom_h_x_dout;
- UOP_SRC_H_Y: uop_src_b_value = brom_h_y_dout;
-
- UOP_SRC_V: uop_src_b_value = v_din;
-
- default: uop_src_b_value = {32{1'bX}};
- endcase
-
- assign mw_cmp_din_y = uop_src_b_value;
- assign mod_add_din_b = uop_src_b_value;
- assign mod_sub_din_b = uop_src_b_value;
- assign mod_mul_din_b = uop_src_b_value;
-
-
- //
- // uOP Source & Destination Address Decoding Logic
- //
- reg [WORD_COUNTER_WIDTH-1:0] uop_src_a_addr;
- reg [WORD_COUNTER_WIDTH-1:0] uop_src_b_addr;
- reg [WORD_COUNTER_WIDTH-1:0] uop_dst_addr;
- reg [WORD_COUNTER_WIDTH-1:0] uop_q_addr;
-
- assign q_addr = uop_q_addr;
-
- always @(*)
- //
- case (uop_opcode)
- //
- OPCODE_CMP: begin
- uop_src_a_addr = mw_cmp_addr_xy;
- uop_src_b_addr = mw_cmp_addr_xy;
- uop_dst_addr = {WORD_COUNTER_WIDTH{1'bX}};
- uop_q_addr = {WORD_COUNTER_WIDTH{1'bX}};
- end
- //
- OPCODE_MOV: begin
- uop_src_a_addr = mw_mov_addr_x;
- uop_src_b_addr = {WORD_COUNTER_WIDTH{1'bX}};
- uop_dst_addr = mw_mov_addr_y;
- uop_q_addr = {WORD_COUNTER_WIDTH{1'bX}};
- end
- //
- OPCODE_ADD: begin
- uop_src_a_addr = mod_add_addr_ab;
- uop_src_b_addr = mod_add_addr_ab;
- uop_dst_addr = mod_add_addr_s;
- uop_q_addr = mod_add_addr_n;
- end
- //
- OPCODE_SUB: begin
- uop_src_a_addr = mod_sub_addr_ab;
- uop_src_b_addr = mod_sub_addr_ab;
- uop_dst_addr = mod_sub_addr_d;
- uop_q_addr = mod_sub_addr_n;
- end
- //
- OPCODE_MUL: begin
- uop_src_a_addr = mod_mul_addr_a;
- uop_src_b_addr = mod_mul_addr_b;
- uop_dst_addr = mod_mul_addr_p;
- uop_q_addr = mod_mul_addr_n;
- end
- //
- default: begin
- uop_src_a_addr = {WORD_COUNTER_WIDTH{1'bX}};
- uop_src_b_addr = {WORD_COUNTER_WIDTH{1'bX}};
- uop_dst_addr = {WORD_COUNTER_WIDTH{1'bX}};
- uop_q_addr = {WORD_COUNTER_WIDTH{1'bX}};
- end
- //
- endcase
-
-
- //
- // uOP Conditional Execution Logic
- //
- reg uop_exec_effective;
-
- always @(*)
- //
- case (uop_exec)
- UOP_EXEC_ALWAYS: uop_exec_effective = 1'b1;
- UOP_EXEC_PZT1T2_0XX: uop_exec_effective = flag_pz_is_zero;
- UOP_EXEC_PZT1T2_100: uop_exec_effective = !flag_pz_is_zero && flag_t1_is_zero && flag_t2_is_zero;
- UOP_EXEC_PZT1T2_101: uop_exec_effective = !flag_pz_is_zero && flag_t1_is_zero && !flag_t2_is_zero;
- endcase
-
-
- //
- // uOP Destination Store Logic
- //
- reg uop_dst_wren;
-
- always @(*)
- //
- case (uop_opcode)
- //
- OPCODE_MOV: uop_dst_wren = mw_mov_wren_y & uop_exec_effective;
- OPCODE_ADD: uop_dst_wren = mod_add_wren_s;
- OPCODE_SUB: uop_dst_wren = mod_sub_wren_d;
- OPCODE_MUL: uop_dst_wren = mod_mul_wren_p;
- default: uop_dst_wren = 1'b0;
- //
- endcase
-
-
- always @(*) begin
- //
- //
- //
- if (uop_src_a == UOP_SRC_PX) px_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_PX) px_addr = uop_src_b_addr;
- else px_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- if (uop_src_a == UOP_SRC_PY) py_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_PY) py_addr = uop_src_b_addr;
- else py_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- if (uop_src_a == UOP_SRC_PZ) pz_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_PZ) pz_addr = uop_src_b_addr;
- else pz_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- //
- //
- if (uop_src_a == UOP_SRC_ONE) brom_one_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_ONE) brom_one_addr = uop_src_b_addr;
- else brom_one_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- //if (uop_src_a == UOP_SRC_ZERO) brom_zero_addr = uop_src_a_addr;
- //else if (uop_src_b == UOP_SRC_ZERO) brom_zero_addr = uop_src_b_addr;
- //else brom_zero_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- if (uop_src_a == UOP_SRC_DELTA) brom_delta_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_DELTA) brom_delta_addr = uop_src_b_addr;
- else brom_delta_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- //
- //
- if (uop_src_a == UOP_SRC_G_X) brom_g_x_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_G_X) brom_g_x_addr = uop_src_b_addr;
- else brom_g_x_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- if (uop_src_a == UOP_SRC_G_Y) brom_g_y_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_G_Y) brom_g_y_addr = uop_src_b_addr;
- else brom_g_y_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- //
- //
- if (uop_src_a == UOP_SRC_H_X) brom_h_x_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_H_X) brom_h_x_addr = uop_src_b_addr;
- else brom_h_x_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- if (uop_src_a == UOP_SRC_H_Y) brom_h_y_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_H_Y) brom_h_y_addr = uop_src_b_addr;
- else brom_h_y_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- //
- //
- if (uop_src_a == UOP_SRC_V) v_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_V) v_addr = uop_src_b_addr;
- else v_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- //
- //
- if (uop_src_a == UOP_SRC_T1) bram_t1_rd_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_T1) bram_t1_rd_addr = uop_src_b_addr;
- else bram_t1_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- if (uop_src_a == UOP_SRC_T2) bram_t2_rd_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_T2) bram_t2_rd_addr = uop_src_b_addr;
- else bram_t2_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- if (uop_src_a == UOP_SRC_T3) bram_t3_rd_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_T3) bram_t3_rd_addr = uop_src_b_addr;
- else bram_t3_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- if (uop_src_a == UOP_SRC_T4) bram_t4_rd_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_T4) bram_t4_rd_addr = uop_src_b_addr;
- else bram_t4_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- //
- //
- if (uop_dst == UOP_DST_T1) bram_t1_wr_addr = uop_dst_addr;
- else bram_t1_wr_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- if (uop_dst == UOP_DST_T2) bram_t2_wr_addr = uop_dst_addr;
- else bram_t2_wr_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- if (uop_dst == UOP_DST_T3) bram_t3_wr_addr = uop_dst_addr;
- else bram_t3_wr_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- if (uop_dst == UOP_DST_T4) bram_t4_wr_addr = uop_dst_addr;
- else bram_t4_wr_addr = {WORD_COUNTER_WIDTH{1'bX}};
- //
- //
- //
- if ((uop_dst == UOP_DST_RX) && (uop_dst_wren)) rx_addr = uop_dst_addr;
- else begin
- if (uop_src_a == UOP_SRC_RX) rx_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_RX) rx_addr = uop_src_b_addr;
- else rx_addr = {WORD_COUNTER_WIDTH{1'bX}};
- end
- //
- if ((uop_dst == UOP_DST_RY) && (uop_dst_wren)) ry_addr = uop_dst_addr;
- else begin
- if (uop_src_a == UOP_SRC_RY) ry_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_RY) ry_addr = uop_src_b_addr;
- else ry_addr = {WORD_COUNTER_WIDTH{1'bX}};
- end
- //
- if ((uop_dst == UOP_DST_RZ) && (uop_dst_wren)) rz_addr = uop_dst_addr;
- else begin
- if (uop_src_a == UOP_SRC_RZ) rz_addr = uop_src_a_addr;
- else if (uop_src_b == UOP_SRC_RZ) rz_addr = uop_src_b_addr;
- else rz_addr = {WORD_COUNTER_WIDTH{1'bX}};
- end
- //
- end
-
-
- assign rx_wren = uop_dst_wren && (uop_dst == UOP_DST_RX);
- assign ry_wren = uop_dst_wren && (uop_dst == UOP_DST_RY);
- assign rz_wren = uop_dst_wren && (uop_dst == UOP_DST_RZ);
-
- assign bram_t1_wr_en = uop_dst_wren && (uop_dst == UOP_DST_T1);
- assign bram_t2_wr_en = uop_dst_wren && (uop_dst == UOP_DST_T2);
- assign bram_t3_wr_en = uop_dst_wren && (uop_dst == UOP_DST_T3);
- assign bram_t4_wr_en = uop_dst_wren && (uop_dst == UOP_DST_T4);
-
-
-
- //
- // Destination Value Selector
- //
- reg [31: 0] uop_dst_value;
-
- always @(*)
- //
- case (uop_opcode)
-
- OPCODE_MOV: uop_dst_value = mw_mov_dout_y;
- OPCODE_ADD: uop_dst_value = mod_add_dout_s;
- OPCODE_SUB: uop_dst_value = mod_sub_dout_d;
- OPCODE_MUL: uop_dst_value = mod_mul_dout_p;
-
- default: uop_dst_value = {32{1'bX}};
-
- endcase
-
- assign rx_dout = uop_dst_value;
- assign ry_dout = uop_dst_value;
- assign rz_dout = uop_dst_value;
-
- assign bram_t1_wr_data = uop_dst_value;
- assign bram_t2_wr_data = uop_dst_value;
- assign bram_t3_wr_data = uop_dst_value;
- assign bram_t4_wr_data = uop_dst_value;
-
-
- //
- // Latch Comparison Flags
- //
- always @(posedge clk)
- //
- if ( (fsm_state == FSM_STATE_EXECUTE) &&
- (uop_opcode == OPCODE_CMP) &&
- (uop_done && !uop_trig_cmp) ) begin
-
- if ( (uop_src_a == UOP_SRC_PZ) && (uop_src_b == UOP_SRC_ZERO) )
- flag_pz_is_zero <= !mw_cmp_out_l && mw_cmp_out_e && !mw_cmp_out_g;
-
- if ( (uop_src_a == UOP_SRC_T1) && (uop_src_b == UOP_SRC_ZERO) )
- flag_t1_is_zero <= !mw_cmp_out_l && mw_cmp_out_e && !mw_cmp_out_g;
-
- if ( (uop_src_a == UOP_SRC_T2) && (uop_src_b == UOP_SRC_ZERO) )
- flag_t2_is_zero <= !mw_cmp_out_l && mw_cmp_out_e && !mw_cmp_out_g;
-
- end
-
-
- //
- // Ready Flag Logic
- //
- reg rdy_reg = 1'b1;
- assign rdy = rdy_reg;
-
- always @(posedge clk or negedge rst_n)
- //
- if (rst_n == 1'b0) rdy_reg <= 1'b1;
- else begin
-
- /* clear flag */
- if (fsm_state == FSM_STATE_STALL)
- if (ena) rdy_reg <= 1'b0;
-
- /* set flag */
- if ((fsm_state == FSM_STATE_EXECUTE) && !uop_trig_fsm && uop_done)
- if (uop_opcode == OPCODE_RDY) rdy_reg <= 1'b1;
-
- end
-
-
-endmodule
-
-
-//------------------------------------------------------------------------------
-// End-of-File
-//------------------------------------------------------------------------------
diff --git a/rtl/curve/curve_mul_256.v b/rtl/curve/curve_mul_256.v
deleted file mode 100644
index 43e2c7b..0000000
--- a/rtl/curve/curve_mul_256.v
+++ /dev/null
@@ -1,719 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// curve_mul_256.v
-// -----------------------------------------------------------------------------
-// Elliptic curve point scalar multiplier.
-//
-// 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 curve_mul_256
- (
- clk, rst_n,
- ena, rdy,
- k_addr, rx_addr, ry_addr,
- rx_wren, ry_wren,
- k_din,
- rx_dout, ry_dout
- );
-
-
- //
- // Constants
- //
- localparam WORD_COUNTER_WIDTH = 3; // 0 .. 7
- localparam OPERAND_NUM_WORDS = 8; // 8 * 32 = 256
-
-
- //
- // 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 [ 2: 0] k_addr;
- output wire [ 2: 0] rx_addr;
- output wire [ 2: 0] ry_addr;
-
- output wire rx_wren;
- output wire ry_wren;
-
- input wire [31: 0] k_din;
-
- output wire [31: 0] rx_dout;
- output wire [31: 0] ry_dout;
-
-
- //
- // Temporary Variables
- //
- reg [ 2: 0] bram_tx_wr_addr;
- reg [ 2: 0] bram_ty_wr_addr;
- reg [ 2: 0] bram_tz_wr_addr;
-
- reg [ 2: 0] bram_rx_wr_addr;
- reg [ 2: 0] bram_ry_wr_addr;
- reg [ 2: 0] bram_rz_wr_addr;
- wire [ 2: 0] bram_rz1_wr_addr;
-
- reg [ 2: 0] bram_tx_rd_addr;
- reg [ 2: 0] bram_ty_rd_addr;
- reg [ 2: 0] bram_tz_rd_addr;
-
- reg [ 2: 0] bram_rx_rd_addr;
- reg [ 2: 0] bram_ry_rd_addr;
- reg [ 2: 0] bram_rz_rd_addr;
- wire [ 2: 0] bram_rz1_rd_addr;
-
- reg bram_tx_wr_en;
- reg bram_ty_wr_en;
- reg bram_tz_wr_en;
-
- reg bram_rx_wr_en;
- reg bram_ry_wr_en;
- reg bram_rz_wr_en;
- wire bram_rz1_wr_en;
-
- wire [31: 0] bram_tx_rd_data;
- wire [31: 0] bram_ty_rd_data;
- wire [31: 0] bram_tz_rd_data;
-
- wire [31: 0] bram_rx_rd_data;
- wire [31: 0] bram_ry_rd_data;
- wire [31: 0] bram_rz_rd_data;
- wire [31: 0] bram_rz1_rd_data;
-
- reg [31: 0] bram_tx_wr_data_in;
- reg [31: 0] bram_ty_wr_data_in;
- reg [31: 0] bram_tz_wr_data_in;
-
- reg [31: 0] bram_rx_wr_data_in;
- reg [31: 0] bram_ry_wr_data_in;
- reg [31: 0] bram_rz_wr_data_in;
- wire [31: 0] bram_rz1_wr_data_in;
-
- wire [31: 0] bram_tx_wr_data_out;
- wire [31: 0] bram_ty_wr_data_out;
- wire [31: 0] bram_tz_wr_data_out;
-
- wire [31: 0] bram_rx_wr_data_out;
- wire [31: 0] bram_ry_wr_data_out;
- wire [31: 0] bram_rz_wr_data_out;
-
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
- bram_tx (.clk(clk),
- .a_addr(bram_tx_wr_addr), .a_wr(bram_tx_wr_en), .a_in(bram_tx_wr_data_in), .a_out(bram_tx_wr_data_out),
- .b_addr(bram_tx_rd_addr), .b_out(bram_tx_rd_data));
-
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
- bram_ty (.clk(clk),
- .a_addr(bram_ty_wr_addr), .a_wr(bram_ty_wr_en), .a_in(bram_ty_wr_data_in), .a_out(bram_ty_wr_data_out),
- .b_addr(bram_ty_rd_addr), .b_out(bram_ty_rd_data));
-
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
- bram_tz (.clk(clk),
- .a_addr(bram_tz_wr_addr), .a_wr(bram_tz_wr_en), .a_in(bram_tz_wr_data_in), .a_out(bram_tz_wr_data_out),
- .b_addr(bram_tz_rd_addr), .b_out(bram_tz_rd_data));
-
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
- bram_rx (.clk(clk),
- .a_addr(bram_rx_wr_addr), .a_wr(bram_rx_wr_en), .a_in(bram_rx_wr_data_in), .a_out(bram_rx_wr_data_out),
- .b_addr(bram_rx_rd_addr), .b_out(bram_rx_rd_data));
-
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
- bram_ry (.clk(clk),
- .a_addr(bram_ry_wr_addr), .a_wr(bram_ry_wr_en), .a_in(bram_ry_wr_data_in), .a_out(bram_ry_wr_data_out),
- .b_addr(bram_ry_rd_addr), .b_out(bram_ry_rd_data));
-
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
- bram_rz (.clk(clk),
- .a_addr(bram_rz_wr_addr), .a_wr(bram_rz_wr_en), .a_in(bram_rz_wr_data_in), .a_out(bram_rz_wr_data_out),
- .b_addr(bram_rz_rd_addr), .b_out(bram_rz_rd_data));
-
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
- bram_rz1 (.clk(clk),
- .a_addr(bram_rz1_wr_addr), .a_wr(bram_rz1_wr_en), .a_in(bram_rz1_wr_data_in), .a_out(),
- .b_addr(bram_rz1_rd_addr), .b_out(bram_rz1_rd_data));
-
-
- //
- // FSM
- //
- localparam [ 3: 0] FSM_STATE_IDLE = 4'd00;
- localparam [ 3: 0] FSM_STATE_PREPARE_TRIG = 4'd01;
- localparam [ 3: 0] FSM_STATE_PREPARE_WAIT = 4'd02;
- localparam [ 3: 0] FSM_STATE_DOUBLE_TRIG = 4'd03;
- localparam [ 3: 0] FSM_STATE_DOUBLE_WAIT = 4'd04;
- localparam [ 3: 0] FSM_STATE_ADD_TRIG = 4'd05;
- localparam [ 3: 0] FSM_STATE_ADD_WAIT = 4'd06;
- localparam [ 3: 0] FSM_STATE_COPY_TRIG = 4'd07;
- localparam [ 3: 0] FSM_STATE_COPY_WAIT = 4'd08;
- localparam [ 3: 0] FSM_STATE_INVERT_TRIG = 4'd09;
- localparam [ 3: 0] FSM_STATE_INVERT_WAIT = 4'd10;
- localparam [ 3: 0] FSM_STATE_CONVERT_TRIG = 4'd11;
- localparam [ 3: 0] FSM_STATE_CONVERT_WAIT = 4'd12;
- localparam [ 3: 0] FSM_STATE_DONE = 4'd13;
-
- reg [3:0] fsm_state = FSM_STATE_IDLE;
-
-
- //
- // Round Counter
- //
- reg [ 7: 0] bit_counter;
- wire [ 7: 0] bit_counter_max = 8'd255;
- wire [ 7: 0] bit_counter_zero = 8'd0;
- wire [ 7: 0] bit_counter_next =
- (bit_counter < bit_counter_max) ? bit_counter + 1'b1 : bit_counter_zero;
-
-
- //
- // Round Completion
- //
- wire [ 3: 0] fsm_state_round_next = (bit_counter < bit_counter_max) ?
- FSM_STATE_DOUBLE_TRIG : FSM_STATE_INVERT_TRIG;
-
-
- //
- // OP Trigger Logic
- //
- reg op_trig;
- wire op_done;
-
- always @(posedge clk or negedge rst_n)
- //
- if (rst_n == 1'b0) op_trig <= 1'b0;
- else op_trig <= (fsm_state == FSM_STATE_PREPARE_TRIG) ||
- (fsm_state == FSM_STATE_DOUBLE_TRIG) ||
- (fsm_state == FSM_STATE_ADD_TRIG) ||
- (fsm_state == FSM_STATE_CONVERT_TRIG);
-
- //
- // Microprograms
- //
- wire [ 5: 0] op_rom_addr;
- wire [19: 0] op_rom_init_data;
- wire [19: 0] op_rom_dbl_data;
- wire [19: 0] op_rom_add_data;
- wire [19: 0] op_rom_conv_data;
- reg [19: 0] op_rom_mux_data;
-
- (* EQUIVALENT_REGISTER_REMOVAL="NO" *)
- uop_init_rom op_rom_init
- (
- .clk (clk),
- .addr (op_rom_addr),
- .data (op_rom_init_data)
- );
- (* EQUIVALENT_REGISTER_REMOVAL="NO" *)
- uop_dbl_rom op_rom_dbl
- (
- .clk (clk),
- .addr (op_rom_addr),
- .data (op_rom_dbl_data)
- );
-
- (* EQUIVALENT_REGISTER_REMOVAL="NO" *)
- uop_add_rom op_rom_add
- (
- .clk (clk),
- .addr (op_rom_addr),
- .data (op_rom_add_data)
- );
-
- (* EQUIVALENT_REGISTER_REMOVAL="NO" *)
- uop_conv_rom op_rom_conv
- (
- .clk (clk),
- .addr (op_rom_addr),
- .data (op_rom_conv_data)
- );
-
- always @(*)
- //
- case (fsm_state)
- FSM_STATE_PREPARE_WAIT: op_rom_mux_data = op_rom_init_data;
- FSM_STATE_DOUBLE_WAIT: op_rom_mux_data = op_rom_dbl_data;
- FSM_STATE_ADD_WAIT: op_rom_mux_data = op_rom_add_data;
- FSM_STATE_CONVERT_WAIT: op_rom_mux_data = op_rom_conv_data;
- default: op_rom_mux_data = {20{1'bX}};
- endcase
-
-
-
- //
- // Modulus
- //
- reg [ 2: 0] rom_q_addr;
- wire [31: 0] rom_q_data;
-
- brom_p256_q rom_q
- (
- .clk (clk),
- .b_addr (rom_q_addr),
- .b_out (rom_q_data)
- );
-
-
- //
- // Worker
- //
- wire [ 2: 0] worker_addr_px;
- wire [ 2: 0] worker_addr_py;
- wire [ 2: 0] worker_addr_pz;
-
- wire [ 2: 0] worker_addr_rx;
- wire [ 2: 0] worker_addr_ry;
- wire [ 2: 0] worker_addr_rz;
-
- wire [ 2: 0] worker_addr_q;
-
- wire worker_wren_rx;
- wire worker_wren_ry;
- wire worker_wren_rz;
-
- reg [31: 0] worker_din_px;
- reg [31: 0] worker_din_py;
- reg [31: 0] worker_din_pz;
-
- reg [31: 0] worker_din_rx;
- reg [31: 0] worker_din_ry;
- reg [31: 0] worker_din_rz;
-
- wire [31: 0] worker_dout_rx;
- wire [31: 0] worker_dout_ry;
- wire [31: 0] worker_dout_rz;
-
- curve_dbl_add_256 worker
- (
- .clk (clk),
- .rst_n (rst_n),
-
- .ena (op_trig),
- .rdy (op_done),
-
- .uop_addr (op_rom_addr),
- .uop (op_rom_mux_data),
-
- .px_addr (worker_addr_px),
- .py_addr (worker_addr_py),
- .pz_addr (worker_addr_pz),
-
- .rx_addr (worker_addr_rx),
- .ry_addr (worker_addr_ry),
- .rz_addr (worker_addr_rz),
-
- .q_addr (worker_addr_q),
-
- .v_addr (bram_rz1_rd_addr),
-
- .rx_wren (worker_wren_rx),
- .ry_wren (worker_wren_ry),
- .rz_wren (worker_wren_rz),
-
- .px_din (worker_din_px),
- .py_din (worker_din_py),
- .pz_din (worker_din_pz),
-
- .rx_din (worker_din_rx),
- .ry_din (worker_din_ry),
- .rz_din (worker_din_rz),
-
- .rx_dout (worker_dout_rx),
- .ry_dout (worker_dout_ry),
- .rz_dout (worker_dout_rz),
-
- .q_din (rom_q_data),
-
- .v_din (bram_rz1_rd_data)
- );
-
-
- //
- // Mover
- //
- reg move_trig;
- wire move_done;
-
- wire [ 2: 0] mover_addr_x;
- wire [ 2: 0] mover_addr_y;
-
- wire mover_wren_y;
-
- always @(posedge clk or negedge rst_n)
- //
- if (rst_n == 1'b0) move_trig <= 1'b0;
- else move_trig <= (fsm_state == FSM_STATE_COPY_TRIG);
-
- mw_mover #
- (
- .WORD_COUNTER_WIDTH (3),
- .OPERAND_NUM_WORDS (8)
- )
- mover
- (
- .clk (clk),
- .rst_n (rst_n),
-
- .ena (move_trig),
- .rdy (move_done),
-
- .x_addr (mover_addr_x),
- .y_addr (mover_addr_y),
- .y_wren (mover_wren_y),
-
- .x_din ({32{1'bX}}),
- .y_dout ()
- );
-
-
- //
- // Invertor
- //
- reg invert_trig;
- wire invert_done;
-
- wire [ 2: 0] invertor_addr_a;
- wire [ 2: 0] invertor_addr_q;
-
- always @(posedge clk or negedge rst_n)
- //
- if (rst_n == 1'b0) invert_trig <= 1'b0;
- else invert_trig <= (fsm_state == FSM_STATE_INVERT_TRIG);
-
- modular_invertor #
- (
- .MAX_OPERAND_WIDTH(256)
- )
- invertor
- (
- .clk (clk),
- .rst_n (rst_n),
-
- .ena (invert_trig),
- .rdy (invert_done),
-
- .a_addr (invertor_addr_a),
- .q_addr (invertor_addr_q),
- .a1_addr (bram_rz1_wr_addr),
- .a1_wren (bram_rz1_wr_en),
-
- .a_din (bram_rz_rd_data),
- .q_din (rom_q_data),
- .a1_dout (bram_rz1_wr_data_in)
- );
-
-
- //
- // FSM Transition Logic
- //
- always @(posedge clk or negedge rst_n)
- //
- if (rst_n == 1'b0) fsm_state <= FSM_STATE_IDLE;
- else case (fsm_state)
-
- FSM_STATE_IDLE: fsm_state <= ena ? FSM_STATE_PREPARE_TRIG : FSM_STATE_IDLE;
-
- FSM_STATE_PREPARE_TRIG: fsm_state <= FSM_STATE_PREPARE_WAIT;
- FSM_STATE_PREPARE_WAIT: fsm_state <= (!op_trig && op_done) ? FSM_STATE_DOUBLE_TRIG : FSM_STATE_PREPARE_WAIT;
-
- FSM_STATE_DOUBLE_TRIG: fsm_state <= FSM_STATE_DOUBLE_WAIT;
- FSM_STATE_DOUBLE_WAIT: fsm_state <= (!op_trig && op_done) ? FSM_STATE_ADD_TRIG : FSM_STATE_DOUBLE_WAIT;
-
- FSM_STATE_ADD_TRIG: fsm_state <= FSM_STATE_ADD_WAIT;
- FSM_STATE_ADD_WAIT: fsm_state <= (!op_trig && op_done) ? FSM_STATE_COPY_TRIG : FSM_STATE_ADD_WAIT;
-
- FSM_STATE_COPY_TRIG: fsm_state <= FSM_STATE_COPY_WAIT;
- FSM_STATE_COPY_WAIT: fsm_state <= (!move_trig && move_done) ? fsm_state_round_next : FSM_STATE_COPY_WAIT;
-
- FSM_STATE_INVERT_TRIG: fsm_state <= FSM_STATE_INVERT_WAIT;
- FSM_STATE_INVERT_WAIT: fsm_state <= (!invert_trig && invert_done) ? FSM_STATE_CONVERT_TRIG : FSM_STATE_INVERT_WAIT;
-
- FSM_STATE_CONVERT_TRIG: fsm_state <= FSM_STATE_CONVERT_WAIT;
- FSM_STATE_CONVERT_WAIT: fsm_state <= (!op_trig && op_done) ? FSM_STATE_DONE : FSM_STATE_CONVERT_WAIT;
-
- FSM_STATE_DONE: fsm_state <= FSM_STATE_IDLE;
-
- default: fsm_state <= FSM_STATE_IDLE;
-
- endcase
-
-
- //
- // Bit Counter Increment
- //
- always @(posedge clk) begin
- //
- if ((fsm_state == FSM_STATE_PREPARE_WAIT) && !op_trig && op_done)
- bit_counter <= bit_counter_zero;
- //
- if ((fsm_state == FSM_STATE_COPY_WAIT) && !move_trig && move_done)
- bit_counter <= bit_counter_next;
- //
- end
-
-
- //
- // K Latch Logic
- //
- reg [ 2: 0] k_addr_reg;
- reg [31: 0] k_din_reg;
-
- assign k_addr = k_addr_reg;
-
- always @(posedge clk) begin
- //
- if (fsm_state == FSM_STATE_DOUBLE_TRIG)
- k_addr_reg <= 3'd7 - bit_counter[7:5];
- //
- if (fsm_state == FSM_STATE_ADD_TRIG)
- k_din_reg <= (bit_counter[4:0] == 5'd0) ? k_din : {k_din_reg[30:0], 1'bX};
- //
- end
-
-
-
- //
- // Copy Inhibit Logic
- //
- wire move_inhibit = k_din_reg[31];
-
- wire copy_t2r_int = mover_wren_y & ~move_inhibit;
-
-
- always @(*) begin
- //
- // Q
- //
- case (fsm_state)
- FSM_STATE_DOUBLE_WAIT: rom_q_addr = worker_addr_q;
- FSM_STATE_ADD_WAIT: rom_q_addr = worker_addr_q;
- FSM_STATE_INVERT_WAIT: rom_q_addr = invertor_addr_q;
- FSM_STATE_CONVERT_WAIT: rom_q_addr = worker_addr_q;
- default: rom_q_addr = worker_addr_q;
- endcase
-
- //
- // R(X,Y,Z)
- //
- case (fsm_state)
- //
- FSM_STATE_PREPARE_WAIT: begin
- //
- bram_rx_rd_addr <= {3{1'bX}}; bram_ry_rd_addr <= {3{1'bX}}; bram_rz_rd_addr <= {3{1'bX}};
- bram_rx_wr_addr <= worker_addr_rx; bram_ry_wr_addr <= worker_addr_ry; bram_rz_wr_addr <= worker_addr_rz;
- bram_rx_wr_en <= worker_wren_rx; bram_ry_wr_en <= worker_wren_ry; bram_rz_wr_en <= worker_wren_rz;
- bram_rx_wr_data_in <= worker_dout_rx; bram_ry_wr_data_in <= worker_dout_ry; bram_rz_wr_data_in <= worker_dout_rz;
- //
- end
- //
- FSM_STATE_DOUBLE_WAIT: begin
- //
- bram_rx_rd_addr <= worker_addr_px; bram_ry_rd_addr <= worker_addr_py; bram_rz_rd_addr <= worker_addr_pz;
- bram_rx_wr_addr <= {3{1'bX}}; bram_ry_wr_addr <= {3{1'bX}}; bram_rz_wr_addr <= {3{1'bX}};
- bram_rx_wr_en <= 1'b0; bram_ry_wr_en <= 1'b0; bram_rz_wr_en <= 1'b0;
- bram_rx_wr_data_in <= {32{1'bX}}; bram_ry_wr_data_in <= {32{1'bX}}; bram_rz_wr_data_in <= {32{1'bX}};
- //
- end
- //
- FSM_STATE_ADD_WAIT: begin
- //
- bram_rx_rd_addr <= {3{1'bX}}; bram_ry_rd_addr <= {3{1'bX}}; bram_rz_rd_addr <= {3{1'bX}};
- bram_rx_wr_addr <= worker_addr_rx; bram_ry_wr_addr <= worker_addr_ry; bram_rz_wr_addr <= worker_addr_rz;
- bram_rx_wr_en <= worker_wren_rx; bram_ry_wr_en <= worker_wren_ry; bram_rz_wr_en <= worker_wren_rz;
- bram_rx_wr_data_in <= worker_dout_rx; bram_ry_wr_data_in <= worker_dout_ry; bram_rz_wr_data_in <= worker_dout_rz;
- //
- end
- //
- FSM_STATE_COPY_WAIT: begin
- //
- bram_rx_rd_addr <= {3{1'bX}}; bram_ry_rd_addr <= {3{1'bX}}; bram_rz_rd_addr <= {3{1'bX}};
- bram_rx_wr_addr <= mover_addr_y; bram_ry_wr_addr <= mover_addr_y; bram_rz_wr_addr <= mover_addr_y;
- bram_rx_wr_en <= copy_t2r_int; bram_ry_wr_en <= copy_t2r_int; bram_rz_wr_en <= copy_t2r_int;
- bram_rx_wr_data_in <= bram_tx_rd_data; bram_ry_wr_data_in <= bram_ty_rd_data; bram_rz_wr_data_in <= bram_tz_rd_data;
- //
- end
- //
- FSM_STATE_INVERT_WAIT: begin
- //
- bram_rx_rd_addr <= {3{1'bX}}; bram_ry_rd_addr <= {3{1'bX}}; bram_rz_rd_addr <= invertor_addr_a;
- bram_rx_wr_addr <= {3{1'bX}}; bram_ry_wr_addr <= {3{1'bX}}; bram_rz_wr_addr <= {3{1'bX}};
- bram_rx_wr_en <= 1'b0; bram_ry_wr_en <= 1'b0; bram_rz_wr_en <= 1'b0;
- bram_rx_wr_data_in <= {32{1'bX}}; bram_ry_wr_data_in <= {32{1'bX}}; bram_rz_wr_data_in <= {32{1'bX}};
- //
- end
- //
- FSM_STATE_CONVERT_WAIT: begin
- //
- bram_rx_rd_addr <= worker_addr_px; bram_ry_rd_addr <= worker_addr_py; bram_rz_rd_addr <= worker_addr_pz;
- bram_rx_wr_addr <= {3{1'bX}}; bram_ry_wr_addr <= {3{1'bX}}; bram_rz_wr_addr <= {3{1'bX}};
- bram_rx_wr_en <= 1'b0; bram_ry_wr_en <= 1'b0; bram_rz_wr_en <= 1'b0;
- bram_rx_wr_data_in <= {32{1'bX}}; bram_ry_wr_data_in <= {32{1'bX}}; bram_rz_wr_data_in <= {32{1'bX}};
- //
- end
-
- //
- default: begin
- //
- bram_rx_rd_addr <= {3{1'bX}}; bram_ry_rd_addr <= {3{1'bX}}; bram_rz_rd_addr <= {3{1'bX}};
- bram_rx_wr_addr <= {3{1'bX}}; bram_ry_wr_addr <= {3{1'bX}}; bram_rz_wr_addr <= {3{1'bX}};
- bram_rx_wr_en <= 1'b0; bram_ry_wr_en <= 1'b0; bram_rz_wr_en <= 1'b0;
- bram_rx_wr_data_in <= {32{1'bX}}; bram_ry_wr_data_in <= {32{1'bX}}; bram_rz_wr_data_in <= {32{1'bX}};
- //
- end
- //
- endcase
- //
- // T(X,Y,Z)
- //
- case (fsm_state)
- //
- FSM_STATE_DOUBLE_WAIT: begin
- //
- bram_tx_rd_addr <= {3{1'bX}}; bram_ty_rd_addr <= {3{1'bX}}; bram_tz_rd_addr <= {3{1'bX}};
- bram_tx_wr_addr <= worker_addr_rx; bram_ty_wr_addr <= worker_addr_ry; bram_tz_wr_addr <= worker_addr_rz;
- bram_tx_wr_en <= worker_wren_rx; bram_ty_wr_en <= worker_wren_ry; bram_tz_wr_en <= worker_wren_rz;
- bram_tx_wr_data_in <= worker_dout_rx; bram_ty_wr_data_in <= worker_dout_ry; bram_tz_wr_data_in <= worker_dout_rz;
- //
- end
- //
- FSM_STATE_ADD_WAIT: begin
- //
- bram_tx_rd_addr <= worker_addr_px; bram_ty_rd_addr <= worker_addr_py; bram_tz_rd_addr <= worker_addr_pz;
- bram_tx_wr_addr <= {3{1'bX}}; bram_ty_wr_addr <= {3{1'bX}}; bram_tz_wr_addr <= {3{1'bX}};
- bram_tx_wr_en <= 1'b0; bram_ty_wr_en <= 1'b0; bram_tz_wr_en <= 1'b0;
- bram_tx_wr_data_in <= {32{1'bX}}; bram_ty_wr_data_in <= {32{1'bX}}; bram_tz_wr_data_in <= {32{1'bX}};
- //
- end
- //
- FSM_STATE_COPY_WAIT: begin
- //
- bram_tx_rd_addr <= mover_addr_x; bram_ty_rd_addr <= mover_addr_x; bram_tz_rd_addr <= mover_addr_x;
- bram_tx_wr_addr <= {3{1'bX}}; bram_ty_wr_addr <= {3{1'bX}}; bram_tz_wr_addr <= {3{1'bX}};
- bram_tx_wr_en <= 1'b0; bram_ty_wr_en <= 1'b0; bram_tz_wr_en <= 1'b0;
- bram_tx_wr_data_in <= {32{1'bX}}; bram_ty_wr_data_in <= {32{1'bX}}; bram_tz_wr_data_in <= {32{1'bX}};
- //
- end
-
- //
- default: begin
- //
- bram_tx_rd_addr <= {3{1'bX}}; bram_ty_rd_addr <= {3{1'bX}}; bram_tz_rd_addr <= {3{1'bX}};
- bram_tx_wr_addr <= {3{1'bX}}; bram_ty_wr_addr <= {3{1'bX}}; bram_tz_wr_addr <= {3{1'bX}};
- bram_tx_wr_en <= 1'b0; bram_ty_wr_en <= 1'b0; bram_tz_wr_en <= 1'b0;
- bram_tx_wr_data_in <= {32{1'bX}}; bram_ty_wr_data_in <= {32{1'bX}}; bram_tz_wr_data_in <= {32{1'bX}};
- //
- end
- //
- endcase
- //
- // Worker
- //
- case (fsm_state)
- //
- FSM_STATE_DOUBLE_WAIT: begin
- //
- worker_din_px <= bram_rx_rd_data; worker_din_py <= bram_ry_rd_data; worker_din_pz <= bram_rz_rd_data;
- worker_din_rx <= bram_tx_wr_data_out; worker_din_ry <= bram_ty_wr_data_out; worker_din_rz <= bram_tz_wr_data_out;
- //
- end
- //
- FSM_STATE_ADD_WAIT: begin
- //
- worker_din_px <= bram_tx_rd_data; worker_din_py <= bram_ty_rd_data; worker_din_pz <= bram_tz_rd_data;
- worker_din_rx <= bram_rx_wr_data_out; worker_din_ry <= bram_ry_wr_data_out; worker_din_rz <= bram_rz_wr_data_out;
- //
- end
- //
- FSM_STATE_CONVERT_WAIT: begin
- //
- worker_din_px <= bram_rx_rd_data; worker_din_py <= bram_ry_rd_data; worker_din_pz <= bram_rz_rd_data;
- worker_din_rx <= {32{1'bX}}; worker_din_ry <= {32{1'bX}}; worker_din_rz <= {32{1'bX}};
- //
- end
- //
- default: begin
- //
- worker_din_px <= {32{1'bX}}; worker_din_py <= {32{1'bX}}; worker_din_pz <= {32{1'bX}};
- worker_din_rx <= {32{1'bX}}; worker_din_ry <= {32{1'bX}}; worker_din_rz <= {32{1'bX}};
- //
- end
- //
- endcase
- //
- end
-
-
- //
- // Output Mapping
- //
- assign rx_wren = worker_wren_rx && (fsm_state == FSM_STATE_CONVERT_WAIT);
- assign ry_wren = worker_wren_ry && (fsm_state == FSM_STATE_CONVERT_WAIT);
-
- assign rx_dout = worker_dout_rx;
- assign ry_dout = worker_dout_ry;
-
- assign rx_addr = worker_addr_rx;
- assign ry_addr = worker_addr_ry;
-
-
- //
- // Ready Flag Logic
- //
- reg rdy_reg = 1'b1;
- assign rdy = rdy_reg;
-
- always @(posedge clk or negedge rst_n)
-
- if (rst_n == 1'b0) rdy_reg <= 1'b1;
- else begin
-
- /* clear flag */
- if ((fsm_state == FSM_STATE_IDLE) && ena)
- rdy_reg <= 1'b0;
-
- /* set flag */
- if (fsm_state == FSM_STATE_DONE)
- rdy_reg <= 1'b1;
-
- end
-
-
-endmodule
-
-
-//------------------------------------------------------------------------------
-// End-of-File
-//------------------------------------------------------------------------------
diff --git a/rtl/curve/rom/brom_p256_delta.v b/rtl/curve/rom/brom_p256_delta.v
deleted file mode 100644
index 4637575..0000000
--- a/rtl/curve/rom/brom_p256_delta.v
+++ /dev/null
@@ -1,68 +0,0 @@
-//======================================================================
-//
-// Copyright (c) 2016, 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 brom_p256_delta
- (
- input wire clk,
- input wire [ 3-1:0] b_addr,
- output wire [32-1:0] b_out
- );
-
-
- //
- // Output Registers
- //
- reg [31:0] bram_reg_b;
-
- assign b_out = bram_reg_b;
-
-
- //
- // Read-Only Port B
- //
- always @(posedge clk)
- //
- case (b_addr)
- 3'b000: bram_reg_b <= 32'h00000000;
- 3'b001: bram_reg_b <= 32'h00000000;
- 3'b010: bram_reg_b <= 32'h80000000;
- 3'b011: bram_reg_b <= 32'h00000000;
- 3'b100: bram_reg_b <= 32'h00000000;
- 3'b101: bram_reg_b <= 32'h80000000;
- 3'b110: bram_reg_b <= 32'h80000000;
- 3'b111: bram_reg_b <= 32'h7fffffff;
- endcase
-
-
-endmodule
diff --git a/rtl/curve/rom/brom_p256_g_x.v b/rtl/curve/rom/brom_p256_g_x.v
deleted file mode 100644
index 86aeafd..0000000
--- a/rtl/curve/rom/brom_p256_g_x.v
+++ /dev/null
@@ -1,68 +0,0 @@
-//======================================================================
-//
-// Copyright (c) 2016, 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 brom_p256_g_x
- (
- input wire clk,
- input wire [ 3-1:0] b_addr,
- output wire [32-1:0] b_out
- );
-
-
- //
- // Output Registers
- //
- reg [31:0] bram_reg_b;
-
- assign b_out = bram_reg_b;
-
-
- //
- // Read-Only Port B
- //
- always @(posedge clk)
- //
- case (b_addr)
- 3'b000: bram_reg_b <= 32'hd898c296;
- 3'b001: bram_reg_b <= 32'hf4a13945;
- 3'b010: bram_reg_b <= 32'h2deb33a0;
- 3'b011: bram_reg_b <= 32'h77037d81;
- 3'b100: bram_reg_b <= 32'h63a440f2;
- 3'b101: bram_reg_b <= 32'hf8bce6e5;
- 3'b110: bram_reg_b <= 32'he12c4247;
- 3'b111: bram_reg_b <= 32'h6b17d1f2;
- endcase
-
-
-endmodule
diff --git a/rtl/curve/rom/brom_p256_g_y.v b/rtl/curve/rom/brom_p256_g_y.v
deleted file mode 100644
index 39f9116..0000000
--- a/rtl/curve/rom/brom_p256_g_y.v
+++ /dev/null
@@ -1,68 +0,0 @@
-//======================================================================
-//
-// Copyright (c) 2016, 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 brom_p256_g_y
- (
- input wire clk,
- input wire [ 3-1:0] b_addr,
- output wire [32-1:0] b_out
- );
-
-
- //
- // Output Registers
- //
- reg [31:0] bram_reg_b;
-
- assign b_out = bram_reg_b;
-
-
- //
- // Read-Only Port B
- //
- always @(posedge clk)
- //
- case (b_addr)
- 3'b000: bram_reg_b <= 32'h37bf51f5;
- 3'b001: bram_reg_b <= 32'hcbb64068;
- 3'b010: bram_reg_b <= 32'h6b315ece;
- 3'b011: bram_reg_b <= 32'h2bce3357;
- 3'b100: bram_reg_b <= 32'h7c0f9e16;
- 3'b101: bram_reg_b <= 32'h8ee7eb4a;
- 3'b110: bram_reg_b <= 32'hfe1a7f9b;
- 3'b111: bram_reg_b <= 32'h4fe342e2;
- endcase
-
-
-endmodule
diff --git a/rtl/curve/rom/brom_p256_h_x.v b/rtl/curve/rom/brom_p256_h_x.v
deleted file mode 100644
index f426475..0000000
--- a/rtl/curve/rom/brom_p256_h_x.v
+++ /dev/null
@@ -1,68 +0,0 @@
-//======================================================================
-//
-// Copyright (c) 2016, 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 brom_p256_h_x
- (
- input wire clk,
- input wire [ 3-1:0] b_addr,
- output wire [32-1:0] b_out
- );
-
-
- //
- // Output Registers
- //
- reg [31:0] bram_reg_b;
-
- assign b_out = bram_reg_b;
-
-
- //
- // Read-Only Port B
- //
- always @(posedge clk)
- //
- case (b_addr)
- 3'b000: bram_reg_b <= 32'h47669978;
- 3'b001: bram_reg_b <= 32'ha60b48fc;
- 3'b010: bram_reg_b <= 32'h77f21b35;
- 3'b011: bram_reg_b <= 32'hc08969e2;
- 3'b100: bram_reg_b <= 32'h04b51ac3;
- 3'b101: bram_reg_b <= 32'h8a523803;
- 3'b110: bram_reg_b <= 32'h8d034f7e;
- 3'b111: bram_reg_b <= 32'h7cf27b18;
- endcase
-
-
-endmodule
diff --git a/rtl/curve/rom/brom_p256_h_y.v b/rtl/curve/rom/brom_p256_h_y.v
deleted file mode 100644
index c75d0da..0000000
--- a/rtl/curve/rom/brom_p256_h_y.v
+++ /dev/null
@@ -1,68 +0,0 @@
-//======================================================================
-//
-// Copyright (c) 2016, 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 brom_p256_h_y
- (
- input wire clk,
- input wire [ 3-1:0] b_addr,
- output wire [32-1:0] b_out
- );
-
-
- //
- // Output Registers
- //
- reg [31:0] bram_reg_b;
-
- assign b_out = bram_reg_b;
-
-
- //
- // Read-Only Port B
- //
- always @(posedge clk)
- //
- case (b_addr)
- 3'b000: bram_reg_b <= 32'h227873d1;
- 3'b001: bram_reg_b <= 32'h9e04b79d;
- 3'b010: bram_reg_b <= 32'h3ce98229;
- 3'b011: bram_reg_b <= 32'hba7dade6;
- 3'b100: bram_reg_b <= 32'h9f7430db;
- 3'b101: bram_reg_b <= 32'h293d9ac6;
- 3'b110: bram_reg_b <= 32'hdb8ed040;
- 3'b111: bram_reg_b <= 32'h07775510;
- endcase
-
-
-endmodule
diff --git a/rtl/curve/rom/brom_p256_one.v b/rtl/curve/rom/brom_p256_one.v
deleted file mode 100644
index 15e3746..0000000
--- a/rtl/curve/rom/brom_p256_one.v
+++ /dev/null
@@ -1,68 +0,0 @@
-//======================================================================
-//
-// Copyright (c) 2016, 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 brom_p256_one
- (
- input wire clk,
- input wire [ 3-1:0] b_addr,
- output wire [32-1:0] b_out
- );
-
-
- //
- // Output Registers
- //
- reg [31:0] bram_reg_b;
-
- assign b_out = bram_reg_b;
-
-
- //
- // Read-Only Port B
- //
- always @(posedge clk)
- //
- case (b_addr)
- 3'b000: bram_reg_b <= 32'h00000001;
- 3'b001: bram_reg_b <= 32'h00000000;
- 3'b010: bram_reg_b <= 32'h00000000;
- 3'b011: bram_reg_b <= 32'h00000000;
- 3'b100: bram_reg_b <= 32'h00000000;
- 3'b101: bram_reg_b <= 32'h00000000;
- 3'b110: bram_reg_b <= 32'h00000000;
- 3'b111: bram_reg_b <= 32'h00000000;
- endcase
-
-
-endmodule
diff --git a/rtl/curve/rom/brom_p256_q.v b/rtl/curve/rom/brom_p256_q.v
deleted file mode 100644
index 101a524..0000000
--- a/rtl/curve/rom/brom_p256_q.v
+++ /dev/null
@@ -1,68 +0,0 @@
-//======================================================================
-//
-// Copyright (c) 2016, 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 brom_p256_q
- (
- input wire clk,
- input wire [ 3-1:0] b_addr,
- output wire [32-1:0] b_out
- );
-
-
- //
- // Output Registers
- //
- reg [31:0] bram_reg_b;
-
- assign b_out = bram_reg_b;
-
-
- //
- // Read-Only Port B
- //
- always @(posedge clk)
- //
- case (b_addr)
- 3'b000: bram_reg_b <= 32'hffffffff;
- 3'b001: bram_reg_b <= 32'hffffffff;
- 3'b010: bram_reg_b <= 32'hffffffff;
- 3'b011: bram_reg_b <= 32'h00000000;
- 3'b100: bram_reg_b <= 32'h00000000;
- 3'b101: bram_reg_b <= 32'h00000000;
- 3'b110: bram_reg_b <= 32'h00000001;
- 3'b111: bram_reg_b <= 32'hffffffff;
- endcase
-
-
-endmodule
diff --git a/rtl/curve/rom/brom_p256_zero.v b/rtl/curve/rom/brom_p256_zero.v
deleted file mode 100644
index 2672cf2..0000000
--- a/rtl/curve/rom/brom_p256_zero.v
+++ /dev/null
@@ -1,70 +0,0 @@
-//======================================================================
-//
-// Copyright (c) 2016, 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 brom_p256_zero
- (
- //input wire clk,
- //input wire [ 3-1:0] b_addr,
- output wire [32-1:0] b_out
- );
-
-
- assign b_out = {32{1'b0}};
-
- //
- // Output Registers
- //
- //reg [31:0] bram_reg_b;
-
- //assign b_out = bram_reg_b;
-
-
- //
- // Read-Only Port B
- //
- //always @(posedge clk)
- //
- //case (b_addr)
- //3'b000: bram_reg_b <= 32'h00000000;
- //3'b001: bram_reg_b <= 32'h00000000;
- //3'b010: bram_reg_b <= 32'h00000000;
- //3'b011: bram_reg_b <= 32'h00000000;
- //3'b100: bram_reg_b <= 32'h00000000;
- //3'b101: bram_reg_b <= 32'h00000000;
- //3'b110: bram_reg_b <= 32'h00000000;
- //3'b111: bram_reg_b <= 32'h00000000;
- //endcase
-
-
-endmodule
diff --git a/rtl/ecdsa256.v b/rtl/ecdsa256.v
deleted file mode 100644
index 11276a2..0000000
--- a/rtl/ecdsa256.v
+++ /dev/null
@@ -1,160 +0,0 @@
-//======================================================================
-//
-// Copyright (c) 2016, 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 ecdsa256
- (
- input wire clk,
- input wire rst_n,
-
- input wire next,
- output wire valid,
-
- input wire bus_cs,
- input wire bus_we,
- input wire [ 4:0] bus_addr,
- input wire [31:0] bus_data_wr,
- output wire [31:0] bus_data_rd
- );
-
-
- //
- // Memory Banks
- //
- localparam [1:0] BUS_ADDR_BANK_K = 2'b00;
- localparam [1:0] BUS_ADDR_BANK_X = 2'b01;
- localparam [1:0] BUS_ADDR_BANK_Y = 2'b10;
-
- wire [1:0] bus_addr_upper = bus_addr[4:3];
- wire [2:0] bus_addr_lower = bus_addr[2:0];
-
-
- //
- // Memories
- //
-
- wire [31:0] user_rw_k_bram_out;
- wire [31:0] user_ro_x_bram_out;
- wire [31:0] user_ro_y_bram_out;
-
- wire [ 2:0] core_ro_k_bram_addr;
- wire [ 2:0] core_rw_x_bram_addr;
- wire [ 2:0] core_rw_y_bram_addr;
-
- wire core_rw_x_bram_wren;
- wire core_rw_y_bram_wren;
-
- wire [31:0] core_ro_k_bram_dout;
- wire [31:0] core_rw_x_bram_din;
- wire [31:0] core_rw_y_bram_din;
-
-
- bram_1rw_1ro_readfirst #
- ( .MEM_WIDTH(32), .MEM_ADDR_BITS(3)
- )
- bram_k
- ( .clk(clk),
- .a_addr(bus_addr_lower), .a_out(user_rw_k_bram_out), .a_wr(bus_cs && bus_we && (bus_addr_upper == BUS_ADDR_BANK_K)), .a_in(bus_data_wr),
- .b_addr(core_ro_k_bram_addr), .b_out(core_ro_k_bram_dout)
- );
-
- bram_1rw_1ro_readfirst #
- ( .MEM_WIDTH(32), .MEM_ADDR_BITS(3)
- )
- bram_x
- ( .clk(clk),
- .a_addr(core_rw_x_bram_addr), .a_out(), .a_wr(core_rw_x_bram_wren), .a_in(core_rw_x_bram_din),
- .b_addr(bus_addr_lower), .b_out(user_ro_x_bram_out)
- );
-
- bram_1rw_1ro_readfirst #
- ( .MEM_WIDTH(32), .MEM_ADDR_BITS(3)
- )
- bram_y
- ( .clk(clk),
- .a_addr(core_rw_y_bram_addr), .a_out(), .a_wr(core_rw_y_bram_wren), .a_in(core_rw_y_bram_din),
- .b_addr(bus_addr_lower), .b_out(user_ro_y_bram_out)
- );
-
-
- //
- // Curve Base Point Multiplier
- //
- reg next_dly;
-
- always @(posedge clk) next_dly <= next;
-
- wire next_trig = next && !next_dly;
-
- curve_mul_256 base_point_multiplier_p256
- (
- .clk (clk),
- .rst_n (rst_n),
-
- .ena (next_trig),
- .rdy (valid),
-
- .k_addr (core_ro_k_bram_addr),
- .rx_addr (core_rw_x_bram_addr),
- .ry_addr (core_rw_y_bram_addr),
-
- .rx_wren (core_rw_x_bram_wren),
- .ry_wren (core_rw_y_bram_wren),
-
- .k_din (core_ro_k_bram_dout),
- .rx_dout (core_rw_x_bram_din),
- .ry_dout (core_rw_y_bram_din)
- );
-
- //
- // Output Selector
- //
- reg [1:0] bus_addr_upper_prev;
- always @(posedge clk) bus_addr_upper_prev = bus_addr_upper;
-
- reg [31: 0] bus_data_rd_mux;
- assign bus_data_rd = bus_data_rd_mux;
-
- always @(*)
- //
- case (bus_addr_upper_prev)
- //
- BUS_ADDR_BANK_K: bus_data_rd_mux = user_rw_k_bram_out;
- BUS_ADDR_BANK_X: bus_data_rd_mux = user_ro_x_bram_out;
- BUS_ADDR_BANK_Y: bus_data_rd_mux = user_ro_y_bram_out;
- //
- default: bus_data_rd_mux = {32{1'b0}};
- //
- endcase
-
-endmodule
diff --git a/rtl/ecdsa256_banks_array.v b/rtl/ecdsa256_banks_array.v
new file mode 100644
index 0000000..1172429
--- /dev/null
+++ b/rtl/ecdsa256_banks_array.v
@@ -0,0 +1,119 @@
+//------------------------------------------------------------------------------
+//
+// ecdsa256_banks_array.v
+// -----------------------------------------------------------------------------
+// ECDSA Operand Banks Array
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 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 ecdsa256_banks_array
+(
+ input clk,
+
+ input banks, // 0: LO -> HI, 1: HI -> LO
+
+ input [ 5:0] src1_operand,
+ input [ 5:0] src2_operand,
+ input [ 5:0] dst_operand,
+
+ input [ 2:0] src1_addr,
+ input [ 2:0] src2_addr,
+ input [ 2:0] dst_addr,
+
+ input dst_wren,
+
+ output [31:0] src1_dout,
+ output [31:0] src2_dout,
+
+ input [31:0] dst_din
+);
+
+
+ //
+ // Banks
+ //
+ wire [31:0] bank_lo1_dout;
+ wire [31:0] bank_lo2_dout;
+ wire [31:0] bank_hi1_dout;
+ wire [31:0] bank_hi2_dout;
+
+ assign src1_dout = !banks ? bank_lo1_dout : bank_hi1_dout;
+ assign src2_dout = !banks ? bank_lo2_dout : bank_hi2_dout;
+
+ ecdsa256_operand_bank bank_operand_lo1
+ (
+ .clk (clk),
+ .a_addr ({dst_operand, dst_addr}),
+ .a_wr (dst_wren & banks),
+ .a_in (dst_din),
+ .b_addr ({src1_operand, src1_addr}),
+ .b_out (bank_lo1_dout)
+ );
+
+ ecdsa256_operand_bank bank_operand_lo2
+ (
+ .clk (clk),
+ .a_addr ({dst_operand, dst_addr}),
+ .a_wr (dst_wren & banks),
+ .a_in (dst_din),
+ .b_addr ({src2_operand, src2_addr}),
+ .b_out (bank_lo2_dout)
+ );
+
+ ecdsa256_operand_bank bank_operand_hi1
+ (
+ .clk (clk),
+ .a_addr ({dst_operand, dst_addr}),
+ .a_wr (dst_wren & ~banks),
+ .a_in (dst_din),
+ .b_addr ({src1_operand, src1_addr}),
+ .b_out (bank_hi1_dout)
+ );
+
+ ecdsa256_operand_bank bank_operand_hi2
+ (
+ .clk (clk),
+ .a_addr ({dst_operand, dst_addr}),
+ .a_wr (dst_wren & ~banks),
+ .a_in (dst_din),
+ .b_addr ({src2_operand, src2_addr}),
+ .b_out (bank_hi2_dout)
+ );
+
+
+endmodule
+
+
+//------------------------------------------------------------------------------
+// End-of-File
+//------------------------------------------------------------------------------
diff --git a/rtl/ecdsa256_base_point_multiplier.v b/rtl/ecdsa256_base_point_multiplier.v
new file mode 100644
index 0000000..8664d0c
--- /dev/null
+++ b/rtl/ecdsa256_base_point_multiplier.v
@@ -0,0 +1,310 @@
+//------------------------------------------------------------------------------
+//
+// ecdsa256_base_point_multiplier.v
+// -----------------------------------------------------------------------------
+// ECDSA base point scalar multiplier.
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 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 ecdsa256_base_point_multiplier
+(
+ clk, rst_n,
+ ena, rdy,
+ k_addr, rxy_addr,
+ rx_wren, ry_wren,
+ k_din,
+ rxy_dout
+);
+
+
+ //
+ // Microcode Header
+ //
+`include "ecdsa_uop.vh"
+
+
+ //
+ // Ports
+ //
+ input clk; // system clock
+ input rst_n; // active-low async reset
+
+ input ena; // enable input
+ output rdy; // ready output
+
+ output [ 2:0] k_addr; //
+ output [ 2:0] rxy_addr; //
+ output rx_wren; //
+ output ry_wren; //
+ input [31:0] k_din; //
+ output [31:0] rxy_dout; //
+
+
+ //
+ // FSM
+ //
+ localparam [4:0] FSM_STATE_IDLE = 5'd00;
+ localparam [4:0] FSM_STATE_PREPARE_TRIG = 5'd01;
+ localparam [4:0] FSM_STATE_PREPARE_WAIT = 5'd02;
+ localparam [4:0] FSM_STATE_CYCLE_DBL_TRIG = 5'd03;
+ localparam [4:0] FSM_STATE_CYCLE_DBL_WAIT = 5'd04;
+ localparam [4:0] FSM_STATE_CYCLE_ADD_TRIG = 5'd05;
+ localparam [4:0] FSM_STATE_CYCLE_ADD_WAIT = 5'd06;
+ localparam [4:0] FSM_STATE_CYCLE_ADD_EXTRA_TRIG = 5'd07;
+ localparam [4:0] FSM_STATE_CYCLE_ADD_EXTRA_WAIT = 5'd08;
+ localparam [4:0] FSM_STATE_AFTER_CYCLE_TRIG = 5'd09;
+ localparam [4:0] FSM_STATE_AFTER_CYCLE_WAIT = 5'd10;
+ localparam [4:0] FSM_STATE_INVERT_TRIG = 5'd11;
+ localparam [4:0] FSM_STATE_INVERT_WAIT = 5'd12;
+ localparam [4:0] FSM_STATE_CONVERT_TRIG = 5'd13;
+ localparam [4:0] FSM_STATE_CONVERT_WAIT = 5'd14;
+ localparam [4:0] FSM_STATE_CONVERT_EXTRA_TRIG = 5'd15;
+ localparam [4:0] FSM_STATE_CONVERT_EXTRA_WAIT = 5'd16;
+ localparam [4:0] FSM_STATE_DONE = 5'd17;
+
+ reg [4:0] fsm_state = FSM_STATE_IDLE;
+ reg [4:0] fsm_state_next;
+
+
+ //
+ // Round Counter
+ //
+ reg [7:0] bit_counter;
+ wire [7:0] bit_counter_last = 8'hFF; // 255
+ wire [7:0] bit_counter_zero = 8'h00; // 0
+ wire [7:0] bit_counter_prev =
+ (bit_counter > bit_counter_zero) ? bit_counter - 1'b1 : bit_counter_last;
+
+ assign k_addr = bit_counter[7:5];
+
+
+ //
+ // Worker Trigger Logic
+ //
+ reg worker_trig = 1'b0;
+ wire worker_done;
+
+ wire fsm_wait_done = !worker_trig && worker_done;
+
+ always @(posedge clk or negedge rst_n)
+ //
+ if (rst_n == 1'b0) worker_trig <= 1'b0;
+ else case (fsm_state)
+ FSM_STATE_PREPARE_TRIG,
+ FSM_STATE_CYCLE_DBL_TRIG,
+ FSM_STATE_CYCLE_ADD_TRIG,
+ FSM_STATE_CYCLE_ADD_EXTRA_TRIG,
+ FSM_STATE_AFTER_CYCLE_TRIG,
+ FSM_STATE_INVERT_TRIG,
+ FSM_STATE_CONVERT_TRIG,
+ FSM_STATE_CONVERT_EXTRA_TRIG: worker_trig <= 1'b1;
+ default: worker_trig <= 1'b0;
+ endcase
+
+
+ //
+ // Round Counter Increment Logic
+ //
+ always @(posedge clk)
+ //
+ case (fsm_state_next)
+ FSM_STATE_PREPARE_TRIG: bit_counter <= bit_counter_last;
+ FSM_STATE_AFTER_CYCLE_TRIG: bit_counter <= bit_counter_prev;
+ endcase
+
+
+ //
+ // Final Cycle Detection Logic
+ //
+ wire [ 3: 0] fsm_state_after_cycle = (bit_counter == bit_counter_last) ?
+ FSM_STATE_INVERT_TRIG : FSM_STATE_CYCLE_DBL_TRIG;
+
+
+ //
+ // K Latch
+ //
+ reg [31:0] k_din_shreg;
+
+ wire [4:0] k_bit_index = bit_counter[4:0];
+
+ always @(posedge clk)
+ //
+ if (fsm_state_next == FSM_STATE_CYCLE_DBL_TRIG)
+ //
+ if (k_bit_index == 5'd31) k_din_shreg <= k_din;
+ else k_din_shreg <= {k_din_shreg[30:0], ~k_din_shreg[31]};
+
+
+ //
+ // Worker Flags
+ //
+ wire worker_flagz_sz;
+ wire worker_flagz_rz;
+ wire worker_flagz_e;
+ wire worker_flagz_f;
+
+ wire [2:0] worker_flagz_cycle_add =
+ {worker_flagz_sz, worker_flagz_e, worker_flagz_f};
+
+ wire worker_flagz_convert_extra =
+ worker_flagz_rz;
+
+
+ //
+ // Worker Offset Logic
+ //
+ reg [UOP_ADDR_WIDTH-1:0] worker_offset;
+
+ always @(posedge clk)
+ //
+ case (fsm_state)
+
+ FSM_STATE_PREPARE_TRIG: worker_offset <= UOP_OFFSET_PREPARE;
+
+ FSM_STATE_CYCLE_DBL_TRIG: worker_offset <= UOP_OFFSET_CYCLE_DOUBLE;
+ FSM_STATE_CYCLE_ADD_TRIG: worker_offset <= UOP_OFFSET_CYCLE_ADD;
+
+ FSM_STATE_CYCLE_ADD_EXTRA_TRIG:
+ // {sz, e, f}
+ casez(worker_flagz_cycle_add)
+ 3'b1??: worker_offset <= UOP_OFFSET_CYCLE_ADD_AT_INFINITY;
+ 3'b011: worker_offset <= UOP_OFFSET_CYCLE_ADD_SAME_X_SAME_Y;
+ 3'b010: worker_offset <= UOP_OFFSET_CYCLE_ADD_SAME_X;
+ 3'b00?: worker_offset <= UOP_OFFSET_CYCLE_ADD_REGULAR;
+ endcase
+
+ FSM_STATE_AFTER_CYCLE_TRIG: worker_offset <= k_din_shreg[31] ?
+ UOP_OFFSET_CYCLE_K1 : UOP_OFFSET_CYCLE_K0;
+
+ FSM_STATE_INVERT_TRIG: worker_offset <= UOP_OFFSET_INVERT;
+ FSM_STATE_CONVERT_TRIG: worker_offset <= UOP_OFFSET_CONVERT;
+
+ FSM_STATE_CONVERT_EXTRA_TRIG: worker_offset <= worker_flagz_convert_extra ?
+ UOP_OFFSET_CONVERT_AT_INFINITY : UOP_OFFSET_CONVERT_REGULAR;
+
+ default: worker_offset <= {UOP_ADDR_WIDTH{1'bX}};
+
+ endcase
+
+
+ //
+ // FSM Process
+ //
+ always @(posedge clk or negedge rst_n)
+ //
+ if (rst_n == 1'b0) fsm_state <= FSM_STATE_IDLE;
+ else fsm_state <= fsm_state_next;
+
+
+ //
+ // FSM Transition Logic
+ //
+ always @* begin
+ //
+ fsm_state_next = FSM_STATE_IDLE;
+ //
+ case (fsm_state)
+
+ FSM_STATE_IDLE: fsm_state_next = ena ? FSM_STATE_PREPARE_TRIG : FSM_STATE_IDLE;
+
+ FSM_STATE_PREPARE_TRIG: fsm_state_next = FSM_STATE_PREPARE_WAIT ;
+ FSM_STATE_PREPARE_WAIT: fsm_state_next = fsm_wait_done ? FSM_STATE_CYCLE_DBL_TRIG : FSM_STATE_PREPARE_WAIT;
+ FSM_STATE_CYCLE_DBL_TRIG: fsm_state_next = FSM_STATE_CYCLE_DBL_WAIT ;
+ FSM_STATE_CYCLE_DBL_WAIT: fsm_state_next = fsm_wait_done ? FSM_STATE_CYCLE_ADD_TRIG : FSM_STATE_CYCLE_DBL_WAIT;
+ FSM_STATE_CYCLE_ADD_TRIG: fsm_state_next = FSM_STATE_CYCLE_ADD_WAIT ;
+ FSM_STATE_CYCLE_ADD_WAIT: fsm_state_next = fsm_wait_done ? FSM_STATE_CYCLE_ADD_EXTRA_TRIG : FSM_STATE_CYCLE_ADD_WAIT;
+ FSM_STATE_CYCLE_ADD_EXTRA_TRIG: fsm_state_next = FSM_STATE_CYCLE_ADD_EXTRA_WAIT ;
+ FSM_STATE_CYCLE_ADD_EXTRA_WAIT: fsm_state_next = fsm_wait_done ? FSM_STATE_AFTER_CYCLE_TRIG : FSM_STATE_CYCLE_ADD_EXTRA_WAIT;
+ FSM_STATE_AFTER_CYCLE_TRIG: fsm_state_next = FSM_STATE_AFTER_CYCLE_WAIT ;
+ FSM_STATE_AFTER_CYCLE_WAIT: fsm_state_next = fsm_wait_done ? fsm_state_after_cycle : FSM_STATE_AFTER_CYCLE_WAIT;
+ FSM_STATE_INVERT_TRIG: fsm_state_next = FSM_STATE_INVERT_WAIT ;
+ FSM_STATE_INVERT_WAIT: fsm_state_next = fsm_wait_done ? FSM_STATE_CONVERT_TRIG : FSM_STATE_INVERT_WAIT;
+ FSM_STATE_CONVERT_TRIG: fsm_state_next = FSM_STATE_CONVERT_WAIT ;
+ FSM_STATE_CONVERT_WAIT: fsm_state_next = fsm_wait_done ? FSM_STATE_CONVERT_EXTRA_TRIG : FSM_STATE_CONVERT_WAIT;
+ FSM_STATE_CONVERT_EXTRA_TRIG: fsm_state_next = FSM_STATE_CONVERT_EXTRA_WAIT ;
+ FSM_STATE_CONVERT_EXTRA_WAIT: fsm_state_next = fsm_wait_done ? FSM_STATE_DONE : FSM_STATE_CONVERT_EXTRA_WAIT;
+ FSM_STATE_DONE: fsm_state_next = FSM_STATE_IDLE ;
+
+ endcase
+ //
+ end
+
+
+ //
+ // Worker
+ //
+ wire worker_output_now = (fsm_state == FSM_STATE_CONVERT_EXTRA_WAIT);
+
+ ecdsa256_uop_worker uop_worker
+ (
+ .clk (clk),
+ .rst_n (rst_n),
+
+ .ena (worker_trig),
+ .rdy (worker_done),
+ .uop_offset (worker_offset),
+ .output_now (worker_output_now),
+
+ .flagz_sz (worker_flagz_sz),
+ .flagz_rz (worker_flagz_rz),
+ .flagz_e (worker_flagz_e),
+ .flagz_f (worker_flagz_f),
+
+ .xy_addr (rxy_addr),
+ .xy_dout (rxy_dout),
+ .x_wren (rx_wren),
+ .y_wren (ry_wren)
+ );
+
+
+ //
+ // Ready Flag Logic
+ //
+ reg rdy_reg = 1'b1;
+ assign rdy = rdy_reg;
+
+ always @(posedge clk or negedge rst_n)
+ //
+ if (rst_n == 1'b0) rdy_reg <= 1'b1;
+ else case (fsm_state)
+ FSM_STATE_IDLE: if (ena) rdy_reg <= 1'b0;
+ FSM_STATE_DONE: rdy_reg <= 1'b1;
+ endcase
+
+
+endmodule
+
+
+//------------------------------------------------------------------------------
+// End-of-File
+//------------------------------------------------------------------------------
diff --git a/rtl/ecdsa256_core_top.v b/rtl/ecdsa256_core_top.v
new file mode 100644
index 0000000..3ce4174
--- /dev/null
+++ b/rtl/ecdsa256_core_top.v
@@ -0,0 +1,150 @@
+//======================================================================
+//
+// Copyright (c) 2016, 2018 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 ecdsa256_core_top
+(
+ input wire clk,
+ input wire rst_n,
+
+ input wire next,
+ output wire valid,
+
+ input wire bus_cs,
+ input wire bus_we,
+ input wire [ 4:0] bus_addr,
+ input wire [31:0] bus_data_wr,
+ output wire [31:0] bus_data_rd
+);
+
+
+ //
+ // Memory Banks
+ //
+ localparam [1:0] BUS_ADDR_BANK_K = 2'b00;
+ localparam [1:0] BUS_ADDR_BANK_X = 2'b01;
+ localparam [1:0] BUS_ADDR_BANK_Y = 2'b10;
+
+ wire [1:0] bus_addr_upper = bus_addr[4:3];
+ wire [2:0] bus_addr_lower = bus_addr[2:0];
+
+
+ //
+ // Memories
+ //
+
+ wire [31:0] user_rw_k_bram_out;
+ wire [31:0] user_ro_x_bram_out;
+ wire [31:0] user_ro_y_bram_out;
+
+ wire [ 2:0] core_ro_k_bram_addr;
+ wire [ 2:0] core_rw_xy_bram_addr;
+
+ wire core_rw_x_bram_wren;
+ wire core_rw_y_bram_wren;
+
+ wire [31:0] core_ro_k_bram_dout;
+ wire [31:0] core_rw_xy_bram_din;
+
+ bram_1rw_1ro_readfirst #
+ (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
+ bram_k
+ ( .clk(clk),
+ .a_addr(bus_addr_lower), .a_out(user_rw_k_bram_out), .a_wr(bus_cs && bus_we && (bus_addr_upper == BUS_ADDR_BANK_K)), .a_in(bus_data_wr),
+ .b_addr(core_ro_k_bram_addr), .b_out(core_ro_k_bram_dout)
+ );
+
+ bram_1rw_1ro_readfirst #
+ (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
+ bram_x
+ ( .clk(clk),
+ .a_addr(core_rw_xy_bram_addr), .a_out(), .a_wr(core_rw_x_bram_wren), .a_in(core_rw_xy_bram_din),
+ .b_addr(bus_addr_lower), .b_out(user_ro_x_bram_out)
+ );
+
+ bram_1rw_1ro_readfirst #
+ (.MEM_WIDTH(32), .MEM_ADDR_BITS(3))
+ bram_y
+ ( .clk(clk),
+ .a_addr(core_rw_xy_bram_addr), .a_out(), .a_wr(core_rw_y_bram_wren), .a_in(core_rw_xy_bram_din),
+ .b_addr(bus_addr_lower), .b_out(user_ro_y_bram_out)
+ );
+
+
+ //
+ // Curve Base Point Multiplier
+ //
+ reg next_dly;
+
+ always @(posedge clk) next_dly <= next;
+
+ wire next_trig = next && !next_dly;
+
+ ecdsa256_base_point_multiplier base_point_multiplier_p256
+ (
+ .clk (clk),
+ .rst_n (rst_n),
+
+ .ena (next_trig),
+ .rdy (valid),
+
+ .k_addr (core_ro_k_bram_addr),
+ .rxy_addr (core_rw_xy_bram_addr),
+
+ .rx_wren (core_rw_x_bram_wren),
+ .ry_wren (core_rw_y_bram_wren),
+
+ .k_din (core_ro_k_bram_dout),
+ .rxy_dout (core_rw_xy_bram_din)
+ );
+
+ //
+ // Output Selector
+ //
+ reg [1:0] bus_addr_upper_prev;
+ always @(posedge clk) bus_addr_upper_prev = bus_addr_upper;
+
+ reg [31:0] bus_data_rd_mux;
+ assign bus_data_rd = bus_data_rd_mux;
+
+ always @(*)
+ //
+ case (bus_addr_upper_prev)
+ //
+ BUS_ADDR_BANK_K: bus_data_rd_mux = user_rw_k_bram_out;
+ BUS_ADDR_BANK_X: bus_data_rd_mux = user_ro_x_bram_out;
+ BUS_ADDR_BANK_Y: bus_data_rd_mux = user_ro_y_bram_out;
+ //
+ default: bus_data_rd_mux = {32{1'b0}};
+ //
+ endcase
+
+endmodule
diff --git a/rtl/ecdsa256_microcode_rom.v b/rtl/ecdsa256_microcode_rom.v
new file mode 100644
index 0000000..82321cb
--- /dev/null
+++ b/rtl/ecdsa256_microcode_rom.v
@@ -0,0 +1,424 @@
+//======================================================================
+//
+// Copyright (c) 2018, 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 ecdsa256_microcode_rom
+(
+ input wire clk,
+ input wire [UOP_ADDR_WIDTH-1:0] addr,
+ output reg [UOP_DATA_WIDTH-1:0] data
+);
+
+`include "ecdsa_uop.vh"
+
+ always @(posedge clk)
+ //
+ case (addr)
+
+ // PREPARE
+ 9'd000: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RX};
+ 9'd001: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY};
+ 9'd002: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RZ};
+ 9'd003: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ // CYCLE_DOUBLE
+ 9'd004: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_CYCLE_Z2};
+ 9'd005: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_RX, UOP_OPERAND_CYCLE_Z2, UOP_OPERAND_CYCLE_T1};
+ 9'd006: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_RX, UOP_OPERAND_CYCLE_Z2, UOP_OPERAND_CYCLE_T2};
+ 9'd007: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_T1, UOP_OPERAND_CYCLE_T2, UOP_OPERAND_CYCLE_T3};
+ 9'd008: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T3, UOP_OPERAND_CYCLE_T3, UOP_OPERAND_CYCLE_T4};
+ 9'd009: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_T4, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_T4};
+ 9'd010: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T3, UOP_OPERAND_CYCLE_T4, UOP_OPERAND_CYCLE_A};
+ 9'd011: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_RY, UOP_OPERAND_CYCLE_RY, UOP_OPERAND_CYCLE_B};
+ 9'd012: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_B, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_CYCLE_SZ};
+ 9'd013: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_B, UOP_OPERAND_CYCLE_B, UOP_OPERAND_CYCLE_C};
+ 9'd014: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_C, UOP_OPERAND_CYCLE_RX, UOP_OPERAND_CYCLE_D};
+ 9'd015: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_C, UOP_OPERAND_CYCLE_C, UOP_OPERAND_CYCLE_C2};
+ 9'd016: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_C2, UOP_OPERAND_CONST_DELTA, UOP_OPERAND_CYCLE_C2_2};
+ 9'd017: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_A, UOP_OPERAND_CYCLE_A, UOP_OPERAND_CYCLE_A2};
+ 9'd018: data <= {UOP_OPCODE_ADD, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_D, UOP_OPERAND_CYCLE_D, UOP_OPERAND_CYCLE_T1};
+ 9'd019: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_A2, UOP_OPERAND_CYCLE_T1, UOP_OPERAND_CYCLE_SX};
+ 9'd020: data <= {UOP_OPCODE_SUB, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_D, UOP_OPERAND_CYCLE_SX, UOP_OPERAND_CYCLE_T1};
+ 9'd021: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T1, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_T1};
+ 9'd022: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_A, UOP_OPERAND_CYCLE_T1, UOP_OPERAND_CYCLE_T2};
+ 9'd023: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T2, UOP_OPERAND_CYCLE_C2_2, UOP_OPERAND_CYCLE_SY};
+ 9'd024: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ // CYCLE_ADD
+ 9'd025: data <= {UOP_OPCODE_CMPZ, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_SZ, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ 9'd026: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_SZ, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_SZ};
+ 9'd027: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_SZ, UOP_OPERAND_CYCLE_SZ, UOP_OPERAND_CYCLE_A};
+ 9'd028: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_A, UOP_OPERAND_CYCLE_SZ, UOP_OPERAND_CYCLE_B};
+ 9'd029: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_B, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_B};
+ 9'd030: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_A, UOP_OPERAND_CONST_GX, UOP_OPERAND_CYCLE_C};
+ 9'd031: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_B, UOP_OPERAND_CONST_GY, UOP_OPERAND_CYCLE_D};
+ 9'd032: data <= {UOP_OPCODE_SUB, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_C, UOP_OPERAND_CYCLE_SX, UOP_OPERAND_CYCLE_E};
+ 9'd033: data <= {UOP_OPCODE_SUB, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_D, UOP_OPERAND_CYCLE_SY, UOP_OPERAND_CYCLE_F};
+ 9'd034: data <= {UOP_OPCODE_CMPZ, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_E, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ 9'd035: data <= {UOP_OPCODE_CMPZ, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_F, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ 9'd036: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_E, UOP_OPERAND_CYCLE_SZ, UOP_OPERAND_CYCLE_RZ};
+ 9'd037: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_E, UOP_OPERAND_CYCLE_E, UOP_OPERAND_CYCLE_G};
+ 9'd038: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_G, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_G};
+ 9'd039: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_E, UOP_OPERAND_CYCLE_G, UOP_OPERAND_CYCLE_H};
+ 9'd040: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_G, UOP_OPERAND_CYCLE_SX, UOP_OPERAND_CYCLE_J};
+ 9'd041: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_J, UOP_OPERAND_CYCLE_J, UOP_OPERAND_CYCLE_T1};
+ 9'd042: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_F, UOP_OPERAND_CYCLE_F, UOP_OPERAND_CYCLE_T2};
+ 9'd043: data <= {UOP_OPCODE_SUB, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_T2, UOP_OPERAND_CYCLE_T1, UOP_OPERAND_CYCLE_T3};
+ 9'd044: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T3, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_T3};
+ 9'd045: data <= {UOP_OPCODE_SUB, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_T3, UOP_OPERAND_CYCLE_H, UOP_OPERAND_CYCLE_RX};
+ 9'd046: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_J, UOP_OPERAND_CYCLE_RX, UOP_OPERAND_CYCLE_T1};
+ 9'd047: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_F, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_F};
+ 9'd048: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_F, UOP_OPERAND_CYCLE_T1, UOP_OPERAND_CYCLE_T2};
+ 9'd049: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_H, UOP_OPERAND_CYCLE_SY, UOP_OPERAND_CYCLE_T3};
+ 9'd050: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T2, UOP_OPERAND_CYCLE_T3, UOP_OPERAND_CYCLE_RY};
+ 9'd051: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_RY, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY};
+ 9'd052: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ // CYCLE_ADD_AT_INFINITY
+ 9'd053: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_GX, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RX};
+ 9'd054: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_GY, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY};
+ 9'd055: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RZ};
+ 9'd056: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ // CYCLE_ADD_SAME_X_SAME_Y
+ 9'd057: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_HX, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RX};
+ 9'd058: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_HY, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY};
+ 9'd059: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RZ};
+ 9'd060: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ // CYCLE_ADD_SAME_X
+ 9'd061: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RX};
+ 9'd062: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY};
+ 9'd063: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RZ};
+ 9'd064: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ // CYCLE_ADD_REGULAR
+ 9'd065: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_T1};
+ 9'd066: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_T2};
+ 9'd067: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_T3};
+ 9'd068: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ // CYCLE_K0
+ 9'd069: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_SX, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RX};
+ 9'd070: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_SY, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY};
+ 9'd071: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_SZ, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RZ};
+ 9'd072: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ // CYCLE_K1
+ 9'd073: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_RX, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_SX};
+ 9'd074: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_RY, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_SY};
+ 9'd075: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_SZ};
+ 9'd076: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ // CONVERT
+ 9'd077: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_A2, UOP_OPERAND_CYCLE_RX, UOP_OPERAND_CYCLE_SX};
+ 9'd078: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_A3, UOP_OPERAND_CYCLE_RY, UOP_OPERAND_CYCLE_SY};
+ 9'd079: data <= {UOP_OPCODE_CMPZ, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ 9'd080: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ // CONVERT_AT_INFINITY
+ 9'd081: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RX};
+ 9'd082: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY};
+ 9'd083: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ // CONVERT_REGULAR
+ 9'd084: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_SX, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RX};
+ 9'd085: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_SY, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY};
+ 9'd086: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+ // INVERT_P256
+ 9'd087: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RZ};
+ 9'd088: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_INVERT_R1};
+ 9'd089: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_X2};
+ 9'd090: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_X2, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_X2};
+ 9'd091: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_X2, UOP_OPERAND_INVERT_X2, UOP_OPERAND_INVERT_R1};
+ 9'd092: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_INVERT_X3};
+ 9'd093: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_X3, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_X3};
+ 9'd094: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_X3, UOP_OPERAND_INVERT_X3, UOP_OPERAND_INVERT_R1};
+ 9'd095: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd096: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd097: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_X3, UOP_OPERAND_INVERT_X6};
+ 9'd098: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_X6, UOP_OPERAND_INVERT_X6, UOP_OPERAND_INVERT_R1};
+ 9'd099: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd100: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd101: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd102: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd103: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd104: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_X6, UOP_OPERAND_INVERT_X12};
+ 9'd105: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_X12, UOP_OPERAND_INVERT_X12, UOP_OPERAND_INVERT_R1};
+ 9'd106: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd107: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd108: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_X3, UOP_OPERAND_INVERT_X15};
+ 9'd109: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_X15, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_X15};
+ 9'd110: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_X15, UOP_OPERAND_INVERT_X15, UOP_OPERAND_INVERT_R1};
+ 9'd111: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd112: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd113: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd114: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd115: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd116: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd117: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd118: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd119: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd120: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd121: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd122: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd123: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd124: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd125: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_X15, UOP_OPERAND_INVERT_X30};
+ 9'd126: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_X30, UOP_OPERAND_INVERT_X30, UOP_OPERAND_INVERT_R1};
+ 9'd127: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd128: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_X2, UOP_OPERAND_INVERT_X32};
+ 9'd129: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_X32, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_X32};
+ 9'd130: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_X32, UOP_OPERAND_INVERT_X32, UOP_OPERAND_INVERT_R1};
+ 9'd131: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd132: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd133: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd134: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd135: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd136: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd137: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd138: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd139: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd140: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd141: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd142: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd143: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd144: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd145: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd146: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd147: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd148: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd149: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd150: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd151: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd152: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd153: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd154: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd155: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd156: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd157: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd158: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd159: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd160: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd161: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd162: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_INVERT_R1};
+ 9'd163: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd164: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd165: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd166: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd167: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd168: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd169: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd170: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd171: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd172: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd173: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd174: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd175: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd176: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd177: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd178: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd179: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd180: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd181: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd182: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd183: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd184: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd185: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd186: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd187: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd188: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd189: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd190: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd191: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd192: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd193: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd194: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd195: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd196: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd197: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd198: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd199: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd200: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd201: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd202: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd203: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd204: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd205: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd206: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd207: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd208: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd209: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd210: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd211: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd212: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd213: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd214: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd215: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd216: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd217: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd218: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd219: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd220: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd221: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd222: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd223: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd224: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd225: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd226: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd227: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd228: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd229: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd230: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd231: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd232: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd233: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd234: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd235: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd236: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd237: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd238: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd239: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd240: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd241: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd242: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd243: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd244: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd245: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd246: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd247: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd248: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd249: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd250: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd251: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd252: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd253: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd254: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd255: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd256: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd257: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd258: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd259: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd260: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd261: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd262: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd263: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd264: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd265: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd266: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd267: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd268: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd269: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd270: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd271: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd272: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd273: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd274: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd275: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd276: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd277: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd278: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd279: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd280: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd281: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd282: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd283: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd284: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd285: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd286: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd287: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd288: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd289: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd290: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd291: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_X32, UOP_OPERAND_INVERT_R2};
+ 9'd292: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd293: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd294: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd295: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd296: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd297: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd298: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd299: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd300: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd301: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd302: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd303: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd304: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd305: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd306: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd307: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd308: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd309: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd310: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd311: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd312: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd313: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd314: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd315: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd316: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd317: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd318: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd319: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd320: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd321: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd322: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd323: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd324: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_X32, UOP_OPERAND_INVERT_R1};
+ 9'd325: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd326: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd327: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd328: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd329: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd330: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd331: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd332: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd333: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd334: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd335: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd336: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd337: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd338: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd339: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd340: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd341: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd342: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd343: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd344: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd345: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd346: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd347: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd348: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd349: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd350: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd351: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd352: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd353: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd354: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd355: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_X30, UOP_OPERAND_INVERT_R2};
+ 9'd356: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1};
+ 9'd357: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2};
+ 9'd358: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_A2};
+ 9'd359: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_A2, UOP_OPERAND_INVERT_A2, UOP_OPERAND_INVERT_R1};
+ 9'd360: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_INVERT_A3};
+ 9'd361: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE};
+
+ endcase
+
+endmodule
diff --git a/rtl/ecdsa256_operand_bank.v b/rtl/ecdsa256_operand_bank.v
new file mode 100644
index 0000000..807927c
--- /dev/null
+++ b/rtl/ecdsa256_operand_bank.v
@@ -0,0 +1,160 @@
+//======================================================================
+//
+// Copyright (c) 2018, 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 ecdsa256_operand_bank
+(
+ input clk,
+
+ input [ 9-1:0] a_addr,
+ input a_wr,
+ input [32-1:0] a_in,
+
+ input [ 9-1:0] b_addr,
+ output [32-1:0] b_out
+);
+
+
+ //
+ // BRAM
+ //
+ reg [31:0] bram[0:64*8-1];
+
+
+ //
+ // Initialization
+ //
+ initial begin
+ //
+ // CONST_ZERO
+ //
+ bram[ 0*8 + 7] = 32'h00000000;
+ bram[ 0*8 + 6] = 32'h00000000;
+ bram[ 0*8 + 5] = 32'h00000000;
+ bram[ 0*8 + 4] = 32'h00000000;
+ bram[ 0*8 + 3] = 32'h00000000;
+ bram[ 0*8 + 2] = 32'h00000000;
+ bram[ 0*8 + 1] = 32'h00000000;
+ bram[ 0*8 + 0] = 32'h00000000;
+ //
+ // CONST_ONE
+ //
+ bram[ 1*8 + 7] = 32'h00000000;
+ bram[ 1*8 + 6] = 32'h00000000;
+ bram[ 1*8 + 5] = 32'h00000000;
+ bram[ 1*8 + 4] = 32'h00000000;
+ bram[ 1*8 + 3] = 32'h00000000;
+ bram[ 1*8 + 2] = 32'h00000000;
+ bram[ 1*8 + 1] = 32'h00000000;
+ bram[ 1*8 + 0] = 32'h00000001;
+ //
+ // CONST_DELTA
+ //
+ bram[ 2*8 + 7] = 32'h7fffffff;
+ bram[ 2*8 + 6] = 32'h80000000;
+ bram[ 2*8 + 5] = 32'h80000000;
+ bram[ 2*8 + 4] = 32'h00000000;
+ bram[ 2*8 + 3] = 32'h00000000;
+ bram[ 2*8 + 2] = 32'h80000000;
+ bram[ 2*8 + 1] = 32'h00000000;
+ bram[ 2*8 + 0] = 32'h00000000;
+ //
+ // G_X
+ //
+ bram[ 3*8 + 7] = 32'h6b17d1f2;
+ bram[ 3*8 + 6] = 32'he12c4247;
+ bram[ 3*8 + 5] = 32'hf8bce6e5;
+ bram[ 3*8 + 4] = 32'h63a440f2;
+ bram[ 3*8 + 3] = 32'h77037d81;
+ bram[ 3*8 + 2] = 32'h2deb33a0;
+ bram[ 3*8 + 1] = 32'hf4a13945;
+ bram[ 3*8 + 0] = 32'hd898c296;
+ //
+ // G_Y
+ //
+ bram[ 4*8 + 7] = 32'h4fe342e2;
+ bram[ 4*8 + 6] = 32'hfe1a7f9b;
+ bram[ 4*8 + 5] = 32'h8ee7eb4a;
+ bram[ 4*8 + 4] = 32'h7c0f9e16;
+ bram[ 4*8 + 3] = 32'h2bce3357;
+ bram[ 4*8 + 2] = 32'h6b315ece;
+ bram[ 4*8 + 1] = 32'hcbb64068;
+ bram[ 4*8 + 0] = 32'h37bf51f5;
+ //
+ // H_X
+ //
+ bram[ 5*8 + 7] = 32'h7cf27b18;
+ bram[ 5*8 + 6] = 32'h8d034f7e;
+ bram[ 5*8 + 5] = 32'h8a523803;
+ bram[ 5*8 + 4] = 32'h04b51ac3;
+ bram[ 5*8 + 3] = 32'hc08969e2;
+ bram[ 5*8 + 2] = 32'h77f21b35;
+ bram[ 5*8 + 1] = 32'ha60b48fc;
+ bram[ 5*8 + 0] = 32'h47669978;
+ //
+ // H_Y
+ //
+ bram[ 6*8 + 7] = 32'h07775510;
+ bram[ 6*8 + 6] = 32'hdb8ed040;
+ bram[ 6*8 + 5] = 32'h293d9ac6;
+ bram[ 6*8 + 4] = 32'h9f7430db;
+ bram[ 6*8 + 3] = 32'hba7dade6;
+ bram[ 6*8 + 2] = 32'h3ce98229;
+ bram[ 6*8 + 1] = 32'h9e04b79d;
+ bram[ 6*8 + 0] = 32'h227873d1;
+ end
+
+
+ //
+ // Output Register
+ //
+ reg [32-1:0] bram_reg_b;
+
+ assign b_out = bram_reg_b;
+
+
+ //
+ // Write Port A
+ //
+ always @(posedge clk)
+ //
+ if (a_wr) bram[a_addr] <= a_in;
+
+
+ //
+ // Read Port B
+ //
+ always @(posedge clk)
+ //
+ bram_reg_b <= bram[b_addr];
+
+
+endmodule
diff --git a/rtl/ecdsa256_uop_worker.v b/rtl/ecdsa256_uop_worker.v
new file mode 100644
index 0000000..a754796
--- /dev/null
+++ b/rtl/ecdsa256_uop_worker.v
@@ -0,0 +1,604 @@
+//------------------------------------------------------------------------------
+//
+// ecdsa256_uop_worker.v
+// -----------------------------------------------------------------------------
+// ECDSA uOP Worker for P-256
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 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 ecdsa256_uop_worker
+(
+ clk, rst_n,
+ ena, rdy,
+ uop_offset,
+ output_now,
+ flagz_sz, flagz_rz,
+ flagz_e, flagz_f,
+ xy_addr, xy_dout, x_wren, y_wren
+);
+
+
+ //
+ // Microcode Header
+ //
+`include "ecdsa_uop.vh"
+
+
+ //
+ // Ports
+ //
+ input clk; // system clock
+ input rst_n; // active-low async reset
+
+ input ena; // enable input
+ output rdy; // ready output
+
+ input [UOP_ADDR_WIDTH-1:0] uop_offset; // starting offset
+
+ input output_now; // produce output
+
+ output flagz_sz; // SZ is zero
+ output flagz_rz; // RZ is zero
+ output flagz_e; // E is zero
+ output flagz_f; // F is zero
+
+ output [ 2: 0] xy_addr;
+ output [31: 0] xy_dout;
+ output x_wren;
+ output y_wren;
+
+
+ //
+ // Constants
+ //
+ localparam integer OPERAND_NUM_WORDS = 8; // 256 bits -> 8 x 32-bit words
+ localparam integer WORD_COUNTER_WIDTH = 3; // 0..7 -> 3 bits
+
+
+ //
+ // FSM
+ //
+ localparam [1:0] FSM_STATE_IDLE = 2'b00;
+ localparam [1:0] FSM_STATE_FETCH = 2'b01;
+ localparam [1:0] FSM_STATE_DECODE = 2'b10;
+ localparam [1:0] FSM_STATE_BUSY = 2'b11;
+
+ reg [1:0] fsm_state = FSM_STATE_IDLE;
+ reg [1:0] fsm_state_next;
+
+
+ //
+ // Microcode
+ //
+ reg [UOP_ADDR_WIDTH-1:0] uop_addr;
+ wire [UOP_DATA_WIDTH-1:0] uop_data;
+
+ wire [5:0] uop_data_opcode = uop_data[1 + 3*6 +: 6];
+ wire uop_data_banks = uop_data[0 + 3*6 +: 1];
+ wire [5:0] uop_data_operand_src1 = uop_data[0 + 2*6 +: 6];
+ wire [5:0] uop_data_operand_src2 = uop_data[0 + 1*6 +: 6];
+ wire [5:0] uop_data_operand_dst = uop_data[0 + 0*6 +: 6];
+
+ wire uop_data_opcode_is_stop = uop_data_opcode[5];
+ wire uop_data_opcode_is_mul = uop_data_opcode[4];
+ wire uop_data_opcode_is_sub = uop_data_opcode[3];
+ wire uop_data_opcode_is_add = uop_data_opcode[2];
+ wire uop_data_opcode_is_copy = uop_data_opcode[1];
+ wire uop_data_opcode_is_cmpz = uop_data_opcode[0];
+
+ ecdsa256_microcode_rom microcode_rom
+ (
+ .clk (clk),
+ .addr (uop_addr),
+ .data (uop_data)
+ );
+
+
+ //
+ // Microcode Address Increment Logic
+ //
+ always @(posedge clk)
+ //
+ if (fsm_state_next == FSM_STATE_FETCH)
+ uop_addr <= (fsm_state == FSM_STATE_IDLE) ? uop_offset : uop_addr + 1'b1;
+
+
+ //
+ // Multi-Word Mover
+ //
+ reg mw_mover_ena = 1'b0;
+ wire mw_mover_rdy;
+
+ wire [WORD_COUNTER_WIDTH-1:0] mw_mover_x_addr;
+ wire [WORD_COUNTER_WIDTH-1:0] mw_mover_y_addr;
+ wire [ 32-1:0] mw_mover_x_din;
+ wire [ 32-1:0] mw_mover_y_dout;
+ wire mw_mover_y_wren;
+
+ multiword_mover #
+ (
+ .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH),
+ .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS)
+ )
+ mw_mover_inst
+ (
+ .clk (clk),
+ .rst_n (rst_n),
+ .ena (mw_mover_ena),
+ .rdy (mw_mover_rdy),
+ .x_addr (mw_mover_x_addr),
+ .y_addr (mw_mover_y_addr),
+ .y_wren (mw_mover_y_wren),
+ .x_din (mw_mover_x_din),
+ .y_dout (mw_mover_y_dout)
+ );
+
+
+ //
+ // Modular Multiplier
+ //
+ reg mod_mul_ena = 1'b0;
+ wire mod_mul_rdy;
+
+ wire [WORD_COUNTER_WIDTH-1:0] mod_mul_a_addr;
+ wire [WORD_COUNTER_WIDTH-1:0] mod_mul_b_addr;
+ wire [WORD_COUNTER_WIDTH-1:0] mod_mul_p_addr;
+ wire [ 32-1:0] mod_mul_a_din;
+ wire [ 32-1:0] mod_mul_b_din;
+ wire [ 32-1:0] mod_mul_p_dout;
+ wire mod_mul_p_wren;
+
+ ecdsa256_modular_multiplier mod_mul_inst
+ (
+ .clk (clk),
+ .rst_n (rst_n),
+ .ena (mod_mul_ena),
+ .rdy (mod_mul_rdy),
+ .a_addr (mod_mul_a_addr),
+ .b_addr (mod_mul_b_addr),
+ .p_addr (mod_mul_p_addr),
+ .p_wren (mod_mul_p_wren),
+ .a_din (mod_mul_a_din),
+ .b_din (mod_mul_b_din),
+ .p_dout (mod_mul_p_dout)
+ );
+
+
+ //
+ // Modular Adder
+ //
+ reg mod_add_ena = 1'b0;
+ wire mod_add_rdy;
+
+ wire [WORD_COUNTER_WIDTH-1:0] mod_add_ab_addr;
+ wire [WORD_COUNTER_WIDTH-1:0] mod_add_n_addr;
+ wire [WORD_COUNTER_WIDTH-1:0] mod_add_s_addr;
+ wire [ 32-1:0] mod_add_a_din;
+ wire [ 32-1:0] mod_add_b_din;
+ wire [ 32-1:0] mod_add_n_din;
+ wire [ 32-1:0] mod_add_s_dout;
+ wire mod_add_s_wren;
+
+ modular_adder #
+ (
+ .OPERAND_NUM_WORDS(OPERAND_NUM_WORDS),
+ .WORD_COUNTER_WIDTH(WORD_COUNTER_WIDTH)
+ )
+ mod_add_inst
+ (
+ .clk (clk),
+ .rst_n (rst_n),
+ .ena (mod_add_ena),
+ .rdy (mod_add_rdy),
+ .ab_addr (mod_add_ab_addr),
+ .n_addr (mod_add_n_addr),
+ .s_addr (mod_add_s_addr),
+ .s_wren (mod_add_s_wren),
+ .a_din (mod_add_a_din),
+ .b_din (mod_add_b_din),
+ .n_din (mod_add_n_din),
+ .s_dout (mod_add_s_dout)
+ );
+
+
+ //
+ // Modular Subtractor
+ //
+ reg mod_sub_ena = 1'b0;
+ wire mod_sub_rdy;
+
+ wire [WORD_COUNTER_WIDTH-1:0] mod_sub_ab_addr;
+ wire [WORD_COUNTER_WIDTH-1:0] mod_sub_n_addr;
+ wire [WORD_COUNTER_WIDTH-1:0] mod_sub_d_addr;
+ wire [ 32-1:0] mod_sub_a_din;
+ wire [ 32-1:0] mod_sub_b_din;
+ wire [ 32-1:0] mod_sub_n_din;
+ wire [ 32-1:0] mod_sub_d_dout;
+ wire mod_sub_d_wren;
+
+ modular_subtractor #
+ (
+ .OPERAND_NUM_WORDS(OPERAND_NUM_WORDS),
+ .WORD_COUNTER_WIDTH(WORD_COUNTER_WIDTH)
+ )
+ mod_sub_inst
+ (
+ .clk (clk),
+ .rst_n (rst_n),
+ .ena (mod_sub_ena),
+ .rdy (mod_sub_rdy),
+ .ab_addr (mod_sub_ab_addr),
+ .n_addr (mod_sub_n_addr),
+ .d_addr (mod_sub_d_addr),
+ .d_wren (mod_sub_d_wren),
+ .a_din (mod_sub_a_din),
+ .b_din (mod_sub_b_din),
+ .n_din (mod_sub_n_din),
+ .d_dout (mod_sub_d_dout)
+ );
+
+
+ //
+ // Modulus (two instances for better placement and routing)
+ //
+ ecdsa256_modulus_distmem modulus_add
+ (
+ .clk (clk),
+ .b_addr (mod_add_n_addr),
+ .b_out (mod_add_n_din)
+ );
+
+ ecdsa256_modulus_distmem modulus_sub
+ (
+ .clk (clk),
+ .b_addr (mod_sub_n_addr),
+ .b_out (mod_sub_n_din)
+ );
+
+
+ //
+ // Multi-Word Comparator
+ //
+ reg mw_comp_ena = 1'b0;
+ wire mw_comp_rdy;
+
+ wire mw_comp_cmp_e;
+
+ wire [WORD_COUNTER_WIDTH-1:0] mw_comp_x_addr;
+ wire [ 32-1:0] mw_comp_x_din;
+
+ multiword_comparator #
+ (
+ .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH),
+ .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS)
+ )
+ mw_comp_inst
+ (
+ .clk (clk),
+ .rst_n (rst_n),
+ .ena (mw_comp_ena),
+ .rdy (mw_comp_rdy),
+ .xy_addr (mw_comp_x_addr),
+ .x_din (mw_comp_x_din),
+ .y_din ({32{1'b0}}),
+ .cmp_l (),
+ .cmp_e (mw_comp_cmp_e),
+ .cmp_g ()
+ );
+
+
+ //
+ // Comparison Flags
+ //
+ reg flagz_sz_reg;
+ reg flagz_rz_reg;
+ reg flagz_e_reg;
+ reg flagz_f_reg;
+
+ assign flagz_sz = flagz_sz_reg;
+ assign flagz_rz = flagz_rz_reg;
+ assign flagz_e = flagz_e_reg;
+ assign flagz_f = flagz_f_reg;
+
+ reg mw_comp_rdy_dly = 1'b1;
+
+ always @(posedge clk) mw_comp_rdy_dly <= mw_comp_rdy;
+
+ always @(posedge clk)
+ //
+ if (mw_comp_rdy && !mw_comp_rdy_dly)
+ //
+ case (uop_data_operand_src1)
+ UOP_OPERAND_CYCLE_SZ: flagz_sz_reg <= mw_comp_cmp_e;
+ UOP_OPERAND_CYCLE_RZ: flagz_rz_reg <= mw_comp_cmp_e;
+ UOP_OPERAND_CYCLE_E: flagz_e_reg <= mw_comp_cmp_e;
+ UOP_OPERAND_CYCLE_F: flagz_f_reg <= mw_comp_cmp_e;
+ endcase
+
+
+
+ //
+ // uOP Trigger Logic
+ //
+ always @(posedge clk)
+ //
+ if (fsm_state == FSM_STATE_DECODE) begin
+ mw_comp_ena <= uop_data_opcode_is_cmpz;
+ mw_mover_ena <= uop_data_opcode_is_copy;
+ mod_mul_ena <= uop_data_opcode_is_mul;
+ mod_add_ena <= uop_data_opcode_is_add;
+ mod_sub_ena <= uop_data_opcode_is_sub;
+ end else begin
+ mw_comp_ena <= 1'b0;
+ mw_mover_ena <= 1'b0;
+ mod_mul_ena <= 1'b0;
+ mod_add_ena <= 1'b0;
+ mod_sub_ena <= 1'b0;
+ end
+
+
+ //
+ // uOP Completion Detector
+ //
+ reg fsm_exit_from_busy;
+
+ always @* begin
+ //
+ fsm_exit_from_busy = 0;
+ //
+ if (uop_data_opcode_is_cmpz) fsm_exit_from_busy = ~mw_comp_ena & mw_comp_rdy;
+ if (uop_data_opcode_is_copy) fsm_exit_from_busy = ~mw_mover_ena & mw_mover_rdy;
+ if (uop_data_opcode_is_mul) fsm_exit_from_busy = ~mod_mul_ena & mod_mul_rdy;
+ if (uop_data_opcode_is_add) fsm_exit_from_busy = ~mod_add_ena & mod_add_rdy;
+ if (uop_data_opcode_is_sub) fsm_exit_from_busy = ~mod_sub_ena & mod_sub_rdy;
+ //
+ end
+
+
+ //
+ // Banks
+ //
+ reg [ 2:0] banks_src1_addr;
+ reg [ 2:0] banks_src2_addr;
+ reg [ 2:0] banks_dst_addr;
+
+ reg banks_dst_wren;
+
+ reg [31:0] banks_dst_din;
+
+ wire [31:0] banks_src1_dout;
+ wire [31:0] banks_src2_dout;
+
+ ecdsa256_banks_array banks_array
+ (
+ .clk (clk),
+
+ .banks (uop_data_banks),
+
+ .src1_operand (uop_data_operand_src1),
+ .src2_operand (uop_data_operand_src2),
+ .dst_operand (uop_data_operand_dst),
+
+ .src1_addr (banks_src1_addr),
+ .src2_addr (banks_src2_addr),
+ .dst_addr (banks_dst_addr),
+
+ .dst_wren (banks_dst_wren),
+
+ .src1_dout (banks_src1_dout),
+ .src2_dout (banks_src2_dout),
+
+ .dst_din (banks_dst_din)
+ );
+
+ assign mw_comp_x_din = banks_src1_dout;
+ assign mw_mover_x_din = banks_src1_dout;
+ assign mod_mul_a_din = banks_src1_dout;
+ assign mod_mul_b_din = banks_src2_dout;
+ assign mod_add_a_din = banks_src1_dout;
+ assign mod_add_b_din = banks_src2_dout;
+ assign mod_sub_a_din = banks_src1_dout;
+ assign mod_sub_b_din = banks_src2_dout;
+
+ always @*
+ //
+ case (uop_data_opcode)
+ //
+ UOP_OPCODE_CMPZ: begin
+ banks_src1_addr = mw_comp_x_addr;
+ banks_src2_addr = {3{1'bX}};
+ //
+ banks_dst_addr = {3{1'bX}};
+ //
+ banks_dst_wren = 1'b0;
+ //
+ banks_dst_din = {32{1'bX}};
+ end
+ //
+ UOP_OPCODE_COPY: begin
+ //
+ banks_src1_addr = mw_mover_x_addr;
+ banks_src2_addr = {3{1'bX}};
+ //
+ banks_dst_addr = mw_mover_y_addr;
+ //
+ banks_dst_wren = mw_mover_y_wren;
+ //
+ banks_dst_din = mw_mover_y_dout;
+ //
+ end
+ //
+ UOP_OPCODE_ADD: begin
+ //
+ banks_src1_addr = mod_add_ab_addr;
+ banks_src2_addr = mod_add_ab_addr;
+ //
+ banks_dst_addr = mod_add_s_addr;
+ //
+ banks_dst_wren = mod_add_s_wren;
+ //
+ banks_dst_din = mod_add_s_dout;
+ //
+ end
+ //
+ UOP_OPCODE_SUB: begin
+ //
+ banks_src1_addr = mod_sub_ab_addr;
+ banks_src2_addr = mod_sub_ab_addr;
+ //
+ banks_dst_addr = mod_sub_d_addr;
+ //
+ banks_dst_wren = mod_sub_d_wren;
+ //
+ banks_dst_din = mod_sub_d_dout;
+ //
+ end
+ //
+ UOP_OPCODE_MUL: begin
+ //
+ banks_src1_addr = mod_mul_a_addr;
+ banks_src2_addr = mod_mul_b_addr;
+ //
+ banks_dst_addr = mod_mul_p_addr;
+ //
+ banks_dst_wren = mod_mul_p_wren;
+ //
+ banks_dst_din = mod_mul_p_dout;
+ //
+ end
+ //
+ default: begin
+ //
+ banks_src1_addr = {3{1'bX}};
+ banks_src2_addr = {3{1'bX}};
+ //
+ banks_dst_addr = {3{1'bX}};
+ //
+ banks_dst_wren = 1'b0;
+ //
+ banks_dst_din = {32{1'bX}};
+ //
+ end
+ //
+ endcase
+
+
+ //
+ // FSM Process
+ //
+ always @(posedge clk or negedge rst_n)
+ //
+ if (rst_n == 1'b0) fsm_state <= FSM_STATE_IDLE;
+ else fsm_state <= fsm_state_next;
+
+
+ //
+ // FSM Transition Logic
+ //
+ always @* begin
+ //
+ fsm_state_next = FSM_STATE_IDLE;
+ //
+ case (fsm_state)
+ FSM_STATE_IDLE: fsm_state_next = ena ? FSM_STATE_FETCH : FSM_STATE_IDLE;
+ FSM_STATE_FETCH: fsm_state_next = FSM_STATE_DECODE;
+ FSM_STATE_DECODE: fsm_state_next = uop_data_opcode_is_stop ? FSM_STATE_IDLE : FSM_STATE_BUSY;
+ FSM_STATE_BUSY: fsm_state_next = fsm_exit_from_busy ? FSM_STATE_FETCH : FSM_STATE_BUSY;
+ endcase
+ //
+ end
+
+
+ //
+ // Ready Flag Logic
+ //
+ reg rdy_reg = 1'b1;
+ assign rdy = rdy_reg;
+
+ always @(posedge clk or negedge rst_n)
+ //
+ if (rst_n == 1'b0) rdy_reg <= 1'b1;
+ else case (fsm_state)
+ FSM_STATE_IDLE: rdy_reg <= ~ena;
+ FSM_STATE_DECODE: rdy_reg <= uop_data_opcode_is_stop;
+ endcase
+
+
+ //
+ // Output Logic
+ //
+ reg [ 2: 0] xy_addr_reg = 3'b000;
+ reg [31: 0] xy_dout_reg = 32'h00000000;
+ reg x_wren_reg = 1'b0;
+ reg y_wren_reg = 1'b0;
+
+ assign xy_addr = xy_addr_reg;
+ assign xy_dout = xy_dout_reg;
+ assign x_wren = x_wren_reg;
+ assign y_wren = y_wren_reg;
+
+ reg xy_phase; // 0 - x, 1 - y
+
+ always @(posedge clk)
+ //
+ if (output_now) begin
+
+ if (ena)
+ xy_phase <= 1'b0;
+ else if (!mw_mover_ena && mw_mover_rdy && (fsm_state == FSM_STATE_BUSY))
+ xy_phase <= 1'b1;
+
+ end
+
+
+ always @(posedge clk)
+ //
+ if (output_now && mw_mover_y_wren) xy_addr_reg <= mw_mover_y_addr;
+ else xy_addr_reg <= 3'b000;
+
+ always @(posedge clk)
+ //
+ if (output_now && mw_mover_y_wren) xy_dout_reg <= mw_mover_y_dout;
+ else xy_dout_reg <= 32'h00000000;
+
+ always @(posedge clk)
+ //
+ if (output_now && mw_mover_y_wren) {y_wren_reg, x_wren_reg} <= {xy_phase, ~xy_phase};
+ else {y_wren_reg, x_wren_reg} <= 2'b00;
+
+endmodule
+
+
+//------------------------------------------------------------------------------
+// End-of-File
+//------------------------------------------------------------------------------
diff --git a/rtl/ecdsa256_wrapper.v b/rtl/ecdsa256_wrapper.v
index 1684599..2b1d781 100644
--- a/rtl/ecdsa256_wrapper.v
+++ b/rtl/ecdsa256_wrapper.v
@@ -1,6 +1,6 @@
//======================================================================
//
-// Copyright (c) 2016, NORDUnet A/S All rights reserved.
+// Copyright (c) 2016, 2018 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
@@ -31,17 +31,17 @@
//======================================================================
module ecdsa256_wrapper
- (
- input wire clk,
- input wire reset_n,
+(
+ input wire clk,
+ input wire reset_n,
- input wire cs,
- input wire we,
+ input wire cs,
+ input wire we,
- input wire [5: 0] address,
- input wire [31: 0] write_data,
- output wire [31: 0] read_data
- );
+ input wire [ 5:0] address,
+ input wire [31:0] write_data,
+ output wire [31:0] read_data
+);
//
@@ -50,15 +50,15 @@ module ecdsa256_wrapper
localparam ADDR_MSB_REGS = 1'b0;
localparam ADDR_MSB_CORE = 1'b1;
- wire [0:0] addr_msb = address[5];
- wire [4:0] addr_lsb = address[4:0];
+ wire [0:0] addr_msb = address[5];
+ wire [4:0] addr_lsb = address[4:0];
//
// Output Mux
//
- wire [31: 0] read_data_regs;
- wire [31: 0] read_data_core;
+ wire [31:0] read_data_regs;
+ wire [31:0] read_data_core;
//
@@ -80,45 +80,45 @@ module ecdsa256_wrapper
localparam CORE_NAME0 = 32'h65636473; // "ecds"
localparam CORE_NAME1 = 32'h61323536; // "a256"
- localparam CORE_VERSION = 32'h302E3131; // "0.11"
+ localparam CORE_VERSION = 32'h302E3230; // "0.20"
//
// Registers
//
- reg reg_control;
- reg [31:0] reg_dummy;
+ reg reg_control;
+ reg [31:0] reg_dummy;
//
// Wires
//
- wire reg_status;
+ wire reg_status;
- //
- // ECDSA256
- //
- ecdsa256 ecdsa256_inst
- (
- .clk (clk),
- .rst_n (reset_n),
+ //
+ // ECDSA256
+ //
+ ecdsa256_core_top ecdsa256_inst
+ (
+ .clk (clk),
+ .rst_n (reset_n),
- .next (reg_control),
- .valid (reg_status),
+ .next (reg_control),
+ .valid (reg_status),
- .bus_cs (cs && (addr_msb == ADDR_MSB_CORE)),
- .bus_we (we),
- .bus_addr (addr_lsb),
- .bus_data_wr (write_data),
- .bus_data_rd (read_data_core)
- );
+ .bus_cs (cs && (addr_msb == ADDR_MSB_CORE)),
+ .bus_we (we),
+ .bus_addr (addr_lsb),
+ .bus_data_wr (write_data),
+ .bus_data_rd (read_data_core)
+ );
//
// Read Latch
//
- reg [31: 0] tmp_read_data;
+ reg [31:0] tmp_read_data;
//
@@ -139,7 +139,7 @@ module ecdsa256_wrapper
case (addr_lsb)
//
ADDR_CONTROL: reg_control <= write_data[CONTROL_NEXT_BIT];
- ADDR_DUMMY: reg_dummy <= write_data;
+ ADDR_DUMMY: reg_dummy <= write_data;
//
endcase
//
@@ -154,7 +154,7 @@ module ecdsa256_wrapper
ADDR_VERSION: tmp_read_data <= CORE_VERSION;
ADDR_CONTROL: tmp_read_data <= {{30{1'b0}}, reg_control, 1'b0};
ADDR_STATUS: tmp_read_data <= {{30{1'b0}}, reg_status, 1'b1};
- ADDR_DUMMY: tmp_read_data <= reg_dummy;
+ ADDR_DUMMY: tmp_read_data <= reg_dummy;
//
default: tmp_read_data <= 32'h00000000;
//
diff --git a/rtl/modular/modular_multiplier_256.v b/rtl/modular/modular_multiplier_256.v
deleted file mode 100644
index 2b35233..0000000
--- a/rtl/modular/modular_multiplier_256.v
+++ /dev/null
@@ -1,402 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// modular_multiplier_256.v
-// -----------------------------------------------------------------------------
-// Modular multiplier.
-//
-// 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 modular_multiplier_256
- (
- clk, rst_n,
- ena, rdy,
- a_addr, b_addr, n_addr, p_addr, p_wren,
- a_din, b_din, n_din, p_dout
- );
-
-
- //
- // Constants
- //
- localparam OPERAND_NUM_WORDS = 8;
- localparam 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 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] a_addr; // index of current A word
- output wire [WORD_COUNTER_WIDTH-1:0] b_addr; // index of current B word
- output wire [WORD_COUNTER_WIDTH-1:0] n_addr; // index of current N word
- output wire [WORD_COUNTER_WIDTH-1:0] p_addr; // index of current P word
- output wire p_wren; // store current P word now
-
- input wire [ 31:0] a_din; // A
- input wire [ 31:0] b_din; // B
- input wire [ 31:0] n_din; // N (must be P-256!)
- output wire [ 31:0] p_dout; // P = A * B mod N
-
-
- //
- // 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 FSM_SHREG_WIDTH = (1 * OPERAND_NUM_WORDS + 1) + (2 * OPERAND_NUM_WORDS + 1) + (2 * OPERAND_NUM_WORDS + 2) + (0 * OPERAND_NUM_WORDS + 2) + 1;
-
- reg [FSM_SHREG_WIDTH-1:0] fsm_shreg;
-
- assign rdy = fsm_shreg[0];
-
- wire [1 * OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_a = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 1) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 0)];
- wire [1 * OPERAND_NUM_WORDS-1:0] fsm_shreg_store_word_a = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 2) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 1)];
- wire [2 * OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_b = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 1) : FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 1)];
- wire [2 * OPERAND_NUM_WORDS-2:0] fsm_shreg_store_si_msb = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 2) : FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 1)];
- wire [0 * OPERAND_NUM_WORDS-0:0] fsm_shreg_store_si_lsb = fsm_shreg[FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 2) : FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 2)];
- wire [2 * OPERAND_NUM_WORDS-2:0] fsm_shreg_shift_si = fsm_shreg[FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 3) : FSM_SHREG_WIDTH - (5 * OPERAND_NUM_WORDS + 1)];
- wire [0 * OPERAND_NUM_WORDS-0:0] fsm_shreg_mask_cw1_sum = fsm_shreg[FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 4) : FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 4)];
- wire [2 * OPERAND_NUM_WORDS-1:0] fsm_shreg_store_c_word = fsm_shreg[FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 5) : FSM_SHREG_WIDTH - (5 * OPERAND_NUM_WORDS + 4)];
- wire [0 * OPERAND_NUM_WORDS-0:0] fsm_shreg_reduce_start = fsm_shreg[FSM_SHREG_WIDTH - (5 * OPERAND_NUM_WORDS + 5) : FSM_SHREG_WIDTH - (5 * OPERAND_NUM_WORDS + 5)];
- wire [0 * OPERAND_NUM_WORDS-0:0] fsm_shreg_reduce_stop = fsm_shreg[FSM_SHREG_WIDTH - (5 * OPERAND_NUM_WORDS + 6) : FSM_SHREG_WIDTH - (5 * OPERAND_NUM_WORDS + 6)];
-
- wire inc_index_a = |fsm_shreg_inc_index_a;
- wire store_word_a = |fsm_shreg_store_word_a;
- wire inc_index_b = |fsm_shreg_inc_index_b;
- wire clear_mac_ab = |fsm_shreg_inc_index_b;
- wire shift_wide_a = |fsm_shreg_inc_index_b;
- wire enable_mac_ab = |fsm_shreg_inc_index_b;
- wire store_si_msb = |fsm_shreg_store_si_msb;
- wire store_si_lsb = fsm_shreg_store_si_lsb;
- wire shift_si = |fsm_shreg_shift_si;
- wire mask_cw1_sum = fsm_shreg_mask_cw1_sum;
- wire store_c_word = |fsm_shreg_store_c_word;
- wire reduce_start = fsm_shreg_reduce_start;
- wire reduce_stop = fsm_shreg_reduce_stop;
-
-
- //
- // FSM Logic
- //
- wire reduce_done;
-
- 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 if (!reduce_stop || reduce_done)
- fsm_shreg <= {1'b0, fsm_shreg[FSM_SHREG_WIDTH-1:1]};
- //
- end
-
-
- //
- // Word Index Increment Logic
- //
- reg index_b_ff;
-
- always @(posedge clk)
- //
- if (inc_index_b) index_b_ff <= ~index_b_ff;
- else index_b_ff <= 1'b0;
-
- always @(posedge clk)
- //
- if (rdy) begin
- //
- index_a <= WORD_INDEX_ZERO;
- index_b <= WORD_INDEX_LAST;
- //
- end else begin
- //
- if (inc_index_a) index_a <= WORD_INDEX_NEXT_OR_ZERO(index_a);
- if (inc_index_b && !index_b_ff) index_b <= WORD_INDEX_PREVIOUS_OR_LAST(index_b);
- //
- end
-
-
- //
- // Wide Operand Buffer
- //
- reg [255:0] buf_a_wide;
-
- always @(posedge clk)
- //
- if (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 (shift_wide_a)
- buf_a_wide <= {buf_a_wide[256-(16+1):0], buf_a_wide[256-16+:16]};
-
-
- //
- // Multiplier Array
- //
- wire mac_inhibit; // control signal to pause all accumulators
-
- wire [46: 0] mac[0:15]; // outputs of all accumulators
- reg [15: 0] mac_clear; // individual per-accumulator clear flag
-
- assign mac_inhibit = ~enable_mac_ab;
-
- always @(posedge clk)
- //
- if (!clear_mac_ab)
- mac_clear <= {16{1'b1}};
- else begin
-
- if (mac_clear == {16{1'b1}})
- mac_clear <= {{14{1'b0}}, 1'b1, {1{1'b0}}};
- else
- mac_clear <= (mac_clear[15] == 1'b0) ? {mac_clear[14:0], 1'b0} : {16{1'b1}};
-
-
- end
-
- //
- // Array of parallel multipliers
- //
- genvar i;
- generate for (i=0; i<16; i=i+1)
- begin : gen_mac_array
- //
- mac16_wrapper mac16_inst
- (
- .clk (clk),
- .ce (~mac_inhibit),
-
- .clr (mac_clear[i]),
-
- .a (buf_a_wide[16*i+:16]),
- .b (index_b_ff ? b_din[15:0] : b_din[31:16]),
- .s (mac[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[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[i] : si_msb[47*(15-i)+:47];
- end
- endgenerate
-
- always @(posedge clk) begin
- //
- if (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 (store_si_msb)
- si_msb <= si_msb_new;
-
- if (store_si_lsb)
- si_lsb <= si_lsb_new;
- end
-
- end
-
-
- //
- // Accumulators
- //
- wire [46: 0] add47_cw0_s;
- wire [46: 0] add47_cw1_s;
-
-
- //
- // cw0, b, cw1, b
- //
- reg [30: 0] si_prev_dly;
- reg [15: 0] si_next_dly;
-
- always @(posedge clk)
- //
- if (shift_si)
- si_prev_dly <= si_lsb[93:63];
- else
- si_prev_dly <= {31{1'b0}};
-
- always @(posedge clk)
- //
- si_next_dly <= si_lsb[62:47];
-
- 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, mask_cw1_sum ? {16{1'b0}} : {1'b0, add47_cw1_s[46:32]}};
-
- adder47_wrapper add47_cw0_inst
- (
- .clk (clk),
- .a (add47_cw0_a),
- .b (add47_cw0_b),
- .s (add47_cw0_s)
- );
-
- adder47_wrapper add47_cw1_inst
- (
- .clk (clk),
- .a (add47_cw1_a),
- .b (add47_cw1_b),
- .s (add47_cw1_s)
- );
-
-
-
- //
- // Full-Size Product
- //
- reg [WORD_COUNTER_WIDTH:0] bram_c_addr;
-
- wire [WORD_COUNTER_WIDTH:0] reduce_c_addr;
- wire [ 31:0] reduce_c_word;
-
- always @(posedge clk)
- //
- if (store_c_word)
- bram_c_addr <= bram_c_addr + 1'b1;
- else
- bram_c_addr <= {2*WORD_COUNTER_WIDTH{1'b0}};
-
- bram_1rw_1ro_readfirst #
- (
- .MEM_WIDTH (32),
- .MEM_ADDR_BITS (WORD_COUNTER_WIDTH + 1)
- )
- bram_c_inst
- (
- .clk (clk),
-
- .a_addr (bram_c_addr),
- .a_wr (store_c_word),
- .a_in (add47_cw1_s[31:0]),
- .a_out (),
-
- .b_addr (reduce_c_addr),
- .b_out (reduce_c_word)
- );
-
-
- //
- // Reduction Stage
- //
- modular_reductor_256 reduce_256_inst
- (
- .clk (clk),
- .rst_n (rst_n),
-
- .ena (reduce_start),
- .rdy (reduce_done),
-
- .x_addr (reduce_c_addr),
- .n_addr (n_addr),
- .p_addr (p_addr),
- .p_wren (p_wren),
-
- .x_din (reduce_c_word),
- .n_din (n_din),
- .p_dout (p_dout)
- );
-
-
- endmodule
-
-
-//------------------------------------------------------------------------------
-// End-of-File
-//------------------------------------------------------------------------------
diff --git a/rtl/modular/modular_reductor_256.v b/rtl/modular/modular_reductor_256.v
deleted file mode 100644
index 6f31570..0000000
--- a/rtl/modular/modular_reductor_256.v
+++ /dev/null
@@ -1,692 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// modular_reductor_256.v
-// -----------------------------------------------------------------------------
-// Modular reductor.
-//
-// 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 modular_reductor_256
- (
- clk, rst_n,
- ena, rdy,
- x_addr, n_addr, p_addr, p_wren,
- x_din, n_din, p_dout
- );
-
- //
- // Constants
- //
- localparam OPERAND_NUM_WORDS = 8;
- localparam WORD_COUNTER_WIDTH = 3;
-
-
- //
- // Handy Numbers
- //
- localparam [WORD_COUNTER_WIDTH:0] WORD_INDEX_ZERO = 0;
- localparam [WORD_COUNTER_WIDTH:0] WORD_INDEX_LAST = 2 * OPERAND_NUM_WORDS - 1;
-
-
- //
- // Handy Functions
- //
- function [WORD_COUNTER_WIDTH:0] WORD_INDEX_PREVIOUS_OR_LAST;
- input [WORD_COUNTER_WIDTH: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 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-0:0] x_addr; // index of current X word
- output wire [WORD_COUNTER_WIDTH-1:0] n_addr; // index of current N word
- output wire [WORD_COUNTER_WIDTH-1:0] p_addr; // index of current P word
- output wire p_wren; // store current P word now
-
- input wire [ 31:0] x_din; // X
- input wire [ 31:0] n_din; // N (must be P-256!)
- output wire [ 31:0] p_dout; // P = X mod N
-
-
- //
- // Word Indices
- //
- reg [WORD_COUNTER_WIDTH:0] index_x;
-
-
- /* map registers to output ports */
- assign x_addr = index_x;
-
-
- //
- // FSM
- //
- localparam FSM_SHREG_WIDTH = (2 * OPERAND_NUM_WORDS + 1) + (5 * 2) + 1;
-
- reg [FSM_SHREG_WIDTH-1:0] fsm_shreg;
-
- assign rdy = fsm_shreg[0];
-
- wire [2 * OPERAND_NUM_WORDS - 1:0] fsm_shreg_inc_index_x = fsm_shreg[FSM_SHREG_WIDTH - 0*OPERAND_NUM_WORDS - 1 -: 2 * OPERAND_NUM_WORDS];
- wire [2 * OPERAND_NUM_WORDS - 1:0] fsm_shreg_store_word_z = fsm_shreg[FSM_SHREG_WIDTH - 0*OPERAND_NUM_WORDS - 2 -: 2 * OPERAND_NUM_WORDS];
- wire [2 * 5 - 1:0] fsm_shreg_reduce_stages = fsm_shreg[ 1 +: 2 * 5];
-
- wire [5-1:0] fsm_shreg_reduce_stage_start;
- wire [5-1:0] fsm_shreg_reduce_stage_stop;
-
- genvar s;
- generate for (s=0; s<5; s=s+1)
- begin : gen_fsm_shreg_reduce_stages
- assign fsm_shreg_reduce_stage_start[5 - (s + 1)] = fsm_shreg_reduce_stages[2 * (5 - s) - 1];
- assign fsm_shreg_reduce_stage_stop[5 - (s + 1)] = fsm_shreg_reduce_stages[2 * (5 - s) - 2];
- end
- endgenerate
-
- wire inc_index_x = |fsm_shreg_inc_index_x;
- wire store_word_z = |fsm_shreg_store_word_z;
- wire reduce_start = |fsm_shreg_reduce_stage_start;
- wire reduce_stop = |fsm_shreg_reduce_stage_stop;
- wire store_p = fsm_shreg_reduce_stage_stop[0];
-
-
- wire reduce_adder0_done;
- wire reduce_adder1_done;
- wire reduce_subtractor_done;
-
- wire reduce_done_all = reduce_adder0_done & reduce_adder1_done & reduce_subtractor_done;
-
- 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 if (!reduce_stop || reduce_done_all)
- //
- fsm_shreg <= {1'b0, fsm_shreg[FSM_SHREG_WIDTH-1:1]};
- //
- end
-
-
- //
- // Word Index Increment Logic
- //
- always @(posedge clk)
- //
- if (rdy)
- //
- index_x <= WORD_INDEX_LAST;
- //
- else if (inc_index_x)
- //
- index_x <= WORD_INDEX_PREVIOUS_OR_LAST(index_x);
-
-
- //
- // Look-up Table
- //
-
- //
- // Take a look at the corresponding C model for more information
- // on how exactly the math behind reduction works. The first step
- // is to assemble nine 256-bit values ("z-words") from 32-bit parts
- // of the full 512-bit product ("c-word"). The problem with z5 is
- // that it contains c13 two times. This implementation scans from
- // c15 to c0 and writes current part of c-word into corresponding
- // parts of z-words. Since those 32-bit parts are stored in block
- // memories, one source word can only be written to one location in
- // every z-word at a time. The trick is to delay c13 and then write
- // the delayed value at the corresponding location in z5 instead of
- // the next c12. "z_save" flag is used to indicate that the current
- // word should be delayed and written once again during the next cycle.
- //
-
- reg [9*WORD_COUNTER_WIDTH-1:0] z_addr; //
- reg [9 -1:0] z_wren; //
- reg [9 -1:0] z_mask; // mask input to store zero word
- reg [9 -1:0] z_save; // save previous word once again
-
- always @(posedge clk)
- //
- if (inc_index_x)
- //
- case (index_x)
- //
- // s9 s8 s7 s6 s5 s4 s3 s2 s1
- // || || || || || || || || ||
- 4'd00: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd00};
- 4'd01: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd01};
- 4'd02: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd02};
- 4'd03: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd03};
- 4'd04: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd04};
- 4'd05: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd05};
- 4'd06: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd06};
- 4'd07: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd07};
- 4'd08: z_addr <= {3'd02, 3'd03, 3'd04, 3'd06, 3'd07, 3'd00, 3'd00, 3'd00, 3'dxx};
- 4'd09: z_addr <= {3'd03, 3'd04, 3'd06, 3'd03, 3'd00, 3'd01, 3'd01, 3'd01, 3'dxx};
- 4'd10: z_addr <= {3'd04, 3'd05, 3'd05, 3'd07, 3'd01, 3'd02, 3'd02, 3'd02, 3'dxx};
- 4'd11: z_addr <= {3'd05, 3'd06, 3'd07, 3'd00, 3'd02, 3'd03, 3'd07, 3'd03, 3'dxx};
- 4'd12: z_addr <= {3'd06, 3'd07, 3'd00, 3'd01, 3'd06, 3'd04, 3'd03, 3'd04, 3'dxx};
- 4'd13: z_addr <= {3'd07, 3'd00, 3'd01, 3'd02, 3'd03, 3'd05, 3'd04, 3'd05, 3'dxx};
- 4'd14: z_addr <= {3'd00, 3'd01, 3'd02, 3'd04, 3'd04, 3'd06, 3'd05, 3'd06, 3'dxx};
- 4'd15: z_addr <= {3'd01, 3'd02, 3'd03, 3'd05, 3'd05, 3'd07, 3'd06, 3'd07, 3'dxx};
- //
- default: z_addr <= {9*WORD_COUNTER_WIDTH{1'bX}};
- //
- endcase
-
- always @(posedge clk)
- //
- case (index_x)
- //
- // 9 8 7 6 5 4 3 2 1
- // | | | | | | | | |
- 4'd00: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1};
- 4'd01: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1};
- 4'd02: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1};
- 4'd03: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1};
- 4'd04: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1};
- 4'd05: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1};
- 4'd06: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1};
- 4'd07: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1};
- 4'd08: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0};
- 4'd09: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0};
- 4'd10: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0};
- 4'd11: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0};
- 4'd12: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0};
- 4'd13: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0};
- 4'd14: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0};
- 4'd15: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0};
- //
- default: z_wren <= {9{1'b0}};
- //
- endcase
-
- always @(posedge clk)
- //
- if (inc_index_x)
- //
- case (index_x)
- //
- // 9 8 7 6 5 4 3 2 1
- // | | | | | | | | |
- 4'd00: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd01: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd02: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd03: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd04: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd05: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd06: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd07: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd08: z_mask <= {1'b1, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b1, 1'b1, 1'b0};
- 4'd09: z_mask <= {1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b1, 1'b1, 1'b0};
- 4'd10: z_mask <= {1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b1, 1'b1, 1'b0};
- 4'd11: z_mask <= {1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b1, 1'b1, 1'b0, 1'b0};
- 4'd12: z_mask <= {1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0};
- 4'd13: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0};
- 4'd14: z_mask <= {1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd15: z_mask <= {1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- //
- default: z_mask <= {9{1'bX}};
- //
- endcase
-
- always @(posedge clk)
- //
- if (inc_index_x)
- //
- case (index_x)
- //
- // 9 8 7 6 5 4 3 2 1
- // | | | | | | | | |
- 4'd00: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd01: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd02: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd03: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd04: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd05: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd06: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd07: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd08: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd09: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd10: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd11: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd12: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd13: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd14: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- 4'd15: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0};
- //
- default: z_save <= {9{1'bX}};
- //
- endcase
-
-
- //
- // Intermediate Numbers
- //
- reg [WORD_COUNTER_WIDTH-1:0] reduce_z_addr[1:9];
- wire [ 32-1:0] reduce_z_dout[1:9];
-
- reg [31: 0] x_din_dly;
- always @(posedge clk)
- //
- x_din_dly <= x_din;
-
-
- genvar z;
- generate for (z=1; z<=9; z=z+1)
- //
- begin : gen_z_bram
- //
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
- bram_c_inst
- (
- .clk (clk),
-
- .a_addr (z_addr[(z-1) * WORD_COUNTER_WIDTH +: WORD_COUNTER_WIDTH]),
- .a_wr (z_wren[z-1] & store_word_z),
- .a_in (z_mask[z-1] ? {32{1'b0}} : (z_save[z-1] ? x_din_dly : x_din)),
- .a_out (),
-
- .b_addr (reduce_z_addr[z]),
- .b_out (reduce_z_dout[z])
- );
- //
- end
- //
- endgenerate
-
-
-
-
- wire [ 32-1:0] bram_sum0_wr_din;
- wire [WORD_COUNTER_WIDTH-1:0] bram_sum0_wr_addr;
- wire bram_sum0_wr_wren;
-
- wire [ 32-1:0] bram_sum1_wr_din;
- wire [WORD_COUNTER_WIDTH-1:0] bram_sum1_wr_addr;
- wire bram_sum1_wr_wren;
-
- wire [ 32-1:0] bram_diff_wr_din;
- wire [WORD_COUNTER_WIDTH-1:0] bram_diff_wr_addr;
- wire bram_diff_wr_wren;
-
- wire [ 32-1:0] bram_sum0_rd_dout;
- reg [WORD_COUNTER_WIDTH-1:0] bram_sum0_rd_addr;
-
- wire [ 32-1:0] bram_sum1_rd_dout;
- reg [WORD_COUNTER_WIDTH-1:0] bram_sum1_rd_addr;
-
- wire [ 32-1:0] bram_diff_rd_dout;
- reg [WORD_COUNTER_WIDTH-1:0] bram_diff_rd_addr;
-
-
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
- bram_sum0_inst
- (
- .clk (clk),
-
- .a_addr (bram_sum0_wr_addr),
- .a_wr (bram_sum0_wr_wren),
- .a_in (bram_sum0_wr_din),
- .a_out (),
-
- .b_addr (bram_sum0_rd_addr),
- .b_out (bram_sum0_rd_dout)
- );
-
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
- bram_sum1_inst
- (
- .clk (clk),
-
- .a_addr (bram_sum1_wr_addr),
- .a_wr (bram_sum1_wr_wren),
- .a_in (bram_sum1_wr_din),
- .a_out (),
-
- .b_addr (bram_sum1_rd_addr),
- .b_out (bram_sum1_rd_dout)
- );
-
- bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH))
- bram_diff_inst
- (
- .clk (clk),
-
- .a_addr (bram_diff_wr_addr),
- .a_wr (bram_diff_wr_wren),
- .a_in (bram_diff_wr_din),
- .a_out (),
-
- .b_addr (bram_diff_rd_addr),
- .b_out (bram_diff_rd_dout)
- );
-
-
- wire [WORD_COUNTER_WIDTH-1:0] adder0_ab_addr;
- wire [WORD_COUNTER_WIDTH-1:0] adder1_ab_addr;
- wire [WORD_COUNTER_WIDTH-1:0] subtractor_ab_addr;
-
- reg [ 32-1:0] adder0_a_din;
- reg [ 32-1:0] adder0_b_din;
-
- reg [ 32-1:0] adder1_a_din;
- reg [ 32-1:0] adder1_b_din;
-
- reg [ 32-1:0] subtractor_a_din;
- reg [ 32-1:0] subtractor_b_din;
-
- // n_addr - only 1 output, because all modules are in sync
-
- modular_adder #
- (
- .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS),
- .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH)
- )
- adder_inst0
- (
- .clk (clk),
- .rst_n (rst_n),
-
- .ena (reduce_start),
- .rdy (reduce_adder0_done),
-
- .ab_addr (adder0_ab_addr),
- .n_addr (),
- .s_addr (bram_sum0_wr_addr),
- .s_wren (bram_sum0_wr_wren),
-
- .a_din (adder0_a_din),
- .b_din (adder0_b_din),
- .n_din (n_din),
- .s_dout (bram_sum0_wr_din)
- );
-
- modular_adder #
- (
- .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS),
- .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH)
- )
- adder_inst1
- (
- .clk (clk),
- .rst_n (rst_n),
-
- .ena (reduce_start),
- .rdy (reduce_adder1_done),
-
- .ab_addr (adder1_ab_addr),
- .n_addr (),
- .s_addr (bram_sum1_wr_addr),
- .s_wren (bram_sum1_wr_wren),
-
- .a_din (adder1_a_din),
- .b_din (adder1_b_din),
- .n_din (n_din),
- .s_dout (bram_sum1_wr_din)
- );
-
- modular_subtractor #
- (
- .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS),
- .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH)
- )
- subtractor_inst
- (
- .clk (clk),
- .rst_n (rst_n),
-
- .ena (reduce_start),
- .rdy (reduce_subtractor_done),
-
- .ab_addr (subtractor_ab_addr),
- .n_addr (n_addr),
- .d_addr (bram_diff_wr_addr),
- .d_wren (bram_diff_wr_wren),
-
- .a_din (subtractor_a_din),
- .b_din (subtractor_b_din),
- .n_din (n_din),
- .d_dout (bram_diff_wr_din)
- );
-
-
- //
- // Address (Operand) Selector
- //
- always @(*)
- //
- case (fsm_shreg_reduce_stage_stop)
- //
- 5'b10000: begin
- reduce_z_addr[1] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[2] = adder0_ab_addr;
- reduce_z_addr[3] = adder1_ab_addr;
- reduce_z_addr[4] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[5] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[6] = subtractor_ab_addr;
- reduce_z_addr[7] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[8] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[9] = {WORD_COUNTER_WIDTH{1'bX}};
- bram_sum0_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
- bram_sum1_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
- bram_diff_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
- end
- //
- 5'b01000: begin
- reduce_z_addr[1] = adder0_ab_addr;
- reduce_z_addr[2] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[3] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[4] = adder1_ab_addr;
- reduce_z_addr[5] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[6] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[7] = subtractor_ab_addr;
- reduce_z_addr[8] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[9] = {WORD_COUNTER_WIDTH{1'bX}};
- bram_sum0_rd_addr = adder0_ab_addr;
- bram_sum1_rd_addr = adder1_ab_addr;
- bram_diff_rd_addr = subtractor_ab_addr;
- end
- //
- 5'b00100: begin
- reduce_z_addr[1] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[2] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[3] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[4] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[5] = adder0_ab_addr;
- reduce_z_addr[6] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[7] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[8] = subtractor_ab_addr;
- reduce_z_addr[9] = {WORD_COUNTER_WIDTH{1'bX}};
- bram_sum0_rd_addr = adder0_ab_addr;
- bram_sum1_rd_addr = adder1_ab_addr;
- bram_diff_rd_addr = subtractor_ab_addr;
- end
- //
- 5'b00010: begin
- reduce_z_addr[1] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[2] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[3] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[4] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[5] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[6] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[7] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[8] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[9] = subtractor_ab_addr;
- bram_sum0_rd_addr = adder0_ab_addr;
- bram_sum1_rd_addr = adder0_ab_addr;
- bram_diff_rd_addr = subtractor_ab_addr;
- end
- //
- 5'b00001: begin
- reduce_z_addr[1] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[2] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[3] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[4] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[5] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[6] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[7] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[8] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[9] = {WORD_COUNTER_WIDTH{1'bX}};
- bram_sum0_rd_addr = adder0_ab_addr;
- bram_sum1_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
- bram_diff_rd_addr = adder0_ab_addr;
- end
- //
- default: begin
- reduce_z_addr[1] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[2] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[3] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[4] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[5] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[6] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[7] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[8] = {WORD_COUNTER_WIDTH{1'bX}};
- reduce_z_addr[9] = {WORD_COUNTER_WIDTH{1'bX}};
- bram_sum0_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
- bram_sum1_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
- bram_diff_rd_addr = {WORD_COUNTER_WIDTH{1'bX}};
- end
- //
- endcase
-
-
- //
- // adder 0
- //
- always @(*) begin
- //
- case (fsm_shreg_reduce_stage_stop)
- 5'b10000: adder0_a_din = reduce_z_dout[2];
- 5'b01000: adder0_a_din = bram_sum0_rd_dout;
- 5'b00100: adder0_a_din = bram_sum0_rd_dout;
- 5'b00010: adder0_a_din = bram_sum0_rd_dout;
- 5'b00001: adder0_a_din = bram_sum0_rd_dout;
- default: adder0_a_din = {32{1'bX}};
- endcase
- //
- case (fsm_shreg_reduce_stage_stop)
- 5'b10000: adder0_b_din = reduce_z_dout[2];
- 5'b01000: adder0_b_din = reduce_z_dout[1];
- 5'b00100: adder0_b_din = reduce_z_dout[5];
- 5'b00010: adder0_b_din = bram_sum1_rd_dout;
- 5'b00001: adder0_b_din = bram_diff_rd_dout;
- default: adder0_b_din = {32{1'bX}};
- endcase
- //
- end
-
- //
- // adder 1
- //
- always @(*) begin
- //
- case (fsm_shreg_reduce_stage_stop)
- 5'b10000: adder1_a_din = reduce_z_dout[3];
- 5'b01000: adder1_a_din = bram_sum1_rd_dout;
- 5'b00100: adder1_a_din = bram_sum1_rd_dout;
- 5'b00010: adder1_a_din = {32{1'bX}};
- 5'b00001: adder1_a_din = {32{1'bX}};
- default: adder1_a_din = {32{1'bX}};
- endcase
- //
- case (fsm_shreg_reduce_stage_stop)
- 5'b10000: adder1_b_din = reduce_z_dout[3];
- 5'b01000: adder1_b_din = reduce_z_dout[4];
- 5'b00100: adder1_b_din = {32{1'b0}};
- 5'b00010: adder1_b_din = {32{1'bX}};
- 5'b00001: adder1_b_din = {32{1'bX}};
- default: adder1_b_din = {32{1'bX}};
- endcase
- //
- end
-
-
- //
- // subtractor
- //
- always @(*) begin
- //
- case (fsm_shreg_reduce_stage_stop)
- 5'b10000: subtractor_a_din = {32{1'b0}};
- 5'b01000: subtractor_a_din = bram_diff_rd_dout;
- 5'b00100: subtractor_a_din = bram_diff_rd_dout;
- 5'b00010: subtractor_a_din = bram_diff_rd_dout;
- 5'b00001: subtractor_a_din = {32{1'bX}};
- default: subtractor_a_din = {32{1'bX}};
- endcase
- //
- case (fsm_shreg_reduce_stage_stop)
- 5'b10000: subtractor_b_din = reduce_z_dout[6];
- 5'b01000: subtractor_b_din = reduce_z_dout[7];
- 5'b00100: subtractor_b_din = reduce_z_dout[8];
- 5'b00010: subtractor_b_din = reduce_z_dout[9];
- 5'b00001: subtractor_b_din = {32{1'bX}};
- default: subtractor_b_din = {32{1'bX}};
- endcase
- //
- end
-
-
- //
- // Address Mapping
- //
- assign p_addr = bram_sum0_wr_addr;
- assign p_wren = bram_sum0_wr_wren & store_p;
- assign p_dout = bram_sum0_wr_din;
-
-
-endmodule
-
-
-//------------------------------------------------------------------------------
-// End-of-File
-//------------------------------------------------------------------------------