From 7df34f4b491dac71b4301828bdda6a6f9d8eecd6 Mon Sep 17 00:00:00 2001 From: "Pavel V. Shatov (Meister)" Date: Mon, 15 Oct 2018 15:53:31 +0300 Subject: Added support for add/subtract opcodes. --- rtl/ed25519_settings.vh | 2 + rtl/ed25519_worker.v | 276 +++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 265 insertions(+), 13 deletions(-) diff --git a/rtl/ed25519_settings.vh b/rtl/ed25519_settings.vh index 08fe8af..1ab492f 100644 --- a/rtl/ed25519_settings.vh +++ b/rtl/ed25519_settings.vh @@ -32,6 +32,8 @@ `define ED25519_MAC16_PRIMITIVE mac16_generic `define ED25519_ADD47_PRIMITIVE adder47_generic +`define ED25519_ADD32_PRIMITIVE adder32_generic +`define ED25519_SUB32_PRIMITIVE subtractor32_generic //------------------------------------------------------------------------------ diff --git a/rtl/ed25519_worker.v b/rtl/ed25519_worker.v index df99f61..be8152e 100644 --- a/rtl/ed25519_worker.v +++ b/rtl/ed25519_worker.v @@ -40,7 +40,20 @@ module ed25519_worker ( clk, rst_n, ena, rdy, - uop_offset + uop_offset, + final_reduce, + handle_sign, + output_now, + y_addr, y_dout, y_wren, + debug_dump_now, + debug_dump_addr1, + debug_dump_addr2, + debug_dump_addr3, + debug_dump_addr4, + debug_dump_addr5, + debug_dump_addr6, + debug_dump_addr7, + debug_dump_addr8 ); @@ -60,6 +73,24 @@ module ed25519_worker output rdy; // ready output input [UOP_ADDR_WIDTH-1:0] uop_offset; // starting offset + + input final_reduce; // use regular (not double) modulus + input handle_sign; // handle sign of x + input output_now; // produce output + + output [ 2: 0] y_addr; + output [31: 0] y_dout; + output y_wren; + + input debug_dump_now; + input [6:0] debug_dump_addr1; + input [6:0] debug_dump_addr2; + input [6:0] debug_dump_addr3; + input [6:0] debug_dump_addr4; + input [6:0] debug_dump_addr5; + input [6:0] debug_dump_addr6; + input [6:0] debug_dump_addr7; + input [6:0] debug_dump_addr8; // @@ -94,6 +125,9 @@ module ed25519_worker 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_mul = uop_data_opcode[3]; + wire uop_data_opcode_is_sub = uop_data_opcode[2]; + wire uop_data_opcode_is_add = uop_data_opcode[1]; wire uop_data_opcode_is_copy = uop_data_opcode[0]; ed25519_microcode microcode @@ -142,17 +176,144 @@ module ed25519_worker .x_din (mw_mover_x_din), .y_dout (mw_mover_y_dout) ); + + + // + // Modular Multiplier + // + reg mod_mul_ena = 1'b0; + wire mod_mul_rdy; + + wire [WORD_COUNTER_WIDTH-1:0] mod_mul_a_addr; + wire [WORD_COUNTER_WIDTH-1:0] mod_mul_b_addr; + wire [WORD_COUNTER_WIDTH-1:0] mod_mul_p_addr; + wire [ 32-1:0] mod_mul_a_din; + wire [ 32-1:0] mod_mul_b_din; + wire [ 32-1:0] mod_mul_p_dout; + wire mod_mul_p_wren; + + ed25519_modular_multiplier mod_mul_inst + ( + .clk (clk), + .rst_n (rst_n), + .ena (mod_mul_ena), + .rdy (mod_mul_rdy), + .a_addr (mod_mul_a_addr), + .b_addr (mod_mul_b_addr), + .p_addr (mod_mul_p_addr), + .p_wren (mod_mul_p_wren), + .a_din (mod_mul_a_din), + .b_din (mod_mul_b_din), + .p_dout (mod_mul_p_dout) + ); + + + // + // Modular Adder + // + reg mod_add_ena = 1'b0; + wire mod_add_rdy; + + wire [WORD_COUNTER_WIDTH-1:0] mod_add_ab_addr; + wire [WORD_COUNTER_WIDTH-1:0] mod_add_n_addr; + wire [WORD_COUNTER_WIDTH-1:0] mod_add_s_addr; + wire [ 32-1:0] mod_add_a_din; + wire [ 32-1:0] mod_add_b_din; + reg [ 32-1:0] mod_add_n_din; + wire [ 32-1:0] mod_add_s_dout; + wire mod_add_s_wren; + + mod_adder # + ( + .OPERAND_NUM_WORDS(OPERAND_NUM_WORDS), + .WORD_COUNTER_WIDTH(WORD_COUNTER_WIDTH) + ) + mod_add_inst + ( + .clk (clk), + .rst_n (rst_n), + .ena (mod_add_ena), + .rdy (mod_add_rdy), + .ab_addr (mod_add_ab_addr), + .n_addr (mod_add_n_addr), + .s_addr (mod_add_s_addr), + .s_wren (mod_add_s_wren), + .a_din (mod_add_a_din), + .b_din (mod_add_b_din), + .n_din (mod_add_n_din), + .s_dout (mod_add_s_dout) + ); + + + // + // Modular Subtractor + // + reg mod_sub_ena = 1'b0; + wire mod_sub_rdy; + + wire [WORD_COUNTER_WIDTH-1:0] mod_sub_ab_addr; + wire [WORD_COUNTER_WIDTH-1:0] mod_sub_n_addr; + wire [WORD_COUNTER_WIDTH-1:0] mod_sub_d_addr; + wire [ 32-1:0] mod_sub_a_din; + wire [ 32-1:0] mod_sub_b_din; + reg [ 32-1:0] mod_sub_n_din; + wire [ 32-1:0] mod_sub_d_dout; + wire mod_sub_d_wren; + + mod_subtractor # + ( + .OPERAND_NUM_WORDS(OPERAND_NUM_WORDS), + .WORD_COUNTER_WIDTH(WORD_COUNTER_WIDTH) + ) + mod_sub_inst + ( + .clk (clk), + .rst_n (rst_n), + .ena (mod_sub_ena), + .rdy (mod_sub_rdy), + .ab_addr (mod_sub_ab_addr), + .n_addr (mod_sub_n_addr), + .d_addr (mod_sub_d_addr), + .d_wren (mod_sub_d_wren), + .a_din (mod_sub_a_din), + .b_din (mod_sub_b_din), + .n_din (mod_sub_n_din), + .d_dout (mod_sub_d_dout) + ); + + + // + // Double Modulus + // + always @(posedge clk) begin + // + case (mod_add_n_addr) + 3'd0: mod_add_n_din <= !final_reduce ? 32'hFFFFFFDA : 32'hFFFFFFED; + 3'd7: mod_add_n_din <= !final_reduce ? 32'hFFFFFFFF : 32'h7FFFFFFF; + default: mod_add_n_din <= 32'hFFFFFFFF; + endcase + // + if (mod_sub_n_addr == 3'd0) mod_sub_n_din <= 32'hFFFFFFDA; + else mod_sub_n_din <= 32'hFFFFFFFF; + // + end + - // // uOP Trigger Logic // always @(posedge clk) // if (fsm_state == FSM_STATE_DECODE) begin - mw_mover_ena <= uop_data_opcode_is_copy; + mw_mover_ena <= uop_data_opcode_is_copy; + mod_mul_ena <= uop_data_opcode_is_mul; + mod_add_ena <= uop_data_opcode_is_add; + mod_sub_ena <= uop_data_opcode_is_sub; end else begin - mw_mover_ena <= 1'b0; + mw_mover_ena <= 1'b0; + mod_mul_ena <= 1'b0; + mod_add_ena <= 1'b0; + mod_sub_ena <= 1'b0; end @@ -166,6 +327,9 @@ module ed25519_worker fsm_exit_from_busy = 0; // if (uop_data_opcode_is_copy) fsm_exit_from_busy = ~mw_mover_ena & mw_mover_rdy; + if (uop_data_opcode_is_mul) fsm_exit_from_busy = ~mod_mul_ena & mod_mul_rdy; + if (uop_data_opcode_is_add) fsm_exit_from_busy = ~mod_add_ena & mod_add_rdy; + if (uop_data_opcode_is_sub) fsm_exit_from_busy = ~mod_sub_ena & mod_sub_rdy; // end @@ -204,10 +368,26 @@ module ed25519_worker .src1_dout (banks_src1_dout), .src2_dout (banks_src2_dout), - .dst_din (banks_dst_din) + .dst_din (banks_dst_din), + + .debug_dump_now(debug_dump_now), + .debug_dump_addr1(debug_dump_addr1), + .debug_dump_addr2(debug_dump_addr2), + .debug_dump_addr3(debug_dump_addr3), + .debug_dump_addr4(debug_dump_addr4), + .debug_dump_addr5(debug_dump_addr5), + .debug_dump_addr6(debug_dump_addr6), + .debug_dump_addr7(debug_dump_addr7), + .debug_dump_addr8(debug_dump_addr8) ); - assign mw_mover_x_din = banks_src1_dout; + assign mw_mover_x_din = banks_src1_dout; + assign mod_mul_a_din = banks_src1_dout; + assign mod_mul_b_din = banks_src2_dout; + assign mod_add_a_din = banks_src1_dout; + assign mod_add_b_din = banks_src2_dout; + assign mod_sub_a_din = banks_src1_dout; + assign mod_sub_b_din = banks_src2_dout; always @* // @@ -226,9 +406,44 @@ module ed25519_worker // end // - //UOP_OPCODE_ADD: d - //UOP_OPCODE_SUB: d - //UOP_OPCODE_MUL: d + UOP_OPCODE_ADD: begin + // + banks_src1_addr = mod_add_ab_addr; + banks_src2_addr = mod_add_ab_addr; + // + banks_dst_addr = mod_add_s_addr; + // + banks_dst_wren = mod_add_s_wren; + // + banks_dst_din = mod_add_s_dout; + // + end + // + UOP_OPCODE_SUB: begin + // + banks_src1_addr = mod_sub_ab_addr; + banks_src2_addr = mod_sub_ab_addr; + // + banks_dst_addr = mod_sub_d_addr; + // + banks_dst_wren = mod_sub_d_wren; + // + banks_dst_din = mod_sub_d_dout; + // + end + // + UOP_OPCODE_MUL: begin + // + banks_src1_addr = mod_mul_a_addr; + banks_src2_addr = mod_mul_b_addr; + // + banks_dst_addr = mod_mul_p_addr; + // + banks_dst_wren = mod_mul_p_wren; + // + banks_dst_din = mod_mul_p_dout; + // + end // default: begin // @@ -243,11 +458,20 @@ module ed25519_worker end // endcase + - //addr - //wren - //dout - //din + // + // Sign Handler + // + reg sign_x_int; + + wire [31:0] mw_mover_y_dout_with_x_sign = {(mw_mover_y_addr == 3'd7) ? + sign_x_int : mw_mover_y_dout[31], mw_mover_y_dout[30:0]}; + + always @(posedge clk) + // + if (handle_sign && mw_mover_y_wren && (mw_mover_y_addr == 0)) + sign_x_int <= mw_mover_y_dout[0]; // @@ -291,6 +515,32 @@ module ed25519_worker endcase + + // + // Output Logic + // + reg [ 2: 0] y_addr_reg = 3'b000; + reg [31: 0] y_dout_reg = 32'h00000000; + reg y_wren_reg = 1'b0; + + assign y_addr = y_addr_reg; + assign y_dout = y_dout_reg; + assign y_wren = y_wren_reg; + + always @(posedge clk) + // + if (output_now && mw_mover_y_wren) begin + // + y_addr_reg <= mw_mover_y_addr; + y_dout_reg <= mw_mover_y_dout_with_x_sign; + y_wren_reg <= 1'b1; + // + end else begin + y_addr_reg <= 3'b000; + y_dout_reg <= 32'h00000000; + y_wren_reg <= 1'b0; + end + endmodule -- cgit v1.2.3