Added support for the Ospero OP47 NVMe board. This is untested as yet.
authorTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Sat, 13 Jun 2020 08:37:43 +0000 (09:37 +0100)
committerTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Sat, 13 Jun 2020 08:37:43 +0000 (09:37 +0100)
Test software: Improvements and script changes for testing Samsung 570 Pro.

14 files changed:
.gitignore
docsrc/DuneNvmeStorageDesign.odt
docsrc/DuneNvmeStorageManual.odt
docsrc/DuneNvmeStorageTestSoftware.odt
src/DuneNvmeTestOpseroTop.vhd [new file with mode: 0644]
src/DuneNvmeTestOpseroTop.xdc [new file with mode: 0644]
src/DuneNvmeTestTop.vhd
src/DuneNvmeTestTop.xdc
test/test.sh
test/test_deallocate.sh
test/test_nvme.cpp
vivado/Config-template.mk [new file with mode: 0644]
vivado/Makefile
vivado/Vivado.mk

index f6ad210114083a9748cc623e9981934bae998535..1c4515368a44d24768c701b2631ef587b8d1d1f6 100644 (file)
@@ -4,3 +4,4 @@ doc/DuneNvmeStorageProject.pdf
 doc/fpga/
 doc/host/
 docsrc/.configured
+vivado/Config.mk
index ad308456dad8ea6eeb8c55270c0910439241a424..9d42c03c5d7482fe6d83551c93bf6d2b9285e5fa 100644 (file)
Binary files a/docsrc/DuneNvmeStorageDesign.odt and b/docsrc/DuneNvmeStorageDesign.odt differ
index a90c388c3aaa35cbe5cdaeb6421d6df6d159c19a..e5b0bdcb7384eecc858769d14b1897aa0ec7f315 100644 (file)
Binary files a/docsrc/DuneNvmeStorageManual.odt and b/docsrc/DuneNvmeStorageManual.odt differ
index a4c3c5f2dba56fe80c55dd54ac58f5647f01ce10..c343f14ddd78fe06653fdabce4b68a6068687100 100644 (file)
Binary files a/docsrc/DuneNvmeStorageTestSoftware.odt and b/docsrc/DuneNvmeStorageTestSoftware.odt differ
diff --git a/src/DuneNvmeTestOpseroTop.vhd b/src/DuneNvmeTestOpseroTop.vhd
new file mode 100644 (file)
index 0000000..0b9ce3e
--- /dev/null
@@ -0,0 +1,361 @@
+--------------------------------------------------------------------------------
+-- DuneNvmeTestTop.vhd Simple NVMe access test system
+--------------------------------------------------------------------------------
+--!
+--! @class     DuneNvmeTestOsperoTop
+--! @author    Terry Barnaby (terry.barnaby@beam.ltd.uk)
+--! @date      2020-05-12
+--! @version   1.0.0
+--!
+--! @brief
+--! This module implements a complete test design for the NvmeStorage system with
+--! the KCU104 and Ospero OP47 boards.
+--!
+--! @details
+--! The FPGA bit file produced allows a host computer to access a NVMe storage device
+--! connected to the FPGA via the hosts PCIe interface. It has a simple test data source
+--! and allows a host computer program to communicate with the NVMe device for research
+--! and development test work.
+--! See the DuneNvmeStorageManual for more details.
+--! 
+--!
+--! @copyright GNU GPL License
+--! Copyright (c) Beam Ltd, All rights reserved. <br>
+--! This code is free software: you can redistribute it and/or modify
+--! it under the terms of the GNU General Public License as published by
+--! the Free Software Foundation, either version 3 of the License, or
+--! (at your option) any later version.
+--! This program is distributed in the hope that it will be useful,
+--! but WITHOUT ANY WARRANTY; without even the implied warranty of
+--! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--! GNU General Public License for more details. <br>
+--! You should have received a copy of the GNU General Public License
+--! along with this code. If not, see <https://www.gnu.org/licenses/>.
+--!
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library unisim;
+use unisim.vcomponents.all;
+
+library work;
+use work.NvmeStoragePkg.all;
+
+entity DuneNvmeTestTop is
+generic(
+       Simulate        : boolean       := False
+);
+port (
+       sys_clk_p       : in std_logic;
+       sys_clk_n       : in std_logic;
+       sys_reset       : in std_logic;
+
+       pci_clk_p       : in std_logic;
+       pci_clk_n       : in std_logic;
+       pci_reset_n     : in std_logic;
+       
+       pci_exp_txp     : out std_logic_vector(3 downto 0);
+       pci_exp_txn     : out std_logic_vector(3 downto 0);
+       pci_exp_rxp     : in std_logic_vector(3 downto 0);
+       pci_exp_rxn     : in std_logic_vector(3 downto 0);
+
+       nvme0_clk_p     : in std_logic;
+       nvme0_clk_n     : in std_logic;
+       nvme0_reset_n   : out std_logic;
+
+       nvme0_exp_txp   : out std_logic_vector(3 downto 0);
+       nvme0_exp_txn   : out std_logic_vector(3 downto 0);
+       nvme0_exp_rxp   : in std_logic_vector(3 downto 0);
+       nvme0_exp_rxn   : in std_logic_vector(3 downto 0);
+
+       nvme1_clk_p     : in std_logic;
+       nvme1_clk_n     : in std_logic;
+       nvme1_reset_n   : out std_logic;
+
+       nvme1_exp_txp   : out std_logic_vector(3 downto 0);
+       nvme1_exp_txn   : out std_logic_vector(3 downto 0);
+       nvme1_exp_rxp   : in std_logic_vector(3 downto 0);
+       nvme1_exp_rxn   : in std_logic_vector(3 downto 0);
+
+       leds            : out std_logic_vector(7 downto 0)
+);
+end;
+
+architecture Behavioral of DuneNvmeTestTop is
+
+component Clk_core is                   
+port (
+       clk_in1_p       : in std_logic; 
+       clk_in1_n       : in std_logic;
+       clk_out1        : out std_logic;
+       locked          : out std_logic
+);                                     
+end component;                 
+
+--! @class     Pcie_host
+--! @brief     The Xilinx PCIe XDMA endpoint for host communications with the FPGA
+--! @details   See the Xilinx documentation for details of this IP block
+component Pcie_host
+port (
+       sys_clk : in std_logic;
+       sys_clk_gt : in std_logic;
+       sys_rst_n : in std_logic;
+       user_lnk_up : out std_logic;
+       pci_exp_txp : out std_logic_vector(3 downto 0);
+       pci_exp_txn : out std_logic_vector(3 downto 0);
+       pci_exp_rxp : in std_logic_vector(3 downto 0);
+       pci_exp_rxn : in std_logic_vector(3 downto 0);
+       axi_aclk : out std_logic;
+       axi_aresetn : out std_logic;
+       usr_irq_req : in std_logic_vector(0 downto 0);
+       usr_irq_ack : out std_logic_vector(0 downto 0);
+       msi_enable : out std_logic;
+       msi_vector_width : out std_logic_vector(2 downto 0);
+       m_axil_awaddr : out std_logic_vector(31 downto 0);
+       m_axil_awprot : out std_logic_vector(2 downto 0);
+       m_axil_awvalid : out std_logic;
+       m_axil_awready : in std_logic;
+       m_axil_wdata : out std_logic_vector(31 downto 0);
+       m_axil_wstrb : out std_logic_vector(3 downto 0);
+       m_axil_wvalid : out std_logic;
+       m_axil_wready : in std_logic;
+       m_axil_bvalid : in std_logic;
+       m_axil_bresp : in std_logic_vector(1 downto 0);
+       m_axil_bready : out std_logic;
+       m_axil_araddr : out std_logic_vector(31 downto 0);
+       m_axil_arprot : out std_logic_vector(2 downto 0);
+       m_axil_arvalid : out std_logic;
+       m_axil_arready : in std_logic;
+       m_axil_rdata : in std_logic_vector(31 downto 0);
+       m_axil_rresp : in std_logic_vector(1 downto 0);
+       m_axil_rvalid : in std_logic;
+       m_axil_rready : out std_logic;
+       cfg_mgmt_addr : in std_logic_vector(18 downto 0);
+       cfg_mgmt_write : in std_logic;
+       cfg_mgmt_write_data : in std_logic_vector(31 downto 0);
+       cfg_mgmt_byte_enable : in std_logic_vector(3 downto 0);
+       cfg_mgmt_read : in std_logic;
+       cfg_mgmt_read_data : out std_logic_vector(31 downto 0);
+       cfg_mgmt_read_write_done : out std_logic;
+       cfg_mgmt_type1_cfg_reg_access : in std_logic;
+       s_axis_c2h_tdata_0 : in std_logic_vector(127 downto 0);
+       s_axis_c2h_tlast_0 : in std_logic;
+       s_axis_c2h_tvalid_0 : in std_logic;
+       s_axis_c2h_tready_0 : out std_logic;
+       s_axis_c2h_tkeep_0 : in std_logic_vector(15 downto 0);
+       m_axis_h2c_tdata_0 : out std_logic_vector(127 downto 0);
+       m_axis_h2c_tlast_0 : out std_logic;
+       m_axis_h2c_tvalid_0 : out std_logic;
+       m_axis_h2c_tready_0 : in std_logic;
+       m_axis_h2c_tkeep_0 : out std_logic_vector(15 downto 0);
+
+       int_qpll1lock_out : out std_logic_vector(0 to 0);
+       int_qpll1outrefclk_out : out std_logic_vector(0 to 0);
+       int_qpll1outclk_out : out std_logic_vector(0 to 0)
+);
+end component;
+
+-- Clock and controls
+signal sys_clk                 : std_logic := 'U';
+
+signal pci_clk                 : std_logic := 'U';
+signal pci_clk_gt              : std_logic := 'U';
+signal nvme0_clk               : std_logic := 'U';
+signal nvme0_clk_gt            : std_logic := 'U';
+signal nvme1_clk               : std_logic := 'U';
+signal nvme1_clk_gt            : std_logic := 'U';
+signal nvme_reset_n            : std_logic := 'U';
+
+signal leds_l                  : std_logic_vector(7 downto 0) := (others => '0');
+
+signal axil_clk                        : std_logic;
+signal axil_reset_n            : std_logic;
+signal axil_reset              : std_logic;
+
+signal axil                    : AxilBusType;                  --! The AXI lite bus
+signal hostSend                        : AxisType;                     --! AXI stream to send requests from the host
+signal hostSend_ready          : std_logic;
+signal hostRecv                        : AxisType;                     --! AXI stream for replies to the host
+signal hostrecv_ready          : std_logic;
+signal dataStream              : AxisDataStreamType;           --! AXI stream for test data
+signal dataStream_ready                : std_logic;
+signal dataEnabled             : std_logic;                    --! Enabled signal for test data
+
+begin
+       -- System clock just used for a boot reset if needed
+       sys_clk_buf : Clk_core port map (
+               clk_in1_p       => sys_clk_p,
+               clk_in1_n       => sys_clk_n,
+               clk_out1        => sys_clk
+       );
+
+       -- PCIE Clock, 100MHz
+       pci_clk_buf0 : IBUFDS_GTE3 port map (
+               I       => pci_clk_p,
+               IB      => pci_clk_n,
+               O       => pci_clk_gt,
+               ODIV2   => pci_clk,
+               CEB     => '0'
+       );
+       
+       -- NVME0 PCIE Clock, 100MHz.
+       nvme_clk_buf0 : IBUFDS_GTE3 port map (
+               I       => nvme0_clk_p,
+               IB      => nvme0_clk_n,
+               O       => nvme0_clk_gt,
+               ODIV2   => nvme0_clk,
+               CEB     => '0'
+       );
+       
+       -- NVME1 PCIE Clock, 100MHz.
+       nvme_clk_buf1 : IBUFDS_GTE3 port map (
+               I       => nvme1_clk_p,
+               IB      => nvme1_clk_n,
+               O       => nvme1_clk_gt,
+               ODIV2   => nvme1_clk,
+               CEB     => '0'
+       );
+
+       nvme0_reset_n <= not nvme_reset_n;
+       nvme1_reset_n <= not nvme_reset_n;
+       
+       -- The PCIe interface to the host
+       pcie_host0 : Pcie_host
+       port map (
+               sys_clk                 => pci_clk,
+               sys_clk_gt              => pci_clk_gt,
+               sys_rst_n               => pci_reset_n,
+               pci_exp_txp             => pci_exp_txp,
+               pci_exp_txn             => pci_exp_txn,
+               pci_exp_rxp             => pci_exp_rxp,
+               pci_exp_rxn             => pci_exp_rxn,
+               
+               user_lnk_up             => leds_l(7),
+
+               usr_irq_req             => (others => '0'),
+               --usr_irq_ack           => usr_irq_ack,
+               --msi_enable            => msi_enable,
+               --msi_vector_width      => msi_vector_width,
+
+               axi_aclk                => axil_clk,
+               axi_aresetn             => axil_reset_n,
+
+               m_axil_awaddr           => axil.toSlave.awaddr,
+               m_axil_awprot           => axil.toSlave.awprot,
+               m_axil_awvalid          => axil.toSlave.awvalid,
+               m_axil_awready          => axil.toMaster.awready,
+               m_axil_wdata            => axil.toSlave.wdata,
+               m_axil_wstrb            => axil.toSlave.wstrb,
+               m_axil_wvalid           => axil.toSlave.wvalid,
+               m_axil_wready           => axil.toMaster.wready,
+               m_axil_bvalid           => axil.toMaster.bvalid,
+               m_axil_bresp            => axil.toMaster.bresp,
+               m_axil_bready           => axil.toSlave.bready,
+               m_axil_araddr           => axil.toSlave.araddr,
+               m_axil_arprot           => axil.toSlave.arprot,
+               m_axil_arvalid          => axil.toSlave.arvalid,
+               m_axil_arready          => axil.toMaster.arready,
+               m_axil_rdata            => axil.toMaster.rdata,
+               m_axil_rresp            => axil.toMaster.rresp,
+               m_axil_rvalid           => axil.toMaster.rvalid,
+               m_axil_rready           => axil.toSlave.rready,
+               
+               cfg_mgmt_addr           => (others => '0'),
+               cfg_mgmt_write          => '0',
+               cfg_mgmt_write_data     => (others => '0'),
+               cfg_mgmt_byte_enable    => (others => '0'),
+               cfg_mgmt_read           => '0',
+               --cfg_mgmt_read_data            => cfg_mgmt_read_data,
+               --cfg_mgmt_read_write_done      => cfg_mgmt_read_write_done,
+               cfg_mgmt_type1_cfg_reg_access   => '0',
+
+               s_axis_c2h_tdata_0      => hostRecv.data,
+               s_axis_c2h_tlast_0      => hostRecv.last,
+               s_axis_c2h_tvalid_0     => hostRecv.valid,
+               s_axis_c2h_tready_0     => hostRecv_ready,
+               s_axis_c2h_tkeep_0      => hostRecv.keep,
+
+               m_axis_h2c_tdata_0      => hostSend.data,
+               m_axis_h2c_tlast_0      => hostSend.last,
+               m_axis_h2c_tvalid_0     => hostSend.valid,
+               m_axis_h2c_tready_0     => hostSend_ready,
+               m_axis_h2c_tkeep_0      => hostSend.keep
+       );
+
+       -- NVME Storage interface
+       axil_reset <= not axil_reset_n;
+       
+       nvmeStorage0 : NvmeStorage
+       generic map (
+               Simulate        => False,                       --! Generate simulation core
+               Platform        => "Ultrascale",                --! The underlying target platform
+               ClockPeriod     => 4 ns,                        --! Clock period for timers (250 MHz)
+               BlockSize       => NvmeStorageBlockSize,        --! System block size
+               NumBlocksDrop   => 2,                           --! The number of blocks to drop at a time
+               UseConfigure    => False,                       --! The module configures the Nvme's on reset
+               NvmeBlockSize   => 512,                         --! The NVMe's formatted block size
+               NvmeTotalBlocks => 104857600,                   --! The total number of 4k blocks available (400G)
+               NvmeRegStride   => 4                            --! The doorbell register stride
+       )
+       port map (
+               clk             => axil_clk,
+               reset           => axil_reset,
+
+               -- Control and status interface
+               axilIn          => axil.toSlave,
+               axilOut         => axil.toMaster,
+
+               -- From host to NVMe request/reply streams
+               hostSend        => hostSend,
+               hostSend_ready  => hostSend_ready,
+               hostRecv        => hostRecv,
+               hostRecv_ready  => hostRecv_ready,
+
+               -- AXIS data stream input
+               dataDropBlocks  => '0',
+               dataEnabledOut  => dataEnabled,
+               dataIn          => dataStream,
+               dataIn_ready    => dataStream_ready,
+
+               -- NVMe interface
+               nvme_reset_n    => nvme_reset_n,
+
+               nvme0_clk       => nvme0_clk,
+               nvme0_clk_gt    => nvme0_clk_gt,
+               nvme0_exp_txp   => nvme0_exp_txp,
+               nvme0_exp_txn   => nvme0_exp_txn,
+               nvme0_exp_rxp   => nvme0_exp_rxp,
+               nvme0_exp_rxn   => nvme0_exp_rxn,
+
+               nvme1_clk       => nvme1_clk,
+               nvme1_clk_gt    => nvme1_clk_gt,
+               nvme1_exp_txp   => nvme1_exp_txp,
+               nvme1_exp_txn   => nvme1_exp_txn,
+               nvme1_exp_rxp   => nvme1_exp_rxp,
+               nvme1_exp_rxn   => nvme1_exp_rxn,
+
+               -- Debug
+               leds            => leds_l(5 downto 0)
+       );
+
+       -- The test data interface
+       testData0 : TestData
+       port map (
+               clk             => axil_clk,
+               reset           => axil_reset,
+
+               enable          => dataEnabled,
+
+               dataOut         => dataStream,
+               dataOutReady    => dataStream_ready
+       );
+
+       -- Led buffers
+       obuf_leds: for i in 0 to 7 generate
+               obuf_led_i: OBUF port map (I => leds_l(i), O => leds(i));
+       end generate;
+
+       leds_l(6) <= '0';
+end;
+
diff --git a/src/DuneNvmeTestOpseroTop.xdc b/src/DuneNvmeTestOpseroTop.xdc
new file mode 100644 (file)
index 0000000..0d8f6de
--- /dev/null
@@ -0,0 +1,172 @@
+###############################################################################\r
+#      DuneNvmeTestOsperoTop.xdc       Constraints for DuneNvmeTestTop on a KCU105\r
+#      T.Barnaby,      Beam Ltd.       2020-02-23\r
+###############################################################################\r
+#\r
+#\r
+# @class       DuneNvmeTestOsperoTop\r
+# @author      Terry Barnaby (terry.barnaby@beam.ltd.uk)\r
+# @date                2020-06-12\r
+# @version     0.9.0\r
+#\r
+# @brief\r
+# This module implements a complete test design for the NvmeStorage system with\r
+# the KCU104 and Ospero OP47 boards.\r
+#\r
+# @details\r
+# The FPGA bit file produced allows a host computer to access a NVMe storage device\r
+# connected to the FPGA via the hosts PCIe interface. It has a simple test data source\r
+# and allows a host computer program to communicate with the NVMe device for research\r
+# and development test work.\r
+# See the DuneNvmeStorageManual for more details.\r
+# \r
+#\r
+# @copyright GNU GPL License\r
+# Copyright (c) Beam Ltd, All rights reserved. <br>\r
+# This code is free software: you can redistribute it and/or modify\r
+# it under the terms of the GNU General Public License as published by\r
+# the Free Software Foundation, either version 3 of the License, or\r
+# (at your option) any later version.\r
+# This program is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+# GNU General Public License for more details. <br>\r
+# You should have received a copy of the GNU General Public License\r
+# along with this code. If not, see <https://www.gnu.org/licenses/>.\r
+#\r
+\r
+# System timings\r
+#create_clock -period 5.000 -name sys_clk_p -waveform {0.000 2.500} [get_ports sys_clk_p]\r
+create_clock -period 10.000 -name pci_clk [get_ports pci_clk_p]\r
+create_clock -period 10.000 -name nvme_clk [get_ports nvme_clk_p]\r
+\r
+# CDC crossings\r
+set_false_path -to [get_cells -hier sendCdcReg1*]\r
+set_false_path -to [get_cells -hier recvCdcReg1*]\r
+\r
+# Asynchronous resets\r
+set_false_path -from [get_ports sys_reset]\r
+set_false_path -from [get_ports pci_reset_n]\r
+set_false_path -through [get_nets -hier -filter {NAME=~ */nvmeStorageUnit*/reset_local}]\r
+#set_false_path -through [get_nets -hier -filter {NAME=~ */nvmeStorageUnit*/nvme_reset_local_n}]\r
+\r
+# Output pins\r
+set_output_delay -clock [get_clocks nvme_clk] -min 0.0 [get_ports -filter NAME=~nvme_reset_n]\r
+set_output_delay -clock [get_clocks nvme_clk] -max 1000.0 [get_ports -filter NAME=~nvme_reset_n]\r
+set_false_path -to [get_ports -filter NAME=~nvme_reset_n]\r
+\r
+set_output_delay -clock [get_clocks nvme_clk] -min 0.0 [get_ports -filter NAME=~leds*]\r
+set_output_delay -clock [get_clocks nvme_clk] -max 1000.0 [get_ports -filter NAME=~leds*]\r
+set_false_path -to [get_ports -filter NAME=~leds*]\r
+\r
+# General settings\r
+set_property CONFIG_VOLTAGE 1.8 [current_design]\r
+set_property CFGBVS GND [current_design]\r
+set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]\r
+\r
+# PCIe Host interface\r
+set_property PACKAGE_PIN K22 [get_ports pci_reset_n]\r
+set_property PULLUP true [get_ports pci_reset_n]\r
+set_property IOSTANDARD LVCMOS18 [get_ports pci_reset_n]\r
+set_property LOC GTHE3_COMMON_X0Y1 [get_cells pci_clk_buf0]\r
+\r
+# CPU Reset\r
+set_property PACKAGE_PIN AN8 [get_ports sys_reset]\r
+set_property PULLUP false [get_ports sys_reset]\r
+set_property IOSTANDARD LVCMOS18 [get_ports sys_reset]\r
+\r
+# LED's\r
+set_property IOSTANDARD LVCMOS18 [get_ports {leds[0]}]\r
+set_property IOSTANDARD LVCMOS18 [get_ports {leds[1]}]\r
+set_property IOSTANDARD LVCMOS18 [get_ports {leds[2]}]\r
+set_property IOSTANDARD LVCMOS18 [get_ports {leds[3]}]\r
+set_property IOSTANDARD LVCMOS18 [get_ports {leds[4]}]\r
+set_property IOSTANDARD LVCMOS18 [get_ports {leds[5]}]\r
+set_property IOSTANDARD LVCMOS18 [get_ports {leds[6]}]\r
+set_property IOSTANDARD LVCMOS18 [get_ports {leds[7]}]\r
+set_property DRIVE 12 [get_ports {leds[0]}]\r
+set_property DRIVE 12 [get_ports {leds[1]}]\r
+set_property DRIVE 12 [get_ports {leds[2]}]\r
+set_property DRIVE 12 [get_ports {leds[3]}]\r
+set_property DRIVE 12 [get_ports {leds[4]}]\r
+set_property DRIVE 12 [get_ports {leds[5]}]\r
+set_property DRIVE 12 [get_ports {leds[6]}]\r
+set_property DRIVE 12 [get_ports {leds[7]}]\r
+set_property SLEW SLOW [get_ports {leds[0]}]\r
+set_property SLEW SLOW [get_ports {leds[1]}]\r
+set_property SLEW SLOW [get_ports {leds[2]}]\r
+set_property SLEW SLOW [get_ports {leds[3]}]\r
+set_property SLEW SLOW [get_ports {leds[4]}]\r
+set_property SLEW SLOW [get_ports {leds[5]}]\r
+set_property SLEW SLOW [get_ports {leds[6]}]\r
+set_property SLEW SLOW [get_ports {leds[7]}]\r
+set_property PACKAGE_PIN AP8 [get_ports {leds[0]}]\r
+set_property PACKAGE_PIN H23 [get_ports {leds[1]}]\r
+set_property PACKAGE_PIN P20 [get_ports {leds[2]}]\r
+set_property PACKAGE_PIN P21 [get_ports {leds[3]}]\r
+set_property PACKAGE_PIN N22 [get_ports {leds[4]}]\r
+set_property PACKAGE_PIN M22 [get_ports {leds[5]}]\r
+set_property PACKAGE_PIN R23 [get_ports {leds[6]}]\r
+set_property PACKAGE_PIN P23 [get_ports {leds[7]}]\r
+\r
+# PCie Nvme0 interfaces\r
+set_property PACKAGE_PIN H11 [get_ports nvme0_reset_n]\r
+set_property IOSTANDARD LVCMOS18 [get_ports nvme0_reset_n]\r
+set_property PACKAGE_PIN K6 [get_ports {nvme0_clk_p}]\r
+set_property PACKAGE_PIN K5 [get_ports {nvme0_clk_n}]\r
+#set_property LOC GTHE3_COMMON_X0Y1 [get_cells nvme_clk_buf0]\r
+\r
+# PCIe Nvme0 PCIe lane interface\r
+set_property LOC GTHE3_CHANNEL_X0Y16 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*gen_gthe3_channel_inst[0].GTHE3_CHANNEL_PRIM_INST}]\r
+set_property LOC GTHE3_CHANNEL_X0Y17 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*gen_gthe3_channel_inst[1].GTHE3_CHANNEL_PRIM_INST}]\r
+set_property LOC GTHE3_CHANNEL_X0Y18 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*gen_gthe3_channel_inst[2].GTHE3_CHANNEL_PRIM_INST}]\r
+set_property LOC GTHE3_CHANNEL_X0Y19 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*gen_gthe3_channel_inst[3].GTHE3_CHANNEL_PRIM_INST}]\r
+\r
+set_property LOC PCIE_3_1_X0Y2 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/PCIE_3_1_inst}]\r
+set_property LOC RAMB36_X8Y57 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_rep_inst/bram_rep_8k_inst/RAMB36E2[0].ramb36e2_inst}]\r
+set_property LOC RAMB36_X8Y58 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_rep_inst/bram_rep_8k_inst/RAMB36E2[1].ramb36e2_inst}]\r
+set_property LOC RAMB18_X8Y98 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_req_inst/bram_req_8k_inst/RAMB18E2[0].ramb18e2_inst}]\r
+set_property LOC RAMB18_X8Y99 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_req_inst/bram_req_8k_inst/RAMB18E2[1].ramb18e2_inst}]\r
+set_property LOC RAMB18_X8Y100 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_req_inst/bram_req_8k_inst/RAMB18E2[2].ramb18e2_inst}]\r
+set_property LOC RAMB18_X8Y101 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_req_inst/bram_req_8k_inst/RAMB18E2[3].ramb18e2_inst}]\r
+set_property LOC RAMB18_X8Y104 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_cpl_inst/CPL_FIFO_16KB.bram_16k_inst/RAMB18E2[0].ramb18e2_inst}]\r
+set_property LOC RAMB18_X8Y105 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_cpl_inst/CPL_FIFO_16KB.bram_16k_inst/RAMB18E2[1].ramb18e2_inst}]\r
+set_property LOC RAMB18_X8Y106 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_cpl_inst/CPL_FIFO_16KB.bram_16k_inst/RAMB18E2[2].ramb18e2_inst}]\r
+set_property LOC RAMB18_X8Y107 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit0*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_cpl_inst/CPL_FIFO_16KB.bram_16k_inst/RAMB18E2[3].ramb18e2_inst}]\r
+\r
+# PCie Nvme1 interfaces\r
+set_property PACKAGE_PIN L12 [get_ports nvme1_reset_n]\r
+set_property IOSTANDARD LVCMOS18 [get_ports nvme1_reset_n]\r
+set_property PACKAGE_PIN H6 [get_ports {nvme1_clk_p}]\r
+set_property PACKAGE_PIN H5 [get_ports {nvme1_clk_n}]\r
+#set_property LOC GTHE3_COMMON_X0Y1 [get_cells nvme_clk_buf1]\r
+\r
+# PCIe Nvme1 PCIe lane interface\r
+set_property LOC GTHE3_CHANNEL_X0Y12 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*gen_gthe3_channel_inst[0].GTHE3_CHANNEL_PRIM_INST}]\r
+set_property LOC GTHE3_CHANNEL_X0Y14 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*gen_gthe3_channel_inst[1].GTHE3_CHANNEL_PRIM_INST}]\r
+set_property LOC GTHE3_CHANNEL_X0Y13 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*gen_gthe3_channel_inst[2].GTHE3_CHANNEL_PRIM_INST}]\r
+set_property LOC GTHE3_CHANNEL_X0Y15 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*gen_gthe3_channel_inst[3].GTHE3_CHANNEL_PRIM_INST}]\r
+\r
+set_property LOC PCIE_3_1_X0Y1 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/PCIE_3_1_inst}]\r
+\r
+set_property LOC RAMB36_X8Y45 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_rep_inst/bram_rep_8k_inst/RAMB36E2[0].ramb36e2_inst}]\r
+set_property LOC RAMB36_X8Y46 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_rep_inst/bram_rep_8k_inst/RAMB36E2[1].ramb36e2_inst}]\r
+set_property LOC RAMB18_X8Y74 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_req_inst/bram_req_8k_inst/RAMB18E2[0].ramb18e2_inst}]\r
+set_property LOC RAMB18_X8Y75 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_req_inst/bram_req_8k_inst/RAMB18E2[1].ramb18e2_inst}]\r
+set_property LOC RAMB18_X8Y76 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_req_inst/bram_req_8k_inst/RAMB18E2[2].ramb18e2_inst}]\r
+set_property LOC RAMB18_X8Y77 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_req_inst/bram_req_8k_inst/RAMB18E2[3].ramb18e2_inst}]\r
+set_property LOC RAMB18_X8Y80 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_cpl_inst/CPL_FIFO_16KB.bram_16k_inst/RAMB18E2[0].ramb18e2_inst}]\r
+set_property LOC RAMB18_X8Y81 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_cpl_inst/CPL_FIFO_16KB.bram_16k_inst/RAMB18E2[1].ramb18e2_inst}]\r
+set_property LOC RAMB18_X8Y82 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_cpl_inst/CPL_FIFO_16KB.bram_16k_inst/RAMB18E2[2].ramb18e2_inst}]\r
+set_property LOC RAMB18_X8Y83 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_cpl_inst/CPL_FIFO_16KB.bram_16k_inst/RAMB18E2[3].ramb18e2_inst}]\r
+\r
+#set_property LOC RAMB36_X8Y45 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_rep_inst/bram_rep_8k_inst/RAMB36E2[0].ramb36e2_inst}]\r
+#set_property LOC RAMB36_X8Y46 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_rep_inst/bram_rep_8k_inst/RAMB36E2[1].ramb36e2_inst}]\r
+#set_property LOC RAMB18_X8Y74 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_req_inst/bram_req_8k_inst/RAMB18E2[0].ramb18e2_inst}]\r
+#set_property LOC RAMB18_X8Y75 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_req_inst/bram_req_8k_inst/RAMB18E2[2].ramb18e2_inst}]\r
+#set_property LOC RAMB18_X8Y76 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_req_inst/bram_req_8k_inst/RAMB18E2[1].ramb18e2_inst}]\r
+#set_property LOC RAMB18_X8Y77 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_req_inst/bram_req_8k_inst/RAMB18E2[3].ramb18e2_inst}]\r
+#set_property LOC RAMB18_X8Y80 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_cpl_inst/CPL_FIFO_16KB.bram_16k_inst/RAMB18E2[0].ramb18e2_inst}]\r
+#set_property LOC RAMB18_X8Y81 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_cpl_inst/CPL_FIFO_16KB.bram_16k_inst/RAMB18E2[2].ramb18e2_inst}]\r
+#set_property LOC RAMB18_X8Y82 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_cpl_inst/CPL_FIFO_16KB.bram_16k_inst/RAMB18E2[1].ramb18e2_inst}]\r
+#set_property LOC RAMB18_X8Y83 [get_cells -hierarchical -filter {NAME =~ *nvmeStorageUnit1*pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/bram_inst/bram_cpl_inst/CPL_FIFO_16KB.bram_16k_inst/RAMB18E2[3].ramb18e2_inst}]\r
index 80b268dae2dd1e2f1db1f9166f1726e0ab06b087..83b76b6fcf1213c6023936fff151317f26c40ae5 100644 (file)
@@ -8,7 +8,8 @@
 --! @version   1.0.0
 --!
 --! @brief
