[Cryptech-Commits] [core/comm/fmc] 04/04: Another testbench to make sure, that the new pipelined core selector can properly pick desired core.

git at cryptech.is git at cryptech.is
Tue Feb 11 13:05:22 UTC 2020


This is an automated email from the git hooks/post-receive script.

meisterpaul1 at yandex.ru pushed a commit to branch master
in repository core/comm/fmc.

commit 19374267f9c8614b1c5863a2f3433a01ae37fb08
Author: Pavel V. Shatov (Meister) <meisterpaul1 at yandex.ru>
AuthorDate: Tue Jan 21 15:26:57 2020 +0300

    Another testbench to make sure, that the new pipelined core selector can
    properly pick desired core.
---
 src/tb/tb_fmc_core_selector.v | 367 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 367 insertions(+)

diff --git a/src/tb/tb_fmc_core_selector.v b/src/tb/tb_fmc_core_selector.v
new file mode 100644
index 0000000..9c0c6ca
--- /dev/null
+++ b/src/tb/tb_fmc_core_selector.v
@@ -0,0 +1,367 @@
+//------------------------------------------------------------------------------
+//
+// tb_fmc_core_selector.v
+// -----------------------------------------------------------------------------
+// Testbench for fixed latency FMC arbiter.
+//
+// Authors: Pavel Shatov
+//
+// Copyright (c) 2018-2019, 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_fmc_core_selector;
+
+
+    //
+    // Settings
+    //
+    localparam integer NUM_TESTS = 100;
+    
+    
+    //
+    // STM32 Settings
+    //
+    localparam integer STM32_FMC_LATENCY = 6;
+    
+
+    //
+    // Clock
+    //
+    
+    /* actual hardware uses 45 MHz, we use 50 for convenience */
+    
+    localparam FMC_CLOCK_PERIOD         = 20.0;
+    localparam FMC_CLOCK_PERIOD_HALF    = 0.5 * FMC_CLOCK_PERIOD;
+    localparam FMC_CLOCK_PERIOD_QUARTER = 0.5 * FMC_CLOCK_PERIOD_HALF;
+
+    reg fmc_clk = 1'b0;
+
+    initial forever #FMC_CLOCK_PERIOD_HALF fmc_clk = ~fmc_clk;
+    
+
+    //
+    // Clock Manager
+    //    
+    wire io_clk;    
+    wire sys_clk;
+    wire sys_rst_n;
+    wire core_clk;
+    
+    alpha_clkmgr clkmgr_inst
+    (
+        .fmc_clk     (fmc_clk),
+
+        .io_clk      (io_clk),
+        .sys_clk     (sys_clk),
+        .sys_rst_n   (sys_rst_n),
+        .core_clk    (core_clk)
+    );
+
+
+    //
+    // FMC Arbiter - FPGA Side
+    //
+    wire [23: 0] sys_fmc_addr;
+    wire         sys_fmc_wren;
+    wire         sys_fmc_rden;
+    wire [31: 0] sys_fmc_dout;
+    wire [31: 0] sys_fmc_din;
+
+
+    //
+    // FMC Arbiter - STM32 Side
+    //
+    reg  [23: 0] fmc_a = {24{1'bX}};
+    reg  [31: 0] fmc_d_drive;
+    wire [31: 0] fmc_d_bidir;
+    reg          fmc_ne1 = 1'b1;
+    reg          fmc_noe = 1'b1;
+    reg          fmc_nwe = 1'b1;
+    reg          fmc_nl = 1'b1;
+    wire         fmc_nwait_dummy;
+
+    assign fmc_d_bidir = fmc_noe ? fmc_d_drive : 32'hZZZZZZZZ;
+
+    fmc_arbiter #(.NUM_ADDR_BITS(24))
+    uut
+    (
+        // fmc bus
+        .fmc_a     (fmc_a),
+        .fmc_d     (fmc_d_bidir),
+        .fmc_ne1   (fmc_ne1),
+        .fmc_nl    (fmc_nl),
+        .fmc_nwe   (fmc_nwe),
+        .fmc_noe   (fmc_noe),
+        .fmc_nwait (fmc_nwait_dummy),
+
+        // system clock, i/o clock
+        .io_clk  (io_clk),
+        .sys_clk (sys_clk),
+
+        // user bus
+        .sys_addr     (sys_fmc_addr),
+        .sys_wr_en    (sys_fmc_wren),
+        .sys_data_out (sys_fmc_dout),
+        .sys_rd_en    (sys_fmc_rden),
+        .sys_data_in  (sys_fmc_din)
+    );
+
+
+    //
+    // Core Selector
+    //
+    core_selector core_selector_inst
+    (
+        .sys_clk        (sys_clk),
+        .sys_rst_n      (sys_rst_n),
+
+        .sys_fmc_addr   (sys_fmc_addr),
+        .sys_fmc_wr     (sys_fmc_wren),
+        .sys_fmc_rd     (sys_fmc_rden),
+        .sys_read_data  (sys_fmc_din),
+        .sys_write_data (sys_fmc_dout),
+        .sys_error      (),
+    
+        .mkm_sclk       (),
+        .mkm_cs_n       (),
+        .mkm_do         (1'bZ),
+        .mkm_di         (),
+        
+        .core_clk       (core_clk),
+
+        .noise          (1'bZ),
+        .debug          ()
+    );
+
+
+    //
+    // "Random" Number Generator
+    //
+    reg [7:0] lfsr8;
+    
+    task lfsr8_next;
+        lfsr8 = {lfsr8[6:0], lfsr8[8-1] ^ lfsr8[6-1] ^ lfsr8[5-1] ^ lfsr8[4-1]};
+    endtask
+
+    task lfsr8_seed;
+        input [7:0] lfsr8_in;
+        lfsr8 = lfsr8_in;
+    endtask
+    
+    
+    //
+    // Helper Tasks
+    //
+    
+    //----------------------
+    task  wait_quarter_tick;
+    //----------------------
+        #FMC_CLOCK_PERIOD_QUARTER;
+    endtask
+
+    //------------------
+    task wait_half_tick;
+    //------------------
+        begin
+            wait_quarter_tick;
+            wait_quarter_tick;
+        end
+    endtask
+
+    //------------------
+    task wait_full_tick;
+    //------------------
+        begin
+            wait_half_tick;
+            wait_half_tick;
+        end
+    endtask
+
+    //----------------
+    task wait_n_ticks;
+    //----------------
+        input integer n;
+        integer i;
+        for (i=0; i<n; i=i+1)
+            wait_full_tick;
+    endtask
+
+    //-------------
+    task fmc_write;
+    //-------------
+        input [15: 0] core;
+        input [ 7: 0] offset;
+        input [31: 0] data;
+        begin
+            fmc_ne1 = 1'b0;                     // select
+            fmc_nl = 1'b0;                      // set latch flag
+            fmc_a = {core, offset};             // set address
+            fmc_nwe = 1'b0;                     // set write-enable
+            wait_full_tick();                   // mimic latency
+
+            fmc_nl = 1'b1;                      // clear latch flag
+            fmc_a = {24{1'bX}};                 // clear address
+            wait_n_ticks(STM32_FMC_LATENCY);    // mimic latency
+
+            fmc_d_drive = data;                 // set data            
+
+            wait_half_tick();                   // mimic latency
+            wait_quarter_tick();
+
+            fmc_ne1 = 1'b1;                     // deselect
+            fmc_nwe = 1'b1;                     // clear write-enable
+            fmc_d_drive = 32'hXXXXXXXX;         // clear data
+
+            wait_quarter_tick();                // finish clock period
+            wait_full_tick();                   // pause
+        end
+    endtask
+
+    //------------
+    task fmc_read;
+    //------------
+        input  [15: 0] core;
+        input  [ 7: 0] offset;
+        output [31: 0] data;
+        begin
+            fmc_ne1 = 1'b0;                     // select
+            fmc_nl = 1'b0;                      // set latch flag
+            fmc_a = {core, offset};             // set address
+
+            wait_full_tick();                   // mimic latency
+
+            fmc_nl = 1'b1;                      // clear latch flag
+            fmc_a = {24{1'bX}};                 // clear address
+            wait_full_tick();                   // mimic latency
+            fmc_noe = 1'b0;                     // tri-state bus
+            wait_n_ticks(STM32_FMC_LATENCY-1);  // mimic latency
+
+            wait_half_tick();                   // mimic latency
+            data = fmc_d_bidir;                 // sample data
+            wait_half_tick();                   // mimic latency
+            
+            wait_full_tick();                   // mimic latency
+            
+            wait_half_tick();                   // mimic latency
+            wait_quarter_tick();
+
+            fmc_ne1 = 1'b1;                     // deselect
+            fmc_noe = 1'b1;                     // drive bus
+
+            wait_quarter_tick();                // finish clock period
+            wait_full_tick();                   // pause
+        end
+    endtask
+    
+    //----------------
+    task gen_rnd_addr;
+    //----------------
+        output [31:0] addr;
+        reg [7:0] a, b, c;
+        begin
+            lfsr8_next; a = lfsr8;
+            lfsr8_next; b = lfsr8;
+            lfsr8_next; c = lfsr8;
+            addr = {a, b, c};
+        end
+    endtask
+    
+    //----------------
+    task gen_rnd_data;
+    //----------------
+        output [31:0] data;
+        reg [7:0] a, b, c, d;
+        begin
+            lfsr8_next; a = lfsr8;
+            lfsr8_next; b = lfsr8;
+            lfsr8_next; c = lfsr8;
+            lfsr8_next; d = lfsr8;
+            data = {a, b, c, d};
+        end
+    endtask
+
+    
+    //
+    // Script
+    //
+    reg [23:0] addr;
+    reg [31:0] data_wr;
+    reg [31:0] data_rd;
+    integer i;
+    initial begin
+
+        // let all signals initialize
+        wait_full_tick;
+
+        // wait for reset to complete
+        while (!sys_rst_n) begin
+            wait_full_tick;
+        end
+        
+        // wait some more time
+        wait_n_ticks(100);        
+
+        // do tests
+        lfsr8_seed(8'hA5);
+        for (i=0; i<NUM_TESTS; i=i+1) begin
+            gen_rnd_data(data_wr);
+            fmc_write(16'h0000, 8'd255, data_wr);
+            fmc_read(16'h0000, 8'd255, data_rd);
+            $display("Read %04d/%04d: 0x%x | 0x%x", i+1, NUM_TESTS, data_rd, data_wr);
+            if (data_rd !== data_wr) begin
+                $display("ERROR");
+                $finish;
+            end
+            gen_rnd_data(data_wr);
+            fmc_write(16'h0037, 8'd15, data_wr);
+            fmc_read(16'h0037, 8'd15, data_rd);
+            $display("                0x%x | 0x%x", data_rd, data_wr);
+            if (data_rd !== data_wr) begin
+                $display("ERROR");
+                $finish;
+            end
+        end
+        
+        $display("All tests passed. [OK]");
+        $finish;
+
+    end
+    
+        
+endmodule
+
+
+//------------------------------------------------------------------------------
+// End-of-File
+//------------------------------------------------------------------------------



More information about the Commits mailing list