Register CDC improvements.
authorTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Tue, 19 May 2020 10:46:33 +0000 (11:46 +0100)
committerTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Tue, 19 May 2020 10:46:33 +0000 (11:46 +0100)
src/NvmeStorage.vhd
src/RegAccessClockConvertor.vhd

index 94ad67b9466b6b6284ec125a38de7d14f9475c52..a0386592c88ee52a5c4855f1ea5f3e1c0c8bd320 100644 (file)
@@ -166,6 +166,7 @@ constant TCQ                : time := 1 ns;
 signal nvme_clk                : std_logic := 'U';
 signal nvme_clk_gt     : std_logic := 'U';
 
+signal wvalid_delay    : std_logic := '0';
 signal rvalid_delay    : unsigned(4 downto 0) := (others => '0');
 
 signal hostSend0       : AxisStreamType;
@@ -214,14 +215,14 @@ begin
        axilOut.awready <= axilIn.awvalid;
        axilOut.arready <= axilIn.arvalid;
        axilOut.rvalid  <= rvalid_delay(4);
-       axilOut.wready  <= axilIn.wvalid;
+       axilOut.wready  <= axilIn.wvalid and wvalid_delay;
 
        -- Always return OK to read and write requests
        axilOut.rresp   <= "00";
        axilOut.bresp   <= "00";
        axilOut.bvalid  <= '1';
 
-       regWrite        <= axilIn.wvalid;
+       regWrite        <= wvalid_delay;        -- Delayed to make sure bits are stable across CDC
        
        regWrite0       <= regWrite when(regAddress < 512) else '0';
        regWrite1       <= regWrite when((regAddress < 256) or (regAddress >= 512)) else '0';
@@ -234,6 +235,7 @@ begin
                        if(reset = '1') then
                                regAddress      <= (others => '0');
                                rvalid_delay    <= (others => '0');
+                               wvalid_delay    <= '0';
                        else
                                if(axilIn.awvalid = '1') then
                                        regAddress <= unsigned(axilIn.awaddr(9 downto 0));
@@ -245,6 +247,7 @@ begin
                                        rvalid_delay <= shift_left(rvalid_delay, 1);
                                end if;
                                
+                               wvalid_delay <= axilIn.wvalid;
                        end if;
                end if;
        end process;
index 8eb87aee6bf24dd5ccb402b3442ab41318592fd7..a8c7eb94a39bd1a2d1bdc068d22018774b4b722f 100644 (file)
@@ -8,9 +8,14 @@
 --! @version   0.0.1
 --!
 --! @brief
---! This module passes register access signals acrossd a clock domain
+--! This module passes register access signals across a clock domain
 --!
 --! @details
+--! This is a very simple, low utilisation clock domain crossing unit for the register interface.
+--! It is designed to work with asynchronous clocks of the same frequency.
+--! It assumes the write signal is delayed by 1 cycle from the address and data transitions to
+--! make sure all bits are stable before the actual register write.
+--! For reads you need to wait 5 cycles.
 --!
 --! @copyright GNU GPL License
 --! Copyright (c) Beam Ltd, All rights reserved. <br>