EppDSTB_DstmFLAGB: in std_logic;
EppWAIT_DstmSLRD: out std_logic;
DstmIFCLK: in std_logic;
- DstmSLCS: in std_logic;
+ DstmSLCS: in std_logic; -- STMEN
DstmADR: out std_logic_vector(1 downto 0);
DstmSLWR: out std_logic;
DstmSLOE: out std_logic;
DstmPKTEND: out std_logic;
- UsbMode: in std_logic;
- UsbRdy: in std_logic;
+ UsbMode: in std_logic; -- I think this is EPPEN, which is referenced in documentation but not defined anywhere
+ UsbRdy: in std_logic; -- High when USB is plugged in and the controller is ready
-- EPP-Wishbone interface
epp_clk_i: in std_logic;
------------------------------------------------------------------------
-- Synchronize reset signal to all clock domains
- e_sync_rst_ifclk: entity utility.sync_rst
+ e_sync_rst_ifclk: entity utility.sync_sig
generic map (SYNC_STAGES => SYNC_STAGES+1)
port map (
rst_i => rst_i,
clk_i => DstmIFCLK,
- rst_o => ifclk_rst
+ sig_o => ifclk_rst
);
- e_sync_rst_epp: entity utility.sync_rst
+ e_sync_rst_epp: entity utility.sync_sig
generic map (SYNC_STAGES => SYNC_STAGES+1)
port map (
rst_i => rst_i,
clk_i => epp_clk_i,
- rst_o => epp_rst
+ sig_o => epp_rst
);
- e_sync_rst_stm: entity utility.sync_rst
+ e_sync_rst_stm: entity utility.sync_sig
generic map (SYNC_STAGES => SYNC_STAGES+1)
port map (
rst_i => rst_i,
clk_i => stm_clk_i,
- rst_o => stm_rst
+ sig_o => stm_rst
);
-- EPP Interface
-- EPP clock domain crossing
- e_xclk_eppen: entity utility.xclk_sig
+ e_xclk_eppen: entity utility.sync_sig
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);
+ port map (
+ rst_i => epp_rst,
+ clk_i => epp_clk_i,
+ sig_i => epp_en,
+ sig_o => xclk_eppen
+ );
- e_xclk_astb: entity utility.xclk_sig
- 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_astb: entity utility.sync_sig
+ generic map (SYNC_STAGES => SYNC_STAGES)
+ port map (
+ clk_i => epp_clk_i,
+ sig_i => epp_astb,
+ sig_o => xclk_astb
+ );
- e_xclk_dstb: entity utility.xclk_sig
- 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_dstb: entity utility.sync_sig
+ generic map (SYNC_STAGES => SYNC_STAGES)
+ port map (
+ clk_i => epp_clk_i,
+ sig_i => epp_dstb,
+ sig_o => xclk_dstb
+ );
- e_xclk_wait: entity utility.xclk_sig
+ e_xclk_wait: entity utility.sync_sig
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);
+ port map (
+ rst_i => ifclk_rst,
+ clk_i => DstmIFCLK,
+ sig_i => xclk_wait,
+ sig_o => epp_wait
+ );
-- These signals are stable during the time that they're validated by the
-- synchronized handshaking signals, so no clock synchronizing is needed
-- Head logic
- e_head_reset: entity utility.sync_rst
+ e_head_reset: entity utility.sync_sig
generic map (SYNC_STAGES => SYNC_STAGES+1)
port map (
rst_i => rst_i,
clk_i => head_clk_i,
- rst_o => head_rst
+ sig_o => head_rst
);
- e_xclk_tail: entity utility.xclk_vec
+ e_xclk_tail: entity utility.sync_vec
generic map (SYNC_STAGES => SYNC_STAGES)
port map (
- a_sig_i => std_logic_vector(tail_adr_reg),
- b_clk_i => head_clk_i,
- b_sig_o => tail_adr_xclk
+ clk_i => head_clk_i,
+ sig_i => std_logic_vector(tail_adr_reg),
+ sig_o => tail_adr_xclk
);
is_full <= '1' when std_logic_vector(head_adr_next) = tail_adr_xclk else '0';
-- Tail logic
- e_tail_reset: entity utility.sync_rst
+ e_tail_reset: entity utility.sync_sig
generic map (SYNC_STAGES => SYNC_STAGES+1)
port map (
rst_i => rst_i,
clk_i => tail_clk_i,
- rst_o => tail_rst
+ sig_o => tail_rst
);
- e_xclk_head: entity utility.xclk_vec
+ e_xclk_head: entity utility.sync_vec
generic map (SYNC_STAGES => SYNC_STAGES)
port map (
- a_sig_i => std_logic_vector(head_adr_reg),
- b_clk_i => tail_clk_i,
- b_sig_o => head_adr_xclk
+ clk_i => tail_clk_i,
+ sig_i => std_logic_vector(head_adr_reg),
+ sig_o => head_adr_xclk
);
is_empty <= '1' when std_logic_vector(tail_adr_reg) = head_adr_xclk else '0';
+--------------------------------------------------------------------------------
+-- power_on_reset_opt - power-on-reset generator and external reset synchronizer
+--
+-- This holds a design in reset after initial configuration and also
+-- synchronizes an active-high external reset.
+--
+-- After synchronizing the external reset, the reset output is held for an
+-- additional 16 clock cycles to give SRLs time to flush.
+--------------------------------------------------------------------------------
+
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
+library work;
+
entity power_on_reset_opt is
+ generic (
+ SYNC_STAGES: positive := 2
+ );
port (
rst_i: in std_logic := '0';
clk_i: in std_logic;
architecture behavioral of power_on_reset_opt is
- signal shift_reg: std_logic_vector(1 downto 0) := (others => '1');
signal rst_sync: std_logic;
signal count_reg: std_logic_vector(3 downto 0) := (others => '1');
begin
-- Synchronize external asynchronous reset to internal clock
- process (rst_i, clk_i, shift_reg)
- begin
- if rst_i = '1' then
- shift_reg <= (others => '1');
- elsif rising_edge(clk_i) then
- shift_reg <= '0' & shift_reg(shift_reg'high downto 1);
- end if;
- end process;
- rst_sync <= shift_reg(0);
+ e_sync_rst: entity work.sync_sig
+ generic map (SYNC_STAGES => SYNC_STAGES)
+ port map (
+ rst_i => rst_i,
+ clk_i => clk_i,
+ sig_o => rst_sync
+ );
-- Continue to hold reset for 16 clock cycles to allow SRLs to flush
process (rst_sync, clk_i, count_reg, count_running)
+++ /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
+--------------------------------------------------------------------------------
+-- sync_sig - synchronize a signal into a clock domain
+--
+-- Generics:
+-- SYNC_STAGES - number of shift register stages to use
+-- INIT - initial and reset signal value
+--
+-- Ports:
+-- rst_i - asynchronous active high reset to force to INIT value
+-- clk_i - the destination clock domain
+-- sig_i - the source signal
+-- sig_o - the synchronized signal
+--
+-- This can be used to both cross clock domains and synchronize reset signals.
+--
+-- To synchronize an active high reset into a clock domain:
+-- INIT => '1' (default)
+-- rst_i => active high reset signal to synchronize
+-- sig_i => '0' (default)
+--
+-- For signals leaving the design, INIT and rst_i should be used.
+--
+-- For signals entering or within the design, reset can be elided as long as the
+-- rest of the design is left in reset for at least SYNC_STAGES cycles to allow
+-- the synchronizing registers to flush.
+--------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+
+entity sync_sig is
+ generic (
+ SYNC_STAGES: positive := 2;
+ INIT: std_logic := '1'
+ );
+ port (
+ rst_i: in std_logic := '0';
+ clk_i: in std_logic;
+
+ sig_i: in std_logic := '0';
+ sig_o: out std_logic
+ );
+end sync_sig;
+
+
+architecture behavioral of sync_sig is
+
+ signal shift_reg: std_logic_vector(SYNC_STAGES-1 downto 0) := (others => INIT);
+
+begin
+
+ process (clk_i, sig_i, shift_reg)
+ begin
+ if rst_i = '1' then
+ shift_reg <= (others => INIT);
+ elsif rising_edge(clk_i) then
+ shift_reg <= sig_i & shift_reg(SYNC_STAGES-1 downto 1);
+ end if;
+ end process;
+ sig_o <= shift_reg(0);
+
+end behavioral;
--- /dev/null
+--------------------------------------------------------------------------------
+-- sync_vec - synchronize a std_logic_vector into a clock domain
+--
+-- Generics:
+-- SYNC_STAGES - number of shift register stages to use
+--
+-- Ports:
+-- clk_i - the destination clock domain
+-- sig_i - the source signal
+-- sig_o - the synchronized signal
+--
+-- This is probably not what you want. This should only be used when sending
+-- a Gray-coded counter value across clock domains for things like dual-clocked
+-- FIFOs, not for synchronizing data busses. Data busses should be held stable
+-- in their source domain while synchronized handshaking signals negotiate the
+-- crossing.
+--
+-- When sending a Gray-coded value across domains, make sure the value is
+-- registered! Combinational logic to generate a Gray-code value for an integer
+-- can have glitches, which would defeat the purpose of this block if unreggied.
+--
+-- There is no reset logic, so the rest of the design should be held in reset
+-- for at least SYNC_STAGES cycles to flush the synchronizing registers.
+--------------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+
+entity sync_vec is
+ generic (
+ SYNC_STAGES: positive := 2
+ );
+ port (
+ clk_i: in std_logic;
+
+ sig_i: in std_logic_vector;
+ sig_o: out std_logic_vector
+ );
+end sync_vec;
+
+
+architecture behavioral of sync_vec is
+
+ type vec_array is array(natural range <>) of std_logic_vector(sig_i'high downto 0);
+
+ signal shift_reg: vec_array(SYNC_STAGES-1 downto 0);
+
+begin
+
+ process (clk_i, sig_i, shift_reg)
+ begin
+ if rising_edge(clk_i) then
+ shift_reg(SYNC_STAGES-1) <= sig_i;
+ for i in SYNC_STAGES-2 downto 0 loop
+ shift_reg(i) <= shift_reg(i+1);
+ end loop;
+ end if;
+ end process;
+ sig_o <= shift_reg(0);
+
+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;
--- /dev/null
+library ieee;
+use ieee.std_logic_1164.all;
+
+library work;
+
+
+entity test_sync_sig is
+end test_sync_sig;
+
+
+architecture behavior of test_sync_sig is
+
+ constant CLK_I_PERIOD: time := 20 ns;
+
+ signal rst_i: std_logic;
+ signal clk_i: std_logic;
+ signal sig_i: std_logic;
+ signal sig_o: std_logic;
+
+begin
+
+ p_test: process
+ begin
+ rst_i <= '0';
+ sig_i <= '0';
+
+ wait until sig_o = '0';
+ wait for CLK_I_PERIOD*3;
+
+ sig_i <= '1';
+ wait until sig_o = '1';
+ wait for CLK_I_PERIOD*3;
+
+ sig_i <= '0';
+ wait until sig_o = '0';
+ wait for CLK_I_PERIOD*3;
+
+ rst_i <= '1';
+ wait for 1 ns;
+ rst_i <= '0';
+ wait for 1 ns;
+ wait until sig_o = '0';
+ wait for CLK_I_PERIOD*3;
+
+ wait;
+ end process;
+
+ e_uut: entity work.sync_sig
+ generic map (
+ SYNC_STAGES => 5, -- For testing purposes. Should probably be 2 or maybe 3 in a design.
+ INIT => '1'
+ )
+ port map (
+ rst_i => rst_i,
+ clk_i => clk_i,
+ sig_i => sig_i,
+ sig_o => sig_o
+ );
+
+ p_clk: process
+ begin
+ clk_i <= '0';
+ wait for CLK_I_PERIOD/2;
+ clk_i <= '1';
+ wait for CLK_I_PERIOD/2;
+ end process;
+
+end;
--- /dev/null
+library ieee;
+use ieee.std_logic_1164.all;
+
+library work;
+
+
+entity test_sync_vec is
+end test_sync_vec;
+
+
+architecture behavior of test_sync_vec is
+
+ constant CLK_I_PERIOD: time := 20 ns;
+
+ signal clk_i: std_logic;
+ signal sig_i: std_logic_vector(7 downto 0);
+ signal sig_o: std_logic_vector(7 downto 0);
+
+begin
+
+ p_test: process
+ begin
+ sig_i <= x"a5";
+ wait until sig_o = x"a5";
+ wait for CLK_I_PERIOD*3;
+
+ sig_i <= x"c3";
+ wait until sig_o = x"c3";
+ wait for CLK_I_PERIOD*3;
+
+ wait;
+ end process;
+
+ e_uut: entity work.sync_vec
+ generic map (
+ SYNC_STAGES => 5 -- For testing purposes. Should probably be 2 or maybe 3 in a design.
+ )
+ port map (
+ clk_i => clk_i,
+ sig_i => sig_i,
+ sig_o => sig_o
+ );
+
+ p_clk: process
+ begin
+ clk_i <= '0';
+ wait for CLK_I_PERIOD/2;
+ clk_i <= '1';
+ wait for CLK_I_PERIOD/2;
+ end process;
+
+end;
+++ /dev/null
-library ieee;
-use ieee.std_logic_1164.all;
-
-
-entity xclk_sig is
- generic (
- SYNC_STAGES: positive := 2;
- INIT: std_logic := '0'
- );
- port (
- a_sig_i: in std_logic;
-
- b_clk_i: in std_logic;
- b_sig_o: out std_logic
- );
-end xclk_sig;
-
-
-architecture behavioral of xclk_sig is
-
- signal sync_regs: std_logic_vector(SYNC_STAGES-1 downto 0) := (others => INIT);
-
-begin
-
- process (b_clk_i, a_sig_i, sync_regs)
- begin
- if rising_edge(b_clk_i) then
- sync_regs <= a_sig_i & sync_regs(SYNC_STAGES-1 downto 1);
- end if;
- end process;
- b_sig_o <= sync_regs(0);
-
-end behavioral;
+++ /dev/null
-library ieee;
-use ieee.std_logic_1164.all;
-
-
-entity xclk_vec is
- generic (SYNC_STAGES: positive := 2);
- port (
- a_sig_i: in std_logic_vector;
-
- b_clk_i: in std_logic;
- b_sig_o: out std_logic_vector
- );
-end xclk_vec;
-
-
-architecture behavioral of xclk_vec is
-
- 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, sync_regs)
- begin
- if rising_edge(b_clk_i) then
- 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 <= sync_regs(0);
-
-end behavioral;