diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rtl/adder.v (renamed from src/rtl/adder32.v) | 42 | ||||
-rw-r--r-- | src/rtl/blockmem1r1w.v | 22 | ||||
-rw-r--r-- | src/rtl/blockmem2r1w.v | 25 | ||||
-rw-r--r-- | src/rtl/blockmem2r1wptr.v | 44 | ||||
-rw-r--r-- | src/rtl/blockmem2rptr1w.v | 41 | ||||
-rw-r--r-- | src/rtl/modexp.v | 78 | ||||
-rw-r--r-- | src/rtl/modexp_core.v | 256 | ||||
-rw-r--r-- | src/rtl/montprod.v | 777 | ||||
-rw-r--r-- | src/rtl/residue.v | 402 | ||||
-rw-r--r-- | src/rtl/shl.v (renamed from src/rtl/shl32.v) | 31 | ||||
-rw-r--r-- | src/rtl/shr.v (renamed from src/rtl/shr32.v) | 25 | ||||
-rw-r--r-- | src/support/rtl/README.md | 18 | ||||
-rw-r--r-- | src/support/rtl/blockmem_rw32ptr_r64.v | 155 | ||||
-rw-r--r-- | src/support/rtl/montprod_wrapper.v | 153 | ||||
-rw-r--r-- | src/tb/tb_modexp.v | 1028 | ||||
-rw-r--r-- | src/tb/tb_modexp_autogenerated.v | 4 | ||||
-rw-r--r-- | src/tb/tb_montprod.v | 757 |
17 files changed, 2634 insertions, 1224 deletions
diff --git a/src/rtl/adder32.v b/src/rtl/adder.v index d9cac45..fa8ed8c 100644 --- a/src/rtl/adder32.v +++ b/src/rtl/adder.v @@ -1,11 +1,12 @@ //====================================================================== // -// adder32.v -// --------- -// 32bit adder with carry in / carry out +// adder.v +// ------- +// Adder with separate carry in and carry out. Used in the montprod +// amd residue modules of the modexp core. // // -// Author: Peter Magnusson +// Author: Peter Magnusson, Joachim Strömbergson // Copyright (c) 2015, NORDUnet A/S All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -36,19 +37,28 @@ // //====================================================================== +module adder #(parameter OPW = 32) + ( + input [(OPW - 1) : 0] a, + input [(OPW - 1) : 0] b, + input carry_in, -module adder32( - input [31 : 0] a, - input [31 : 0] b, - input carry_in, - output wire [31 : 0] sum, - output wire carry_out); + output wire [(OPW - 1) : 0] sum, + output wire carry_out + ); - reg [32 : 0] adder_result; + reg [(OPW) : 0] adder_result; - assign sum = adder_result[31:0]; - assign carry_out = adder_result[32]; + assign sum = adder_result[(OPW - 1) : 0]; + assign carry_out = adder_result[(OPW)]; - always @(a, b, carry_in) - adder_result = {1'b0, a} + {1'b0, b} + {32'b0, carry_in}; -endmodule + always @* + begin + adder_result = {1'b0, a} + {1'b0, b} + {{OPW{1'b0}}, carry_in}; + end + +endmodule // adder + +//====================================================================== +// EOF adder.v +//====================================================================== diff --git a/src/rtl/blockmem1r1w.v b/src/rtl/blockmem1r1w.v index 1d84369..6856e0a 100644 --- a/src/rtl/blockmem1r1w.v +++ b/src/rtl/blockmem1r1w.v @@ -7,6 +7,9 @@ // // The memory is used in the modexp core. // +// paremeter OPW is operand word width in bits. +// parameter ADW is address width in bits. +// // // Author: Joachim Strombergson // Copyright (c) 2015, NORDUnet A/S All rights reserved. @@ -39,19 +42,20 @@ // //====================================================================== -module blockmem1r1w( - input wire clk, +module blockmem1r1w #(parameter OPW = 32, parameter ADW = 8) + ( + input wire clk, - input wire [07 : 0] read_addr, - output wire [31 : 0] read_data, + input wire [(ADW - 1) : 0] read_addr, + output wire [(OPW - 1) : 0] read_data, - input wire wr, - input wire [07 : 0] write_addr, - input wire [31 : 0] write_data + input wire wr, + input wire [(ADW - 1) : 0] write_addr, + input wire [(OPW - 1) : 0] write_data ); - reg [31 : 0] mem [0 : 255]; - reg [31 : 0] tmp_read_data; + reg [(OPW - 1) : 0] mem [0 : ((2**ADW) - 1)]; + reg [(OPW - 1) : 0] tmp_read_data; assign read_data = tmp_read_data; diff --git a/src/rtl/blockmem2r1w.v b/src/rtl/blockmem2r1w.v index 252764f..aa44101 100644 --- a/src/rtl/blockmem2r1w.v +++ b/src/rtl/blockmem2r1w.v @@ -39,23 +39,24 @@ // //====================================================================== -module blockmem2r1w( - input wire clk, +module blockmem2r1w #(parameter OPW = 32, parameter ADW = 8) + ( + input wire clk, - input wire [07 : 0] read_addr0, - output wire [31 : 0] read_data0, + input wire [(ADW - 1) : 0] read_addr0, + output wire [(OPW - 1) : 0] read_data0, - input wire [07 : 0] read_addr1, - output wire [31 : 0] read_data1, + input wire [(ADW - 1) : 0] read_addr1, + output wire [(OPW - 1) : 0] read_data1, - input wire wr, - input wire [07 : 0] write_addr, - input wire [31 : 0] write_data + input wire wr, + input wire [(ADW - 1) : 0] write_addr, + input wire [(OPW - 1) : 0] write_data ); - reg [31 : 0] mem [0 : 255]; - reg [31 : 0] tmp_read_data0; - reg [31 : 0] tmp_read_data1; + reg [(OPW - 1) : 0] mem [0 : ((2**ADW) - 1)]; + reg [(OPW - 1) : 0] tmp_read_data0; + reg [(OPW - 1) : 0] tmp_read_data1; assign read_data0 = tmp_read_data0; assign read_data1 = tmp_read_data1; diff --git a/src/rtl/blockmem2r1wptr.v b/src/rtl/blockmem2r1wptr.v index 41efc85..2435cfd 100644 --- a/src/rtl/blockmem2r1wptr.v +++ b/src/rtl/blockmem2r1wptr.v @@ -8,6 +8,12 @@ // when the cs signal is set. The pointer is reset to zero when // the rst signal is asserted. // +// +// NOTE: This memory needs to be rebuilt if interface 0 is changed +// to use bigger operand widths and fewer words than interface 1. +// This adaption is NOT automatic. +// +// // The memory is used in the modexp core. // // @@ -42,32 +48,32 @@ // //====================================================================== -module blockmem2r1wptr( - input wire clk, - input wire reset_n, - - input wire [07 : 0] read_addr0, - output wire [31 : 0] read_data0, +module blockmem2r1wptr #(parameter OPW = 32, parameter ADW = 8) + ( + input wire clk, + input wire reset_n, - output wire [31 : 0] read_data1, + input wire [(ADW - 1) : 0] read_addr0, + output wire [(OPW - 1) : 0] read_data0, - input wire rst, - input wire cs, - input wire wr, - input wire [31 : 0] write_data + output wire [31 : 0] read_data1, + input wire rst, + input wire cs, + input wire wr, + input wire [31 : 0] write_data ); //---------------------------------------------------------------- // Memories and regs including update variables and write enable. //---------------------------------------------------------------- - reg [31 : 0] mem [0 : 255]; - reg [31 : 0] tmp_read_data0; - reg [31 : 0] tmp_read_data1; + reg [(OPW - 1) : 0] mem [0 : ((2**ADW) - 1)]; + reg [(OPW - 1) : 0] tmp_read_data0; + reg [31 : 0] tmp_read_data1; - reg [7 : 0] ptr_reg; - reg [7 : 0] ptr_new; - reg ptr_we; + reg [7 : 0] ptr_reg; + reg [7 : 0] ptr_new; + reg ptr_we; //---------------------------------------------------------------- @@ -94,10 +100,10 @@ module blockmem2r1wptr( //---------------------------------------------------------------- - // reg_update + // ptr_update //---------------------------------------------------------------- always @ (posedge clk or negedge reset_n) - begin : reg_mem_update + begin : ptr_update if (!reset_n) ptr_reg <= 8'h00; diff --git a/src/rtl/blockmem2rptr1w.v b/src/rtl/blockmem2rptr1w.v index 4eb529e..a1d7448 100644 --- a/src/rtl/blockmem2rptr1w.v +++ b/src/rtl/blockmem2rptr1w.v @@ -9,6 +9,11 @@ // The memory is used in the modexp core. // // +// NOTE: This memory needs to be rebuilt if interface 0 is changed +// to use bigger operand widths and fewer words than interface 1. +// This adaption is NOT automatic. +// +// // Author: Joachim Strombergson // Copyright (c) 2015, NORDUnet A/S All rights reserved. // @@ -40,33 +45,33 @@ // //====================================================================== -module blockmem2rptr1w( - input wire clk, - input wire reset_n, - - input wire [07 : 0] read_addr0, - output wire [31 : 0] read_data0, +module blockmem2rptr1w #(parameter OPW = 32, parameter ADW = 8) + ( + input wire clk, + input wire reset_n, - output wire [31 : 0] read_data1, + input wire [(ADW - 1) : 0] read_addr0, + output wire [(OPW - 1) : 0] read_data0, - input wire rst, - input wire cs, - input wire wr, - input wire [07 : 0] write_addr, - input wire [31 : 0] write_data + output wire [31 : 0] read_data1, + input wire rst, + input wire cs, + input wire wr, + input wire [07 : 0] write_addr, + input wire [31 : 0] write_data ); //---------------------------------------------------------------- // Memories and regs including update variables and write enable. //---------------------------------------------------------------- - reg [31 : 0] mem [0 : 255]; - reg [31 : 0] tmp_read_data0; - reg [31 : 0] tmp_read_data1; + reg [(OPW - 1) : 0] mem [0 : ((2**ADW) - 1)]; + reg [(OPW - 1) : 0] tmp_read_data0; + reg [31 : 0] tmp_read_data1; - reg [7 : 0] ptr_reg; - reg [7 : 0] ptr_new; - reg ptr_we; + reg [7 : 0] ptr_reg; + reg [7 : 0] ptr_new; + reg ptr_we; //---------------------------------------------------------------- diff --git a/src/rtl/modexp.v b/src/rtl/modexp.v index 2af987f..ebda365 100644 --- a/src/rtl/modexp.v +++ b/src/rtl/modexp.v @@ -72,6 +72,15 @@ module modexp( //---------------------------------------------------------------- // Internal constant and parameter definitions. //---------------------------------------------------------------- + + // The operand width is the internal operand width in bits. + // The address width is the size of the address space used. This + // value must be balances with OPERAND_WIDTH to allow a total + // of 8192 bits of data. OPERAND_WIDTH * (ADDRESS_WIDTH ** 2) + // is the formula. Note that the API data with is always 32 bits. + localparam OPERAND_WIDTH = 32; + localparam ADDRESS_WIDTH = 8; + localparam ADDR_NAME0 = 8'h00; localparam ADDR_NAME1 = 8'h01; localparam ADDR_VERSION = 8'h02; @@ -161,40 +170,41 @@ module modexp( //---------------------------------------------------------------- // core instantiations. //---------------------------------------------------------------- - modexp_core core_inst( - .clk(clk), - .reset_n(reset_n), - - .start(start_reg), - .ready(ready), - - .exponent_length(exponent_length_reg), - .modulus_length(modulus_length_reg), - - .cycles(cycles), - - .exponent_mem_api_cs(exponent_mem_api_cs), - .exponent_mem_api_wr(exponent_mem_api_wr), - .exponent_mem_api_rst(exponent_mem_api_rst), - .exponent_mem_api_write_data(write_data), - .exponent_mem_api_read_data(exponent_mem_api_read_data), - - .modulus_mem_api_cs(modulus_mem_api_cs), - .modulus_mem_api_wr(modulus_mem_api_wr), - .modulus_mem_api_rst(modulus_mem_api_rst), - .modulus_mem_api_write_data(write_data), - .modulus_mem_api_read_data(modulus_mem_api_read_data), - - .message_mem_api_cs(message_mem_api_cs), - .message_mem_api_wr(message_mem_api_wr), - .message_mem_api_rst(message_mem_api_rst), - .message_mem_api_write_data(write_data), - .message_mem_api_read_data(message_mem_api_read_data), - - .result_mem_api_cs(result_mem_api_cs), - .result_mem_api_rst(result_mem_api_rst), - .result_mem_api_read_data(result_mem_api_read_data) - ); + modexp_core #(.OPW(OPERAND_WIDTH), .ADW(ADDRESS_WIDTH)) + core_inst( + .clk(clk), + .reset_n(reset_n), + + .start(start_reg), + .ready(ready), + + .exponent_length(exponent_length_reg), + .modulus_length(modulus_length_reg), + + .cycles(cycles), + + .exponent_mem_api_cs(exponent_mem_api_cs), + .exponent_mem_api_wr(exponent_mem_api_wr), + .exponent_mem_api_rst(exponent_mem_api_rst), + .exponent_mem_api_write_data(write_data), + .exponent_mem_api_read_data(exponent_mem_api_read_data), + + .modulus_mem_api_cs(modulus_mem_api_cs), + .modulus_mem_api_wr(modulus_mem_api_wr), + .modulus_mem_api_rst(modulus_mem_api_rst), + .modulus_mem_api_write_data(write_data), + .modulus_mem_api_read_data(modulus_mem_api_read_data), + + .message_mem_api_cs(message_mem_api_cs), + .message_mem_api_wr(message_mem_api_wr), + .message_mem_api_rst(message_mem_api_rst), + .message_mem_api_write_data(write_data), + .message_mem_api_read_data(message_mem_api_read_data), + + .result_mem_api_cs(result_mem_api_cs), + .result_mem_api_rst(result_mem_api_rst), + .result_mem_api_read_data(result_mem_api_read_data) + ); //---------------------------------------------------------------- diff --git a/src/rtl/modexp_core.v b/src/rtl/modexp_core.v index b8c4403..c1a88d1 100644 --- a/src/rtl/modexp_core.v +++ b/src/rtl/modexp_core.v @@ -54,7 +54,8 @@ // //====================================================================== -module modexp_core( +module modexp_core #(parameter OPW = 32, parameter ADW = 8) + ( input wire clk, input wire reset_n, @@ -235,7 +236,8 @@ module modexp_core( reg residue_valid_new; reg residue_valid_int_validated; - wire [7 : 0] length_m1; + wire [7 : 0] modulus_length_m1; + wire [7 : 0] exponent_length_m1; //---------------------------------------------------------------- @@ -244,127 +246,137 @@ module modexp_core( assign ready = ready_reg; assign cycles = {cycle_ctr_high_reg, cycle_ctr_low_reg}; - assign length_m1 = modulus_length - 8'h1; + assign modulus_length_m1 = modulus_length - 8'h1; + assign exponent_length_m1 = exponent_length - 8'h1; //---------------------------------------------------------------- // core instantiations. //---------------------------------------------------------------- - montprod montprod_inst( - .clk(clk), - .reset_n(reset_n), - - .calculate(montprod_calc), - .ready(montprod_ready), - - .length(montprod_length), - - .opa_addr(montprod_opa_addr), - .opa_data(montprod_opa_data), - - .opb_addr(montprod_opb_addr), - .opb_data(montprod_opb_data), - - .opm_addr(montprod_opm_addr), - .opm_data(montprod_opm_data), - - .result_addr(montprod_result_addr), - .result_data(montprod_result_data), - .result_we(montprod_result_we) - ); - - - residue residue_inst( - .clk(clk), - .reset_n(reset_n), - .calculate(residue_calculate), - .ready(residue_ready), - .nn(residue_nn), - .length(residue_length), - .opa_rd_addr(residue_opa_rd_addr), - .opa_rd_data(residue_opa_rd_data), - .opa_wr_addr(residue_opa_wr_addr), - .opa_wr_data(residue_opa_wr_data), - .opa_wr_we(residue_opa_wr_we), - .opm_addr(residue_opm_addr), - .opm_data(residue_opm_data) - ); - - blockmem2r1w residue_mem( - .clk(clk), - .read_addr0(residue_opa_rd_addr), - .read_data0(residue_opa_rd_data), - .read_addr1(residue_mem_montprod_read_addr), - .read_data1(residue_mem_montprod_read_data), - .wr(residue_opa_wr_we), - .write_addr(residue_opa_wr_addr), - .write_data(residue_opa_wr_data) - ); - - - blockmem2r1w p_mem( - .clk(clk), - .read_addr0(p_mem_rd0_addr), - .read_data0(p_mem_rd0_data), - .read_addr1(p_mem_rd1_addr), - .read_data1(p_mem_rd1_data), - .wr(p_mem_we), - .write_addr(p_mem_wr_addr), - .write_data(p_mem_wr_data) - ); - - - blockmem2r1wptr exponent_mem( - .clk(clk), - .reset_n(reset_n), - .read_addr0(exponent_mem_int_rd_addr), - .read_data0(exponent_mem_int_rd_data), - .read_data1(exponent_mem_api_read_data), - .rst(exponent_mem_api_rst), - .cs(exponent_mem_api_cs), - .wr(exponent_mem_api_wr), - .write_data(exponent_mem_api_write_data) - ); - - - blockmem2r1wptr modulus_mem( - .clk(clk), - .reset_n(reset_n), - .read_addr0(modulus_mem_int_rd_addr), - .read_data0(modulus_mem_int_rd_data), - .read_data1(modulus_mem_api_read_data), - .rst(modulus_mem_api_rst), - .cs(modulus_mem_api_cs), - .wr(modulus_mem_api_wr), - .write_data(modulus_mem_api_write_data) - ); - - - blockmem2r1wptr message_mem( - .clk(clk), - .reset_n(reset_n), - .read_addr0(message_mem_int_rd_addr), - .read_data0(message_mem_int_rd_data), - .read_data1(message_mem_api_read_data), - .rst(message_mem_api_rst), - .cs(message_mem_api_cs), - .wr(message_mem_api_wr), - .write_data(message_mem_api_write_data) - ); - - - blockmem2rptr1w result_mem( - .clk(clk), - .reset_n(reset_n), - .read_addr0(result_mem_int_rd_addr[7 : 0]), - .read_data0(result_mem_int_rd_data), - .read_data1(result_mem_api_read_data), - .rst(result_mem_api_rst), - .cs(result_mem_api_cs), - .wr(result_mem_int_we), - .write_addr(result_mem_int_wr_addr), - .write_data(result_mem_int_wr_data) - ); + montprod #(.OPW(OPW), .ADW(ADW)) + montprod_inst( + .clk(clk), + .reset_n(reset_n), + + .calculate(montprod_calc), + .ready(montprod_ready), + + .length(montprod_length), + + .opa_addr(montprod_opa_addr), + .opa_data(montprod_opa_data), + + .opb_addr(montprod_opb_addr), + .opb_data(montprod_opb_data), + + .opm_addr(montprod_opm_addr), + .opm_data(montprod_opm_data), + + .result_addr(montprod_result_addr), + .result_data(montprod_result_data), + .result_we(montprod_result_we) + ); + + + residue #(.OPW(OPW), .ADW(ADW)) + residue_inst( + .clk(clk), + .reset_n(reset_n), + .calculate(residue_calculate), + .ready(residue_ready), + .nn(residue_nn), + .length(residue_length), + .opa_rd_addr(residue_opa_rd_addr), + .opa_rd_data(residue_opa_rd_data), + .opa_wr_addr(residue_opa_wr_addr), + .opa_wr_data(residue_opa_wr_data), + .opa_wr_we(residue_opa_wr_we), + .opm_addr(residue_opm_addr), + .opm_data(residue_opm_data) + ); + + + blockmem2r1w #(.OPW(OPW), .ADW(ADW)) + residue_mem( + .clk(clk), + .read_addr0(residue_opa_rd_addr), + .read_data0(residue_opa_rd_data), + .read_addr1(residue_mem_montprod_read_addr), + .read_data1(residue_mem_montprod_read_data), + .wr(residue_opa_wr_we), + .write_addr(residue_opa_wr_addr), + .write_data(residue_opa_wr_data) + ); + + + blockmem2r1w #(.OPW(OPW), .ADW(ADW)) + p_mem( + .clk(clk), + .read_addr0(p_mem_rd0_addr), + .read_data0(p_mem_rd0_data), + .read_addr1(p_mem_rd1_addr), + .read_data1(p_mem_rd1_data), + .wr(p_mem_we), + .write_addr(p_mem_wr_addr), + .write_data(p_mem_wr_data) + ); + + + blockmem2r1wptr #(.OPW(OPW), .ADW(ADW)) + exponent_mem( + .clk(clk), + .reset_n(reset_n), + .read_addr0(exponent_mem_int_rd_addr), + .read_data0(exponent_mem_int_rd_data), + .read_data1(exponent_mem_api_read_data), + .rst(exponent_mem_api_rst), + .cs(exponent_mem_api_cs), + .wr(exponent_mem_api_wr), + .write_data(exponent_mem_api_write_data) + ); + + + blockmem2r1wptr #(.OPW(OPW), .ADW(ADW)) + modulus_mem( + .clk(clk), + .reset_n(reset_n), + .read_addr0(modulus_mem_int_rd_addr), + .read_data0(modulus_mem_int_rd_data), + .read_data1(modulus_mem_api_read_data), + .rst(modulus_mem_api_rst), + .cs(modulus_mem_api_cs), + .wr(modulus_mem_api_wr), + .write_data(modulus_mem_api_write_data) + ); + + + blockmem2r1wptr #(.OPW(OPW), .ADW(ADW)) + message_mem( + .clk(clk), + .reset_n(reset_n), + .read_addr0(message_mem_int_rd_addr), + .read_data0(message_mem_int_rd_data), + .read_data1(message_mem_api_read_data), + .rst(message_mem_api_rst), + .cs(message_mem_api_cs), + .wr(message_mem_api_wr), + .write_data(message_mem_api_write_data) + ); + + + blockmem2rptr1w #(.OPW(OPW), .ADW(ADW)) + result_mem( + .clk(clk), + .reset_n(reset_n), + .read_addr0(result_mem_int_rd_addr[7 : 0]), + .read_data0(result_mem_int_rd_data), + .read_data1(result_mem_api_read_data), + .rst(result_mem_api_rst), + .cs(result_mem_api_cs), + .wr(result_mem_int_we), + .write_addr(result_mem_int_wr_addr), + .write_data(result_mem_int_wr_data) + ); //---------------------------------------------------------------- @@ -485,10 +497,10 @@ module modexp_core( one_new = 32'h00000000; b_one_new = 32'h00000000; - if (montprod_opa_addr == length_m1) + if (montprod_opa_addr == modulus_length_m1) one_new = 32'h00000001; - if (montprod_opb_addr == length_m1) + if (montprod_opb_addr == modulus_length_m1) b_one_new = 32'h00000001; end @@ -634,7 +646,7 @@ module modexp_core( loop_counter_new = 13'b0; loop_counter_we = 1'b0; - if (loop_counter_reg == {length_m1, 5'b11111}) + if (loop_counter_reg == {exponent_length_m1, 5'b11111}) last_iteration = 1'b1; else last_iteration = 1'b0; @@ -668,7 +680,7 @@ module modexp_core( begin : exponent_process // Accessing new instead of reg - pick up update at // CTRL_ITERATE_NEW to remove a pipeline stall. - E_word_index = length_m1 - loop_counter_new[ 12 : 5 ]; + E_word_index = exponent_length_m1 - loop_counter_new[ 12 : 5 ]; E_bit_index = loop_counter_reg[ 04 : 0 ]; diff --git a/src/rtl/montprod.v b/src/rtl/montprod.v index 6b525f7..3a310d7 100644 --- a/src/rtl/montprod.v +++ b/src/rtl/montprod.v @@ -4,6 +4,9 @@ // --------- // Montgomery product calculator for the modular exponentiantion core. // +// parameter OPW is operand word width in bits. +// parameter ADW is address width in bits. +// // // Author: Peter Magnusson, Joachim Strombergson // Copyright (c) 2015, NORDUnet A/S All rights reserved. @@ -36,135 +39,158 @@ // //====================================================================== -module montprod( - input wire clk, - input wire reset_n, +module montprod #(parameter OPW = 32, parameter ADW = 8) + ( + input wire clk, + input wire reset_n, - input wire calculate, - output wire ready, + input wire calculate, + output wire ready, - input [7 : 0] length, + input wire [(ADW - 1) : 0] length, - output wire [7 : 0] opa_addr, - input wire [31 : 0] opa_data, + output wire [(ADW - 1) : 0] opa_addr, + input wire [(OPW - 1) : 0] opa_data, - output wire [7 : 0] opb_addr, - input wire [31 : 0] opb_data, + output wire [(ADW - 1) : 0] opb_addr, + input wire [(OPW - 1) : 0] opb_data, - output wire [7 : 0] opm_addr, - input wire [31 : 0] opm_data, + output wire [(ADW - 1) : 0] opm_addr, + input wire [(OPW - 1) : 0] opm_data, - output wire [7 : 0] result_addr, - output wire [31 : 0] result_data, - output wire result_we + output wire [(ADW - 1) : 0] result_addr, + output wire [(OPW - 1) : 0] result_data, + output wire result_we ); //---------------------------------------------------------------- // Internal constant and parameter definitions. //---------------------------------------------------------------- - localparam DEBUG = 0; - - localparam CTRL_IDLE = 4'h0; - localparam CTRL_INIT_S = 4'h1; - localparam CTRL_LOOP_INIT = 4'h2; - localparam CTRL_LOOP_ITER = 4'h3; - localparam CTRL_LOOP_BQ = 4'h4; - localparam CTRL_L_CALC_SM = 4'h5; - localparam CTRL_L_STALLPIPE_SM = 4'h6; - localparam CTRL_L_CALC_SA = 4'h7; - localparam CTRL_L_STALLPIPE_SA = 4'h8; - localparam CTRL_L_CALC_SDIV2 = 4'h9; - localparam CTRL_L_STALLPIPE_D2 = 4'hA; - localparam CTRL_L_STALLPIPE_ES = 4'hB; - localparam CTRL_EMIT_S = 4'hC; - localparam CTRL_DONE = 4'hD; - - localparam SMUX_0 = 2'h0; - localparam SMUX_ADD_SM = 2'h1; - localparam SMUX_ADD_SA = 2'h2; - localparam SMUX_SHR = 2'h3; + localparam CTRL_IDLE = 4'h0; + localparam CTRL_LOOP_ITER = 4'h1; + localparam CTRL_LOOP_BQ = 4'h2; + localparam CTRL_CALC_ADD = 4'h3; + localparam CTRL_STALLPIPE_ADD = 4'h4; + localparam CTRL_CALC_SDIV2 = 4'h5; + localparam CTRL_STALLPIPE_SDIV2 = 4'h6; + localparam CTRL_L_STALLPIPE_ES = 4'h7; + localparam CTRL_EMIT_S = 4'h8; + + localparam SMUX_ZERO = 2'h0; + localparam SMUX_ADD = 2'h1; + localparam SMUX_SHR = 2'h2; + //---------------------------------------------------------------- // Registers including update variables and write enable. //---------------------------------------------------------------- + reg ready_reg; + reg ready_new; + reg ready_we; - reg [07 : 0] opa_addr_reg; - reg [07 : 0] opb_addr_reg; - reg [07 : 0] opm_addr_reg; + reg [3 : 0] montprod_ctrl_reg; + reg [3 : 0] montprod_ctrl_new; + reg montprod_ctrl_we; - reg [07 : 0] result_addr_reg; - reg [31 : 0] result_data_reg; + reg [1 : 0] s_mux_new; + reg [1 : 0] s_mux_reg; - reg ready_reg; - reg ready_new; - reg ready_we; + reg s_mem_we_reg; + reg s_mem_we_new; - reg [3 : 0] montprod_ctrl_reg; - reg [3 : 0] montprod_ctrl_new; - reg montprod_ctrl_we; + reg [(ADW - 1) : 0] s_mem_read_addr_reg; - reg [1 : 0] s_mux_new; - reg [1 : 0] s_mux_reg; + reg q_new; + reg q_reg; + reg b_new; + reg b_reg; + reg bq_we; - reg [31 : 0] s_mem_new; - reg s_mem_we; - reg s_mem_we_new; - reg [07 : 0] s_mem_addr; - reg [07 : 0] s_mem_wr_addr; - wire [31 : 0] s_mem_read_data; + reg [12 : 0] loop_ctr_reg; + reg [12 : 0] loop_ctr_new; + reg loop_ctr_we; + reg loop_ctr_set; + reg loop_ctr_dec; - reg q; //q = (s - b * A) & 1 - reg q_reg; - reg b; //b: bit of B - reg b_reg; + reg [(13 - ADW - 1) : 0] b_bit_index_reg; + reg [(13 - ADW - 1) : 0] b_bit_index_new; + reg b_bit_index_we; - reg [12 : 0] loop_counter; - reg [12 : 0] loop_counter_new; - reg [12 : 0] loop_counter_dec; - reg [07 : 0] B_word_index; //loop counter as a word index - reg [04 : 0] B_bit_index; //loop counter as a bit index - reg [04 : 0] B_bit_index_reg; //loop counter as a bit index + reg [(ADW - 1) : 0] word_index_reg; + reg [(ADW - 1) : 0] word_index_new; + reg word_index_we; + reg [(ADW - 1) : 0] word_index_prev_reg; + reg reset_word_index_lsw; + reg reset_word_index_msw; + reg inc_word_index; + reg dec_word_index; - reg [07 : 0] word_index; //register of what word is being read - reg [07 : 0] word_index_new; //calculation of what word to be read - reg [07 : 0] word_index_prev; //register of what word was read previously (result address to emit) - reg [07 : 0] length_m1; + reg add_carry_in_sa_reg; + reg add_carry_in_sa_new; + reg add_carry_in_sm_reg; + reg add_carry_in_sm_new; - reg add_carry_in_sa; - reg add_carry_new_sa; - reg add_carry_in_sm; - reg add_carry_new_sm; + reg shr_carry_in_reg; + reg shr_carry_in_new; - reg shr_carry_in; - reg shr_carry_new; + reg first_iteration_reg; + reg first_iteration_new; + reg first_iteration_we; - reg reset_word_index_LSW; - reg reset_word_index_MSW; + reg test_reg; + reg test_new; + + reg [(OPW - 2) : 0] shr_data_out_reg; + reg shr_carry_out_reg; + reg shr_carry_out_new; //---------------------------------------------------------------- // Wires. //---------------------------------------------------------------- - reg tmp_result_we; - wire [31 : 0] add_result_sa; - wire add_carry_out_sa; - wire [31 : 0] add_result_sm; - wire add_carry_out_sm; + wire [(OPW - 1) : 0] add_result_sa; + wire add_carry_out_sa; + wire [(OPW - 1) : 0] add_result_sm; + wire add_carry_out_sm; + + reg [(ADW - 1) : 0] b_word_index; //loop counter as a word index + + reg [(OPW - 1) : 0] shr_data_in; + wire shr_carry_out; + wire [(OPW - 1) : 0] shr_data_out; + + reg [(ADW - 1) : 0] tmp_opa_addr; + reg tmp_result_we; + + reg [(ADW - 1) : 0] s_mem_read_addr; + wire [(OPW - 1) : 0] s_mem_read_data; + reg [(ADW - 1) : 0] s_mem_write_addr; + reg [(OPW - 1) : 0] s_mem_write_data; + reg [(OPW - 1) : 0] tmp_s_mem_write_data; + + reg [(OPW - 1) : 0] sa_adder_data_in; + reg [(OPW - 1) : 0] muxed_s_mem_read_data; + reg [(OPW - 1) : 0] shifted_s_mem_write_data; + + wire [(ADW - 1) : 0] length_m1; - wire shr_carry_out; - wire [31 : 0] shr_adiv2; + // Temporary debug wires. + reg [1 : 0] state_trace; + reg [1 : 0] mux_trace; //---------------------------------------------------------------- // Concurrent connectivity for ports etc. //---------------------------------------------------------------- - assign opa_addr = opa_addr_reg; - assign opb_addr = opb_addr_reg; - assign opm_addr = opm_addr_reg; + assign length_m1 = length - 1'b1; - assign result_addr = result_addr_reg; - assign result_data = result_data_reg; + assign opa_addr = tmp_opa_addr; + assign opb_addr = b_word_index; + assign opm_addr = word_index_reg; + + assign result_addr = word_index_prev_reg; + assign result_data = s_mem_read_data; assign result_we = tmp_result_we; assign ready = ready_reg; @@ -173,55 +199,38 @@ module montprod( //---------------------------------------------------------------- // Instantions //---------------------------------------------------------------- - - blockmem1r1w s_mem( - .clk(clk), - .read_addr(s_mem_addr), - .read_data(s_mem_read_data), - .wr(s_mem_we), - .write_addr(s_mem_wr_addr), - .write_data(s_mem_new) - ); - - - adder32 s_adder_sa( - .a(s_mem_read_data), - .b(opa_data), - .carry_in(add_carry_in_sa), - .sum(add_result_sa), - .carry_out(add_carry_out_sa) - ); - - adder32 s_adder_sm( - .a(s_mem_read_data), - .b(opm_data), - .carry_in(add_carry_in_sm), - .sum(add_result_sm), - .carry_out(add_carry_out_sm) - ); - - shr32 shifter( - .a( s_mem_read_data ), - .carry_in( shr_carry_in ), - .adiv2( shr_adiv2 ), - .carry_out( shr_carry_out ) - ); - - always @* - begin : s_mux - case (s_mux_reg) - SMUX_0: - s_mem_new = 32'b0; - SMUX_ADD_SA: - s_mem_new = add_result_sa; - SMUX_ADD_SM: - s_mem_new = add_result_sm; - SMUX_SHR: - s_mem_new = shr_adiv2; - endcase - if (DEBUG) - $display("SMUX%x: %x", s_mux_reg, s_mem_new); - end + blockmem1r1w #(.OPW(OPW), .ADW(ADW)) s_mem( + .clk(clk), + .read_addr(s_mem_read_addr), + .read_data(s_mem_read_data), + .wr(s_mem_we_reg), + .write_addr(s_mem_write_addr), + .write_data(s_mem_write_data) + ); + + adder #(.OPW(OPW)) s_adder_sm( + .a(muxed_s_mem_read_data), + .b(opm_data), + .carry_in(add_carry_in_sm_reg), + .sum(add_result_sm), + .carry_out(add_carry_out_sm) + ); + + + adder #(.OPW(OPW)) s_adder_sa( + .a(sa_adder_data_in), + .b(opa_data), + .carry_in(add_carry_in_sa_reg), + .sum(add_result_sa), + .carry_out(add_carry_out_sa) + ); + + shr #(.OPW(OPW)) shifter( + .a(shr_data_in), + .carry_in(shr_carry_in_reg), + .adiv2(shr_data_out), + .carry_out(shr_carry_out) + ); //---------------------------------------------------------------- @@ -235,205 +244,246 @@ module montprod( begin : reg_update if (!reset_n) begin - ready_reg <= 1'b0; - loop_counter <= 13'h0; - word_index <= 8'h0; - word_index_prev <= 8'h0; - add_carry_in_sa <= 1'b0; - add_carry_in_sm <= 1'b0; - shr_carry_in <= 1'b0; - montprod_ctrl_reg <= CTRL_IDLE; - b_reg <= 1'b0; - q_reg <= 1'b0; - s_mux_reg <= SMUX_0; - s_mem_we <= 1'b0; - s_mem_wr_addr <= 8'h0; - B_bit_index_reg <= 5'h0; + test_reg <= 1'b1; + ready_reg <= 1'b1; + loop_ctr_reg <= 13'h0; + word_index_reg <= {ADW{1'b0}}; + word_index_prev_reg <= {ADW{1'b0}}; + add_carry_in_sa_reg <= 1'b0; + add_carry_in_sm_reg <= 1'b0; + shr_data_out_reg <= {(OPW - 1){1'b0}}; + shr_carry_in_reg <= 1'b0; + b_reg <= 1'b0; + q_reg <= 1'b0; + s_mux_reg <= SMUX_ZERO; + s_mem_we_reg <= 1'b0; + s_mem_read_addr_reg <= {ADW{1'b0}}; + b_bit_index_reg <= {(13 - ADW){1'b0}}; + first_iteration_reg <= 1'b0; + montprod_ctrl_reg <= CTRL_IDLE; end else begin - if (ready_we) - ready_reg <= ready_new; + test_reg <= test_new; - if (montprod_ctrl_we) - begin - montprod_ctrl_reg <= montprod_ctrl_new; - end + s_mem_read_addr_reg <= s_mem_read_addr; + s_mem_we_reg <= s_mem_we_new; + s_mux_reg <= s_mux_new; - s_mem_wr_addr <= s_mem_addr; + word_index_prev_reg <= word_index_reg; - s_mem_we <= s_mem_we_new; + shr_carry_in_reg <= shr_carry_in_new; + add_carry_in_sa_reg <= add_carry_in_sa_new; + add_carry_in_sm_reg <= add_carry_in_sm_new; + shr_data_out_reg <= shr_data_out[(OPW - 2) : 0]; - word_index <= word_index_new; - word_index_prev <= word_index; + if (word_index_we) + word_index_reg <= word_index_new; - loop_counter <= loop_counter_new; - shr_carry_in <= shr_carry_new; - add_carry_in_sa <= add_carry_new_sa; - add_carry_in_sm <= add_carry_new_sm; + if (first_iteration_we) + first_iteration_reg <= first_iteration_new; - B_bit_index_reg <= B_bit_index; - q_reg <= q; - b_reg <= b; + if (b_bit_index_we) + b_bit_index_reg <= b_bit_index_new; - s_mux_reg <= s_mux_new; - end - end // reg_update + if (bq_we) + begin + b_reg <= b_new; + q_reg <= q_new; + end - always @* - begin : bq_process - b = b_reg; - q = q_reg; - if (montprod_ctrl_reg == CTRL_LOOP_BQ) - begin - b = opb_data[ B_bit_index_reg ]; - //opa_addr will point to length-1 to get A LSB. - //s_read_addr will point to length-1 - q = s_mem_read_data[0] ^ (opa_data[0] & b); - if (DEBUG) - $display("s_mem_read_data: %x opa_data %x b %x q %x B_bit_index_reg %x", s_mem_read_data, opa_data, b, q, B_bit_index_reg); + if (ready_we) + ready_reg <= ready_new; + + if (loop_ctr_we) + loop_ctr_reg <= loop_ctr_new; + + if (montprod_ctrl_we) + begin + montprod_ctrl_reg <= montprod_ctrl_new; + end end - end + end // reg_update //---------------------------------------------------------------- - // Process for iterating the loop counter and setting related B indexes + // s_logic + // + // Logic to calculate S memory updates including address + // and write enable. This is the main montprod datapath. //---------------------------------------------------------------- always @* - begin : loop_counter_process - loop_counter_new = loop_counter; - length_m1 = length - 1'b1; - loop_counter_dec = loop_counter - 1'b1; - B_word_index = loop_counter[12:5]; - B_bit_index = B_bit_index_reg; + begin : s_logic + shr_carry_in_new = 1'b0; + muxed_s_mem_read_data = {OPW{1'b0}}; + sa_adder_data_in = {OPW{1'b0}}; + add_carry_in_sa_new = 1'b0; + add_carry_in_sm_new = 1'b0; + s_mem_read_addr = word_index_reg; + s_mem_write_addr = s_mem_read_addr_reg; + s_mem_write_data = {OPW{1'b0}}; + s_mem_we_new = 1'b0; + state_trace = 0; + mux_trace = 0; + tmp_s_mem_write_data = {OPW{1'b0}}; + test_new = 1'b0; case (montprod_ctrl_reg) - CTRL_LOOP_INIT: - loop_counter_new = {length, 5'b00000} - 1'b1; - CTRL_LOOP_ITER: begin - B_word_index = loop_counter[12:5]; - B_bit_index = 5'h1f - loop_counter[4:0]; + s_mem_read_addr = length_m1; end - CTRL_L_STALLPIPE_D2: - loop_counter_new = loop_counter_dec; - - default: - loop_counter_new = loop_counter; - endcase - end - - - //---------------------------------------------------------------- - // prodcalc - //---------------------------------------------------------------- - always @* - begin : prodcalc - - case (montprod_ctrl_reg) - CTRL_LOOP_ITER: - //q = (s[length-1] ^ A[length-1]) & 1; - opa_addr_reg = length_m1; - - default: - opa_addr_reg = word_index; - endcase + CTRL_CALC_ADD: + begin + //s = (s + q*M + b*A) >>> 1;, if(b==1) S+= A. Takes (1..length) cycles. + s_mem_we_new = b_reg | q_reg | first_iteration_reg; + state_trace = 1; + test_new = 1'b1; + end - opb_addr_reg = B_word_index; - opm_addr_reg = word_index; + CTRL_CALC_SDIV2: + begin + //s = (s + q*M + b*A) >>> 1; s>>=1. Takes (1..length) cycles. + s_mem_we_new = 1'b1; + end - case (montprod_ctrl_reg) - CTRL_LOOP_ITER: - s_mem_addr = length_m1; default: - s_mem_addr = word_index; + begin + end endcase + case (s_mux_reg) + SMUX_ADD: + begin + mux_trace = 1; + if (first_iteration_reg) + muxed_s_mem_read_data = {OPW{1'b0}}; + else + muxed_s_mem_read_data = s_mem_read_data; - result_addr_reg = word_index_prev; - result_data_reg = s_mem_read_data; - case (montprod_ctrl_reg) - CTRL_EMIT_S: - tmp_result_we = 1'b1; - default: - tmp_result_we = 1'b0; - endcase + if (q_reg) + sa_adder_data_in = add_result_sm; + else + sa_adder_data_in = muxed_s_mem_read_data; - if (reset_word_index_LSW == 1'b1) - word_index_new = length_m1; - else if (reset_word_index_MSW == 1'b1) - word_index_new = 8'h0; - else if (montprod_ctrl_reg == CTRL_L_CALC_SDIV2) - word_index_new = word_index + 1'b1; - else - word_index_new = word_index - 1'b1; - end // prodcalc + if (b_reg) + tmp_s_mem_write_data = add_result_sa; + else if (q_reg) + tmp_s_mem_write_data = add_result_sm; + else if (first_iteration_reg) + tmp_s_mem_write_data = {OPW{1'b0}}; + s_mem_write_data = tmp_s_mem_write_data; + add_carry_in_sa_new = add_carry_out_sa; + add_carry_in_sm_new = add_carry_out_sm; - always @* - begin : s_writer_process - shr_carry_new = 1'b0; - s_mux_new = SMUX_0; - s_mem_we_new = 1'b0; - case (montprod_ctrl_reg) - CTRL_INIT_S: - begin - s_mem_we_new = 1'b1; - s_mux_new = SMUX_0; // write 0 + // Experimental integration of shift in add. + shr_data_in = tmp_s_mem_write_data; + shifted_s_mem_write_data = {shr_carry_out, shr_data_out_reg}; end - CTRL_L_CALC_SM: - begin - //s = (s + q*M + b*A) >>> 1;, if(q==1) S+= M. Takes (1..length) cycles. - s_mem_we_new = q_reg; - s_mux_new = SMUX_ADD_SM; - end - - CTRL_L_CALC_SA: - begin - //s = (s + q*M + b*A) >>> 1;, if(b==1) S+= A. Takes (1..length) cycles. - s_mem_we_new = b_reg; - s_mux_new = SMUX_ADD_SA; - end - CTRL_L_CALC_SDIV2: + SMUX_SHR: begin - //s = (s + q*M + b*A) >>> 1; s>>=1. Takes (1..length) cycles. - s_mux_new = SMUX_SHR; - s_mem_we_new = 1'b1; + shr_data_in = s_mem_read_data; + s_mem_write_data = shr_data_out; + shr_carry_in_new = shr_carry_out; end default: begin end endcase + end // s_logic - add_carry_new_sa = 1'b0; - add_carry_new_sm = 1'b0; - case (s_mux_reg) - SMUX_ADD_SM: - add_carry_new_sm = add_carry_out_sm; + //---------------------------------------------------------------- + // bq + // + // Extract b and q bits. + // b: current bit of B used. + // q = (s - b * A) & 1 + // update the b bit and word indices based on loop counter. + //---------------------------------------------------------------- + always @* + begin : bq + b_new = opb_data[b_bit_index_reg]; - SMUX_ADD_SA: - add_carry_new_sa = add_carry_out_sa; + if (first_iteration_reg) + q_new = 1'b0 ^ (opa_data[0] & b_new); + else + q_new = s_mem_read_data[0] ^ (opa_data[0] & b_new); - SMUX_SHR: - shr_carry_new = shr_carry_out; + // B_bit_index = 5'h1f - loop_counter[4:0]; + b_bit_index_new = ((2**(13 - ADW)) - 1'b1) - loop_ctr_reg[(13 - ADW - 1) : 0]; + b_word_index = loop_ctr_reg[12 : (13 - ADW)]; + end // bq - default: - begin - end - endcase - end // prodcalc + //---------------------------------------------------------------- + // word_index + // + // Logic that implements the word index used to drive + // addresses for operands. + //---------------------------------------------------------------- + always @* + begin : word_index + word_index_new = {ADW{1'b0}}; + word_index_we = 1'b0; + + if (reset_word_index_lsw) + begin + word_index_new = length_m1; + word_index_we = 1'b1; + end + + if (reset_word_index_msw) + begin + word_index_new = {ADW{1'b0}}; + word_index_we = 1'b1; + end + + if (inc_word_index) + begin + word_index_new = word_index_reg + 1'b1; + word_index_we = 1'b1; + end + + if (dec_word_index) + begin + word_index_new = word_index_reg - 1'b1; + word_index_we = 1'b1; + end + end // word_index + + + //---------------------------------------------------------------- + // loop_ctr + // Logic for updating the loop counter. + //---------------------------------------------------------------- + always @* + begin : loop_ctr + loop_ctr_new = 13'h0; + loop_ctr_we = 1'b0; + + if (loop_ctr_set) + begin + loop_ctr_new = {length, {(13 - ADW){1'b0}}} - 1'b1; + loop_ctr_we = 1'b1; + end + + if (loop_ctr_dec) + begin + loop_ctr_new = loop_ctr_reg - 1'b1; + loop_ctr_we = 1'b1; + end + end //---------------------------------------------------------------- @@ -443,146 +493,131 @@ module montprod( //---------------------------------------------------------------- always @* begin : montprod_ctrl - ready_new = 1'b0; - ready_we = 1'b0; - montprod_ctrl_new = CTRL_IDLE; - montprod_ctrl_we = 1'b0; + ready_new = 1'b0; + ready_we = 1'b0; + loop_ctr_set = 1'b0; + loop_ctr_dec = 1'b0; + b_bit_index_we = 1'b0; + bq_we = 1'b0; + s_mux_new = SMUX_ZERO; + dec_word_index = 1'b0; + inc_word_index = 1'b0; + reset_word_index_lsw = 1'b0; + reset_word_index_msw = 1'b0; + first_iteration_new = 1'b0; + first_iteration_we = 1'b0; + tmp_opa_addr = word_index_reg; + tmp_result_we = 1'b0; + montprod_ctrl_new = CTRL_IDLE; + montprod_ctrl_we = 1'b0; - reset_word_index_LSW = 1'b0; - reset_word_index_MSW = 1'b0; case (montprod_ctrl_reg) CTRL_IDLE: begin if (calculate) begin - ready_new = 1'b0; - ready_we = 1'b1; - montprod_ctrl_new = CTRL_INIT_S; - montprod_ctrl_we = 1'b1; - reset_word_index_LSW = 1'b1; - end - else - begin - ready_new = 1'b1; - ready_we = 1'b1; + first_iteration_new = 1'b1; + first_iteration_we = 1'b1; + ready_new = 1'b0; + ready_we = 1'b1; + reset_word_index_lsw = 1'b1; + loop_ctr_set = 1'b1; + montprod_ctrl_new = CTRL_LOOP_ITER; + montprod_ctrl_we = 1'b1; end end - CTRL_INIT_S: - begin - if (word_index == 8'h0) - begin - montprod_ctrl_new = CTRL_LOOP_INIT; - montprod_ctrl_we = 1'b1; - end - end - - - CTRL_LOOP_INIT: - begin - montprod_ctrl_new = CTRL_LOOP_ITER; - montprod_ctrl_we = 1'b1; - end - //calculate q = (s - b * A) & 1;. // Also abort loop if done. CTRL_LOOP_ITER: begin - reset_word_index_LSW = 1'b1; - montprod_ctrl_new = CTRL_LOOP_BQ; - montprod_ctrl_we = 1'b1; + tmp_opa_addr = length_m1; + b_bit_index_we = 1'b1; + montprod_ctrl_new = CTRL_LOOP_BQ; + montprod_ctrl_we = 1'b1; end CTRL_LOOP_BQ: begin - reset_word_index_LSW = 1'b1; - montprod_ctrl_new = CTRL_L_CALC_SM; - montprod_ctrl_we = 1'b1; + reset_word_index_lsw = 1'b1; + bq_we = 1'b1; + montprod_ctrl_new = CTRL_CALC_ADD; + montprod_ctrl_we = 1'b1; end - CTRL_L_CALC_SM: + CTRL_CALC_ADD: begin - if (word_index == 8'h0) + s_mux_new = SMUX_ADD; + + if (word_index_reg == 0) begin - reset_word_index_LSW = 1'b1; - montprod_ctrl_we = 1'b1; - montprod_ctrl_new = CTRL_L_STALLPIPE_SM; + reset_word_index_lsw = 1'b1; + montprod_ctrl_new = CTRL_STALLPIPE_ADD; + montprod_ctrl_we = 1'b1; end - end - - CTRL_L_STALLPIPE_SM: - begin - montprod_ctrl_new = CTRL_L_CALC_SA; - montprod_ctrl_we = 1'b1; - reset_word_index_LSW = 1'b1; - end - - CTRL_L_CALC_SA: - begin - if (word_index == 8'h0) + else begin - reset_word_index_LSW = 1'b1; - montprod_ctrl_new = CTRL_L_STALLPIPE_SA; - montprod_ctrl_we = 1'b1; + dec_word_index = 1'b1; end end - CTRL_L_STALLPIPE_SA: + CTRL_STALLPIPE_ADD: begin - montprod_ctrl_new = CTRL_L_CALC_SDIV2; - montprod_ctrl_we = 1'b1; - reset_word_index_MSW = 1'b1; + first_iteration_new = 1'b0; + first_iteration_we = 1'b1; + reset_word_index_msw = 1'b1; + montprod_ctrl_new = CTRL_CALC_SDIV2; + montprod_ctrl_we = 1'b1; end - CTRL_L_CALC_SDIV2: + CTRL_CALC_SDIV2: begin - if (word_index == length_m1) + s_mux_new = SMUX_SHR; + + if (word_index_reg == length_m1) begin - montprod_ctrl_new = CTRL_L_STALLPIPE_D2; - montprod_ctrl_we = 1'b1; - //reset_word_index = 1'b1; + montprod_ctrl_new = CTRL_STALLPIPE_SDIV2; + montprod_ctrl_we = 1'b1; end + else + inc_word_index = 1'b1; end - CTRL_L_STALLPIPE_D2: + CTRL_STALLPIPE_SDIV2: begin - montprod_ctrl_new = CTRL_LOOP_ITER; //loop - montprod_ctrl_we = 1'b1; - reset_word_index_LSW = 1'b1; - if (loop_counter == 0) + loop_ctr_dec = 1'b1; + montprod_ctrl_new = CTRL_LOOP_ITER; + montprod_ctrl_we = 1'b1; + reset_word_index_lsw = 1'b1; + + if (loop_ctr_reg == 0) begin montprod_ctrl_new = CTRL_L_STALLPIPE_ES; - montprod_ctrl_we = 1'b1; + montprod_ctrl_we = 1'b1; end end CTRL_L_STALLPIPE_ES: begin montprod_ctrl_new = CTRL_EMIT_S; - montprod_ctrl_we = 1'b1; - //reset_word_index_LSW = 1'b1; + montprod_ctrl_we = 1'b1; end CTRL_EMIT_S: begin - if (DEBUG) - $display("EMIT_S word_index: %d", word_index); - if (word_index_prev == 8'h0) + dec_word_index = 1'b1; + tmp_result_we = 1'b1; + + if (word_index_prev_reg == 0) begin - montprod_ctrl_new = CTRL_DONE; + ready_new = 1'b1; + ready_we = 1'b1; + montprod_ctrl_new = CTRL_IDLE; montprod_ctrl_we = 1'b1; end end - CTRL_DONE: - begin - ready_new = 1'b1; - ready_we = 1'b1; - montprod_ctrl_new = CTRL_IDLE; - montprod_ctrl_we = 1'b1; - end - default: begin end diff --git a/src/rtl/residue.v b/src/rtl/residue.v index 3fa1666..f3d114c 100644 --- a/src/rtl/residue.v +++ b/src/rtl/residue.v @@ -45,119 +45,109 @@ // //====================================================================== -module residue( - input wire clk, - input wire reset_n, +module residue #(parameter OPW = 32, parameter ADW = 8) + ( + input wire clk, + input wire reset_n, - input wire calculate, - output wire ready, + input wire calculate, + output wire ready, - input wire [14 : 0] nn, //MAX(2*N)=8192*2 (14 bit) - input wire [07 : 0] length, + input wire [14 : 0] nn, //MAX(2*N)=8192*2 (14 bit) + input wire [(ADW - 1) : 0] length, - output wire [07 : 0] opa_rd_addr, - input wire [31 : 0] opa_rd_data, - output wire [07 : 0] opa_wr_addr, - output wire [31 : 0] opa_wr_data, - output wire opa_wr_we, + output wire [(ADW - 1) : 0] opa_rd_addr, + input wire [(OPW - 1) : 0] opa_rd_data, + output wire [(ADW - 1) : 0] opa_wr_addr, + output wire [(OPW - 1) : 0] opa_wr_data, + output wire opa_wr_we, - output wire [07 : 0] opm_addr, - input wire [31 : 0] opm_data + output wire [(ADW - 1) : 0] opm_addr, + input wire [(OPW - 1) : 0] opm_data + ); -); - -//---------------------------------------------------------------- -// Internal constant and parameter definitions. -//---------------------------------------------------------------- + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- + localparam CTRL_IDLE = 4'h0; + localparam CTRL_INIT = 4'h1; + localparam CTRL_INIT_STALL = 4'h2; + localparam CTRL_SHL = 4'h3; + localparam CTRL_SHL_STALL = 4'h4; + localparam CTRL_COMPARE = 4'h5; + localparam CTRL_COMPARE_STALL = 4'h6; + localparam CTRL_SUB = 4'h7; + localparam CTRL_SUB_STALL = 4'h8; + localparam CTRL_LOOP = 4'h9; -// m_residue_2_2N_array( N, M, Nr) -// Nr = 00...01 ; Nr = 1 == 2**(2N-2N) -// for (int i = 0; i < 2 * N; i++) -// Nr = Nr shift left 1 -// if (Nr less than M) continue; -// Nr = Nr - M -// return Nr -// -localparam CTRL_IDLE = 4'h0; -localparam CTRL_INIT = 4'h1; // Nr = 00...01 ; Nr = 1 == 2**(2N-2N) -localparam CTRL_INIT_STALL = 4'h2; -localparam CTRL_SHL = 4'h3; // Nr = Nr shift left 1 -localparam CTRL_SHL_STALL = 4'h4; -localparam CTRL_COMPARE = 4'h5; //if (Nr less than M) continue; -localparam CTRL_COMPARE_STALL = 4'h6; -localparam CTRL_SUB = 4'h7; //Nr = Nr - M -localparam CTRL_SUB_STALL = 4'h8; -localparam CTRL_LOOP = 4'h9; //for (int i = 0; i < 2 * N; i++) - -//---------------------------------------------------------------- -// Registers including update variables and write enable. -//---------------------------------------------------------------- - -reg [07 : 0] opa_rd_addr_reg; -reg [07 : 0] opa_wr_addr_reg; -reg [31 : 0] opa_wr_data_reg; -reg opa_wr_we_reg; -reg [07 : 0] opm_addr_reg; -reg ready_reg; -reg ready_new; -reg ready_we; -reg [03 : 0] residue_ctrl_reg; -reg [03 : 0] residue_ctrl_new; -reg residue_ctrl_we; -reg reset_word_index; -reg reset_n_counter; -reg [14 : 0] loop_counter_1_to_nn_reg; //for i = 1 to nn (2*N) -reg [14 : 0] loop_counter_1_to_nn_new; -reg loop_counter_1_to_nn_we; -reg [14 : 0] nn_reg; -reg nn_we; -reg [07 : 0] length_m1_reg; -reg [07 : 0] length_m1_new; -reg length_m1_we; -reg [07 : 0] word_index_reg; -reg [07 : 0] word_index_new; -reg word_index_we; - -reg [31 : 0] one_data; -wire [31 : 0] sub_data; -wire [31 : 0] shl_data; -reg sub_carry_in_new; -reg sub_carry_in_reg; -wire sub_carry_out; -reg shl_carry_in_new; -reg shl_carry_in_reg; -wire shl_carry_out; - -//---------------------------------------------------------------- -// Concurrent connectivity for ports etc. -//---------------------------------------------------------------- -assign opa_rd_addr = opa_rd_addr_reg; -assign opa_wr_addr = opa_wr_addr_reg; -assign opa_wr_data = opa_wr_data_reg; -assign opa_wr_we = opa_wr_we_reg; -assign opm_addr = opm_addr_reg; -assign ready = ready_reg; + //---------------------------------------------------------------- + // Registers including update variables and write enable. + //---------------------------------------------------------------- + reg [(ADW - 1) : 0] opa_rd_addr_reg; + reg [(ADW - 1) : 0] opa_wr_addr_reg; + reg [(OPW - 1) : 0] opa_wr_data_reg; + reg opa_wr_we_reg; + reg [(ADW - 1) : 0] opm_addr_reg; + reg ready_reg; + reg ready_new; + reg ready_we; + reg [03 : 0] residue_ctrl_reg; + reg [03 : 0] residue_ctrl_new; + reg residue_ctrl_we; + reg reset_word_index; + reg reset_n_counter; + reg [14 : 0] loop_counter_1_to_nn_reg; //for i = 1 to nn (2*N) + reg [14 : 0] loop_counter_1_to_nn_new; + reg loop_counter_1_to_nn_we; + reg [14 : 0] nn_reg; + reg nn_we; + reg [(ADW - 1) : 0] length_m1_reg; + reg [(ADW - 1) : 0] length_m1_new; + reg length_m1_we; + reg [(ADW - 1) : 0] word_index_reg; + reg [(ADW - 1) : 0] word_index_new; + reg word_index_we; + + reg [(OPW - 1) : 0] one_data; + wire [(OPW - 1) : 0] sub_data; + wire [(OPW - 1) : 0] shl_data; + reg sub_carry_in_new; + reg sub_carry_in_reg; + wire sub_carry_out; + reg shl_carry_in_new; + reg shl_carry_in_reg; + wire shl_carry_out; //---------------------------------------------------------------- - // Instantions + // Concurrent connectivity for ports etc. //---------------------------------------------------------------- - adder32 subcmp( - .a(opa_rd_data), - .b( ~ opm_data), - .carry_in(sub_carry_in_reg), - .sum(sub_data), - .carry_out(sub_carry_out) - ); + assign opa_rd_addr = opa_rd_addr_reg; + assign opa_wr_addr = opa_wr_addr_reg; + assign opa_wr_data = opa_wr_data_reg; + assign opa_wr_we = opa_wr_we_reg; + assign opm_addr = opm_addr_reg; + assign ready = ready_reg; - shl32 shl( - .a(opa_rd_data), - .carry_in(shl_carry_in_reg), - .amul2(shl_data), - .carry_out(shl_carry_out) - ); + //---------------------------------------------------------------- + // Instantions + //---------------------------------------------------------------- + adder #(.OPW(OPW)) add_inst( + .a(opa_rd_data), + .b( ~ opm_data), + .carry_in(sub_carry_in_reg), + .sum(sub_data), + .carry_out(sub_carry_out) + ); + + shl #(.OPW(OPW)) shl_inst( + .a(opa_rd_data), + .carry_in(shl_carry_in_reg), + .amul2(shl_data), + .carry_out(shl_carry_out) + ); //---------------------------------------------------------------- @@ -167,14 +157,14 @@ assign ready = ready_reg; begin if (!reset_n) begin - residue_ctrl_reg <= CTRL_IDLE; - word_index_reg <= 8'h0; - length_m1_reg <= 8'h0; - nn_reg <= 15'h0; + residue_ctrl_reg <= CTRL_IDLE; + word_index_reg <= {ADW{1'b1}}; + length_m1_reg <= {ADW{1'b1}}; + nn_reg <= 15'h0; loop_counter_1_to_nn_reg <= 15'h0; - ready_reg <= 1'b1; - sub_carry_in_reg <= 1'b0; - shl_carry_in_reg <= 1'b0; + ready_reg <= 1'b1; + sub_carry_in_reg <= 1'b0; + shl_carry_in_reg <= 1'b0; end else begin @@ -229,22 +219,24 @@ assign ready = ready_reg; loop_counter_1_to_nn_we = 1'b1; end + //---------------------------------------------------------------- // implements looping over words in a multiword operation //---------------------------------------------------------------- always @* begin : word_index_process - word_index_new = word_index_reg - 8'h1; + word_index_new = word_index_reg - 1'b1; word_index_we = 1'b1; if (reset_word_index) word_index_new = length_m1_reg; if (residue_ctrl_reg == CTRL_IDLE) - word_index_new = length_m1_new; //reduce a pipeline stage with early read - + //reduce a pipeline stage with early read + word_index_new = length_m1_new; end + //---------------------------------------------------------------- // writer process. implements: // Nr = 00...01 ; Nr = 1 == 2**(2N-2N) @@ -299,6 +291,7 @@ assign ready = ready_reg; opm_addr_reg = word_index_new; end + //---------------------------------------------------------------- // carry process. "Ripple carry awesomeness!" //---------------------------------------------------------------- @@ -321,6 +314,7 @@ assign ready = ready_reg; endcase end + //---------------------------------------------------------------- // Nr = 00...01 ; Nr = 1 == 2**(2N-2N) //---------------------------------------------------------------- @@ -329,128 +323,130 @@ assign ready = ready_reg; one_data = 32'h0; if (residue_ctrl_reg == CTRL_INIT) if (word_index_reg == length_m1_reg) - one_data = 32'h1; + one_data = {{(OPW - 1){1'b0}}, 1'b1}; end -//---------------------------------------------------------------- -// residue_ctrl -// -// Control FSM for residue -//---------------------------------------------------------------- -always @* - begin : residue_ctrl - ready_new = 1'b0; - ready_we = 1'b0; - - residue_ctrl_new = CTRL_IDLE; - residue_ctrl_we = 1'b0; - reset_word_index = 1'b0; - reset_n_counter = 1'b0; + //---------------------------------------------------------------- + // residue_ctrl + // + // Control FSM for residue + //---------------------------------------------------------------- + always @* + begin : residue_ctrl + ready_new = 1'b0; + ready_we = 1'b0; + reset_word_index = 1'b0; + reset_n_counter = 1'b0; + length_m1_new = length - 1'b1; + length_m1_we = 1'b0; + nn_we = 1'b0; + residue_ctrl_new = CTRL_IDLE; + residue_ctrl_we = 1'b0; - length_m1_new = length - 8'h1; - length_m1_we = 1'b0; + case (residue_ctrl_reg) + CTRL_IDLE: + if (calculate) + begin + ready_new = 1'b0; + ready_we = 1'b1; + reset_word_index = 1'b1; + length_m1_we = 1'b1; + nn_we = 1'b1; + residue_ctrl_new = CTRL_INIT; + residue_ctrl_we = 1'b1; + end - nn_we = 1'b0; + // Nr = 00...01 ; Nr = 1 == 2**(2N-2N) + CTRL_INIT: + if (word_index_reg == 0) + begin + residue_ctrl_new = CTRL_INIT_STALL; + residue_ctrl_we = 1'b1; + end - case (residue_ctrl_reg) - CTRL_IDLE: - if (calculate) + CTRL_INIT_STALL: begin - ready_new = 1'b0; - ready_we = 1'b1; - residue_ctrl_new = CTRL_INIT; - residue_ctrl_we = 1'b1; reset_word_index = 1'b1; - length_m1_we = 1'b1; - nn_we = 1'b1; + reset_n_counter = 1'b1; + residue_ctrl_new = CTRL_SHL; + residue_ctrl_we = 1'b1; end - CTRL_INIT: - if (word_index_reg == 8'h0) + // Nr = Nr shift left 1 + CTRL_SHL: begin - residue_ctrl_new = CTRL_INIT_STALL; - residue_ctrl_we = 1'b1; + if (word_index_reg == 0) + begin + residue_ctrl_new = CTRL_SHL_STALL; + residue_ctrl_we = 1'b1; + end end - CTRL_INIT_STALL: - begin - reset_word_index = 1'b1; - reset_n_counter = 1'b1; - residue_ctrl_new = CTRL_SHL; - residue_ctrl_we = 1'b1; - end - - CTRL_SHL: - begin - if (word_index_reg == 8'h0) + CTRL_SHL_STALL: begin - residue_ctrl_new = CTRL_SHL_STALL; + reset_word_index = 1'b1; + residue_ctrl_new = CTRL_COMPARE; residue_ctrl_we = 1'b1; end - end - CTRL_SHL_STALL: - begin - reset_word_index = 1'b1; - residue_ctrl_new = CTRL_COMPARE; - residue_ctrl_we = 1'b1; - end + //if (Nr less than M) continue + CTRL_COMPARE: + if (word_index_reg == 0) + begin + residue_ctrl_new = CTRL_COMPARE_STALL; + residue_ctrl_we = 1'b1; + end - CTRL_COMPARE: - if (word_index_reg == 8'h0) + CTRL_COMPARE_STALL: begin - residue_ctrl_new = CTRL_COMPARE_STALL; + reset_word_index = 1'b1; residue_ctrl_we = 1'b1; + if (sub_carry_in_reg == 1'b1) + //TODO: Bug! detect CF to detect less than, but no detect ZF to detect equal to. + residue_ctrl_new = CTRL_SUB; + else + residue_ctrl_new = CTRL_LOOP; end - CTRL_COMPARE_STALL: - begin - reset_word_index = 1'b1; - residue_ctrl_we = 1'b1; - if (sub_carry_in_reg == 1'b1) - //TODO: Bug! detect CF to detect less than, but no detect ZF to detect equal to. - residue_ctrl_new = CTRL_SUB; - else - residue_ctrl_new = CTRL_LOOP; - end + //Nr = Nr - M + CTRL_SUB: + if (word_index_reg == 0) + begin + residue_ctrl_new = CTRL_SUB_STALL; + residue_ctrl_we = 1'b1; + end - CTRL_SUB: - if (word_index_reg == 8'h0) + CTRL_SUB_STALL: begin - residue_ctrl_new = CTRL_SUB_STALL; + residue_ctrl_new = CTRL_LOOP; residue_ctrl_we = 1'b1; end - CTRL_SUB_STALL: - begin - residue_ctrl_new = CTRL_LOOP; - residue_ctrl_we = 1'b1; - end - - CTRL_LOOP: - begin - if (loop_counter_1_to_nn_reg == nn_reg) - begin - ready_new = 1'b1; - ready_we = 1'b1; - residue_ctrl_new = CTRL_IDLE; - residue_ctrl_we = 1'b1; - end - else - begin - reset_word_index = 1'b1; - residue_ctrl_new = CTRL_SHL; - residue_ctrl_we = 1'b1; - end - end + //for (int i = 0; i < 2 * N; i++) + CTRL_LOOP: + begin + if (loop_counter_1_to_nn_reg == nn_reg) + begin + ready_new = 1'b1; + ready_we = 1'b1; + residue_ctrl_new = CTRL_IDLE; + residue_ctrl_we = 1'b1; + end + else + begin + reset_word_index = 1'b1; + residue_ctrl_new = CTRL_SHL; + residue_ctrl_we = 1'b1; + end + end - default: - begin - end + default: + begin + end - endcase - end + endcase + end endmodule // residue diff --git a/src/rtl/shl32.v b/src/rtl/shl.v index 42521fd..bed83e8 100644 --- a/src/rtl/shl32.v +++ b/src/rtl/shl.v @@ -1,11 +1,12 @@ //====================================================================== // -// shl32.v -// ------- -// 32bit left shift with carry in / carry out +// shl.v +// ----- +// One bit left shift of words with carry in and carry out. Used in +// the residue module of the modexp core. // // -// Author: Peter Magnusson +// Author: Peter Magnusson, Joachim Strömbergson // Copyright (c) 2015, NORDUnet A/S All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -36,18 +37,20 @@ // //====================================================================== -module shl32( - input wire [31 : 0] a, - input wire carry_in, - output wire [31 : 0] amul2, - output wire carry_out - ); +module shl #(parameter OPW = 32) + ( + input wire [(OPW - 1) : 0] a, + input wire carry_in, - assign amul2 = {a[30 : 0], carry_in}; - assign carry_out = a[31]; + output wire [(OPW - 1) : 0] amul2, + output wire carry_out + ); -endmodule // shl32 + assign amul2 = {a[(OPW - 2) : 0], carry_in}; + assign carry_out = a[(OPW - 1)]; + +endmodule // shl //====================================================================== -// EOF shl32.v +// EOF shl.v //====================================================================== diff --git a/src/rtl/shr32.v b/src/rtl/shr.v index 66b15c3..40ef111 100644 --- a/src/rtl/shr32.v +++ b/src/rtl/shr.v @@ -2,10 +2,11 @@ // // shr32.v // ------- -// 32bit right shift with carry in / carry out. +// One bit right shift with carry in and carry out. +// Used in the montprod module of the modexp core. // // -// Author: Peter Magnusson +// Author: Peter Magnusson, Joachim Strömbergson // Copyright (c) 2015, NORDUnet A/S All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -36,18 +37,20 @@ // //====================================================================== -module shr32( - input wire [31 : 0] a, - input wire carry_in, - output wire [31 : 0] adiv2, - output wire carry_out - ); +module shr #(parameter OPW = 32) + ( + input wire [(OPW - 1) : 0] a, + input wire carry_in, - assign adiv2 = {carry_in, a[31 : 1]}; + output wire [(OPW - 1) : 0] adiv2, + output wire carry_out + ); + + assign adiv2 = {carry_in, a[(OPW - 1) : 1]}; assign carry_out = a[0]; -endmodule // shr32 +endmodule // shr //====================================================================== -// EOF shr32.v +// EOF shr.v //====================================================================== diff --git a/src/support/rtl/README.md b/src/support/rtl/README.md new file mode 100644 index 0000000..7ccd111 --- /dev/null +++ b/src/support/rtl/README.md @@ -0,0 +1,18 @@ +This directory contains support RTL code for the modexp core. The code +here is not directly part of the core RTL. + +montprod_wrapper.v + A simple wrapper to mux together inputs and outputs from the montprod + module. Used for test builds of versions of montprod with different + (64, 128,2 256 bits) operand widths which means that the interface + from the montprod can contain a huge number of bits and thus pins. + + +blockmem_rw32ptr_r64.v + A synchronous block memory with two separate ports and internal + address generator as used in the modex_core to implement the exponent, + modulus and message memories. This version sports a 64 bit wide data + port for core internal read access while the API facing interface uses + 32 bit wide data. When the modexp is set to use 64 bit operands, this + module should be included into the src/rtl dir to be used in the + modexp_core instantiation of the block memory. diff --git a/src/support/rtl/blockmem_rw32ptr_r64.v b/src/support/rtl/blockmem_rw32ptr_r64.v new file mode 100644 index 0000000..4f0315c --- /dev/null +++ b/src/support/rtl/blockmem_rw32ptr_r64.v @@ -0,0 +1,155 @@ +//====================================================================== +// +// blockmem_rw32ptr_r64.v +// ---------------------- +// Synchronous block memory with two separate ports. Port one is +// called the api port and port two is called the internal port. +// +// The api port contains its own address generator and the api port +// uses 32 bit data width. The address is automatically increased when +// the cs signal is set. The address is reset to zero when the rst +// signal is asserted. +// +// The second data port is called the internal port. The internal +// port uses 64 bit data width. +// +// and an internal port. The api port contains apointer +// and 32 bit data width. The internal port +// For port 1 the address is implicit and instead given by the +// internal pointer. +// Redistribution and use in source and binary forms, with or +// without modification, are permitted provided that the following +// conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. 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. +// +// 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 OWNER 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 blockmem_rw32ptr_r64( + input wire clk, + input wire reset_n, + + input wire api_rst, + input wire api_cs, + input wire api_wr, + input wire [31 : 0] api_wr_data, + output wire [31 : 0] api_rd_data, + + input wire [06 : 0] internal_addr, + output wire [63 : 0] internal_rd_data + ); + + + //---------------------------------------------------------------- + // Regs and memories. + //---------------------------------------------------------------- + reg [31 : 0] mem0 [0 : 127]; + wire mem0_we; + + reg [31 : 0] mem1 [0 : 127]; + wire mem1_we; + + reg [7 : 0] ptr_reg; + reg [7 : 0] ptr_new; + reg ptr_we; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + reg [31 : 0] tmp0_api_rd_data; + reg [31 : 0] tmp1_api_rd_data; + reg [31 : 0] tmp0_int_rd_data; + reg [31 : 0] tmp1_int_rd_data; + + + //---------------------------------------------------------------- + // Assignments. + //---------------------------------------------------------------- + assign api_rd_data = ptr_reg[0] ? tmp1_api_rd_data : tmp0_api_rd_data; + assign internal_rd_data = {tmp1_int_rd_data, tmp0_int_rd_data}; + + assign mem0_we = api_wr & ~ptr_reg[0]; + assign mem1_we = api_wr & ptr_reg[0]; + + + //---------------------------------------------------------------- + // mem0_updates + //---------------------------------------------------------------- + always @ (posedge clk) + begin : update_mem0 + if (mem0_we) + mem0[ptr_reg[7 : 1]] <= api_wr_data; + + tmp0_api_rd_data <= mem0[ptr_reg[7 : 1]]; + tmp0_int_rd_data <= mem0[internal_addr]; + end + + always @ (posedge clk) + begin : update_mem1 + if (mem1_we) + mem1[ptr_reg[7 : 1]] <= api_wr_data; + + tmp1_api_rd_data <= mem1[ptr_reg[7 : 1]]; + tmp1_int_rd_data <= mem1[internal_addr]; + end + + + //---------------------------------------------------------------- + // reg_update + //---------------------------------------------------------------- + always @ (posedge clk or negedge reset_n) + begin : reg_update + if (!reset_n) + ptr_reg <= 8'h00; + else + if (ptr_we) + ptr_reg <= ptr_new; + end + + + //---------------------------------------------------------------- + // ptr_logic + //---------------------------------------------------------------- + always @* + begin : ptr_logic + ptr_new = 8'h00; + ptr_we = 1'b0; + + if (api_rst) + begin + ptr_new = 8'h00; + ptr_we = 1'b1; + end + + if (api_cs) + begin + ptr_new = ptr_reg + 1'b1; + ptr_we = 1'b1; + end + end + +endmodule // blockmem_rw32ptr_r64 + +//====================================================================== +// EOF blockmem_rw32ptr_r64 +//====================================================================== diff --git a/src/support/rtl/montprod_wrapper.v b/src/support/rtl/montprod_wrapper.v new file mode 100644 index 0000000..e06e712 --- /dev/null +++ b/src/support/rtl/montprod_wrapper.v @@ -0,0 +1,153 @@ +//====================================================================== +// +// montprod_wrapper +// ---------------- +// Simple wrapper to allow us to build versions of montprod with +// different operand widths for performance testing. +// +// +// Author: Joachim Strombergson +// Copyright (c) 2015, NORDUnet A/S All rights reserved. +// +// 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 montprod_wrapper( + input wire clk, + input wire reset_n, + + input wire calculate, + output wire ready, + input wire [(ADW - 1) : 0] length, + + input wire [1 : 0] operand_select, + input wire [(OPW - 1) : 0] operand_data, + output wire [(ADW - 1) : 0] operand_addr, + + output wire [(ADW - 1) : 0] result_addr, + input wire result_words, + output wire [31 : 0] result_data, + output wire result_we + ); + + //---------------------------------------------------------------- + // Defines + //---------------------------------------------------------------- + localparam OPW = 64; + localparam ADW = 7; + + + //---------------------------------------------------------------- + // Wires. + //---------------------------------------------------------------- + wire [(ADW - 1) : 0] opa_addr; + reg [(OPW - 1) : 0] opa_data; + wire [(ADW - 1) : 0] opb_addr; + reg [(OPW - 1) : 0] opb_data; + wire [(ADW - 1) : 0] opm_addr; + reg [(OPW - 1) : 0] opm_data; + + reg [(ADW - 1) : 0] tmp_operand_addr; + wire [(OPW - 1) : 0] internal_result_data; + + + //---------------------------------------------------------------- + // Assignments. + //---------------------------------------------------------------- + assign result_data = internal_result_data[result_words * 32 +: 32]; + assign operand_addr = tmp_operand_addr; + + + //---------------------------------------------------------------- + // core instantiations. + //---------------------------------------------------------------- + montprod #(.OPW(OPW), .ADW(ADW)) + montprod_inst( + .clk(clk), + .reset_n(reset_n), + + .calculate(calculate), + .ready(ready), + + .length(length), + + .opa_addr(opa_addr), + .opa_data(opa_data), + + .opb_addr(opb_addr), + .opb_data(opb_data), + + .opm_addr(opm_addr), + .opm_data(opm_data), + + .result_addr(result_addr), + .result_data(internal_result_data), + .result_we(result_we) + ); + + + //---------------------------------------------------------------- + // Operand select mux. + //---------------------------------------------------------------- + always @* + begin : operand_mux + tmp_operand_addr = {ADW{1'b0}}; + opa_data = {OPW{1'b1}}; + opb_data = {OPW{1'b1}}; + opm_data = {OPW{1'b1}}; + + case (operand_select) + 0: + begin + tmp_operand_addr = opa_addr; + opa_data = operand_data; + end + + 1: + begin + tmp_operand_addr = opb_addr; + opb_data = operand_data; + end + + 2: + begin + tmp_operand_addr = opm_addr; + opm_data = operand_data; + end + + default: + begin + end + endcase // case (operand_select) + end + +endmodule // montprod_wrapper + +//====================================================================== +// EOF montprod_wrapper +//====================================================================== diff --git a/src/tb/tb_modexp.v b/src/tb/tb_modexp.v index c2ab7fb..637d5a7 100644 --- a/src/tb/tb_modexp.v +++ b/src/tb/tb_modexp.v @@ -6,33 +6,33 @@ // // // Author: Joachim Strombergson, Peter Magnusson -// Copyright (c) 2015, Assured AB -// All rights reserved. +// Copyright (c) 2015, NORDUnet A/S All rights reserved. // -// Redistribution and use in source and binary forms, with or -// without modification, are permitted provided that the following -// conditions are met: +// 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. // -// 1. 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. // -// 2. 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 OWNER 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. +// 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. // //====================================================================== @@ -256,8 +256,8 @@ module tb_modexp(); dut.core_inst.ready_reg, dut.start_reg, dut.start_new); $display("residue_valid = 0x%01x", dut.core_inst.residue_valid_reg); $display("loop_counter_reg = 0x%08x", dut.core_inst.loop_counter_reg); - $display("exponent_length_reg = 0x%02x, modulus_length_reg = 0x%02x length_m1 = 0x%02x", - dut.exponent_length_reg, dut.modulus_length_reg, dut.core_inst.length_m1); + $display("exponent_length_reg = 0x%02x exponent_length_m1 = 0x%02x modulus_length_reg = 0x%02x modulus_length_m1 = 0x%02x", + dut.exponent_length_reg, dut.core_inst.exponent_length_m1, dut.modulus_length_reg, dut.core_inst.modulus_length_m1); $display("ctrl_reg = 0x%04x", dut.core_inst.modexp_ctrl_reg); $display(""); end @@ -786,26 +786,28 @@ module tb_modexp(); tc_ctr = tc_ctr + 1; $display("autogenerated_BASIC_128bit"); - write_word({GENERAL_PREFIX, ADDR_MESSAGE_PTR_RST}, 32'h00000000); - write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h29462882); - write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h12caa2d5); - write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hb80e1c66); - write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h1006807f); - write_word({GENERAL_PREFIX, ADDR_EXPONENT_PTR_RST}, 32'h00000000); write_word({GENERAL_PREFIX, ADDR_EXPONENT_DATA}, 32'h3285c343); write_word({GENERAL_PREFIX, ADDR_EXPONENT_DATA}, 32'h2acbcb0f); write_word({GENERAL_PREFIX, ADDR_EXPONENT_DATA}, 32'h4d023228); write_word({GENERAL_PREFIX, ADDR_EXPONENT_DATA}, 32'h2ecc73db); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h29462882); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h12caa2d5); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hb80e1c66); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h1006807f); + write_word({GENERAL_PREFIX, ADDR_MODULUS_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h00000000); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h267d2f2e); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h51c216a7); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hda752ead); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h48d22d89); write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000004); - write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000004); + write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000005); start_test_cycle_ctr(); @@ -816,10 +818,11 @@ module tb_modexp(); stop_test_cycle_ctr(); write_word({GENERAL_PREFIX, ADDR_RESULT_PTR_RST}, 32'h00000000); - read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h0ddc404d, read_data); //TEMPLATE_EXPECTED_VALUES - read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h91600596, read_data); //TEMPLATE_EXPECTED_VALUES - read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h7425a8d8, read_data); //TEMPLATE_EXPECTED_VALUES - read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha066ca56, read_data); //TEMPLATE_EXPECTED_VALUES + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h0ddc404d, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h91600596, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h7425a8d8, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha066ca56, read_data); if (success !== 1) begin @@ -833,6 +836,57 @@ module tb_modexp(); //---------------------------------------------------------------- + // e64bit_64bit_modulus() + //---------------------------------------------------------------- + task e64bit_64bit_modulus(); + reg [31 : 0] read_data; + begin + success = 32'h1; + tc_ctr = tc_ctr + 1; + $display("Test with 64 bit exponent and 64 bit modulus."); + + write_word({GENERAL_PREFIX, ADDR_EXPONENT_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_EXPONENT_DATA}, 32'h12345678); + write_word({GENERAL_PREFIX, ADDR_EXPONENT_DATA}, 32'h97543211); + + write_word({GENERAL_PREFIX, ADDR_MESSAGE_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hfeababab); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hdeadbeef); + + write_word({GENERAL_PREFIX, ADDR_MODULUS_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffee); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hbeefbeef); + + write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000002); + write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000003); + + start_test_cycle_ctr(); + + // Start processing and wait for ready. + write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001); + wait_ready(); + + stop_test_cycle_ctr(); + + write_word({GENERAL_PREFIX, ADDR_RESULT_PTR_RST}, 32'h00000000); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'he52c5b9f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h85de87eb, read_data); + + if (success !== 1) + begin + $display("*** ERROR: 64 bit exponent and 64 bit_modulus was NOT successful."); + error_ctr = error_ctr + 1; + end + else + $display("*** 64 bit exponent and 64 bit modulus success."); + end + endtask // e64bit_64bit_modulus + + + //---------------------------------------------------------------- // e65537_64bit_modulus() //---------------------------------------------------------------- task e65537_64bit_modulus(); @@ -846,15 +900,17 @@ module tb_modexp(); write_word({GENERAL_PREFIX, ADDR_EXPONENT_DATA}, 32'h00010001); write_word({GENERAL_PREFIX, ADDR_MODULUS_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h00000000); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hf077656f); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h3bf9e69b); write_word({GENERAL_PREFIX, ADDR_MESSAGE_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h00000000); write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hb6684dc3); write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h79a5824b); write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); - write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000002); + write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000003); start_test_cycle_ctr(); @@ -865,8 +921,9 @@ module tb_modexp(); stop_test_cycle_ctr(); write_word({GENERAL_PREFIX, ADDR_RESULT_PTR_RST}, 32'h00000000); - read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h419a024f, read_data); - read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hdddf178e, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h132d8e17, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hdd4d85a4, read_data); if (success !== 1) begin @@ -880,6 +937,56 @@ module tb_modexp(); //---------------------------------------------------------------- + // e65537_64bit_modulus_elength() + //---------------------------------------------------------------- + task e65537_64bit_modulus_elength(); + reg [31 : 0] read_data; + begin + success = 32'h1; + tc_ctr = tc_ctr + 1; + $display("Test with e = 65537 and 64 bit modulus, explicit exponent length."); + + write_word({GENERAL_PREFIX, ADDR_EXPONENT_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_EXPONENT_DATA}, 32'h00010001); + + write_word({GENERAL_PREFIX, ADDR_MODULUS_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hf077656f); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h3bf9e69b); + + write_word({GENERAL_PREFIX, ADDR_MESSAGE_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hb6684dc3); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h79a5824b); + + write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); + write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000003); + + start_test_cycle_ctr(); + + // Start processing and wait for ready. + write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001); + wait_ready(); + + stop_test_cycle_ctr(); + + write_word({GENERAL_PREFIX, ADDR_RESULT_PTR_RST}, 32'h00000000); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h132d8e17, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hdd4d85a4, read_data); + + if (success !== 1) + begin + $display("*** ERROR: e65537_64bit_modulus with explicit elength was NOT successful."); + error_ctr = error_ctr + 1; + end + else + $display("*** e65537_64bit_modulus success."); + end + endtask // e65537_64bit_modulus_elength + + + //---------------------------------------------------------------- // e65537_128bit_modulus() //---------------------------------------------------------------- task e65537_128bit_modulus(); @@ -893,19 +1000,21 @@ module tb_modexp(); write_word({GENERAL_PREFIX, ADDR_EXPONENT_DATA}, 32'h00010001); write_word({GENERAL_PREFIX, ADDR_MODULUS_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h00000000); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hf5e8eee0); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hc06b048a); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h964b2105); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h2c36ad6b); write_word({GENERAL_PREFIX, ADDR_MESSAGE_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h00000000); write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h956e61b3); write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h27997bc4); write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h94e7e5c9); write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hb53585cf); write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); - write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000004); + write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000005); start_test_cycle_ctr(); @@ -916,10 +1025,11 @@ module tb_modexp(); stop_test_cycle_ctr(); write_word({GENERAL_PREFIX, ADDR_RESULT_PTR_RST}, 32'h00000000); - read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h1e97bff8, read_data); - read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h60029e6e, read_data); - read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hedaef85e, read_data); - read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hfb0c6562, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h9c6d322c, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h25ab8bd3, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4aa80100, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf0f3a02c, read_data); if (success !== 1) begin @@ -947,17 +1057,8 @@ module tb_modexp(); write_word({GENERAL_PREFIX, ADDR_EXPONENT_PTR_RST}, 32'h00000000); write_word({GENERAL_PREFIX, ADDR_EXPONENT_DATA}, 32'h00010001); - write_word({GENERAL_PREFIX, ADDR_MESSAGE_PTR_RST}, 32'h00000000); - write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hf169d36e); - write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hbe2ce61d); - write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hc2e87809); - write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h4fed15c3); - write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h7c70eac5); - write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'ha123e643); - write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h299b36d2); - write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h788e583b); - write_word({GENERAL_PREFIX, ADDR_MODULUS_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h00000000); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hf169d36e); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hbe2ce61d); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hc2e87809); @@ -967,8 +1068,19 @@ module tb_modexp(); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h299b36d2); write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h788e583b); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hf169d36e); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hbe2ce61d); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hc2e87809); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h4fed15c3); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h7c70eac5); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'ha123e643); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h299b36d2); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h788e583a); + write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); - write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000008); + write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000009); start_test_cycle_ctr(); @@ -979,10 +1091,15 @@ module tb_modexp(); stop_test_cycle_ctr(); write_word({GENERAL_PREFIX, ADDR_RESULT_PTR_RST}, 32'h00000000); - read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h0ddc404d, read_data); //TEMPLATE_EXPECTED_VALUES - read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h91600596, read_data); //TEMPLATE_EXPECTED_VALUES - read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h7425a8d8, read_data); //TEMPLATE_EXPECTED_VALUES - read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha066ca56, read_data); //TEMPLATE_EXPECTED_VALUES + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf169d36e, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hbe2ce61d, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hc2e87809, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4fed15c3, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h7c70eac5, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha123e643, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h299b36d2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h788e583a, read_data); if (success !== 1) begin @@ -996,6 +1113,790 @@ module tb_modexp(); //---------------------------------------------------------------- + // e65537_1024bit_modulus() + // + // Task that tests modexp with small exponent and + // 2048 bit modulus. + //---------------------------------------------------------------- + task e65537_1024bit_modulus(); + reg [31 : 0] read_data; + begin + success = 32'h1; + tc_ctr = tc_ctr + 1; + $display("Test with e = 65537 and 1024 bit modulus."); + + write_word({GENERAL_PREFIX, ADDR_EXPONENT_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_EXPONENT_DATA}, 32'h00010001); + + write_word({GENERAL_PREFIX, ADDR_MODULUS_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + + + write_word({GENERAL_PREFIX, ADDR_MESSAGE_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + + write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); + write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000021); + + start_test_cycle_ctr(); + + // Start processing and wait for ready. + write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001); + wait_ready(); + + stop_test_cycle_ctr(); + + write_word({GENERAL_PREFIX, ADDR_RESULT_PTR_RST}, 32'h00000000); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h45d55343, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'ha0971add, read_data); + + if (success !== 1) + begin + $display("*** ERROR: e65537_1024bit_modulus was NOT successful."); + error_ctr = error_ctr + 1; + end + else + $display("*** e65537_1024bit_modulus success."); + end + endtask // e65537_1024bit_modulus + + + //---------------------------------------------------------------- + // e65537_1536bit_modulus() + // + // Task that tests modexp with small exponent and + // 1536 bit modulus. + //---------------------------------------------------------------- + task e65537_1536bit_modulus(); + reg [31 : 0] read_data; + begin + success = 32'h1; + tc_ctr = tc_ctr + 1; + $display("Test with e = 65537 and 1536 bit modulus."); + + write_word({GENERAL_PREFIX, ADDR_EXPONENT_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_EXPONENT_DATA}, 32'h00010001); + + write_word({GENERAL_PREFIX, ADDR_MODULUS_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + + + write_word({GENERAL_PREFIX, ADDR_MESSAGE_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + + write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); + write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000031); + + start_test_cycle_ctr(); + + // Start processing and wait for ready. + write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001); + wait_ready(); + + stop_test_cycle_ctr(); + + write_word({GENERAL_PREFIX, ADDR_RESULT_PTR_RST}, 32'h00000000); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4ade4f46, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h02cb4a2f, read_data); + + if (success !== 1) + begin + $display("*** ERROR: e65537_1536bit_modulus was NOT successful."); + error_ctr = error_ctr + 1; + end + else + $display("*** e65537_1536bit_modulus success."); + end + endtask // e65537_1536bit_modulus + + + + //---------------------------------------------------------------- + // e65537_1664bit_modulus() + // + // Task that tests modexp with small exponent and + // 1664 bit modulus. + //---------------------------------------------------------------- + task e65537_1664bit_modulus(); + reg [31 : 0] read_data; + begin + success = 32'h1; + tc_ctr = tc_ctr + 1; + $display("Test with e = 65537 and 1664 bit modulus."); + + write_word({GENERAL_PREFIX, ADDR_EXPONENT_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_EXPONENT_DATA}, 32'h00010001); + + write_word({GENERAL_PREFIX, ADDR_MODULUS_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + + + write_word({GENERAL_PREFIX, ADDR_MESSAGE_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + + write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); + write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000035); + + start_test_cycle_ctr(); + + // Start processing and wait for ready. + write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001); + wait_ready(); + + stop_test_cycle_ctr(); + + write_word({GENERAL_PREFIX, ADDR_RESULT_PTR_RST}, 32'h00000000); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h88671c15, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h2aeeb8b2, read_data); + + if (success !== 1) + begin + $display("*** ERROR: e65537_1664bit_modulus was NOT successful."); + error_ctr = error_ctr + 1; + end + else + $display("*** e65537_1664it_modulus success."); + end + endtask // e65537_1664bit_modulus + + + //---------------------------------------------------------------- + // e65537_2048bit_modulus() + // + // Task that tests modexp with small exponent and + // 2048 bit modulus. + //---------------------------------------------------------------- + task e65537_2048bit_modulus(); + reg [31 : 0] read_data; + begin + success = 32'h1; + tc_ctr = tc_ctr + 1; + $display("Test with e = 65537 and 2048 bit modulus."); + + write_word({GENERAL_PREFIX, ADDR_EXPONENT_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_EXPONENT_DATA}, 32'h00010001); + + write_word({GENERAL_PREFIX, ADDR_MODULUS_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + write_word({GENERAL_PREFIX, ADDR_MODULUS_DATA}, 32'hffeeffef); + + + write_word({GENERAL_PREFIX, ADDR_MESSAGE_PTR_RST}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'h00000000); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hffaabbcc); + write_word({GENERAL_PREFIX, ADDR_MESSAGE_DATA}, 32'hddeeffff); + + write_word({GENERAL_PREFIX, ADDR_EXPONENT_LENGTH}, 32'h00000001); + write_word({GENERAL_PREFIX, ADDR_MODULUS_LENGTH}, 32'h00000041); + + start_test_cycle_ctr(); + + // Start processing and wait for ready. + write_word({GENERAL_PREFIX, ADDR_CTRL}, 32'h00000001); + wait_ready(); + + stop_test_cycle_ctr(); + + write_word({GENERAL_PREFIX, ADDR_RESULT_PTR_RST}, 32'h00000000); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h00000000, read_data); + + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'hf1752196, read_data); + read_word({GENERAL_PREFIX, ADDR_RESULT_DATA}); read_data = tb_read_data; success = success & assertEquals(32'h4c36e92f, read_data); + + if (success !== 1) + begin + $display("*** ERROR: e65537_2048bit_modulus was NOT successful."); + error_ctr = error_ctr + 1; + end + else + $display("*** e65537_2048bit_modulus success."); + end + endtask // e65537_2048bit_modulus + + + //---------------------------------------------------------------- // rob_dec_1024() // // Task that tests modexp with 1024 bit decipher/sign with @@ -1373,12 +2274,17 @@ module tb_modexp(); // tc3(); // autogenerated_BASIC_33bit(); // autogenerated_BASIC_128bit(); +// e64bit_64bit_modulus(); // e65537_64bit_modulus(); +// e65537_64bit_modulus_elength(); // e65537_128bit_modulus(); // e65537_256bit_modulus(); - +// e65537_1024bit_modulus(); +// e65537_1536bit_modulus(); +// e65537_1664bit_modulus(); + e65537_2048bit_modulus(); // rob_dec_1024(); - rob_enc_1024(); +// rob_enc_1024(); display_test_results(); diff --git a/src/tb/tb_modexp_autogenerated.v b/src/tb/tb_modexp_autogenerated.v index 1eb80d5..0bb9432 100644 --- a/src/tb/tb_modexp_autogenerated.v +++ b/src/tb/tb_modexp_autogenerated.v @@ -174,8 +174,8 @@ module tb_modexp_autogenerated(); dut.core_inst.ready_reg, dut.start_reg, dut.start_new); $display("residue_valid = 0x%01x", dut.core_inst.residue_valid_reg); $display("loop_counter_reg = 0x%08x", dut.core_inst.loop_counter_reg); - $display("exponent_length_reg = 0x%02x, modulus_length_reg = 0x%02x length_m1 = 0x%02x", - dut.exponent_length_reg, dut.modulus_length_reg, dut.core_inst.length_m1); + $display("exponent_length_reg = 0x%02x, modulus_length_reg = 0x%02x modulus_length_m1 = 0x%02x", + dut.exponent_length_reg, dut.modulus_length_reg, dut.core_inst.modulus_length_m1); $display("ctrl_reg = 0x%04x", dut.core_inst.modexp_ctrl_reg); $display(""); end diff --git a/src/tb/tb_montprod.v b/src/tb/tb_montprod.v index 601e7f8..cd27949 100644 --- a/src/tb/tb_montprod.v +++ b/src/tb/tb_montprod.v @@ -41,373 +41,466 @@ //------------------------------------------------------------------ `timescale 1ns/100ps -//------------------------------------------------------------------ -// Test module. -//------------------------------------------------------------------ module tb_montprod(); -//---------------------------------------------------------------- -// Internal constant and parameter definitions. -//---------------------------------------------------------------- - parameter SHOW_INIT = 0; - - parameter DUMP_MEM = 0; - parameter DEBUG = 0; + //---------------------------------------------------------------- + // Internal constant and parameter definitions. + //---------------------------------------------------------------- parameter CLK_HALF_PERIOD = 2; - parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD; - - -//---------------------------------------------------------------- -// Register and Wire declarations. -//---------------------------------------------------------------- - -reg tb_clk; -reg tb_reset_n; -reg tb_calculate; -wire tb_ready; -reg [ 7 : 0] tb_length; -wire [ 7 : 0] tb_opa_addr; -reg [31 : 0] tb_opa_data; -wire [ 7 : 0] tb_opb_addr; -reg [31 : 0] tb_opb_data; -wire [ 7 : 0] tb_opm_addr; -reg [31 : 0] tb_opm_data; -wire [ 7 : 0] tb_result_addr; -wire [31 : 0] tb_result_data; -wire tb_result_we; - -reg [31 : 0] tb_a [0 : 255]; //tb_opa_data -reg [31 : 0] tb_b [0 : 255]; //tb_opb_data reads here -reg [31 : 0] tb_m [0 : 255]; //tb_opm_data reads here -reg [31 : 0] tb_r [0 : 255]; //tb_result_data writes here - - reg monitor_s; - -integer test_mont_prod_success; -integer test_mont_prod_fail; - -//---------------------------------------------------------------- -// Device Under Test. -//---------------------------------------------------------------- - -montprod dut( - .clk(tb_clk), - .reset_n(tb_reset_n), - .length(tb_length), - .calculate(tb_calculate), - .ready(tb_ready), - .opa_addr(tb_opa_addr), - .opa_data(tb_opa_data), - .opb_addr(tb_opb_addr), - .opb_data(tb_opb_data), - .opm_addr(tb_opm_addr), - .opm_data(tb_opm_data), - .result_addr(tb_result_addr), - .result_data(tb_result_data), - .result_we(tb_result_we) -); - -always @(posedge tb_clk) - begin : read_test_memory - tb_opa_data <= tb_a[tb_opa_addr]; - tb_opb_data <= tb_b[tb_opb_addr]; - tb_opm_data <= tb_m[tb_opm_addr]; - - if (DUMP_MEM) - $display("a %x %x b %x %x m %x %x", tb_opa_addr, tb_a[tb_opa_addr], tb_opb_addr, tb_b[tb_opb_addr], tb_opm_addr, tb_m[tb_opm_addr]); - end - -always @* - begin : write_test_memory - if (tb_result_we == 1'b1) - begin - $display("write %d: %x", tb_result_addr, tb_result_data); - tb_r[tb_result_addr] = tb_result_data; - end - end + parameter CLK_PERIOD = 2 * CLK_HALF_PERIOD; + + parameter SHOW_INIT = 0; + parameter DUMP_MEM = 0; + parameter DEBUG = 0; + parameter SHOW_WRITE_MEM = 0; + parameter SHOW_WRITE_RESULT_MEM = 0; + parameter SHOW_S_MONITOR = 0; + parameter SHOW_BQ_DEBUG = 0; + parameter SHOW_FSM_STATUS = 0; + parameter DISPLAY_TEST_CYCLES = 1; + + parameter WAIT_TIMEOUT = 100000000; + + + //---------------------------------------------------------------- + // Register and Wire declarations. + //---------------------------------------------------------------- + reg tb_clk; + reg tb_reset_n; + reg tb_calculate; + wire tb_ready; + reg [ 7 : 0] tb_length; + wire [ 7 : 0] tb_opa_addr; + reg [31 : 0] tb_opa_data; + wire [ 7 : 0] tb_opb_addr; + reg [31 : 0] tb_opb_data; + wire [ 7 : 0] tb_opm_addr; + reg [31 : 0] tb_opm_data; + wire [ 7 : 0] tb_result_addr; + wire [31 : 0] tb_result_data; + wire tb_result_we; + + reg [31 : 0] test_cycle_ctr; + reg test_cycle_ctr_rst; + reg test_cycle_ctr_inc; + + reg [31 : 0] tb_a [0 : 255]; //tb_opa_data + reg [31 : 0] tb_b [0 : 255]; //tb_opb_data reads here + reg [31 : 0] tb_m [0 : 255]; //tb_opm_data reads here + reg [31 : 0] tb_r [0 : 255]; //tb_result_data writes here + + integer test_mont_prod_success; + integer test_mont_prod_fail; + + + //---------------------------------------------------------------- + // Device Under Test. + //---------------------------------------------------------------- + montprod dut( + .clk(tb_clk), + .reset_n(tb_reset_n), + .length(tb_length), + .calculate(tb_calculate), + .ready(tb_ready), + .opa_addr(tb_opa_addr), + .opa_data(tb_opa_data), + .opb_addr(tb_opb_addr), + .opb_data(tb_opb_data), + .opm_addr(tb_opm_addr), + .opm_data(tb_opm_data), + .result_addr(tb_result_addr), + .result_data(tb_result_data), + .result_we(tb_result_we) + ); + + + //---------------------------------------------------------------- + // clk_gen + // Clock generator process. + //---------------------------------------------------------------- + always + begin : clk_gen + #CLK_HALF_PERIOD tb_clk = !tb_clk; + end // clk_gen + + + //---------------------------------------------------------------- + // test_cycle_counter + // + // Used to measure the number of cycles it takes to perform + // a given test case. + //---------------------------------------------------------------- + always @ (posedge tb_clk) + begin + if (test_cycle_ctr_rst) + test_cycle_ctr = 64'h0000000000000000; + if (test_cycle_ctr_inc) + test_cycle_ctr = test_cycle_ctr + 1; + end -//---------------------------------------------------------------- -// clk_gen -// -// Clock generator process. -//---------------------------------------------------------------- -always - begin : clk_gen - #CLK_HALF_PERIOD tb_clk = !tb_clk; - end // clk_gen + //---------------------------------------------------------------- + // start_test_cycle_ctr + // + // Reset and start the test cycle counter. + //---------------------------------------------------------------- + task start_test_cycle_ctr(); + begin + test_cycle_ctr_rst = 1; + #(CLK_PERIOD); + test_cycle_ctr_rst = 0; -//---------------------------------------------------------------- -// S monitor -//---------------------------------------------------------------- - always @ (posedge tb_clk) - begin : s_monitor - if (monitor_s) - $display("S[ 0 ]: %x", dut.s_mem.mem[0] ); + test_cycle_ctr_inc = 1; + end + endtask // start_test_cycle_ctr() + + + //---------------------------------------------------------------- + // stop_test_cycle_ctr() + // + // Stop the test cycle counter and optionally display the + // result. + //---------------------------------------------------------------- + task stop_test_cycle_ctr(); + begin + test_cycle_ctr_inc = 0; + #(CLK_PERIOD); + + if (DISPLAY_TEST_CYCLES) + $display("*** Number of cycles performed during test: 0x%016x", test_cycle_ctr); end + endtask // stop_test_cycle_ctr() + //---------------------------------------------------------------- + // read_test_memory + //---------------------------------------------------------------- + always @(posedge tb_clk) + begin : read_test_memory + tb_opa_data <= tb_a[tb_opa_addr]; + tb_opb_data <= tb_b[tb_opb_addr]; + tb_opm_data <= tb_m[tb_opm_addr]; -//---------------------------------------------------------------- -// S monitor -//---------------------------------------------------------------- - always @ (posedge tb_clk) - begin : s_write_minitor - if (monitor_s) - if (dut.s_mem_we) - $display("Write to S[0x%02x]: 0x%08x", dut.s_mem_wr_addr, dut.s_mem_new); + if (DUMP_MEM) + $display("a %x %x b %x %x m %x %x", tb_opa_addr, tb_a[tb_opa_addr], tb_opb_addr, tb_b[tb_opb_addr], tb_opm_addr, tb_m[tb_opm_addr]); end + //---------------------------------------------------------------- + // write_result_memory + //---------------------------------------------------------------- + always @* + begin : write_result_memory + if (tb_result_we == 1'b1) + begin + tb_r[tb_result_addr] = tb_result_data; + + if (SHOW_WRITE_RESULT_MEM) + $display("write result mnen 0x%02%x: 0x%08x", tb_result_addr, tb_result_data); + end + end -//---------------------------------------------------------------- -//---------------------------------------------------------------- + + //---------------------------------------------------------------- + // s_monitor + //---------------------------------------------------------------- + always @ (posedge tb_clk) + begin : s_monitor + if (SHOW_S_MONITOR) + begin + $display("S[0x00]: 0x%08x", dut.s_mem.mem[0]); + + if (dut.s_mem_we_reg) + $display("Write to S[0x%02x]: 0x%08x", dut.s_mem_write_addr, dut.s_mem_write_data); + end + end + + + //---------------------------------------------------------------- + // bq_debug + //---------------------------------------------------------------- always @ (posedge tb_clk) begin : bq_debug - if (dut.montprod_ctrl_reg == dut.CTRL_L_CALC_SM) - $display("====================> B: %x Q: %x B_bit_index_reg: %x <=====================", dut.b_reg, dut.q_reg, dut.B_bit_index_reg); + if (SHOW_BQ_DEBUG) + begin + if (dut.montprod_ctrl_reg == dut.CTRL_CALC_ADD) + $display("====================> B: %x Q: %x b_bit_index_reg: %x <=====================", dut.b_reg, dut.q_reg, dut.b_bit_index_reg); + end end - //case (montprod_ctrl_reg) - // CTRL_LOOP_BQ: - // $display("DEBUG: b: %d q: %d opa_data %x opb_data %x s_mem_read_data %x", b, q, opa_addr_reg, opa_data, opb_data, s_mem_read_data); - // default: - // begin end - //endcase -//---------------------------------------------------------------- -//---------------------------------------------------------------- + //---------------------------------------------------------------- + // fsm_monitor + //---------------------------------------------------------------- always @ (posedge tb_clk) - begin : fsm_debug - if (dut.montprod_ctrl_we) - case (dut.montprod_ctrl_new) - dut.CTRL_IDLE: - $display("FSM: IDLE"); - dut.CTRL_INIT_S: - $display("FSM: INIT_S"); - dut.CTRL_LOOP_INIT: - $display("FSM: LOOP_INIT"); - dut.CTRL_LOOP_ITER: - $display("FSM: LOOP_ITER"); - dut.CTRL_LOOP_BQ: - $display("FSM: LOOP_BQ"); - dut.CTRL_L_CALC_SM: - $display("FSM: LOOP_CALC_SM"); - dut.CTRL_L_CALC_SA: - $display("FSM: LOOP_CALC_SA"); - dut.CTRL_L_STALLPIPE_SA: - $display("FSM: STALL_PIPE"); - dut.CTRL_L_CALC_SDIV2: - $display("FSM: LOOP_CALC_SDIV2"); - dut.CTRL_EMIT_S: - $display("FSM: LOOP_EMIT_S"); - dut.CTRL_DONE: - $display("FSM: DONE"); - default: - $display("FSM: %x", dut.montprod_ctrl_new); - endcase + begin : fsm_monitor + if (SHOW_FSM_STATUS) + if (dut.montprod_ctrl_we) + case (dut.montprod_ctrl_new) + dut.CTRL_IDLE: + $display("FSM: IDLE"); + dut.CTRL_LOOP_ITER: + $display("FSM: LOOP_ITER"); + dut.CTRL_LOOP_BQ: + $display("FSM: LOOP_BQ"); + dut.CTRL_CALC_ADD: + $display("FSM: LOOP_CALC_ADD"); + dut.CTRL_STALLPIPE_ADD: + $display("FSM: STALL_PIPE_ADD"); + dut.CTRL_CALC_SDIV2: + $display("FSM: CALC_SDIV2"); + dut.CTRL_EMIT_S: + $display("FSM: LOOP_EMIT_S"); + default: + $display("FSM: %x", dut.montprod_ctrl_new); + endcase end -//---------------------------------------------------------------- -// reset_dut() -// -// Toggles reset to force the DUT into a well defined state. -//---------------------------------------------------------------- -task reset_dut(); - begin - $display("*** Toggle reset."); - tb_reset_n = 0; - #(2 * CLK_PERIOD); - tb_reset_n = 1; - end -endtask // reset_dut - -//---------------------------------------------------------------- -// init_sim() -// -// Initialize all counters and testbed functionality as well -// as setting the DUT inputs to defined values. -//---------------------------------------------------------------- -task init_sim(); - begin - $display("*** init_sim"); - tb_clk = 0; - tb_reset_n = 0; - tb_length = 0; - tb_calculate = 0; - monitor_s = 1; - test_mont_prod_success = 0; - test_mont_prod_fail = 0; - end -endtask // init_dut - -//---------------------------------------------------------------- -// wait_ready() -// -// Wait for the ready flag in the dut to be set. -// -// Note: It is the callers responsibility to call the function -// when the dut is actively processing and will in fact at some -// point set the flag. -//---------------------------------------------------------------- -task wait_ready(); - begin - $display("*** wait_ready"); - begin: wait_loop - integer i; - for (i=0; i<1000000; i=i+1) - if (tb_ready == 0) - #(CLK_PERIOD); + //---------------------------------------------------------------- + // reset_dut() + // + // Toggles reset to force the DUT into a well defined state. + //---------------------------------------------------------------- + task reset_dut(); + begin + $display("*** Toggle reset."); + tb_reset_n = 0; + #(2 * CLK_PERIOD); + tb_reset_n = 1; + end + endtask // reset_dut + + + //---------------------------------------------------------------- + // init_sim() + // + // Initialize all counters and testbed functionality as well + // as setting the DUT inputs to defined values. + //---------------------------------------------------------------- + task init_sim(); + begin + $display("*** init_sim"); + tb_clk = 0; + tb_reset_n = 0; + tb_length = 0; + tb_calculate = 0; + test_mont_prod_success = 0; + test_mont_prod_fail = 0; end - if (tb_ready == 0) - begin - $display("*** wait_ready failed, never became ready!"); - $finish; - end - end -endtask // wait_ready - -//---------------------------------------------------------------- -//---------------------------------------------------------------- -task signal_calculate(); - begin - $display("*** signal_calculate"); - tb_calculate = 1; - #(CLK_PERIOD); - tb_calculate = 0; - end -endtask // signal_calculate - - -//---------------------------------------------------------------- -// Tests the montgomery multiplications -//---------------------------------------------------------------- -task test_mont_prod( - input [7 : 0] length, - input [0 : 8192-1] a, - input [0 : 8192-1] b, - input [0 : 8192-1] m, - input [0 : 8192-1] expected - ); - begin - $display("*** test started"); - begin: copy_test_vectors + endtask // init_sim + + + //---------------------------------------------------------------- + // wait_ready() + // + // Wait for the ready flag in the dut to be set. + // + // Note: It is the callers responsibility to call the function + // when the dut is actively processing and will in fact at some + // point set the flag. + //---------------------------------------------------------------- + task wait_ready(); + begin : wait_ready integer i; - integer j; - $display("*** Initializing..."); - for (i=32'h0; i<256; i=i+1) + $display("*** waiting for core to be ready..."); + + i = 0; + while ((tb_ready == 0) && (i < WAIT_TIMEOUT)) begin - j = {i, 5'h0}; - tb_a[i] = a[j +: 32]; - tb_b[i] = b[j +: 32]; - tb_m[i] = m[j +: 32]; - tb_r[i] = 32'h0; - if (SHOW_INIT) - $display("*** init %0x: a: %x b: %x m: %x r: %x", i, tb_a[i], tb_b[i], tb_m[i], tb_r[i]); + i = i + 1; + #(CLK_PERIOD); end - end - $display("*** Test vector copied"); - wait_ready(); - tb_length = length; - signal_calculate(); - wait_ready(); - begin: verify_test_vectors - integer i; - integer j; - integer success; - integer fail; - success = 1; - fail = 0; - for (i=0; i<length; i=i+1) + if (tb_ready == 0) begin - j = i * 32; - $display("offset: %02d expected 0x%08x actual 0x%08x", i, expected[j +: 32], tb_r[i]); - if (expected[j +: 32] != tb_r[i]) - begin - success = 0; - fail = 1; - end + $display("*** wait_ready failed, never became ready!"); + $finish; end - test_mont_prod_success = test_mont_prod_success + success; - test_mont_prod_fail = test_mont_prod_fail + fail; end + endtask // wait_ready + + + //---------------------------------------------------------------- + // signal_calculate() + // + // Start the montgomery calculation by pulling the calculate + // flag to the dut. + //---------------------------------------------------------------- + task signal_calculate(); + begin + $display("*** signal_calculate"); + tb_calculate = 1; + #(CLK_PERIOD); + tb_calculate = 0; + end + endtask // signal_calculate + + + //---------------------------------------------------------------- + // Tests the montgomery multiplications + //---------------------------------------------------------------- + task test_mont_prod( + input [7 : 0] length, + input [0 : 8192-1] a, + input [0 : 8192-1] b, + input [0 : 8192-1] m, + input [0 : 8192-1] expected + ); + begin + $display("*** Mongomry multiplier test started"); + begin: copy_test_vectors + integer i; + integer j; + + $display("*** Initializing..."); + for (i=32'h0; i<256; i=i+1) + begin + j = {i, 5'h0}; + tb_a[i] = a[j +: 32]; + tb_b[i] = b[j +: 32]; + tb_m[i] = m[j +: 32]; + tb_r[i] = 32'h0; + if (SHOW_INIT) + $display("*** init %0x: a: %x b: %x m: %x r: %x", i, tb_a[i], tb_b[i], tb_m[i], tb_r[i]); + end + end + + $display("*** Test vector copied"); + wait_ready(); + tb_length = length; + + start_test_cycle_ctr(); + + signal_calculate(); + wait_ready(); + + stop_test_cycle_ctr(); + + begin: verify_test_vectors + integer i; + integer j; + integer success; + integer fail; + success = 1; + fail = 0; + for (i=0; i<length; i=i+1) + begin + j = i * 32; + $display("offset: %02d expected 0x%08x actual 0x%08x", i, expected[j +: 32], tb_r[i]); + if (expected[j +: 32] != tb_r[i]) + begin + success = 0; + fail = 1; + end + end + test_mont_prod_success = test_mont_prod_success + success; + test_mont_prod_fail = test_mont_prod_fail + fail; + + if (success) + $display("*** test stopped, test successful."); + else + $display("*** test stopped, test failed."); + $display(""); + end + end + endtask // test_mont_prod + + + //---------------------------------------------------------------- + // short_tests + // + // Short tests that are fast to run jut to check that the + // functionality is as expected. + //---------------------------------------------------------------- + task short_tests(); + begin : short_tests + //* A= b B= 11 M= 13 A*B= 10 Ar= 9 Br= 7 Ar*Br= 1 A*B= 10 + + test_mont_prod( 1, {32'h9, 8160'h0}, {32'h7, 8160'h0}, {32'h13,8160'h0}, {32'h1,8160'h0} ); + + //* A= b B= 13 M= 11 A*B= 5 Ar= b Br= 2 Ar*Br= 5 A*B= 5 + + test_mont_prod( 1, {32'hb, 8160'h0}, {32'h2, 8160'h0}, {32'h11,8160'h0}, {32'h5,8160'h0} ); + + //* A= 11 B= b M= 13 A*B= 10 Ar= 7 Br= 9 Ar*Br= 1 A*B= 10 + + test_mont_prod( 1, {32'h7, 8160'h0}, {32'h9, 8160'h0}, {32'h13,8160'h0}, {32'h1,8160'h0} ); + + //* A= 11 B= 13 M= b A*B= 4 Ar= 2 Br= a Ar*Br= 5 A*B= 4 + + test_mont_prod( 1, {32'h2, 8160'h0}, {32'ha, 8160'h0}, {32'h0b,8160'h0}, {32'h5,8160'h0} ); + + //* A= 13 B= b M= 11 A*B= 5 Ar= 2 Br= b Ar*Br= 5 A*B= 5 + //* A= 13 B= 11 M= b A*B= 4 Ar= a Br= 2 Ar*Br= 5 A*B= 4 + //* A=10001 B= 11 M= 13 A*B= 7 Ar= 11 Br= 7 Ar*Br= 4 A*B= 7 + //* A=10001 B= 13 M= 11 A*B= 4 Ar= 2 Br= 2 Ar*Br= 4 A*B= 4 + //* A= 11 B=10001 M= 13 A*B= 7 Ar= 7 Br= 11 Ar*Br= 4 A*B= 7 + //* A= 11 B= 13 M=10001 A*B=143 Ar= 11 Br= 13 Ar*Br=143 A*B=143 + //* A= 13 B=10001 M= 11 A*B= 4 Ar= 2 Br= 2 Ar*Br= 4 A*B= 4 + //* A= 13 B= 11 M=10001 A*B=143 Ar= 13 Br= 11 Ar*Br=143 A*B=143 + //* A=10001 B= 11 M=7fffffff A*B=110011 Ar=20002 Br= 22 Ar*Br=220022 A*B=110011 + //* A=10001 B=7fffffff M= 11 A*B= 10 Ar= 2 Br= 8 Ar*Br= 10 A*B= 10 + //* A= 11 B=10001 M=7fffffff A*B=110011 Ar= 22 Br=20002 Ar*Br=220022 A*B=110011 + //* A= 11 B=7fffffff M=10001 A*B=7ff8 Ar= 11 Br=8000 Ar*Br=7ff8 A*B=7ff8 + //* A=7fffffff B=10001 M= 11 A*B= 10 Ar= 8 Br= 2 Ar*Br= 10 A*B= 10 + //* A=7fffffff B= 11 M=10001 A*B=7ff8 Ar=8000 Br= 11 Ar*Br=7ff8 A*B=7ff8 + + //debug A => 0 0 1 + //debug B => 0 0 4000 + //debug M => 1ffffff ffffffff ffffffff + //debug s => 0 0 80 + test_mont_prod( 3, {96'h1, 8096'h0}, {96'h4000, 8096'h0}, {96'h1ffffffffffffffffffffff,8096'h0}, {96'h80,8096'h0} ); + end + endtask // short_tests + + + //---------------------------------------------------------------- + // long_tests() + // + // Longer, tests with real operand sizes. + //---------------------------------------------------------------- + task long_tests(); + begin + //debug A => 00000000 098b0437 ae647838 09d930b9 a1d269d5 03579a63 9c4e3ac5 fd070836 413389c2 321cfe8b a6a5732e bc7cbcf8 a2f1df87 19f7a767 43ef9b5d 6bd33597 23bfc574 8ec046da 5419d7ff 31811123 740b227b 709f3ace e53ba5cc 38cbc161 a0c15c88 64f26a18 423692ef a5e52a20 80d9f244 717aa2d5 e1a6680a b29eed64 57c6b005 + //debug B => 00000000 098b0437 ae647838 09d930b9 a1d269d5 03579a63 9c4e3ac5 fd070836 413389c2 321cfe8b a6a5732e bc7cbcf8 a2f1df87 19f7a767 43ef9b5d 6bd33597 23bfc574 8ec046da 5419d7ff 31811123 740b227b 709f3ace e53ba5cc 38cbc161 a0c15c88 64f26a18 423692ef a5e52a20 80d9f244 717aa2d5 e1a6680a b29eed64 57c6b005 + //debug M => 00000000 f14b5a0a 122ff247 85813db2 02c0d3af bd0a4615 2889ff7d 8f655e9e c866e586 f21003a0 e969769b 127ec8a5 67f07708 217775f7 7654cabc 3a624f9b 4074bdf1 55fa84c0 0354fe59 0ad04cfd 14e666c0 ce6cea72 788c31f4 edcf3dd7 3a5a59c1 b9b3ef41 565df033 69a82de8 f18c2793 0abd5502 f3730ec0 d1943dc4 a660a267 + //debug s => 00000000 0a8a4a44 40e5c3b0 a05383c2 4ad92fc9 0af7b72e d22fa180 f3a99e64 38ffbe72 3854bc5e 93fffa55 ce49b2cf f809c9eb 81176d8b 4f8b942c 3de18f9c 6393a70a 89924a58 5684cb90 acfd1bde b408b2c0 a8d862c1 74b5a10d 90532d4e 79fe2f50 430decda 0ed75e0a ac354c46 69ce0bd8 eb36e857 b55623d1 527b9711 86cd4d75 + + test_mont_prod(33, + { 1056'h098b0437ae64783809d930b9a1d269d503579a639c4e3ac5fd070836413389c2321cfe8ba6a5732ebc7cbcf8a2f1df8719f7a76743ef9b5d6bd3359723bfc5748ec046da5419d7ff31811123740b227b709f3acee53ba5cc38cbc161a0c15c8864f26a18423692efa5e52a2080d9f244717aa2d5e1a6680ab29eed6457c6b005 + , 7136'h0 }, + { 1056'h098b0437ae64783809d930b9a1d269d503579a639c4e3ac5fd070836413389c2321cfe8ba6a5732ebc7cbcf8a2f1df8719f7a76743ef9b5d6bd3359723bfc5748ec046da5419d7ff31811123740b227b709f3acee53ba5cc38cbc161a0c15c8864f26a18423692efa5e52a2080d9f244717aa2d5e1a6680ab29eed6457c6b005 + , 7136'h0 }, + {1056'hf14b5a0a122ff24785813db202c0d3afbd0a46152889ff7d8f655e9ec866e586f21003a0e969769b127ec8a567f07708217775f77654cabc3a624f9b4074bdf155fa84c00354fe590ad04cfd14e666c0ce6cea72788c31f4edcf3dd73a5a59c1b9b3ef41565df03369a82de8f18c27930abd5502f3730ec0d1943dc4a660a267 + , 7136'h0 }, + {1056'h0a8a4a4440e5c3b0a05383c24ad92fc90af7b72ed22fa180f3a99e6438ffbe723854bc5e93fffa55ce49b2cff809c9eb81176d8b4f8b942c3de18f9c6393a70a89924a585684cb90acfd1bdeb408b2c0a8d862c174b5a10d90532d4e79fe2f50430decda0ed75e0aac354c4669ce0bd8eb36e857b55623d1527b971186cd4d75 + , 7136'h0 }); - $display("*** test stopped"); - end -endtask - -//---------------------------------------------------------------- -// The main test functionality. -//---------------------------------------------------------------- -initial - begin : montgomery_product_tests - $display(" -- Testbench for montprod started --"); - init_sim(); - reset_dut(); - -//* A= b B= 11 M= 13 A*B= 10 Ar= 9 Br= 7 Ar*Br= 1 A*B= 10 - - test_mont_prod( 1, {32'h9, 8160'h0}, {32'h7, 8160'h0}, {32'h13,8160'h0}, {32'h1,8160'h0} ); - -//* A= b B= 13 M= 11 A*B= 5 Ar= b Br= 2 Ar*Br= 5 A*B= 5 - - test_mont_prod( 1, {32'hb, 8160'h0}, {32'h2, 8160'h0}, {32'h11,8160'h0}, {32'h5,8160'h0} ); - -//* A= 11 B= b M= 13 A*B= 10 Ar= 7 Br= 9 Ar*Br= 1 A*B= 10 - - test_mont_prod( 1, {32'h7, 8160'h0}, {32'h9, 8160'h0}, {32'h13,8160'h0}, {32'h1,8160'h0} ); - -//* A= 11 B= 13 M= b A*B= 4 Ar= 2 Br= a Ar*Br= 5 A*B= 4 - - test_mont_prod( 1, {32'h2, 8160'h0}, {32'ha, 8160'h0}, {32'h0b,8160'h0}, {32'h5,8160'h0} ); - -//* A= 13 B= b M= 11 A*B= 5 Ar= 2 Br= b Ar*Br= 5 A*B= 5 -//* A= 13 B= 11 M= b A*B= 4 Ar= a Br= 2 Ar*Br= 5 A*B= 4 -//* A=10001 B= 11 M= 13 A*B= 7 Ar= 11 Br= 7 Ar*Br= 4 A*B= 7 -//* A=10001 B= 13 M= 11 A*B= 4 Ar= 2 Br= 2 Ar*Br= 4 A*B= 4 -//* A= 11 B=10001 M= 13 A*B= 7 Ar= 7 Br= 11 Ar*Br= 4 A*B= 7 -//* A= 11 B= 13 M=10001 A*B=143 Ar= 11 Br= 13 Ar*Br=143 A*B=143 -//* A= 13 B=10001 M= 11 A*B= 4 Ar= 2 Br= 2 Ar*Br= 4 A*B= 4 -//* A= 13 B= 11 M=10001 A*B=143 Ar= 13 Br= 11 Ar*Br=143 A*B=143 -//* A=10001 B= 11 M=7fffffff A*B=110011 Ar=20002 Br= 22 Ar*Br=220022 A*B=110011 -//* A=10001 B=7fffffff M= 11 A*B= 10 Ar= 2 Br= 8 Ar*Br= 10 A*B= 10 -//* A= 11 B=10001 M=7fffffff A*B=110011 Ar= 22 Br=20002 Ar*Br=220022 A*B=110011 -//* A= 11 B=7fffffff M=10001 A*B=7ff8 Ar= 11 Br=8000 Ar*Br=7ff8 A*B=7ff8 -//* A=7fffffff B=10001 M= 11 A*B= 10 Ar= 8 Br= 2 Ar*Br= 10 A*B= 10 -//* A=7fffffff B= 11 M=10001 A*B=7ff8 Ar=8000 Br= 11 Ar*Br=7ff8 A*B=7ff8 - - //debug A => 0 0 1 - //debug B => 0 0 4000 - //debug M => 1ffffff ffffffff ffffffff - //debug s => 0 0 80 - test_mont_prod( 3, {96'h1, 8096'h0}, {96'h4000, 8096'h0}, {96'h1ffffffffffffffffffffff,8096'h0}, {96'h80,8096'h0} ); - - //debug A => 00000000 098b0437 ae647838 09d930b9 a1d269d5 03579a63 9c4e3ac5 fd070836 413389c2 321cfe8b a6a5732e bc7cbcf8 a2f1df87 19f7a767 43ef9b5d 6bd33597 23bfc574 8ec046da 5419d7ff 31811123 740b227b 709f3ace e53ba5cc 38cbc161 a0c15c88 64f26a18 423692ef a5e52a20 80d9f244 717aa2d5 e1a6680a b29eed64 57c6b005 - //debug B => 00000000 098b0437 ae647838 09d930b9 a1d269d5 03579a63 9c4e3ac5 fd070836 413389c2 321cfe8b a6a5732e bc7cbcf8 a2f1df87 19f7a767 43ef9b5d 6bd33597 23bfc574 8ec046da 5419d7ff 31811123 740b227b 709f3ace e53ba5cc 38cbc161 a0c15c88 64f26a18 423692ef a5e52a20 80d9f244 717aa2d5 e1a6680a b29eed64 57c6b005 - //debug M => 00000000 f14b5a0a 122ff247 85813db2 02c0d3af bd0a4615 2889ff7d 8f655e9e c866e586 f21003a0 e969769b 127ec8a5 67f07708 217775f7 7654cabc 3a624f9b 4074bdf1 55fa84c0 0354fe59 0ad04cfd 14e666c0 ce6cea72 788c31f4 edcf3dd7 3a5a59c1 b9b3ef41 565df033 69a82de8 f18c2793 0abd5502 f3730ec0 d1943dc4 a660a267 - //debug s => 00000000 0a8a4a44 40e5c3b0 a05383c2 4ad92fc9 0af7b72e d22fa180 f3a99e64 38ffbe72 3854bc5e 93fffa55 ce49b2cf f809c9eb 81176d8b 4f8b942c 3de18f9c 6393a70a 89924a58 5684cb90 acfd1bde b408b2c0 a8d862c1 74b5a10d 90532d4e 79fe2f50 430decda 0ed75e0a ac354c46 69ce0bd8 eb36e857 b55623d1 527b9711 86cd4d75 - - test_mont_prod( - 33, -{ 1056'h098b0437ae64783809d930b9a1d269d503579a639c4e3ac5fd070836413389c2321cfe8ba6a5732ebc7cbcf8a2f1df8719f7a76743ef9b5d6bd3359723bfc5748ec046da5419d7ff31811123740b227b709f3acee53ba5cc38cbc161a0c15c8864f26a18423692efa5e52a2080d9f244717aa2d5e1a6680ab29eed6457c6b005 -, 7136'h0 }, -{ 1056'h098b0437ae64783809d930b9a1d269d503579a639c4e3ac5fd070836413389c2321cfe8ba6a5732ebc7cbcf8a2f1df8719f7a76743ef9b5d6bd3359723bfc5748ec046da5419d7ff31811123740b227b709f3acee53ba5cc38cbc161a0c15c8864f26a18423692efa5e52a2080d9f244717aa2d5e1a6680ab29eed6457c6b005 -, 7136'h0 }, -{1056'hf14b5a0a122ff24785813db202c0d3afbd0a46152889ff7d8f655e9ec866e586f21003a0e969769b127ec8a567f07708217775f77654cabc3a624f9b4074bdf155fa84c00354fe590ad04cfd14e666c0ce6cea72788c31f4edcf3dd73a5a59c1b9b3ef41565df03369a82de8f18c27930abd5502f3730ec0d1943dc4a660a267 -, 7136'h0 }, -{1056'h0a8a4a4440e5c3b0a05383c24ad92fc90af7b72ed22fa180f3a99e6438ffbe723854bc5e93fffa55ce49b2cff809c9eb81176d8b4f8b942c3de18f9c6393a70a89924a585684cb90acfd1bdeb408b2c0a8d862c174b5a10d90532d4e79fe2f50430decda0ed75e0aac354c4669ce0bd8eb36e857b55623d1527b971186cd4d75 -, 7136'h0 }); - - $display(" -- Testbench for montprod done. --"); - $display(" tests success: %d", test_mont_prod_success); - $display(" tests failed: %d", test_mont_prod_fail); - $finish; - end // montprod + end + endtask // long_tests + + + //---------------------------------------------------------------- + // The main test functionality. + //---------------------------------------------------------------- + initial + begin : montgomery_product_tests + $display(" -- Testbench for montprod started --"); + init_sim(); + reset_dut(); + + short_tests(); +// long_tests(); + + $display(" -- Testbench for montprod done. --"); + $display(" tests success: %d", test_mont_prod_success); + $display(" tests failed: %d", test_mont_prod_fail); + $finish; + end // montprod endmodule // tb_montprod //====================================================================== |