NvmeConfig: Updated to use latest NvmeQueue engine.
authorTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Sat, 6 Jun 2020 07:27:06 +0000 (08:27 +0100)
committerTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Sat, 6 Jun 2020 07:27:06 +0000 (08:27 +0100)
Test software updated for latest nvmeConfig.

src/DuneNvmeTestTop.vhd
src/NvmeConfig.vhd
test/NvmeAccess.cpp
test/test_nvme.cpp

index 5357234c44a08e428ab7dfd6497d71cab450e969..ef4902132d4f2e253d2384c687e991396a02949b 100644 (file)
@@ -267,6 +267,17 @@ begin
        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 => 134217728,                   --! The total number of 4k blocks available
+               NvmeRegStride   => 4                            --! The doorbell register stride
+       )
        port map (
                clk             => axil_clk,
                reset           => axil_reset,
index 6f438ddd669450335a434465584f301ba3b9e70f..6c053fb710f6053c441cb3688b49541fadf1b976 100644 (file)
@@ -4,7 +4,7 @@
 --!
 --! @class     NvmeConfig
 --! @author    Terry Barnaby (terry.barnaby@beam.ltd.uk)
---! @date      2020-05-12
+--! @date      2020-06-06
 --! @version   1.0.0
 --!
 --! @brief
@@ -80,14 +80,18 @@ signal state                : StateType := STATE_IDLE;
 
 --! The Configuration requests                         
 type RomType   is array(integer range <>) of std_logic_vector(127 downto 0);
-constant rom   : RomType(0 to 41) := (
+
+constant rom   : RomType(0 to 34) := (
        -- Set PCIe configuration command word
        setHeader(10, 16#00004#, 1, 0), to_stl(16#00010006#, 128),
        
+       -- Stop controller
+       setHeader(1, 16#0014#, 1, 0), to_stl(x"00460000", 128),
+
        -- Disable interrupts
        setHeader(1, 16#000C#, 1, 0), to_stl(x"FFFFFFFF", 128),
 
-       -- Admin queue lengths to 8 entries each
+       -- Admin queue lengths to NvmeQueueNum entries each
        setHeader(1, 16#0024#, 1, 0), zeros(96) & to_stl(NvmeQueueNum-1, 16) & to_stl(NvmeQueueNum-1, 16),
 
        -- Admin request queue base address
@@ -96,61 +100,49 @@ constant rom       : RomType(0 to 41) := (
        -- Admin reply queue base address
        setHeader(1, 16#0030#, 1, 0), to_stl(x"02100000", 128),
 
-       -- Create DataWrite reply queue (8 entries)  by sending 64byte request to Admin queue
-       setHeader(12, 16#02000000#, 16, 0),
-               zeros(96) & x"02000005",                                        -- Dwords 3, 2, 1, 0
+       -- Start controller
+       setHeader(1, 16#0014#, 1, 0), to_stl(x"00460001", 128),
+       
+       -- We should wait for CSTS.RDY. For simplicity we delay for 1ms between each command
+
+       -- Create DataWrite reply queue (16 entries)  by sending 64byte request to Admin queue
+       setHeader(1, 16#02000000#, 16, 0),
+               zeros(96) & x"03000005",                                        -- Dwords 3, 2, 1, 0
                zeros(32) & x"02110000" & zeros(64),                            -- DWords 7, 6, 5, 4
                x"00000001" & to_stl(NvmeQueueNum-1, 16) & x"0001" & zeros(64), -- DWords 11, 10, 9, 8
                zeros(128),                                                     -- DWords 15, 14, 13, 12
 
-       -- Notify queue entry to Nvme
-       setHeader(1, 16#1000#, 1, 0), to_stl(1, 128),
-       
        -- Could Wait for reply in queue
 
        -- Create DataWrite request queue by sending 64byte request to Admin queue
-       setHeader(12, 16#02000000#, 16, 0),
-               zeros(96) & x"02000001",                                        -- Dwords 3, 2, 1, 0
+       setHeader(1, 16#02000000#, 16, 0),
+               zeros(96) & x"03010001",                                        -- Dwords 3, 2, 1, 0
                zeros(32) & x"02010000" & zeros(64),                            -- DWords 7, 6, 5, 4
                x"00010001" & to_stl(NvmeQueueNum-1, 16) & x"0001" & zeros(64), -- DWords 11, 10, 9, 8
                zeros(128),                                                     -- DWords 15, 14, 13, 12
 
-       -- Notify queue entry to Nvme
-       setHeader(1, 16#1000#, 1, 0), to_stl(2, 128),
-       
        -- Could Wait for reply in queue
        
-       -- Create DataRead reply queue (8 entries)  by sending 64byte request to Admin queue
-       setHeader(12, 16#02000000#, 16, 0),
-               zeros(96) & x"02000005",                                        -- Dwords 3, 2, 1, 0
+       -- Create DataRead reply queue (16 entries)  by sending 64byte request to Admin queue
+       setHeader(1, 16#02000000#, 16, 0),
+               zeros(96) & x"03020005",                                        -- Dwords 3, 2, 1, 0
                zeros(32) & x"02120000" & zeros(64),                            -- DWords 7, 6, 5, 4
                x"00000001" & to_stl(NvmeQueueNum-1, 16) & x"0002" & zeros(64), -- DWords 11, 10, 9, 8
                zeros(128),                                                     -- DWords 15, 14, 13, 12
 
-       -- Notify queue entry to Nvme
-       setHeader(1, 16#1000#, 1, 0), to_stl(1, 128),
-       
        -- Could Wait for reply in queue
 
        -- Create DataRead request queue by sending 64byte request to Admin queue
-       setHeader(12, 16#02000000#, 16, 0),
-               zeros(96) & x"02000001",                                        -- Dwords 3, 2, 1, 0
+       setHeader(1, 16#02000000#, 16, 0),
+               zeros(96) & x"03030001",                                        -- Dwords 3, 2, 1, 0
                zeros(32) & x"02020000" & zeros(64),                            -- DWords 7, 6, 5, 4
                x"00020001" & to_stl(NvmeQueueNum-1, 16) & x"0002" & zeros(64), -- DWords 11, 10, 9, 8
                zeros(128),                                                     -- DWords 15, 14, 13, 12
 
-       -- Notify queue entry to Nvme
-       setHeader(1, 16#1000#, 1, 0), to_stl(2, 128),
-       
        -- Could Wait for reply in queue
 
-       -- Start controller
-       setHeader(1, 16#0014#, 1, 0), to_stl(x"00460001", 128),
-
-       (others => '0'),
        (others => '0')
-       );
-
+);
 
 signal requestHead     : PcieRequestHeadType;                  --! The PCIe TLP request header fields
 signal tag             : unsigned(7 downto 0);
@@ -158,7 +150,6 @@ signal count                : integer range 0 to rom'length;        --! The ROM position pointer
 signal numWords                : unsigned(10 downto 0);                --! The number of 32 bit data words left to transfer
 signal delay           : integer;                              --! Delay counter in clock periods
 
-
 begin
        streamIn.ready  <= '1';                                 --! Ignore any replies
        requestHead     <= to_PcieRequestHeadType(rom(count));
@@ -224,7 +215,8 @@ begin
                                        count           <= count + 1;
                                        streamOut.valid <= '0';
                                        streamOut.last  <= '0';
-                                       state           <= STATE_NEXT_ITEM;
+                                       delay           <= 1 ms / ClockPeriod;
+                                       state           <= STATE_DELAY;
 
                                end case;
                        end if;
index e15035e4ed1aa3b30a5b5a4ed7d809456524329f..0dca3b6a0ccb3b89af37d5d239bfc0451ba6f472 100644 (file)
@@ -192,14 +192,14 @@ void NvmeAccess::reset(){
 
        printf("Last status was: %8.8x\n", data);
        
-       if(UseConfigEngine){
+       if(UseFpgaConfigure){
                data = 0;
-               while((data & 4) == 0){
+               while((data & 2) == 0){
                        data = readNvmeStorageReg(RegStatus);
                        usleep(1000);
                }
                te = getTime();
-               printf("Full Reset time was: %f ms\n", (te - ts) * 1000);
+               printf("Reset plus Config time was: %f ms\n", (te - ts) * 1000);
 
                usleep(100000);
                printf("Last status was: %8.8x\n", data);
@@ -215,7 +215,7 @@ void NvmeAccess::reset(){
 
        if(UseFpgaConfigure){
                data = 1;
-               while(data & 3){
+               while((data & 3) != 2){
                        data = readNvmeStorageReg(8);
                        usleep(1000);
                }
index 34fee12f433e5e5f0791ac1d4147e7d03d5eebb7..2da5958b851d01925a44d58b4ddad39eba754ead 100644 (file)
@@ -208,9 +208,9 @@ int Control::nvmeConfigure(){
                uprintf("Start configuration\n");
                writeNvmeStorageReg(4, 0x00000002);
 
-               data = 2;
-               while(data & 2){
-                       data = readNvmeStorageReg(8);
+               data = 0;
+               while(! (data & 2)){
+                       data = readNvmeStorageReg(RegStatus);
                        usleep(1000);
                }
                uprintf("Configuration complete: Status: %8.8x\n", readNvmeStorageReg(RegStatus));
@@ -299,7 +299,7 @@ int Control::nvmeConfigure(){
                }
                
                // Wait for Nvme to start
-               usleep(100000);
+               usleep(10000);
 
                //dumpNvmeRegisters();
 
@@ -340,7 +340,6 @@ int Control::nvmeConfigure(){
                        nvmeRequest(1, 0, 0x01, 0x01020000, cmd0 | 2, 0x00020001);
                }
        }
-
        // Make sure all is settled
        usleep(100000);
 
@@ -468,7 +467,7 @@ void Control::nvmeDataPacket(NvmeRequestPacket& packet){
 
        // Check if the last block of a Nvme read operation     
        if(oblockNum >= oreadNumBlocks){
-               printf("Read complete at: %u\n", oreadNumBlocks);
+               printf("Read complete at: %u blocks\n", oreadNumBlocks);
                oreadComplete.set();
        }
 }