//------------------------------------------------------------------------------ // // 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 //------------------------------------------------------------------------------