Set default available blocks to 400G.
authorTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Sat, 6 Jun 2020 10:05:36 +0000 (11:05 +0100)
committerTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Sat, 6 Jun 2020 10:05:36 +0000 (11:05 +0100)
Test software added captureRepeat test.
Code tidy ups.

src/DuneNvmeTestTop.vhd
src/NvmeStorage.vhd
src/NvmeStorageUnit.vhd
test/test_nvme.cpp

index ef4902132d4f2e253d2384c687e991396a02949b..80b268dae2dd1e2f1db1f9166f1726e0ab06b087 100644 (file)
@@ -275,7 +275,7 @@ begin
                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
+               NvmeTotalBlocks => 104857600,                   --! The total number of 4k blocks available (400G)
                NvmeRegStride   => 4                            --! The doorbell register stride
        )
        port map (
index 24bea15b4d657098b4880e957ab29824fa7d56a6..cd5143eaa5449f13f1e4ddc315e92e099b941b17 100644 (file)
@@ -58,7 +58,7 @@ generic(
        NumBlocksDrop   : integer       := 2;                           --! The number of blocks to drop at a time
        UseConfigure    : boolean       := False;                       --! The module configures the Nvme's on reset
        NvmeBlockSize   : integer       := 512;                         --! The NVMe's formatted block size
-       NvmeTotalBlocks : integer       := 134217728;                   --! The total number of 4k blocks available
+       NvmeTotalBlocks : integer       := 104857600;                   --! The total number of 4k blocks available (400 G)
        NvmeRegStride   : integer       := 4                            --! The doorbell register stride
 );
 port (
index 387a0fb51dfc75a6495216aac6930483248555a7..33672165d30eaa0cfadf09e361920fc69df658b4 100644 (file)
@@ -62,7 +62,7 @@ generic(
        PcieCore        : integer       := 0;                   --! The Pcie hardblock block to use
        UseConfigure    : boolean       := False;               --! The module configures the Nvme's on reset
        NvmeBlockSize   : integer       := 512;                 --! The NVMe's formatted block size
-       NvmeTotalBlocks : integer       := 134217728;           --! The total number of 4k blocks available
+       NvmeTotalBlocks : integer       := 104857600;           --! The total number of 4k blocks available (400G)
        NvmeRegStride   : integer       := 4                    --! The doorbell register stride
 );
 port (
@@ -785,7 +785,6 @@ begin
        end generate;
        
        -- Full switched communications
-       gen03: if true generate
        set1: for i in 7 to 7 generate
                streamSend(i).valid     <= '0';
                streamRecv(i).ready     <= '1';
@@ -883,6 +882,4 @@ begin
                regDataIn       => regDataIn1,
                regDataOut      => reg_nvmeRead
        );
-
-       end generate;
 end;
index 2da5958b851d01925a44d58b4ddad39eba754ead..daa6c65a02941974b65c95c481fe06aad86fac35 100644 (file)
@@ -70,6 +70,7 @@ public:
 
        // Normal test functions
        int             nvmeCapture();                          ///< Capture FPGA datastream writing to Nvme
+       int             nvmeCaptureRepeat();                    ///< Capture FPGA datastream writing to Nvme multiple times
        int             nvmeRead();                             ///< Read blocks from Nvme
        int             nvmeCaptureAndRead();                   ///< Capture FPGA datastream writing to Nvme
        int             nvmeTrim();                             ///< Trim blocks on Nvme
@@ -476,6 +477,7 @@ int Control::nvmeCapture(){
        int     e;
        BUInt32 n;
        BUInt32 t;
+       BUInt32 l;
        double  r;
        double  ts;
        BUInt   numBlocks;
@@ -522,10 +524,101 @@ int Control::nvmeCapture(){
        }
 
        t = readNvmeStorageReg(RegWriteTime);
+       l = readNvmeStorageReg(RegWritePeakLatency);
        r = ((double(BlockSize) * onumBlocks) / (1e-6 * t));
 
-       printf("Time: %u\n", t);
-       printf("NvmeWrite: rate: %f MBytes/s\n", r / (1024 * 1024));
+       uprintf("Time: %u\n", t);
+       printf("NvmeWrite: rate: %f MBytes/s, PeakLatancy: %8u us\n", r / (1024 * 1024), l);
+       
+       e = readNvmeStorageReg(RegWriteError);
+       if(overbose || e){
+               printf("Error status: 0x%x\n", e);
+               return 1;
+       }
+
+       return 0;
+}
+
+int Control::nvmeCaptureRepeat(){
+       int     e;
+       BUInt32 n;
+       BUInt32 t;
+       BUInt32 l;
+       double  r;
+       BUInt   startBlock;
+       BUInt   numBlocks;
+       BUInt32 b;
+       double  ts;
+       double  tExpected;
+       
+       printf("nvmeCaptureRepeat: Write FPGA data stream to Nvme devices multiple time. nvme: %u startBlock: %u numBlocks: %u\n", onvmeNum, ostartBlock, onumBlocks);
+
+       tExpected = (double(onumBlocks) * BlockSize) / (4000.0 * 1024 * 1024);
+
+       // Initialise Nvme devices
+       if(e = nvmeInit())
+               return e;
+
+       n = 0;
+       while(1){
+               // Toggle start location
+               if(l & 1){
+                       startBlock = ostartBlock + onumBlocks;
+               }
+               else {
+                       startBlock = ostartBlock;
+               }
+
+               // Set number of blocks to write
+               if(onvmeNum == 2){
+                       writeNvmeStorageReg(RegDataChunkStart, startBlock / 2);
+                       writeNvmeStorageReg(RegDataChunkSize, onumBlocks / 2);
+                       numBlocks = onumBlocks / 2;
+               }
+               else {
+                       writeNvmeStorageReg(RegDataChunkStart, startBlock);
+                       writeNvmeStorageReg(RegDataChunkSize, onumBlocks);
+                       numBlocks = onumBlocks;
+               }
+
+               // Start off NvmeWrite engine
+               uprintf("Start NvmeWrite engine\n");
+               writeNvmeStorageReg(4, 0x00000004);
+
+               // Wait until all blocks have been processed.
+               b = 0;
+               ts = getTime();
+               while(b != numBlocks){
+                       b = readNvmeStorageReg(RegWriteNumBlocks);
+                       uprintf("NvmeWrite: numBlocks: %u\n", n);
+                       usleep(100000);
+                       if((getTime() - ts) > (2 * tExpected)){
+                               printf("Took to long. At block: %u\n", b);
+                               printf("Registers\n");
+                               dumpRegs(0);
+                               dumpRegs(1);
+                               return 1;
+                       }
+               }
+
+               e = readNvmeStorageReg(RegWriteError);
+               t = readNvmeStorageReg(RegWriteTime);
+               l = readNvmeStorageReg(RegWritePeakLatency);
+               r = ((double(BlockSize) * onumBlocks) / (1e-6 * t));
+
+               uprintf("Time: %u\n", t);
+               tprintf("%8d ErrorStatus: 0x%x, DataRate: %.3f MBytes/s, PeakLatancy: %8u us\n", n, e, r / (1024 * 1024), l);
+
+               if(e){
+                       printf("Error status: 0x%x, aborted\n", e);
+                       return 1;
+               }
+
+               uprintf("Stop/Clear NvmeWrite engine\n");
+               writeNvmeStorageReg(4, 0x00000000);
+
+               n++;
+       }
 
        return 0;
 }
@@ -636,6 +729,12 @@ int Control::nvmeCaptureAndRead(){
        printf("Time: %u\n", t);
        printf("NvmeWrite: rate: %f MBytes/s\n", r / (1024 * 1024));
 
+       e = readNvmeStorageReg(RegWriteError);
+       if(overbose || e){
+               printf("Error status: 0x%x\n", e);
+               return 1;
+       }
+
        // Wait for read complete
        oreadComplete.wait();
        te = getTime();
@@ -1190,6 +1289,7 @@ int main(int argc, char** argv){
        
        if(listTests){
                printf("capture: Perform data input from FPGA TestData source into Nvme's.\n");
+               printf("captureRepeat: Perform data input from FPGA TestData source into Nvme's multiple times.\n");
                printf("read: Read data from Nvme's\n");
                printf("captureAndRead: Perform data input from FPGA TestData source into Nvme's and read data.\n");
                printf("write: Write data to Nvme's\n");
@@ -1211,6 +1311,9 @@ int main(int argc, char** argv){
                if(!strcmp(test, "capture")){
                        err = control.nvmeCapture();
                }
+               else if(!strcmp(test, "captureRepeat")){
+                       err = control.nvmeCaptureRepeat();
+               }
                else if(!strcmp(test, "read")){
                        err = control.nvmeRead();
                }