Timing and CDC improvements.
authorTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Wed, 27 May 2020 16:09:18 +0000 (17:09 +0100)
committerTerry Barnaby <terry.barnaby@beam.beam.ltd.uk>
Wed, 27 May 2020 16:09:18 +0000 (17:09 +0100)
src/Cdc.vhd
src/DuneNvmeTestTop.xdc
src/NvmeStorage.vhd
src/NvmeStorageUnit.vhd
src/RegAccessClockConvertor.vhd

index f2f4b398f12a6aa66880010494601a9836dfc3fb..3f95baed7a313c120a971355002b59562cbd729f 100644 (file)
@@ -54,30 +54,30 @@ architecture Behavioral of Cdc is
 constant TCQ           : time := 1 ns;
 subtype RegisterType   is std_logic_vector(Width-1 downto 0);
 
-signal cdcReg1         : RegisterType := (others => '0');
-signal cdcReg2         : RegisterType := (others => '0');
+signal sendCdcReg1     : RegisterType := (others => '0');
+signal sendCdcReg2     : RegisterType := (others => '0');
 
-attribute keep : string;
+attribute keep         : string;
 attribute async_reg    : string;
 
-attribute keep of cdcReg1 : signal is "true";
-attribute keep of cdcReg2 : signal is "true";
+attribute keep         of sendCdcReg1 : signal is "true";
+attribute keep         of sendCdcReg2 : signal is "true";
 
-attribute async_reg    of cdcReg1 : signal is "true";
-attribute async_reg    of cdcReg2 : signal is "true";
+attribute async_reg    of sendCdcReg1 : signal is "true";
+attribute async_reg    of sendCdcReg2 : signal is "true";
 
 begin
-       signals2        <= cdcReg2;
+       signals2        <= sendCdcReg2;
 
        process(clk2)
        begin
                if(rising_edge(clk2)) then
                        if(reset2 = '1') then
-                               cdcReg1 <= (others => '0');
-                               cdcReg2 <= (others => '0');
+                               sendCdcReg1     <= (others => '0');
+                               sendCdcReg2     <= (others => '0');
                        else
-                               cdcReg2 <= cdcReg1;
-                               cdcReg1 <= signals1;
+                               sendCdcReg2     <= sendCdcReg1;
+                               sendCdcReg1     <= signals1;
                        end if;
                end if;
        end process;
@@ -104,30 +104,30 @@ architecture Behavioral of CdcSingle is
 
 constant TCQ           : time := 1 ns;
 
-signal cdcReg1         : std_logic := '0';
-signal cdcReg2         : std_logic := '0';
+signal sendCdcReg1     : std_logic := '0';
+signal sendCdcReg2     : std_logic := '0';
 
 attribute keep         : string;
 attribute async_reg    : string;
 
-attribute keep         of cdcReg1 : signal is "true";
-attribute keep         of cdcReg2 : signal is "true";
+attribute keep         of sendCdcReg1 : signal is "true";
+attribute keep         of sendCdcReg2 : signal is "true";
 
-attribute async_reg    of cdcReg1 : signal is "true";
-attribute async_reg    of cdcReg2 : signal is "true";
+attribute async_reg    of sendCdcReg1 : signal is "true";
+attribute async_reg    of sendCdcReg2 : signal is "true";
 
 begin
-       signal2 <= cdcReg2;
+       signal2 <= sendCdcReg2;
 
        process(clk2)
        begin
                if(rising_edge(clk2)) then
                        if(reset2 = '1') then
-                               cdcReg1 <= '0';
-                               cdcReg2 <= '0';
+                               sendCdcReg1     <= '0';
+                               sendCdcReg2     <= '0';
                        else
-                               cdcReg2 <= cdcReg1;
-                               cdcReg1 <= signal1;
+                               sendCdcReg2     <= sendCdcReg1;
+                               sendCdcReg1     <= signal1;
                        end if;
                end if;
        end process;
