summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2018-10-15 15:53:31 +0300
committerPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2018-10-15 15:53:31 +0300
commit7df34f4b491dac71b4301828bdda6a6f9d8eecd6 (patch)
tree481c40d68cac430c6b455e3b5d287d8f0a6f26af
parent1a233271ba75b0a878068e5c6acfb7ba66480c21 (diff)
Added support for add/subtract opcodes.
-rw-r--r--rtl/ed25519_settings.vh2
-rw-r--r--rtl/ed25519_worker.v276
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