---! This module implements a complete test design for the NvmeStorage system.
+--! This module implements a complete test design for the NvmeStorage system with
+--! the KCU104 and AB17-M2FMC boards.
 --!
 --! @details
 --! The FPGA bit file produced allows a host computer to access a NVMe storage device
index f530864f021e78d3c5954c2c7c990a22d0786fa2..eb8e82bb67bbb7c9d1d024969a4ab0899cc0593e 100644 (file)
@@ -3,6 +3,36 @@
 #      T.Barnaby,      Beam Ltd.       2020-02-23\r
 ###############################################################################\r
 #\r
+# @class       DuneNvmeTestOsperoTop\r
+# @author      Terry Barnaby (terry.barnaby@beam.ltd.uk)\r
+# @date                2020-06-12\r
+# @version     0.9.0\r
+#\r
+# @brief\r
+# This module implements a complete test design for the NvmeStorage system with\r
+# the KCU104 and AB17-M2FMC boards.\r
+#\r
+# @details\r
+# The FPGA bit file produced allows a host computer to access a NVMe storage device\r
+# connected to the FPGA via the hosts PCIe interface. It has a simple test data source\r
+# and allows a host computer program to communicate with the NVMe device for research\r
+# and development test work.\r
+# See the DuneNvmeStorageManual for more details.\r
+# \r
+#\r
+# @copyright GNU GPL License\r
+# Copyright (c) Beam Ltd, All rights reserved. <br>\r
+# This code is free software: you can redistribute it and/or modify\r
+# it under the terms of the GNU General Public License as published by\r
+# the Free Software Foundation, either version 3 of the License, or\r
+# (at your option) any later version.\r
+# This program is distributed in the hope that it will be useful,\r
+# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+# GNU General Public License for more details. <br>\r
+# You should have received a copy of the GNU General Public License\r
+# along with this code. If not, see <https://www.gnu.org/licenses/>.\r
+#\r
 \r
 # System timings\r
 #create_clock -period 5.000 -name sys_clk_p -waveform {0.000 2.500} [get_ports sys_clk_p]\r
