]> git.the-white-hart.net Git - vhdl/commitdiff
Add reset logic and update clock syncs
authorrs <>
Wed, 12 Nov 2025 02:08:23 +0000 (20:08 -0600)
committerrs <>
Wed, 12 Nov 2025 02:08:23 +0000 (20:08 -0600)
libraries/nexys2/tests/nexys2_usb.vhd
libraries/nexys2/usb.vhd
libraries/utility/fifo_xclk.vhd
libraries/utility/sync_rst.vhd [new file with mode: 0644]
libraries/utility/tests/test_sync_rst.vhd [new file with mode: 0644]
libraries/utility/xclk_sig.vhd
libraries/utility/xclk_vec.vhd

index 2d1c22ce998503237dab11e7b6f84dd99cfd5114..c8e481677e328aced09ad8a20c8249397dab9211 100644 (file)
@@ -58,6 +58,8 @@ begin
 
        e_usb: entity work.usb_cypress
                port map (
+                       rst_i             => rst,
+
                        EppDB_DstmDB      => EppDB_DstmDB,
                        EppWRITE          => EppWRITE,
                        EppASTB_DstmFLAGA => EppASTB_DstmFLAGA,
@@ -72,7 +74,6 @@ begin
                        UsbMode           => UsbMode,
                        UsbRdy            => UsbRdy,
 
-                       epp_rst_i         => rst,
                        epp_clk_i         => clk_50,
                        epp_cyc_o         => wb_cyc,
                        epp_stb_o         => wb_stb,
@@ -82,7 +83,6 @@ begin
                        epp_dat_i         => wb_miso,
                        epp_dat_o         => wb_mosi,
 
-                       stm_rst_i         => rst,
                        stm_clk_i         => clk_50,
                        stm_dl_stb_o      => stm_stb,
                        stm_dl_ack_i      => stm_ack,
index 878dbd0c6a6238a584ea62ba420eb1a4040dd44b..6f0a00249ef8268c83c3dd6ed6ccafd4046e451e 100644 (file)
@@ -7,7 +7,10 @@ library work;
 
 
 entity usb_cypress is
+       generic (SYNC_STAGES: positive := 2);
        port (
+               rst_i:             in    std_logic;
+
                -- Nexys2 pins
                EppDB_DstmDB:      inout std_logic_vector(7 downto 0);
                EppWRITE:          in    std_logic;
@@ -24,7 +27,6 @@ entity usb_cypress is
                UsbRdy:            in    std_logic;
 
                -- EPP-Wishbone interface
-               epp_rst_i:         in    std_logic;
                epp_clk_i:         in    std_logic;
 
                epp_cyc_o:         out   std_logic;
@@ -36,7 +38,6 @@ entity usb_cypress is
                epp_dat_o:         out   std_logic_vector(7 downto 0);
 
                -- STM-Pipeline interfaces
-               stm_rst_i:         in    std_logic;
                stm_clk_i:         in    std_logic;
 
                stm_dl_stb_o:      out   std_logic;
@@ -52,6 +53,10 @@ end usb_cypress;
 
 architecture behavioral of usb_cypress is
 
+       signal ifclk_rst:   std_logic;
+       signal epp_rst:     std_logic;
+       signal stm_rst:     std_logic;
+
        -- Between USB mux and EPP interface, in DstmIFCLK domain
        signal epp_en:      std_logic;
        signal epp_astb:    std_logic;
@@ -98,6 +103,34 @@ architecture behavioral of usb_cypress is
 
 begin
 
+       ------------------------------------------------------------------------
+       -- Synchronize reset signal to all clock domains
+
+       e_sync_rst_ifclk: entity utility.sync_rst
+               generic map (SYNC_STAGES => SYNC_STAGES+1)
+               port map (
+                       rst_i => rst_i,
+                       clk_i => DstmIFCLK,
+                       rst_o => ifclk_rst
+               );
+
+       e_sync_rst_epp: entity utility.sync_rst
+               generic map (SYNC_STAGES => SYNC_STAGES+1)
+               port map (
+                       rst_i => rst_i,
+                       clk_i => epp_clk_i,
+                       rst_o => epp_rst
+               );
+
+       e_sync_rst_stm: entity utility.sync_rst
+               generic map (SYNC_STAGES => SYNC_STAGES+1)
+               port map (
+                       rst_i => rst_i,
+                       clk_i => stm_clk_i,
+                       rst_o => stm_rst
+               );
+
+
        ------------------------------------------------------------------------
        -- Sharing single USB controller interface between EPP and STM
 
@@ -144,19 +177,19 @@ begin
 
        -- EPP clock domain crossing
        e_xclk_eppen: entity utility.xclk_sig
-               generic map (INIT => '0')
+               generic map (SYNC_STAGES => SYNC_STAGES, INIT => '0')
                port map (a_sig_i => epp_en,    b_clk_i => epp_clk_i, b_sig_o => xclk_eppen);
 
        e_xclk_astb: entity utility.xclk_sig
-               generic map (INIT => '1')
+               generic map (SYNC_STAGES => SYNC_STAGES, INIT => '1')
                port map (a_sig_i => epp_astb,  b_clk_i => epp_clk_i, b_sig_o => xclk_astb);
 
        e_xclk_dstb: entity utility.xclk_sig
-               generic map (INIT => '1')
+               generic map (SYNC_STAGES => SYNC_STAGES, INIT => '1')
                port map (a_sig_i => epp_dstb,  b_clk_i => epp_clk_i, b_sig_o => xclk_dstb);
 
        e_xclk_wait: entity utility.xclk_sig
-               generic map (INIT => '0')  -- FIXME: is this the best initial value for WAIT?
+               generic map (SYNC_STAGES => SYNC_STAGES, INIT => '0')  -- FIXME: is this the best initial value for WAIT?
                port map (a_sig_i => xclk_wait, b_clk_i => DstmIFCLK, b_sig_o => epp_wait);
 
        -- These signals are stable during the time that they're validated by the
@@ -178,7 +211,7 @@ begin
                        EppDB_w => xclk_db_w,
                        EppWait => xclk_wait,
 
-                       rst_i   => epp_rst_i,
+                       rst_i   => epp_rst,
                        clk_i   => epp_clk_i,
                        cyc_o   => epp_cyc_o,
                        stb_o   => epp_stb_o,
@@ -220,7 +253,10 @@ begin
 
        -- STM clock domain crossing, download side
        e_dl_fifo: entity utility.fifo_xclk
+               generic map (SYNC_STAGES => SYNC_STAGES)
                port map (
+                       rst_i      => rst_i,
+
                        head_clk_i => dstm_ifclk,
                        head_stb_i => dl_stb,
                        head_rdy_o => dl_rdy,
@@ -234,7 +270,10 @@ begin
 
        -- STM clock domain crossing, upload side
        e_ul_fifo: entity utility.fifo_xclk
+               generic map (SYNC_STAGES => SYNC_STAGES)
                port map (
+                       rst_i      => rst_i,
+
                        head_clk_i => stm_clk_i,
                        head_stb_i => stm_ul_stb_i,
                        head_rdy_o => stm_ul_ack_o,
index d2e55ceaa1266cde25933a64aa97672fb9761ae2..4709d934440040f5f344a6b9fd29615cf7ae0529 100644 (file)
@@ -9,7 +9,10 @@ library utility;
 
 
 entity fifo_xclk is
+       generic (SYNC_STAGES: positive := 2);
        port (
+               rst_i:      in  std_logic;
+
                head_clk_i: in  std_logic;
                head_stb_i: in  std_logic;
                head_rdy_o: out std_logic;
@@ -25,6 +28,7 @@ end fifo_xclk;
 
 architecture behavioral of fifo_xclk is
 
+       signal head_rst:      std_logic;
        signal tail_adr_xclk: std_logic_vector(10 downto 0);
        signal head_adr_reg:  std_logic_vector(10 downto 0) := (others => '0');
        signal head_adr_next: std_logic_vector(10 downto 0);
@@ -32,6 +36,7 @@ architecture behavioral of fifo_xclk is
        signal head_step:     std_logic;
        signal is_full:       std_logic;
 
+       signal tail_rst:      std_logic;
        signal head_adr_xclk: std_logic_vector(10 downto 0);
        signal tail_adr_reg:  std_logic_vector(10 downto 0) := (others => '0');
        signal tail_adr_inc:  std_logic_vector(10 downto 0);
@@ -44,7 +49,16 @@ begin
 
        -- Head logic
 
+       e_head_reset: entity utility.sync_rst
+               generic map (SYNC_STAGES => SYNC_STAGES+1)
+               port map (
+                       rst_i => rst_i,
+                       clk_i => head_clk_i,
+                       rst_o => head_rst
+               );
+
        e_xclk_tail: entity utility.xclk_vec
+               generic map (SYNC_STAGES => SYNC_STAGES)
                port map (
                        a_sig_i => std_logic_vector(tail_adr_reg),
                        b_clk_i => head_clk_i,
@@ -61,7 +75,7 @@ begin
        e_head_adr: entity utility.gray_counter
                generic map (N => 11)
                port map (
-                       rst_i => '0',
+                       rst_i => head_rst,
                        clk_i => head_clk_i,
                        ena_i => head_step,
                        gray  => head_adr_reg,
@@ -71,7 +85,16 @@ begin
 
        -- Tail logic
 
+       e_tail_reset: entity utility.sync_rst
+               generic map (SYNC_STAGES => SYNC_STAGES+1)
+               port map (
+                       rst_i => rst_i,
+                       clk_i => tail_clk_i,
+                       rst_o => tail_rst
+               );
+
        e_xclk_head: entity utility.xclk_vec
+               generic map (SYNC_STAGES => SYNC_STAGES)
                port map (
                        a_sig_i => std_logic_vector(head_adr_reg),
                        b_clk_i => tail_clk_i,
@@ -89,7 +112,7 @@ begin
        e_tail_adr: entity utility.gray_counter
                generic map (N => 11)
                port map (
-                       rst_i => '0',
+                       rst_i => tail_rst,
                        clk_i => tail_clk_i,
                        ena_i => tail_step,
                        gray  => tail_adr_reg,
diff --git a/libraries/utility/sync_rst.vhd b/libraries/utility/sync_rst.vhd
new file mode 100644 (file)
index 0000000..42b6731
--- /dev/null
@@ -0,0 +1,32 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+
+entity sync_rst is
+       generic (SYNC_STAGES: positive := 2);
+       port (
+               rst_i: in  std_logic;
+               clk_i: in  std_logic;
+               rst_o: out std_logic
+       );
+end sync_rst;
+
+
+architecture behavioral of sync_rst is
+
+       signal shift_reg: std_logic_vector(SYNC_STAGES-1 downto 0) := (others => '1');
+
+begin
+
+       rst_o <= shift_reg(0);
+
+       process (rst_i, clk_i)
+       begin
+               if rst_i = '1' then
+                       shift_reg <= (others => '1');
+               elsif rising_edge(clk_i) then
+                       shift_reg <= '0' & shift_reg(SYNC_STAGES-1 downto 1);
+               end if;
+       end process;
+
+end behavioral;
diff --git a/libraries/utility/tests/test_sync_rst.vhd b/libraries/utility/tests/test_sync_rst.vhd
new file mode 100644 (file)
index 0000000..8529d93
--- /dev/null
@@ -0,0 +1,47 @@
+library ieee;
+use ieee.std_logic_1164.all;
+
+library work;
+
+
+entity test_sync_rst is
+end test_sync_rst;
+
+
+architecture behavior of test_sync_rst is
+
+       signal rst_i: std_logic;
+       signal clk_i: std_logic;
+       signal rst_o: std_logic;
+
+begin
+
+       p_test: process
+       begin
+               rst_i <= '0';
+               wait until rst_o = '0';
+               wait for 40 ns;
+               rst_i <= '1';
+               wait for 2 ns;
+               rst_i <= '0';
+
+               wait;
+       end process;
+
+       e_uut: entity work.sync_rst
+               generic map (SYNC_STAGES => 5)
+               port map (
+                       rst_i => rst_i,
+                       clk_i => clk_i,
+                       rst_o => rst_o
+               );
+
+       p_clk: process
+       begin
+               clk_i <= '0';
+               wait for 10 ns;
+               clk_i <= '1';
+               wait for 10 ns;
+       end process;
+
+end;
index aec6e8c6d65ad7a1f454c00fe0cd99736e04cc5b..f2531563c62ee0783dee18585454d0b3a38fa3e3 100644 (file)
@@ -4,6 +4,7 @@ use ieee.std_logic_1164.all;
 
 entity xclk_sig is
        generic (
+               SYNC_STAGES: positive := 2;
                INIT: std_logic := '0'
        );
        port (
@@ -17,18 +18,16 @@ end xclk_sig;
 
 architecture behavioral of xclk_sig is
 
-       signal b_0_reg: std_logic := INIT;
-       signal b_1_reg: std_logic := INIT;
+       signal sync_regs: std_logic_vector(SYNC_STAGES-1 downto 0) := (others => INIT);
 
 begin
 
-       process (b_clk_i, a_sig_i, b_0_reg)
+       process (b_clk_i, a_sig_i, sync_regs)
        begin
                if rising_edge(b_clk_i) then
-                       b_0_reg <= a_sig_i;
-                       b_1_reg <= b_0_reg;
+                       sync_regs <= a_sig_i & sync_regs(SYNC_STAGES-1 downto 1);
                end if;
        end process;
-       b_sig_o <= b_1_reg;
+       b_sig_o <= sync_regs(0);
 
 end behavioral;
index cd50daad8d7057ecae042e968ececbb75683b9eb..a1662da8c3715a989a05719a0388b515d83def64 100644 (file)
@@ -3,6 +3,7 @@ use ieee.std_logic_1164.all;
 
 
 entity xclk_vec is
+       generic (SYNC_STAGES: positive := 2);
        port (
                a_sig_i: in  std_logic_vector;
 
@@ -14,18 +15,21 @@ end xclk_vec;
 
 architecture behavioral of xclk_vec is
 
-       signal b_0_reg: std_logic_vector(b_sig_o'high downto 0) := (others => '0');
-       signal b_1_reg: std_logic_vector(b_sig_o'high downto 0) := (others => '0');
+       type value_array is array(natural range <>) of std_logic_vector(a_sig_i'high downto 0);
+
+       signal sync_regs: value_array(SYNC_STAGES-1 downto 0);
 
 begin
 
-       process (b_clk_i, a_sig_i, b_0_reg)
+       process (b_clk_i, a_sig_i, sync_regs)
        begin
                if rising_edge(b_clk_i) then
-                       b_0_reg <= a_sig_i;
-                       b_1_reg <= b_0_reg;
+                       sync_regs(SYNC_STAGES-1) <= a_sig_i;
+                       for i in SYNC_STAGES-2 downto 0 loop
+                               sync_regs(i) <= sync_regs(i+1);
+                       end loop;
                end if;
        end process;
-       b_sig_o <= b_1_reg;
+       b_sig_o <= sync_regs(0);
 
 end behavioral;