diff options
author | Pavel V. Shatov (Meister) <meisterpaul1@yandex.ru> | 2018-09-25 01:20:17 +0300 |
---|---|---|
committer | Pavel V. Shatov (Meister) <meisterpaul1@yandex.ru> | 2018-09-25 01:20:17 +0300 |
commit | a067a55a908b89abe0cb2d8c91a6ae701846d4d9 (patch) | |
tree | 0dcfd96b1122b1b59f6e02390e5239593c6ebec0 | |
parent | 0770d120f20bab87df10df989790d9157afa91a2 (diff) |
Microcoded "worker" unit. Supports "move" opcode, support for "add"/"sub" will
be added by copying code from ECDSA cores. Support for "mul" opcode requires
reworking of the modular reduction helper module, work in progress.
-rw-r--r-- | rtl/ed25519_worker.v | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/rtl/ed25519_worker.v b/rtl/ed25519_worker.v new file mode 100644 index 0000000..df99f61 --- /dev/null +++ b/rtl/ed25519_worker.v @@ -0,0 +1,299 @@ +//------------------------------------------------------------------------------ +// +// ed25519_uop_worker.v +// ----------------------------------------------------------------------------- +// Ed25519 uOP Worker. +// +// Authors: Pavel Shatov +// +// Copyright (c) 2018, NORDUnet A/S +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// - Neither the name of the NORDUnet nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +//------------------------------------------------------------------------------ + +module ed25519_worker +( + clk, rst_n, + ena, rdy, + uop_offset +); + + + // + // Microcode Header + // +`include "ed25519_uop.v" + + + // + // Ports + // + input clk; // system clock + input rst_n; // active-low async reset + + input ena; // enable input + output rdy; // ready output + + input [UOP_ADDR_WIDTH-1:0] uop_offset; // starting offset + + + // + // Constants + // + localparam integer OPERAND_NUM_WORDS = 8; // 256 bits -> 8 x 32-bit words + localparam integer WORD_COUNTER_WIDTH = 3; // 0..7 -> 3 bits + + + // + // FSM + // + localparam [1:0] FSM_STATE_IDLE = 2'b00; + localparam [1:0] FSM_STATE_FETCH = 2'b01; + localparam [1:0] FSM_STATE_DECODE = 2'b10; + localparam [1:0] FSM_STATE_BUSY = 2'b11; + + reg [1:0] fsm_state = FSM_STATE_IDLE; + reg [1:0] fsm_state_next; + + + // + // Microcode + // + reg [UOP_ADDR_WIDTH-1:0] uop_addr; + wire [UOP_DATA_WIDTH-1:0] uop_data; + + wire [4:0] uop_data_opcode = uop_data[1 + 3*6 +: 5]; + wire uop_data_banks = uop_data[0 + 3*6 +: 1]; + wire [5:0] uop_data_operand_src1 = uop_data[0 + 2*6 +: 6]; + wire [5:0] uop_data_operand_src2 = uop_data[0 + 1*6 +: 6]; + wire [5:0] uop_data_operand_dst = uop_data[0 + 0*6 +: 6]; + + wire uop_data_opcode_is_stop = uop_data_opcode[4]; + wire uop_data_opcode_is_copy = uop_data_opcode[0]; + + ed25519_microcode microcode + ( + .clk (clk), + .addr (uop_addr), + .data (uop_data) + ); + + + // + // Microcode Address Increment Logic + // + always @(posedge clk) + // + if (fsm_state_next == FSM_STATE_FETCH) + uop_addr <= (fsm_state == FSM_STATE_IDLE) ? uop_offset : uop_addr + 1'b1; + + + // + // Multi-Word Mover + // + reg mw_mover_ena = 1'b0; + wire mw_mover_rdy; + + wire [WORD_COUNTER_WIDTH-1:0] mw_mover_x_addr; + wire [WORD_COUNTER_WIDTH-1:0] mw_mover_y_addr; + wire [ 32-1:0] mw_mover_x_din; + wire [ 32-1:0] mw_mover_y_dout; + wire mw_mover_y_wren; + + 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_mover_ena), + .rdy (mw_mover_rdy), + .x_addr (mw_mover_x_addr), + .y_addr (mw_mover_y_addr), + .y_wren (mw_mover_y_wren), + .x_din (mw_mover_x_din), + .y_dout (mw_mover_y_dout) + ); + + + // + // uOP Trigger Logic + // + always @(posedge clk) + // + if (fsm_state == FSM_STATE_DECODE) begin + mw_mover_ena <= uop_data_opcode_is_copy; + end else begin + mw_mover_ena <= 1'b0; + end + + + // + // uOP Completion Detector + // + reg fsm_exit_from_busy; + + always @* begin + // + fsm_exit_from_busy = 0; + // + if (uop_data_opcode_is_copy) fsm_exit_from_busy = ~mw_mover_ena & mw_mover_rdy; + // + end + + + + // + // Banks + // + reg [ 2:0] banks_src1_addr; + reg [ 2:0] banks_src2_addr; + reg [ 2:0] banks_dst_addr; + + reg banks_dst_wren; + + reg [31:0] banks_dst_din; + + wire [31:0] banks_src1_dout; + wire [31:0] banks_src2_dout; + + ed25519_banks banks + ( + .clk (clk), + + .banks (uop_data_banks), + + .src1_operand (uop_data_operand_src1), + .src2_operand (uop_data_operand_src2), + .dst_operand (uop_data_operand_dst), + + .src1_addr (banks_src1_addr), + .src2_addr (banks_src2_addr), + .dst_addr (banks_dst_addr), + + .dst_wren (banks_dst_wren), + + .src1_dout (banks_src1_dout), + .src2_dout (banks_src2_dout), + + .dst_din (banks_dst_din) + ); + + assign mw_mover_x_din = banks_src1_dout; + + always @* + // + case (uop_data_opcode) + // + UOP_OPCODE_COPY: begin + // + banks_src1_addr = mw_mover_x_addr; + banks_src2_addr = 'bX; + // + banks_dst_addr = mw_mover_y_addr; + // + banks_dst_wren = mw_mover_y_wren; + // + banks_dst_din = mw_mover_y_dout; + // + end + // + //UOP_OPCODE_ADD: d + //UOP_OPCODE_SUB: d + //UOP_OPCODE_MUL: d + // + default: begin + // + banks_src1_addr = 'bX; + banks_src2_addr = 'bX; + // + banks_dst_addr = 'bX; + // + banks_dst_wren = 'b0; + // + banks_dst_din = 'bX; + end + // + endcase + + //addr + //wren + //dout + //din + + + // + // FSM Process + // + always @(posedge clk or negedge rst_n) + // + if (rst_n == 1'b0) fsm_state <= FSM_STATE_IDLE; + else fsm_state <= fsm_state_next; + + + // + // FSM Transition Logic + // + always @* begin + // + fsm_state_next = FSM_STATE_IDLE; + // + case (fsm_state) + FSM_STATE_IDLE: fsm_state_next = ena ? FSM_STATE_FETCH : FSM_STATE_IDLE; + FSM_STATE_FETCH: fsm_state_next = FSM_STATE_DECODE; + FSM_STATE_DECODE: fsm_state_next = uop_data_opcode_is_stop ? FSM_STATE_IDLE : FSM_STATE_BUSY; + FSM_STATE_BUSY: fsm_state_next = fsm_exit_from_busy ? FSM_STATE_FETCH : FSM_STATE_BUSY; + endcase + // + end + + + // + // Ready Flag Logic + // + reg rdy_reg = 1'b1; + assign rdy = rdy_reg; + + always @(posedge clk or negedge rst_n) + // + if (rst_n == 1'b0) rdy_reg <= 1'b1; + else case (fsm_state) + FSM_STATE_IDLE: rdy_reg <= ~ena; + FSM_STATE_DECODE: rdy_reg <= uop_data_opcode_is_stop; + endcase + + +endmodule + + +//------------------------------------------------------------------------------ +// End-of-File +//------------------------------------------------------------------------------ |