//------------------------------------------------------------------------------ // // tb_fmc.v // ----------------------------------------------------------------------------- // Testbench for fixed latency FMC arbiter. // // Authors: Pavel Shatov // // Copyright 2018 NORDUnet A/S // Copyright 2020-2021 The Commons Conservancy Cryptech Project // SPDX-License-Identifier: BSD-3-Clause // // 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 copyright holder 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; // // Settings // localparam NUM_TESTS = 100; 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; reg [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) ); // // "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