NvmeRead: Initial basic bandwidth management support. Currently stops reads while...
authorTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Fri, 5 Jun 2020 14:11:08 +0000 (15:11 +0100)
committerTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Fri, 5 Jun 2020 14:11:08 +0000 (15:11 +0100)
src/NvmeRead.vhd
src/NvmeStorageUnit.vhd
src/NvmeWrite.vhd

index 23e5d811c07a82543446cd592b3ef957ff1eb70f..c226fce7ad9ae34d56d0737967ebd850d25dfe32 100644 (file)
@@ -58,6 +58,8 @@ port (
        clk             : in std_logic;                         --! The interface clock line
        reset           : in std_logic;                         --! The active high reset line
 
+       enable          : in std_logic;                         --! Enable operation, used to limit bandwidth used
+
        -- To Nvme Request/reply streams
        requestOut      : inout AxisStreamType := AxisStreamOutput;     --! To Nvme request stream (3)
        replyIn         : inout AxisStreamType := AxisStreamInput;      --! from Nvme reply stream
@@ -173,7 +175,7 @@ begin
                                                        complete <= '1';
                                                        state <= STATE_COMPLETE;
                                                
-                                               else
+                                               elsif(enable = '1') then
                                                        requestOut.data         <= setHeader(1, 16#02020000#, 16, 0);
                                                        requestOut.valid        <= '1';
                                                        state                   <= STATE_QUEUE_HEAD;
index 0eae66e39fb008b558927d59989e2f327a82bb2c..387a0fb51dfc75a6495216aac6930483248555a7 100644 (file)
@@ -342,6 +342,8 @@ port (
        enable          : in std_logic;                         --! Enable the data writing process
        dataIn          : inout AxisStreamType := AxisStreamInput;      --! Raw data to save stream
 
+       waitingForData  : out std_logic;                        --! Set when dataIn is empty so other tasks can be run.
+
        -- To Nvme Request/reply streams
        requestOut      : inout AxisStreamType := AxisStreamOutput;     --! To Nvme request stream (3)
        replyIn         : inout AxisStreamType := AxisStreamInput;      --! from Nvme reply stream
@@ -368,6 +370,8 @@ port (
        clk             : in std_logic;                         --! The interface clock line
        reset           : in std_logic;                         --! The active high reset line
 
+       enable          : in std_logic;                         --! Enable operation, used to limit bandwidth used
+
        -- To Nvme Request/reply streams
        requestOut      : inout AxisStreamType := AxisStreamOutput;     --! To Nvme request stream (3)
        replyIn         : inout AxisStreamType := AxisStreamInput;      --! from Nvme reply stream
@@ -450,7 +454,7 @@ signal configComplete               : std_logic := 'U';
 
 -- Nvme data write signals
 signal writeEnable             : std_logic := 'U';
-
+signal waitingForData          : std_logic := 'U';
 
 -- Pcie_nvme signals
 signal nvme_reset_local_n      : std_logic := '0';
@@ -465,10 +469,6 @@ signal cfg_mgmt_read_data          : std_logic_vector(31 downto 0);
 signal cfg_mgmt_read_write_done                : std_logic;
 signal cfg_mgmt_type1_cfg_reg_access   : std_logic;
 
-signal dummy1                  : AxisStreamType := AxisStreamInput;
-signal dummy2                  : AxisStreamType := AxisStreamOutput;
-signal dummy3                  : AxisStreamType := AxisStreamOutput;
-
 attribute keep : string;
 attribute keep of reset_local : signal is "true";
 attribute keep of nvme_reset_local_n : signal is "true";
@@ -853,6 +853,8 @@ begin
                enable          => writeEnable,
                dataIn          => dataIn1,
 
+               waitingForData  => waitingForData,
+               
                requestOut      => writeSend,
                replyIn         => writeRecv,
 
@@ -871,6 +873,8 @@ begin
                clk             => nvme_user_clk,
                reset           => nvme_user_reset,
 
+               enable          => waitingForData,
+
                requestOut      => readSend,
                replyIn         => readRecv,
 
index ec8002a2b09588d245c545a61c9546aeb1dd6055..b5c0ab3e810163d7944ca554e4a60beed351ed08 100644 (file)
@@ -87,6 +87,8 @@ port (
 
        enable          : in std_logic;                         --! Enable the data writing process
        dataIn          : inout AxisStreamType := AxisStreamInput;      --! Raw data to save stream
+       
+       waitingForData  : out std_logic;                        --! Set when dataIn is empty so other tasks can be run.
 
        -- To Nvme Request/reply streams
        requestOut      : inout AxisStreamType := AxisStreamOutput;     --! To Nvme request stream (3)
@@ -181,6 +183,7 @@ signal inState              : InStateType := INSTATE_IDLE;
 signal state           : StateType := STATE_IDLE;
 signal replyState      : ReplyStateType := REPSTATE_QUEUE_REPLY1;
 
+signal complete                : std_logic := '0';
 signal blockNumberIn   : unsigned(31 downto 0) := (others => '0');             --! Input block number
 signal numBlocksProc   : unsigned(31 downto 0) := (others => '0');             --! Number of block write requests sent
 signal numBlocksDone   : unsigned(31 downto 0) := (others => '0');             --! Number of block write completions received
@@ -318,6 +321,8 @@ begin
 
        -- Input data process. Accepts data from input stream and stores it into a free buffer if available.
        dataIn.ready <= writeEnable;
+       --waitingForData <= not enable or complete or not dataIn.valid;
+       waitingForData <= not enable or complete;
 
        process(clk)
        variable c: integer;
@@ -428,6 +433,7 @@ begin
                                processQueueOut         <= 0;
                                numBlocksTrimmed        <= (others => '0');
                                trimQueueProc           <= (others => '0');
+                               complete                <= '0';
                                state                   <= STATE_IDLE;
                        else
                                case(state) is
@@ -443,12 +449,14 @@ begin
                                        numBlocksProc   <= (others => '0');
                                        processQueueOut <= 0;
                                        numBlocksTrimmed<= (others => '0');
+                                       complete        <= '0';
                                        state           <= STATE_RUN;
                                        
                                when STATE_RUN =>
                                        if(enable = '1') then
                                                if(numBlocksProc >= dataChunkSize) then
-                                                       state <= STATE_COMPLETE;
+                                                       complete        <= '1';
+                                                       state           <= STATE_COMPLETE;
                                                
                                                elsif(DoTrim and (numBlocksTrimmed < dataChunkSize) and ((trimQueueProc - trimQueueDone) < 4)) then
                                                        requestOut.data         <= setHeader(1, 16#02010000#, 16, 0);
@@ -465,7 +473,8 @@ begin
 
                                                end if;
                                        else
-                                               state <= STATE_COMPLETE;
+                                               complete        <= '1';
+                                               state           <= STATE_COMPLETE;
                                        end if;
                                
                                when STATE_COMPLETE =>