diff options
35 files changed, 2185 insertions, 6983 deletions
diff --git a/bench/ecdsa256_test_vector_nsa.vh b/bench/ecdsa256_test_vector_nsa.vh new file mode 100644 index 0000000..e62b657 --- /dev/null +++ b/bench/ecdsa256_test_vector_nsa.vh @@ -0,0 +1,26 @@ +/* Values from "Suite B Implementer's Guide to FIPS 186-3 (ECDSA)" */ + +localparam [255:0] ECDSA_P256_D_NSA = + {32'h70a12c2d, 32'hb16845ed, 32'h56ff68cf, 32'hc21a472b, + 32'h3f04d7d6, 32'h851bf634, 32'h9f2d7d5b, 32'h3452b38a}; + +localparam [255:0] ECDSA_P256_QX_NSA = + {32'h8101ece4, 32'h7464a6ea, 32'hd70cf69a, 32'h6e2bd3d8, + 32'h8691a326, 32'h2d22cba4, 32'hf7635eaf, 32'hf26680a8}; + +localparam [255:0] ECDSA_P256_QY_NSA = + {32'hd8a12ba6, 32'h1d599235, 32'hf67d9cb4, 32'hd58f1783, + 32'hd3ca43e7, 32'h8f0a5aba, 32'ha6240799, 32'h36c0c3a9}; + +localparam [255:0] ECDSA_P256_K_NSA = + {32'h580ec00d, 32'h85643433, 32'h4cef3f71, 32'hecaed496, + 32'h5b12ae37, 32'hfa47055b, 32'h1965c7b1, 32'h34ee45d0}; + +localparam [255:0] ECDSA_P256_RX_NSA = + {32'h7214bc96, 32'h47160bbd, 32'h39ff2f80, 32'h533f5dc6, + 32'hddd70ddf, 32'h86bb8156, 32'h61e805d5, 32'hd4e6f27c}; + +localparam [255:0] ECDSA_P256_RY_NSA = + {32'h8b81e3e9, 32'h77597110, 32'hc7cf2633, 32'h435b2294, + 32'hb7264298, 32'h7defd3d4, 32'h007e1cfc, 32'h5df84541}; + diff --git a/bench/ecdsa_test_vector_randomized.vh b/bench/ecdsa_test_vector_randomized.vh new file mode 100644 index 0000000..6c5cf80 --- /dev/null +++ b/bench/ecdsa_test_vector_randomized.vh @@ -0,0 +1,29 @@ +/* Generated automatically, do not edit. */ + +localparam [255:0] ECDSA_P256_D_RANDOM = + {32'h503e58af, 32'hcf3af333, 32'h7bf53409, 32'h445012b8, + 32'h1fb4548c, 32'h4d2b1302, 32'ha617f9b1, 32'hd00d7de0}; + +localparam [255:0] ECDSA_P256_QX_RANDOM = + {32'hd9349b48, 32'hb0ee8c36, 32'h139b1d78, 32'hedc1911b, + 32'h250877fb, 32'h7ad44ae1, 32'h8bb2f8a6, 32'hf4dccae5}; + +localparam [255:0] ECDSA_P256_QY_RANDOM = + {32'he0a056e8, 32'hb5092a6c, 32'h728f4bc8, 32'h9043fbe2, + 32'h7c262744, 32'hdfbdaf17, 32'h83fc2e01, 32'hb060771b}; + +localparam [383:0] ECDSA_P384_D_RANDOM = + {32'hbb4a09d8, 32'he527f062, 32'h665eb4d0, 32'hb39a1dce, + 32'h94daa2c5, 32'h935b3163, 32'hb090f079, 32'h3ee36a5a, + 32'h62a7055d, 32'h5d850d1b, 32'h15dc656d, 32'h65d8b3a2}; + +localparam [383:0] ECDSA_P384_QX_RANDOM = + {32'hb8023e60, 32'hae42ea14, 32'h6330f2c3, 32'h883096ca, + 32'h961b11f5, 32'hdfea4a1d, 32'h65e98e64, 32'hb33527fb, + 32'h57226db4, 32'h8a514325, 32'h1ef06bde, 32'hf78eb57a}; + +localparam [383:0] ECDSA_P384_QY_RANDOM = + {32'hd3c66469, 32'h625aaaad, 32'ha347e103, 32'h3c1474b6, + 32'h343a9368, 32'hff294501, 32'hbbd53b1c, 32'hc49fd972, + 32'hda439c9d, 32'ha827e230, 32'h2720e2b7, 32'h8dd14f9e}; + diff --git a/bench/tb_curve_adder_256.v b/bench/tb_curve_adder_256.v deleted file mode 100644 index c9b50ce..0000000 --- a/bench/tb_curve_adder_256.v +++ /dev/null @@ -1,420 +0,0 @@ -//------------------------------------------------------------------------------ -// -// tb_curve_adder_256.v -// ----------------------------------------------------------------------------- -// Testbench for 256-bit curve point adder. -// -// Authors: Pavel Shatov -// -// Copyright (c) 2016, NORDUnet A/S -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the NORDUnet nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -`timescale 1ns / 1ps -//------------------------------------------------------------------------------ - -module tb_curve_adder_256; - - - // - // Test Vectors - // - localparam [255:0] PX_1 = 256'ha536512112e4bb911ae72744a914761ddc53700f889c88e583e0edd45c179b08; - localparam [255:0] PY_1 = 256'h239e73bf40f4831ab71ccea072291893ac8582982ea6fec6bd6aaf36ac32d22e; - localparam [255:0] PZ_1 = 256'h32258ae04c5498bb34b29c54a7f95afc10c009540c51731eae164750ca385029; - - localparam [255:0] RX_1 = 256'he4fcdd1a151b405b2a567d20d7674031c6d5b207b0b5dcf277015d81784492d5; - localparam [255:0] RY_1 = 256'h4782c540b58988b07bb8e0c5ad3ff562dd45c075a39ee71896d5eb33702dd656; - localparam [255:0] RZ_1 = 256'hae637ff2fd5468780241afb3a8ebaeb8618e86b4a1a211b350546c9e6fea93d4; - - localparam [255:0] PX_2 = 256'he58a6470e038f6b261d5a9a72fb2bd96b6bad433ff7baea6a40b5facf5085189; - localparam [255:0] PY_2 = 256'h03dd8785b592307811ee5512e2d713c5dc65f60f01883340fe0f56f858a39474; - localparam [255:0] PZ_2 = 256'h1b4657b1e79c9074fbf7f63f96ce2854db4808afc72841fac623dc68d9bff64d; - - localparam [255:0] RX_2 = 256'hc354e99a827a3f1c30f29f6b1d72273eb0daaeb06bb373ed315e305b89d857ca; - localparam [255:0] RY_2 = 256'h0cb054f95589c1fcbe763df3b8d7badd568d5e93a667076dddfc70dcfab74948; - localparam [255:0] RZ_2 = 256'hd79d9170dd628aee82d149715a6ec6cc44426ccae236d2a146edbd15a564ea53; - - localparam [255:0] PX_3 = 256'hbf5fe30c79025a0b638b0fd62bf1349aee0a9fc7fc2719291b0c23535c16eb52; - localparam [255:0] PY_3 = 256'h8a637c7c0b9459de664d40a717e1abc0f843f03169fae943e0835cbe767da06b; - localparam [255:0] PZ_3 = 256'h0871d93601d654216912866514a788a92e8a9b6047611bf185d459e204727377; - - localparam [255:0] RX_3 = 256'h1ba6259b5b750e4d6e4f490f661646cd9491be16965f47044ac2688048e567c5; - localparam [255:0] RY_3 = 256'h80e55c16f403f8d7282bca628477771a45330567caa5aaab9a54919dbe05e3e4; - localparam [255:0] RZ_3 = 256'hb99663f045c9602b05f23aaaa508e6167d15740be900175dbeceb957a9dad951; - - localparam [255:0] PX_4 = 256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; - localparam [255:0] PY_4 = 256'hxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; - localparam [255:0] PZ_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - - localparam [255:0] RX_4 = 256'h6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296; // G.x - localparam [255:0] RY_4 = 256'h4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5; // G.y - localparam [255:0] RZ_4 = 256'h0000000000000000000000000000000000000000000000000000000000000001; - - localparam [255:0] PX_5 = 256'h6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296; // G.x - localparam [255:0] PY_5 = 256'h4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5; // G.y - localparam [255:0] PZ_5 = 256'h0000000000000000000000000000000000000000000000000000000000000001; - - localparam [255:0] RX_5 = 256'h29d05c193da77b710e86323538b77e1b11f904fea42998be16bd8d744ece7ad0; // H.x - localparam [255:0] RY_5 = 256'hb01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae07; // H.y - localparam [255:0] RZ_5 = 256'h0000000000000000000000000000000000000000000000000000000000000001; - - localparam [255:0] PX_6 = 256'h6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296; // G.x - localparam [255:0] PY_6 = 256'h4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5; // G.y - localparam [255:0] PZ_6 = 256'h0000000000000000000000000000000000000000000000000000000000000001; - - localparam [255:0] RX_6 = 256'h0000000000000000000000000000000000000000000000000000000000000001; - localparam [255:0] RY_6 = 256'h0000000000000000000000000000000000000000000000000000000000000001; - localparam [255:0] RZ_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - - localparam [255:0] Q = 256'hffffffff00000001000000000000000000000000ffffffffffffffffffffffff; - - - // - // Core Parameters - // - localparam WORD_COUNTER_WIDTH = 3; - localparam OPERAND_NUM_WORDS = 8; - - - // - // Clock (100 MHz) - // - reg clk = 1'b0; - always #5 clk = ~clk; - - - // - // Inputs, Outputs - // - reg rst_n; - reg ena; - wire rdy; - - - // - // Buffers (PX, PY, PZ, RX, RY, RZ, Q) - // - wire [WORD_COUNTER_WIDTH-1:0] core_px_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_py_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_pz_addr; - - wire [WORD_COUNTER_WIDTH-1:0] core_rx_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_ry_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_rz_addr; - - wire [WORD_COUNTER_WIDTH-1:0] core_q_addr; - - wire core_rx_wren; - wire core_ry_wren; - wire core_rz_wren; - - wire [ 32-1:0] core_px_data; - wire [ 32-1:0] core_py_data; - wire [ 32-1:0] core_pz_data; - - wire [ 32-1:0] core_rx_data_wr; - wire [ 32-1:0] core_ry_data_wr; - wire [ 32-1:0] core_rz_data_wr; - - wire [ 32-1:0] core_rx_data_rd; - wire [ 32-1:0] core_ry_data_rd; - wire [ 32-1:0] core_rz_data_rd; - - wire [ 32-1:0] core_q_data; - - reg [WORD_COUNTER_WIDTH-1:0] tb_xyzq_addr; - reg tb_xyzq_wren; - - reg [ 31:0] tb_px_data; - reg [ 31:0] tb_py_data; - reg [ 31:0] tb_pz_data; - wire [ 31:0] tb_rx_data; - wire [ 31:0] tb_ry_data; - wire [ 31:0] tb_rz_data; - reg [ 31:0] tb_q_data; - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_px - ( .clk(clk), - .a_addr(tb_xyzq_addr), .a_wr(tb_xyzq_wren), .a_in(tb_px_data), .a_out(), - .b_addr(core_px_addr), .b_out(core_px_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_py - ( .clk(clk), - .a_addr(tb_xyzq_addr), .a_wr(tb_xyzq_wren), .a_in(tb_py_data), .a_out(), - .b_addr(core_py_addr), .b_out(core_py_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_pz - ( .clk(clk), - .a_addr(tb_xyzq_addr), .a_wr(tb_xyzq_wren), .a_in(tb_pz_data), .a_out(), - .b_addr(core_pz_addr), .b_out(core_pz_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_q - ( .clk(clk), - .a_addr(tb_xyzq_addr), .a_wr(tb_xyzq_wren), .a_in(tb_q_data), .a_out(), - .b_addr(core_q_addr), .b_out(core_q_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_rx - ( .clk(clk), - .a_addr(core_rx_addr), .a_wr(core_rx_wren), .a_in(core_rx_data_wr), .a_out(core_rx_data_rd), - .b_addr(tb_xyzq_addr), .b_out(tb_rx_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_ry - ( .clk(clk), - .a_addr(core_ry_addr), .a_wr(core_ry_wren), .a_in(core_ry_data_wr), .a_out(core_ry_data_rd), - .b_addr(tb_xyzq_addr), .b_out(tb_ry_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_rz - ( .clk(clk), - .a_addr(core_rz_addr), .a_wr(core_rz_wren), .a_in(core_rz_data_wr), .a_out(core_rz_data_rd), - .b_addr(tb_xyzq_addr), .b_out(tb_rz_data) - ); - - - // - // Opcode - // - wire [ 5: 0] add_uop_addr; - wire [19: 0] add_uop; - - uop_add_rom add_rom - ( - .clk (clk), - .addr (add_uop_addr), - .data (add_uop) - ); - - // - // UUT - // - curve_dbl_add_256 uut - ( - .clk (clk), - .rst_n (rst_n), - - .ena (ena), - .rdy (rdy), - - .uop_addr (add_uop_addr), - .uop (add_uop), - - .px_addr (core_px_addr), - .py_addr (core_py_addr), - .pz_addr (core_pz_addr), - .rx_addr (core_rx_addr), - .ry_addr (core_ry_addr), - .rz_addr (core_rz_addr), - .q_addr (core_q_addr), - - .rx_wren (core_rx_wren), - .ry_wren (core_ry_wren), - .rz_wren (core_rz_wren), - - .px_din (core_px_data), - .py_din (core_py_data), - .pz_din (core_pz_data), - .rx_din (core_rx_data_rd), - .ry_din (core_ry_data_rd), - .rz_din (core_rz_data_rd), - .rx_dout (core_rx_data_wr), - .ry_dout (core_ry_data_wr), - .rz_dout (core_rz_data_wr), - .q_din (core_q_data) - ); - - - // - // Testbench Routine - // - reg ok = 1; - initial begin - - /* initialize control inputs */ - rst_n = 0; - ena = 0; - - /* wait for some time */ - #200; - - /* de-assert reset */ - rst_n = 1; - - /* wait for some time */ - #100; - - /* run tests */ - test_curve_adder(PX_1, PY_1, PZ_1, RX_1, RY_1, RZ_1); - test_curve_adder(PX_2, PY_2, PZ_2, RX_2, RY_2, RZ_2); - test_curve_adder(PX_3, PY_3, PZ_3, RX_3, RY_3, RZ_3); - test_curve_adder(PX_4, PY_4, PZ_4, RX_4, RY_4, RZ_4); - test_curve_adder(PX_5, PY_5, PZ_5, RX_5, RY_5, RZ_5); - test_curve_adder(PX_6, Q - PY_6, PZ_6, RX_6, RY_6, RZ_6); - - /* print result */ - if (ok) $display("tb_curve_adder_256: SUCCESS"); - else $display("tb_curve_adder_256: FAILURE"); - // - $finish; - // - end - - - // - // Test Task - // - reg t_ok; - - integer w; - - task test_curve_adder; - - input [255:0] px; - input [255:0] py; - input [255:0] pz; - - input [255:0] rx; - input [255:0] ry; - input [255:0] rz; - - reg [255:0] px_shreg; - reg [255:0] py_shreg; - reg [255:0] pz_shreg; - - reg [255:0] rx_shreg; - reg [255:0] ry_shreg; - reg [255:0] rz_shreg; - - reg [255:0] q_shreg; - - begin - - /* start filling memories */ - tb_xyzq_wren = 1; - - /* initialize shift registers */ - px_shreg = px; - py_shreg = py; - pz_shreg = pz; - q_shreg = Q; - - /* write all the words */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set addresses */ - tb_xyzq_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* set data words */ - tb_px_data = px_shreg[31:0]; - tb_py_data = py_shreg[31:0]; - tb_pz_data = pz_shreg[31:0]; - tb_q_data = q_shreg[31:0]; - - /* shift inputs */ - px_shreg = {{32{1'bX}}, px_shreg[255:32]}; - py_shreg = {{32{1'bX}}, py_shreg[255:32]}; - pz_shreg = {{32{1'bX}}, pz_shreg[255:32]}; - q_shreg = {{32{1'bX}}, q_shreg[255:32]}; - - /* wait for 1 clock tick */ - #10; - - end - - /* wipe addresses */ - tb_xyzq_addr = {WORD_COUNTER_WIDTH{1'bX}}; - - /* wipe data words */ - tb_px_data = {32{1'bX}}; - tb_py_data = {32{1'bX}}; - tb_pz_data = {32{1'bX}}; - tb_q_data = {32{1'bX}}; - - /* stop filling memories */ - tb_xyzq_wren = 0; - - /* start operation */ - ena = 1; - - /* clear flag */ - #10 ena = 0; - - /* wait for operation to complete */ - while (!rdy) #10; - - /* read result */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set address */ - tb_xyzq_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* wait for 1 clock tick */ - #10; - - /* store data word */ - rx_shreg = {tb_rx_data, rx_shreg[255:32]}; - ry_shreg = {tb_ry_data, ry_shreg[255:32]}; - rz_shreg = {tb_rz_data, rz_shreg[255:32]}; - - end - - /* compare */ - t_ok = (rx_shreg == rx) && - (ry_shreg == ry) && - (rz_shreg == rz); - - /* display results */ - $display("test_curve_adder(): %s", t_ok ? "OK" : "ERROR"); - - /* update global flag */ - ok = ok && t_ok; - - end - - endtask - -endmodule - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/bench/tb_curve_doubler_256.v b/bench/tb_curve_doubler_256.v deleted file mode 100644 index c7a1c0f..0000000 --- a/bench/tb_curve_doubler_256.v +++ /dev/null @@ -1,409 +0,0 @@ -//------------------------------------------------------------------------------ -// -// tb_curve_doubler_256.v -// ----------------------------------------------------------------------------- -// Testbench for 256-bit curve point doubler. -// -// Authors: Pavel Shatov -// -// Copyright (c) 2016, NORDUnet A/S -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the NORDUnet nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -`timescale 1ns / 1ps -//------------------------------------------------------------------------------ - -module tb_curve_doubler_256; - - - // - // Test Vectors - // - localparam [255:0] PX_1 = 256'h6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296; - localparam [255:0] PY_1 = 256'h4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5; - localparam [255:0] PZ_1 = 256'h0000000000000000000000000000000000000000000000000000000000000001; - - localparam [255:0] RX_1 = 256'h9a978f59acd1b5ad570e7d52dcfcde43804b42274f61ddcf1e7d848391d6c70f; - localparam [255:0] RY_1 = 256'h4126885e7f786af905338238e5346d5fe77fc46388668bd0fd59be3190d2f5d1; - localparam [255:0] RZ_1 = 256'h9fc685c5fc34ff371dcfd694f81f3c2c579c66aed662bd9d976c80d06f7ea3ea; - - localparam [255:0] PX_2 = 256'h0ec88440c8b00a9e572bf1bceb7d0c5906bd65990a9b7081130bd72e2c136ca0; - localparam [255:0] PY_2 = 256'hc0bc77e1339e899101f8e8eccf79c3f7f4bbdd1bf96f6446199bd423026a60d6; - localparam [255:0] PZ_2 = 256'hdd27cb52a31d1f6e041accf1103de05ba0a5edd74b738d51fe3397de0e3fc306; - - localparam [255:0] RX_2 = 256'he6afae63e774df21244609cb4c35d17d28b36b8b9fb7c58929af247f34ac72f9; - localparam [255:0] RY_2 = 256'h061076db7a5745adc90b2e9eebe0ad6482309690f50b60835c265cf83a1b34eb; - localparam [255:0] RZ_2 = 256'h1b6bfd04f2a41d68e85423655db1142d97ebaec0c67c450408f427e35c4f054f; - - localparam [255:0] PX_3 = 256'hb0f824c88ec62df89912ca9ffbcbbb4ffb4d80f8a7d7b4a992273261a2f7be7f; - localparam [255:0] PY_3 = 256'h403e34c78c2b816fce2b1f8d73cfeef28113b8de8bda4a447d17b619bef73705; - localparam [255:0] PZ_3 = 256'h0e3e81bb8e954f3164ae54a6cffa7fcc9631dfddee55fac61e46415f1f5fe5e2; - - localparam [255:0] RX_3 = 256'hd4e725920c88cc2f57847a315f3b6c180abb278b8fa2a47da3d1a191a8c29e19; - localparam [255:0] RY_3 = 256'ha798ad8dbd66c98b53414ab1d04b0f871929a90fea996c88b96d9d68eb8eb0dc; - localparam [255:0] RZ_3 = 256'ha7ead72c01294eaf2899bb6b84f7d26417e6758e3db29f3b5c2ca8e9911067f5; - - localparam [255:0] PX_4 = 256'hXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX; - localparam [255:0] PY_4 = 256'hXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX; - localparam [255:0] PZ_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - - localparam [255:0] RX_4 = 256'h0000000000000000000000000000000000000000000000000000000000000001; - localparam [255:0] RY_4 = 256'h0000000000000000000000000000000000000000000000000000000000000001; - localparam [255:0] RZ_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - - localparam [255:0] Q = 256'hffffffff00000001000000000000000000000000ffffffffffffffffffffffff; - - - - // - // TODO: Test special cases! - // - - - // - // Core Parameters - // - localparam WORD_COUNTER_WIDTH = 3; - localparam OPERAND_NUM_WORDS = 8; - - - // - // Clock (100 MHz) - // - reg clk = 1'b0; - always #5 clk = ~clk; - - - // - // Inputs, Outputs - // - reg rst_n; - reg ena; - wire rdy; - - - // - // Buffers (PX, PY, PZ, RX, RY, RZ, Q) - // - wire [WORD_COUNTER_WIDTH-1:0] core_px_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_py_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_pz_addr; - - wire [WORD_COUNTER_WIDTH-1:0] core_rx_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_ry_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_rz_addr; - - wire [WORD_COUNTER_WIDTH-1:0] core_q_addr; - - wire core_rx_wren; - wire core_ry_wren; - wire core_rz_wren; - - wire [ 32-1:0] core_px_data; - wire [ 32-1:0] core_py_data; - wire [ 32-1:0] core_pz_data; - - wire [ 32-1:0] core_rx_data_wr; - wire [ 32-1:0] core_ry_data_wr; - wire [ 32-1:0] core_rz_data_wr; - - wire [ 32-1:0] core_rx_data_rd; - wire [ 32-1:0] core_ry_data_rd; - wire [ 32-1:0] core_rz_data_rd; - - wire [ 32-1:0] core_q_data; - - reg [WORD_COUNTER_WIDTH-1:0] tb_xyzq_addr; - reg tb_xyzq_wren; - - reg [ 31:0] tb_px_data; - reg [ 31:0] tb_py_data; - reg [ 31:0] tb_pz_data; - wire [ 31:0] tb_rx_data; - wire [ 31:0] tb_ry_data; - wire [ 31:0] tb_rz_data; - reg [ 31:0] tb_q_data; - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_px - ( .clk(clk), - .a_addr(tb_xyzq_addr), .a_wr(tb_xyzq_wren), .a_in(tb_px_data), .a_out(), - .b_addr(core_px_addr), .b_out(core_px_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_py - ( .clk(clk), - .a_addr(tb_xyzq_addr), .a_wr(tb_xyzq_wren), .a_in(tb_py_data), .a_out(), - .b_addr(core_py_addr), .b_out(core_py_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_pz - ( .clk(clk), - .a_addr(tb_xyzq_addr), .a_wr(tb_xyzq_wren), .a_in(tb_pz_data), .a_out(), - .b_addr(core_pz_addr), .b_out(core_pz_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_q - ( .clk(clk), - .a_addr(tb_xyzq_addr), .a_wr(tb_xyzq_wren), .a_in(tb_q_data), .a_out(), - .b_addr(core_q_addr), .b_out(core_q_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_rx - ( .clk(clk), - .a_addr(core_rx_addr), .a_wr(core_rx_wren), .a_in(core_rx_data_wr), .a_out(core_rx_data_rd), - .b_addr(tb_xyzq_addr), .b_out(tb_rx_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_ry - ( .clk(clk), - .a_addr(core_ry_addr), .a_wr(core_ry_wren), .a_in(core_ry_data_wr), .a_out(core_ry_data_rd), - .b_addr(tb_xyzq_addr), .b_out(tb_ry_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_rz - ( .clk(clk), - .a_addr(core_rz_addr), .a_wr(core_rz_wren), .a_in(core_rz_data_wr), .a_out(core_rz_data_rd), - .b_addr(tb_xyzq_addr), .b_out(tb_rz_data) - ); - - - // - // Opcode - // - wire [ 5: 0] dbl_uop_addr; - wire [19: 0] dbl_uop; - - uop_dbl_rom dbl_rom - ( - .clk (clk), - .addr (dbl_uop_addr), - .data (dbl_uop) - ); - - - // - // UUT - // - curve_dbl_add_256 uut - ( - .clk (clk), - .rst_n (rst_n), - - .ena (ena), - .rdy (rdy), - - .uop_addr (dbl_uop_addr), - .uop (dbl_uop), - - .px_addr (core_px_addr), - .py_addr (core_py_addr), - .pz_addr (core_pz_addr), - .rx_addr (core_rx_addr), - .ry_addr (core_ry_addr), - .rz_addr (core_rz_addr), - .q_addr (core_q_addr), - - .rx_wren (core_rx_wren), - .ry_wren (core_ry_wren), - .rz_wren (core_rz_wren), - - .px_din (core_px_data), - .py_din (core_py_data), - .pz_din (core_pz_data), - .rx_din (core_rx_data_rd), - .ry_din (core_ry_data_rd), - .rz_din (core_rz_data_rd), - .rx_dout (core_rx_data_wr), - .ry_dout (core_ry_data_wr), - .rz_dout (core_rz_data_wr), - .q_din (core_q_data) - ); - - - // - // Testbench Routine - // - reg ok = 1; - initial begin - - /* initialize control inputs */ - rst_n = 0; - ena = 0; - - /* wait for some time */ - #200; - - /* de-assert reset */ - rst_n = 1; - - /* wait for some time */ - #100; - - /* run tests */ - test_curve_doubler(PX_1, PY_1, PZ_1, RX_1, RY_1, RZ_1); - test_curve_doubler(PX_2, PY_2, PZ_2, RX_2, RY_2, RZ_2); - test_curve_doubler(PX_3, PY_3, PZ_3, RX_3, RY_3, RZ_3); - test_curve_doubler(PX_4, PY_4, PZ_4, RX_4, RY_4, RZ_4); - - /* print result */ - if (ok) $display("tb_curve_doubler_256: SUCCESS"); - else $display("tb_curve_doubler_256: FAILURE"); - // - // $finish; - // - end - - - // - // Test Task - // - reg t_ok; - - integer w; - - task test_curve_doubler; - - input [255:0] px; - input [255:0] py; - input [255:0] pz; - - input [255:0] rx; - input [255:0] ry; - input [255:0] rz; - - reg [255:0] px_shreg; - reg [255:0] py_shreg; - reg [255:0] pz_shreg; - - reg [255:0] rx_shreg; - reg [255:0] ry_shreg; - reg [255:0] rz_shreg; - - reg [255:0] q_shreg; - - begin - - /* start filling memories */ - tb_xyzq_wren = 1; - - /* initialize shift registers */ - px_shreg = px; - py_shreg = py; - pz_shreg = pz; - q_shreg = Q; - - /* write all the words */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set addresses */ - tb_xyzq_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* set data words */ - tb_px_data = px_shreg[31:0]; - tb_py_data = py_shreg[31:0]; - tb_pz_data = pz_shreg[31:0]; - tb_q_data = q_shreg[31:0]; - - /* shift inputs */ - px_shreg = {{32{1'bX}}, px_shreg[255:32]}; - py_shreg = {{32{1'bX}}, py_shreg[255:32]}; - pz_shreg = {{32{1'bX}}, pz_shreg[255:32]}; - q_shreg = {{32{1'bX}}, q_shreg[255:32]}; - - /* wait for 1 clock tick */ - #10; - - end - - /* wipe addresses */ - tb_xyzq_addr = {WORD_COUNTER_WIDTH{1'bX}}; - - /* wipe data words */ - tb_px_data = {32{1'bX}}; - tb_py_data = {32{1'bX}}; - tb_pz_data = {32{1'bX}}; - tb_q_data = {32{1'bX}}; - - /* stop filling memories */ - tb_xyzq_wren = 0; - - /* start operation */ - ena = 1; - - /* clear flag */ - #10 ena = 0; - - /* wait for operation to complete */ - while (!rdy) #10; - - /* read result */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set address */ - tb_xyzq_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* wait for 1 clock tick */ - #10; - - /* store data word */ - rx_shreg = {tb_rx_data, rx_shreg[255:32]}; - ry_shreg = {tb_ry_data, ry_shreg[255:32]}; - rz_shreg = {tb_rz_data, rz_shreg[255:32]}; - - end - - /* compare */ - t_ok = (rx_shreg == rx) && - (ry_shreg == ry) && - (rz_shreg == rz); - - /* display results */ - $display("test_curve_doubler(): %s", t_ok ? "OK" : "ERROR"); - - /* update global flag */ - ok = ok && t_ok; - - end - - endtask - - -endmodule - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/bench/tb_curve_multiplier_256.v b/bench/tb_curve_multiplier_256.v index c7839e0..a2a6769 100644 --- a/bench/tb_curve_multiplier_256.v +++ b/bench/tb_curve_multiplier_256.v @@ -2,11 +2,11 @@ // // tb_curve_multiplier_256.v // ----------------------------------------------------------------------------- -// Testbench for 256-bit curve point scalar multiplier. +// Testbench for 256-bit curve base point scalar multiplier. // // Authors: Pavel Shatov // -// Copyright (c) 2016, NORDUnet A/S +// Copyright (c) 2016, 2018 NORDUnet A/S // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: @@ -36,265 +36,274 @@ // //------------------------------------------------------------------------------ -//------------------------------------------------------------------------------ -`timescale 1ns / 1ps -//------------------------------------------------------------------------------ - module tb_curve_multiplier_256; - // - // Test Vectors - // - - /* Q = d * G */ - localparam [255:0] K_1 = 256'h70a12c2db16845ed56ff68cfc21a472b3f04d7d6851bf6349f2d7d5b3452b38a; - localparam [255:0] PX_1 = 256'h8101ece47464a6ead70cf69a6e2bd3d88691a3262d22cba4f7635eaff26680a8; - localparam [255:0] PY_1 = 256'hd8a12ba61d599235f67d9cb4d58f1783d3ca43e78f0a5abaa624079936c0c3a9; - - /* R = k * G */ - localparam [255:0] K_2 = 256'h580ec00d856434334cef3f71ecaed4965b12ae37fa47055b1965c7b134ee45d0; - localparam [255:0] PX_2 = 256'h7214bc9647160bbd39ff2f80533f5dc6ddd70ddf86bb815661e805d5d4e6f27c; - localparam [255:0] PY_2 = 256'h8b81e3e977597110c7cf2633435b2294b72642987defd3d4007e1cfc5df84541; - - /* O = n * G */ - localparam [255:0] K_3 = 256'hffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551; - localparam [255:0] PX_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - localparam [255:0] PY_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000; - - /* H = 2 * G */ - localparam [255:0] K_4 = 256'h0000000000000000000000000000000000000000000000000000000000000002; - localparam [255:0] PX_4 = 256'h7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978; - localparam [255:0] PY_4 = 256'h07775510db8ed040293d9ac69f7430dbba7dade63ce982299e04b79d227873d1; - - /* G = (n + 1) * G */ - localparam [255:0] K_5 = 256'hffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 + 'd1; - localparam [255:0] PX_5 = 256'h6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296; - localparam [255:0] PY_5 = 256'h4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5; - - /* H = (n + 2) * G */ - localparam [255:0] K_6 = 256'hffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 + 'd2; - localparam [255:0] PX_6 = 256'h7cf27b188d034f7e8a52380304b51ac3c08969e277f21b35a60b48fc47669978; - localparam [255:0] PY_6 = 256'h07775510db8ed040293d9ac69f7430dbba7dade63ce982299e04b79d227873d1; - - - // - // Core Parameters - // - localparam WORD_COUNTER_WIDTH = 3; - localparam OPERAND_NUM_WORDS = 8; - - - // - // Clock (100 MHz) - // - reg clk = 1'b0; - always #5 clk = ~clk; - - - // - // Inputs, Outputs - // - reg rst_n; - reg ena; - wire rdy; - - - // - // Buffers (K, PX, PY) - // - wire [WORD_COUNTER_WIDTH-1:0] core_k_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_px_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_py_addr; - - wire core_px_wren; - wire core_py_wren; - - wire [ 32-1:0] core_k_data; - wire [ 32-1:0] core_px_data; - wire [ 32-1:0] core_py_data; - - reg [WORD_COUNTER_WIDTH-1:0] tb_k_addr; - reg [WORD_COUNTER_WIDTH-1:0] tb_pxy_addr; - - reg tb_k_wren; - - reg [ 31:0] tb_k_data; - wire [ 31:0] tb_px_data; - wire [ 31:0] tb_py_data; - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_k - ( .clk(clk), - .a_addr(tb_k_addr), .a_wr(tb_k_wren), .a_in(tb_k_data), .a_out(), - .b_addr(core_k_addr), .b_out(core_k_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_px - ( .clk(clk), - .a_addr(core_px_addr), .a_wr(core_px_wren), .a_in(core_px_data), .a_out(), - .b_addr(tb_pxy_addr), .b_out(tb_px_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_py - ( .clk(clk), - .a_addr(core_py_addr), .a_wr(core_py_wren), .a_in(core_py_data), .a_out(), - .b_addr(tb_pxy_addr), .b_out(tb_py_data) - ); - - - // - // UUT - // - curve_mul_256 uut - ( - .clk (clk), - .rst_n (rst_n), - - .ena (ena), - .rdy (rdy), - - .k_addr (core_k_addr), - .rx_addr (core_px_addr), - .ry_addr (core_py_addr), - - .rx_wren (core_px_wren), - .ry_wren (core_py_wren), - - .k_din (core_k_data), - - .rx_dout (core_px_data), - .ry_dout (core_py_data) - ); - - - // - // Testbench Routine - // - reg ok = 1; - initial begin - - /* initialize control inputs */ - rst_n = 0; - ena = 0; - - /* wait for some time */ - #200; - - /* de-assert reset */ - rst_n = 1; - - /* wait for some time */ - #100; - - /* run tests */ - //test_curve_multiplier(K_1, PX_1, PY_1); - //test_curve_multiplier(K_2, PX_2, PY_2); - //test_curve_multiplier(K_3, PX_3, PY_3); - //test_curve_multiplier(K_4, PX_4, PY_4); - //test_curve_multiplier(K_5, PX_5, PY_5); - test_curve_multiplier(K_6, PX_6, PY_6); - - /* print result */ - if (ok) $display("tb_curve_multiplier_256: SUCCESS"); - else $display("tb_curve_multiplier_256: FAILURE"); - // - //$finish; - // - end - - - // - // Test Task - // - reg p_ok; - - integer w; - - task test_curve_multiplier; - - input [255:0] k; - input [255:0] px; - input [255:0] py; - - reg [255:0] k_shreg; - reg [255:0] px_shreg; - reg [255:0] py_shreg; - - begin - - /* start filling memories */ - tb_k_wren = 1; - - /* initialize shift registers */ - k_shreg = k; - - /* write all the words */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set addresses */ - tb_k_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* set data words */ - tb_k_data = k_shreg[31:0]; - - /* shift inputs */ - k_shreg = {{32{1'bX}}, k_shreg[255:32]}; - - /* wait for 1 clock tick */ - #10; - - end - - /* wipe addresses */ - tb_k_addr = {WORD_COUNTER_WIDTH{1'bX}}; - - /* wipe data words */ - tb_k_data = {32{1'bX}}; - - /* stop filling memories */ - tb_k_wren = 0; - - /* start operation */ - ena = 1; - - /* clear flag */ - #10 ena = 0; - - /* wait for operation to complete */ - while (!rdy) #10; - - /* read result */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set address */ - tb_pxy_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* wait for 1 clock tick */ - #10; - - /* store data word */ - px_shreg = {tb_px_data, px_shreg[255:32]}; - py_shreg = {tb_py_data, py_shreg[255:32]}; - - end - - /* compare */ - p_ok = (px_shreg == px) && - (py_shreg == py); - - /* display results */ - $display("test_curve_multiplier(): %s", p_ok ? "OK" : "ERROR"); - - /* update global flag */ - ok = ok && p_ok; - - end - - endtask - + // + // Test Vectors + // + `include "ecdsa256_test_vector_nsa.vh" + `include "ecdsa_test_vector_randomized.vh" + + + // + // Core Parameters + // + localparam WORD_COUNTER_WIDTH = 3; + localparam OPERAND_NUM_WORDS = 8; + + + // + // P-256 Domain Parameters + // + localparam ECDSA_P256_N = + {32'hffffffff, 32'h00000000, 32'hffffffff, 32'hffffffff, + 32'hbce6faad, 32'ha7179e84, 32'hf3b9cac2, 32'hfc632551}; + + localparam ECDSA_P256_GX = + {32'h6b17d1f2, 32'he12c4247, 32'hf8bce6e5, 32'h63a440f2, + 32'h77037d81, 32'h2deb33a0, 32'hf4a13945, 32'hd898c296}; + + localparam ECDSA_P256_GY = + {32'h4fe342e2, 32'hfe1a7f9b, 32'h8ee7eb4a, 32'h7c0f9e16, + 32'h2bce3357, 32'h6b315ece, 32'hcbb64068, 32'h37bf51f5}; + + localparam ECDSA_P256_HX = + {32'h7cf27b18, 32'h8d034f7e, 32'h8a523803, 32'h04b51ac3, + 32'hc08969e2, 32'h77f21b35, 32'ha60b48fc, 32'h47669978}; + + localparam ECDSA_P256_HY = + {32'h07775510, 32'hdb8ed040, 32'h293d9ac6, 32'h9f7430db, + 32'hba7dade6, 32'h3ce98229, 32'h9e04b79d, 32'h227873d1}; + + + // + // Clock (100 MHz) + // + reg clk = 1'b0; + always #5 clk = ~clk; + + + // + // Inputs, Outputs + // + reg rst_n; + reg ena; + wire rdy; + + + // + // Buffers (K, PX, PY) + // + wire [WORD_COUNTER_WIDTH-1:0] core_k_addr; + wire [WORD_COUNTER_WIDTH-1:0] core_pxy_addr; + + wire core_px_wren; + wire core_py_wren; + + wire [ 32-1:0] core_k_data; + wire [ 32-1:0] core_pxy_data; + + reg [WORD_COUNTER_WIDTH-1:0] tb_k_addr; + reg [WORD_COUNTER_WIDTH-1:0] tb_pxy_addr; + + reg tb_k_wren; + + reg [ 31:0] tb_k_data; + wire [ 31:0] tb_px_data; + wire [ 31:0] tb_py_data; + + bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) + bram_k + ( .clk(clk), + .a_addr(tb_k_addr), .a_wr(tb_k_wren), .a_in(tb_k_data), .a_out(), + .b_addr(core_k_addr), .b_out(core_k_data) + ); + + bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) + bram_px + ( .clk(clk), + .a_addr(core_pxy_addr), .a_wr(core_px_wren), .a_in(core_pxy_data), .a_out(), + .b_addr(tb_pxy_addr), .b_out(tb_px_data) + ); + + bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) + bram_py + ( .clk(clk), + .a_addr(core_pxy_addr), .a_wr(core_py_wren), .a_in(core_pxy_data), .a_out(), + .b_addr(tb_pxy_addr), .b_out(tb_py_data) + ); + + + // + // UUT + // + ecdsa256_base_point_multiplier uut + ( + .clk (clk), + .rst_n (rst_n), + + .ena (ena), + .rdy (rdy), + + .k_addr (core_k_addr), + .rxy_addr (core_pxy_addr), + + .rx_wren (core_px_wren), + .ry_wren (core_py_wren), + + .k_din (core_k_data), + + .rxy_dout (core_pxy_data) + ); + + + // + // Testbench Routine + // + reg ok = 1; + initial begin + + /* initialize control inputs */ + rst_n = 0; + ena = 0; + + /* wait for some time */ + #200; + + /* de-assert reset */ + rst_n = 1; + + /* wait for some time */ + #100; + + /* run tests */ + $display("1. Q1 = d1 * G..."); + test_curve_multiplier(ECDSA_P256_D_NSA, ECDSA_P256_QX_NSA, ECDSA_P256_QY_NSA); + + $display("2. R = k * G..."); + test_curve_multiplier(ECDSA_P256_K_NSA, ECDSA_P256_RX_NSA, ECDSA_P256_RY_NSA); + + $display("3. Q2 = d2 * G..."); + test_curve_multiplier(ECDSA_P256_D_RANDOM, ECDSA_P256_QX_RANDOM, ECDSA_P256_QY_RANDOM); + + $display("4. O = n * G..."); + test_curve_multiplier(ECDSA_P256_N, 256'd0, 256'd0); + + $display("5. G = (n + 1) * G..."); + test_curve_multiplier(ECDSA_P256_N + 256'd1, ECDSA_P256_GX, ECDSA_P256_GY); + + $display("6. H = 2 * G..."); + test_curve_multiplier(256'd2, ECDSA_P256_HX, ECDSA_P256_HY); + + $display("7. H = (n + 2) * G..."); + test_curve_multiplier(ECDSA_P256_N + 256'd2, ECDSA_P256_HX, ECDSA_P256_HY); + + /* print result */ + if (ok) $display("tb_curve_multiplier_256: SUCCESS"); + else $display("tb_curve_multiplier_256: FAILURE"); + + //$finish; + + end + + + // + // Test Task + // + reg p_ok; + + integer w; + + task test_curve_multiplier; + + input [255:0] k; + input [255:0] px; + input [255:0] py; + + reg [255:0] k_shreg; + reg [255:0] px_shreg; + reg [255:0] py_shreg; + + begin + + /* start filling memories */ + tb_k_wren = 1; + + /* initialize shift registers */ + k_shreg = k; + + /* write all the words */ + for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin + + /* set addresses */ + tb_k_addr = w[WORD_COUNTER_WIDTH-1:0]; + + /* set data words */ + tb_k_data = k_shreg[31:0]; + + /* shift inputs */ + k_shreg = {{32{1'bX}}, k_shreg[255:32]}; + + /* wait for 1 clock tick */ + #10; + + end + + /* wipe addresses */ + tb_k_addr = {WORD_COUNTER_WIDTH{1'bX}}; + + /* wipe data words */ + tb_k_data = {32{1'bX}}; + + /* stop filling memories */ + tb_k_wren = 0; + + /* start operation */ + ena = 1; + + /* clear flag */ + #10 ena = 0; + + /* wait for operation to complete */ + while (!rdy) #10; + + /* read result */ + for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin + + /* set address */ + tb_pxy_addr = w[WORD_COUNTER_WIDTH-1:0]; + + /* wait for 1 clock tick */ + #10; + + /* store data word */ + px_shreg = {tb_px_data, px_shreg[255:32]}; + py_shreg = {tb_py_data, py_shreg[255:32]}; + + end + + /* compare */ + p_ok = (px_shreg === px) && + (py_shreg === py); + + /* display results */ + if (p_ok) $display("test_curve_multiplier(): OK"); + else begin + $display("test_curve_multiplier(): ERROR"); + $display("ref_px == %x", px); + $display("calc_px == %x", px_shreg); + $display("ref_py == %x", py); + $display("calc_py == %x", py_shreg); + end + + /* update global flag */ + ok = ok && p_ok; + + end + + endtask + endmodule diff --git a/bench/tb_lowlevel_adder32.v b/bench/tb_lowlevel_adder32.v deleted file mode 100644 index 70fbb15..0000000 --- a/bench/tb_lowlevel_adder32.v +++ /dev/null @@ -1,175 +0,0 @@ -//------------------------------------------------------------------------------ -// -// tb_lowlevel_adder32.v -// ----------------------------------------------------------------------------- -// Testbench for 32-bit adder. -// -// Authors: Pavel Shatov -// -// Copyright (c) 2015-2016, NORDUnet A/S -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the NORDUnet nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -`timescale 1ns / 1ps -//------------------------------------------------------------------------------ - - -module tb_lowlevel_adder32; - - // - // Inputs - // - reg clk; - reg [31: 0] a; - reg [31: 0] b; - reg c_in; - - // - // Outputs - // - wire [31: 0] s; - wire c_out; - - // - // Test Vectors {a, b, c_in} - // - wire [64: 0] vec_0 = {32'h00000000, 32'h00000000, 1'b0}; // all zeroes, no carry - wire [64: 0] vec_1 = {32'h00000000, 32'h00000000, 1'b1}; // all zeroes with carry - wire [64: 0] vec_2 = {32'h00000000, 32'hFFFFFFFF, 1'b0}; // zeroes and ones, no carry - wire [64: 0] vec_3 = {32'h00000000, 32'hFFFFFFFF, 1'b1}; // zeroes and ones with carry - wire [64: 0] vec_4 = {32'hFFFFFFFF, 32'h00000000, 1'b0}; // ones and zeroes, no carry - wire [64: 0] vec_5 = {32'hFFFFFFFF, 32'h00000000, 1'b1}; // ones and zeroes with carry - wire [64: 0] vec_6 = {32'hFFFFFFFF, 32'hFFFFFFFF, 1'b0}; // all ones, no carry - wire [64: 0] vec_7 = {32'hFFFFFFFF, 32'hFFFFFFFF, 1'b1}; // all ones with carry - - wire [64: 0] vec_8 = {32'hd898c296, 32'h37bf51f5, 1'b0}; // random values, no carry - wire [64: 0] vec_9 = {32'hf4a13945, 32'hcbb64068, 1'b0}; // random values, no carry - wire [64: 0] vec_10 = {32'h2deb33a0, 32'h6b315ece, 1'b0}; // random values, no carry - wire [64: 0] vec_11 = {32'h77037d81, 32'h2bce3357, 1'b0}; // random values, no carry - wire [64: 0] vec_12 = {32'h63a440f2, 32'h7c0f9e16, 1'b1}; // random values with carry - wire [64: 0] vec_13 = {32'hf8bce6e5, 32'h8ee7eb4a, 1'b1}; // random values with carry - wire [64: 0] vec_14 = {32'he12c4247, 32'hfe1a7f9b, 1'b1}; // random values with carry - wire [64: 0] vec_15 = {32'h6b17d1f2, 32'h4fe342e2, 1'b1}; // random values with carry - - - // - // UUT - // - adder32_wrapper uut - ( - .clk (clk), - .a (a), - .b (b), - .s (s), - .c_in (c_in), - .c_out (c_out) - ); - - - // - // Testbench Routine - // - reg ok = 1; - initial begin - // - clk = 0; - // - #100; - // - test_adder32(vec_0); - test_adder32(vec_1); - test_adder32(vec_2); - test_adder32(vec_3); - test_adder32(vec_4); - test_adder32(vec_5); - test_adder32(vec_6); - test_adder32(vec_7); - // - test_adder32(vec_8); - test_adder32(vec_9); - test_adder32(vec_10); - test_adder32(vec_11); - test_adder32(vec_12); - test_adder32(vec_13); - test_adder32(vec_14); - test_adder32(vec_15); - // - if (ok) $display("tb_lowlevel_adder32: SUCCESS"); - else $display("tb_lowlevel_adder32: FAILURE"); - // - $finish; - // - end - - - // - // Test Routine - // - reg [31: 0] ss; // reference value of sum - reg cc; // reference value of carry - reg ss_ok; // result matches reference value - - task test_adder32; - - input [64: 0] vec; - - begin - - /* break down test vector */ - a = vec[64:33]; - b = vec[32: 1]; - c_in = vec[ 0: 0]; - - /* calculate reference values */ - {cc, ss} = {1'b0, a} + {1'b0, b} + {32'd0, c_in}; - - /* send one clock tick */ - #10 clk = 1; - #10 clk = 0; - - /* check outputs */ - ss_ok = (s == ss) && (c_out == cc); - - /* display results */ - $display("test_adder32(): 0x%08X + 0x%08X + %01d = {%01d, 0x%08X} [%0s]", a, b, c_in, c_out, s, ok ? "OK" : "ERROR"); - - /* update global flag */ - ok = ok && ss_ok; - - end - - endtask - -endmodule - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/bench/tb_lowlevel_adder47.v b/bench/tb_lowlevel_adder47.v deleted file mode 100644 index 663e8f9..0000000 --- a/bench/tb_lowlevel_adder47.v +++ /dev/null @@ -1,151 +0,0 @@ -//------------------------------------------------------------------------------ -// -// tb_lowlevel_adder47.v -// ----------------------------------------------------------------------------- -// Testbench for 47-bit adder. -// -// Authors: Pavel Shatov -// -// Copyright (c) 2016, NORDUnet A/S -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the NORDUnet nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -`timescale 1ns / 1ps -//------------------------------------------------------------------------------ - - -module tb_lowlevel_adder47; - - // - // Inputs - // - reg clk; - reg [46: 0] a; - reg [46: 0] b; - - // - // Outputs - // - wire [46: 0] s; - - // - // Test Vectors {a, b} - // - wire [93: 0] vec_0 = {47'h2a87ca22be8b, 47'h05378eb1c71e}; - wire [93: 0] vec_1 = {47'h7320ad746e1d, 47'h3b628ba79b98}; - wire [93: 0] vec_2 = {47'h59f741e08254, 47'h2a385502f25d}; - wire [93: 0] vec_3 = {47'h3f55296c3a54, 47'h5e3872760ab7}; - wire [93: 0] vec_4 = {47'h3617de4a9626, 47'h2c6f5d9e98bf}; - wire [93: 0] vec_5 = {47'h1292dc29f8f4, 47'h1dbd289a147c}; - wire [93: 0] vec_6 = {47'h69da3113b5f0, 47'h38c00a60b1ce}; - wire [93: 0] vec_7 = {47'h1d7e819d7a43, 47'h1d7c90ea0e5f}; - - // - // UUT - // - adder47_wrapper uut - ( - .clk (clk), - .a (a), - .b (b), - .s (s) - ); - - - // - // Testbench Routine - // - reg ok = 1; - initial begin - // - clk = 0; - // - #100; - // - test_adder47(vec_0); - test_adder47(vec_1); - test_adder47(vec_2); - test_adder47(vec_3); - test_adder47(vec_4); - test_adder47(vec_5); - test_adder47(vec_6); - test_adder47(vec_7); - // - if (ok) $display("tb_lowlevel_adder47: SUCCESS"); - else $display("tb_lowlevel_adder47: FAILURE"); - // - $finish; - // - end - - - // - // Test Routine - // - reg [46: 0] ss; // reference value of sum - reg cc; // reference value of carry - reg ss_ok; // result matches reference value - - task test_adder47; - - input [93: 0] vec; - - begin - - /* break down test vector */ - a = vec[93:47]; - b = vec[46: 0]; - - /* calculate reference values */ - ss = a + b; - - /* send one clock tick */ - #10 clk = 1; - #10 clk = 0; - - /* check outputs */ - ss_ok = (s == ss); - - /* display results */ - $display("test_adder47(): %s", ok ? "OK" : "ERROR"); - - /* update global flag */ - ok = ok && ss_ok; - - end - - endtask - -endmodule - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/bench/tb_lowlevel_subtractor32.v b/bench/tb_lowlevel_subtractor32.v deleted file mode 100644 index fd96000..0000000 --- a/bench/tb_lowlevel_subtractor32.v +++ /dev/null @@ -1,174 +0,0 @@ -//------------------------------------------------------------------------------ -// -// tb_lowlevel_subtractor32.v -// ----------------------------------------------------------------------------- -// Testbench for 32-bit subtractor. -// -// Authors: Pavel Shatov -// -// Copyright (c) 2015-2016, NORDUnet A/S -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the NORDUnet nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -`timescale 1ns / 1ps -//------------------------------------------------------------------------------ - -module tb_lowlevel_subtractor32; - - // - // Inputs - // - reg clk; - reg [31: 0] a; - reg [31: 0] b; - reg b_in; - - // - // Outputs - // - wire [31: 0] d; - wire b_out; - - // - // Test Vectors {a, b, b_in} - // - wire [64: 0] vec_0 = {32'h00000000, 32'h00000000, 1'b0}; // all zeroes, no borrow - wire [64: 0] vec_1 = {32'h00000000, 32'h00000000, 1'b1}; // all zeroes with borrow - wire [64: 0] vec_2 = {32'h00000000, 32'hFFFFFFFF, 1'b0}; // zeroes and ones, no borrow - wire [64: 0] vec_3 = {32'h00000000, 32'hFFFFFFFF, 1'b1}; // zeroes and ones with borrow - wire [64: 0] vec_4 = {32'hFFFFFFFF, 32'h00000000, 1'b0}; // ones and zeroes, no borrow - wire [64: 0] vec_5 = {32'hFFFFFFFF, 32'h00000000, 1'b1}; // ones and zeroes with borrow - wire [64: 0] vec_6 = {32'hFFFFFFFF, 32'hFFFFFFFF, 1'b0}; // all ones, no borrow - wire [64: 0] vec_7 = {32'hFFFFFFFF, 32'hFFFFFFFF, 1'b1}; // all ones with borrow - - wire [64: 0] vec_8 = {32'hd898c296, 32'h37bf51f5, 1'b0}; // random values, no borrow - wire [64: 0] vec_9 = {32'hf4a13945, 32'hcbb64068, 1'b0}; // random values, no borrow - wire [64: 0] vec_10 = {32'h2deb33a0, 32'h6b315ece, 1'b0}; // random values, no borrow - wire [64: 0] vec_11 = {32'h77037d81, 32'h2bce3357, 1'b0}; // random values, no borrow - wire [64: 0] vec_12 = {32'h63a440f2, 32'h7c0f9e16, 1'b1}; // random values with borrow - wire [64: 0] vec_13 = {32'hf8bce6e5, 32'h8ee7eb4a, 1'b1}; // random values with borrow - wire [64: 0] vec_14 = {32'he12c4247, 32'hfe1a7f9b, 1'b1}; // random values with borrow - wire [64: 0] vec_15 = {32'h6b17d1f2, 32'h4fe342e2, 1'b1}; // random values with borrow - - - // - // UUT - // - subtractor32_wrapper uut - ( - .clk (clk), - .a (a), - .b (b), - .d (d), - .b_in (b_in), - .b_out (b_out) - ); - - - // - // Testbench Routine - // - reg ok = 1; - initial begin - // - clk = 0; - // - #100; - // - test_subtractor32(vec_0); - test_subtractor32(vec_1); - test_subtractor32(vec_2); - test_subtractor32(vec_3); - test_subtractor32(vec_4); - test_subtractor32(vec_5); - test_subtractor32(vec_6); - test_subtractor32(vec_7); - // - test_subtractor32(vec_8); - test_subtractor32(vec_9); - test_subtractor32(vec_10); - test_subtractor32(vec_11); - test_subtractor32(vec_12); - test_subtractor32(vec_13); - test_subtractor32(vec_14); - test_subtractor32(vec_15); - // - if (ok) $display("tb_lowlevel_subtractor32: SUCCESS"); - else $display("tb_lowlevel_subtractor32: FAILURE"); - // - $finish; - // - end - - - // - // Test Routine - // - reg [31: 0] dd; // reference value of difference - reg bb; // reference value of borrow - reg dd_ok; // result matches reference value - - task test_subtractor32; - - input [64: 0] vec; - - begin - - /* break down test vector */ - a = vec[64:33]; - b = vec[32: 1]; - b_in = vec[ 0: 0]; - - /* calculate reference values */ - {bb, dd} = {1'b0, a} - {1'b0, b} - {32'd0, b_in}; - - /* send one clock tick */ - #10 clk = 1; - #10 clk = 0; - - /* check outputs */ - dd_ok = (d == dd) && (b_out == bb); - - /* display results */ - $display("test_subtractor32(): 0x%08X - (0x%08X + %01d) = {%01d, 0x%08X} [%0s]", a, b, b_in, b_out, d, dd_ok ? "OK" : "ERROR"); - - /* update global flag */ - ok = ok && dd_ok; - - end - - endtask - -endmodule - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/bench/tb_modular_adder.v b/bench/tb_modular_adder.v deleted file mode 100644 index 713ff22..0000000 --- a/bench/tb_modular_adder.v +++ /dev/null @@ -1,357 +0,0 @@ -//------------------------------------------------------------------------------ -// -// tb_modular_adder_256.v -// ----------------------------------------------------------------------------- -// Testbench for modular multi-word adder. -// -// Authors: Pavel Shatov -// -// Copyright (c) 2016, NORDUnet A/S -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the NORDUnet nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -`timescale 1ns / 1ps -//------------------------------------------------------------------------------ - -module tb_modular_adder_256; - - - // - // Test Vectors - // - localparam [255:0] N = 256'hffffffff00000001000000000000000000000000ffffffffffffffffffffffff; - - localparam [255:0] X_1 = 256'h1ddbd0769df27bab1e234019dad09dccce1e87e2193b417ffa1a3465d7439ecd; - localparam [255:0] Y_1 = 256'h1f67cdc34bac91a072945d212f0a03442fc4855788583ecb7b2e375ad3848210; - - localparam [255:0] X_2 = 256'hff563f653b1392a6fa6b0295a280f7a904a11e22d8ae468e220301d8ac232fcf; - localparam [255:0] Y_2 = 256'hf6f53c4b57b25453b68e923fb118e4f753d74af01fc58476dd15a80933453899; - - - // - // Core Parameters - // - localparam WORD_COUNTER_WIDTH = 3; - localparam OPERAND_NUM_WORDS = 8; - - - // - // Clock (100 MHz) - // - reg clk = 1'b0; - always #5 clk = ~clk; - - - // - // Inputs, Outputs - // - reg rst_n; - reg ena; - wire rdy; - - - // - // Buffers (X, Y, N) - // - wire [WORD_COUNTER_WIDTH-1:0] core_xy_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_n_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_s_addr; - wire core_s_wren; - - wire [ 31:0] core_x_data; - wire [ 31:0] core_y_data; - wire [ 31:0] core_n_data; - wire [ 31:0] core_s_data; - - reg [WORD_COUNTER_WIDTH-1:0] tb_xyn_addr; - reg [WORD_COUNTER_WIDTH-1:0] tb_s_addr; - reg tb_xyn_wren; - - reg [ 31:0] tb_x_data; - reg [ 31:0] tb_y_data; - reg [ 31:0] tb_n_data; - wire [ 31:0] tb_s_data; - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_x - ( - .clk (clk), - - .a_addr (tb_xyn_addr), - .a_wr (tb_xyn_wren), - .a_in (tb_x_data), - .a_out (), - - .b_addr (core_xy_addr), - .b_out (core_x_data) - ); - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_y - ( - .clk (clk), - - .a_addr (tb_xyn_addr), - .a_wr (tb_xyn_wren), - .a_in (tb_y_data), - .a_out (), - - .b_addr (core_xy_addr), - .b_out (core_y_data) - ); - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_n - ( - .clk (clk), - - .a_addr (tb_xyn_addr), - .a_wr (tb_xyn_wren), - .a_in (tb_n_data), - .a_out (), - - .b_addr (core_n_addr), - .b_out (core_n_data) - ); - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_s - ( - .clk (clk), - - .a_addr (core_s_addr), - .a_wr (core_s_wren), - .a_in (core_s_data), - .a_out (), - - .b_addr (tb_s_addr), - .b_out (tb_s_data) - ); - - - // - // UUT - // - modular_adder # - ( - .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH), - .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS) - ) - uut - ( - .clk (clk), - .rst_n (rst_n), - - .ena (ena), - .rdy (rdy), - - .ab_addr (core_xy_addr), - .n_addr (core_n_addr), - .s_addr (core_s_addr), - .s_wren (core_s_wren), - - .a_din (core_x_data), - .b_din (core_y_data), - .n_din (core_n_data), - .s_dout (core_s_data) - ); - - - // - // Testbench Routine - // - reg ok = 1; - initial begin - - /* initialize control inputs */ - rst_n = 0; - ena = 0; - - tb_xyn_wren = 0; - - /* wait for some time */ - #200; - - /* de-assert reset */ - rst_n = 1; - - /* wait for some time */ - #100; - - /* run tests */ - test_modular_adder(X_1, Y_1, N); - test_modular_adder(X_2, Y_2, N); - test_modular_adder(Y_1, X_1, N); - test_modular_adder(Y_2, X_2, N); - - test_modular_adder(X_1, X_2, N); - test_modular_adder(X_2, X_1, N); - test_modular_adder(Y_1, Y_2, N); - test_modular_adder(Y_2, Y_1, N); - - test_modular_adder(X_1, Y_2, N); - test_modular_adder(Y_2, X_1, N); - test_modular_adder(X_2, Y_1, N); - test_modular_adder(Y_1, X_2, N); - - /* print result */ - if (ok) $display("tb_modular_adder_256: SUCCESS"); - else $display("tb_modular_adder_256: FAILURE"); - // - $finish; - // - end - - - // - // Test Task - // - reg [256:0] s; - wire [255:0] s_dummy = s[255:0]; - reg s_ok; - - integer w; - - reg [255:0] x_shreg; - reg [255:0] y_shreg; - reg [255:0] n_shreg; - reg [255:0] s_shreg; - - task test_modular_adder; - - input [255:0] x; - input [255:0] y; - input [255:0] n; - - begin - - /* start filling memories */ - tb_xyn_wren = 1; - - /* initialize shift registers */ - x_shreg = x; - y_shreg = y; - n_shreg = n; - - /* write all the words */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set addresses */ - tb_xyn_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* set data words */ - tb_x_data = x_shreg[31:0]; - tb_y_data = y_shreg[31:0]; - tb_n_data = n_shreg[31:0]; - - /* shift inputs */ - x_shreg = {{32{1'bX}}, x_shreg[255:32]}; - y_shreg = {{32{1'bX}}, y_shreg[255:32]}; - n_shreg = {{32{1'bX}}, n_shreg[255:32]}; - - /* wait for 1 clock tick */ - #10; - - end - - /* wipe addresses */ - tb_xyn_addr = {WORD_COUNTER_WIDTH{1'bX}}; - - /* wipe data words */ - tb_x_data = {32{1'bX}}; - tb_y_data = {32{1'bX}}; - tb_n_data = {32{1'bX}}; - - /* stop filling memories */ - tb_xyn_wren = 0; - - /* calculate reference value */ - s = {1'b0, x} + {1'b0, y}; - if (s >= {1'b0, n}) - s = s - {1'b0, n}; - - /* start operation */ - ena = 1; - - /* clear flag */ - #10 ena = 0; - - /* wait for operation to complete */ - while (!rdy) #10; - - /* read result */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set address */ - tb_s_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* wait for 1 clock tick */ - #10; - - /* store data word */ - s_shreg = {tb_s_data, s_shreg[255:32]}; - - end - - /* compare */ - s_ok = (s_shreg == s[255:0]); - - /* display results */ - $display("test_modular_adder(): %s", s_ok ? "OK" : "ERROR"); - - /* update global flag */ - ok = ok && s_ok; - - end - - endtask - - -endmodule - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/bench/tb_modular_invertor.v b/bench/tb_modular_invertor.v deleted file mode 100644 index 24f6db1..0000000 --- a/bench/tb_modular_invertor.v +++ /dev/null @@ -1,225 +0,0 @@ -`timescale 1ns / 1ps - -module tb_modular_invertor; - - - // - // Test Vectors - // - localparam [255:0] Q = 256'hffffffff00000001000000000000000000000000ffffffffffffffffffffffff; - - localparam [255:0] A_1 = 256'hd3e73ccd63a5b10da308c615bb9ebd3f76e2c5fccc256fd9f629dcc956bf2382; - localparam [255:0] A1_1 = 256'h93fb26d5d199bbb7232a4b7c98e97ba9bb7530d304b5f07736ea4027bbb57ecd; - - localparam [255:0] A_2 = 256'h57b6c628a5c4e870740b2517975ace2216acbe094ac54568b53212ef45e69d22; - localparam [255:0] A1_2 = 256'hcd2af4766642d7d2f3f3f67d92c575c496772ef7d55c75eb46bd07e8d5f9a4aa; - - - // - // Clock - // - reg clk = 1'b0; - always #5 clk = ~clk; - - - // - // Inputs, Outputs - // - reg rst_n; - reg ena; - wire rdy; - - - // - // Buffers (A, A1, Q) - // - wire [ 2: 0] core_a_addr; - wire [ 2: 0] core_q_addr; - wire [ 2: 0] core_a1_addr; - wire core_a1_wren; - - wire [31: 0] core_a_data; - wire [31: 0] core_q_data; - wire [31: 0] core_a1_data; - - reg [ 2: 0] tb_aq_addr; - reg tb_aq_wren; - reg [ 2: 0] tb_a1_addr; - - reg [31: 0] tb_a_data; - reg [31: 0] tb_q_data; - wire [31: 0] tb_a1_data; - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) - bram_a - ( .clk(clk), - .a_addr(tb_aq_addr), .a_wr(tb_aq_wren), .a_in(tb_a_data), .a_out(), - .b_addr(core_a_addr), .b_out(core_a_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) - bram_q - ( .clk(clk), - .a_addr(tb_aq_addr), .a_wr(tb_aq_wren), .a_in(tb_q_data), .a_out(), - .b_addr(core_q_addr), .b_out(core_q_data) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) - bram_a1 - ( .clk(clk), - .a_addr(core_a1_addr), .a_wr(core_a1_wren), .a_in(core_a1_data), .a_out(), - .b_addr(tb_a1_addr), .b_out(tb_a1_data) - ); - - - // - // UUT - // - modular_invertor # - ( - .MAX_OPERAND_WIDTH (256) - ) - uut - ( - .clk (clk), - .rst_n (rst_n), - - .ena (ena), - .rdy (rdy), - - .a_addr (core_a_addr), - .q_addr (core_q_addr), - .a1_addr (core_a1_addr), - .a1_wren (core_a1_wren), - - .a_din (core_a_data), - .q_din (core_q_data), - .a1_dout (core_a1_data) - ); - - // - // Testbench Routine - // - reg ok = 1; - initial begin - - /* initialize control inputs */ - rst_n = 0; - ena = 0; - - /* wait for some time */ - #200; - - /* de-assert reset */ - rst_n = 1; - - /* wait for some time */ - #100; - - /* run tests */ - test_modular_invertor(A_1, A1_1, Q); - test_modular_invertor(A_2, A1_2, Q); - - /* print result */ - if (ok) $display("tb_modular_invertor: SUCCESS"); - else $display("tb_modular_invertor: FAILURE"); - // - //$finish; - // - - end - - - // - // Test Task - // - reg a1_ok; - - integer w; - - task test_modular_invertor; - - input [255:0] a; - input [255:0] a1; - input [255:0] q; - - reg [255:0] a_shreg; - reg [255:0] a1_shreg; - reg [255:0] q_shreg; - - begin - - /* start filling memories */ - tb_aq_wren = 1; - - /* initialize shift registers */ - a_shreg = a; - q_shreg = q; - - /* write all the words */ - for (w=0; w<8; w=w+1) begin - - /* set addresses */ - tb_aq_addr = w[2:0]; - - /* set data words */ - tb_a_data = a_shreg[31:0]; - tb_q_data = q_shreg[31:0]; - - /* shift inputs */ - a_shreg = {{32{1'bX}}, a_shreg[255:32]}; - q_shreg = {{32{1'bX}}, q_shreg[255:32]}; - - /* wait for 1 clock tick */ - #10; - - end - - /* wipe addresses */ - tb_aq_addr = {3{1'bX}}; - - /* wipe data words */ - tb_a_data = {32{1'bX}}; - tb_q_data = {32{1'bX}}; - - /* stop filling memories */ - tb_aq_wren = 0; - - /* start operation */ - ena = 1; - - /* clear flag */ - #10 ena = 0; - - /* wait for operation to complete */ - while (!rdy) #10; - - /* read result */ - for (w=0; w<8; w=w+1) begin - - /* set address */ - tb_a1_addr = w[2:0]; - - /* wait for 1 clock tick */ - #10; - - /* store data word */ - a1_shreg = {tb_a1_data, a1_shreg[255:32]}; - - end - - /* compare */ - a1_ok = (a1_shreg == a1); - - /* display results */ - $display("test_modular_invertor(): %s", a1_ok ? "OK" : "ERROR"); - - /* update global flag */ - ok = ok && a1_ok; - - end - - endtask - - -endmodule diff --git a/bench/tb_modular_multiplier_256.v b/bench/tb_modular_multiplier_256.v deleted file mode 100644 index 676a183..0000000 --- a/bench/tb_modular_multiplier_256.v +++ /dev/null @@ -1,366 +0,0 @@ -//------------------------------------------------------------------------------ -// -// tb_modular_multiplier_256.v -// ----------------------------------------------------------------------------- -// Testbench for modular multi-word multiplier. -// -// Authors: Pavel Shatov -// -// Copyright (c) 2015-2016, NORDUnet A/S -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the NORDUnet nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -`timescale 1ns / 1ps -//------------------------------------------------------------------------------ - -module tb_modular_multiplier_256; - - - // - // Test Vectors - // - localparam [255:0] N = 256'hffffffff00000001000000000000000000000000ffffffffffffffffffffffff; - - localparam [255:0] X_1 = 256'h6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296; - localparam [255:0] Y_1 = 256'h4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5; - localparam [255:0] P_1 = 256'h823cd15f6dd3c71933565064513a6b2bd183e554c6a08622f713ebbbface98be; - - localparam [255:0] X_2 = 256'h29d05c193da77b710e86323538b77e1b11f904fea42998be16bd8d744ece7ad0; - localparam [255:0] Y_2 = 256'hb01cbd1c01e58065711814b583f061e9d431cca994cea1313449bf97c840ae07; - localparam [255:0] P_2 = 256'h76b2571d1d009ab0e7d1cc086c7d3648f08755b2e2585e780d11f053b06fb6ec; - - localparam [255:0] X_3 = 256'h8101ece47464a6ead70cf69a6e2bd3d88691a3262d22cba4f7635eaff26680a8; - localparam [255:0] Y_3 = 256'hd8a12ba61d599235f67d9cb4d58f1783d3ca43e78f0a5abaa624079936c0c3a9; - localparam [255:0] P_3 = 256'h944fea6a4fac7ae475a6bb211db4bbd394bd9b3ee9a038f6c17125a00b3a5375; - - localparam [255:0] X_4 = 256'h7214bc9647160bbd39ff2f80533f5dc6ddd70ddf86bb815661e805d5d4e6f27c; - localparam [255:0] Y_4 = 256'h8b81e3e977597110c7cf2633435b2294b72642987defd3d4007e1cfc5df84541; - localparam [255:0] P_4 = 256'h78d3e33c81ab9c652679363c76df004ea6f9a9e3a242a0fb71a4e8fdf41ab519; - - - // - // Core Parameters - // - localparam WORD_COUNTER_WIDTH = 3; - localparam OPERAND_NUM_WORDS = 8; - - - // - // Clock (100 MHz) - // - reg clk = 1'b0; - always #5 clk = ~clk; - - - // - // Inputs, Outputs - // - reg rst_n; - reg ena; - wire rdy; - - - // - // Buffers (X, Y, N, P) - // - wire [WORD_COUNTER_WIDTH-1:0] core_x_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_y_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_n_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_p_addr; - - wire core_p_wren; - - wire [ 31:0] core_x_data; - wire [ 31:0] core_y_data; - wire [ 31:0] core_n_data; - wire [ 31:0] core_p_data; - - reg [WORD_COUNTER_WIDTH-1:0] tb_xyn_addr; - reg [WORD_COUNTER_WIDTH-1:0] tb_p_addr; - - reg tb_xyn_wren; - - reg [ 31:0] tb_x_data; - reg [ 31:0] tb_y_data; - reg [ 31:0] tb_n_data; - wire [ 31:0] tb_p_data; - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_x - ( - .clk (clk), - - .a_addr (tb_xyn_addr), - .a_wr (tb_xyn_wren), - .a_in (tb_x_data), - .a_out (), - - .b_addr (core_x_addr), - .b_out (core_x_data) - ); - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_y - ( - .clk (clk), - - .a_addr (tb_xyn_addr), - .a_wr (tb_xyn_wren), - .a_in (tb_y_data), - .a_out (), - - .b_addr (core_y_addr), - .b_out (core_y_data) - ); - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_n - ( - .clk (clk), - - .a_addr (tb_xyn_addr), - .a_wr (tb_xyn_wren), - .a_in (tb_n_data), - .a_out (), - - .b_addr (core_n_addr), - .b_out (core_n_data) - ); - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_s - ( - .clk (clk), - - .a_addr (core_p_addr), - .a_wr (core_p_wren), - .a_in (core_p_data), - .a_out (), - - .b_addr (tb_p_addr), - .b_out (tb_p_data) - ); - - - // - // UUT - // - modular_multiplier_256 uut - ( - .clk (clk), - .rst_n (rst_n), - - .ena (ena), - .rdy (rdy), - - .a_addr (core_x_addr), - .b_addr (core_y_addr), - .n_addr (core_n_addr), - .p_addr (core_p_addr), - .p_wren (core_p_wren), - - .a_din (core_x_data), - .b_din (core_y_data), - .n_din (core_n_data), - .p_dout (core_p_data) - ); - - - // - // Testbench Routine - // - reg ok = 1; - initial begin - - /* initialize control inputs */ - rst_n = 0; - ena = 0; - - tb_xyn_wren = 0; - - /* wait for some time */ - #200; - - /* de-assert reset */ - rst_n = 1; - - /* wait for some time */ - #100; - - /* run tests */ - test_modular_multiplier(X_1, Y_1, N, P_1); - test_modular_multiplier(X_2, Y_2, N, P_2); - test_modular_multiplier(X_3, Y_3, N, P_3); - test_modular_multiplier(X_4, Y_4, N, P_4); - - /* print result */ - if (ok) $display("tb_modular_multiplier_256: SUCCESS"); - else $display("tb_modular_multiplier_256: FAILURE"); - // - //$finish; - // - end - - - // - // Test Task - // - reg [255:0] p; - reg p_ok; - - integer w; - - reg [511:0] pp_full; - reg [255:0] pp_ref; - - task test_modular_multiplier; - - input [255:0] x; - input [255:0] y; - input [255:0] n; - input [255:0] pp; - - reg [255:0] x_shreg; - reg [255:0] y_shreg; - reg [255:0] n_shreg; - reg [255:0] p_shreg; - - begin - - /* start filling memories */ - tb_xyn_wren = 1; - - /* initialize shift registers */ - x_shreg = x; - y_shreg = y; - n_shreg = n; - - /* write all the words */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set addresses */ - tb_xyn_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* set data words */ - tb_x_data = x_shreg[31:0]; - tb_y_data = y_shreg[31:0]; - tb_n_data = n_shreg[31:0]; - - /* shift inputs */ - x_shreg = {{32{1'bX}}, x_shreg[255:32]}; - y_shreg = {{32{1'bX}}, y_shreg[255:32]}; - n_shreg = {{32{1'bX}}, n_shreg[255:32]}; - - /* wait for 1 clock tick */ - #10; - - end - - /* wipe addresses */ - tb_xyn_addr = {WORD_COUNTER_WIDTH{1'bX}}; - - /* wipe data words */ - tb_x_data = {32{1'bX}}; - tb_y_data = {32{1'bX}}; - tb_n_data = {32{1'bX}}; - - /* stop filling memories */ - tb_xyn_wren = 0; - - /* calculate reference value */ - pp_full = {{256{1'b0}}, x} * {{256{1'b0}}, y}; - pp_ref = pp_full % {{256{1'b0}}, n}; - - /* compare reference value against hard-coded one */ - if (pp_ref != pp) begin - $display("ERROR: pp_ref != pp"); - $finish; - end - - /* start operation */ - ena = 1; - - /* clear flag */ - #10 ena = 0; - - /* wait for operation to complete */ - while (!rdy) #10; - - /* read result */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set address */ - tb_p_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* wait for 1 clock tick */ - #10; - - /* store data word */ - p_shreg = {tb_p_data, p_shreg[255:32]}; - - end - - /* compare */ - p_ok = (p_shreg == pp); - - /* display results */ - $display("test_modular_multiplier_256(): %s", p_ok ? "OK" : "ERROR"); - - /* update flag */ - ok = ok && p_ok; - - end - - endtask - - - - -endmodule - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/bench/tb_modular_subtractor.v b/bench/tb_modular_subtractor.v deleted file mode 100644 index 6cf0e01..0000000 --- a/bench/tb_modular_subtractor.v +++ /dev/null @@ -1,356 +0,0 @@ -//------------------------------------------------------------------------------ -// -// tb_modular_subtractor_256.v -// ----------------------------------------------------------------------------- -// Testbench for modular multi-word subtractor. -// -// Authors: Pavel Shatov -// -// Copyright (c) 2016, NORDUnet A/S -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the NORDUnet nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -`timescale 1ns / 1ps -//------------------------------------------------------------------------------ - -module tb_modular_subtractor_256; - - - // - // Test Vectors - // - localparam [255:0] N = 256'hffffffff00000001000000000000000000000000ffffffffffffffffffffffff; - - localparam [255:0] X_1 = 256'h1ddbd0769df27bab1e234019dad09dccce1e87e2193b417ffa1a3465d7439ecd; - localparam [255:0] Y_1 = 256'h1f67cdc34bac91a072945d212f0a03442fc4855788583ecb7b2e375ad3848210; - - localparam [255:0] X_2 = 256'hff563f653b1392a6fa6b0295a280f7a904a11e22d8ae468e220301d8ac232fcf; - localparam [255:0] Y_2 = 256'hf6f53c4b57b25453b68e923fb118e4f753d74af01fc58476dd15a80933453899; - - - // - // Core Parameters - // - localparam WORD_COUNTER_WIDTH = 3; - localparam OPERAND_NUM_WORDS = 8; - - - // - // Clock (100 MHz) - // - reg clk = 1'b0; - always #5 clk = ~clk; - - - // - // Inputs, Outputs - // - reg rst_n; - reg ena; - wire rdy; - - - // - // Buffers (X, Y, N) - // - wire [WORD_COUNTER_WIDTH-1:0] core_xy_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_n_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_d_addr; - wire core_d_wren; - - wire [ 31:0] core_x_data; - wire [ 31:0] core_y_data; - wire [ 31:0] core_n_data; - wire [ 31:0] core_d_data; - - reg [WORD_COUNTER_WIDTH-1:0] tb_xyn_addr; - reg [WORD_COUNTER_WIDTH-1:0] tb_d_addr; - reg tb_xyn_wren; - - reg [ 31:0] tb_x_data; - reg [ 31:0] tb_y_data; - reg [ 31:0] tb_n_data; - wire [ 31:0] tb_d_data; - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_x - ( - .clk (clk), - - .a_addr (tb_xyn_addr), - .a_wr (tb_xyn_wren), - .a_in (tb_x_data), - .a_out (), - - .b_addr (core_xy_addr), - .b_out (core_x_data) - ); - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_y - ( - .clk (clk), - - .a_addr (tb_xyn_addr), - .a_wr (tb_xyn_wren), - .a_in (tb_y_data), - .a_out (), - - .b_addr (core_xy_addr), - .b_out (core_y_data) - ); - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_n - ( - .clk (clk), - - .a_addr (tb_xyn_addr), - .a_wr (tb_xyn_wren), - .a_in (tb_n_data), - .a_out (), - - .b_addr (core_n_addr), - .b_out (core_n_data) - ); - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_s - ( - .clk (clk), - - .a_addr (core_d_addr), - .a_wr (core_d_wren), - .a_in (core_d_data), - .a_out (), - - .b_addr (tb_d_addr), - .b_out (tb_d_data) - ); - - - // - // UUT - // - modular_subtractor # - ( - .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH), - .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS) - ) - uut - ( - .clk (clk), - .rst_n (rst_n), - - .ena (ena), - .rdy (rdy), - - .ab_addr (core_xy_addr), - .n_addr (core_n_addr), - .d_addr (core_d_addr), - .d_wren (core_d_wren), - - .a_din (core_x_data), - .b_din (core_y_data), - .n_din (core_n_data), - .d_dout (core_d_data) - ); - - - // - // Testbench Routine - // - reg ok = 1; - initial begin - - /* initialize control inputs */ - rst_n = 0; - ena = 0; - - tb_xyn_wren = 0; - - /* wait for some time */ - #200; - - /* de-assert reset */ - rst_n = 1; - - /* wait for some time */ - #100; - - /* run tests */ - test_modular_subtractor(X_1, Y_1, N); - test_modular_subtractor(X_2, Y_2, N); - test_modular_subtractor(Y_1, X_1, N); - test_modular_subtractor(Y_2, X_2, N); - - test_modular_subtractor(X_1, X_2, N); - test_modular_subtractor(X_2, X_1, N); - test_modular_subtractor(Y_1, Y_2, N); - test_modular_subtractor(Y_2, Y_1, N); - - test_modular_subtractor(X_1, Y_2, N); - test_modular_subtractor(Y_2, X_1, N); - test_modular_subtractor(X_2, Y_1, N); - test_modular_subtractor(Y_1, X_2, N); - - /* print result */ - if (ok) $display("tb_modular_subtractor_256: SUCCESS"); - else $display("tb_modular_subtractor_256: FAILURE"); - // - $finish; - // - end - - - // - // Test Task - // - reg [256:0] d; - wire [255:0] d_dummy = d[255:0]; - reg d_ok; - - integer w; - - reg [255:0] x_shreg; - reg [255:0] y_shreg; - reg [255:0] n_shreg; - reg [255:0] d_shreg; - - task test_modular_subtractor; - - input [255:0] x; - input [255:0] y; - input [255:0] n; - - begin - - /* start filling memories */ - tb_xyn_wren = 1; - - /* initialize shift registers */ - x_shreg = x; - y_shreg = y; - n_shreg = n; - - /* write all the words */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set addresses */ - tb_xyn_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* set data words */ - tb_x_data = x_shreg[31:0]; - tb_y_data = y_shreg[31:0]; - tb_n_data = n_shreg[31:0]; - - /* shift inputs */ - x_shreg = {{32{1'bX}}, x_shreg[255:32]}; - y_shreg = {{32{1'bX}}, y_shreg[255:32]}; - n_shreg = {{32{1'bX}}, n_shreg[255:32]}; - - /* wait for 1 clock tick */ - #10; - - end - - /* wipe addresses */ - tb_xyn_addr = {WORD_COUNTER_WIDTH{1'bX}}; - - /* wipe data words */ - tb_x_data = {32{1'bX}}; - tb_y_data = {32{1'bX}}; - tb_n_data = {32{1'bX}}; - - /* stop filling memories */ - tb_xyn_wren = 0; - - /* calculate reference value */ - d = {1'b0, (x < y) ? n : {256{1'b0}}}; - d = d + {1'b0, x} - {1'b0, y}; - - /* start operation */ - ena = 1; - - /* clear flag */ - #10 ena = 0; - - /* wait for operation to complete */ - while (!rdy) #10; - - /* read result */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set address */ - tb_d_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* wait for 1 clock tick */ - #10; - - /* store data word */ - d_shreg = {tb_d_data, d_shreg[255:32]}; - - end - - /* compare */ - d_ok = (d_shreg == d[255:0]); - - /* display results */ - $display("test_modular_subtractor(): %s", d_ok ? "OK" : "ERROR"); - - /* update global flag */ - ok = ok && d_ok; - - end - - endtask - - -endmodule - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/bench/tb_mw_comparator.v b/bench/tb_mw_comparator.v deleted file mode 100644 index ed830a8..0000000 --- a/bench/tb_mw_comparator.v +++ /dev/null @@ -1,322 +0,0 @@ -//------------------------------------------------------------------------------ -// -// tb_mw_comparator.v -// ----------------------------------------------------------------------------- -// Testbench for multi-word comparator. -// -// Authors: Pavel Shatov -// -// Copyright (c) 2016, NORDUnet A/S -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the NORDUnet nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -`timescale 1ns / 1ps -//------------------------------------------------------------------------------ - -module tb_mw_comparator; - - - // - // Test Vectors - // - localparam [383:0] A_0 = 384'hBDC7B53C_616B13B5_77622510_75BA95FC_475D568B_79E730D4_18A9143C_18905F76; - - localparam [383:0] A_1 = 384'hBDC7B53C_616B13B5_77622510_75BA95FC_475D568B_79E730D4_18A9143C_18905F75; - localparam [383:0] A_2 = 384'hBDC7B53C_616B13B5_77622510_75BA95FC_475D568B_79E730D4_18A9143C_18905F77; - - localparam [383:0] A_3 = 384'hBDC7B53C_616B13B5_77622510_75BA95FC_375D568B_79E730D4_18A9143C_18905F76; - localparam [383:0] A_4 = 384'hBDC7B53C_616B13B5_77622510_75BA95FC_575D568B_79E730D4_18A9143C_18905F76; - - localparam [383:0] A_5 = 384'hBDC7B53C_616B13B5_77622510_75BA95FB_475D568B_79E730D4_18A9143C_18905F76; - localparam [383:0] A_6 = 384'hBDC7B53C_616B13B5_77622510_75BA95FD_475D568B_79E730D4_18A9143C_18905F76; - - localparam [383:0] A_7 = 384'hADC7B53C_616B13B5_77622510_75BA95FC_475D568B_79E730D4_18A9143C_18905F76; - localparam [383:0] A_8 = 384'hCDC7B53C_616B13B5_77622510_75BA95FC_475D568B_79E730D4_18A9143C_18905F76; - - localparam [383:0] B_0 = 384'h348A6D1F_7C66D21E_8D1490D9_AA6AE3C0_AD784F98_850046D4_10DDD64D_F6BB32E5; - - localparam [383:0] B_1 = 384'h348A6D1F_7C66D21E_8D1490D9_AA6AE3C0_AD784F98_850046D4_10DDD64D_F6BB32E4; - localparam [383:0] B_2 = 384'h348A6D1F_7C66D21E_8D1490D9_AA6AE3C0_AD784F98_850046D4_10DDD64D_F6BB32E6; - - localparam [383:0] B_3 = 384'h348A6D1F_7C66D21E_8D1490D9_AA6AE3C0_9D784F98_850046D4_10DDD64D_F6BB32E5; - localparam [383:0] B_4 = 384'h348A6D1F_7C66D21E_8D1490D9_AA6AE3C0_BD784F98_850046D4_10DDD64D_F6BB32E5; - - localparam [383:0] B_5 = 384'h348A6D1F_7C66D21E_8D1490D9_AA6AE3BF_AD784F98_850046D4_10DDD64D_F6BB32E5; - localparam [383:0] B_6 = 384'h348A6D1F_7C66D21E_8D1490D9_AA6AE3C1_AD784F98_850046D4_10DDD64D_F6BB32E5; - - localparam [383:0] B_7 = 384'h248A6D1F_7C66D21E_8D1490D9_AA6AE3C0_AD784F98_850046D4_10DDD64D_F6BB32E5; - localparam [383:0] B_8 = 384'h448A6D1F_7C66D21E_8D1490D9_AA6AE3C0_AD784F98_850046D4_10DDD64D_F6BB32E5; - - - // - // Core Parameters - // - localparam WORD_COUNTER_WIDTH = 3; - parameter OPERAND_NUM_WORDS = 8; - - - // - // Clock (100 MHz) - // - reg clk = 1'b0; - always #5 clk = ~clk; - - - // - // Inputs, Outputs - // - reg rst_n; - reg ena; - wire rdy; - - wire core_cmp_l; - wire core_cmp_e; - wire core_cmp_g; - - - // - // Buffers (X, Y) - // - wire [WORD_COUNTER_WIDTH-1:0] core_xy_addr; - - wire [ 32-1:0] core_x_data; - wire [ 32-1:0] core_y_data; - - reg [WORD_COUNTER_WIDTH-1:0] tb_xy_addr; - reg tb_xy_wren; - - reg [ 32-1:0] tb_x_data; - reg [ 32-1:0] tb_y_data; - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_x - ( - .clk (clk), - - .a_addr (tb_xy_addr), - .a_wr (tb_xy_wren), - .a_in (tb_x_data), - .a_out (), - - .b_addr (core_xy_addr), - .b_out (core_x_data) - ); - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_y - ( - .clk (clk), - - .a_addr (tb_xy_addr), - .a_wr (tb_xy_wren), - .a_in (tb_y_data), - .a_out (), - - .b_addr (core_xy_addr), - .b_out (core_y_data) - ); - - - // - // UUT - // - mw_comparator # - ( - .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH), - .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS) - ) - uut - ( - .clk (clk), - .rst_n (rst_n), - - .ena (ena), - .rdy (rdy), - - .xy_addr (core_xy_addr), - .x_din (core_x_data), - .y_din (core_y_data), - - .cmp_l (core_cmp_l), - .cmp_e (core_cmp_e), - .cmp_g (core_cmp_g) - ); - - - // - // Testbench Routine - // - reg ok = 1; - initial begin - - /* initialize control inputs */ - rst_n = 0; - ena = 0; - - tb_xy_wren = 0; - - /* wait for some time */ - #200; - - /* de-assert reset */ - rst_n = 1; - - /* wait for some time */ - #100; - - /* run tests */ - test_mw_comparator(A_0, A_0); - - test_mw_comparator(A_0, A_1); - test_mw_comparator(A_0, A_2); - test_mw_comparator(A_0, A_3); - test_mw_comparator(A_0, A_4); - test_mw_comparator(A_0, A_5); - test_mw_comparator(A_0, A_6); - test_mw_comparator(A_0, A_7); - test_mw_comparator(A_0, A_8); - - test_mw_comparator(B_0, B_0); - - test_mw_comparator(B_0, B_1); - test_mw_comparator(B_0, B_2); - test_mw_comparator(B_0, B_3); - test_mw_comparator(B_0, B_4); - test_mw_comparator(B_0, B_5); - test_mw_comparator(B_0, B_6); - test_mw_comparator(B_0, B_7); - test_mw_comparator(B_0, B_8); - - /* print result */ - if (ok) $display("tb_mw_comparator: SUCCESS"); - else $display("tb_mw_comparator: FAILURE"); - // - $finish; - // - end - - - // - // Test Task - // - reg cmp_l; - reg cmp_e; - reg cmp_g; - reg cmp_ok; - - integer w; - - task test_mw_comparator; - - input [255:0] x; - input [255:0] y; - - reg [255:0] x_shreg; - reg [255:0] y_shreg; - - begin - - /* start filling memories */ - tb_xy_wren = 1; - - /* initialize shift registers */ - x_shreg = x; - y_shreg = y; - - /* write all the words */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set addresses */ - tb_xy_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* set data words */ - tb_x_data = x_shreg[31:0]; - tb_y_data = y_shreg[31:0]; - - /* shift inputs */ - x_shreg = {{32{1'bX}}, x_shreg[255:32]}; - y_shreg = {{32{1'bX}}, y_shreg[255:32]}; - - /* wait for 1 clock tick */ - #10; - - end - - /* wipe addresses */ - tb_xy_addr = {WORD_COUNTER_WIDTH{1'bX}}; - - /* wipe data words */ - tb_x_data = {32{1'bX}}; - tb_y_data = {32{1'bX}}; - - /* stop filling memories */ - tb_xy_wren = 0; - - /* calculate reference values */ - cmp_l = (x < y) ? 1 : 0; - cmp_e = (x == y) ? 1 : 0; - cmp_g = (x > y) ? 1 : 0; - - /* start operation */ - ena = 1; - - /* clear flag */ - #10 ena = 0; - - /* wait for operation to complete */ - while (!rdy) #10; - - /* compare */ - cmp_ok = (cmp_l == core_cmp_l) && (cmp_e == core_cmp_e) && (cmp_g == core_cmp_g); - - /* display results */ - $display("test_mw_comparator(): %s", cmp_ok ? "OK" : "ERROR"); - - /* update global flag */ - ok = ok && cmp_ok; - - end - - endtask - -endmodule - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/bench/tb_mw_mover.v b/bench/tb_mw_mover.v deleted file mode 100644 index 08bdb9e..0000000 --- a/bench/tb_mw_mover.v +++ /dev/null @@ -1,282 +0,0 @@ -//------------------------------------------------------------------------------ -// -// tb_modular_mover.v -// ----------------------------------------------------------------------------- -// Testbench for multi-word data mover. -// -// Authors: Pavel Shatov -// -// Copyright (c) 2016, NORDUnet A/S -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the NORDUnet nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -`timescale 1ns / 1ps -//------------------------------------------------------------------------------ - -module tb_mw_mover; - - - // - // Test Vectors - // - localparam [255:0] X_1 = 256'h1ddbd0769df27bab1e234019dad09dccce1e87e2193b417ffa1a3465d7439ecd; - localparam [255:0] X_2 = 256'h1f67cdc34bac91a072945d212f0a03442fc4855788583ecb7b2e375ad3848210; - localparam [255:0] X_3 = 256'hff563f653b1392a6fa6b0295a280f7a904a11e22d8ae468e220301d8ac232fcf; - localparam [255:0] X_4 = 256'hf6f53c4b57b25453b68e923fb118e4f753d74af01fc58476dd15a80933453899; - - - // - // Core Parameters - // - localparam WORD_COUNTER_WIDTH = 3; - localparam OPERAND_NUM_WORDS = 8; - - - // - // Clock (100 MHz) - // - reg clk = 1'b0; - always #5 clk = ~clk; - - - // - // Inputs, Outputs - // - reg rst_n; - reg ena; - wire rdy; - - - // - // Buffers (X, Y) - // - wire [WORD_COUNTER_WIDTH-1:0] core_x_addr; - wire [WORD_COUNTER_WIDTH-1:0] core_y_addr; - wire core_y_wren; - - wire [ 32-1:0] core_x_data; - wire [ 32-1:0] core_y_data; - - reg [WORD_COUNTER_WIDTH-1:0] tb_x_addr; - reg [WORD_COUNTER_WIDTH-1:0] tb_y_addr; - reg tb_x_wren; - - reg [ 32-1:0] tb_x_data; - wire [ 32-1:0] tb_y_data; - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_x - ( - .clk (clk), - - .a_addr (tb_x_addr), - .a_wr (tb_x_wren), - .a_in (tb_x_data), - .a_out (), - - .b_addr (core_x_addr), - .b_out (core_x_data) - ); - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH) - ) - bram_d - ( - .clk (clk), - - .a_addr (core_y_addr), - .a_wr (core_y_wren), - .a_in (core_y_data), - .a_out (), - - .b_addr (tb_y_addr), - .b_out (tb_y_data) - ); - - - // - // UUT - // - mw_mover # - ( - .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH), - .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS) - ) - uut - ( - .clk (clk), - .rst_n (rst_n), - - .ena (ena), - .rdy (rdy), - - .x_addr (core_x_addr), - .y_addr (core_y_addr), - .y_wren (core_y_wren), - - .x_din (core_x_data), - .y_dout (core_y_data) - ); - - - // - // Testbench Routine - // - reg ok = 1; - initial begin - - /* initialize control inputs */ - rst_n = 0; - ena = 0; - - tb_x_wren = 0; - - /* wait for some time */ - #200; - - /* de-assert reset */ - rst_n = 1; - - /* wait for some time */ - #100; - - /* run tests */ - test_modular_mover(X_1); - test_modular_mover(X_2); - test_modular_mover(X_3); - test_modular_mover(X_4); - - /* print result */ - if (ok) $display("tb_modular_mover: SUCCESS"); - else $display("tb_modular_mover: FAILURE"); - // - $finish; - // - end - - - // - // Test Task - // - reg [255:0] y; - reg y_ok; - - integer w; - - reg [255:0] x_shreg; - reg [255:0] y_shreg; - - task test_modular_mover; - - input [255:0] x; - - begin - - /* start filling memories */ - tb_x_wren = 1; - - /* initialize shift registers */ - x_shreg = x; - - /* write all the words */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set addresses */ - tb_x_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* set data words */ - tb_x_data = x_shreg[31:0]; - - /* shift inputs */ - x_shreg = {{32{1'bX}}, x_shreg[255:32]}; - - /* wait for 1 clock tick */ - #10; - - end - - /* wipe addresses */ - tb_x_addr = {WORD_COUNTER_WIDTH{1'bX}}; - - /* wipe data words */ - tb_x_data = {32{1'bX}}; - - /* stop filling memories */ - tb_x_wren = 0; - - /* start operation */ - ena = 1; - - /* clear flag */ - #10 ena = 0; - - /* wait for operation to complete */ - while (!rdy) #10; - - /* read result */ - for (w=0; w<OPERAND_NUM_WORDS; w=w+1) begin - - /* set address */ - tb_y_addr = w[WORD_COUNTER_WIDTH-1:0]; - - /* wait for 1 clock tick */ - #10; - - /* store data word */ - y_shreg = {tb_y_data, y_shreg[255:32]}; - - end - - /* compare */ - y_ok = (y_shreg == x); - - /* display results */ - $display("test_modular_mover(): %s", y_ok ? "OK" : "ERROR"); - - /* update global flag */ - ok = ok && y_ok; - - end - - endtask - - -endmodule - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/rtl/curve/curve_dbl_add_256.v b/rtl/curve/curve_dbl_add_256.v deleted file mode 100644 index 1fb1bea..0000000 --- a/rtl/curve/curve_dbl_add_256.v +++ /dev/null @@ -1,893 +0,0 @@ -//------------------------------------------------------------------------------ -// -// curve_dbl_add_256.v -// ----------------------------------------------------------------------------- -// Elliptic curve point adder and doubler. -// -// Authors: Pavel Shatov -// -// Copyright (c) 2016, 2018 NORDUnet A/S -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the NORDUnet nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//------------------------------------------------------------------------------ - -module curve_dbl_add_256 - ( - clk, rst_n, - ena, rdy, - uop_addr, uop, - px_addr, py_addr, pz_addr, rx_addr, ry_addr, rz_addr, q_addr, v_addr, - rx_wren, ry_wren, rz_wren, - px_din, py_din, pz_din, - rx_din, ry_din, rz_din, - rx_dout, ry_dout, rz_dout, q_din, v_din - ); - - - // - // Microcode - // -`include "../../../../math/ecdsalib/rtl/curve/uop_ecdsa.v" - - - // - // Constants - // - localparam WORD_COUNTER_WIDTH = 3; // 0 .. 7 - localparam OPERAND_NUM_WORDS = 8; // 8 * 32 = 256 - - - // - // Ports - // - input wire clk; // system clock - input wire rst_n; // active-low async reset - - input wire ena; // enable input - output wire rdy; // ready output - - output reg [ 6-1: 0] uop_addr; - input wire [20-1: 0] uop; - - output reg [WORD_COUNTER_WIDTH-1:0] px_addr; - output reg [WORD_COUNTER_WIDTH-1:0] py_addr; - output reg [WORD_COUNTER_WIDTH-1:0] pz_addr; - output reg [WORD_COUNTER_WIDTH-1:0] rx_addr; - output reg [WORD_COUNTER_WIDTH-1:0] ry_addr; - output reg [WORD_COUNTER_WIDTH-1:0] rz_addr; - output reg [WORD_COUNTER_WIDTH-1:0] v_addr; - output wire [WORD_COUNTER_WIDTH-1:0] q_addr; - - output wire rx_wren; - output wire ry_wren; - output wire rz_wren; - - input wire [ 32-1:0] px_din; - input wire [ 32-1:0] py_din; - input wire [ 32-1:0] pz_din; - input wire [ 32-1:0] rx_din; - input wire [ 32-1:0] ry_din; - input wire [ 32-1:0] rz_din; - output wire [ 32-1:0] rx_dout; - output wire [ 32-1:0] ry_dout; - output wire [ 32-1:0] rz_dout; - input wire [ 32-1:0] q_din; - input wire [ 32-1:0] v_din; - - - // - // Microcode - // - wire [ 4: 0] uop_opcode = uop[19:15]; - wire [ 4: 0] uop_src_a = uop[14:10]; - wire [ 4: 0] uop_src_b = uop[ 9: 5]; - wire [ 2: 0] uop_dst = uop[ 4: 2]; - wire [ 1: 0] uop_exec = uop[ 1: 0]; - - - // - // Multi-Word Comparator - // - wire mw_cmp_ena; - wire mw_cmp_rdy; - - wire mw_cmp_out_l; - wire mw_cmp_out_e; - wire mw_cmp_out_g; - - wire [WORD_COUNTER_WIDTH-1:0] mw_cmp_addr_xy; - - wire [ 32-1:0] mw_cmp_din_x; - wire [ 32-1:0] mw_cmp_din_y; - - // flags - reg flag_pz_is_zero; - reg flag_t1_is_zero; - reg flag_t2_is_zero; - - mw_comparator # - ( - .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH), - .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS) - ) - mw_comparator_inst - ( - .clk (clk), - .rst_n (rst_n), - - .ena (mw_cmp_ena), - .rdy (mw_cmp_rdy), - - .xy_addr (mw_cmp_addr_xy), - .x_din (mw_cmp_din_x), - .y_din (mw_cmp_din_y), - - .cmp_l (mw_cmp_out_l), - .cmp_e (mw_cmp_out_e), - .cmp_g (mw_cmp_out_g) - ); - - - // - // Modular Adder - // - wire mod_add_ena; - wire mod_add_rdy; - - wire [WORD_COUNTER_WIDTH-1:0] mod_add_addr_ab; - wire [WORD_COUNTER_WIDTH-1:0] mod_add_addr_n; - wire [WORD_COUNTER_WIDTH-1:0] mod_add_addr_s; - wire mod_add_wren_s; - - wire [ 32-1:0] mod_add_din_a; - wire [ 32-1:0] mod_add_din_b; - wire [ 32-1:0] mod_add_din_n; - wire [ 32-1:0] mod_add_dout_s; - - assign mod_add_din_n = q_din; - - modular_adder # - ( - .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH), - .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS) - ) - modular_adder_inst - ( - .clk (clk), - .rst_n (rst_n), - - .ena (mod_add_ena), - .rdy (mod_add_rdy), - - .ab_addr (mod_add_addr_ab), - .n_addr (mod_add_addr_n), - .s_addr (mod_add_addr_s), - .s_wren (mod_add_wren_s), - - .a_din (mod_add_din_a), - .b_din (mod_add_din_b), - .n_din (mod_add_din_n), - .s_dout (mod_add_dout_s) - ); - - - // - // Modular Subtractor - // - wire mod_sub_ena; - wire mod_sub_rdy; - - wire [WORD_COUNTER_WIDTH-1:0] mod_sub_addr_ab; - wire [WORD_COUNTER_WIDTH-1:0] mod_sub_addr_n; - wire [WORD_COUNTER_WIDTH-1:0] mod_sub_addr_d; - wire mod_sub_wren_d; - - wire [ 32-1:0] mod_sub_din_a; - wire [ 32-1:0] mod_sub_din_b; - wire [ 32-1:0] mod_sub_din_n; - wire [ 32-1:0] mod_sub_dout_d; - - assign mod_sub_din_n = q_din; - - modular_subtractor # - ( - .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH), - .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS) - ) - modular_subtractor_inst - ( - .clk (clk), - .rst_n (rst_n), - - .ena (mod_sub_ena), - .rdy (mod_sub_rdy), - - .ab_addr (mod_sub_addr_ab), - .n_addr (mod_sub_addr_n), - .d_addr (mod_sub_addr_d), - .d_wren (mod_sub_wren_d), - - .a_din (mod_sub_din_a), - .b_din (mod_sub_din_b), - .n_din (mod_sub_din_n), - .d_dout (mod_sub_dout_d) - ); - - - // - // Modular Multiplier - // - wire mod_mul_ena; - wire mod_mul_rdy; - - wire [WORD_COUNTER_WIDTH-1:0] mod_mul_addr_a; - wire [WORD_COUNTER_WIDTH-1:0] mod_mul_addr_b; - wire [WORD_COUNTER_WIDTH-1:0] mod_mul_addr_n; - wire [WORD_COUNTER_WIDTH-1:0] mod_mul_addr_p; - wire mod_mul_wren_p; - - wire [ 32-1:0] mod_mul_din_a; - wire [ 32-1:0] mod_mul_din_b; - wire [ 32-1:0] mod_mul_din_n; - wire [ 32-1:0] mod_mul_dout_p; - - assign mod_mul_din_n = q_din; - - modular_multiplier_256 modular_multiplier_inst - ( - .clk (clk), - .rst_n (rst_n), - - .ena (mod_mul_ena), - .rdy (mod_mul_rdy), - - .a_addr (mod_mul_addr_a), - .b_addr (mod_mul_addr_b), - .n_addr (mod_mul_addr_n), - .p_addr (mod_mul_addr_p), - .p_wren (mod_mul_wren_p), - - .a_din (mod_mul_din_a), - .b_din (mod_mul_din_b), - .n_din (mod_mul_din_n), - .p_dout (mod_mul_dout_p) - ); - - - // - // Multi-Word Data Mover - // - wire mw_mov_ena; - wire mw_mov_rdy; - - wire [WORD_COUNTER_WIDTH-1:0] mw_mov_addr_x; - wire [WORD_COUNTER_WIDTH-1:0] mw_mov_addr_y; - wire mw_mov_wren_y; - - wire [ 32-1:0] mw_mov_din_x; - wire [ 32-1:0] mw_mov_dout_y; - - mw_mover # - ( - .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH), - .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS) - - ) - mw_mover_inst - ( - .clk (clk), - .rst_n (rst_n), - - .ena (mw_mov_ena), - .rdy (mw_mov_rdy), - - .x_addr (mw_mov_addr_x), - .y_addr (mw_mov_addr_y), - .y_wren (mw_mov_wren_y), - - .x_din (mw_mov_din_x), - .y_dout (mw_mov_dout_y) - ); - - - // - // ROMs - // - reg [WORD_COUNTER_WIDTH-1:0] brom_one_addr; - //reg [WORD_COUNTER_WIDTH-1:0] brom_zero_addr; - reg [WORD_COUNTER_WIDTH-1:0] brom_delta_addr; - reg [WORD_COUNTER_WIDTH-1:0] brom_g_x_addr; - reg [WORD_COUNTER_WIDTH-1:0] brom_g_y_addr; - reg [WORD_COUNTER_WIDTH-1:0] brom_h_x_addr; - reg [WORD_COUNTER_WIDTH-1:0] brom_h_y_addr; - - wire [ 32-1:0] brom_one_dout; - wire [ 32-1:0] brom_zero_dout; - wire [ 32-1:0] brom_delta_dout; - wire [ 32-1:0] brom_g_x_dout; - wire [ 32-1:0] brom_g_y_dout; - wire [ 32-1:0] brom_h_x_dout; - wire [ 32-1:0] brom_h_y_dout; - - (* ROM_STYLE="BLOCK" *) brom_p256_one brom_one_inst - (.clk(clk), .b_addr(brom_one_addr), .b_out(brom_one_dout)); - - brom_p256_zero brom_zero_inst - (.b_out(brom_zero_dout)); - - (* ROM_STYLE="BLOCK" *) brom_p256_delta brom_delta_inst - (.clk(clk), .b_addr(brom_delta_addr), .b_out(brom_delta_dout)); - - (* ROM_STYLE="BLOCK" *) brom_p256_g_x brom_g_x_inst - (.clk(clk), .b_addr(brom_g_x_addr), .b_out(brom_g_x_dout)); - - (* ROM_STYLE="BLOCK" *) brom_p256_g_y brom_g_y_inst - (.clk(clk), .b_addr(brom_g_y_addr), .b_out(brom_g_y_dout)); - - (* ROM_STYLE="BLOCK" *) brom_p256_h_x brom_h_x_inst - (.clk(clk), .b_addr(brom_h_x_addr), .b_out(brom_h_x_dout)); - - (* ROM_STYLE="BLOCK" *) brom_p256_h_y brom_h_y_inst - (.clk(clk), .b_addr(brom_h_y_addr), .b_out(brom_h_y_dout)); - - - // - // Temporary Variables - // - reg [WORD_COUNTER_WIDTH-1:0] bram_t1_wr_addr; - reg [WORD_COUNTER_WIDTH-1:0] bram_t2_wr_addr; - reg [WORD_COUNTER_WIDTH-1:0] bram_t3_wr_addr; - reg [WORD_COUNTER_WIDTH-1:0] bram_t4_wr_addr; - - reg [WORD_COUNTER_WIDTH-1:0] bram_t1_rd_addr; - reg [WORD_COUNTER_WIDTH-1:0] bram_t2_rd_addr; - reg [WORD_COUNTER_WIDTH-1:0] bram_t3_rd_addr; - reg [WORD_COUNTER_WIDTH-1:0] bram_t4_rd_addr; - - wire bram_t1_wr_en; - wire bram_t2_wr_en; - wire bram_t3_wr_en; - wire bram_t4_wr_en; - - wire [ 32-1:0] bram_t1_wr_data; - wire [ 32-1:0] bram_t2_wr_data; - wire [ 32-1:0] bram_t3_wr_data; - wire [ 32-1:0] bram_t4_wr_data; - - wire [ 32-1:0] bram_t1_rd_data; - wire [ 32-1:0] bram_t2_rd_data; - wire [ 32-1:0] bram_t3_rd_data; - wire [ 32-1:0] bram_t4_rd_data; - - bram_1rw_1ro_readfirst # - ( .MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH) - ) - bram_t1 - ( .clk (clk), - .a_addr(bram_t1_wr_addr), .a_wr(bram_t1_wr_en), .a_in(bram_t1_wr_data), .a_out(), - .b_addr(bram_t1_rd_addr), .b_out(bram_t1_rd_data) - ); - - bram_1rw_1ro_readfirst # - ( .MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH) - ) - bram_t2 - ( .clk (clk), - .a_addr(bram_t2_wr_addr), .a_wr(bram_t2_wr_en), .a_in(bram_t2_wr_data), .a_out(), - .b_addr(bram_t2_rd_addr), .b_out(bram_t2_rd_data) - ); - - bram_1rw_1ro_readfirst # - ( .MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH) - ) - bram_t3 - ( .clk (clk), - .a_addr(bram_t3_wr_addr), .a_wr(bram_t3_wr_en), .a_in(bram_t3_wr_data), .a_out(), - .b_addr(bram_t3_rd_addr), .b_out(bram_t3_rd_data) - ); - - bram_1rw_1ro_readfirst # - ( .MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH) - ) - bram_t4 - ( .clk (clk), - .a_addr(bram_t4_wr_addr), .a_wr(bram_t4_wr_en), .a_in(bram_t4_wr_data), .a_out(), - .b_addr(bram_t4_rd_addr), .b_out(bram_t4_rd_data) - ); - - - // - // uOP Trigger Logic - // - (* EQUIVALENT_REGISTER_REMOVAL="NO" *) reg uop_trig_fsm; - (* EQUIVALENT_REGISTER_REMOVAL="NO" *) reg uop_trig_cmp; - (* EQUIVALENT_REGISTER_REMOVAL="NO" *) reg uop_trig_mov; - (* EQUIVALENT_REGISTER_REMOVAL="NO" *) reg uop_trig_add; - (* EQUIVALENT_REGISTER_REMOVAL="NO" *) reg uop_trig_sub; - (* EQUIVALENT_REGISTER_REMOVAL="NO" *) reg uop_trig_mul; - - always @(posedge clk or negedge rst_n) - // - if (rst_n == 1'b0) begin - uop_trig_fsm <= 1'b0; - uop_trig_cmp <= 1'b0; - uop_trig_mov <= 1'b0; - uop_trig_add <= 1'b0; - uop_trig_sub <= 1'b0; - uop_trig_mul <= 1'b0; - end else begin - uop_trig_fsm <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0; - uop_trig_cmp <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0; - uop_trig_mov <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0; - uop_trig_add <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0; - uop_trig_sub <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0; - uop_trig_mul <= (fsm_state == FSM_STATE_FETCH) ? 1'b1 : 1'b0; - end - - - // - // FSM - // - localparam [ 1: 0] FSM_STATE_STALL = 2'b00; - localparam [ 1: 0] FSM_STATE_FETCH = 2'b01; - localparam [ 1: 0] FSM_STATE_EXECUTE = 2'b10; - - reg [ 1: 0] fsm_state = FSM_STATE_STALL; - wire [ 1: 0] fsm_state_next = (uop_opcode == OPCODE_RDY) ? FSM_STATE_STALL : FSM_STATE_FETCH; - - - // - // FSM Transition Logic - // - reg uop_done; - - always @(posedge clk or negedge rst_n) - // - if (rst_n == 1'b0) fsm_state <= FSM_STATE_STALL; - else case (fsm_state) - FSM_STATE_STALL: fsm_state <= ena ? FSM_STATE_FETCH : FSM_STATE_STALL; - FSM_STATE_FETCH: fsm_state <= FSM_STATE_EXECUTE; - FSM_STATE_EXECUTE: fsm_state <= (!uop_trig_fsm && uop_done) ? fsm_state_next : FSM_STATE_EXECUTE; - default: fsm_state <= FSM_STATE_STALL; - endcase - - - // - // uOP Address Increment Logic - // - always @(posedge clk) - // - if (fsm_state == FSM_STATE_STALL) - uop_addr <= 5'd0; - else if (fsm_state == FSM_STATE_EXECUTE) - if (!uop_trig_fsm && uop_done) - uop_addr <= (uop_opcode == OPCODE_RDY) ? 5'd0 : uop_addr + 1'b1; - - - // - // uOP Completion Logic - // - always @(*) - // - case (uop_opcode) - OPCODE_CMP: uop_done = mw_cmp_rdy; - OPCODE_MOV: uop_done = mw_mov_rdy; - OPCODE_ADD: uop_done = mod_add_rdy; - OPCODE_SUB: uop_done = mod_sub_rdy; - OPCODE_MUL: uop_done = mod_mul_rdy; - OPCODE_RDY: uop_done = 1'b1; - default: uop_done = 1'b0; - endcase - - - // - // Helper Modules Enable Logic - // - assign mw_cmp_ena = uop_opcode[0] & uop_trig_cmp; - assign mw_mov_ena = uop_opcode[1] & uop_trig_mov; - assign mod_add_ena = uop_opcode[2] & uop_trig_add; - assign mod_sub_ena = uop_opcode[3] & uop_trig_sub; - assign mod_mul_ena = uop_opcode[4] & uop_trig_mul; - - - // - // uOP Source Value Decoding Logic - // - reg [31: 0] uop_src_a_value; - - always @(*) - // - case (uop_src_a) - UOP_SRC_PX: uop_src_a_value = px_din; - UOP_SRC_PY: uop_src_a_value = py_din; - UOP_SRC_PZ: uop_src_a_value = pz_din; - - UOP_SRC_RX: uop_src_a_value = rx_din; - UOP_SRC_RY: uop_src_a_value = ry_din; - UOP_SRC_RZ: uop_src_a_value = rz_din; - - UOP_SRC_T1: uop_src_a_value = bram_t1_rd_data; - UOP_SRC_T2: uop_src_a_value = bram_t2_rd_data; - UOP_SRC_T3: uop_src_a_value = bram_t3_rd_data; - UOP_SRC_T4: uop_src_a_value = bram_t4_rd_data; - - UOP_SRC_ONE: uop_src_a_value = brom_one_dout; - UOP_SRC_ZERO: uop_src_a_value = brom_zero_dout; - UOP_SRC_DELTA: uop_src_a_value = brom_delta_dout; - - UOP_SRC_G_X: uop_src_a_value = brom_g_x_dout; - UOP_SRC_G_Y: uop_src_a_value = brom_g_y_dout; - - UOP_SRC_H_X: uop_src_a_value = brom_h_x_dout; - UOP_SRC_H_Y: uop_src_a_value = brom_h_y_dout; - - UOP_SRC_V: uop_src_a_value = v_din; - - default: uop_src_a_value = {32{1'bX}}; - endcase - - - assign mw_cmp_din_x = uop_src_a_value; - assign mw_mov_din_x = uop_src_a_value; - assign mod_add_din_a = uop_src_a_value; - assign mod_sub_din_a = uop_src_a_value; - assign mod_mul_din_a = uop_src_a_value; - - reg [31: 0] uop_src_b_value; - - always @(*) - // - case (uop_src_b) - UOP_SRC_PX: uop_src_b_value = px_din; - UOP_SRC_PY: uop_src_b_value = py_din; - UOP_SRC_PZ: uop_src_b_value = pz_din; - - UOP_SRC_RX: uop_src_b_value = rx_din; - UOP_SRC_RY: uop_src_b_value = ry_din; - UOP_SRC_RZ: uop_src_b_value = rz_din; - - UOP_SRC_T1: uop_src_b_value = bram_t1_rd_data; - UOP_SRC_T2: uop_src_b_value = bram_t2_rd_data; - UOP_SRC_T3: uop_src_b_value = bram_t3_rd_data; - UOP_SRC_T4: uop_src_b_value = bram_t4_rd_data; - - UOP_SRC_ONE: uop_src_b_value = brom_one_dout; - UOP_SRC_ZERO: uop_src_b_value = brom_zero_dout; - UOP_SRC_DELTA: uop_src_b_value = brom_delta_dout; - - UOP_SRC_G_X: uop_src_b_value = brom_g_x_dout; - UOP_SRC_G_Y: uop_src_b_value = brom_g_y_dout; - - UOP_SRC_H_X: uop_src_b_value = brom_h_x_dout; - UOP_SRC_H_Y: uop_src_b_value = brom_h_y_dout; - - UOP_SRC_V: uop_src_b_value = v_din; - - default: uop_src_b_value = {32{1'bX}}; - endcase - - assign mw_cmp_din_y = uop_src_b_value; - assign mod_add_din_b = uop_src_b_value; - assign mod_sub_din_b = uop_src_b_value; - assign mod_mul_din_b = uop_src_b_value; - - - // - // uOP Source & Destination Address Decoding Logic - // - reg [WORD_COUNTER_WIDTH-1:0] uop_src_a_addr; - reg [WORD_COUNTER_WIDTH-1:0] uop_src_b_addr; - reg [WORD_COUNTER_WIDTH-1:0] uop_dst_addr; - reg [WORD_COUNTER_WIDTH-1:0] uop_q_addr; - - assign q_addr = uop_q_addr; - - always @(*) - // - case (uop_opcode) - // - OPCODE_CMP: begin - uop_src_a_addr = mw_cmp_addr_xy; - uop_src_b_addr = mw_cmp_addr_xy; - uop_dst_addr = {WORD_COUNTER_WIDTH{1'bX}}; - uop_q_addr = {WORD_COUNTER_WIDTH{1'bX}}; - end - // - OPCODE_MOV: begin - uop_src_a_addr = mw_mov_addr_x; - uop_src_b_addr = {WORD_COUNTER_WIDTH{1'bX}}; - uop_dst_addr = mw_mov_addr_y; - uop_q_addr = {WORD_COUNTER_WIDTH{1'bX}}; - end - // - OPCODE_ADD: begin - uop_src_a_addr = mod_add_addr_ab; - uop_src_b_addr = mod_add_addr_ab; - uop_dst_addr = mod_add_addr_s; - uop_q_addr = mod_add_addr_n; - end - // - OPCODE_SUB: begin - uop_src_a_addr = mod_sub_addr_ab; - uop_src_b_addr = mod_sub_addr_ab; - uop_dst_addr = mod_sub_addr_d; - uop_q_addr = mod_sub_addr_n; - end - // - OPCODE_MUL: begin - uop_src_a_addr = mod_mul_addr_a; - uop_src_b_addr = mod_mul_addr_b; - uop_dst_addr = mod_mul_addr_p; - uop_q_addr = mod_mul_addr_n; - end - // - default: begin - uop_src_a_addr = {WORD_COUNTER_WIDTH{1'bX}}; - uop_src_b_addr = {WORD_COUNTER_WIDTH{1'bX}}; - uop_dst_addr = {WORD_COUNTER_WIDTH{1'bX}}; - uop_q_addr = {WORD_COUNTER_WIDTH{1'bX}}; - end - // - endcase - - - // - // uOP Conditional Execution Logic - // - reg uop_exec_effective; - - always @(*) - // - case (uop_exec) - UOP_EXEC_ALWAYS: uop_exec_effective = 1'b1; - UOP_EXEC_PZT1T2_0XX: uop_exec_effective = flag_pz_is_zero; - UOP_EXEC_PZT1T2_100: uop_exec_effective = !flag_pz_is_zero && flag_t1_is_zero && flag_t2_is_zero; - UOP_EXEC_PZT1T2_101: uop_exec_effective = !flag_pz_is_zero && flag_t1_is_zero && !flag_t2_is_zero; - endcase - - - // - // uOP Destination Store Logic - // - reg uop_dst_wren; - - always @(*) - // - case (uop_opcode) - // - OPCODE_MOV: uop_dst_wren = mw_mov_wren_y & uop_exec_effective; - OPCODE_ADD: uop_dst_wren = mod_add_wren_s; - OPCODE_SUB: uop_dst_wren = mod_sub_wren_d; - OPCODE_MUL: uop_dst_wren = mod_mul_wren_p; - default: uop_dst_wren = 1'b0; - // - endcase - - - always @(*) begin - // - // - // - if (uop_src_a == UOP_SRC_PX) px_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_PX) px_addr = uop_src_b_addr; - else px_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - if (uop_src_a == UOP_SRC_PY) py_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_PY) py_addr = uop_src_b_addr; - else py_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - if (uop_src_a == UOP_SRC_PZ) pz_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_PZ) pz_addr = uop_src_b_addr; - else pz_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - // - // - if (uop_src_a == UOP_SRC_ONE) brom_one_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_ONE) brom_one_addr = uop_src_b_addr; - else brom_one_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - //if (uop_src_a == UOP_SRC_ZERO) brom_zero_addr = uop_src_a_addr; - //else if (uop_src_b == UOP_SRC_ZERO) brom_zero_addr = uop_src_b_addr; - //else brom_zero_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - if (uop_src_a == UOP_SRC_DELTA) brom_delta_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_DELTA) brom_delta_addr = uop_src_b_addr; - else brom_delta_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - // - // - if (uop_src_a == UOP_SRC_G_X) brom_g_x_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_G_X) brom_g_x_addr = uop_src_b_addr; - else brom_g_x_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - if (uop_src_a == UOP_SRC_G_Y) brom_g_y_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_G_Y) brom_g_y_addr = uop_src_b_addr; - else brom_g_y_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - // - // - if (uop_src_a == UOP_SRC_H_X) brom_h_x_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_H_X) brom_h_x_addr = uop_src_b_addr; - else brom_h_x_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - if (uop_src_a == UOP_SRC_H_Y) brom_h_y_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_H_Y) brom_h_y_addr = uop_src_b_addr; - else brom_h_y_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - // - // - if (uop_src_a == UOP_SRC_V) v_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_V) v_addr = uop_src_b_addr; - else v_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - // - // - if (uop_src_a == UOP_SRC_T1) bram_t1_rd_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_T1) bram_t1_rd_addr = uop_src_b_addr; - else bram_t1_rd_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - if (uop_src_a == UOP_SRC_T2) bram_t2_rd_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_T2) bram_t2_rd_addr = uop_src_b_addr; - else bram_t2_rd_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - if (uop_src_a == UOP_SRC_T3) bram_t3_rd_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_T3) bram_t3_rd_addr = uop_src_b_addr; - else bram_t3_rd_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - if (uop_src_a == UOP_SRC_T4) bram_t4_rd_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_T4) bram_t4_rd_addr = uop_src_b_addr; - else bram_t4_rd_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - // - // - if (uop_dst == UOP_DST_T1) bram_t1_wr_addr = uop_dst_addr; - else bram_t1_wr_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - if (uop_dst == UOP_DST_T2) bram_t2_wr_addr = uop_dst_addr; - else bram_t2_wr_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - if (uop_dst == UOP_DST_T3) bram_t3_wr_addr = uop_dst_addr; - else bram_t3_wr_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - if (uop_dst == UOP_DST_T4) bram_t4_wr_addr = uop_dst_addr; - else bram_t4_wr_addr = {WORD_COUNTER_WIDTH{1'bX}}; - // - // - // - if ((uop_dst == UOP_DST_RX) && (uop_dst_wren)) rx_addr = uop_dst_addr; - else begin - if (uop_src_a == UOP_SRC_RX) rx_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_RX) rx_addr = uop_src_b_addr; - else rx_addr = {WORD_COUNTER_WIDTH{1'bX}}; - end - // - if ((uop_dst == UOP_DST_RY) && (uop_dst_wren)) ry_addr = uop_dst_addr; - else begin - if (uop_src_a == UOP_SRC_RY) ry_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_RY) ry_addr = uop_src_b_addr; - else ry_addr = {WORD_COUNTER_WIDTH{1'bX}}; - end - // - if ((uop_dst == UOP_DST_RZ) && (uop_dst_wren)) rz_addr = uop_dst_addr; - else begin - if (uop_src_a == UOP_SRC_RZ) rz_addr = uop_src_a_addr; - else if (uop_src_b == UOP_SRC_RZ) rz_addr = uop_src_b_addr; - else rz_addr = {WORD_COUNTER_WIDTH{1'bX}}; - end - // - end - - - assign rx_wren = uop_dst_wren && (uop_dst == UOP_DST_RX); - assign ry_wren = uop_dst_wren && (uop_dst == UOP_DST_RY); - assign rz_wren = uop_dst_wren && (uop_dst == UOP_DST_RZ); - - assign bram_t1_wr_en = uop_dst_wren && (uop_dst == UOP_DST_T1); - assign bram_t2_wr_en = uop_dst_wren && (uop_dst == UOP_DST_T2); - assign bram_t3_wr_en = uop_dst_wren && (uop_dst == UOP_DST_T3); - assign bram_t4_wr_en = uop_dst_wren && (uop_dst == UOP_DST_T4); - - - - // - // Destination Value Selector - // - reg [31: 0] uop_dst_value; - - always @(*) - // - case (uop_opcode) - - OPCODE_MOV: uop_dst_value = mw_mov_dout_y; - OPCODE_ADD: uop_dst_value = mod_add_dout_s; - OPCODE_SUB: uop_dst_value = mod_sub_dout_d; - OPCODE_MUL: uop_dst_value = mod_mul_dout_p; - - default: uop_dst_value = {32{1'bX}}; - - endcase - - assign rx_dout = uop_dst_value; - assign ry_dout = uop_dst_value; - assign rz_dout = uop_dst_value; - - assign bram_t1_wr_data = uop_dst_value; - assign bram_t2_wr_data = uop_dst_value; - assign bram_t3_wr_data = uop_dst_value; - assign bram_t4_wr_data = uop_dst_value; - - - // - // Latch Comparison Flags - // - always @(posedge clk) - // - if ( (fsm_state == FSM_STATE_EXECUTE) && - (uop_opcode == OPCODE_CMP) && - (uop_done && !uop_trig_cmp) ) begin - - if ( (uop_src_a == UOP_SRC_PZ) && (uop_src_b == UOP_SRC_ZERO) ) - flag_pz_is_zero <= !mw_cmp_out_l && mw_cmp_out_e && !mw_cmp_out_g; - - if ( (uop_src_a == UOP_SRC_T1) && (uop_src_b == UOP_SRC_ZERO) ) - flag_t1_is_zero <= !mw_cmp_out_l && mw_cmp_out_e && !mw_cmp_out_g; - - if ( (uop_src_a == UOP_SRC_T2) && (uop_src_b == UOP_SRC_ZERO) ) - flag_t2_is_zero <= !mw_cmp_out_l && mw_cmp_out_e && !mw_cmp_out_g; - - end - - - // - // Ready Flag Logic - // - reg rdy_reg = 1'b1; - assign rdy = rdy_reg; - - always @(posedge clk or negedge rst_n) - // - if (rst_n == 1'b0) rdy_reg <= 1'b1; - else begin - - /* clear flag */ - if (fsm_state == FSM_STATE_STALL) - if (ena) rdy_reg <= 1'b0; - - /* set flag */ - if ((fsm_state == FSM_STATE_EXECUTE) && !uop_trig_fsm && uop_done) - if (uop_opcode == OPCODE_RDY) rdy_reg <= 1'b1; - - end - - -endmodule - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/rtl/curve/curve_mul_256.v b/rtl/curve/curve_mul_256.v deleted file mode 100644 index 43e2c7b..0000000 --- a/rtl/curve/curve_mul_256.v +++ /dev/null @@ -1,719 +0,0 @@ -//------------------------------------------------------------------------------ -// -// curve_mul_256.v -// ----------------------------------------------------------------------------- -// Elliptic curve point scalar multiplier. -// -// Authors: Pavel Shatov -// -// Copyright (c) 2016, NORDUnet A/S -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the NORDUnet nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//------------------------------------------------------------------------------ - -module curve_mul_256 - ( - clk, rst_n, - ena, rdy, - k_addr, rx_addr, ry_addr, - rx_wren, ry_wren, - k_din, - rx_dout, ry_dout - ); - - - // - // Constants - // - localparam WORD_COUNTER_WIDTH = 3; // 0 .. 7 - localparam OPERAND_NUM_WORDS = 8; // 8 * 32 = 256 - - - // - // Ports - // - input wire clk; // system clock - input wire rst_n; // active-low async reset - - input wire ena; // enable input - output wire rdy; // ready output - - output wire [ 2: 0] k_addr; - output wire [ 2: 0] rx_addr; - output wire [ 2: 0] ry_addr; - - output wire rx_wren; - output wire ry_wren; - - input wire [31: 0] k_din; - - output wire [31: 0] rx_dout; - output wire [31: 0] ry_dout; - - - // - // Temporary Variables - // - reg [ 2: 0] bram_tx_wr_addr; - reg [ 2: 0] bram_ty_wr_addr; - reg [ 2: 0] bram_tz_wr_addr; - - reg [ 2: 0] bram_rx_wr_addr; - reg [ 2: 0] bram_ry_wr_addr; - reg [ 2: 0] bram_rz_wr_addr; - wire [ 2: 0] bram_rz1_wr_addr; - - reg [ 2: 0] bram_tx_rd_addr; - reg [ 2: 0] bram_ty_rd_addr; - reg [ 2: 0] bram_tz_rd_addr; - - reg [ 2: 0] bram_rx_rd_addr; - reg [ 2: 0] bram_ry_rd_addr; - reg [ 2: 0] bram_rz_rd_addr; - wire [ 2: 0] bram_rz1_rd_addr; - - reg bram_tx_wr_en; - reg bram_ty_wr_en; - reg bram_tz_wr_en; - - reg bram_rx_wr_en; - reg bram_ry_wr_en; - reg bram_rz_wr_en; - wire bram_rz1_wr_en; - - wire [31: 0] bram_tx_rd_data; - wire [31: 0] bram_ty_rd_data; - wire [31: 0] bram_tz_rd_data; - - wire [31: 0] bram_rx_rd_data; - wire [31: 0] bram_ry_rd_data; - wire [31: 0] bram_rz_rd_data; - wire [31: 0] bram_rz1_rd_data; - - reg [31: 0] bram_tx_wr_data_in; - reg [31: 0] bram_ty_wr_data_in; - reg [31: 0] bram_tz_wr_data_in; - - reg [31: 0] bram_rx_wr_data_in; - reg [31: 0] bram_ry_wr_data_in; - reg [31: 0] bram_rz_wr_data_in; - wire [31: 0] bram_rz1_wr_data_in; - - wire [31: 0] bram_tx_wr_data_out; - wire [31: 0] bram_ty_wr_data_out; - wire [31: 0] bram_tz_wr_data_out; - - wire [31: 0] bram_rx_wr_data_out; - wire [31: 0] bram_ry_wr_data_out; - wire [31: 0] bram_rz_wr_data_out; - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) - bram_tx (.clk(clk), - .a_addr(bram_tx_wr_addr), .a_wr(bram_tx_wr_en), .a_in(bram_tx_wr_data_in), .a_out(bram_tx_wr_data_out), - .b_addr(bram_tx_rd_addr), .b_out(bram_tx_rd_data)); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) - bram_ty (.clk(clk), - .a_addr(bram_ty_wr_addr), .a_wr(bram_ty_wr_en), .a_in(bram_ty_wr_data_in), .a_out(bram_ty_wr_data_out), - .b_addr(bram_ty_rd_addr), .b_out(bram_ty_rd_data)); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) - bram_tz (.clk(clk), - .a_addr(bram_tz_wr_addr), .a_wr(bram_tz_wr_en), .a_in(bram_tz_wr_data_in), .a_out(bram_tz_wr_data_out), - .b_addr(bram_tz_rd_addr), .b_out(bram_tz_rd_data)); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) - bram_rx (.clk(clk), - .a_addr(bram_rx_wr_addr), .a_wr(bram_rx_wr_en), .a_in(bram_rx_wr_data_in), .a_out(bram_rx_wr_data_out), - .b_addr(bram_rx_rd_addr), .b_out(bram_rx_rd_data)); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) - bram_ry (.clk(clk), - .a_addr(bram_ry_wr_addr), .a_wr(bram_ry_wr_en), .a_in(bram_ry_wr_data_in), .a_out(bram_ry_wr_data_out), - .b_addr(bram_ry_rd_addr), .b_out(bram_ry_rd_data)); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) - bram_rz (.clk(clk), - .a_addr(bram_rz_wr_addr), .a_wr(bram_rz_wr_en), .a_in(bram_rz_wr_data_in), .a_out(bram_rz_wr_data_out), - .b_addr(bram_rz_rd_addr), .b_out(bram_rz_rd_data)); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) - bram_rz1 (.clk(clk), - .a_addr(bram_rz1_wr_addr), .a_wr(bram_rz1_wr_en), .a_in(bram_rz1_wr_data_in), .a_out(), - .b_addr(bram_rz1_rd_addr), .b_out(bram_rz1_rd_data)); - - - // - // FSM - // - localparam [ 3: 0] FSM_STATE_IDLE = 4'd00; - localparam [ 3: 0] FSM_STATE_PREPARE_TRIG = 4'd01; - localparam [ 3: 0] FSM_STATE_PREPARE_WAIT = 4'd02; - localparam [ 3: 0] FSM_STATE_DOUBLE_TRIG = 4'd03; - localparam [ 3: 0] FSM_STATE_DOUBLE_WAIT = 4'd04; - localparam [ 3: 0] FSM_STATE_ADD_TRIG = 4'd05; - localparam [ 3: 0] FSM_STATE_ADD_WAIT = 4'd06; - localparam [ 3: 0] FSM_STATE_COPY_TRIG = 4'd07; - localparam [ 3: 0] FSM_STATE_COPY_WAIT = 4'd08; - localparam [ 3: 0] FSM_STATE_INVERT_TRIG = 4'd09; - localparam [ 3: 0] FSM_STATE_INVERT_WAIT = 4'd10; - localparam [ 3: 0] FSM_STATE_CONVERT_TRIG = 4'd11; - localparam [ 3: 0] FSM_STATE_CONVERT_WAIT = 4'd12; - localparam [ 3: 0] FSM_STATE_DONE = 4'd13; - - reg [3:0] fsm_state = FSM_STATE_IDLE; - - - // - // Round Counter - // - reg [ 7: 0] bit_counter; - wire [ 7: 0] bit_counter_max = 8'd255; - wire [ 7: 0] bit_counter_zero = 8'd0; - wire [ 7: 0] bit_counter_next = - (bit_counter < bit_counter_max) ? bit_counter + 1'b1 : bit_counter_zero; - - - // - // Round Completion - // - wire [ 3: 0] fsm_state_round_next = (bit_counter < bit_counter_max) ? - FSM_STATE_DOUBLE_TRIG : FSM_STATE_INVERT_TRIG; - - - // - // OP Trigger Logic - // - reg op_trig; - wire op_done; - - always @(posedge clk or negedge rst_n) - // - if (rst_n == 1'b0) op_trig <= 1'b0; - else op_trig <= (fsm_state == FSM_STATE_PREPARE_TRIG) || - (fsm_state == FSM_STATE_DOUBLE_TRIG) || - (fsm_state == FSM_STATE_ADD_TRIG) || - (fsm_state == FSM_STATE_CONVERT_TRIG); - - // - // Microprograms - // - wire [ 5: 0] op_rom_addr; - wire [19: 0] op_rom_init_data; - wire [19: 0] op_rom_dbl_data; - wire [19: 0] op_rom_add_data; - wire [19: 0] op_rom_conv_data; - reg [19: 0] op_rom_mux_data; - - (* EQUIVALENT_REGISTER_REMOVAL="NO" *) - uop_init_rom op_rom_init - ( - .clk (clk), - .addr (op_rom_addr), - .data (op_rom_init_data) - ); - (* EQUIVALENT_REGISTER_REMOVAL="NO" *) - uop_dbl_rom op_rom_dbl - ( - .clk (clk), - .addr (op_rom_addr), - .data (op_rom_dbl_data) - ); - - (* EQUIVALENT_REGISTER_REMOVAL="NO" *) - uop_add_rom op_rom_add - ( - .clk (clk), - .addr (op_rom_addr), - .data (op_rom_add_data) - ); - - (* EQUIVALENT_REGISTER_REMOVAL="NO" *) - uop_conv_rom op_rom_conv - ( - .clk (clk), - .addr (op_rom_addr), - .data (op_rom_conv_data) - ); - - always @(*) - // - case (fsm_state) - FSM_STATE_PREPARE_WAIT: op_rom_mux_data = op_rom_init_data; - FSM_STATE_DOUBLE_WAIT: op_rom_mux_data = op_rom_dbl_data; - FSM_STATE_ADD_WAIT: op_rom_mux_data = op_rom_add_data; - FSM_STATE_CONVERT_WAIT: op_rom_mux_data = op_rom_conv_data; - default: op_rom_mux_data = {20{1'bX}}; - endcase - - - - // - // Modulus - // - reg [ 2: 0] rom_q_addr; - wire [31: 0] rom_q_data; - - brom_p256_q rom_q - ( - .clk (clk), - .b_addr (rom_q_addr), - .b_out (rom_q_data) - ); - - - // - // Worker - // - wire [ 2: 0] worker_addr_px; - wire [ 2: 0] worker_addr_py; - wire [ 2: 0] worker_addr_pz; - - wire [ 2: 0] worker_addr_rx; - wire [ 2: 0] worker_addr_ry; - wire [ 2: 0] worker_addr_rz; - - wire [ 2: 0] worker_addr_q; - - wire worker_wren_rx; - wire worker_wren_ry; - wire worker_wren_rz; - - reg [31: 0] worker_din_px; - reg [31: 0] worker_din_py; - reg [31: 0] worker_din_pz; - - reg [31: 0] worker_din_rx; - reg [31: 0] worker_din_ry; - reg [31: 0] worker_din_rz; - - wire [31: 0] worker_dout_rx; - wire [31: 0] worker_dout_ry; - wire [31: 0] worker_dout_rz; - - curve_dbl_add_256 worker - ( - .clk (clk), - .rst_n (rst_n), - - .ena (op_trig), - .rdy (op_done), - - .uop_addr (op_rom_addr), - .uop (op_rom_mux_data), - - .px_addr (worker_addr_px), - .py_addr (worker_addr_py), - .pz_addr (worker_addr_pz), - - .rx_addr (worker_addr_rx), - .ry_addr (worker_addr_ry), - .rz_addr (worker_addr_rz), - - .q_addr (worker_addr_q), - - .v_addr (bram_rz1_rd_addr), - - .rx_wren (worker_wren_rx), - .ry_wren (worker_wren_ry), - .rz_wren (worker_wren_rz), - - .px_din (worker_din_px), - .py_din (worker_din_py), - .pz_din (worker_din_pz), - - .rx_din (worker_din_rx), - .ry_din (worker_din_ry), - .rz_din (worker_din_rz), - - .rx_dout (worker_dout_rx), - .ry_dout (worker_dout_ry), - .rz_dout (worker_dout_rz), - - .q_din (rom_q_data), - - .v_din (bram_rz1_rd_data) - ); - - - // - // Mover - // - reg move_trig; - wire move_done; - - wire [ 2: 0] mover_addr_x; - wire [ 2: 0] mover_addr_y; - - wire mover_wren_y; - - always @(posedge clk or negedge rst_n) - // - if (rst_n == 1'b0) move_trig <= 1'b0; - else move_trig <= (fsm_state == FSM_STATE_COPY_TRIG); - - mw_mover # - ( - .WORD_COUNTER_WIDTH (3), - .OPERAND_NUM_WORDS (8) - ) - mover - ( - .clk (clk), - .rst_n (rst_n), - - .ena (move_trig), - .rdy (move_done), - - .x_addr (mover_addr_x), - .y_addr (mover_addr_y), - .y_wren (mover_wren_y), - - .x_din ({32{1'bX}}), - .y_dout () - ); - - - // - // Invertor - // - reg invert_trig; - wire invert_done; - - wire [ 2: 0] invertor_addr_a; - wire [ 2: 0] invertor_addr_q; - - always @(posedge clk or negedge rst_n) - // - if (rst_n == 1'b0) invert_trig <= 1'b0; - else invert_trig <= (fsm_state == FSM_STATE_INVERT_TRIG); - - modular_invertor # - ( - .MAX_OPERAND_WIDTH(256) - ) - invertor - ( - .clk (clk), - .rst_n (rst_n), - - .ena (invert_trig), - .rdy (invert_done), - - .a_addr (invertor_addr_a), - .q_addr (invertor_addr_q), - .a1_addr (bram_rz1_wr_addr), - .a1_wren (bram_rz1_wr_en), - - .a_din (bram_rz_rd_data), - .q_din (rom_q_data), - .a1_dout (bram_rz1_wr_data_in) - ); - - - // - // FSM Transition Logic - // - always @(posedge clk or negedge rst_n) - // - if (rst_n == 1'b0) fsm_state <= FSM_STATE_IDLE; - else case (fsm_state) - - FSM_STATE_IDLE: fsm_state <= ena ? FSM_STATE_PREPARE_TRIG : FSM_STATE_IDLE; - - FSM_STATE_PREPARE_TRIG: fsm_state <= FSM_STATE_PREPARE_WAIT; - FSM_STATE_PREPARE_WAIT: fsm_state <= (!op_trig && op_done) ? FSM_STATE_DOUBLE_TRIG : FSM_STATE_PREPARE_WAIT; - - FSM_STATE_DOUBLE_TRIG: fsm_state <= FSM_STATE_DOUBLE_WAIT; - FSM_STATE_DOUBLE_WAIT: fsm_state <= (!op_trig && op_done) ? FSM_STATE_ADD_TRIG : FSM_STATE_DOUBLE_WAIT; - - FSM_STATE_ADD_TRIG: fsm_state <= FSM_STATE_ADD_WAIT; - FSM_STATE_ADD_WAIT: fsm_state <= (!op_trig && op_done) ? FSM_STATE_COPY_TRIG : FSM_STATE_ADD_WAIT; - - FSM_STATE_COPY_TRIG: fsm_state <= FSM_STATE_COPY_WAIT; - FSM_STATE_COPY_WAIT: fsm_state <= (!move_trig && move_done) ? fsm_state_round_next : FSM_STATE_COPY_WAIT; - - FSM_STATE_INVERT_TRIG: fsm_state <= FSM_STATE_INVERT_WAIT; - FSM_STATE_INVERT_WAIT: fsm_state <= (!invert_trig && invert_done) ? FSM_STATE_CONVERT_TRIG : FSM_STATE_INVERT_WAIT; - - FSM_STATE_CONVERT_TRIG: fsm_state <= FSM_STATE_CONVERT_WAIT; - FSM_STATE_CONVERT_WAIT: fsm_state <= (!op_trig && op_done) ? FSM_STATE_DONE : FSM_STATE_CONVERT_WAIT; - - FSM_STATE_DONE: fsm_state <= FSM_STATE_IDLE; - - default: fsm_state <= FSM_STATE_IDLE; - - endcase - - - // - // Bit Counter Increment - // - always @(posedge clk) begin - // - if ((fsm_state == FSM_STATE_PREPARE_WAIT) && !op_trig && op_done) - bit_counter <= bit_counter_zero; - // - if ((fsm_state == FSM_STATE_COPY_WAIT) && !move_trig && move_done) - bit_counter <= bit_counter_next; - // - end - - - // - // K Latch Logic - // - reg [ 2: 0] k_addr_reg; - reg [31: 0] k_din_reg; - - assign k_addr = k_addr_reg; - - always @(posedge clk) begin - // - if (fsm_state == FSM_STATE_DOUBLE_TRIG) - k_addr_reg <= 3'd7 - bit_counter[7:5]; - // - if (fsm_state == FSM_STATE_ADD_TRIG) - k_din_reg <= (bit_counter[4:0] == 5'd0) ? k_din : {k_din_reg[30:0], 1'bX}; - // - end - - - - // - // Copy Inhibit Logic - // - wire move_inhibit = k_din_reg[31]; - - wire copy_t2r_int = mover_wren_y & ~move_inhibit; - - - always @(*) begin - // - // Q - // - case (fsm_state) - FSM_STATE_DOUBLE_WAIT: rom_q_addr = worker_addr_q; - FSM_STATE_ADD_WAIT: rom_q_addr = worker_addr_q; - FSM_STATE_INVERT_WAIT: rom_q_addr = invertor_addr_q; - FSM_STATE_CONVERT_WAIT: rom_q_addr = worker_addr_q; - default: rom_q_addr = worker_addr_q; - endcase - - // - // R(X,Y,Z) - // - case (fsm_state) - // - FSM_STATE_PREPARE_WAIT: begin - // - bram_rx_rd_addr <= {3{1'bX}}; bram_ry_rd_addr <= {3{1'bX}}; bram_rz_rd_addr <= {3{1'bX}}; - bram_rx_wr_addr <= worker_addr_rx; bram_ry_wr_addr <= worker_addr_ry; bram_rz_wr_addr <= worker_addr_rz; - bram_rx_wr_en <= worker_wren_rx; bram_ry_wr_en <= worker_wren_ry; bram_rz_wr_en <= worker_wren_rz; - bram_rx_wr_data_in <= worker_dout_rx; bram_ry_wr_data_in <= worker_dout_ry; bram_rz_wr_data_in <= worker_dout_rz; - // - end - // - FSM_STATE_DOUBLE_WAIT: begin - // - bram_rx_rd_addr <= worker_addr_px; bram_ry_rd_addr <= worker_addr_py; bram_rz_rd_addr <= worker_addr_pz; - bram_rx_wr_addr <= {3{1'bX}}; bram_ry_wr_addr <= {3{1'bX}}; bram_rz_wr_addr <= {3{1'bX}}; - bram_rx_wr_en <= 1'b0; bram_ry_wr_en <= 1'b0; bram_rz_wr_en <= 1'b0; - bram_rx_wr_data_in <= {32{1'bX}}; bram_ry_wr_data_in <= {32{1'bX}}; bram_rz_wr_data_in <= {32{1'bX}}; - // - end - // - FSM_STATE_ADD_WAIT: begin - // - bram_rx_rd_addr <= {3{1'bX}}; bram_ry_rd_addr <= {3{1'bX}}; bram_rz_rd_addr <= {3{1'bX}}; - bram_rx_wr_addr <= worker_addr_rx; bram_ry_wr_addr <= worker_addr_ry; bram_rz_wr_addr <= worker_addr_rz; - bram_rx_wr_en <= worker_wren_rx; bram_ry_wr_en <= worker_wren_ry; bram_rz_wr_en <= worker_wren_rz; - bram_rx_wr_data_in <= worker_dout_rx; bram_ry_wr_data_in <= worker_dout_ry; bram_rz_wr_data_in <= worker_dout_rz; - // - end - // - FSM_STATE_COPY_WAIT: begin - // - bram_rx_rd_addr <= {3{1'bX}}; bram_ry_rd_addr <= {3{1'bX}}; bram_rz_rd_addr <= {3{1'bX}}; - bram_rx_wr_addr <= mover_addr_y; bram_ry_wr_addr <= mover_addr_y; bram_rz_wr_addr <= mover_addr_y; - bram_rx_wr_en <= copy_t2r_int; bram_ry_wr_en <= copy_t2r_int; bram_rz_wr_en <= copy_t2r_int; - bram_rx_wr_data_in <= bram_tx_rd_data; bram_ry_wr_data_in <= bram_ty_rd_data; bram_rz_wr_data_in <= bram_tz_rd_data; - // - end - // - FSM_STATE_INVERT_WAIT: begin - // - bram_rx_rd_addr <= {3{1'bX}}; bram_ry_rd_addr <= {3{1'bX}}; bram_rz_rd_addr <= invertor_addr_a; - bram_rx_wr_addr <= {3{1'bX}}; bram_ry_wr_addr <= {3{1'bX}}; bram_rz_wr_addr <= {3{1'bX}}; - bram_rx_wr_en <= 1'b0; bram_ry_wr_en <= 1'b0; bram_rz_wr_en <= 1'b0; - bram_rx_wr_data_in <= {32{1'bX}}; bram_ry_wr_data_in <= {32{1'bX}}; bram_rz_wr_data_in <= {32{1'bX}}; - // - end - // - FSM_STATE_CONVERT_WAIT: begin - // - bram_rx_rd_addr <= worker_addr_px; bram_ry_rd_addr <= worker_addr_py; bram_rz_rd_addr <= worker_addr_pz; - bram_rx_wr_addr <= {3{1'bX}}; bram_ry_wr_addr <= {3{1'bX}}; bram_rz_wr_addr <= {3{1'bX}}; - bram_rx_wr_en <= 1'b0; bram_ry_wr_en <= 1'b0; bram_rz_wr_en <= 1'b0; - bram_rx_wr_data_in <= {32{1'bX}}; bram_ry_wr_data_in <= {32{1'bX}}; bram_rz_wr_data_in <= {32{1'bX}}; - // - end - - // - default: begin - // - bram_rx_rd_addr <= {3{1'bX}}; bram_ry_rd_addr <= {3{1'bX}}; bram_rz_rd_addr <= {3{1'bX}}; - bram_rx_wr_addr <= {3{1'bX}}; bram_ry_wr_addr <= {3{1'bX}}; bram_rz_wr_addr <= {3{1'bX}}; - bram_rx_wr_en <= 1'b0; bram_ry_wr_en <= 1'b0; bram_rz_wr_en <= 1'b0; - bram_rx_wr_data_in <= {32{1'bX}}; bram_ry_wr_data_in <= {32{1'bX}}; bram_rz_wr_data_in <= {32{1'bX}}; - // - end - // - endcase - // - // T(X,Y,Z) - // - case (fsm_state) - // - FSM_STATE_DOUBLE_WAIT: begin - // - bram_tx_rd_addr <= {3{1'bX}}; bram_ty_rd_addr <= {3{1'bX}}; bram_tz_rd_addr <= {3{1'bX}}; - bram_tx_wr_addr <= worker_addr_rx; bram_ty_wr_addr <= worker_addr_ry; bram_tz_wr_addr <= worker_addr_rz; - bram_tx_wr_en <= worker_wren_rx; bram_ty_wr_en <= worker_wren_ry; bram_tz_wr_en <= worker_wren_rz; - bram_tx_wr_data_in <= worker_dout_rx; bram_ty_wr_data_in <= worker_dout_ry; bram_tz_wr_data_in <= worker_dout_rz; - // - end - // - FSM_STATE_ADD_WAIT: begin - // - bram_tx_rd_addr <= worker_addr_px; bram_ty_rd_addr <= worker_addr_py; bram_tz_rd_addr <= worker_addr_pz; - bram_tx_wr_addr <= {3{1'bX}}; bram_ty_wr_addr <= {3{1'bX}}; bram_tz_wr_addr <= {3{1'bX}}; - bram_tx_wr_en <= 1'b0; bram_ty_wr_en <= 1'b0; bram_tz_wr_en <= 1'b0; - bram_tx_wr_data_in <= {32{1'bX}}; bram_ty_wr_data_in <= {32{1'bX}}; bram_tz_wr_data_in <= {32{1'bX}}; - // - end - // - FSM_STATE_COPY_WAIT: begin - // - bram_tx_rd_addr <= mover_addr_x; bram_ty_rd_addr <= mover_addr_x; bram_tz_rd_addr <= mover_addr_x; - bram_tx_wr_addr <= {3{1'bX}}; bram_ty_wr_addr <= {3{1'bX}}; bram_tz_wr_addr <= {3{1'bX}}; - bram_tx_wr_en <= 1'b0; bram_ty_wr_en <= 1'b0; bram_tz_wr_en <= 1'b0; - bram_tx_wr_data_in <= {32{1'bX}}; bram_ty_wr_data_in <= {32{1'bX}}; bram_tz_wr_data_in <= {32{1'bX}}; - // - end - - // - default: begin - // - bram_tx_rd_addr <= {3{1'bX}}; bram_ty_rd_addr <= {3{1'bX}}; bram_tz_rd_addr <= {3{1'bX}}; - bram_tx_wr_addr <= {3{1'bX}}; bram_ty_wr_addr <= {3{1'bX}}; bram_tz_wr_addr <= {3{1'bX}}; - bram_tx_wr_en <= 1'b0; bram_ty_wr_en <= 1'b0; bram_tz_wr_en <= 1'b0; - bram_tx_wr_data_in <= {32{1'bX}}; bram_ty_wr_data_in <= {32{1'bX}}; bram_tz_wr_data_in <= {32{1'bX}}; - // - end - // - endcase - // - // Worker - // - case (fsm_state) - // - FSM_STATE_DOUBLE_WAIT: begin - // - worker_din_px <= bram_rx_rd_data; worker_din_py <= bram_ry_rd_data; worker_din_pz <= bram_rz_rd_data; - worker_din_rx <= bram_tx_wr_data_out; worker_din_ry <= bram_ty_wr_data_out; worker_din_rz <= bram_tz_wr_data_out; - // - end - // - FSM_STATE_ADD_WAIT: begin - // - worker_din_px <= bram_tx_rd_data; worker_din_py <= bram_ty_rd_data; worker_din_pz <= bram_tz_rd_data; - worker_din_rx <= bram_rx_wr_data_out; worker_din_ry <= bram_ry_wr_data_out; worker_din_rz <= bram_rz_wr_data_out; - // - end - // - FSM_STATE_CONVERT_WAIT: begin - // - worker_din_px <= bram_rx_rd_data; worker_din_py <= bram_ry_rd_data; worker_din_pz <= bram_rz_rd_data; - worker_din_rx <= {32{1'bX}}; worker_din_ry <= {32{1'bX}}; worker_din_rz <= {32{1'bX}}; - // - end - // - default: begin - // - worker_din_px <= {32{1'bX}}; worker_din_py <= {32{1'bX}}; worker_din_pz <= {32{1'bX}}; - worker_din_rx <= {32{1'bX}}; worker_din_ry <= {32{1'bX}}; worker_din_rz <= {32{1'bX}}; - // - end - // - endcase - // - end - - - // - // Output Mapping - // - assign rx_wren = worker_wren_rx && (fsm_state == FSM_STATE_CONVERT_WAIT); - assign ry_wren = worker_wren_ry && (fsm_state == FSM_STATE_CONVERT_WAIT); - - assign rx_dout = worker_dout_rx; - assign ry_dout = worker_dout_ry; - - assign rx_addr = worker_addr_rx; - assign ry_addr = worker_addr_ry; - - - // - // Ready Flag Logic - // - reg rdy_reg = 1'b1; - assign rdy = rdy_reg; - - always @(posedge clk or negedge rst_n) - - if (rst_n == 1'b0) rdy_reg <= 1'b1; - else begin - - /* clear flag */ - if ((fsm_state == FSM_STATE_IDLE) && ena) - rdy_reg <= 1'b0; - - /* set flag */ - if (fsm_state == FSM_STATE_DONE) - rdy_reg <= 1'b1; - - end - - -endmodule - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/rtl/curve/rom/brom_p256_delta.v b/rtl/curve/rom/brom_p256_delta.v deleted file mode 100644 index 4637575..0000000 --- a/rtl/curve/rom/brom_p256_delta.v +++ /dev/null @@ -1,68 +0,0 @@ -//====================================================================== -// -// Copyright (c) 2016, 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. -// -//====================================================================== - -`timescale 1ns / 1ps - -module brom_p256_delta - ( - input wire clk, - input wire [ 3-1:0] b_addr, - output wire [32-1:0] b_out - ); - - - // - // Output Registers - // - reg [31:0] bram_reg_b; - - assign b_out = bram_reg_b; - - - // - // Read-Only Port B - // - always @(posedge clk) - // - case (b_addr) - 3'b000: bram_reg_b <= 32'h00000000; - 3'b001: bram_reg_b <= 32'h00000000; - 3'b010: bram_reg_b <= 32'h80000000; - 3'b011: bram_reg_b <= 32'h00000000; - 3'b100: bram_reg_b <= 32'h00000000; - 3'b101: bram_reg_b <= 32'h80000000; - 3'b110: bram_reg_b <= 32'h80000000; - 3'b111: bram_reg_b <= 32'h7fffffff; - endcase - - -endmodule diff --git a/rtl/curve/rom/brom_p256_g_x.v b/rtl/curve/rom/brom_p256_g_x.v deleted file mode 100644 index 86aeafd..0000000 --- a/rtl/curve/rom/brom_p256_g_x.v +++ /dev/null @@ -1,68 +0,0 @@ -//====================================================================== -// -// Copyright (c) 2016, 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. -// -//====================================================================== - -`timescale 1ns / 1ps - -module brom_p256_g_x - ( - input wire clk, - input wire [ 3-1:0] b_addr, - output wire [32-1:0] b_out - ); - - - // - // Output Registers - // - reg [31:0] bram_reg_b; - - assign b_out = bram_reg_b; - - - // - // Read-Only Port B - // - always @(posedge clk) - // - case (b_addr) - 3'b000: bram_reg_b <= 32'hd898c296; - 3'b001: bram_reg_b <= 32'hf4a13945; - 3'b010: bram_reg_b <= 32'h2deb33a0; - 3'b011: bram_reg_b <= 32'h77037d81; - 3'b100: bram_reg_b <= 32'h63a440f2; - 3'b101: bram_reg_b <= 32'hf8bce6e5; - 3'b110: bram_reg_b <= 32'he12c4247; - 3'b111: bram_reg_b <= 32'h6b17d1f2; - endcase - - -endmodule diff --git a/rtl/curve/rom/brom_p256_g_y.v b/rtl/curve/rom/brom_p256_g_y.v deleted file mode 100644 index 39f9116..0000000 --- a/rtl/curve/rom/brom_p256_g_y.v +++ /dev/null @@ -1,68 +0,0 @@ -//====================================================================== -// -// Copyright (c) 2016, 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. -// -//====================================================================== - -`timescale 1ns / 1ps - -module brom_p256_g_y - ( - input wire clk, - input wire [ 3-1:0] b_addr, - output wire [32-1:0] b_out - ); - - - // - // Output Registers - // - reg [31:0] bram_reg_b; - - assign b_out = bram_reg_b; - - - // - // Read-Only Port B - // - always @(posedge clk) - // - case (b_addr) - 3'b000: bram_reg_b <= 32'h37bf51f5; - 3'b001: bram_reg_b <= 32'hcbb64068; - 3'b010: bram_reg_b <= 32'h6b315ece; - 3'b011: bram_reg_b <= 32'h2bce3357; - 3'b100: bram_reg_b <= 32'h7c0f9e16; - 3'b101: bram_reg_b <= 32'h8ee7eb4a; - 3'b110: bram_reg_b <= 32'hfe1a7f9b; - 3'b111: bram_reg_b <= 32'h4fe342e2; - endcase - - -endmodule diff --git a/rtl/curve/rom/brom_p256_h_x.v b/rtl/curve/rom/brom_p256_h_x.v deleted file mode 100644 index f426475..0000000 --- a/rtl/curve/rom/brom_p256_h_x.v +++ /dev/null @@ -1,68 +0,0 @@ -//====================================================================== -// -// Copyright (c) 2016, 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. -// -//====================================================================== - -`timescale 1ns / 1ps - -module brom_p256_h_x - ( - input wire clk, - input wire [ 3-1:0] b_addr, - output wire [32-1:0] b_out - ); - - - // - // Output Registers - // - reg [31:0] bram_reg_b; - - assign b_out = bram_reg_b; - - - // - // Read-Only Port B - // - always @(posedge clk) - // - case (b_addr) - 3'b000: bram_reg_b <= 32'h47669978; - 3'b001: bram_reg_b <= 32'ha60b48fc; - 3'b010: bram_reg_b <= 32'h77f21b35; - 3'b011: bram_reg_b <= 32'hc08969e2; - 3'b100: bram_reg_b <= 32'h04b51ac3; - 3'b101: bram_reg_b <= 32'h8a523803; - 3'b110: bram_reg_b <= 32'h8d034f7e; - 3'b111: bram_reg_b <= 32'h7cf27b18; - endcase - - -endmodule diff --git a/rtl/curve/rom/brom_p256_h_y.v b/rtl/curve/rom/brom_p256_h_y.v deleted file mode 100644 index c75d0da..0000000 --- a/rtl/curve/rom/brom_p256_h_y.v +++ /dev/null @@ -1,68 +0,0 @@ -//====================================================================== -// -// Copyright (c) 2016, 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. -// -//====================================================================== - -`timescale 1ns / 1ps - -module brom_p256_h_y - ( - input wire clk, - input wire [ 3-1:0] b_addr, - output wire [32-1:0] b_out - ); - - - // - // Output Registers - // - reg [31:0] bram_reg_b; - - assign b_out = bram_reg_b; - - - // - // Read-Only Port B - // - always @(posedge clk) - // - case (b_addr) - 3'b000: bram_reg_b <= 32'h227873d1; - 3'b001: bram_reg_b <= 32'h9e04b79d; - 3'b010: bram_reg_b <= 32'h3ce98229; - 3'b011: bram_reg_b <= 32'hba7dade6; - 3'b100: bram_reg_b <= 32'h9f7430db; - 3'b101: bram_reg_b <= 32'h293d9ac6; - 3'b110: bram_reg_b <= 32'hdb8ed040; - 3'b111: bram_reg_b <= 32'h07775510; - endcase - - -endmodule diff --git a/rtl/curve/rom/brom_p256_one.v b/rtl/curve/rom/brom_p256_one.v deleted file mode 100644 index 15e3746..0000000 --- a/rtl/curve/rom/brom_p256_one.v +++ /dev/null @@ -1,68 +0,0 @@ -//====================================================================== -// -// Copyright (c) 2016, 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. -// -//====================================================================== - -`timescale 1ns / 1ps - -module brom_p256_one - ( - input wire clk, - input wire [ 3-1:0] b_addr, - output wire [32-1:0] b_out - ); - - - // - // Output Registers - // - reg [31:0] bram_reg_b; - - assign b_out = bram_reg_b; - - - // - // Read-Only Port B - // - always @(posedge clk) - // - case (b_addr) - 3'b000: bram_reg_b <= 32'h00000001; - 3'b001: bram_reg_b <= 32'h00000000; - 3'b010: bram_reg_b <= 32'h00000000; - 3'b011: bram_reg_b <= 32'h00000000; - 3'b100: bram_reg_b <= 32'h00000000; - 3'b101: bram_reg_b <= 32'h00000000; - 3'b110: bram_reg_b <= 32'h00000000; - 3'b111: bram_reg_b <= 32'h00000000; - endcase - - -endmodule diff --git a/rtl/curve/rom/brom_p256_q.v b/rtl/curve/rom/brom_p256_q.v deleted file mode 100644 index 101a524..0000000 --- a/rtl/curve/rom/brom_p256_q.v +++ /dev/null @@ -1,68 +0,0 @@ -//====================================================================== -// -// Copyright (c) 2016, 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. -// -//====================================================================== - -`timescale 1ns / 1ps - -module brom_p256_q - ( - input wire clk, - input wire [ 3-1:0] b_addr, - output wire [32-1:0] b_out - ); - - - // - // Output Registers - // - reg [31:0] bram_reg_b; - - assign b_out = bram_reg_b; - - - // - // Read-Only Port B - // - always @(posedge clk) - // - case (b_addr) - 3'b000: bram_reg_b <= 32'hffffffff; - 3'b001: bram_reg_b <= 32'hffffffff; - 3'b010: bram_reg_b <= 32'hffffffff; - 3'b011: bram_reg_b <= 32'h00000000; - 3'b100: bram_reg_b <= 32'h00000000; - 3'b101: bram_reg_b <= 32'h00000000; - 3'b110: bram_reg_b <= 32'h00000001; - 3'b111: bram_reg_b <= 32'hffffffff; - endcase - - -endmodule diff --git a/rtl/curve/rom/brom_p256_zero.v b/rtl/curve/rom/brom_p256_zero.v deleted file mode 100644 index 2672cf2..0000000 --- a/rtl/curve/rom/brom_p256_zero.v +++ /dev/null @@ -1,70 +0,0 @@ -//====================================================================== -// -// Copyright (c) 2016, 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. -// -//====================================================================== - -`timescale 1ns / 1ps - -module brom_p256_zero - ( - //input wire clk, - //input wire [ 3-1:0] b_addr, - output wire [32-1:0] b_out - ); - - - assign b_out = {32{1'b0}}; - - // - // Output Registers - // - //reg [31:0] bram_reg_b; - - //assign b_out = bram_reg_b; - - - // - // Read-Only Port B - // - //always @(posedge clk) - // - //case (b_addr) - //3'b000: bram_reg_b <= 32'h00000000; - //3'b001: bram_reg_b <= 32'h00000000; - //3'b010: bram_reg_b <= 32'h00000000; - //3'b011: bram_reg_b <= 32'h00000000; - //3'b100: bram_reg_b <= 32'h00000000; - //3'b101: bram_reg_b <= 32'h00000000; - //3'b110: bram_reg_b <= 32'h00000000; - //3'b111: bram_reg_b <= 32'h00000000; - //endcase - - -endmodule diff --git a/rtl/ecdsa256.v b/rtl/ecdsa256.v deleted file mode 100644 index 11276a2..0000000 --- a/rtl/ecdsa256.v +++ /dev/null @@ -1,160 +0,0 @@ -//====================================================================== -// -// Copyright (c) 2016, 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. -// -//====================================================================== - -`timescale 1ns / 1ps - -module ecdsa256 - ( - input wire clk, - input wire rst_n, - - input wire next, - output wire valid, - - input wire bus_cs, - input wire bus_we, - input wire [ 4:0] bus_addr, - input wire [31:0] bus_data_wr, - output wire [31:0] bus_data_rd - ); - - - // - // Memory Banks - // - localparam [1:0] BUS_ADDR_BANK_K = 2'b00; - localparam [1:0] BUS_ADDR_BANK_X = 2'b01; - localparam [1:0] BUS_ADDR_BANK_Y = 2'b10; - - wire [1:0] bus_addr_upper = bus_addr[4:3]; - wire [2:0] bus_addr_lower = bus_addr[2:0]; - - - // - // Memories - // - - wire [31:0] user_rw_k_bram_out; - wire [31:0] user_ro_x_bram_out; - wire [31:0] user_ro_y_bram_out; - - wire [ 2:0] core_ro_k_bram_addr; - wire [ 2:0] core_rw_x_bram_addr; - wire [ 2:0] core_rw_y_bram_addr; - - wire core_rw_x_bram_wren; - wire core_rw_y_bram_wren; - - wire [31:0] core_ro_k_bram_dout; - wire [31:0] core_rw_x_bram_din; - wire [31:0] core_rw_y_bram_din; - - - bram_1rw_1ro_readfirst # - ( .MEM_WIDTH(32), .MEM_ADDR_BITS(3) - ) - bram_k - ( .clk(clk), - .a_addr(bus_addr_lower), .a_out(user_rw_k_bram_out), .a_wr(bus_cs && bus_we && (bus_addr_upper == BUS_ADDR_BANK_K)), .a_in(bus_data_wr), - .b_addr(core_ro_k_bram_addr), .b_out(core_ro_k_bram_dout) - ); - - bram_1rw_1ro_readfirst # - ( .MEM_WIDTH(32), .MEM_ADDR_BITS(3) - ) - bram_x - ( .clk(clk), - .a_addr(core_rw_x_bram_addr), .a_out(), .a_wr(core_rw_x_bram_wren), .a_in(core_rw_x_bram_din), - .b_addr(bus_addr_lower), .b_out(user_ro_x_bram_out) - ); - - bram_1rw_1ro_readfirst # - ( .MEM_WIDTH(32), .MEM_ADDR_BITS(3) - ) - bram_y - ( .clk(clk), - .a_addr(core_rw_y_bram_addr), .a_out(), .a_wr(core_rw_y_bram_wren), .a_in(core_rw_y_bram_din), - .b_addr(bus_addr_lower), .b_out(user_ro_y_bram_out) - ); - - - // - // Curve Base Point Multiplier - // - reg next_dly; - - always @(posedge clk) next_dly <= next; - - wire next_trig = next && !next_dly; - - curve_mul_256 base_point_multiplier_p256 - ( - .clk (clk), - .rst_n (rst_n), - - .ena (next_trig), - .rdy (valid), - - .k_addr (core_ro_k_bram_addr), - .rx_addr (core_rw_x_bram_addr), - .ry_addr (core_rw_y_bram_addr), - - .rx_wren (core_rw_x_bram_wren), - .ry_wren (core_rw_y_bram_wren), - - .k_din (core_ro_k_bram_dout), - .rx_dout (core_rw_x_bram_din), - .ry_dout (core_rw_y_bram_din) - ); - - // - // Output Selector - // - reg [1:0] bus_addr_upper_prev; - always @(posedge clk) bus_addr_upper_prev = bus_addr_upper; - - reg [31: 0] bus_data_rd_mux; - assign bus_data_rd = bus_data_rd_mux; - - always @(*) - // - case (bus_addr_upper_prev) - // - BUS_ADDR_BANK_K: bus_data_rd_mux = user_rw_k_bram_out; - BUS_ADDR_BANK_X: bus_data_rd_mux = user_ro_x_bram_out; - BUS_ADDR_BANK_Y: bus_data_rd_mux = user_ro_y_bram_out; - // - default: bus_data_rd_mux = {32{1'b0}}; - // - endcase - -endmodule diff --git a/rtl/ecdsa256_banks_array.v b/rtl/ecdsa256_banks_array.v new file mode 100644 index 0000000..1172429 --- /dev/null +++ b/rtl/ecdsa256_banks_array.v @@ -0,0 +1,119 @@ +//------------------------------------------------------------------------------ +// +// ecdsa256_banks_array.v +// ----------------------------------------------------------------------------- +// ECDSA Operand Banks Array +// +// Authors: Pavel Shatov +// +// Copyright (c) 2018, NORDUnet A/S +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// - Neither the name of the NORDUnet nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +//------------------------------------------------------------------------------ + +module ecdsa256_banks_array +( + input clk, + + input banks, // 0: LO -> HI, 1: HI -> LO + + input [ 5:0] src1_operand, + input [ 5:0] src2_operand, + input [ 5:0] dst_operand, + + input [ 2:0] src1_addr, + input [ 2:0] src2_addr, + input [ 2:0] dst_addr, + + input dst_wren, + + output [31:0] src1_dout, + output [31:0] src2_dout, + + input [31:0] dst_din +); + + + // + // Banks + // + wire [31:0] bank_lo1_dout; + wire [31:0] bank_lo2_dout; + wire [31:0] bank_hi1_dout; + wire [31:0] bank_hi2_dout; + + assign src1_dout = !banks ? bank_lo1_dout : bank_hi1_dout; + assign src2_dout = !banks ? bank_lo2_dout : bank_hi2_dout; + + ecdsa256_operand_bank bank_operand_lo1 + ( + .clk (clk), + .a_addr ({dst_operand, dst_addr}), + .a_wr (dst_wren & banks), + .a_in (dst_din), + .b_addr ({src1_operand, src1_addr}), + .b_out (bank_lo1_dout) + ); + + ecdsa256_operand_bank bank_operand_lo2 + ( + .clk (clk), + .a_addr ({dst_operand, dst_addr}), + .a_wr (dst_wren & banks), + .a_in (dst_din), + .b_addr ({src2_operand, src2_addr}), + .b_out (bank_lo2_dout) + ); + + ecdsa256_operand_bank bank_operand_hi1 + ( + .clk (clk), + .a_addr ({dst_operand, dst_addr}), + .a_wr (dst_wren & ~banks), + .a_in (dst_din), + .b_addr ({src1_operand, src1_addr}), + .b_out (bank_hi1_dout) + ); + + ecdsa256_operand_bank bank_operand_hi2 + ( + .clk (clk), + .a_addr ({dst_operand, dst_addr}), + .a_wr (dst_wren & ~banks), + .a_in (dst_din), + .b_addr ({src2_operand, src2_addr}), + .b_out (bank_hi2_dout) + ); + + +endmodule + + +//------------------------------------------------------------------------------ +// End-of-File +//------------------------------------------------------------------------------ diff --git a/rtl/ecdsa256_base_point_multiplier.v b/rtl/ecdsa256_base_point_multiplier.v new file mode 100644 index 0000000..8664d0c --- /dev/null +++ b/rtl/ecdsa256_base_point_multiplier.v @@ -0,0 +1,310 @@ +//------------------------------------------------------------------------------ +// +// ecdsa256_base_point_multiplier.v +// ----------------------------------------------------------------------------- +// ECDSA base point scalar multiplier. +// +// Authors: Pavel Shatov +// +// Copyright (c) 2016, 2018 NORDUnet A/S +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// - Neither the name of the NORDUnet nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +//------------------------------------------------------------------------------ + +module ecdsa256_base_point_multiplier +( + clk, rst_n, + ena, rdy, + k_addr, rxy_addr, + rx_wren, ry_wren, + k_din, + rxy_dout +); + + + // + // Microcode Header + // +`include "ecdsa_uop.vh" + + + // + // Ports + // + input clk; // system clock + input rst_n; // active-low async reset + + input ena; // enable input + output rdy; // ready output + + output [ 2:0] k_addr; // + output [ 2:0] rxy_addr; // + output rx_wren; // + output ry_wren; // + input [31:0] k_din; // + output [31:0] rxy_dout; // + + + // + // FSM + // + localparam [4:0] FSM_STATE_IDLE = 5'd00; + localparam [4:0] FSM_STATE_PREPARE_TRIG = 5'd01; + localparam [4:0] FSM_STATE_PREPARE_WAIT = 5'd02; + localparam [4:0] FSM_STATE_CYCLE_DBL_TRIG = 5'd03; + localparam [4:0] FSM_STATE_CYCLE_DBL_WAIT = 5'd04; + localparam [4:0] FSM_STATE_CYCLE_ADD_TRIG = 5'd05; + localparam [4:0] FSM_STATE_CYCLE_ADD_WAIT = 5'd06; + localparam [4:0] FSM_STATE_CYCLE_ADD_EXTRA_TRIG = 5'd07; + localparam [4:0] FSM_STATE_CYCLE_ADD_EXTRA_WAIT = 5'd08; + localparam [4:0] FSM_STATE_AFTER_CYCLE_TRIG = 5'd09; + localparam [4:0] FSM_STATE_AFTER_CYCLE_WAIT = 5'd10; + localparam [4:0] FSM_STATE_INVERT_TRIG = 5'd11; + localparam [4:0] FSM_STATE_INVERT_WAIT = 5'd12; + localparam [4:0] FSM_STATE_CONVERT_TRIG = 5'd13; + localparam [4:0] FSM_STATE_CONVERT_WAIT = 5'd14; + localparam [4:0] FSM_STATE_CONVERT_EXTRA_TRIG = 5'd15; + localparam [4:0] FSM_STATE_CONVERT_EXTRA_WAIT = 5'd16; + localparam [4:0] FSM_STATE_DONE = 5'd17; + + reg [4:0] fsm_state = FSM_STATE_IDLE; + reg [4:0] fsm_state_next; + + + // + // Round Counter + // + reg [7:0] bit_counter; + wire [7:0] bit_counter_last = 8'hFF; // 255 + wire [7:0] bit_counter_zero = 8'h00; // 0 + wire [7:0] bit_counter_prev = + (bit_counter > bit_counter_zero) ? bit_counter - 1'b1 : bit_counter_last; + + assign k_addr = bit_counter[7:5]; + + + // + // Worker Trigger Logic + // + reg worker_trig = 1'b0; + wire worker_done; + + wire fsm_wait_done = !worker_trig && worker_done; + + always @(posedge clk or negedge rst_n) + // + if (rst_n == 1'b0) worker_trig <= 1'b0; + else case (fsm_state) + FSM_STATE_PREPARE_TRIG, + FSM_STATE_CYCLE_DBL_TRIG, + FSM_STATE_CYCLE_ADD_TRIG, + FSM_STATE_CYCLE_ADD_EXTRA_TRIG, + FSM_STATE_AFTER_CYCLE_TRIG, + FSM_STATE_INVERT_TRIG, + FSM_STATE_CONVERT_TRIG, + FSM_STATE_CONVERT_EXTRA_TRIG: worker_trig <= 1'b1; + default: worker_trig <= 1'b0; + endcase + + + // + // Round Counter Increment Logic + // + always @(posedge clk) + // + case (fsm_state_next) + FSM_STATE_PREPARE_TRIG: bit_counter <= bit_counter_last; + FSM_STATE_AFTER_CYCLE_TRIG: bit_counter <= bit_counter_prev; + endcase + + + // + // Final Cycle Detection Logic + // + wire [ 3: 0] fsm_state_after_cycle = (bit_counter == bit_counter_last) ? + FSM_STATE_INVERT_TRIG : FSM_STATE_CYCLE_DBL_TRIG; + + + // + // K Latch + // + reg [31:0] k_din_shreg; + + wire [4:0] k_bit_index = bit_counter[4:0]; + + always @(posedge clk) + // + if (fsm_state_next == FSM_STATE_CYCLE_DBL_TRIG) + // + if (k_bit_index == 5'd31) k_din_shreg <= k_din; + else k_din_shreg <= {k_din_shreg[30:0], ~k_din_shreg[31]}; + + + // + // Worker Flags + // + wire worker_flagz_sz; + wire worker_flagz_rz; + wire worker_flagz_e; + wire worker_flagz_f; + + wire [2:0] worker_flagz_cycle_add = + {worker_flagz_sz, worker_flagz_e, worker_flagz_f}; + + wire worker_flagz_convert_extra = + worker_flagz_rz; + + + // + // Worker Offset Logic + // + reg [UOP_ADDR_WIDTH-1:0] worker_offset; + + always @(posedge clk) + // + case (fsm_state) + + FSM_STATE_PREPARE_TRIG: worker_offset <= UOP_OFFSET_PREPARE; + + FSM_STATE_CYCLE_DBL_TRIG: worker_offset <= UOP_OFFSET_CYCLE_DOUBLE; + FSM_STATE_CYCLE_ADD_TRIG: worker_offset <= UOP_OFFSET_CYCLE_ADD; + + FSM_STATE_CYCLE_ADD_EXTRA_TRIG: + // {sz, e, f} + casez(worker_flagz_cycle_add) + 3'b1??: worker_offset <= UOP_OFFSET_CYCLE_ADD_AT_INFINITY; + 3'b011: worker_offset <= UOP_OFFSET_CYCLE_ADD_SAME_X_SAME_Y; + 3'b010: worker_offset <= UOP_OFFSET_CYCLE_ADD_SAME_X; + 3'b00?: worker_offset <= UOP_OFFSET_CYCLE_ADD_REGULAR; + endcase + + FSM_STATE_AFTER_CYCLE_TRIG: worker_offset <= k_din_shreg[31] ? + UOP_OFFSET_CYCLE_K1 : UOP_OFFSET_CYCLE_K0; + + FSM_STATE_INVERT_TRIG: worker_offset <= UOP_OFFSET_INVERT; + FSM_STATE_CONVERT_TRIG: worker_offset <= UOP_OFFSET_CONVERT; + + FSM_STATE_CONVERT_EXTRA_TRIG: worker_offset <= worker_flagz_convert_extra ? + UOP_OFFSET_CONVERT_AT_INFINITY : UOP_OFFSET_CONVERT_REGULAR; + + default: worker_offset <= {UOP_ADDR_WIDTH{1'bX}}; + + endcase + + + // + // FSM Process + // + always @(posedge clk or negedge rst_n) + // + if (rst_n == 1'b0) fsm_state <= FSM_STATE_IDLE; + else fsm_state <= fsm_state_next; + + + // + // FSM Transition Logic + // + always @* begin + // + fsm_state_next = FSM_STATE_IDLE; + // + case (fsm_state) + + FSM_STATE_IDLE: fsm_state_next = ena ? FSM_STATE_PREPARE_TRIG : FSM_STATE_IDLE; + + FSM_STATE_PREPARE_TRIG: fsm_state_next = FSM_STATE_PREPARE_WAIT ; + FSM_STATE_PREPARE_WAIT: fsm_state_next = fsm_wait_done ? FSM_STATE_CYCLE_DBL_TRIG : FSM_STATE_PREPARE_WAIT; + FSM_STATE_CYCLE_DBL_TRIG: fsm_state_next = FSM_STATE_CYCLE_DBL_WAIT ; + FSM_STATE_CYCLE_DBL_WAIT: fsm_state_next = fsm_wait_done ? FSM_STATE_CYCLE_ADD_TRIG : FSM_STATE_CYCLE_DBL_WAIT; + FSM_STATE_CYCLE_ADD_TRIG: fsm_state_next = FSM_STATE_CYCLE_ADD_WAIT ; + FSM_STATE_CYCLE_ADD_WAIT: fsm_state_next = fsm_wait_done ? FSM_STATE_CYCLE_ADD_EXTRA_TRIG : FSM_STATE_CYCLE_ADD_WAIT; + FSM_STATE_CYCLE_ADD_EXTRA_TRIG: fsm_state_next = FSM_STATE_CYCLE_ADD_EXTRA_WAIT ; + FSM_STATE_CYCLE_ADD_EXTRA_WAIT: fsm_state_next = fsm_wait_done ? FSM_STATE_AFTER_CYCLE_TRIG : FSM_STATE_CYCLE_ADD_EXTRA_WAIT; + FSM_STATE_AFTER_CYCLE_TRIG: fsm_state_next = FSM_STATE_AFTER_CYCLE_WAIT ; + FSM_STATE_AFTER_CYCLE_WAIT: fsm_state_next = fsm_wait_done ? fsm_state_after_cycle : FSM_STATE_AFTER_CYCLE_WAIT; + FSM_STATE_INVERT_TRIG: fsm_state_next = FSM_STATE_INVERT_WAIT ; + FSM_STATE_INVERT_WAIT: fsm_state_next = fsm_wait_done ? FSM_STATE_CONVERT_TRIG : FSM_STATE_INVERT_WAIT; + FSM_STATE_CONVERT_TRIG: fsm_state_next = FSM_STATE_CONVERT_WAIT ; + FSM_STATE_CONVERT_WAIT: fsm_state_next = fsm_wait_done ? FSM_STATE_CONVERT_EXTRA_TRIG : FSM_STATE_CONVERT_WAIT; + FSM_STATE_CONVERT_EXTRA_TRIG: fsm_state_next = FSM_STATE_CONVERT_EXTRA_WAIT ; + FSM_STATE_CONVERT_EXTRA_WAIT: fsm_state_next = fsm_wait_done ? FSM_STATE_DONE : FSM_STATE_CONVERT_EXTRA_WAIT; + FSM_STATE_DONE: fsm_state_next = FSM_STATE_IDLE ; + + endcase + // + end + + + // + // Worker + // + wire worker_output_now = (fsm_state == FSM_STATE_CONVERT_EXTRA_WAIT); + + ecdsa256_uop_worker uop_worker + ( + .clk (clk), + .rst_n (rst_n), + + .ena (worker_trig), + .rdy (worker_done), + .uop_offset (worker_offset), + .output_now (worker_output_now), + + .flagz_sz (worker_flagz_sz), + .flagz_rz (worker_flagz_rz), + .flagz_e (worker_flagz_e), + .flagz_f (worker_flagz_f), + + .xy_addr (rxy_addr), + .xy_dout (rxy_dout), + .x_wren (rx_wren), + .y_wren (ry_wren) + ); + + + // + // Ready Flag Logic + // + reg rdy_reg = 1'b1; + assign rdy = rdy_reg; + + always @(posedge clk or negedge rst_n) + // + if (rst_n == 1'b0) rdy_reg <= 1'b1; + else case (fsm_state) + FSM_STATE_IDLE: if (ena) rdy_reg <= 1'b0; + FSM_STATE_DONE: rdy_reg <= 1'b1; + endcase + + +endmodule + + +//------------------------------------------------------------------------------ +// End-of-File +//------------------------------------------------------------------------------ diff --git a/rtl/ecdsa256_core_top.v b/rtl/ecdsa256_core_top.v new file mode 100644 index 0000000..3ce4174 --- /dev/null +++ b/rtl/ecdsa256_core_top.v @@ -0,0 +1,150 @@ +//====================================================================== +// +// Copyright (c) 2016, 2018 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 ecdsa256_core_top +( + input wire clk, + input wire rst_n, + + input wire next, + output wire valid, + + input wire bus_cs, + input wire bus_we, + input wire [ 4:0] bus_addr, + input wire [31:0] bus_data_wr, + output wire [31:0] bus_data_rd +); + + + // + // Memory Banks + // + localparam [1:0] BUS_ADDR_BANK_K = 2'b00; + localparam [1:0] BUS_ADDR_BANK_X = 2'b01; + localparam [1:0] BUS_ADDR_BANK_Y = 2'b10; + + wire [1:0] bus_addr_upper = bus_addr[4:3]; + wire [2:0] bus_addr_lower = bus_addr[2:0]; + + + // + // Memories + // + + wire [31:0] user_rw_k_bram_out; + wire [31:0] user_ro_x_bram_out; + wire [31:0] user_ro_y_bram_out; + + wire [ 2:0] core_ro_k_bram_addr; + wire [ 2:0] core_rw_xy_bram_addr; + + wire core_rw_x_bram_wren; + wire core_rw_y_bram_wren; + + wire [31:0] core_ro_k_bram_dout; + wire [31:0] core_rw_xy_bram_din; + + bram_1rw_1ro_readfirst # + (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) + bram_k + ( .clk(clk), + .a_addr(bus_addr_lower), .a_out(user_rw_k_bram_out), .a_wr(bus_cs && bus_we && (bus_addr_upper == BUS_ADDR_BANK_K)), .a_in(bus_data_wr), + .b_addr(core_ro_k_bram_addr), .b_out(core_ro_k_bram_dout) + ); + + bram_1rw_1ro_readfirst # + (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) + bram_x + ( .clk(clk), + .a_addr(core_rw_xy_bram_addr), .a_out(), .a_wr(core_rw_x_bram_wren), .a_in(core_rw_xy_bram_din), + .b_addr(bus_addr_lower), .b_out(user_ro_x_bram_out) + ); + + bram_1rw_1ro_readfirst # + (.MEM_WIDTH(32), .MEM_ADDR_BITS(3)) + bram_y + ( .clk(clk), + .a_addr(core_rw_xy_bram_addr), .a_out(), .a_wr(core_rw_y_bram_wren), .a_in(core_rw_xy_bram_din), + .b_addr(bus_addr_lower), .b_out(user_ro_y_bram_out) + ); + + + // + // Curve Base Point Multiplier + // + reg next_dly; + + always @(posedge clk) next_dly <= next; + + wire next_trig = next && !next_dly; + + ecdsa256_base_point_multiplier base_point_multiplier_p256 + ( + .clk (clk), + .rst_n (rst_n), + + .ena (next_trig), + .rdy (valid), + + .k_addr (core_ro_k_bram_addr), + .rxy_addr (core_rw_xy_bram_addr), + + .rx_wren (core_rw_x_bram_wren), + .ry_wren (core_rw_y_bram_wren), + + .k_din (core_ro_k_bram_dout), + .rxy_dout (core_rw_xy_bram_din) + ); + + // + // Output Selector + // + reg [1:0] bus_addr_upper_prev; + always @(posedge clk) bus_addr_upper_prev = bus_addr_upper; + + reg [31:0] bus_data_rd_mux; + assign bus_data_rd = bus_data_rd_mux; + + always @(*) + // + case (bus_addr_upper_prev) + // + BUS_ADDR_BANK_K: bus_data_rd_mux = user_rw_k_bram_out; + BUS_ADDR_BANK_X: bus_data_rd_mux = user_ro_x_bram_out; + BUS_ADDR_BANK_Y: bus_data_rd_mux = user_ro_y_bram_out; + // + default: bus_data_rd_mux = {32{1'b0}}; + // + endcase + +endmodule diff --git a/rtl/ecdsa256_microcode_rom.v b/rtl/ecdsa256_microcode_rom.v new file mode 100644 index 0000000..82321cb --- /dev/null +++ b/rtl/ecdsa256_microcode_rom.v @@ -0,0 +1,424 @@ +//====================================================================== +// +// Copyright (c) 2018, 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 ecdsa256_microcode_rom +( + input wire clk, + input wire [UOP_ADDR_WIDTH-1:0] addr, + output reg [UOP_DATA_WIDTH-1:0] data +); + +`include "ecdsa_uop.vh" + + always @(posedge clk) + // + case (addr) + + // PREPARE + 9'd000: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RX}; + 9'd001: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY}; + 9'd002: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RZ}; + 9'd003: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + // CYCLE_DOUBLE + 9'd004: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_CYCLE_Z2}; + 9'd005: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_RX, UOP_OPERAND_CYCLE_Z2, UOP_OPERAND_CYCLE_T1}; + 9'd006: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_RX, UOP_OPERAND_CYCLE_Z2, UOP_OPERAND_CYCLE_T2}; + 9'd007: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_T1, UOP_OPERAND_CYCLE_T2, UOP_OPERAND_CYCLE_T3}; + 9'd008: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T3, UOP_OPERAND_CYCLE_T3, UOP_OPERAND_CYCLE_T4}; + 9'd009: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_T4, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_T4}; + 9'd010: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T3, UOP_OPERAND_CYCLE_T4, UOP_OPERAND_CYCLE_A}; + 9'd011: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_RY, UOP_OPERAND_CYCLE_RY, UOP_OPERAND_CYCLE_B}; + 9'd012: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_B, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_CYCLE_SZ}; + 9'd013: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_B, UOP_OPERAND_CYCLE_B, UOP_OPERAND_CYCLE_C}; + 9'd014: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_C, UOP_OPERAND_CYCLE_RX, UOP_OPERAND_CYCLE_D}; + 9'd015: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_C, UOP_OPERAND_CYCLE_C, UOP_OPERAND_CYCLE_C2}; + 9'd016: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_C2, UOP_OPERAND_CONST_DELTA, UOP_OPERAND_CYCLE_C2_2}; + 9'd017: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_A, UOP_OPERAND_CYCLE_A, UOP_OPERAND_CYCLE_A2}; + 9'd018: data <= {UOP_OPCODE_ADD, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_D, UOP_OPERAND_CYCLE_D, UOP_OPERAND_CYCLE_T1}; + 9'd019: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_A2, UOP_OPERAND_CYCLE_T1, UOP_OPERAND_CYCLE_SX}; + 9'd020: data <= {UOP_OPCODE_SUB, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_D, UOP_OPERAND_CYCLE_SX, UOP_OPERAND_CYCLE_T1}; + 9'd021: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T1, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_T1}; + 9'd022: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_A, UOP_OPERAND_CYCLE_T1, UOP_OPERAND_CYCLE_T2}; + 9'd023: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T2, UOP_OPERAND_CYCLE_C2_2, UOP_OPERAND_CYCLE_SY}; + 9'd024: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + // CYCLE_ADD + 9'd025: data <= {UOP_OPCODE_CMPZ, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_SZ, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + 9'd026: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_SZ, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_SZ}; + 9'd027: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_SZ, UOP_OPERAND_CYCLE_SZ, UOP_OPERAND_CYCLE_A}; + 9'd028: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_A, UOP_OPERAND_CYCLE_SZ, UOP_OPERAND_CYCLE_B}; + 9'd029: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_B, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_B}; + 9'd030: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_A, UOP_OPERAND_CONST_GX, UOP_OPERAND_CYCLE_C}; + 9'd031: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_B, UOP_OPERAND_CONST_GY, UOP_OPERAND_CYCLE_D}; + 9'd032: data <= {UOP_OPCODE_SUB, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_C, UOP_OPERAND_CYCLE_SX, UOP_OPERAND_CYCLE_E}; + 9'd033: data <= {UOP_OPCODE_SUB, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_D, UOP_OPERAND_CYCLE_SY, UOP_OPERAND_CYCLE_F}; + 9'd034: data <= {UOP_OPCODE_CMPZ, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_E, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + 9'd035: data <= {UOP_OPCODE_CMPZ, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_F, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + 9'd036: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_E, UOP_OPERAND_CYCLE_SZ, UOP_OPERAND_CYCLE_RZ}; + 9'd037: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_E, UOP_OPERAND_CYCLE_E, UOP_OPERAND_CYCLE_G}; + 9'd038: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_G, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_G}; + 9'd039: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_E, UOP_OPERAND_CYCLE_G, UOP_OPERAND_CYCLE_H}; + 9'd040: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_G, UOP_OPERAND_CYCLE_SX, UOP_OPERAND_CYCLE_J}; + 9'd041: data <= {UOP_OPCODE_ADD, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_J, UOP_OPERAND_CYCLE_J, UOP_OPERAND_CYCLE_T1}; + 9'd042: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_F, UOP_OPERAND_CYCLE_F, UOP_OPERAND_CYCLE_T2}; + 9'd043: data <= {UOP_OPCODE_SUB, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_T2, UOP_OPERAND_CYCLE_T1, UOP_OPERAND_CYCLE_T3}; + 9'd044: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T3, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_T3}; + 9'd045: data <= {UOP_OPCODE_SUB, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_T3, UOP_OPERAND_CYCLE_H, UOP_OPERAND_CYCLE_RX}; + 9'd046: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_J, UOP_OPERAND_CYCLE_RX, UOP_OPERAND_CYCLE_T1}; + 9'd047: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_F, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_F}; + 9'd048: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_F, UOP_OPERAND_CYCLE_T1, UOP_OPERAND_CYCLE_T2}; + 9'd049: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_H, UOP_OPERAND_CYCLE_SY, UOP_OPERAND_CYCLE_T3}; + 9'd050: data <= {UOP_OPCODE_SUB, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_T2, UOP_OPERAND_CYCLE_T3, UOP_OPERAND_CYCLE_RY}; + 9'd051: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_RY, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY}; + 9'd052: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + // CYCLE_ADD_AT_INFINITY + 9'd053: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_GX, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RX}; + 9'd054: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_GY, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY}; + 9'd055: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RZ}; + 9'd056: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + // CYCLE_ADD_SAME_X_SAME_Y + 9'd057: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_HX, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RX}; + 9'd058: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_HY, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY}; + 9'd059: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RZ}; + 9'd060: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + // CYCLE_ADD_SAME_X + 9'd061: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RX}; + 9'd062: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY}; + 9'd063: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RZ}; + 9'd064: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + // CYCLE_ADD_REGULAR + 9'd065: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_T1}; + 9'd066: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ONE, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_T2}; + 9'd067: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_T3}; + 9'd068: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + // CYCLE_K0 + 9'd069: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_SX, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RX}; + 9'd070: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_SY, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY}; + 9'd071: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_SZ, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RZ}; + 9'd072: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + // CYCLE_K1 + 9'd073: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_RX, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_SX}; + 9'd074: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_RY, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_SY}; + 9'd075: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_SZ}; + 9'd076: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + // CONVERT + 9'd077: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_A2, UOP_OPERAND_CYCLE_RX, UOP_OPERAND_CYCLE_SX}; + 9'd078: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_A3, UOP_OPERAND_CYCLE_RY, UOP_OPERAND_CYCLE_SY}; + 9'd079: data <= {UOP_OPCODE_CMPZ, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + 9'd080: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + // CONVERT_AT_INFINITY + 9'd081: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RX}; + 9'd082: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CONST_ZERO, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY}; + 9'd083: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + // CONVERT_REGULAR + 9'd084: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_SX, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RX}; + 9'd085: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_SY, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RY}; + 9'd086: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + // INVERT_P256 + 9'd087: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_DONTCARE, UOP_OPERAND_CYCLE_RZ}; + 9'd088: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_INVERT_R1}; + 9'd089: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_X2}; + 9'd090: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_X2, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_X2}; + 9'd091: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_X2, UOP_OPERAND_INVERT_X2, UOP_OPERAND_INVERT_R1}; + 9'd092: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_INVERT_X3}; + 9'd093: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_X3, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_X3}; + 9'd094: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_X3, UOP_OPERAND_INVERT_X3, UOP_OPERAND_INVERT_R1}; + 9'd095: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd096: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd097: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_X3, UOP_OPERAND_INVERT_X6}; + 9'd098: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_X6, UOP_OPERAND_INVERT_X6, UOP_OPERAND_INVERT_R1}; + 9'd099: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd100: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd101: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd102: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd103: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd104: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_X6, UOP_OPERAND_INVERT_X12}; + 9'd105: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_X12, UOP_OPERAND_INVERT_X12, UOP_OPERAND_INVERT_R1}; + 9'd106: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd107: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd108: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_X3, UOP_OPERAND_INVERT_X15}; + 9'd109: data <= {UOP_OPCODE_COPY, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_X15, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_X15}; + 9'd110: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_X15, UOP_OPERAND_INVERT_X15, UOP_OPERAND_INVERT_R1}; + 9'd111: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd112: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd113: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd114: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd115: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd116: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd117: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd118: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd119: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd120: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd121: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd122: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd123: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd124: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd125: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_X15, UOP_OPERAND_INVERT_X30}; + 9'd126: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_X30, UOP_OPERAND_INVERT_X30, UOP_OPERAND_INVERT_R1}; + 9'd127: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd128: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_X2, UOP_OPERAND_INVERT_X32}; + 9'd129: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_X32, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_X32}; + 9'd130: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_X32, UOP_OPERAND_INVERT_X32, UOP_OPERAND_INVERT_R1}; + 9'd131: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd132: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd133: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd134: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd135: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd136: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd137: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd138: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd139: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd140: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd141: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd142: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd143: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd144: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd145: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd146: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd147: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd148: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd149: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd150: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd151: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd152: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd153: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd154: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd155: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd156: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd157: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd158: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd159: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd160: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd161: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd162: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_INVERT_R1}; + 9'd163: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd164: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd165: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd166: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd167: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd168: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd169: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd170: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd171: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd172: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd173: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd174: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd175: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd176: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd177: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd178: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd179: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd180: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd181: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd182: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd183: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd184: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd185: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd186: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd187: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd188: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd189: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd190: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd191: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd192: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd193: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd194: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd195: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd196: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd197: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd198: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd199: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd200: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd201: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd202: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd203: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd204: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd205: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd206: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd207: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd208: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd209: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd210: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd211: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd212: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd213: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd214: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd215: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd216: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd217: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd218: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd219: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd220: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd221: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd222: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd223: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd224: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd225: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd226: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd227: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd228: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd229: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd230: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd231: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd232: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd233: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd234: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd235: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd236: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd237: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd238: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd239: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd240: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd241: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd242: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd243: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd244: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd245: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd246: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd247: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd248: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd249: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd250: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd251: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd252: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd253: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd254: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd255: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd256: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd257: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd258: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd259: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd260: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd261: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd262: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd263: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd264: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd265: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd266: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd267: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd268: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd269: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd270: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd271: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd272: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd273: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd274: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd275: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd276: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd277: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd278: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd279: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd280: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd281: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd282: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd283: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd284: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd285: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd286: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd287: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd288: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd289: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd290: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd291: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_X32, UOP_OPERAND_INVERT_R2}; + 9'd292: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd293: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd294: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd295: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd296: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd297: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd298: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd299: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd300: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd301: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd302: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd303: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd304: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd305: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd306: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd307: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd308: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd309: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd310: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd311: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd312: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd313: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd314: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd315: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd316: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd317: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd318: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd319: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd320: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd321: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd322: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd323: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd324: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_X32, UOP_OPERAND_INVERT_R1}; + 9'd325: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd326: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd327: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd328: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd329: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd330: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd331: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd332: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd333: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd334: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd335: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd336: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd337: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd338: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd339: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd340: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd341: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd342: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd343: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd344: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd345: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd346: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd347: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd348: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd349: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd350: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd351: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd352: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd353: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd354: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd355: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_X30, UOP_OPERAND_INVERT_R2}; + 9'd356: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R2, UOP_OPERAND_INVERT_R1}; + 9'd357: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R1, UOP_OPERAND_INVERT_R2}; + 9'd358: data <= {UOP_OPCODE_COPY, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R2, UOP_OPERAND_DONTCARE, UOP_OPERAND_INVERT_A2}; + 9'd359: data <= {UOP_OPCODE_MUL, UOP_BANKS_HI2LO, UOP_OPERAND_INVERT_A2, UOP_OPERAND_INVERT_A2, UOP_OPERAND_INVERT_R1}; + 9'd360: data <= {UOP_OPCODE_MUL, UOP_BANKS_LO2HI, UOP_OPERAND_INVERT_R1, UOP_OPERAND_CYCLE_RZ, UOP_OPERAND_INVERT_A3}; + 9'd361: data <= {UOP_OPCODE_STOP, UOP_BANKS_DUMMY, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE, UOP_OPERAND_DONTCARE}; + + endcase + +endmodule diff --git a/rtl/ecdsa256_operand_bank.v b/rtl/ecdsa256_operand_bank.v new file mode 100644 index 0000000..807927c --- /dev/null +++ b/rtl/ecdsa256_operand_bank.v @@ -0,0 +1,160 @@ +//====================================================================== +// +// Copyright (c) 2018, 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 ecdsa256_operand_bank +( + input clk, + + input [ 9-1:0] a_addr, + input a_wr, + input [32-1:0] a_in, + + input [ 9-1:0] b_addr, + output [32-1:0] b_out +); + + + // + // BRAM + // + reg [31:0] bram[0:64*8-1]; + + + // + // Initialization + // + initial begin + // + // CONST_ZERO + // + bram[ 0*8 + 7] = 32'h00000000; + bram[ 0*8 + 6] = 32'h00000000; + bram[ 0*8 + 5] = 32'h00000000; + bram[ 0*8 + 4] = 32'h00000000; + bram[ 0*8 + 3] = 32'h00000000; + bram[ 0*8 + 2] = 32'h00000000; + bram[ 0*8 + 1] = 32'h00000000; + bram[ 0*8 + 0] = 32'h00000000; + // + // CONST_ONE + // + bram[ 1*8 + 7] = 32'h00000000; + bram[ 1*8 + 6] = 32'h00000000; + bram[ 1*8 + 5] = 32'h00000000; + bram[ 1*8 + 4] = 32'h00000000; + bram[ 1*8 + 3] = 32'h00000000; + bram[ 1*8 + 2] = 32'h00000000; + bram[ 1*8 + 1] = 32'h00000000; + bram[ 1*8 + 0] = 32'h00000001; + // + // CONST_DELTA + // + bram[ 2*8 + 7] = 32'h7fffffff; + bram[ 2*8 + 6] = 32'h80000000; + bram[ 2*8 + 5] = 32'h80000000; + bram[ 2*8 + 4] = 32'h00000000; + bram[ 2*8 + 3] = 32'h00000000; + bram[ 2*8 + 2] = 32'h80000000; + bram[ 2*8 + 1] = 32'h00000000; + bram[ 2*8 + 0] = 32'h00000000; + // + // G_X + // + bram[ 3*8 + 7] = 32'h6b17d1f2; + bram[ 3*8 + 6] = 32'he12c4247; + bram[ 3*8 + 5] = 32'hf8bce6e5; + bram[ 3*8 + 4] = 32'h63a440f2; + bram[ 3*8 + 3] = 32'h77037d81; + bram[ 3*8 + 2] = 32'h2deb33a0; + bram[ 3*8 + 1] = 32'hf4a13945; + bram[ 3*8 + 0] = 32'hd898c296; + // + // G_Y + // + bram[ 4*8 + 7] = 32'h4fe342e2; + bram[ 4*8 + 6] = 32'hfe1a7f9b; + bram[ 4*8 + 5] = 32'h8ee7eb4a; + bram[ 4*8 + 4] = 32'h7c0f9e16; + bram[ 4*8 + 3] = 32'h2bce3357; + bram[ 4*8 + 2] = 32'h6b315ece; + bram[ 4*8 + 1] = 32'hcbb64068; + bram[ 4*8 + 0] = 32'h37bf51f5; + // + // H_X + // + bram[ 5*8 + 7] = 32'h7cf27b18; + bram[ 5*8 + 6] = 32'h8d034f7e; + bram[ 5*8 + 5] = 32'h8a523803; + bram[ 5*8 + 4] = 32'h04b51ac3; + bram[ 5*8 + 3] = 32'hc08969e2; + bram[ 5*8 + 2] = 32'h77f21b35; + bram[ 5*8 + 1] = 32'ha60b48fc; + bram[ 5*8 + 0] = 32'h47669978; + // + // H_Y + // + bram[ 6*8 + 7] = 32'h07775510; + bram[ 6*8 + 6] = 32'hdb8ed040; + bram[ 6*8 + 5] = 32'h293d9ac6; + bram[ 6*8 + 4] = 32'h9f7430db; + bram[ 6*8 + 3] = 32'hba7dade6; + bram[ 6*8 + 2] = 32'h3ce98229; + bram[ 6*8 + 1] = 32'h9e04b79d; + bram[ 6*8 + 0] = 32'h227873d1; + end + + + // + // Output Register + // + reg [32-1:0] bram_reg_b; + + assign b_out = bram_reg_b; + + + // + // Write Port A + // + always @(posedge clk) + // + if (a_wr) bram[a_addr] <= a_in; + + + // + // Read Port B + // + always @(posedge clk) + // + bram_reg_b <= bram[b_addr]; + + +endmodule diff --git a/rtl/ecdsa256_uop_worker.v b/rtl/ecdsa256_uop_worker.v new file mode 100644 index 0000000..a754796 --- /dev/null +++ b/rtl/ecdsa256_uop_worker.v @@ -0,0 +1,604 @@ +//------------------------------------------------------------------------------ +// +// ecdsa256_uop_worker.v +// ----------------------------------------------------------------------------- +// ECDSA uOP Worker for P-256 +// +// Authors: Pavel Shatov +// +// Copyright (c) 2018, NORDUnet A/S +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// - Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// - Neither the name of the NORDUnet nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +//------------------------------------------------------------------------------ + +module ecdsa256_uop_worker +( + clk, rst_n, + ena, rdy, + uop_offset, + output_now, + flagz_sz, flagz_rz, + flagz_e, flagz_f, + xy_addr, xy_dout, x_wren, y_wren +); + + + // + // Microcode Header + // +`include "ecdsa_uop.vh" + + + // + // Ports + // + input clk; // system clock + input rst_n; // active-low async reset + + input ena; // enable input + output rdy; // ready output + + input [UOP_ADDR_WIDTH-1:0] uop_offset; // starting offset + + input output_now; // produce output + + output flagz_sz; // SZ is zero + output flagz_rz; // RZ is zero + output flagz_e; // E is zero + output flagz_f; // F is zero + + output [ 2: 0] xy_addr; + output [31: 0] xy_dout; + output x_wren; + output y_wren; + + + // + // Constants + // + localparam integer OPERAND_NUM_WORDS = 8; // 256 bits -> 8 x 32-bit words + localparam integer WORD_COUNTER_WIDTH = 3; // 0..7 -> 3 bits + + + // + // FSM + // + localparam [1:0] FSM_STATE_IDLE = 2'b00; + localparam [1:0] FSM_STATE_FETCH = 2'b01; + localparam [1:0] FSM_STATE_DECODE = 2'b10; + localparam [1:0] FSM_STATE_BUSY = 2'b11; + + reg [1:0] fsm_state = FSM_STATE_IDLE; + reg [1:0] fsm_state_next; + + + // + // Microcode + // + reg [UOP_ADDR_WIDTH-1:0] uop_addr; + wire [UOP_DATA_WIDTH-1:0] uop_data; + + wire [5:0] uop_data_opcode = uop_data[1 + 3*6 +: 6]; + wire uop_data_banks = uop_data[0 + 3*6 +: 1]; + wire [5:0] uop_data_operand_src1 = uop_data[0 + 2*6 +: 6]; + wire [5:0] uop_data_operand_src2 = uop_data[0 + 1*6 +: 6]; + wire [5:0] uop_data_operand_dst = uop_data[0 + 0*6 +: 6]; + + wire uop_data_opcode_is_stop = uop_data_opcode[5]; + wire uop_data_opcode_is_mul = uop_data_opcode[4]; + wire uop_data_opcode_is_sub = uop_data_opcode[3]; + wire uop_data_opcode_is_add = uop_data_opcode[2]; + wire uop_data_opcode_is_copy = uop_data_opcode[1]; + wire uop_data_opcode_is_cmpz = uop_data_opcode[0]; + + ecdsa256_microcode_rom microcode_rom + ( + .clk (clk), + .addr (uop_addr), + .data (uop_data) + ); + + + // + // Microcode Address Increment Logic + // + always @(posedge clk) + // + if (fsm_state_next == FSM_STATE_FETCH) + uop_addr <= (fsm_state == FSM_STATE_IDLE) ? uop_offset : uop_addr + 1'b1; + + + // + // Multi-Word Mover + // + reg mw_mover_ena = 1'b0; + wire mw_mover_rdy; + + wire [WORD_COUNTER_WIDTH-1:0] mw_mover_x_addr; + wire [WORD_COUNTER_WIDTH-1:0] mw_mover_y_addr; + wire [ 32-1:0] mw_mover_x_din; + wire [ 32-1:0] mw_mover_y_dout; + wire mw_mover_y_wren; + + multiword_mover # + ( + .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH), + .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS) + ) + mw_mover_inst + ( + .clk (clk), + .rst_n (rst_n), + .ena (mw_mover_ena), + .rdy (mw_mover_rdy), + .x_addr (mw_mover_x_addr), + .y_addr (mw_mover_y_addr), + .y_wren (mw_mover_y_wren), + .x_din (mw_mover_x_din), + .y_dout (mw_mover_y_dout) + ); + + + // + // Modular Multiplier + // + reg mod_mul_ena = 1'b0; + wire mod_mul_rdy; + + wire [WORD_COUNTER_WIDTH-1:0] mod_mul_a_addr; + wire [WORD_COUNTER_WIDTH-1:0] mod_mul_b_addr; + wire [WORD_COUNTER_WIDTH-1:0] mod_mul_p_addr; + wire [ 32-1:0] mod_mul_a_din; + wire [ 32-1:0] mod_mul_b_din; + wire [ 32-1:0] mod_mul_p_dout; + wire mod_mul_p_wren; + + ecdsa256_modular_multiplier mod_mul_inst + ( + .clk (clk), + .rst_n (rst_n), + .ena (mod_mul_ena), + .rdy (mod_mul_rdy), + .a_addr (mod_mul_a_addr), + .b_addr (mod_mul_b_addr), + .p_addr (mod_mul_p_addr), + .p_wren (mod_mul_p_wren), + .a_din (mod_mul_a_din), + .b_din (mod_mul_b_din), + .p_dout (mod_mul_p_dout) + ); + + + // + // Modular Adder + // + reg mod_add_ena = 1'b0; + wire mod_add_rdy; + + wire [WORD_COUNTER_WIDTH-1:0] mod_add_ab_addr; + wire [WORD_COUNTER_WIDTH-1:0] mod_add_n_addr; + wire [WORD_COUNTER_WIDTH-1:0] mod_add_s_addr; + wire [ 32-1:0] mod_add_a_din; + wire [ 32-1:0] mod_add_b_din; + wire [ 32-1:0] mod_add_n_din; + wire [ 32-1:0] mod_add_s_dout; + wire mod_add_s_wren; + + modular_adder # + ( + .OPERAND_NUM_WORDS(OPERAND_NUM_WORDS), + .WORD_COUNTER_WIDTH(WORD_COUNTER_WIDTH) + ) + mod_add_inst + ( + .clk (clk), + .rst_n (rst_n), + .ena (mod_add_ena), + .rdy (mod_add_rdy), + .ab_addr (mod_add_ab_addr), + .n_addr (mod_add_n_addr), + .s_addr (mod_add_s_addr), + .s_wren (mod_add_s_wren), + .a_din (mod_add_a_din), + .b_din (mod_add_b_din), + .n_din (mod_add_n_din), + .s_dout (mod_add_s_dout) + ); + + + // + // Modular Subtractor + // + reg mod_sub_ena = 1'b0; + wire mod_sub_rdy; + + wire [WORD_COUNTER_WIDTH-1:0] mod_sub_ab_addr; + wire [WORD_COUNTER_WIDTH-1:0] mod_sub_n_addr; + wire [WORD_COUNTER_WIDTH-1:0] mod_sub_d_addr; + wire [ 32-1:0] mod_sub_a_din; + wire [ 32-1:0] mod_sub_b_din; + wire [ 32-1:0] mod_sub_n_din; + wire [ 32-1:0] mod_sub_d_dout; + wire mod_sub_d_wren; + + modular_subtractor # + ( + .OPERAND_NUM_WORDS(OPERAND_NUM_WORDS), + .WORD_COUNTER_WIDTH(WORD_COUNTER_WIDTH) + ) + mod_sub_inst + ( + .clk (clk), + .rst_n (rst_n), + .ena (mod_sub_ena), + .rdy (mod_sub_rdy), + .ab_addr (mod_sub_ab_addr), + .n_addr (mod_sub_n_addr), + .d_addr (mod_sub_d_addr), + .d_wren (mod_sub_d_wren), + .a_din (mod_sub_a_din), + .b_din (mod_sub_b_din), + .n_din (mod_sub_n_din), + .d_dout (mod_sub_d_dout) + ); + + + // + // Modulus (two instances for better placement and routing) + // + ecdsa256_modulus_distmem modulus_add + ( + .clk (clk), + .b_addr (mod_add_n_addr), + .b_out (mod_add_n_din) + ); + + ecdsa256_modulus_distmem modulus_sub + ( + .clk (clk), + .b_addr (mod_sub_n_addr), + .b_out (mod_sub_n_din) + ); + + + // + // Multi-Word Comparator + // + reg mw_comp_ena = 1'b0; + wire mw_comp_rdy; + + wire mw_comp_cmp_e; + + wire [WORD_COUNTER_WIDTH-1:0] mw_comp_x_addr; + wire [ 32-1:0] mw_comp_x_din; + + multiword_comparator # + ( + .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH), + .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS) + ) + mw_comp_inst + ( + .clk (clk), + .rst_n (rst_n), + .ena (mw_comp_ena), + .rdy (mw_comp_rdy), + .xy_addr (mw_comp_x_addr), + .x_din (mw_comp_x_din), + .y_din ({32{1'b0}}), + .cmp_l (), + .cmp_e (mw_comp_cmp_e), + .cmp_g () + ); + + + // + // Comparison Flags + // + reg flagz_sz_reg; + reg flagz_rz_reg; + reg flagz_e_reg; + reg flagz_f_reg; + + assign flagz_sz = flagz_sz_reg; + assign flagz_rz = flagz_rz_reg; + assign flagz_e = flagz_e_reg; + assign flagz_f = flagz_f_reg; + + reg mw_comp_rdy_dly = 1'b1; + + always @(posedge clk) mw_comp_rdy_dly <= mw_comp_rdy; + + always @(posedge clk) + // + if (mw_comp_rdy && !mw_comp_rdy_dly) + // + case (uop_data_operand_src1) + UOP_OPERAND_CYCLE_SZ: flagz_sz_reg <= mw_comp_cmp_e; + UOP_OPERAND_CYCLE_RZ: flagz_rz_reg <= mw_comp_cmp_e; + UOP_OPERAND_CYCLE_E: flagz_e_reg <= mw_comp_cmp_e; + UOP_OPERAND_CYCLE_F: flagz_f_reg <= mw_comp_cmp_e; + endcase + + + + // + // uOP Trigger Logic + // + always @(posedge clk) + // + if (fsm_state == FSM_STATE_DECODE) begin + mw_comp_ena <= uop_data_opcode_is_cmpz; + mw_mover_ena <= uop_data_opcode_is_copy; + mod_mul_ena <= uop_data_opcode_is_mul; + mod_add_ena <= uop_data_opcode_is_add; + mod_sub_ena <= uop_data_opcode_is_sub; + end else begin + mw_comp_ena <= 1'b0; + mw_mover_ena <= 1'b0; + mod_mul_ena <= 1'b0; + mod_add_ena <= 1'b0; + mod_sub_ena <= 1'b0; + end + + + // + // uOP Completion Detector + // + reg fsm_exit_from_busy; + + always @* begin + // + fsm_exit_from_busy = 0; + // + if (uop_data_opcode_is_cmpz) fsm_exit_from_busy = ~mw_comp_ena & mw_comp_rdy; + if (uop_data_opcode_is_copy) fsm_exit_from_busy = ~mw_mover_ena & mw_mover_rdy; + if (uop_data_opcode_is_mul) fsm_exit_from_busy = ~mod_mul_ena & mod_mul_rdy; + if (uop_data_opcode_is_add) fsm_exit_from_busy = ~mod_add_ena & mod_add_rdy; + if (uop_data_opcode_is_sub) fsm_exit_from_busy = ~mod_sub_ena & mod_sub_rdy; + // + end + + + // + // Banks + // + reg [ 2:0] banks_src1_addr; + reg [ 2:0] banks_src2_addr; + reg [ 2:0] banks_dst_addr; + + reg banks_dst_wren; + + reg [31:0] banks_dst_din; + + wire [31:0] banks_src1_dout; + wire [31:0] banks_src2_dout; + + ecdsa256_banks_array banks_array + ( + .clk (clk), + + .banks (uop_data_banks), + + .src1_operand (uop_data_operand_src1), + .src2_operand (uop_data_operand_src2), + .dst_operand (uop_data_operand_dst), + + .src1_addr (banks_src1_addr), + .src2_addr (banks_src2_addr), + .dst_addr (banks_dst_addr), + + .dst_wren (banks_dst_wren), + + .src1_dout (banks_src1_dout), + .src2_dout (banks_src2_dout), + + .dst_din (banks_dst_din) + ); + + assign mw_comp_x_din = banks_src1_dout; + assign mw_mover_x_din = banks_src1_dout; + assign mod_mul_a_din = banks_src1_dout; + assign mod_mul_b_din = banks_src2_dout; + assign mod_add_a_din = banks_src1_dout; + assign mod_add_b_din = banks_src2_dout; + assign mod_sub_a_din = banks_src1_dout; + assign mod_sub_b_din = banks_src2_dout; + + always @* + // + case (uop_data_opcode) + // + UOP_OPCODE_CMPZ: begin + banks_src1_addr = mw_comp_x_addr; + banks_src2_addr = {3{1'bX}}; + // + banks_dst_addr = {3{1'bX}}; + // + banks_dst_wren = 1'b0; + // + banks_dst_din = {32{1'bX}}; + end + // + UOP_OPCODE_COPY: begin + // + banks_src1_addr = mw_mover_x_addr; + banks_src2_addr = {3{1'bX}}; + // + banks_dst_addr = mw_mover_y_addr; + // + banks_dst_wren = mw_mover_y_wren; + // + banks_dst_din = mw_mover_y_dout; + // + end + // + UOP_OPCODE_ADD: begin + // + banks_src1_addr = mod_add_ab_addr; + banks_src2_addr = mod_add_ab_addr; + // + banks_dst_addr = mod_add_s_addr; + // + banks_dst_wren = mod_add_s_wren; + // + banks_dst_din = mod_add_s_dout; + // + end + // + UOP_OPCODE_SUB: begin + // + banks_src1_addr = mod_sub_ab_addr; + banks_src2_addr = mod_sub_ab_addr; + // + banks_dst_addr = mod_sub_d_addr; + // + banks_dst_wren = mod_sub_d_wren; + // + banks_dst_din = mod_sub_d_dout; + // + end + // + UOP_OPCODE_MUL: begin + // + banks_src1_addr = mod_mul_a_addr; + banks_src2_addr = mod_mul_b_addr; + // + banks_dst_addr = mod_mul_p_addr; + // + banks_dst_wren = mod_mul_p_wren; + // + banks_dst_din = mod_mul_p_dout; + // + end + // + default: begin + // + banks_src1_addr = {3{1'bX}}; + banks_src2_addr = {3{1'bX}}; + // + banks_dst_addr = {3{1'bX}}; + // + banks_dst_wren = 1'b0; + // + banks_dst_din = {32{1'bX}}; + // + end + // + endcase + + + // + // FSM Process + // + always @(posedge clk or negedge rst_n) + // + if (rst_n == 1'b0) fsm_state <= FSM_STATE_IDLE; + else fsm_state <= fsm_state_next; + + + // + // FSM Transition Logic + // + always @* begin + // + fsm_state_next = FSM_STATE_IDLE; + // + case (fsm_state) + FSM_STATE_IDLE: fsm_state_next = ena ? FSM_STATE_FETCH : FSM_STATE_IDLE; + FSM_STATE_FETCH: fsm_state_next = FSM_STATE_DECODE; + FSM_STATE_DECODE: fsm_state_next = uop_data_opcode_is_stop ? FSM_STATE_IDLE : FSM_STATE_BUSY; + FSM_STATE_BUSY: fsm_state_next = fsm_exit_from_busy ? FSM_STATE_FETCH : FSM_STATE_BUSY; + endcase + // + end + + + // + // Ready Flag Logic + // + reg rdy_reg = 1'b1; + assign rdy = rdy_reg; + + always @(posedge clk or negedge rst_n) + // + if (rst_n == 1'b0) rdy_reg <= 1'b1; + else case (fsm_state) + FSM_STATE_IDLE: rdy_reg <= ~ena; + FSM_STATE_DECODE: rdy_reg <= uop_data_opcode_is_stop; + endcase + + + // + // Output Logic + // + reg [ 2: 0] xy_addr_reg = 3'b000; + reg [31: 0] xy_dout_reg = 32'h00000000; + reg x_wren_reg = 1'b0; + reg y_wren_reg = 1'b0; + + assign xy_addr = xy_addr_reg; + assign xy_dout = xy_dout_reg; + assign x_wren = x_wren_reg; + assign y_wren = y_wren_reg; + + reg xy_phase; // 0 - x, 1 - y + + always @(posedge clk) + // + if (output_now) begin + + if (ena) + xy_phase <= 1'b0; + else if (!mw_mover_ena && mw_mover_rdy && (fsm_state == FSM_STATE_BUSY)) + xy_phase <= 1'b1; + + end + + + always @(posedge clk) + // + if (output_now && mw_mover_y_wren) xy_addr_reg <= mw_mover_y_addr; + else xy_addr_reg <= 3'b000; + + always @(posedge clk) + // + if (output_now && mw_mover_y_wren) xy_dout_reg <= mw_mover_y_dout; + else xy_dout_reg <= 32'h00000000; + + always @(posedge clk) + // + if (output_now && mw_mover_y_wren) {y_wren_reg, x_wren_reg} <= {xy_phase, ~xy_phase}; + else {y_wren_reg, x_wren_reg} <= 2'b00; + +endmodule + + +//------------------------------------------------------------------------------ +// End-of-File +//------------------------------------------------------------------------------ diff --git a/rtl/ecdsa256_wrapper.v b/rtl/ecdsa256_wrapper.v index 1684599..2b1d781 100644 --- a/rtl/ecdsa256_wrapper.v +++ b/rtl/ecdsa256_wrapper.v @@ -1,6 +1,6 @@ //====================================================================== // -// Copyright (c) 2016, NORDUnet A/S All rights reserved. +// Copyright (c) 2016, 2018 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 @@ -31,17 +31,17 @@ //====================================================================== module ecdsa256_wrapper - ( - input wire clk, - input wire reset_n, +( + input wire clk, + input wire reset_n, - input wire cs, - input wire we, + input wire cs, + input wire we, - input wire [5: 0] address, - input wire [31: 0] write_data, - output wire [31: 0] read_data - ); + input wire [ 5:0] address, + input wire [31:0] write_data, + output wire [31:0] read_data +); // @@ -50,15 +50,15 @@ module ecdsa256_wrapper localparam ADDR_MSB_REGS = 1'b0; localparam ADDR_MSB_CORE = 1'b1; - wire [0:0] addr_msb = address[5]; - wire [4:0] addr_lsb = address[4:0]; + wire [0:0] addr_msb = address[5]; + wire [4:0] addr_lsb = address[4:0]; // // Output Mux // - wire [31: 0] read_data_regs; - wire [31: 0] read_data_core; + wire [31:0] read_data_regs; + wire [31:0] read_data_core; // @@ -80,45 +80,45 @@ module ecdsa256_wrapper localparam CORE_NAME0 = 32'h65636473; // "ecds" localparam CORE_NAME1 = 32'h61323536; // "a256" - localparam CORE_VERSION = 32'h302E3131; // "0.11" + localparam CORE_VERSION = 32'h302E3230; // "0.20" // // Registers // - reg reg_control; - reg [31:0] reg_dummy; + reg reg_control; + reg [31:0] reg_dummy; // // Wires // - wire reg_status; + wire reg_status; - // - // ECDSA256 - // - ecdsa256 ecdsa256_inst - ( - .clk (clk), - .rst_n (reset_n), + // + // ECDSA256 + // + ecdsa256_core_top ecdsa256_inst + ( + .clk (clk), + .rst_n (reset_n), - .next (reg_control), - .valid (reg_status), + .next (reg_control), + .valid (reg_status), - .bus_cs (cs && (addr_msb == ADDR_MSB_CORE)), - .bus_we (we), - .bus_addr (addr_lsb), - .bus_data_wr (write_data), - .bus_data_rd (read_data_core) - ); + .bus_cs (cs && (addr_msb == ADDR_MSB_CORE)), + .bus_we (we), + .bus_addr (addr_lsb), + .bus_data_wr (write_data), + .bus_data_rd (read_data_core) + ); // // Read Latch // - reg [31: 0] tmp_read_data; + reg [31:0] tmp_read_data; // @@ -139,7 +139,7 @@ module ecdsa256_wrapper case (addr_lsb) // ADDR_CONTROL: reg_control <= write_data[CONTROL_NEXT_BIT]; - ADDR_DUMMY: reg_dummy <= write_data; + ADDR_DUMMY: reg_dummy <= write_data; // endcase // @@ -154,7 +154,7 @@ module ecdsa256_wrapper ADDR_VERSION: tmp_read_data <= CORE_VERSION; ADDR_CONTROL: tmp_read_data <= {{30{1'b0}}, reg_control, 1'b0}; ADDR_STATUS: tmp_read_data <= {{30{1'b0}}, reg_status, 1'b1}; - ADDR_DUMMY: tmp_read_data <= reg_dummy; + ADDR_DUMMY: tmp_read_data <= reg_dummy; // default: tmp_read_data <= 32'h00000000; // diff --git a/rtl/modular/modular_multiplier_256.v b/rtl/modular/modular_multiplier_256.v deleted file mode 100644 index 2b35233..0000000 --- a/rtl/modular/modular_multiplier_256.v +++ /dev/null @@ -1,402 +0,0 @@ -//------------------------------------------------------------------------------ -// -// modular_multiplier_256.v -// ----------------------------------------------------------------------------- -// Modular multiplier. -// -// Authors: Pavel Shatov -// -// Copyright (c) 2015-2016, NORDUnet A/S -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the NORDUnet nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//------------------------------------------------------------------------------ - -module modular_multiplier_256 - ( - clk, rst_n, - ena, rdy, - a_addr, b_addr, n_addr, p_addr, p_wren, - a_din, b_din, n_din, p_dout - ); - - - // - // Constants - // - localparam OPERAND_NUM_WORDS = 8; - localparam WORD_COUNTER_WIDTH = 3; - - - // - // Handy Numbers - // - localparam [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_ZERO = 0; - localparam [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_LAST = OPERAND_NUM_WORDS - 1; - - - // - // Handy Functions - // - function [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_NEXT_OR_ZERO; - input [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_CURRENT; - begin - WORD_INDEX_NEXT_OR_ZERO = (WORD_INDEX_CURRENT < WORD_INDEX_LAST) ? - WORD_INDEX_CURRENT + 1'b1 : WORD_INDEX_ZERO; - end - endfunction - - function [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_PREVIOUS_OR_LAST; - input [WORD_COUNTER_WIDTH-1:0] WORD_INDEX_CURRENT; - begin - WORD_INDEX_PREVIOUS_OR_LAST = (WORD_INDEX_CURRENT > WORD_INDEX_ZERO) ? - WORD_INDEX_CURRENT - 1'b1 : WORD_INDEX_LAST; - end - endfunction - - - // - // Ports - // - input wire clk; // system clock - input wire rst_n; // active-low async reset - - input wire ena; // enable input - output wire rdy; // ready output - - output wire [WORD_COUNTER_WIDTH-1:0] a_addr; // index of current A word - output wire [WORD_COUNTER_WIDTH-1:0] b_addr; // index of current B word - output wire [WORD_COUNTER_WIDTH-1:0] n_addr; // index of current N word - output wire [WORD_COUNTER_WIDTH-1:0] p_addr; // index of current P word - output wire p_wren; // store current P word now - - input wire [ 31:0] a_din; // A - input wire [ 31:0] b_din; // B - input wire [ 31:0] n_din; // N (must be P-256!) - output wire [ 31:0] p_dout; // P = A * B mod N - - - // - // Word Indices - // - reg [WORD_COUNTER_WIDTH-1:0] index_a; - reg [WORD_COUNTER_WIDTH-1:0] index_b; - - /* map registers to output ports */ - assign a_addr = index_a; - assign b_addr = index_b; - - // - // FSM - // - localparam FSM_SHREG_WIDTH = (1 * OPERAND_NUM_WORDS + 1) + (2 * OPERAND_NUM_WORDS + 1) + (2 * OPERAND_NUM_WORDS + 2) + (0 * OPERAND_NUM_WORDS + 2) + 1; - - reg [FSM_SHREG_WIDTH-1:0] fsm_shreg; - - assign rdy = fsm_shreg[0]; - - wire [1 * OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_a = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 1) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 0)]; - wire [1 * OPERAND_NUM_WORDS-1:0] fsm_shreg_store_word_a = fsm_shreg[FSM_SHREG_WIDTH - (0 * OPERAND_NUM_WORDS + 2) : FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 1)]; - wire [2 * OPERAND_NUM_WORDS-1:0] fsm_shreg_inc_index_b = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 1) : FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 1)]; - wire [2 * OPERAND_NUM_WORDS-2:0] fsm_shreg_store_si_msb = fsm_shreg[FSM_SHREG_WIDTH - (1 * OPERAND_NUM_WORDS + 2) : FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 1)]; - wire [0 * OPERAND_NUM_WORDS-0:0] fsm_shreg_store_si_lsb = fsm_shreg[FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 2) : FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 2)]; - wire [2 * OPERAND_NUM_WORDS-2:0] fsm_shreg_shift_si = fsm_shreg[FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 3) : FSM_SHREG_WIDTH - (5 * OPERAND_NUM_WORDS + 1)]; - wire [0 * OPERAND_NUM_WORDS-0:0] fsm_shreg_mask_cw1_sum = fsm_shreg[FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 4) : FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 4)]; - wire [2 * OPERAND_NUM_WORDS-1:0] fsm_shreg_store_c_word = fsm_shreg[FSM_SHREG_WIDTH - (3 * OPERAND_NUM_WORDS + 5) : FSM_SHREG_WIDTH - (5 * OPERAND_NUM_WORDS + 4)]; - wire [0 * OPERAND_NUM_WORDS-0:0] fsm_shreg_reduce_start = fsm_shreg[FSM_SHREG_WIDTH - (5 * OPERAND_NUM_WORDS + 5) : FSM_SHREG_WIDTH - (5 * OPERAND_NUM_WORDS + 5)]; - wire [0 * OPERAND_NUM_WORDS-0:0] fsm_shreg_reduce_stop = fsm_shreg[FSM_SHREG_WIDTH - (5 * OPERAND_NUM_WORDS + 6) : FSM_SHREG_WIDTH - (5 * OPERAND_NUM_WORDS + 6)]; - - wire inc_index_a = |fsm_shreg_inc_index_a; - wire store_word_a = |fsm_shreg_store_word_a; - wire inc_index_b = |fsm_shreg_inc_index_b; - wire clear_mac_ab = |fsm_shreg_inc_index_b; - wire shift_wide_a = |fsm_shreg_inc_index_b; - wire enable_mac_ab = |fsm_shreg_inc_index_b; - wire store_si_msb = |fsm_shreg_store_si_msb; - wire store_si_lsb = fsm_shreg_store_si_lsb; - wire shift_si = |fsm_shreg_shift_si; - wire mask_cw1_sum = fsm_shreg_mask_cw1_sum; - wire store_c_word = |fsm_shreg_store_c_word; - wire reduce_start = fsm_shreg_reduce_start; - wire reduce_stop = fsm_shreg_reduce_stop; - - - // - // FSM Logic - // - wire reduce_done; - - always @(posedge clk or negedge rst_n) - // - if (rst_n == 1'b0) - // - fsm_shreg <= {{FSM_SHREG_WIDTH-1{1'b0}}, 1'b1}; - // - else begin - // - if (rdy) - fsm_shreg <= {ena, {FSM_SHREG_WIDTH-2{1'b0}}, ~ena}; - // - else if (!reduce_stop || reduce_done) - fsm_shreg <= {1'b0, fsm_shreg[FSM_SHREG_WIDTH-1:1]}; - // - end - - - // - // Word Index Increment Logic - // - reg index_b_ff; - - always @(posedge clk) - // - if (inc_index_b) index_b_ff <= ~index_b_ff; - else index_b_ff <= 1'b0; - - always @(posedge clk) - // - if (rdy) begin - // - index_a <= WORD_INDEX_ZERO; - index_b <= WORD_INDEX_LAST; - // - end else begin - // - if (inc_index_a) index_a <= WORD_INDEX_NEXT_OR_ZERO(index_a); - if (inc_index_b && !index_b_ff) index_b <= WORD_INDEX_PREVIOUS_OR_LAST(index_b); - // - end - - - // - // Wide Operand Buffer - // - reg [255:0] buf_a_wide; - - always @(posedge clk) - // - if (store_word_a) - buf_a_wide <= {buf_a_wide[16 +: 256 - 3 * 16], {a_din[15:0], a_din[31:16]}, buf_a_wide[256 - 2 * 16 +: 16]}; - else if (shift_wide_a) - buf_a_wide <= {buf_a_wide[256-(16+1):0], buf_a_wide[256-16+:16]}; - - - // - // Multiplier Array - // - wire mac_inhibit; // control signal to pause all accumulators - - wire [46: 0] mac[0:15]; // outputs of all accumulators - reg [15: 0] mac_clear; // individual per-accumulator clear flag - - assign mac_inhibit = ~enable_mac_ab; - - always @(posedge clk) - // - if (!clear_mac_ab) - mac_clear <= {16{1'b1}}; - else begin - - if (mac_clear == {16{1'b1}}) - mac_clear <= {{14{1'b0}}, 1'b1, {1{1'b0}}}; - else - mac_clear <= (mac_clear[15] == 1'b0) ? {mac_clear[14:0], 1'b0} : {16{1'b1}}; - - - end - - // - // Array of parallel multipliers - // - genvar i; - generate for (i=0; i<16; i=i+1) - begin : gen_mac_array - // - mac16_wrapper mac16_inst - ( - .clk (clk), - .ce (~mac_inhibit), - - .clr (mac_clear[i]), - - .a (buf_a_wide[16*i+:16]), - .b (index_b_ff ? b_din[15:0] : b_din[31:16]), - .s (mac[i]) - ); - // - end - endgenerate - - // - // Intermediate Words - // - reg [47*(2*OPERAND_NUM_WORDS-1)-1:0] si_msb; - reg [47*(2*OPERAND_NUM_WORDS-0)-1:0] si_lsb; - - - wire [47*(2*OPERAND_NUM_WORDS-1)-1:0] si_msb_new; - wire [47*(2*OPERAND_NUM_WORDS-0)-1:0] si_lsb_new; - - generate for (i=0; i<16; i=i+1) - begin : gen_si_lsb_new - assign si_lsb_new[47*i+:47] = mac[15-i]; - end - endgenerate - - generate for (i=1; i<16; i=i+1) - begin : gen_si_msb_new - assign si_msb_new[47*(15-i)+:47] = mac_clear[i] ? mac[i] : si_msb[47*(15-i)+:47]; - end - endgenerate - - always @(posedge clk) begin - // - if (shift_si) begin - si_msb <= {{2*47{1'b0}}, si_msb[15*47-1:2*47]}; - si_lsb <= {si_msb[2*47-1:0], si_lsb[16*47-1:2*47]}; - end else begin - - if (store_si_msb) - si_msb <= si_msb_new; - - if (store_si_lsb) - si_lsb <= si_lsb_new; - end - - end - - - // - // Accumulators - // - wire [46: 0] add47_cw0_s; - wire [46: 0] add47_cw1_s; - - - // - // cw0, b, cw1, b - // - reg [30: 0] si_prev_dly; - reg [15: 0] si_next_dly; - - always @(posedge clk) - // - if (shift_si) - si_prev_dly <= si_lsb[93:63]; - else - si_prev_dly <= {31{1'b0}}; - - always @(posedge clk) - // - si_next_dly <= si_lsb[62:47]; - - wire [46: 0] add47_cw0_a = si_lsb[46:0]; - wire [46: 0] add47_cw0_b = {{16{1'b0}}, si_prev_dly}; - - wire [46: 0] add47_cw1_a = add47_cw0_s; - wire [46: 0] add47_cw1_b = {{15{1'b0}}, si_next_dly, mask_cw1_sum ? {16{1'b0}} : {1'b0, add47_cw1_s[46:32]}}; - - adder47_wrapper add47_cw0_inst - ( - .clk (clk), - .a (add47_cw0_a), - .b (add47_cw0_b), - .s (add47_cw0_s) - ); - - adder47_wrapper add47_cw1_inst - ( - .clk (clk), - .a (add47_cw1_a), - .b (add47_cw1_b), - .s (add47_cw1_s) - ); - - - - // - // Full-Size Product - // - reg [WORD_COUNTER_WIDTH:0] bram_c_addr; - - wire [WORD_COUNTER_WIDTH:0] reduce_c_addr; - wire [ 31:0] reduce_c_word; - - always @(posedge clk) - // - if (store_c_word) - bram_c_addr <= bram_c_addr + 1'b1; - else - bram_c_addr <= {2*WORD_COUNTER_WIDTH{1'b0}}; - - bram_1rw_1ro_readfirst # - ( - .MEM_WIDTH (32), - .MEM_ADDR_BITS (WORD_COUNTER_WIDTH + 1) - ) - bram_c_inst - ( - .clk (clk), - - .a_addr (bram_c_addr), - .a_wr (store_c_word), - .a_in (add47_cw1_s[31:0]), - .a_out (), - - .b_addr (reduce_c_addr), - .b_out (reduce_c_word) - ); - - - // - // Reduction Stage - // - modular_reductor_256 reduce_256_inst - ( - .clk (clk), - .rst_n (rst_n), - - .ena (reduce_start), - .rdy (reduce_done), - - .x_addr (reduce_c_addr), - .n_addr (n_addr), - .p_addr (p_addr), - .p_wren (p_wren), - - .x_din (reduce_c_word), - .n_din (n_din), - .p_dout (p_dout) - ); - - - endmodule - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/rtl/modular/modular_reductor_256.v b/rtl/modular/modular_reductor_256.v deleted file mode 100644 index 6f31570..0000000 --- a/rtl/modular/modular_reductor_256.v +++ /dev/null @@ -1,692 +0,0 @@ -//------------------------------------------------------------------------------ -// -// modular_reductor_256.v -// ----------------------------------------------------------------------------- -// Modular reductor. -// -// Authors: Pavel Shatov -// -// Copyright (c) 2015-2016, NORDUnet A/S -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// - Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// - Neither the name of the NORDUnet nor the names of its contributors may be -// used to endorse or promote products derived from this software without -// specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. -// -//------------------------------------------------------------------------------ - -module modular_reductor_256 - ( - clk, rst_n, - ena, rdy, - x_addr, n_addr, p_addr, p_wren, - x_din, n_din, p_dout - ); - - // - // Constants - // - localparam OPERAND_NUM_WORDS = 8; - localparam WORD_COUNTER_WIDTH = 3; - - - // - // Handy Numbers - // - localparam [WORD_COUNTER_WIDTH:0] WORD_INDEX_ZERO = 0; - localparam [WORD_COUNTER_WIDTH:0] WORD_INDEX_LAST = 2 * OPERAND_NUM_WORDS - 1; - - - // - // Handy Functions - // - function [WORD_COUNTER_WIDTH:0] WORD_INDEX_PREVIOUS_OR_LAST; - input [WORD_COUNTER_WIDTH:0] WORD_INDEX_CURRENT; - begin - WORD_INDEX_PREVIOUS_OR_LAST = (WORD_INDEX_CURRENT > WORD_INDEX_ZERO) ? - WORD_INDEX_CURRENT - 1'b1 : WORD_INDEX_LAST; - end - endfunction - - - // - // Ports - // - input wire clk; // system clock - input wire rst_n; // active-low async reset - - input wire ena; // enable input - output wire rdy; // ready output - - output wire [WORD_COUNTER_WIDTH-0:0] x_addr; // index of current X word - output wire [WORD_COUNTER_WIDTH-1:0] n_addr; // index of current N word - output wire [WORD_COUNTER_WIDTH-1:0] p_addr; // index of current P word - output wire p_wren; // store current P word now - - input wire [ 31:0] x_din; // X - input wire [ 31:0] n_din; // N (must be P-256!) - output wire [ 31:0] p_dout; // P = X mod N - - - // - // Word Indices - // - reg [WORD_COUNTER_WIDTH:0] index_x; - - - /* map registers to output ports */ - assign x_addr = index_x; - - - // - // FSM - // - localparam FSM_SHREG_WIDTH = (2 * OPERAND_NUM_WORDS + 1) + (5 * 2) + 1; - - reg [FSM_SHREG_WIDTH-1:0] fsm_shreg; - - assign rdy = fsm_shreg[0]; - - wire [2 * OPERAND_NUM_WORDS - 1:0] fsm_shreg_inc_index_x = fsm_shreg[FSM_SHREG_WIDTH - 0*OPERAND_NUM_WORDS - 1 -: 2 * OPERAND_NUM_WORDS]; - wire [2 * OPERAND_NUM_WORDS - 1:0] fsm_shreg_store_word_z = fsm_shreg[FSM_SHREG_WIDTH - 0*OPERAND_NUM_WORDS - 2 -: 2 * OPERAND_NUM_WORDS]; - wire [2 * 5 - 1:0] fsm_shreg_reduce_stages = fsm_shreg[ 1 +: 2 * 5]; - - wire [5-1:0] fsm_shreg_reduce_stage_start; - wire [5-1:0] fsm_shreg_reduce_stage_stop; - - genvar s; - generate for (s=0; s<5; s=s+1) - begin : gen_fsm_shreg_reduce_stages - assign fsm_shreg_reduce_stage_start[5 - (s + 1)] = fsm_shreg_reduce_stages[2 * (5 - s) - 1]; - assign fsm_shreg_reduce_stage_stop[5 - (s + 1)] = fsm_shreg_reduce_stages[2 * (5 - s) - 2]; - end - endgenerate - - wire inc_index_x = |fsm_shreg_inc_index_x; - wire store_word_z = |fsm_shreg_store_word_z; - wire reduce_start = |fsm_shreg_reduce_stage_start; - wire reduce_stop = |fsm_shreg_reduce_stage_stop; - wire store_p = fsm_shreg_reduce_stage_stop[0]; - - - wire reduce_adder0_done; - wire reduce_adder1_done; - wire reduce_subtractor_done; - - wire reduce_done_all = reduce_adder0_done & reduce_adder1_done & reduce_subtractor_done; - - always @(posedge clk or negedge rst_n) - // - if (rst_n == 1'b0) - // - fsm_shreg <= {{FSM_SHREG_WIDTH-1{1'b0}}, 1'b1}; - // - else begin - // - if (rdy) - // - fsm_shreg <= {ena, {FSM_SHREG_WIDTH-2{1'b0}}, ~ena}; - // - else if (!reduce_stop || reduce_done_all) - // - fsm_shreg <= {1'b0, fsm_shreg[FSM_SHREG_WIDTH-1:1]}; - // - end - - - // - // Word Index Increment Logic - // - always @(posedge clk) - // - if (rdy) - // - index_x <= WORD_INDEX_LAST; - // - else if (inc_index_x) - // - index_x <= WORD_INDEX_PREVIOUS_OR_LAST(index_x); - - - // - // Look-up Table - // - - // - // Take a look at the corresponding C model for more information - // on how exactly the math behind reduction works. The first step - // is to assemble nine 256-bit values ("z-words") from 32-bit parts - // of the full 512-bit product ("c-word"). The problem with z5 is - // that it contains c13 two times. This implementation scans from - // c15 to c0 and writes current part of c-word into corresponding - // parts of z-words. Since those 32-bit parts are stored in block - // memories, one source word can only be written to one location in - // every z-word at a time. The trick is to delay c13 and then write - // the delayed value at the corresponding location in z5 instead of - // the next c12. "z_save" flag is used to indicate that the current - // word should be delayed and written once again during the next cycle. - // - - reg [9*WORD_COUNTER_WIDTH-1:0] z_addr; // - reg [9 -1:0] z_wren; // - reg [9 -1:0] z_mask; // mask input to store zero word - reg [9 -1:0] z_save; // save previous word once again - - always @(posedge clk) - // - if (inc_index_x) - // - case (index_x) - // - // s9 s8 s7 s6 s5 s4 s3 s2 s1 - // || || || || || || || || || - 4'd00: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd00}; - 4'd01: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd01}; - 4'd02: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd02}; - 4'd03: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd03}; - 4'd04: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd04}; - 4'd05: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd05}; - 4'd06: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd06}; - 4'd07: z_addr <= {3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'dxx, 3'd07}; - 4'd08: z_addr <= {3'd02, 3'd03, 3'd04, 3'd06, 3'd07, 3'd00, 3'd00, 3'd00, 3'dxx}; - 4'd09: z_addr <= {3'd03, 3'd04, 3'd06, 3'd03, 3'd00, 3'd01, 3'd01, 3'd01, 3'dxx}; - 4'd10: z_addr <= {3'd04, 3'd05, 3'd05, 3'd07, 3'd01, 3'd02, 3'd02, 3'd02, 3'dxx}; - 4'd11: z_addr <= {3'd05, 3'd06, 3'd07, 3'd00, 3'd02, 3'd03, 3'd07, 3'd03, 3'dxx}; - 4'd12: z_addr <= {3'd06, 3'd07, 3'd00, 3'd01, 3'd06, 3'd04, 3'd03, 3'd04, 3'dxx}; - 4'd13: z_addr <= {3'd07, 3'd00, 3'd01, 3'd02, 3'd03, 3'd05, 3'd04, 3'd05, 3'dxx}; - 4'd14: z_addr <= {3'd00, 3'd01, 3'd02, 3'd04, 3'd04, 3'd06, 3'd05, 3'd06, 3'dxx}; - 4'd15: z_addr <= {3'd01, 3'd02, 3'd03, 3'd05, 3'd05, 3'd07, 3'd06, 3'd07, 3'dxx}; - // - default: z_addr <= {9*WORD_COUNTER_WIDTH{1'bX}}; - // - endcase - - always @(posedge clk) - // - case (index_x) - // - // 9 8 7 6 5 4 3 2 1 - // | | | | | | | | | - 4'd00: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1}; - 4'd01: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1}; - 4'd02: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1}; - 4'd03: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1}; - 4'd04: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1}; - 4'd05: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1}; - 4'd06: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1}; - 4'd07: z_wren <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1}; - 4'd08: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0}; - 4'd09: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0}; - 4'd10: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0}; - 4'd11: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0}; - 4'd12: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0}; - 4'd13: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0}; - 4'd14: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0}; - 4'd15: z_wren <= {1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b1, 1'b0}; - // - default: z_wren <= {9{1'b0}}; - // - endcase - - always @(posedge clk) - // - if (inc_index_x) - // - case (index_x) - // - // 9 8 7 6 5 4 3 2 1 - // | | | | | | | | | - 4'd00: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd01: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd02: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd03: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd04: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd05: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd06: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd07: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd08: z_mask <= {1'b1, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b1, 1'b1, 1'b0}; - 4'd09: z_mask <= {1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b1, 1'b1, 1'b0}; - 4'd10: z_mask <= {1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b1, 1'b1, 1'b0}; - 4'd11: z_mask <= {1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b1, 1'b1, 1'b0, 1'b0}; - 4'd12: z_mask <= {1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0}; - 4'd13: z_mask <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0}; - 4'd14: z_mask <= {1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd15: z_mask <= {1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - // - default: z_mask <= {9{1'bX}}; - // - endcase - - always @(posedge clk) - // - if (inc_index_x) - // - case (index_x) - // - // 9 8 7 6 5 4 3 2 1 - // | | | | | | | | | - 4'd00: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd01: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd02: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd03: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd04: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd05: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd06: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd07: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd08: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd09: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd10: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd11: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd12: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b1, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd13: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd14: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - 4'd15: z_save <= {1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0, 1'b0}; - // - default: z_save <= {9{1'bX}}; - // - endcase - - - // - // Intermediate Numbers - // - reg [WORD_COUNTER_WIDTH-1:0] reduce_z_addr[1:9]; - wire [ 32-1:0] reduce_z_dout[1:9]; - - reg [31: 0] x_din_dly; - always @(posedge clk) - // - x_din_dly <= x_din; - - - genvar z; - generate for (z=1; z<=9; z=z+1) - // - begin : gen_z_bram - // - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_c_inst - ( - .clk (clk), - - .a_addr (z_addr[(z-1) * WORD_COUNTER_WIDTH +: WORD_COUNTER_WIDTH]), - .a_wr (z_wren[z-1] & store_word_z), - .a_in (z_mask[z-1] ? {32{1'b0}} : (z_save[z-1] ? x_din_dly : x_din)), - .a_out (), - - .b_addr (reduce_z_addr[z]), - .b_out (reduce_z_dout[z]) - ); - // - end - // - endgenerate - - - - - wire [ 32-1:0] bram_sum0_wr_din; - wire [WORD_COUNTER_WIDTH-1:0] bram_sum0_wr_addr; - wire bram_sum0_wr_wren; - - wire [ 32-1:0] bram_sum1_wr_din; - wire [WORD_COUNTER_WIDTH-1:0] bram_sum1_wr_addr; - wire bram_sum1_wr_wren; - - wire [ 32-1:0] bram_diff_wr_din; - wire [WORD_COUNTER_WIDTH-1:0] bram_diff_wr_addr; - wire bram_diff_wr_wren; - - wire [ 32-1:0] bram_sum0_rd_dout; - reg [WORD_COUNTER_WIDTH-1:0] bram_sum0_rd_addr; - - wire [ 32-1:0] bram_sum1_rd_dout; - reg [WORD_COUNTER_WIDTH-1:0] bram_sum1_rd_addr; - - wire [ 32-1:0] bram_diff_rd_dout; - reg [WORD_COUNTER_WIDTH-1:0] bram_diff_rd_addr; - - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_sum0_inst - ( - .clk (clk), - - .a_addr (bram_sum0_wr_addr), - .a_wr (bram_sum0_wr_wren), - .a_in (bram_sum0_wr_din), - .a_out (), - - .b_addr (bram_sum0_rd_addr), - .b_out (bram_sum0_rd_dout) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_sum1_inst - ( - .clk (clk), - - .a_addr (bram_sum1_wr_addr), - .a_wr (bram_sum1_wr_wren), - .a_in (bram_sum1_wr_din), - .a_out (), - - .b_addr (bram_sum1_rd_addr), - .b_out (bram_sum1_rd_dout) - ); - - bram_1rw_1ro_readfirst # (.MEM_WIDTH(32), .MEM_ADDR_BITS(WORD_COUNTER_WIDTH)) - bram_diff_inst - ( - .clk (clk), - - .a_addr (bram_diff_wr_addr), - .a_wr (bram_diff_wr_wren), - .a_in (bram_diff_wr_din), - .a_out (), - - .b_addr (bram_diff_rd_addr), - .b_out (bram_diff_rd_dout) - ); - - - wire [WORD_COUNTER_WIDTH-1:0] adder0_ab_addr; - wire [WORD_COUNTER_WIDTH-1:0] adder1_ab_addr; - wire [WORD_COUNTER_WIDTH-1:0] subtractor_ab_addr; - - reg [ 32-1:0] adder0_a_din; - reg [ 32-1:0] adder0_b_din; - - reg [ 32-1:0] adder1_a_din; - reg [ 32-1:0] adder1_b_din; - - reg [ 32-1:0] subtractor_a_din; - reg [ 32-1:0] subtractor_b_din; - - // n_addr - only 1 output, because all modules are in sync - - modular_adder # - ( - .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS), - .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH) - ) - adder_inst0 - ( - .clk (clk), - .rst_n (rst_n), - - .ena (reduce_start), - .rdy (reduce_adder0_done), - - .ab_addr (adder0_ab_addr), - .n_addr (), - .s_addr (bram_sum0_wr_addr), - .s_wren (bram_sum0_wr_wren), - - .a_din (adder0_a_din), - .b_din (adder0_b_din), - .n_din (n_din), - .s_dout (bram_sum0_wr_din) - ); - - modular_adder # - ( - .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS), - .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH) - ) - adder_inst1 - ( - .clk (clk), - .rst_n (rst_n), - - .ena (reduce_start), - .rdy (reduce_adder1_done), - - .ab_addr (adder1_ab_addr), - .n_addr (), - .s_addr (bram_sum1_wr_addr), - .s_wren (bram_sum1_wr_wren), - - .a_din (adder1_a_din), - .b_din (adder1_b_din), - .n_din (n_din), - .s_dout (bram_sum1_wr_din) - ); - - modular_subtractor # - ( - .OPERAND_NUM_WORDS (OPERAND_NUM_WORDS), - .WORD_COUNTER_WIDTH (WORD_COUNTER_WIDTH) - ) - subtractor_inst - ( - .clk (clk), - .rst_n (rst_n), - - .ena (reduce_start), - .rdy (reduce_subtractor_done), - - .ab_addr (subtractor_ab_addr), - .n_addr (n_addr), - .d_addr (bram_diff_wr_addr), - .d_wren (bram_diff_wr_wren), - - .a_din (subtractor_a_din), - .b_din (subtractor_b_din), - .n_din (n_din), - .d_dout (bram_diff_wr_din) - ); - - - // - // Address (Operand) Selector - // - always @(*) - // - case (fsm_shreg_reduce_stage_stop) - // - 5'b10000: begin - reduce_z_addr[1] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[2] = adder0_ab_addr; - reduce_z_addr[3] = adder1_ab_addr; - reduce_z_addr[4] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[5] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[6] = subtractor_ab_addr; - reduce_z_addr[7] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[8] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[9] = {WORD_COUNTER_WIDTH{1'bX}}; - bram_sum0_rd_addr = {WORD_COUNTER_WIDTH{1'bX}}; - bram_sum1_rd_addr = {WORD_COUNTER_WIDTH{1'bX}}; - bram_diff_rd_addr = {WORD_COUNTER_WIDTH{1'bX}}; - end - // - 5'b01000: begin - reduce_z_addr[1] = adder0_ab_addr; - reduce_z_addr[2] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[3] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[4] = adder1_ab_addr; - reduce_z_addr[5] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[6] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[7] = subtractor_ab_addr; - reduce_z_addr[8] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[9] = {WORD_COUNTER_WIDTH{1'bX}}; - bram_sum0_rd_addr = adder0_ab_addr; - bram_sum1_rd_addr = adder1_ab_addr; - bram_diff_rd_addr = subtractor_ab_addr; - end - // - 5'b00100: begin - reduce_z_addr[1] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[2] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[3] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[4] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[5] = adder0_ab_addr; - reduce_z_addr[6] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[7] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[8] = subtractor_ab_addr; - reduce_z_addr[9] = {WORD_COUNTER_WIDTH{1'bX}}; - bram_sum0_rd_addr = adder0_ab_addr; - bram_sum1_rd_addr = adder1_ab_addr; - bram_diff_rd_addr = subtractor_ab_addr; - end - // - 5'b00010: begin - reduce_z_addr[1] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[2] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[3] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[4] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[5] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[6] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[7] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[8] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[9] = subtractor_ab_addr; - bram_sum0_rd_addr = adder0_ab_addr; - bram_sum1_rd_addr = adder0_ab_addr; - bram_diff_rd_addr = subtractor_ab_addr; - end - // - 5'b00001: begin - reduce_z_addr[1] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[2] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[3] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[4] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[5] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[6] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[7] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[8] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[9] = {WORD_COUNTER_WIDTH{1'bX}}; - bram_sum0_rd_addr = adder0_ab_addr; - bram_sum1_rd_addr = {WORD_COUNTER_WIDTH{1'bX}}; - bram_diff_rd_addr = adder0_ab_addr; - end - // - default: begin - reduce_z_addr[1] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[2] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[3] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[4] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[5] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[6] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[7] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[8] = {WORD_COUNTER_WIDTH{1'bX}}; - reduce_z_addr[9] = {WORD_COUNTER_WIDTH{1'bX}}; - bram_sum0_rd_addr = {WORD_COUNTER_WIDTH{1'bX}}; - bram_sum1_rd_addr = {WORD_COUNTER_WIDTH{1'bX}}; - bram_diff_rd_addr = {WORD_COUNTER_WIDTH{1'bX}}; - end - // - endcase - - - // - // adder 0 - // - always @(*) begin - // - case (fsm_shreg_reduce_stage_stop) - 5'b10000: adder0_a_din = reduce_z_dout[2]; - 5'b01000: adder0_a_din = bram_sum0_rd_dout; - 5'b00100: adder0_a_din = bram_sum0_rd_dout; - 5'b00010: adder0_a_din = bram_sum0_rd_dout; - 5'b00001: adder0_a_din = bram_sum0_rd_dout; - default: adder0_a_din = {32{1'bX}}; - endcase - // - case (fsm_shreg_reduce_stage_stop) - 5'b10000: adder0_b_din = reduce_z_dout[2]; - 5'b01000: adder0_b_din = reduce_z_dout[1]; - 5'b00100: adder0_b_din = reduce_z_dout[5]; - 5'b00010: adder0_b_din = bram_sum1_rd_dout; - 5'b00001: adder0_b_din = bram_diff_rd_dout; - default: adder0_b_din = {32{1'bX}}; - endcase - // - end - - // - // adder 1 - // - always @(*) begin - // - case (fsm_shreg_reduce_stage_stop) - 5'b10000: adder1_a_din = reduce_z_dout[3]; - 5'b01000: adder1_a_din = bram_sum1_rd_dout; - 5'b00100: adder1_a_din = bram_sum1_rd_dout; - 5'b00010: adder1_a_din = {32{1'bX}}; - 5'b00001: adder1_a_din = {32{1'bX}}; - default: adder1_a_din = {32{1'bX}}; - endcase - // - case (fsm_shreg_reduce_stage_stop) - 5'b10000: adder1_b_din = reduce_z_dout[3]; - 5'b01000: adder1_b_din = reduce_z_dout[4]; - 5'b00100: adder1_b_din = {32{1'b0}}; - 5'b00010: adder1_b_din = {32{1'bX}}; - 5'b00001: adder1_b_din = {32{1'bX}}; - default: adder1_b_din = {32{1'bX}}; - endcase - // - end - - - // - // subtractor - // - always @(*) begin - // - case (fsm_shreg_reduce_stage_stop) - 5'b10000: subtractor_a_din = {32{1'b0}}; - 5'b01000: subtractor_a_din = bram_diff_rd_dout; - 5'b00100: subtractor_a_din = bram_diff_rd_dout; - 5'b00010: subtractor_a_din = bram_diff_rd_dout; - 5'b00001: subtractor_a_din = {32{1'bX}}; - default: subtractor_a_din = {32{1'bX}}; - endcase - // - case (fsm_shreg_reduce_stage_stop) - 5'b10000: subtractor_b_din = reduce_z_dout[6]; - 5'b01000: subtractor_b_din = reduce_z_dout[7]; - 5'b00100: subtractor_b_din = reduce_z_dout[8]; - 5'b00010: subtractor_b_din = reduce_z_dout[9]; - 5'b00001: subtractor_b_din = {32{1'bX}}; - default: subtractor_b_din = {32{1'bX}}; - endcase - // - end - - - // - // Address Mapping - // - assign p_addr = bram_sum0_wr_addr; - assign p_wren = bram_sum0_wr_wren & store_p; - assign p_dout = bram_sum0_wr_din; - - -endmodule - - -//------------------------------------------------------------------------------ -// End-of-File -//------------------------------------------------------------------------------ diff --git a/stm32_driver/ecdsa256_driver_sample.c b/stm32_driver/ecdsa256_driver_sample.c index 1950491..35f1525 100644 --- a/stm32_driver/ecdsa256_driver_sample.c +++ b/stm32_driver/ecdsa256_driver_sample.c @@ -31,34 +31,44 @@ // curve selection #define USE_CURVE 1 -#include "../../../user/shatov/ecdsa_fpga_model/ecdsa_model.h" +#include "ecdsa_test_vector_nsa.h" +#include "ecdsa_test_vector_randomized.h" -#define BUF_NUM_WORDS (OPERAND_WIDTH / (sizeof(uint32_t) << 3)) // 8 +#define bool uint32_t // very dirty hack, but works in this particular case +#include "ecdsa_fpga_lowlevel.h" +#include "ecdsa_fpga_multiword.h" +#include "ecdsa_fpga_curve.h" +#undef bool + +#define BUF_NUM_WORDS FPGA_OPERAND_NUM_WORDS // // test vectors // -static const uint32_t p256_d[BUF_NUM_WORDS] = ECDSA_D; -static const uint32_t p256_qx[BUF_NUM_WORDS] = ECDSA_Q_X; -static const uint32_t p256_qy[BUF_NUM_WORDS] = ECDSA_Q_Y; +static const uint32_t p256_d_nsa[BUF_NUM_WORDS] = ECDSA_P256_D_NSA_INIT; +static const uint32_t p256_qx_nsa[BUF_NUM_WORDS] = ECDSA_P256_QX_NSA_INIT; +static const uint32_t p256_qy_nsa[BUF_NUM_WORDS] = ECDSA_P256_QY_NSA_INIT; + +static const uint32_t p256_k_nsa[BUF_NUM_WORDS] = ECDSA_P256_K_NSA_INIT; +static const uint32_t p256_rx_nsa[BUF_NUM_WORDS] = ECDSA_P256_RX_NSA_INIT; +static const uint32_t p256_ry_nsa[BUF_NUM_WORDS] = ECDSA_P256_RY_NSA_INIT; -static const uint32_t p256_k[BUF_NUM_WORDS] = ECDSA_K; -static const uint32_t p256_rx[BUF_NUM_WORDS] = ECDSA_R_X; -static const uint32_t p256_ry[BUF_NUM_WORDS] = ECDSA_R_Y; +static const uint32_t p256_d_random[BUF_NUM_WORDS] = ECDSA_P256_D_RANDOM_INIT; +static const uint32_t p256_qx_random[BUF_NUM_WORDS] = ECDSA_P256_QX_RANDOM_INIT; +static const uint32_t p256_qy_random[BUF_NUM_WORDS] = ECDSA_P256_QY_RANDOM_INIT; -static const uint32_t p256_i[BUF_NUM_WORDS] = ECDSA_ONE; -static const uint32_t p256_gx[BUF_NUM_WORDS] = ECDSA_G_X; -static const uint32_t p256_gy[BUF_NUM_WORDS] = ECDSA_G_Y; -static const uint32_t p256_hx[BUF_NUM_WORDS] = ECDSA_H_X; -static const uint32_t p256_hy[BUF_NUM_WORDS] = ECDSA_H_Y; +static const uint32_t p256_gx[BUF_NUM_WORDS] = ECDSA_P256_GX_INIT; +static const uint32_t p256_gy[BUF_NUM_WORDS] = ECDSA_P256_GY_INIT; +static const uint32_t p256_hx[BUF_NUM_WORDS] = ECDSA_P256_HX_INIT; +static const uint32_t p256_hy[BUF_NUM_WORDS] = ECDSA_P256_HY_INIT; +static const uint32_t p256_n[BUF_NUM_WORDS] = ECDSA_P256_N_INIT; -static const uint32_t p256_z[BUF_NUM_WORDS] = ECDSA_ZERO; -static const uint32_t p256_n[BUF_NUM_WORDS] = ECDSA_N; +static uint32_t p256_zero[BUF_NUM_WORDS]; +static uint32_t p256_two [BUF_NUM_WORDS]; +static uint32_t p256_n1 [BUF_NUM_WORDS]; +static uint32_t p256_n2 [BUF_NUM_WORDS]; -static uint32_t p256_2[BUF_NUM_WORDS]; // 2 -static uint32_t p256_n1[BUF_NUM_WORDS]; // n + 1 -static uint32_t p256_n2[BUF_NUM_WORDS]; // n + 2 // // prototypes @@ -84,9 +94,11 @@ int main() uint32_t core_name0; uint32_t core_name1; + uint32_t core_version; - fmc_read_32(CORE_ADDR_NAME0, &core_name0); - fmc_read_32(CORE_ADDR_NAME1, &core_name1); + fmc_read_32(CORE_ADDR_NAME0, &core_name0); + fmc_read_32(CORE_ADDR_NAME1, &core_name1); + fmc_read_32(CORE_ADDR_VERSION, &core_version); // "ecds", "a256" if ((core_name0 != 0x65636473) || (core_name1 != 0x61323536)) { @@ -98,15 +110,15 @@ int main() // prepare more numbers size_t w; for (w=0; w<BUF_NUM_WORDS; w++) - { p256_2[w] = p256_z[w]; // p256_2 = p256_z = 0 - p256_n1[w] = p256_n[w]; // p256_n1 = p256_n = N - p256_n2[w] = p256_n[w]; // p256_n2 = p256_n = N + { p256_zero[w] = 0; + p256_two [w] = 0; + p256_n1 [w] = p256_n [w]; + p256_n2 [w] = p256_n [w]; } - p256_2[BUF_NUM_WORDS-1] += 2; // p256_2 = 2 - p256_n1[BUF_NUM_WORDS-1] += 1; // p256_n1 = N + 1 - p256_n2[BUF_NUM_WORDS-1] += 2; // p256_n2 = N + 2 - + p256_two[BUF_NUM_WORDS-1] += 2; + p256_n1 [BUF_NUM_WORDS-1] += 1; + p256_n2 [BUF_NUM_WORDS-1] += 2; // repeat forever @@ -114,15 +126,12 @@ int main() { ok = 1; - ok = ok && test_p256_multiplier(p256_d, p256_qx, p256_qy); /* Q = d * G */ - ok = ok && test_p256_multiplier(p256_k, p256_rx, p256_ry); /* R = k * G */ + ok = ok && test_p256_multiplier(p256_d_nsa, p256_qx_nsa, p256_qy_nsa); /* Q = d * G */ + ok = ok && test_p256_multiplier(p256_k_nsa, p256_rx_nsa, p256_ry_nsa); /* R = k * G */ + ok = ok && test_p256_multiplier(p256_d_random, p256_qx_random, p256_qy_random); /* Q = d * G */ - ok = ok && test_p256_multiplier(p256_z, p256_z, p256_z); /* O = 0 * G */ - ok = ok && test_p256_multiplier(p256_i, p256_gx, p256_gy); /* G = 1 * G */ - - ok = ok && test_p256_multiplier(p256_n, p256_z, p256_z); /* O = n * G */ - - ok = ok && test_p256_multiplier(p256_n1, p256_gx, p256_gy); /* G = (n + 1) * G */ + ok = ok && test_p256_multiplier(p256_n, p256_zero, p256_zero); /* O = n * G */ + ok = ok && test_p256_multiplier(p256_n1, p256_gx, p256_gy); /* G = (n + 1) * G */ // // The following two vectors test the virtually never taken path in the curve point @@ -136,8 +145,9 @@ int main() // on the fly. Note that in practice one should never be multiplying by anything larger than (n-1), // because both the secret key and the per-message (random) number must be from [1, n-1]. // - ok = ok && test_p256_multiplier(p256_2, p256_hx, p256_hy); /* H = 2 * G */ - ok = ok && test_p256_multiplier(p256_n2, p256_hx, p256_hy); /* H = (n + 2) * G */ + ok = ok && test_p256_multiplier(p256_two, p256_hx, p256_hy); /* H = 2 * G */ + ok = ok && test_p256_multiplier(p256_n2, p256_hx, p256_hy); /* H = (n + 2) * G */ + if (!ok) { led_off(LED_GREEN); @@ -163,14 +173,14 @@ int test_p256_multiplier(const uint32_t *k, const uint32_t *px, const uint32_t * // fill k for (i=0; i<BUF_NUM_WORDS; i++) { k_word = k[i]; - fmc_write_32(CORE_ADDR_BUF_K + ((BUF_NUM_WORDS - (i + 1)) * sizeof(uint32_t)), &k_word); + fmc_write_32(CORE_ADDR_BUF_K + ((BUF_NUM_WORDS - (i + 1)) * sizeof(uint32_t)), k_word); } // clear 'next' control bit, then set 'next' control bit again to trigger new operation reg_control = 0; - fmc_write_32(CORE_ADDR_CONTROL, ®_control); + fmc_write_32(CORE_ADDR_CONTROL, reg_control); reg_control = CORE_CONTROL_BIT_NEXT; - fmc_write_32(CORE_ADDR_CONTROL, ®_control); + fmc_write_32(CORE_ADDR_CONTROL, reg_control); // wait for 'ready' status bit to be set num_cyc = 0; @@ -208,5 +218,15 @@ void toggle_yellow_led(void) // +// systick +// +void SysTick_Handler(void) +{ + HAL_IncTick(); + HAL_SYSTICK_IRQHandler(); +} + + +// // end of file // |