index f7d574464511241c5d3ed5696029bb4639ddf1b1..5e7c6948def29d2535323e92aa771598c1e169a8 100644 (file)
@@ -8,17 +8,23 @@
 #create_clock -period 5.000 -name sys_clk_p -waveform {0.000 2.500} [get_ports sys_clk_p]\r
 create_clock -period 10.000 -name pci_clk [get_ports pci_clk_p]\r
 create_clock -period 10.000 -name nvme_clk [get_ports nvme_clk_p]\r
-set_clock_groups -name async_host_nvme -asynchronous -group [get_clocks -include_generated_clocks pci_clk] -group [get_clocks -include_generated_clocks nvme_clk]\r
+\r
+# CDC crossings\r
+set_false_path -to [get_cells -hier sendCdcReg1*]\r
+set_false_path -to [get_cells -hier recvCdcReg1*]\r
 \r
 # Asynchronous resets\r
 set_false_path -from [get_ports sys_reset]\r
 set_false_path -from [get_ports pci_reset_n]\r
+set_false_path -through [get_nets -hier -filter {NAME=~ */nvmeStorageUnit*/reset_local}]\r
+#set_false_path -through [get_nets -hier -filter {NAME=~ */nvmeStorageUnit*/nvme_reset_local_n}]\r
 \r
 # PCIe Host\r
-#set_false_path -through [get_pins pcie_host0/inst/pcie3_ip_i/U0/pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/PCIE_3_1_inst/CFGMAX*]\r
-#set_false_path -through [get_nets pcie_host0/inst/cfg_max*]\r
-#set_false_path -to [get_pins -hier *sync_reg[0]/D]\r
+set_false_path -through [get_pins pcie_host0/inst/pcie3_ip_i/U0/pcie3_uscale_top_inst/pcie3_uscale_wrapper_inst/PCIE_3_1_inst/CFGMAX*]\r
+set_false_path -through [get_nets pcie_host0/inst/cfg_max*]\r
+set_false_path -to [get_pins -hier *sync_reg[0]/D]\r
 \r
+# Output pins\r
 set_output_delay -clock [get_clocks nvme_clk] -min 0.0 [get_ports -filter NAME=~nvme_reset_n]\r
 set_output_delay -clock [get_clocks nvme_clk] -max 1000.0 [get_ports -filter NAME=~nvme_reset_n]\r
 set_false_path -to [get_ports -filter NAME=~nvme_reset_n]\r
index ed9a94232f8bf2ebd8b8cb0e4e4ff2401412a029..e37b078d4417e127ee96efb9ba252cff34d4b688 100644 (file)
@@ -178,7 +178,7 @@ end component;
 constant TCQ           : time := 1 ns;
 
 signal wvalid_delay    : std_logic := '0';
-signal rvalid_delay    : unsigned(4 downto 0) := (others => '0');
+signal rvalid_delay    : unsigned(5 downto 0) := (others => '0');
 
 signal hostSend0       : AxisStreamType;
 signal hostRecv0       : AxisStreamType;
@@ -219,7 +219,7 @@ begin
        -- Bus ready returns            
        axilOut.awready <= axilIn.awvalid;
        axilOut.arready <= axilIn.arvalid;
-       axilOut.rvalid  <= rvalid_delay(4);
+       axilOut.rvalid  <= rvalid_delay(5);
        axilOut.wready  <= axilIn.wvalid and wvalid_delay;
 
        -- Always return OK to read and write requests
index 0c7130b84764ee5e159f6086fe747081ea2ce13e..436d24ef7afbe569acd4076657fc39e6e6391a7e 100644 (file)
@@ -474,8 +474,6 @@ begin
                regDataIn1      => regDataIn,
                regDataOut1     => regDataOut0,
 
-               --clk2          => clk,                         --! **** Needs to operate from Nvme clock
-               --reset2        => reset,
                clk2            => nvme_user_clk,
                reset2          => nvme_user_reset,
 
@@ -558,7 +556,7 @@ begin
        reset_local             <= reset or reset_local_active;
        nvme_reset_local_n      <= not reset_local;
        nvme_reset_n            <= nvme_reset_local_n;
-       
+
        -- Process reset
        process(clk)
        begin
