diff options
Diffstat (limited to 'src/rtl/modexpa7_top.v')
-rw-r--r-- | src/rtl/modexpa7_top.v | 80 |
1 files changed, 55 insertions, 25 deletions
diff --git a/src/rtl/modexpa7_top.v b/src/rtl/modexpa7_top.v index ad101dd..7723b88 100644 --- a/src/rtl/modexpa7_top.v +++ b/src/rtl/modexpa7_top.v @@ -54,7 +54,7 @@ module modexpa7_top # input bus_cs, input bus_we, - input [OPERAND_ADDR_WIDTH+1:0] bus_addr, + input [OPERAND_ADDR_WIDTH+2:0] bus_addr, input [ 32-1:0] bus_data_wr, output [ 32-1:0] bus_data_rd ); @@ -154,17 +154,21 @@ module modexpa7_top # /* * Split bus address into bank/word parts. */ - wire [ 2 - 1 : 0] bus_addr_bank = bus_addr[OPERAND_ADDR_WIDTH+1:OPERAND_ADDR_WIDTH]; + wire [ 3 - 1 : 0] bus_addr_bank = bus_addr[OPERAND_ADDR_WIDTH+2:OPERAND_ADDR_WIDTH]; wire [OPERAND_ADDR_WIDTH - 1 : 0] bus_addr_word = bus_addr[OPERAND_ADDR_WIDTH-1:0]; /* * Define bank offsets. */ - localparam [ 1: 0] BANK_MODULUS = 2'b00; // 0 - localparam [ 1: 0] BANK_MESSAGE = 2'b01; // 1 - localparam [ 1: 0] BANK_EXPONENT = 2'b10; // 2 - localparam [ 1: 0] BANK_RESULT = 2'b11; // 3 + localparam [ 2: 0] BANK_MODULUS = 3'b000; // 0 + localparam [ 2: 0] BANK_MESSAGE = 3'b001; // 1 + localparam [ 2: 0] BANK_EXPONENT = 3'b010; // 2 + localparam [ 2: 0] BANK_RESULT = 3'b011; // 3
+ localparam [ 2: 0] BANK_MODULUS_COEFF_OUT = 3'b100; // 5
+ localparam [ 2: 0] BANK_MODULUS_COEFF_IN = 3'b101; // 4
+ localparam [ 2: 0] BANK_MONTGOMERY_FACTOR_OUT = 3'b110; // 7 + localparam [ 2: 0] BANK_MONTGOMERY_FACTOR_IN = 3'b111; // 6
/* @@ -176,7 +180,7 @@ module modexpa7_top # * * Note, that the core does squaring and multiplication simultaneously, so * there are two identical systolic multipliers inside. It's better to have two - * copies of modulus to give router some freeding in placing the multipliers, + * copies of modulus to give router some freedom in placing the multipliers, * that's why there are actually two identical block memories N1 and N2 instead of N. * User reads from the first one, but writes to both of them. Note that the synthesis * tool might get too clever and find out that N1 and N2 are identical and decide @@ -250,14 +254,18 @@ module modexpa7_top # /* - * Instantiate internal memories. + * Instantiate more block memories.
+ *
+ * Fast modular exponentiation requires two pre-calculated helper quantities: Montgomery
+ * factor F and modulus-dependent speed-up coefficient N_COEFF. This core has two separate
+ * buffers for each of those quantities, during pre-computation F and N_COEFF are written to
+ * the "output" buffers, so that user can retrieve them and store along with the key for
+ * future use. During exponentiation F and N_COEFF are read from the "input" buffers and
+ * must be supplied by user along with the modulus. * - * We have two block memories: F for Montgomery factor and N_COEFF for modulus-dependent - * coefficient, they are written to during pre-calculation and read from during exponentiation. - * - * Note, that there are actually two identical block memories N_COEFF1 and N_COEFF2 instead of - * just one N_COEFF, read the explanation above. F is only used by one of the multipliers, so - * we don't need F1 and F2. + * Note, that there are actually two identical input block memories N_COEFF1 and N_COEFF2
+ * instead of just one N_COEFF, read the explanation above. F is only used by one of
+ * the multipliers, so we don't need F1 and F2. */ wire [OPERAND_ADDR_WIDTH-1:0] core_f_addr_wr; @@ -274,20 +282,38 @@ module modexpa7_top # wire core_f_wren; wire core_n_coeff_wren; +
+ wire [ 32-1:0] user_f_out_data; + wire [ 32-1:0] user_f_in_data; + wire [ 32-1:0] user_n_coeff_out_data; + wire [ 32-1:0] user_n_coeff_in_data; +
+ wire user_f_in_wren = bus_cs && bus_we && (bus_addr_bank == BANK_MONTGOMERY_FACTOR_IN); + wire user_n_coeff_in_wren = bus_cs && bus_we && (bus_addr_bank == BANK_MODULUS_COEFF_IN);
bram_1rw_1ro_readfirst #(.MEM_WIDTH(32), .MEM_ADDR_BITS(OPERAND_ADDR_WIDTH)) - bram_f (.clk(clk), + bram_f_out (.clk(clk), .a_addr(core_f_addr_wr), .a_out(), .a_wr(core_f_wren), .a_in(core_f_data_wr), + .b_addr(bus_addr_word), .b_out(user_f_out_data)); +
+ bram_1rw_1ro_readfirst #(.MEM_WIDTH(32), .MEM_ADDR_BITS(OPERAND_ADDR_WIDTH)) + bram_f_in (.clk(clk), + .a_addr(bus_addr_word), .a_out(user_f_in_data), .a_wr(user_f_in_wren), .a_in(bus_data_wr), .b_addr(core_f_addr_rd), .b_out(core_f_data_rd)); - +
bram_1rw_1ro_readfirst #(.MEM_WIDTH(32), .MEM_ADDR_BITS(OPERAND_ADDR_WIDTH)) - bram_n_coeff1 (.clk(clk), + bram_n_coeff_out (.clk(clk), .a_addr(core_n_coeff_addr_wr), .a_out(), .a_wr(core_n_coeff_wren), .a_in(core_n_coeff_data_wr), + .b_addr(bus_addr_word), .b_out(user_n_coeff_out_data));
+ + bram_1rw_1ro_readfirst #(.MEM_WIDTH(32), .MEM_ADDR_BITS(OPERAND_ADDR_WIDTH)) + bram_n_coeff_in1 (.clk(clk), + .a_addr(bus_addr_word), .a_out(user_n_coeff_in_data), .a_wr(user_n_coeff_in_wren), .a_in(bus_data_wr), .b_addr(core_n_coeff1_addr_rd), .b_out(core_n_coeff1_data_rd)); bram_1rw_1ro_readfirst #(.MEM_WIDTH(32), .MEM_ADDR_BITS(OPERAND_ADDR_WIDTH)) - bram_n_coeff2 (.clk(clk), - .a_addr(core_n_coeff_addr_wr), .a_out(), .a_wr(core_n_coeff_wren), .a_in(core_n_coeff_data_wr), + bram_n_coeff_in2 (.clk(clk), + .a_addr(bus_addr_word), .a_out(), .a_wr(user_n_coeff_in_wren), .a_in(bus_data_wr), .b_addr(core_n_coeff2_addr_rd), .b_out(core_n_coeff2_data_rd)); @@ -461,7 +487,7 @@ module modexpa7_top # */ // delay bus_addr_bank by 1 clock cycle to remember from where we've just been reading - reg [1: 0] bus_addr_bank_dly; + reg [2: 0] bus_addr_bank_dly; always @(posedge clk) if (bus_cs) bus_addr_bank_dly <= bus_addr_bank; @@ -474,12 +500,16 @@ module modexpa7_top # // case (bus_addr_bank_dly) // - BANK_MODULUS: bus_data_rd_mux = user_n_data; - BANK_MESSAGE: bus_data_rd_mux = user_m_data; - BANK_EXPONENT: bus_data_rd_mux = user_d_data; - BANK_RESULT: bus_data_rd_mux = user_r_data; + BANK_MODULUS: bus_data_rd_mux = user_n_data; + BANK_MESSAGE: bus_data_rd_mux = user_m_data; + BANK_EXPONENT: bus_data_rd_mux = user_d_data; + BANK_RESULT: bus_data_rd_mux = user_r_data;
+ //
+ BANK_MODULUS_COEFF_OUT: bus_data_rd_mux = user_n_coeff_out_data;
+ BANK_MODULUS_COEFF_IN: bus_data_rd_mux = user_n_coeff_in_data;
+ BANK_MONTGOMERY_FACTOR_OUT: bus_data_rd_mux = user_f_out_data; + BANK_MONTGOMERY_FACTOR_IN: bus_data_rd_mux = user_f_in_data; // endcase - endmodule |