aboutsummaryrefslogtreecommitdiff
path: root/bench
diff options
context:
space:
mode:
authorPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2018-12-19 15:34:55 +0300
committerPavel V. Shatov (Meister) <meisterpaul1@yandex.ru>2018-12-19 15:41:00 +0300
commitc617c0c711620f58eb3ead22edcdfe57fed06088 (patch)
tree8c15184d5ca6403ea01843560394f6d909a0986f /bench
parentea4d251c81c8b53e0bbc71cd1719dfea4d0517c1 (diff)
* Rewritten from scratch, uses the same hardware architecture as the Ed25519HEADmaster
core for better timing performance * Removed custom modular inversion sub-module, now uses micro-coded modular inversion routine based on Fermat's little theorem (~10% faster) * Uses math primitives from core/lib * Added randomized test vector (see user/shatov/ecdsa_fpga_model/test_vectors/)
Diffstat (limited to 'bench')
-rw-r--r--bench/ecdsa256_test_vector_nsa.vh26
-rw-r--r--bench/ecdsa_test_vector_randomized.vh29
-rw-r--r--bench/tb_curve_adder_256.v420
-rw-r--r--bench/tb_curve_doubler_256.v409
-rw-r--r--bench/tb_curve_multiplier_256.v525
-rw-r--r--bench/tb_lowlevel_adder32.v175
-rw-r--r--bench/tb_lowlevel_adder47.v151
-rw-r--r--bench/tb_lowlevel_subtractor32.v174
-rw-r--r--bench/tb_modular_adder.v357
-rw-r--r--bench/tb_modular_invertor.v225
-rw-r--r--bench/tb_modular_multiplier_256.v366
-rw-r--r--bench/tb_modular_subtractor.v356
-rw-r--r--bench/tb_mw_comparator.v322
-rw-r--r--bench/tb_mw_mover.v282
14 files changed, 322 insertions, 3495 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
-//------------------------------------------------------------------------------