Register access: Added delay on read to handle clock domain crossing latency.
authorTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Tue, 19 May 2020 08:28:29 +0000 (09:28 +0100)
committerTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Tue, 19 May 2020 08:28:29 +0000 (09:28 +0100)
Some tidy ups.

sim/Makefile
sim/testbench/test020-write.vhd
src/NvmeStorage.vhd
src/NvmeStorageUnit.vhd

index 49f5a96fb69e9a82317bdb9d9e5a836ca91a6c55..33fe640bf86838388b65affa58ebf825582d1929 100644 (file)
@@ -72,6 +72,7 @@ GFLAGS        = --ieee=synopsys --warn-no-unused
 GFLAGS += -fexplicit
 GFLAGS += -Psimu
 SFLAGS = --assert-level=error
+SFLAGS += --ieee-asserts=disable-at-0
 #SFLAGS += --stop-time=300ns
 SFLAGS += --stop-time=30us
 
index fd6ac508740b0a6933fc103050d7c6e63f4a6b93..5e5992b3e8105a82aa43f253565f5ce8ffef4ef8 100644 (file)
@@ -165,11 +165,12 @@ begin
                axil.toSlave <= ((others => '0'), (others => '0'), '0', (others => '0'), (others => '0'), '0', '0', (others => '0'), (others => '0'), '0', '0');
                wait until reset = '0';
 
-               if(False) then
+               if(True) then
                        -- Test Read/Write NvmeStorageUnit's registers
                        wait for 100 ns;
                        busWrite(clk, axil.toSlave, axil.toMaster, 16#0004#, 16#40000000#);
                        busWrite(clk, axil.toSlave, axil.toMaster, 16#0204#, 16#48000000#);
+                       busRead(clk, axil.toSlave, axil.toMaster, 16#0000#);
                        busRead(clk, axil.toSlave, axil.toMaster, 16#0004#);
                        busRead(clk, axil.toSlave, axil.toMaster, 16#0204#);
 
@@ -191,6 +192,7 @@ begin
                        -- Perform local reset
                        wait for 100 ns;
                        busWrite(clk, axil.toSlave, axil.toMaster, 4, 16#00000001#);
+                       busRead(clk, axil.toSlave, axil.toMaster, 16#0000#);
                        busRead(clk, axil.toSlave, axil.toMaster, 16#0008#);
                        busRead(clk, axil.toSlave, axil.toMaster, 16#0008#);
                        wait for 200 ns;
index 8faf5bcc9051e7eed45ee630097775128d09e50d..94ad67b9466b6b6284ec125a38de7d14f9475c52 100644 (file)
@@ -166,17 +166,15 @@ constant TCQ              : time := 1 ns;
 signal nvme_clk                : std_logic := 'U';
 signal nvme_clk_gt     : std_logic := 'U';
 
+signal rvalid_delay    : unsigned(4 downto 0) := (others => '0');
+
 signal hostSend0       : AxisStreamType;
 signal hostRecv0       : AxisStreamType;
 
-signal axilIn0         : AxilToSlaveType;
-signal axilOut0                : AxilToMasterType;
 signal data0           : AxisStreamType := AxisStreamOutput;
 signal nvme0Send       : AxisStreamType;
 signal nvme0Recv       : AxisStreamType;
 
-signal axilIn1         : AxilToSlaveType;
-signal axilOut1                : AxilToMasterType;
 signal data1           : AxisStreamType := AxisStreamOutput;
 signal nvme1Send       : AxisStreamType;
 signal nvme1Recv       : AxisStreamType;
@@ -200,28 +198,6 @@ signal dataIn1_ready       : std_logic := 'U';
 signal dataEnabledOut0 : std_logic := 'U';
 signal dataEnabledOut1 : std_logic := 'U';
 
-function busPass(axil: AxilToSlaveType; enable: std_logic) return AxilToSlaveType is
-variable ret: AxilToSlaveType;
-begin
-       ret.awaddr      := axil.awaddr;
-       ret.awprot      := axil.awprot;
-       ret.awvalid     := axil.awvalid;
-       ret.wdata       := axil.wdata;
-       ret.wstrb       := axil.wstrb;
-       if(enable = '1') then
-               ret.wvalid := axil.wvalid;
-       else
-               ret.wvalid := '0';
-       end if;
-       ret.bready      := axil.bready;
-       ret.araddr      := axil.araddr;
-       ret.arprot      := axil.arprot;
-       ret.arvalid     := axil.arvalid;
-       ret.rready      := axil.rready;
-       
-       return ret;
-end;
-
 begin
        -- NVME PCIE Clock, 100MHz
        nvme_clk_buf0 : IBUFDS_GTE3
@@ -237,7 +213,7 @@ begin
        -- Bus ready returns            
        axilOut.awready <= axilIn.awvalid;
        axilOut.arready <= axilIn.arvalid;
-       axilOut.rvalid  <= '1';
+       axilOut.rvalid  <= rvalid_delay(4);
        axilOut.wready  <= axilIn.wvalid;
 
        -- Always return OK to read and write requests
@@ -256,13 +232,19 @@ begin
        begin
                if(rising_edge(clk)) then
                        if(reset = '1') then
-                               regAddress <= (others => '0');
+                               regAddress      <= (others => '0');
+                               rvalid_delay    <= (others => '0');
                        else
                                if(axilIn.awvalid = '1') then
                                        regAddress <= unsigned(axilIn.awaddr(9 downto 0));
                                elsif(axilIn.arvalid = '1') then
                                        regAddress <= unsigned(axilIn.araddr(9 downto 0));
+                                       rvalid_delay(0) <= '1';
+                               else
+                                       -- rvalid delay to handle clock domain crossing latency
+                                       rvalid_delay <= shift_left(rvalid_delay, 1);
                                end if;
+                               
                        end if;
                end if;
        end process;
@@ -303,7 +285,7 @@ begin
 
                streamTx        => data1
        );
-
+       
        process(clk)
        begin
                if(rising_edge(clk)) then
index da3807bb2a96daffeb0f277d6ee6797536bec132..06389da06f3fdc483a91ead0fdab637aa1f01f3f 100644 (file)
@@ -390,7 +390,7 @@ type StateType                      is (STATE_START, STATE_IDLE, STATE_WRITE, STATE_READ1, STATE_RE
 signal state                   : StateType := STATE_START;
 
 signal regWrite1               : std_logic;                            --! Enable write to register
-signal regAddress1             : unsigned(5 downto 0);                 --! Register to read/write
+signal regAddress1             : unsigned(5 downto 0) := (others => '0');      --! Register to read/write
 signal regDataIn1              : std_logic_vector(31 downto 0);        --! Register write data
 signal regDataOut0             : std_logic_vector(31 downto 0);        --! Register contents
 signal regDataOut1             : std_logic_vector(31 downto 0);        --! Register contents
@@ -489,7 +489,6 @@ begin
                streamTx        => dataIn1
        );
 
-       
        -- Register access
        regDataOut1 <= reg_id when(regAddress1 = 0) else
                        reg_control when(regAddress1 = 1) else