-- -- Capture ADC sample data from FPGA input ports. -- -- The ADC sends one 14-bit sample per clock cycle. -- These 14 bits are transferred through 7 DDR signals. -- -- Joris van Rantwijk 2024 -- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; library unisim; use unisim.vcomponents.all; use work.puzzlefw_pkg.all; entity adc_capture_ddr is port ( -- Source-synchronous clock for capturing data. clk_capture: in std_logic; -- Clock for intermediate register stage. clk_intermediate: in std_logic; -- System clock for data output. -- This clock is approximately phase aligned with the capture clock. clk_handoff: in std_logic; -- Input signals, DDR. in_data: in std_logic_vector(6 downto 0); -- Output sample stream. -- Produces one new ADC sample per clock cycle. out_data: out adc_data_type ); end entity; architecture arch of adc_capture_ddr is signal s_data_delayed: std_logic_vector(6 downto 0); signal s_data_iddr: std_logic_vector(adc_data_bits - 1 downto 0); signal s_data_staged: std_logic_vector(adc_data_bits - 1 downto 0); signal r_out_data: std_logic_vector(adc_data_bits - 1 downto 0); begin gen_bit_capture: for i in 0 to 6 generate -- Delay input signal. -- Delay by 30 / (32 * 2 * 200 MHz) = 2.34 ns. inst_idelay: IDELAYE2 generic map ( DELAY_SRC => "IDATAIN", HIGH_PERFORMANCE_MODE => "FALSE", IDELAY_TYPE => "FIXED", IDELAY_VALUE => 30, REFCLK_FREQUENCY => 200.0, SIGNAL_PATTERN => "DATA" ) port map ( CNTVALUEOUT => open, DATAOUT => s_data_delayed(i), C => '0', CE => '0', CINVCTRL => '0', CNTVALUEIN => (others => '0'), DATAIN => '0', IDATAIN => in_data(i), INC => '0', LD => '0', LDPIPEEN => '0', REGRST => '0' ); -- DDR input register. inst_iddr: IDDR generic map ( DDR_CLK_EDGE => "SAME_EDGE_PIPELINED" ) port map ( Q1 => s_data_iddr(2*i), Q2 => s_data_iddr(2*i+1), C => clk_capture, CE => '1', D => s_data_delayed(i), R => '0', S => '0' ); end generate; -- -- Re-capture samples on intermediate clock. -- gen_ffpair: for i in 0 to adc_data_bits - 1 generate inst_ffpair: entity work.ffpair port map ( clk1 => clk_capture, clk2 => clk_intermediate, di => s_data_iddr(i), do => s_data_staged(i) ); end generate; -- -- Re-capture samples on system clock. -- process (clk_handoff) is begin if rising_edge(clk_handoff) then r_out_data <= s_data_staged; end if; end process; -- Drive output ports. out_data <= r_out_data; end architecture;