redpitaya-puzzlefw/fpga/rtl/adc_capture_ddr.vhd

119 lines
3.4 KiB
VHDL
Raw Permalink Normal View History

2024-10-08 08:49:34 +02:00
--
-- 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;