---------------------------------------------------------------------------------- -- Company: -- Engineer: Stefan Zimmer -- -- Create Date: 17:02:15 05/06/2008 -- Design Name: -- Module Name: pattern_sync - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: Samples a signal either on a rising or a falling edge -- and delays it from 0 to 31 clk160 cycles. In addition it can measure the rate of a pattern occurance. -- This feature can be used to select the right sampling edge. -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity pattern_sync is Port ( reset : in STD_LOGIC; clk160 : in STD_Logic; signal_in : in STD_LOGIC; edge_sel : in STD_LOGIC; signal_sync_delayed : out STD_LOGIC; edge_rate : out STD_LOGIC_VECTOR (15 downto 0); set_delay : in STD_LOGIC_VECTOR(4 downto 0)); end pattern_sync; architecture Behavioral of pattern_sync is signal sig1, sig2, sig3, sig5, sig6, sig7, sig8, sig9, sig10: std_logic; signal sig4: std_logic_vector(31 downto 0); signal counter_value_reg_signal: std_logic_vector(15 downto 0); signal rate_counter_int: integer range 0 to (2**14)-1; -- 2**14 is limit for int in xilinx vhdl signal edge_counter_int: integer range 0 to (2**14)-1; -- 2**14 is limit for int in xilinx vhdl attribute period: string; attribute PERIOD of clk160: signal is "4ns"; begin -- sample with negative edge process(clk160, signal_in) begin if clk160'event and clk160='0' then sig1 <= signal_in; end if; end process; process(clk160, sig1) begin if clk160'event and clk160='1' then sig2 <= sig1; end if; end process; -- sample with positive edge process(clk160, signal_in) begin if clk160'event and clk160='1' then sig3 <= signal_in; end if; end process; -- mux to select option --sig4(0) <= (sig2 and not edge_sel) or (sig3 and edge_sel); process(edge_sel, sig2, sig3) begin case (edge_sel) is when '0' => sig4(0) <= sig2; when '1' => sig4(0) <= sig3; when others => sig4(0) <= '0'; end case; end process; -- counter for rate intervall process(clk160, rate_counter_int) begin if clk160'event and clk160 = '1' then if sig6 = '1' then rate_counter_int <= 0; else rate_counter_int <= rate_counter_int+1; end if; end if; end process; sig6 <= '1' when rate_counter_int = ((2**14)-1) else '0'; -- pattern recognitions sig5<= '1' when sig4(8 downto 5) = "0110" else '0'; process(clk160, sig5, sig6) begin if clk160'event and clk160 = '1' then if sig5 = '0' and sig6 = '1' then edge_counter_int <= 0; elsif sig5='1' and sig6='1' then -- if an enable comes while reset is on edge_counter_int <= 1; elsif sig5 = '1' then -- normal increment edge_counter_int <= edge_counter_int+1; end if; end if; end process; -- counter value output register process(clk160,sig6,edge_counter_int) begin if clk160'event and clk160='1' and sig6 = '1' then counter_value_reg_signal(15 downto 0) <= CONV_STD_LOGIC_VECTOR(edge_counter_int, 16); end if; end process; -- delay chain delay_chain: for i in 1 to 31 generate process(reset, clk160, sig4) begin if reset = '1' then sig4(i) <= '0'; elsif (clk160'event and clk160='1') then sig4(i) <= sig4(i-1); end if; end process; end generate; -- fastpath idea: don't guide the 0 delay signal through the big mux or if zero delay -- if the mux is used use an additional register sig7 <= '1' when set_delay(4 downto 0)="00000" else '0'; process(clk160, reset, sig7) begin if reset = '1' then sig8 <= '0'; elsif clk160'event and clk160 = '1' then sig8 <= sig7; end if; end process; --mux_signal --Mux to select delayed signal process(set_delay(4 downto 0), sig4(31 downto 0)) begin case (set_delay(4 downto 0)) is when "00000" => sig9 <= '0'; -- use fastpath instead when "00001" => sig9 <= sig4(0); -- shifted by one for fastpath so is a register after the mux possible when "00010" => sig9 <= sig4(1); when "00011" => sig9 <= sig4(2); when "00100" => sig9 <= sig4(3); when "00101" => sig9 <= sig4(4); when "00110" => sig9 <= sig4(5); when "00111" => sig9 <= sig4(6); when "01000" => sig9 <= sig4(7); when "01001" => sig9 <= sig4(8); when "01010" => sig9 <= sig4(9); when "01011" => sig9 <= sig4(10); when "01100" => sig9 <= sig4(11); when "01101" => sig9 <= sig4(12); when "01110" => sig9 <= sig4(13); when "01111" => sig9 <= sig4(14); when "10000" => sig9 <= sig4(15); when "10001" => sig9 <= sig4(16); when "10010" => sig9 <= sig4(17); when "10011" => sig9 <= sig4(18); when "10100" => sig9 <= sig4(19); when "10101" => sig9 <= sig4(20); when "10110" => sig9 <= sig4(21); when "10111" => sig9 <= sig4(22); when "11000" => sig9 <= sig4(23); when "11001" => sig9 <= sig4(24); when "11010" => sig9 <= sig4(25); when "11011" => sig9 <= sig4(26); when "11100" => sig9 <= sig4(27); when "11101" => sig9 <= sig4(28); when "11110" => sig9 <= sig4(29); when "11111" => sig9 <= sig4(30); when others => sig9 <= sig4(29); end case; end process; process(clk160, reset, sig9) begin if reset = '1' then sig10 <= '0'; elsif clk160'event and clk160 = '1' then sig10 <= sig9; end if; end process; signal_sync_delayed <= sig4(0) when sig8 = '1' else sig10; -- fastpath for sig4(0) edge_rate(15 downto 0) <= counter_value_reg_signal(15 downto 0); end Behavioral;