------------------------------------------------------------------------------- -- Title : Parametrized delay block -- Project : General Cores ------------------------------------------------------------------------------- -- File : gc_delay_line.vhd -- Company : CERN -- Platform : FPGA-generics -- Standard : VHDL '93 ------------------------------------------------------------------------------- -- Copyright (c) 2011-2017 CERN -- -- This source file is free software; you can redistribute it -- and/or modify it under the terms of the GNU Lesser General -- Public License as published by the Free Software Foundation; -- either version 2.1 of the License, or (at your option) any -- later version. -- -- This source is distributed in the hope that it will be -- useful, but WITHOUT ANY WARRANTY; without even the implied -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR -- PURPOSE. See the GNU Lesser General Public License for more -- details. -- -- You should have received a copy of the GNU Lesser General -- Public License along with this source; if not, download it -- from http://www.gnu.org/licenses/lgpl-2.1.html ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.genram_pkg.all; entity gc_delay_line is generic ( g_delay : integer; g_width : integer); port ( clk_i : in std_logic; rst_n_i : in std_logic; d_i : in std_logic_vector(g_width -1 downto 0); q_o : out std_logic_vector(g_width -1 downto 0); ready_o : out std_logic); end gc_delay_line; architecture rtl of gc_delay_line is constant c_counter_width : integer := f_log2_size(g_delay+1); signal rd_ptr : unsigned(c_counter_width-1 downto 0) := (others => '0'); signal wr_ptr : unsigned(c_counter_width-1 downto 0) := (others => '0'); signal init : std_logic; signal wr_data, rd_data : std_logic_vector(g_width-1 downto 0); begin U_DPRAM : generic_dpram generic map ( g_data_width => g_width, g_size => 2**c_counter_width, g_dual_clock => FALSE) port map ( rst_n_i => rst_n_i, clka_i => clk_i, bwea_i => (others => '0'), wea_i => '1', aa_i => std_logic_vector(wr_ptr), da_i => wr_data, clkb_i => clk_i, bweb_i => (others => '0'), web_i => '0', ab_i => std_logic_vector(rd_ptr), db_i => (others => '0'), qb_o => rd_data); wr_data <= (others => '0') when init = '1' else d_i; process(clk_i) begin if rising_edge(clk_i) then if rst_n_i = '0' then wr_ptr <= (others => '0'); rd_ptr <= (others => '0'); init <= '1'; ready_o <= '0'; else if (init = '1') then if (wr_ptr = 2**c_counter_width-1) then wr_ptr <= to_unsigned(g_delay-1, c_counter_width); rd_ptr <= (others => '0'); init <= '0'; ready_o <= '1'; else wr_ptr <= wr_ptr + 1; end if; else wr_ptr <= wr_ptr + 1; rd_ptr <= rd_ptr + 1; end if; end if; end if; end process; q_o <= rd_data; end rtl;