349dea5a6cd06589b0497a3f315f84cc51bf502b
[DuneNvme.git] / src / DuneNvmeTestTop.vhd
1 --------------------------------------------------------------------------------
2 -- DuneNvmeTestTop.vhd Simple NVMe access test system
3 --------------------------------------------------------------------------------
4 --!
5 --! @class      DuneNvmeTestTop
6 --! @author     Terry Barnaby (terry.barnaby@beam.ltd.uk)
7 --! @date       2020-05-12
8 --! @version    0.5.1
9 --!
10 --! @brief
11 --! This FPGA bit file allows a host computer to access a NVMe storage device
12 --!  connected to the FPGA via the hosts PCIe interface. It allows a host computer
13 --!  program to communicate with the NVMe device for research and developemnt test work.
14 --!
15 --! @details
16 --!
17 --! @copyright GNU GPL License
18 --! Copyright (c) Beam Ltd, All rights reserved. <br>
19 --! This code is free software: you can redistribute it and/or modify
20 --! it under the terms of the GNU General Public License as published by
21 --! the Free Software Foundation, either version 3 of the License, or
22 --! (at your option) any later version.
23 --! This program is distributed in the hope that it will be useful,
24 --! but WITHOUT ANY WARRANTY; without even the implied warranty of
25 --! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26 --! GNU General Public License for more details. <br>
27 --! You should have received a copy of the GNU General Public License
28 --! along with this code. If not, see <https://www.gnu.org/licenses/>.
29 --!
30 library ieee;
31 use ieee.std_logic_1164.all;
32 use ieee.numeric_std.all;
33
34 library unisim;
35 use unisim.vcomponents.all;
36
37 library work;
38 use work.NvmeStoragePkg.all;
39
40 entity DuneNvmeTestTop is
41 generic(
42         Simulate        : boolean       := False
43 );
44 port (
45         sys_clk_p       : in std_logic;
46         sys_clk_n       : in std_logic;
47         sys_reset       : in std_logic;
48
49         pci_clk_p       : in std_logic;
50         pci_clk_n       : in std_logic;
51         pci_reset_n     : in std_logic;
52         
53         pci_exp_txp     : out std_logic_vector(3 downto 0);
54         pci_exp_txn     : out std_logic_vector(3 downto 0);
55         pci_exp_rxp     : in std_logic_vector(3 downto 0);
56         pci_exp_rxn     : in std_logic_vector(3 downto 0);
57
58         nvme_clk_p      : in std_logic;
59         nvme_clk_n      : in std_logic;
60         nvme_reset_n    : out std_logic;
61
62         nvme0_exp_txp   : out std_logic_vector(3 downto 0);
63         nvme0_exp_txn   : out std_logic_vector(3 downto 0);
64         nvme0_exp_rxp   : in std_logic_vector(3 downto 0);
65         nvme0_exp_rxn   : in std_logic_vector(3 downto 0);
66
67         nvme1_exp_txp   : out std_logic_vector(3 downto 0);
68         nvme1_exp_txn   : out std_logic_vector(3 downto 0);
69         nvme1_exp_rxp   : in std_logic_vector(3 downto 0);
70         nvme1_exp_rxn   : in std_logic_vector(3 downto 0);
71
72         leds            : out std_logic_vector(7 downto 0)
73 );
74 end;
75
76 architecture Behavioral of DuneNvmeTestTop is
77
78 component Clk_core is                   
79 port (
80         clk_in1_p       : in std_logic; 
81         clk_in1_n       : in std_logic;
82         clk_out1        : out std_logic;
83         locked          : out std_logic
84 );                                     
85 end component;                 
86
87 component Pcie_host
88 port (
89         sys_clk : in std_logic;
90         sys_clk_gt : in std_logic;
91         sys_rst_n : in std_logic;
92         user_lnk_up : out std_logic;
93         pci_exp_txp : out std_logic_vector(3 downto 0);
94         pci_exp_txn : out std_logic_vector(3 downto 0);
95         pci_exp_rxp : in std_logic_vector(3 downto 0);
96         pci_exp_rxn : in std_logic_vector(3 downto 0);
97         axi_aclk : out std_logic;
98         axi_aresetn : out std_logic;
99         usr_irq_req : in std_logic_vector(0 downto 0);
100         usr_irq_ack : out std_logic_vector(0 downto 0);
101         msi_enable : out std_logic;
102         msi_vector_width : out std_logic_vector(2 downto 0);
103         m_axil_awaddr : out std_logic_vector(31 downto 0);
104         m_axil_awprot : out std_logic_vector(2 downto 0);
105         m_axil_awvalid : out std_logic;
106         m_axil_awready : in std_logic;
107         m_axil_wdata : out std_logic_vector(31 downto 0);
108         m_axil_wstrb : out std_logic_vector(3 downto 0);
109         m_axil_wvalid : out std_logic;
110         m_axil_wready : in std_logic;
111         m_axil_bvalid : in std_logic;
112         m_axil_bresp : in std_logic_vector(1 downto 0);
113         m_axil_bready : out std_logic;
114         m_axil_araddr : out std_logic_vector(31 downto 0);
115         m_axil_arprot : out std_logic_vector(2 downto 0);
116         m_axil_arvalid : out std_logic;
117         m_axil_arready : in std_logic;
118         m_axil_rdata : in std_logic_vector(31 downto 0);
119         m_axil_rresp : in std_logic_vector(1 downto 0);
120         m_axil_rvalid : in std_logic;
121         m_axil_rready : out std_logic;
122         cfg_mgmt_addr : in std_logic_vector(18 downto 0);
123         cfg_mgmt_write : in std_logic;
124         cfg_mgmt_write_data : in std_logic_vector(31 downto 0);
125         cfg_mgmt_byte_enable : in std_logic_vector(3 downto 0);
126         cfg_mgmt_read : in std_logic;
127         cfg_mgmt_read_data : out std_logic_vector(31 downto 0);
128         cfg_mgmt_read_write_done : out std_logic;
129         cfg_mgmt_type1_cfg_reg_access : in std_logic;
130         s_axis_c2h_tdata_0 : in std_logic_vector(127 downto 0);
131         s_axis_c2h_tlast_0 : in std_logic;
132         s_axis_c2h_tvalid_0 : in std_logic;
133         s_axis_c2h_tready_0 : out std_logic;
134         s_axis_c2h_tkeep_0 : in std_logic_vector(15 downto 0);
135         m_axis_h2c_tdata_0 : out std_logic_vector(127 downto 0);
136         m_axis_h2c_tlast_0 : out std_logic;
137         m_axis_h2c_tvalid_0 : out std_logic;
138         m_axis_h2c_tready_0 : in std_logic;
139         m_axis_h2c_tkeep_0 : out std_logic_vector(15 downto 0);
140
141         int_qpll1lock_out : out std_logic_vector(0 to 0);
142         int_qpll1outrefclk_out : out std_logic_vector(0 to 0);
143         int_qpll1outclk_out : out std_logic_vector(0 to 0)
144 );
145 end component;
146
147 -- Clock and controls
148 signal sys_clk                  : std_logic := 'U';
149
150 signal pci_clk                  : std_logic := 'U';
151 signal pci_clk_gt               : std_logic := 'U';
152 signal leds_l                   : std_logic_vector(7 downto 0) := (others => '0');
153
154 signal axil_clk                 : std_logic;
155 signal axil_reset_n             : std_logic;
156 signal axil_reset               : std_logic;
157
158 signal axil                     : AxilBusType;                  --! The AXI lite bus
159 signal hostSend                 : AxisType;                     --! AXI stream to send requests from the host
160 signal hostSend_ready           : std_logic;
161 signal hostRecv                 : AxisType;                     --! AXI stream for replies to the host
162 signal hostrecv_ready           : std_logic;
163 signal dataStream               : AxisDataStreamType;           --! AXI stream for test data
164 signal dataStream_ready         : std_logic;
165 signal dataEnabled              : std_logic;                    --! Enabled signal for test data
166
167 begin
168         -- System clock just used for a boot reset
169         sys_clk_buf : Clk_core port map (
170                 clk_in1_p       => sys_clk_p,
171                 clk_in1_n       => sys_clk_n,
172                 clk_out1        => sys_clk
173         );
174
175         -- PCIE Clock, 100MHz
176         pci_clk_buf0 : IBUFDS_GTE3 port map(
177                 I       => pci_clk_p,
178                 IB      => pci_clk_n,
179                 O       => pci_clk_gt,
180                 ODIV2   => pci_clk,
181                 CEB     => '0'
182         );
183         
184         -- The PCIe interface to the host
185         pcie_host0 : Pcie_host
186         port map (
187                 sys_clk                 => pci_clk,
188                 sys_clk_gt              => pci_clk_gt,
189                 sys_rst_n               => pci_reset_n,
190                 pci_exp_txp             => pci_exp_txp,
191                 pci_exp_txn             => pci_exp_txn,
192                 pci_exp_rxp             => pci_exp_rxp,
193                 pci_exp_rxn             => pci_exp_rxn,
194                 
195                 user_lnk_up             => leds_l(7),
196
197                 usr_irq_req             => (others => '0'),
198                 --usr_irq_ack           => usr_irq_ack,
199                 --msi_enable            => msi_enable,
200                 --msi_vector_width      => msi_vector_width,
201
202                 axi_aclk                => axil_clk,
203                 axi_aresetn             => axil_reset_n,
204
205                 m_axil_awaddr           => axil.toSlave.awaddr,
206                 m_axil_awprot           => axil.toSlave.awprot,
207                 m_axil_awvalid          => axil.toSlave.awvalid,
208                 m_axil_awready          => axil.toMaster.awready,
209                 m_axil_wdata            => axil.toSlave.wdata,
210                 m_axil_wstrb            => axil.toSlave.wstrb,
211                 m_axil_wvalid           => axil.toSlave.wvalid,
212                 m_axil_wready           => axil.toMaster.wready,
213                 m_axil_bvalid           => axil.toMaster.bvalid,
214                 m_axil_bresp            => axil.toMaster.bresp,
215                 m_axil_bready           => axil.toSlave.bready,
216                 m_axil_araddr           => axil.toSlave.araddr,
217                 m_axil_arprot           => axil.toSlave.arprot,
218                 m_axil_arvalid          => axil.toSlave.arvalid,
219                 m_axil_arready          => axil.toMaster.arready,
220                 m_axil_rdata            => axil.toMaster.rdata,
221                 m_axil_rresp            => axil.toMaster.rresp,
222                 m_axil_rvalid           => axil.toMaster.rvalid,
223                 m_axil_rready           => axil.toSlave.rready,
224                 
225                 cfg_mgmt_addr           => (others => '0'),
226                 cfg_mgmt_write          => '0',
227                 cfg_mgmt_write_data     => (others => '0'),
228                 cfg_mgmt_byte_enable    => (others => '0'),
229                 cfg_mgmt_read           => '0',
230                 --cfg_mgmt_read_data            => cfg_mgmt_read_data,
231                 --cfg_mgmt_read_write_done      => cfg_mgmt_read_write_done,
232                 cfg_mgmt_type1_cfg_reg_access   => '0',
233
234                 s_axis_c2h_tdata_0      => hostRecv.data,
235                 s_axis_c2h_tlast_0      => hostRecv.last,
236                 s_axis_c2h_tvalid_0     => hostRecv.valid,
237                 s_axis_c2h_tready_0     => hostRecv_ready,
238                 s_axis_c2h_tkeep_0      => hostRecv.keep,
239
240                 m_axis_h2c_tdata_0      => hostSend.data,
241                 m_axis_h2c_tlast_0      => hostSend.last,
242                 m_axis_h2c_tvalid_0     => hostSend.valid,
243                 m_axis_h2c_tready_0     => hostSend_ready,
244                 m_axis_h2c_tkeep_0      => hostSend.keep
245         );
246
247         -- NVME Storage interface
248         axil_reset <= not axil_reset_n;
249         
250         nvmeStorage0 : NvmeStorage
251         generic map (
252                 ClockPeriod     => 8 ns
253         )
254         port map (
255                 clk             => axil_clk,
256                 reset           => axil_reset,
257
258                 -- Control and status interface
259                 axilIn          => axil.toSlave,
260                 axilOut         => axil.toMaster,
261
262                 -- From host to NVMe request/reply streams
263                 hostSend        => hostSend,
264                 hostSend_ready  => hostSend_ready,
265                 hostRecv        => hostRecv,
266                 hostRecv_ready  => hostRecv_ready,
267
268                 -- AXIS data stream input
269                 dataDropBlocks  => '0',
270                 dataEnabledOut  => dataEnabled,
271                 dataIn          => dataStream,
272                 dataIn_ready    => dataStream_ready,
273
274                 -- NVMe interface
275                 nvme_clk_p      => nvme_clk_p,
276                 nvme_clk_n      => nvme_clk_n,
277                 nvme_reset_n    => nvme_reset_n,
278
279                 nvme0_exp_txp   => nvme0_exp_txp,
280                 nvme0_exp_txn   => nvme0_exp_txn,
281                 nvme0_exp_rxp   => nvme0_exp_rxp,
282                 nvme0_exp_rxn   => nvme0_exp_rxn,
283
284                 nvme1_exp_txp   => nvme1_exp_txp,
285                 nvme1_exp_txn   => nvme1_exp_txn,
286                 nvme1_exp_rxp   => nvme1_exp_rxp,
287                 nvme1_exp_rxn   => nvme1_exp_rxn,
288
289                 -- Debug
290                 leds            => leds_l(5 downto 0)
291         );
292
293         -- The test data interface
294         testData0 : TestData
295         port map (
296                 clk             => axil_clk,
297                 reset           => axil_reset,
298
299                 enable          => dataEnabled,
300
301                 dataOut         => dataStream,
302                 dataOutReady    => dataStream_ready
303         );
304
305         -- Led buffers
306         obuf_leds: for i in 0 to 7 generate
307                 obuf_led_i: OBUF port map (I => leds_l(i), O => leds(i));
308         end generate;
309
310         leds_l(6) <= '0';
311 end;
312