e_usb: entity work.usb_cypress
port map (
+ rst_i => rst,
+
EppDB_DstmDB => EppDB_DstmDB,
EppWRITE => EppWRITE,
EppASTB_DstmFLAGA => EppASTB_DstmFLAGA,
UsbMode => UsbMode,
UsbRdy => UsbRdy,
- epp_rst_i => rst,
epp_clk_i => clk_50,
epp_cyc_o => wb_cyc,
epp_stb_o => wb_stb,
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,
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;
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;
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;
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;
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
-- 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
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,
-- 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,
-- 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,
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;
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);
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);
-- 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,
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,
-- 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,
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,
--- /dev/null
+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;
--- /dev/null
+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;
entity xclk_sig is
generic (
+ SYNC_STAGES: positive := 2;
INIT: std_logic := '0'
);
port (
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;
entity xclk_vec is
+ generic (SYNC_STAGES: positive := 2);
port (
a_sig_i: in std_logic_vector;
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;