index 7f55340192b897989f946e8e9164f6bd84231b72..5a3572acf4b1d03e6b85dad2b55f475662ae963e 100644 (file)
@@ -14,7 +14,32 @@ test1(){
 }
 
 test2(){
-       echo "Simple capture test loop: 200 GByte"
+       ./test_nvme -d 2 -s 0 -n 5242880 capture
+       ./test_nvme -nr -d 2 -s 0 -n 5242880 capture
+       #./test_nvme -v -nr -nv -d 2 -s 0 -n 8 read
+       ./test_nvme -v -nr -d 2 -s 0 -n 8 read
+}
+
+test3(){
+       echo "Simple capture test loop: 200 GByte no trim"
+
+       ./test_nvme -d 2 -s 0 -n 52428800 trim
+       ./test_nvme -nr -d 2 -s 52428800 -n 52428800 trim
+
+       # Let NVMe's perform some trimming
+       sleep 20
+
+       while true; do
+               ./test_nvme -nr -d 2 -s 0 -n 52428800 capture
+               sleep 10
+
+               ./test_nvme -nr -d 2 -s 52428800 -n 52428800 capture
+               sleep 10
+       done
+}
+
+test4(){
+       echo "Simple capture test loop: 200 GByte with trim"
 
        ./test_nvme -d 2 -s 0 -n 52428800 trim
        ./test_nvme -nr -d 2 -s 52428800 -n 52428800 trim
@@ -33,8 +58,8 @@ test2(){
        done
 }
 
-test2a(){
-       echo "Simple capture test loop: 200 GByte"
+test5(){
+       echo "Simple capture test loop: 200 GByte, with trim but no initial trim"
 
        #./test_nvme -d 2 -s 0 -n 52428800 trim
        #./test_nvme -nr -d 2 -s 52428800 -n 52428800 trim
@@ -54,13 +79,6 @@ test2a(){
        done
 }
 
-test3(){
-       ./test_nvme -d 2 -s 0 -n 5242880 capture
-       ./test_nvme -nr -d 2 -s 0 -n 5242880 capture
-       #./test_nvme -v -nr -nv -d 2 -s 0 -n 8 read
-       ./test_nvme -v -nr -d 2 -s 0 -n 8 read
-}
-
-test2a
+test3
 
 exit 0
index 86d2fc925657fdf4629da9c2d59c5943d752a0c1..01989d0ad387f122787abaf7da5211efa7a265ec 100644 (file)
@@ -108,12 +108,11 @@ test1(){
                ./test_nvme -nr -d 2 -s ${captureBlocks} -n ${captureBlocks} capture
 
                #delay=`expr $delay + $delay / 3`
-               #delay=`expr $delay + $delay / 3`
        done
 }
 
 test2(){
-       delay=280
+       delay=140
 
        # Initially allocate most of the drives blocks for worst case
        echo "Allocate most of the drives blocks initially"
@@ -142,7 +141,7 @@ test2(){
 
                ./test_nvme -nr -d 2 -s ${captureBlocks} -n ${captureBlocks} capture
 
-               delay=`expr $delay + $delay / 3`
+               #delay=`expr $delay + $delay / 3`
        done
 }
 
index 9d57c22e3884dea0e0e2dd57cb81567bde3ea4e6..d2d1892bf89758d89eee7beecae8ffe1b661a7b3 100644 (file)
@@ -656,7 +656,7 @@ int Control::nvmeCaptureRepeat(){
                }
 
                uprintf("Process time: %u\n", t);
-               tprintf("%8u ErrorStatus: 0x%x, StartBlock: %8u, DataRate: %.3f MBytes/s, PeakLatancy: %8u us\n", n, e, ostartBlock, r / (1024 * 1024), l);
+               tprintf("%8u ErrorStatus: 0x%x, StartBlock: %8u, DataRate: %.3f MBytes/s, PeakLatancy: %8u us\n", n, e, startBlock, r / (1024 * 1024), l);
 
                if(e){
                        printf("Error status: 0x%x, aborted\n", e);
@@ -1041,6 +1041,9 @@ int Control::test1(){
 
        printf("Test1: Simple PCIe command register read, write and read.\n");
 
+       reset();
+       start();
+       
        printf("Configure PCIe for memory accesses\n");
        pcieRead(8, 4, 1, data);
        dl1printf("Commandreg: %8.8x\n", data[0]);
@@ -1051,6 +1054,7 @@ int Control::test1(){
        pcieRead(8, 4, 1, data);
        dl1printf("Commandreg: %8.8x\n", data[0]);
 
+       dumpNvmeRegisters();
        printf("Complete\n");
 
        return 0;
diff --git a/vivado/Config-template.mk b/vivado/Config-template.mk
new file mode 100644 (file)
index 0000000..36fbde2
--- /dev/null
@@ -0,0 +1,8 @@
+################################################################################
+#      Config.mk       DuneNvme Beam build configuration
+#                      T.Barnaby,      BEAM Ltd,       2020-05-21
+################################################################################
+#
+FPGA_TOP       = DuneNvmeTestOsperoTop
+VIVADO_PATH    = /opt/Xilinx/Vivado/2019.2/bin
+VIVADO_TARGET  = ""
index db2ecb3763386d9ac3aa4c7bd3c4871628cebaab..24feee0b1f912119fde36c0514fb8443f11b8967 100644 (file)
 PROJECT        = nvme-test
 BOARD          = xilinx.com:kcu105:part0:1.6
 FPGA_PART      = xcku040-ffva1156-2-e
-FPGA_TOP       = DuneNvmeTestTop
+FPGA_TOP       ?= DuneNvmeTestTop
 VIVADO_PATH    ?= /opt/Xilinx/Vivado/2019.2/bin
 VIVADO_TARGET  ?= ""
 
+-include Config.mk
+
 # Files for synthesis
 SYN_FILES      = ../src/NvmeStoragePkg.vhd ../src/NvmeStorageIntPkg.vhd
 SYN_FILES      += ../src/Ram.vhd ../src/Fifo.vhd ../src/Cdc.vhd
@@ -35,7 +37,7 @@ SYN_FILES     += ../src/NvmeRead.vhd
 SYN_FILES      += ../src/NvmeStorageUnit.vhd
 SYN_FILES      += ../src/NvmeStorage.vhd
 SYN_FILES      += ../src/TestData.vhd
-SYN_FILES      += ../src/DuneNvmeTestTop.vhd
+SYN_FILES      += ../src/${FPGA_TOP}.vhd
 
 # IP cores
 XCI_FILES      = ../src/ip/Clk_core.xci
@@ -46,9 +48,8 @@ XCI_FILES     += ../src/ip/Pcie_nvme0.xci
 XCI_FILES      += ../src/ip/Pcie_nvme1.xci
 
 # XDC files
-XDC_FILES      = ../src/DuneNvmeTestTop.xdc
+XDC_FILES      = ../src/${FPGA_TOP}.xdc
 
--include Config.mk
 include Vivado.mk
 
 sync_ip:
index e7b913f97dc006c6f490b8f1e19d1fc96cb85323..c44999a5036d0acfb5fb81b584d30eab05baef24 100644 (file)
@@ -50,7 +50,7 @@ distclean: clean
        -rm -rf rev
 
 # Vivado project file
-${PROJECT}.xpr: Makefile $(XCI_FILES)
+${PROJECT}.xpr: Makefile Config.mk $(XCI_FILES)
        rm -rf defines.v
        touch defines.v
        for x in $(DEFS); do echo '`define' $$x >> defines.v; done