From 89f913c3aa2a6dad35630f3882a06b99e0978105 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Tue, 7 Mar 2017 19:52:36 -0500 Subject: Promote to a repository in the core tree. Change name of reset signal from rst_n to reset_n for consistancy with other Cryptech cores. Code common between this core and the ecdsa384 core split out into a separate library repository. Minor cleanup (Windows-isms, indentation). --- rtl/curve/curve_dbl_add_256.v | 1748 +++++++++++++++++++-------------------- rtl/curve/curve_mul_256.v | 1440 ++++++++++++++++---------------- rtl/curve/rom/brom_p256_delta.v | 38 +- rtl/curve/rom/brom_p256_g_x.v | 38 +- rtl/curve/rom/brom_p256_g_y.v | 40 +- rtl/curve/rom/brom_p256_h_x.v | 38 +- rtl/curve/rom/brom_p256_h_y.v | 40 +- rtl/curve/rom/brom_p256_one.v | 38 +- rtl/curve/rom/brom_p256_q.v | 40 +- rtl/curve/rom/brom_p256_zero.v | 40 +- rtl/curve/uop/uop_add_rom.v | 66 -- rtl/curve/uop/uop_conv_rom.v | 38 - rtl/curve/uop/uop_dbl_rom.v | 58 -- rtl/curve/uop/uop_init_rom.v | 33 - rtl/curve/uop_ecdsa.v | 50 -- 15 files changed, 1750 insertions(+), 1995 deletions(-) delete mode 100644 rtl/curve/uop/uop_add_rom.v delete mode 100644 rtl/curve/uop/uop_conv_rom.v delete mode 100644 rtl/curve/uop/uop_dbl_rom.v delete mode 100644 rtl/curve/uop/uop_init_rom.v delete mode 100644 rtl/curve/uop_ecdsa.v (limited to 'rtl/curve') diff --git a/rtl/curve/curve_dbl_add_256.v b/rtl/curve/curve_dbl_add_256.v index 8ef505d..6a93823 100644 --- a/rtl/curve/curve_dbl_add_256.v +++ b/rtl/curve/curve_dbl_add_256.v @@ -1,874 +1,874 @@ -//------------------------------------------------------------------------------ -// -// curve_dbl_add_256.v -// ----------------------------------------------------------------------------- -// Elliptic curve point adder and doubler. -// -// 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_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 "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 - // - reg uop_trig; - always @(posedge clk or negedge rst_n) - // - if (rst_n == 1'b0) uop_trig <= 1'b0; - else uop_trig <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0; - - - // - // 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 && 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 && 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; - assign mw_mov_ena = uop_opcode[1] & uop_trig; - assign mod_add_ena = uop_opcode[2] & uop_trig; - assign mod_sub_ena = uop_opcode[3] & uop_trig; - assign mod_mul_ena = uop_opcode[4] & uop_trig; - - - // - // 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) ) 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 && uop_done) - if (uop_opcode == OPCODE_RDY) rdy_reg <= 1'b1; - - end - - -endmodule - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// +// curve_dbl_add_256.v +// ----------------------------------------------------------------------------- +// Elliptic curve point adder and doubler. +// +// 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_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 + // + reg uop_trig; + always @(posedge clk or negedge rst_n) + // + if (rst_n == 1'b0) uop_trig <= 1'b0; + else uop_trig <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0; + + + // + // 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 && 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 && 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; + assign mw_mov_ena = uop_opcode[1] & uop_trig; + assign mod_add_ena = uop_opcode[2] & uop_trig; + assign mod_sub_ena = uop_opcode[3] & uop_trig; + assign mod_mul_ena = uop_opcode[4] & uop_trig; + + + // + // 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) ) 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 && 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 index 0ac2be0..423c863 100644 --- a/rtl/curve/curve_mul_256.v +++ b/rtl/curve/curve_mul_256.v @@ -1,720 +1,720 @@ -//------------------------------------------------------------------------------ -// -// 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; - - (* RAM_STYLE="BLOCK" *) - uop_init_rom op_rom_init - ( - .clk (clk), - .addr (op_rom_addr), - .data (op_rom_init_data) - ); - - (* RAM_STYLE="BLOCK" *) - uop_dbl_rom op_rom_dbl - ( - .clk (clk), - .addr (op_rom_addr), - .data (op_rom_dbl_data) - ); - - (* RAM_STYLE="BLOCK" *) - uop_add_rom op_rom_add - ( - .clk (clk), - .addr (op_rom_addr), - .data (op_rom_add_data) - ); - - (* RAM_STYLE="BLOCK" *) - 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 -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// +// 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; + + (* RAM_STYLE="BLOCK" *) + uop_init_rom op_rom_init + ( + .clk (clk), + .addr (op_rom_addr), + .data (op_rom_init_data) + ); + + (* RAM_STYLE="BLOCK" *) + uop_dbl_rom op_rom_dbl + ( + .clk (clk), + .addr (op_rom_addr), + .data (op_rom_dbl_data) + ); + + (* RAM_STYLE="BLOCK" *) + uop_add_rom op_rom_add + ( + .clk (clk), + .addr (op_rom_addr), + .data (op_rom_add_data) + ); + + (* RAM_STYLE="BLOCK" *) + 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 index b9a345a..4637575 100644 --- a/rtl/curve/rom/brom_p256_delta.v +++ b/rtl/curve/rom/brom_p256_delta.v @@ -33,36 +33,36 @@ `timescale 1ns / 1ps module brom_p256_delta - ( - input wire clk, - input wire [ 3-1:0] b_addr, - output wire [32-1:0] b_out - ); + ( + 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; + 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 + // + 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 index 0816ef6..86aeafd 100644 --- a/rtl/curve/rom/brom_p256_g_x.v +++ b/rtl/curve/rom/brom_p256_g_x.v @@ -33,36 +33,36 @@ `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 - ); + ( + 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; + 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 + // + 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 index 4d9c61e..39f9116 100644 --- a/rtl/curve/rom/brom_p256_g_y.v +++ b/rtl/curve/rom/brom_p256_g_y.v @@ -33,36 +33,36 @@ `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 - ); + ( + 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; + 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 + // + 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 index 0b69f77..554d346 100644 --- a/rtl/curve/rom/brom_p256_h_x.v +++ b/rtl/curve/rom/brom_p256_h_x.v @@ -33,36 +33,36 @@ `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 - ); + ( + 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; + 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'h4ece7ad0; - 3'b001: bram_reg_b <= 32'h16bd8d74; - 3'b010: bram_reg_b <= 32'ha42998be; - 3'b011: bram_reg_b <= 32'h11f904fe; - 3'b100: bram_reg_b <= 32'h38b77e1b; - 3'b101: bram_reg_b <= 32'h0e863235; - 3'b110: bram_reg_b <= 32'h3da77b71; - 3'b111: bram_reg_b <= 32'h29d05c19; - endcase + // + always @(posedge clk) + // + case (b_addr) + 3'b000: bram_reg_b <= 32'h4ece7ad0; + 3'b001: bram_reg_b <= 32'h16bd8d74; + 3'b010: bram_reg_b <= 32'ha42998be; + 3'b011: bram_reg_b <= 32'h11f904fe; + 3'b100: bram_reg_b <= 32'h38b77e1b; + 3'b101: bram_reg_b <= 32'h0e863235; + 3'b110: bram_reg_b <= 32'h3da77b71; + 3'b111: bram_reg_b <= 32'h29d05c19; + endcase endmodule diff --git a/rtl/curve/rom/brom_p256_h_y.v b/rtl/curve/rom/brom_p256_h_y.v index 362fce6..6b5b8d9 100644 --- a/rtl/curve/rom/brom_p256_h_y.v +++ b/rtl/curve/rom/brom_p256_h_y.v @@ -33,36 +33,36 @@ `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 - ); + ( + 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; + 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'hc840ae07; - 3'b001: bram_reg_b <= 32'h3449bf97; - 3'b010: bram_reg_b <= 32'h94cea131; - 3'b011: bram_reg_b <= 32'hd431cca9; - 3'b100: bram_reg_b <= 32'h83f061e9; - 3'b101: bram_reg_b <= 32'h711814b5; - 3'b110: bram_reg_b <= 32'h01e58065; - 3'b111: bram_reg_b <= 32'hb01cbd1c; - endcase + // + always @(posedge clk) + // + case (b_addr) + 3'b000: bram_reg_b <= 32'hc840ae07; + 3'b001: bram_reg_b <= 32'h3449bf97; + 3'b010: bram_reg_b <= 32'h94cea131; + 3'b011: bram_reg_b <= 32'hd431cca9; + 3'b100: bram_reg_b <= 32'h83f061e9; + 3'b101: bram_reg_b <= 32'h711814b5; + 3'b110: bram_reg_b <= 32'h01e58065; + 3'b111: bram_reg_b <= 32'hb01cbd1c; + endcase endmodule diff --git a/rtl/curve/rom/brom_p256_one.v b/rtl/curve/rom/brom_p256_one.v index 4097874..15e3746 100644 --- a/rtl/curve/rom/brom_p256_one.v +++ b/rtl/curve/rom/brom_p256_one.v @@ -33,36 +33,36 @@ `timescale 1ns / 1ps module brom_p256_one - ( - input wire clk, - input wire [ 3-1:0] b_addr, - output wire [32-1:0] b_out - ); + ( + 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; + 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 + // + 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 index fe94593..101a524 100644 --- a/rtl/curve/rom/brom_p256_q.v +++ b/rtl/curve/rom/brom_p256_q.v @@ -33,36 +33,36 @@ `timescale 1ns / 1ps module brom_p256_q - ( - input wire clk, - input wire [ 3-1:0] b_addr, - output wire [32-1:0] b_out - ); + ( + 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; + 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 + // + 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 index f6d19a1..2672cf2 100644 --- a/rtl/curve/rom/brom_p256_zero.v +++ b/rtl/curve/rom/brom_p256_zero.v @@ -33,14 +33,14 @@ `timescale 1ns / 1ps module brom_p256_zero - ( - //input wire clk, - //input wire [ 3-1:0] b_addr, - output wire [32-1:0] b_out - ); + ( + //input wire clk, + //input wire [ 3-1:0] b_addr, + output wire [32-1:0] b_out + ); - - assign b_out = {32{1'b0}}; + + assign b_out = {32{1'b0}}; // // Output Registers @@ -52,19 +52,19 @@ module brom_p256_zero // // 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 + // + //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/curve/uop/uop_add_rom.v b/rtl/curve/uop/uop_add_rom.v deleted file mode 100644 index c807736..0000000 --- a/rtl/curve/uop/uop_add_rom.v +++ /dev/null @@ -1,66 +0,0 @@ -`timescale 1ns / 1ps - -module uop_add_rom - ( - input wire clk, - input wire [ 5: 0] addr, - output reg [19: 0] data - ); - - - // - // Microcode - // -`include "..\uop_ecdsa.v" - - - // - // Addition Microprogram - // - always @(posedge clk) - - case (addr) - -/* 2. */6'd00: data <= {OPCODE_CMP, UOP_SRC_PZ, UOP_SRC_ZERO, UOP_DST_DUMMY, UOP_EXEC_ALWAYS}; -/* 3. */6'd01: data <= {OPCODE_MOV, UOP_SRC_PZ, UOP_SRC_DUMMY, UOP_DST_T1, UOP_EXEC_ALWAYS}; - 6'd02: data <= {OPCODE_MUL, UOP_SRC_PZ, UOP_SRC_T1, UOP_DST_T1, UOP_EXEC_ALWAYS}; -/* 4. */6'd03: data <= {OPCODE_MUL, UOP_SRC_PZ, UOP_SRC_T1, UOP_DST_T2, UOP_EXEC_ALWAYS}; -/* 5. */6'd04: data <= {OPCODE_MUL, UOP_SRC_T1, UOP_SRC_G_X, UOP_DST_T1, UOP_EXEC_ALWAYS}; -/* 6. */6'd05: data <= {OPCODE_MUL, UOP_SRC_T2, UOP_SRC_G_Y, UOP_DST_T2, UOP_EXEC_ALWAYS}; -/* 7. */6'd06: data <= {OPCODE_SUB, UOP_SRC_T1, UOP_SRC_PX, UOP_DST_T1, UOP_EXEC_ALWAYS}; -/* 8. */6'd07: data <= {OPCODE_SUB, UOP_SRC_T2, UOP_SRC_PY, UOP_DST_T2, UOP_EXEC_ALWAYS}; -/* 9. */6'd08: data <= {OPCODE_CMP, UOP_SRC_T1, UOP_SRC_ZERO, UOP_DST_DUMMY, UOP_EXEC_ALWAYS}; - 6'd09: data <= {OPCODE_CMP, UOP_SRC_T2, UOP_SRC_ZERO, UOP_DST_DUMMY, UOP_EXEC_ALWAYS}; -/* 10. */6'd10: data <= {OPCODE_MUL, UOP_SRC_PZ, UOP_SRC_T1, UOP_DST_RZ, UOP_EXEC_ALWAYS}; -/* 11. */6'd11: data <= {OPCODE_MOV, UOP_SRC_T1, UOP_SRC_DUMMY, UOP_DST_T3, UOP_EXEC_ALWAYS}; - 6'd12: data <= {OPCODE_MUL, UOP_SRC_T1, UOP_SRC_T3, UOP_DST_T3, UOP_EXEC_ALWAYS}; -/* 12. */6'd13: data <= {OPCODE_MUL, UOP_SRC_T1, UOP_SRC_T3, UOP_DST_T4, UOP_EXEC_ALWAYS}; -/* 13. */6'd14: data <= {OPCODE_MUL, UOP_SRC_PX, UOP_SRC_T3, UOP_DST_T3, UOP_EXEC_ALWAYS}; -/* 14. */6'd15: data <= {OPCODE_ADD, UOP_SRC_T3, UOP_SRC_T3, UOP_DST_T1, UOP_EXEC_ALWAYS}; -/* 15. */6'd16: data <= {OPCODE_MOV, UOP_SRC_T2, UOP_SRC_DUMMY, UOP_DST_RX, UOP_EXEC_ALWAYS}; - 6'd17: data <= {OPCODE_MUL, UOP_SRC_RX, UOP_SRC_T2, UOP_DST_RX, UOP_EXEC_ALWAYS}; -/* 16. */6'd18: data <= {OPCODE_SUB, UOP_SRC_RX, UOP_SRC_T1, UOP_DST_RX, UOP_EXEC_ALWAYS}; -/* 17. */6'd19: data <= {OPCODE_SUB, UOP_SRC_RX, UOP_SRC_T4, UOP_DST_RX, UOP_EXEC_ALWAYS}; -/* 18. */6'd20: data <= {OPCODE_SUB, UOP_SRC_T3, UOP_SRC_RX, UOP_DST_T3, UOP_EXEC_ALWAYS}; -/* 19. */6'd21: data <= {OPCODE_MUL, UOP_SRC_T2, UOP_SRC_T3, UOP_DST_T3, UOP_EXEC_ALWAYS}; -/* 20. */6'd22: data <= {OPCODE_MUL, UOP_SRC_PY, UOP_SRC_T4, UOP_DST_T4, UOP_EXEC_ALWAYS}; -/* 21. */6'd23: data <= {OPCODE_SUB, UOP_SRC_T3, UOP_SRC_T4, UOP_DST_RY, UOP_EXEC_ALWAYS}; - - 6'd24: data <= {OPCODE_MOV, UOP_SRC_G_X, UOP_SRC_DUMMY, UOP_DST_RX, UOP_EXEC_PZT1T2_0XX}; - 6'd25: data <= {OPCODE_MOV, UOP_SRC_G_Y, UOP_SRC_DUMMY, UOP_DST_RY, UOP_EXEC_PZT1T2_0XX}; - 6'd26: data <= {OPCODE_MOV, UOP_SRC_ONE, UOP_SRC_DUMMY, UOP_DST_RZ, UOP_EXEC_PZT1T2_0XX}; - - 6'd27: data <= {OPCODE_MOV, UOP_SRC_H_X, UOP_SRC_DUMMY, UOP_DST_RX, UOP_EXEC_PZT1T2_100}; - 6'd28: data <= {OPCODE_MOV, UOP_SRC_H_Y, UOP_SRC_DUMMY, UOP_DST_RY, UOP_EXEC_PZT1T2_100}; - 6'd29: data <= {OPCODE_MOV, UOP_SRC_ONE, UOP_SRC_DUMMY, UOP_DST_RZ, UOP_EXEC_PZT1T2_100}; - - 6'd30: data <= {OPCODE_MOV, UOP_SRC_ONE, UOP_SRC_DUMMY, UOP_DST_RX, UOP_EXEC_PZT1T2_101}; - 6'd31: data <= {OPCODE_MOV, UOP_SRC_ONE, UOP_SRC_DUMMY, UOP_DST_RY, UOP_EXEC_PZT1T2_101}; - 6'd32: data <= {OPCODE_MOV, UOP_SRC_ZERO, UOP_SRC_DUMMY, UOP_DST_RZ, UOP_EXEC_PZT1T2_101}; - - default: data <= {OPCODE_RDY, UOP_SRC_DUMMY, UOP_SRC_DUMMY, UOP_DST_DUMMY}; - - endcase - - -endmodule diff --git a/rtl/curve/uop/uop_conv_rom.v b/rtl/curve/uop/uop_conv_rom.v deleted file mode 100644 index 3097736..0000000 --- a/rtl/curve/uop/uop_conv_rom.v +++ /dev/null @@ -1,38 +0,0 @@ -`timescale 1ns / 1ps - -module uop_conv_rom - ( - input wire clk, - input wire [ 5: 0] addr, - output reg [19: 0] data - ); - - - // - // Microcode - // -`include "..\uop_ecdsa.v" - - - // - // Doubling Microprogram - // - always @(posedge clk) - - case (addr) - - 6'd00: data <= {OPCODE_CMP, UOP_SRC_PZ, UOP_SRC_ZERO, UOP_DST_DUMMY, UOP_EXEC_ALWAYS}; - 6'd01: data <= {OPCODE_MOV, UOP_SRC_V, UOP_SRC_DUMMY, UOP_DST_T1, UOP_EXEC_ALWAYS}; - 6'd02: data <= {OPCODE_MUL, UOP_SRC_V, UOP_SRC_T1, UOP_DST_T2, UOP_EXEC_ALWAYS}; - 6'd03: data <= {OPCODE_MUL, UOP_SRC_V, UOP_SRC_T2, UOP_DST_T3, UOP_EXEC_ALWAYS}; - 6'd04: data <= {OPCODE_MUL, UOP_SRC_PX, UOP_SRC_T2, UOP_DST_RX, UOP_EXEC_ALWAYS}; - 6'd05: data <= {OPCODE_MUL, UOP_SRC_PY, UOP_SRC_T3, UOP_DST_RY, UOP_EXEC_ALWAYS}; - 6'd06: data <= {OPCODE_MOV, UOP_SRC_ZERO, UOP_SRC_DUMMY, UOP_DST_RX, UOP_EXEC_PZT1T2_0XX}; - 6'd07: data <= {OPCODE_MOV, UOP_SRC_ZERO, UOP_SRC_DUMMY, UOP_DST_RY, UOP_EXEC_PZT1T2_0XX}; - - default: data <= {OPCODE_RDY, UOP_SRC_DUMMY, UOP_SRC_DUMMY, UOP_DST_DUMMY}; - - endcase - - -endmodule diff --git a/rtl/curve/uop/uop_dbl_rom.v b/rtl/curve/uop/uop_dbl_rom.v deleted file mode 100644 index 1939ca9..0000000 --- a/rtl/curve/uop/uop_dbl_rom.v +++ /dev/null @@ -1,58 +0,0 @@ -`timescale 1ns / 1ps - -module uop_dbl_rom - ( - input wire clk, - input wire [ 5: 0] addr, - output reg [19: 0] data - ); - - - // - // Microcode - // -`include "..\uop_ecdsa.v" - - - // - // Doubling Microprogram - // - always @(posedge clk) - - case (addr) - -/* 1. */6'd00: data <= {OPCODE_CMP, UOP_SRC_PZ, UOP_SRC_ZERO, UOP_DST_DUMMY, UOP_EXEC_ALWAYS}; -/* 2. */6'd01: data <= {OPCODE_MOV, UOP_SRC_PZ, UOP_SRC_DUMMY, UOP_DST_T1, UOP_EXEC_ALWAYS}; - 5'd02: data <= {OPCODE_MUL, UOP_SRC_PZ, UOP_SRC_T1, UOP_DST_T1, UOP_EXEC_ALWAYS}; -/* 3. */6'd03: data <= {OPCODE_SUB, UOP_SRC_PX, UOP_SRC_T1, UOP_DST_T2, UOP_EXEC_ALWAYS}; -/* 4. */6'd04: data <= {OPCODE_ADD, UOP_SRC_PX, UOP_SRC_T1, UOP_DST_T1, UOP_EXEC_ALWAYS}; -/* 5. */6'd05: data <= {OPCODE_MUL, UOP_SRC_T1, UOP_SRC_T2, UOP_DST_T2, UOP_EXEC_ALWAYS}; -/* 6. */6'd06: data <= {OPCODE_ADD, UOP_SRC_T2, UOP_SRC_T2, UOP_DST_T1, UOP_EXEC_ALWAYS}; - 6'd07: data <= {OPCODE_ADD, UOP_SRC_T1, UOP_SRC_T2, UOP_DST_T2, UOP_EXEC_ALWAYS}; -/* 7. */6'd08: data <= {OPCODE_ADD, UOP_SRC_PY, UOP_SRC_PY, UOP_DST_RY, UOP_EXEC_ALWAYS}; -/* 8. */6'd09: data <= {OPCODE_MUL, UOP_SRC_PZ, UOP_SRC_RY, UOP_DST_RZ, UOP_EXEC_ALWAYS}; -/* 9. */6'd10: data <= {OPCODE_MOV, UOP_SRC_RY, UOP_SRC_DUMMY, UOP_DST_T1, UOP_EXEC_ALWAYS}; - 6'd11: data <= {OPCODE_MOV, UOP_SRC_RY, UOP_SRC_DUMMY, UOP_DST_T3, UOP_EXEC_ALWAYS}; - 6'd12: data <= {OPCODE_MUL, UOP_SRC_T1, UOP_SRC_T3, UOP_DST_RY, UOP_EXEC_ALWAYS}; -/* 10. */6'd13: data <= {OPCODE_MUL, UOP_SRC_PX, UOP_SRC_RY, UOP_DST_T3, UOP_EXEC_ALWAYS}; -/* 11. */6'd14: data <= {OPCODE_MOV, UOP_SRC_RY, UOP_SRC_DUMMY, UOP_DST_T1, UOP_EXEC_ALWAYS}; - 6'd15: data <= {OPCODE_MUL, UOP_SRC_RY, UOP_SRC_T1, UOP_DST_T1, UOP_EXEC_ALWAYS}; -/* 12. */6'd16: data <= {OPCODE_MUL, UOP_SRC_T1, UOP_SRC_DELTA, UOP_DST_RY, UOP_EXEC_ALWAYS}; -/* 13. */6'd17: data <= {OPCODE_MOV, UOP_SRC_T2, UOP_SRC_DUMMY, UOP_DST_T1, UOP_EXEC_ALWAYS}; - 6'd18: data <= {OPCODE_MUL, UOP_SRC_T1, UOP_SRC_T2, UOP_DST_RX, UOP_EXEC_ALWAYS}; -/* 14. */6'd19: data <= {OPCODE_ADD, UOP_SRC_T3, UOP_SRC_T3, UOP_DST_T1, UOP_EXEC_ALWAYS}; -/* 15. */6'd20: data <= {OPCODE_SUB, UOP_SRC_RX, UOP_SRC_T1, UOP_DST_RX, UOP_EXEC_ALWAYS}; -/* 16. */6'd21: data <= {OPCODE_SUB, UOP_SRC_T3, UOP_SRC_RX, UOP_DST_T1, UOP_EXEC_ALWAYS}; -/* 17. */6'd22: data <= {OPCODE_MUL, UOP_SRC_T1, UOP_SRC_T2, UOP_DST_T1, UOP_EXEC_ALWAYS}; -/* 18. */6'd23: data <= {OPCODE_SUB, UOP_SRC_T1, UOP_SRC_RY, UOP_DST_RY, UOP_EXEC_ALWAYS}; - - 6'd24: data <= {OPCODE_MOV, UOP_SRC_ONE, UOP_SRC_DUMMY, UOP_DST_RX, UOP_EXEC_PZT1T2_0XX}; - 6'd25: data <= {OPCODE_MOV, UOP_SRC_ONE, UOP_SRC_DUMMY, UOP_DST_RY, UOP_EXEC_PZT1T2_0XX}; - 6'd26: data <= {OPCODE_MOV, UOP_SRC_ZERO, UOP_SRC_DUMMY, UOP_DST_RZ, UOP_EXEC_PZT1T2_0XX}; - - default: data <= {OPCODE_RDY, UOP_SRC_DUMMY, UOP_SRC_DUMMY, UOP_DST_DUMMY}; - - endcase - - -endmodule diff --git a/rtl/curve/uop/uop_init_rom.v b/rtl/curve/uop/uop_init_rom.v deleted file mode 100644 index ac44b55..0000000 --- a/rtl/curve/uop/uop_init_rom.v +++ /dev/null @@ -1,33 +0,0 @@ -`timescale 1ns / 1ps - -module uop_init_rom - ( - input wire clk, - input wire [ 5: 0] addr, - output reg [19: 0] data - ); - - - // - // Microcode - // -`include "..\uop_ecdsa.v" - - - // - // Doubling Microprogram - // - always @(posedge clk) - - case (addr) - - 6'd00: data <= {OPCODE_MOV, UOP_SRC_ONE, UOP_SRC_DUMMY, UOP_DST_RX, UOP_EXEC_ALWAYS}; - 6'd01: data <= {OPCODE_MOV, UOP_SRC_ONE, UOP_SRC_DUMMY, UOP_DST_RY, UOP_EXEC_ALWAYS}; - 6'd02: data <= {OPCODE_MOV, UOP_SRC_ZERO, UOP_SRC_DUMMY, UOP_DST_RZ, UOP_EXEC_ALWAYS}; - - default: data <= {OPCODE_RDY, UOP_SRC_DUMMY, UOP_SRC_DUMMY, UOP_DST_DUMMY}; - - endcase - - -endmodule diff --git a/rtl/curve/uop_ecdsa.v b/rtl/curve/uop_ecdsa.v deleted file mode 100644 index e64119d..0000000 --- a/rtl/curve/uop_ecdsa.v +++ /dev/null @@ -1,50 +0,0 @@ -localparam [ 4: 0] OPCODE_CMP = 5'b00001; -localparam [ 4: 0] OPCODE_MOV = 5'b00010; -localparam [ 4: 0] OPCODE_ADD = 5'b00100; -localparam [ 4: 0] OPCODE_SUB = 5'b01000; -localparam [ 4: 0] OPCODE_MUL = 5'b10000; -localparam [ 4: 0] OPCODE_RDY = 5'b00000; - -localparam [ 4: 0] UOP_SRC_PX = 5'h0_0; -localparam [ 4: 0] UOP_SRC_PY = 5'h0_1; -localparam [ 4: 0] UOP_SRC_PZ = 5'h0_2; - -localparam [ 4: 0] UOP_SRC_RX = 5'h0_3; -localparam [ 4: 0] UOP_SRC_RY = 5'h0_4; -localparam [ 4: 0] UOP_SRC_RZ = 5'h0_5; - -localparam [ 4: 0] UOP_SRC_T1 = 5'h0_6; -localparam [ 4: 0] UOP_SRC_T2 = 5'h0_7; -localparam [ 4: 0] UOP_SRC_T3 = 5'h0_8; -localparam [ 4: 0] UOP_SRC_T4 = 5'h0_9; - -localparam [ 4: 0] UOP_SRC_ONE = 5'h0_A; -localparam [ 4: 0] UOP_SRC_ZERO = 5'h0_B; -localparam [ 4: 0] UOP_SRC_DELTA = 5'h0_C; - -localparam [ 4: 0] UOP_SRC_V = 5'h0_F; - -localparam [ 4: 0] UOP_SRC_G_X = 5'h1_0; -localparam [ 4: 0] UOP_SRC_G_Y = 5'h1_1; - -localparam [ 4: 0] UOP_SRC_H_X = 5'h1_2; -localparam [ 4: 0] UOP_SRC_H_Y = 5'h1_3; - -localparam [ 4: 0] UOP_SRC_DUMMY = 5'hX_X; - -localparam [ 2: 0] UOP_DST_RX = 3'd0; -localparam [ 2: 0] UOP_DST_RY = 3'd1; -localparam [ 2: 0] UOP_DST_RZ = 3'd2; - -localparam [ 2: 0] UOP_DST_T1 = 3'd3; -localparam [ 2: 0] UOP_DST_T2 = 3'd4; -localparam [ 2: 0] UOP_DST_T3 = 3'd5; -localparam [ 2: 0] UOP_DST_T4 = 3'd6; - -localparam [ 2: 0] UOP_DST_DUMMY = 3'dX; - -localparam UOP_EXEC_ALWAYS = 2'b11; // R -localparam UOP_EXEC_PZT1T2_0XX = 2'b10; // G -localparam UOP_EXEC_PZT1T2_100 = 2'b00; // H -localparam UOP_EXEC_PZT1T2_101 = 2'b01; // O - -- cgit v1.2.3