index 9b82f4ad0fa309acb83b8cad5f27c4ca4918706a..3f048d26c5c24d0ad1929d9ce2c95657c4b7d080 100644 (file)
@@ -70,53 +70,59 @@ constant SigRecvWidth       : integer := 32;
 subtype SigSendType    is std_logic_vector(SigSendWidth-1 downto 0);
 subtype SigRecvType    is std_logic_vector(SigRecvWidth-1 downto 0);
 
-signal sigSendFifo1    : SigSendType := (others => '0');
-signal sigSendFifo2    : SigSendType := (others => '0');
-signal sigRecvFifo1    : SigRecvType := (others => '0');
-signal sigRecvFifo2    : SigRecvType := (others => '0');
+signal sendCdcReg1     : SigSendType := (others => '0');
+signal sendCdcReg2     : SigSendType := (others => '0');
+
+signal recvCdcReg0     : SigRecvType := (others => '0');
+signal recvCdcReg1     : SigRecvType := (others => '0');
+signal recvCdcReg2     : SigRecvType := (others => '0');
 
 attribute keep         : string;
 attribute async_reg    : string;
 
-attribute keep         of sigSendFifo1 : signal is "true";
-attribute keep         of sigSendFifo2 : signal is "true";
-attribute keep         of sigRecvFifo1 : signal is "true";
-attribute keep         of sigRecvFifo2 : signal is "true";
+attribute keep         of sendCdcReg1 : signal is "true";
+attribute keep         of sendCdcReg2 : signal is "true";
+attribute keep         of recvCdcReg0 : signal is "true";
+attribute keep         of recvCdcReg1 : signal is "true";
+attribute keep         of recvCdcReg2 : signal is "true";
 
-attribute async_reg    of sigSendFifo1 : signal is "true";
-attribute async_reg    of sigSendFifo2 : signal is "true";
-attribute async_reg    of sigRecvFifo1 : signal is "true";
-attribute async_reg    of sigRecvFifo2 : signal is "true";
+attribute async_reg    of sendCdcReg1 : signal is "true";
+attribute async_reg    of sendCdcReg2 : signal is "true";
+attribute async_reg    of recvCdcReg1 : signal is "true";
+attribute async_reg    of recvCdcReg2 : signal is "true";
 
 begin
-       regWrite2       <= sigSendFifo2(38);
-       regAddress2     <= unsigned(sigSendFifo2(37 downto 32));
-       regDataIn2      <= sigSendFifo2(31 downto 0);
+       regWrite2       <= sendCdcReg2(38);
+       regAddress2     <= unsigned(sendCdcReg2(37 downto 32));
+       regDataIn2      <= sendCdcReg2(31 downto 0);
 
        process(clk2)
        begin
                if(rising_edge(clk2)) then
                        if(reset2 = '1') then
-                               sigSendFifo1    <= (others => '0');
-                               sigSendFifo2    <= (others => '0');
+                               sendCdcReg1     <= (others => '0');
+                               sendCdcReg2     <= (others => '0');
+                               recvCdcReg0     <= (others => '0');
                        else
-                               sigSendFifo2    <= sigSendFifo1;
-                               sigSendFifo1    <= regWrite1 & to_stl(regAddress1) & regDataIn1;
+                               sendCdcReg2     <= sendCdcReg1;
+                               sendCdcReg1     <= regWrite1 & to_stl(regAddress1) & regDataIn1;
+                               
+                               recvCdcReg0     <= regDataOut2;
                        end if;
                end if;
        end process;
 
-       regDataOut1 <= sigRecvFifo2;
+       regDataOut1 <= recvCdcReg2;
 
        process(clk1)
        begin
                if(rising_edge(clk1)) then
                        if(reset1 = '1') then
-                               sigRecvFifo1    <= (others => '0');
-                               sigRecvFifo2    <= (others => '0');
+                               recvCdcReg1     <= (others => '0');
+                               recvCdcReg2     <= (others => '0');
                        else
-                               sigRecvFifo2    <= sigRecvFifo1;
-                               sigRecvFifo1    <= regDataOut2;
+                               recvCdcReg2     <= recvCdcReg1;
+                               recvCdcReg1     <= recvCdcReg0;
                        end if;
                end if;
        end process;