From: Michael Boehmer Date: Wed, 13 Apr 2022 12:45:59 +0000 (+0200) Subject: DDMTD - first approach X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=ca99336e26c14a4e74458a86134b90f8f3e6d194;p=trbnet.git DDMTD - first approach --- diff --git a/media_interfaces/ecp3_sfp/serdes_sync_all_125M_RS.lpc b/media_interfaces/ecp3_sfp/serdes_sync_all_125M_RS.lpc index be8a991..c6f03fc 100644 --- a/media_interfaces/ecp3_sfp/serdes_sync_all_125M_RS.lpc +++ b/media_interfaces/ecp3_sfp/serdes_sync_all_125M_RS.lpc @@ -166,10 +166,10 @@ _ilsm0=ENABLED _ilsm1=ENABLED _ilsm2=ENABLED _ilsm3=ENABLED -_scomma0=K28P157 -_scomma1=K28P157 -_scomma2=K28P157 -_scomma3=K28P157 +_scomma0=User Defined +_scomma1=User Defined +_scomma2=User Defined +_scomma3=User Defined _comma_a0=1100000101 _comma_a1=1100000101 _comma_a2=1100000101 @@ -178,10 +178,10 @@ _comma_b0=0011111010 _comma_b1=0011111010 _comma_b2=0011111010 _comma_b3=0011111010 -_comma_m0=1111111100 -_comma_m1=1111111100 -_comma_m2=1111111100 -_comma_m3=1111111100 +_comma_m0=1111111111 +_comma_m1=1111111111 +_comma_m2=1111111111 +_comma_m3=1111111111 _ctc0=DISABLED _ctc1=DISABLED _ctc2=DISABLED diff --git a/media_interfaces/ecp3_sfp/serdes_sync_all_125M_RS.txt b/media_interfaces/ecp3_sfp/serdes_sync_all_125M_RS.txt index 477095a..e1b5925 100644 --- a/media_interfaces/ecp3_sfp/serdes_sync_all_125M_RS.txt +++ b/media_interfaces/ecp3_sfp/serdes_sync_all_125M_RS.txt @@ -115,10 +115,10 @@ CH0_COMMA_B "0011111010" CH1_COMMA_B "0011111010" CH2_COMMA_B "0011111010" CH3_COMMA_B "0011111010" -CH0_COMMA_M "1111111100" -CH1_COMMA_M "1111111100" -CH2_COMMA_M "1111111100" -CH3_COMMA_M "1111111100" +CH0_COMMA_M "1111111111" +CH1_COMMA_M "1111111111" +CH2_COMMA_M "1111111111" +CH3_COMMA_M "1111111111" CH0_RXWA "ENABLED" CH1_RXWA "ENABLED" CH2_RXWA "ENABLED" diff --git a/media_interfaces/ecp3_sfp/serdes_sync_all_200M_RS.lpc b/media_interfaces/ecp3_sfp/serdes_sync_all_200M_RS.lpc index c6fde15..b7ca1f0 100644 --- a/media_interfaces/ecp3_sfp/serdes_sync_all_200M_RS.lpc +++ b/media_interfaces/ecp3_sfp/serdes_sync_all_200M_RS.lpc @@ -166,10 +166,10 @@ _ilsm0=ENABLED _ilsm1=ENABLED _ilsm2=ENABLED _ilsm3=ENABLED -_scomma0=K28P157 -_scomma1=K28P157 -_scomma2=K28P157 -_scomma3=K28P157 +_scomma0=User Defined +_scomma1=User Defined +_scomma2=User Defined +_scomma3=User Defined _comma_a0=1100000101 _comma_a1=1100000101 _comma_a2=1100000101 @@ -178,10 +178,10 @@ _comma_b0=0011111010 _comma_b1=0011111010 _comma_b2=0011111010 _comma_b3=0011111010 -_comma_m0=1111111100 -_comma_m1=1111111100 -_comma_m2=1111111100 -_comma_m3=1111111100 +_comma_m0=1111111111 +_comma_m1=1111111111 +_comma_m2=1111111111 +_comma_m3=1111111111 _ctc0=DISABLED _ctc1=DISABLED _ctc2=DISABLED diff --git a/media_interfaces/ecp3_sfp/serdes_sync_all_200M_RS.txt b/media_interfaces/ecp3_sfp/serdes_sync_all_200M_RS.txt index 26149c4..f773134 100644 --- a/media_interfaces/ecp3_sfp/serdes_sync_all_200M_RS.txt +++ b/media_interfaces/ecp3_sfp/serdes_sync_all_200M_RS.txt @@ -115,10 +115,10 @@ CH0_COMMA_B "0011111010" CH1_COMMA_B "0011111010" CH2_COMMA_B "0011111010" CH3_COMMA_B "0011111010" -CH0_COMMA_M "1111111100" -CH1_COMMA_M "1111111100" -CH2_COMMA_M "1111111100" -CH3_COMMA_M "1111111100" +CH0_COMMA_M "1111111111" +CH1_COMMA_M "1111111111" +CH2_COMMA_M "1111111111" +CH3_COMMA_M "1111111111" CH0_RXWA "ENABLED" CH1_RXWA "ENABLED" CH2_RXWA "ENABLED" diff --git a/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd b/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd index 3bef1e5..2ded66a 100644 --- a/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd +++ b/media_interfaces/med_ecp3_sfp_sync_all_RS.vhd @@ -31,6 +31,10 @@ entity med_ecp3_sfp_sync_all_RS is RX_RST_WORD_OUT : out std_logic_vector(7 downto 0); -- RST data byte, registered TX_RST_IN : in std_logic; TX_RST_WORD_IN : in std_logic_vector(7 downto 0); + -- phase measurement + PING_OUT : out std_logic_vector(3 downto 0); + PONG_OUT : out std_logic_vector(3 downto 0); + PONG_CLK_OUT : out std_logic_vector(3 downto 0); -- sync operation WORD_SYNC_IN : in std_logic; -- byte alignment for DLM/RST forwarding (to master port) WORD_SYNC_OUT : out std_logic; -- byte alignment for DLM/RST forwarding (from slave port) @@ -43,7 +47,7 @@ entity med_ecp3_sfp_sync_all_RS is TX_PCS_RST_IN : in std_logic; -- TX PCS reset signal SYNC_TX_PLL_IN : in std_logic; -- bit0 alignment for TX serializer LINK_TX_READY_IN : in std_logic; -- from TX reset generator - DESTROY_LINK_IN : in std_logic_vector(3 downto 0); -- hard reset for links + DISABLE_LINK_IN : in std_logic_vector(3 downto 0); -- disable links by status WAP_REQUESTED_IN : in std_logic_vector(3 downto 0); -- TESTTESTTEST --SFP Connection SD_PRSNT_N_IN : in std_logic_vector(3 downto 0); -- SFP Present ('0' = SFP in place, '1' = no SFP mounted) @@ -131,6 +135,9 @@ architecture med_ecp3_sfp_sync_all_RS_arch of med_ecp3_sfp_sync_all_RS is signal lb_start_i : std_logic; signal lb_start_qsys : std_logic; signal lb_onoff_i : std_logic; + + signal ws_tx_i : std_logic_vector(3 downto 0); + signal ws_rx_i : std_logic_vector(3 downto 0); signal quad_mode : integer range 0 to 100; @@ -182,10 +189,10 @@ begin link_rx_null_i(3) when ((quad_mode >= 8) and (IS_MODE(3) = c_IS_SLAVE)) else '0'; - link_tx_null_i(3) <= (LINK_TX_NULL_IN or DESTROY_LINK_IN(3)) when (IS_MODE(3) = c_IS_MASTER) else '0'; - link_tx_null_i(2) <= (LINK_TX_NULL_IN or DESTROY_LINK_IN(2)) when (IS_MODE(2) = c_IS_MASTER) else '0'; - link_tx_null_i(1) <= (LINK_TX_NULL_IN or DESTROY_LINK_IN(1)) when (IS_MODE(1) = c_IS_MASTER) else '0'; - link_tx_null_i(0) <= (LINK_TX_NULL_IN or DESTROY_LINK_IN(0)) when (IS_MODE(0) = c_IS_MASTER) else '0'; + link_tx_null_i(3) <= LINK_TX_NULL_IN when (IS_MODE(3) = c_IS_MASTER) else '0'; + link_tx_null_i(2) <= LINK_TX_NULL_IN when (IS_MODE(2) = c_IS_MASTER) else '0'; + link_tx_null_i(1) <= LINK_TX_NULL_IN when (IS_MODE(1) = c_IS_MASTER) else '0'; + link_tx_null_i(0) <= LINK_TX_NULL_IN when (IS_MODE(0) = c_IS_MASTER) else '0'; ------------------------------------------------- -- stable RX recovered clock available @@ -270,6 +277,23 @@ begin lb_onoff_i <= TX_RST_WORD_IN(0); +------------------------------------------------- +------------------------------------------------- + PING_OUT(0) <= ws_tx_i(0) when (IS_MODE(0) = c_IS_MASTER) else '0'; + PING_OUT(1) <= ws_tx_i(1) when (IS_MODE(1) = c_IS_MASTER) else '0'; + PING_OUT(2) <= ws_tx_i(2) when (IS_MODE(2) = c_IS_MASTER) else '0'; + PING_OUT(3) <= ws_tx_i(3) when (IS_MODE(3) = c_IS_MASTER) else '0'; + + PONG_OUT(0) <= ws_rx_i(0) when (IS_MODE(0) = c_IS_MASTER) else '0'; + PONG_OUT(1) <= ws_rx_i(1) when (IS_MODE(1) = c_IS_MASTER) else '0'; + PONG_OUT(2) <= ws_rx_i(2) when (IS_MODE(2) = c_IS_MASTER) else '0'; + PONG_OUT(3) <= ws_rx_i(3) when (IS_MODE(3) = c_IS_MASTER) else '0'; + + PONG_CLK_OUT(0) <= clk_rx_full(0) when (IS_MODE(0) = c_IS_MASTER) else '0'; + PONG_CLK_OUT(1) <= clk_rx_full(1) when (IS_MODE(1) = c_IS_MASTER) else '0'; + PONG_CLK_OUT(2) <= clk_rx_full(2) when (IS_MODE(2) = c_IS_MASTER) else '0'; + PONG_CLK_OUT(3) <= clk_rx_full(3) when (IS_MODE(3) = c_IS_MASTER) else '0'; + ------------------------------------------------- -- Serdes ------------------------------------------------- @@ -615,6 +639,7 @@ gen_control : for i in 0 to 3 generate LINK_RX_READY_OUT => link_rx_ready_i(i), LINK_RX_NULL_OUT => link_rx_null_i(i), LINK_TX_NULL_IN => link_tx_null_i(i), + DISABLE_LINK_IN => DISABLE_LINK_IN(i), -- komma operation TX_DLM_IN => TX_DLM_IN, TX_DLM_WORD_IN => TX_DLM_WORD_IN, @@ -624,6 +649,9 @@ gen_control : for i in 0 to 3 generate RX_DLM_WORD_OUT => RX_DLM_WORD_OUT(i*8+7 downto i*8), RX_RST_OUT => rx_rst_i(i), RX_RST_WORD_OUT => rx_rst_word_i(i*8+7 downto i*8), + -- + WS_RX_OUT => ws_rx_i(i), + WS_TX_OUT => ws_tx_i(i), -- Status and debug signals STAT_TX_CONTROL => stat_tx_control_i(i*32+31 downto i*32), STAT_RX_CONTROL => stat_rx_control_i(i*32+31 downto i*32), @@ -651,6 +679,8 @@ gen_control : for i in 0 to 3 generate RX_DLM_WORD_OUT(i*8+7 downto i*8) <= (others => '0'); rx_rst_i(i) <= '0'; rx_rst_word_i(i*8+7 downto i*8) <= (others => '0'); + ws_tx_i(i) <= '0'; + ws_rx_i(i) <= '0'; debug_i(i*32+31 downto i*32) <= (others => '0'); end generate; diff --git a/media_interfaces/sync/med_sync_control_RS.vhd b/media_interfaces/sync/med_sync_control_RS.vhd index 97c377f..82f866a 100644 --- a/media_interfaces/sync/med_sync_control_RS.vhd +++ b/media_interfaces/sync/med_sync_control_RS.vhd @@ -42,10 +42,11 @@ entity med_sync_control_RS is -- ports for synchronous operation WORD_SYNC_IN : in std_logic; -- sync signal for Byte/Word Alignment WORD_SYNC_OUT : out std_logic; - LINK_TX_READY_IN : in std_logic; -- - LINK_RX_READY_OUT : out std_logic; -- + LINK_TX_READY_IN : in std_logic; + LINK_RX_READY_OUT : out std_logic; LINK_RX_NULL_OUT : out std_logic; LINK_TX_NULL_IN : in std_logic; + DISABLE_LINK_IN : in std_logic; -- komma handling TX_DLM_IN : in std_logic; -- transmit one DLM komma TX_DLM_WORD_IN : in std_logic_vector(7 downto 0); @@ -55,6 +56,9 @@ entity med_sync_control_RS is RX_DLM_WORD_OUT : out std_logic_vector(7 downto 0); RX_RST_OUT : out std_logic; -- one RST komma received RX_RST_WORD_OUT : out std_logic_vector(7 downto 0); + -- + WS_RX_OUT : out std_logic; + WS_TX_OUT : out std_logic; -- Status and debug signals STAT_TX_CONTROL : out std_logic_vector(31 downto 0); STAT_RX_CONTROL : out std_logic_vector(31 downto 0); @@ -209,7 +213,9 @@ begin ); DEBUG_RX_CONTROL <= debug_rx_control_i; - + + WS_RX_OUT <= word_sync_rx_i; + -- clocks for media interface media_med2int_i.clk_half <= CLK_RXHALF; -- goes to clock and reset handler media_med2int_i.clk_full <= CLK_RXI; -- goes to clock and reset handler @@ -253,6 +259,8 @@ begin DEBUG_TX_CONTROL <= debug_tx_control_i; + WS_TX_OUT <= word_sync_tx_i; + -- WordSync is taken from RX in case of SP to sync the MPs in a hub. -- In case of a root MP it is taken from MP to sync DLM sending. -- NB: a root MP needs WORD_SYNC_IN set to '1' for operation. @@ -298,7 +306,7 @@ begin media_med2int_i.stat_op(4) <= link_active_qsys; -- rx_allow media_med2int_i.stat_op(3 downto 0) <= link_status_qsys; - link_status <= x"0" when (link_active_i = '1') else x"7"; + link_status <= x"0" when ((link_active_i = '1') and (DISABLE_LINK_IN = '0')) else x"7"; SYNC_MEDIA_SIGS : entity work.signal_sync generic map( @@ -342,5 +350,5 @@ begin DEBUG_OUT(2) <= link_active_qsys; DEBUG_OUT(1) <= link_rx_ready_qsys; DEBUG_OUT(0) <= link_tx_ready_qsys; - + end architecture; diff --git a/special/ddmtd.vhd b/special/ddmtd.vhd new file mode 100644 index 0000000..1f1d35e --- /dev/null +++ b/special/ddmtd.vhd @@ -0,0 +1,94 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; + +entity ddmtd is +port( + AUXCLK : in std_logic; -- auxiliary clock for sampling + RESET : in std_logic; + PING_IN : in std_logic; -- TX_K signal + PONG_IN : in std_logic; -- RX_K signal + PING_OUT : out std_logic; -- stretched TX_K signal + PONG_OUT : out std_logic; -- stretched RX_K signal + START_PING_OUT : out std_logic; -- rising edge of stretched TX_K signal + START_PONG_OUT : out std_logic; -- rising edge of stretched RX_K signal + TOGGLE_OUT : out std_logic; + BEAT_OUT : out std_logic +); +end entity ddmtd; + +architecture ddmtd_arch of ddmtd is + + signal ping_q : std_logic_vector(2 downto 0); + signal pong_q : std_logic_vector(2 downto 0); + signal beat_xor_x : std_logic; + signal beat_xor_q : std_logic; + signal toggle_q : std_logic; + signal start_ping_i : std_logic; + signal start_pong_i : std_logic; + + + attribute HGROUP : string; +-- attribute BBOX : string; + attribute HGROUP of ddmtd_arch : architecture is "ddmtd_group"; +-- attribute BBOX of ddmtd_arch : architecture is "2,2"; + attribute syn_sharing : string; + attribute syn_sharing of ddmtd_arch : architecture is "off"; + attribute syn_hier : string; + attribute syn_hier of ddmtd_arch : architecture is "hard"; + +begin + +THE_SAMPLER_PROC: process( AUXCLK ) +begin + if( rising_edge(AUXCLK) ) then + -- shift register for metastability + ping_q <= ping_q(1 downto 0) & PING_IN; + pong_q <= pong_q(1 downto 0) & PONG_IN; + -- register stages + beat_xor_q <= beat_xor_x; + end if; +end process THE_SAMPLER_PROC; + +-- PING deglitcher +THE_PING_DEGLITCH: entity deglitch +port map( + AUXCLK => AUXCLK, + RESET => RESET, + SIGNAL_IN => ping_q(1), + START_OUT => start_ping_i +); + +-- PONG deglitcher +THE_PONG_DEGLITCH: entity deglitch +port map( + AUXCLK => AUXCLK, + RESET => RESET, + SIGNAL_IN => pong_q(1), + START_OUT => start_pong_i +); + +-- XOR of both stretched signals +beat_xor_x <= ping_q(1) xor pong_q(1); + +-- toggle bit for clock check +THE_TOGGLE_PROC: process( AUXCLK, RESET ) +begin + if ( RESET = '1' ) then + toggle_q <= '0'; + elsif( rising_edge(AUXCLK) ) then + toggle_q <= not toggle_q; + end if; +end process THE_TOGGLE_PROC; + +PING_OUT <= ping_q(1); +PONG_OUT <= pong_q(1); +START_PING_OUT <= start_ping_i; +START_PONG_OUT <= start_pong_i; + +TOGGLE_OUT <= toggle_q; +BEAT_OUT <= beat_xor_q; + +end architecture; diff --git a/special/deglitch.vhd b/special/deglitch.vhd new file mode 100644 index 0000000..d2ba61b --- /dev/null +++ b/special/deglitch.vhd @@ -0,0 +1,65 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +library work; + +entity deglitch is +port( + AUXCLK : in std_logic; + RESET : in std_logic; + SIGNAL_IN : in std_logic; + START_OUT : out std_logic +); +end entity deglitch; + +architecture deglitch_arch of deglitch is + + signal deglitch_q : std_logic_vector(7 downto 0); + signal counter : unsigned(3 downto 0); + signal start_x : std_logic; + signal start_q : std_logic; + signal ctr_up_x : std_logic; + signal ctr_down_x : std_logic; + + attribute HGROUP : string; +-- attribute BBOX : string; + attribute HGROUP of deglitch_arch : architecture is "deglitch_group"; +-- attribute BBOX of deglitch_arch : architecture is "4,4"; + attribute syn_sharing : string; + attribute syn_sharing of deglitch_arch : architecture is "off"; + attribute syn_hier : string; + attribute syn_hier of deglitch_arch : architecture is "hard"; + + begin + +THE_SYNC_PROC: process( AUXCLK ) +begin + if( rising_edge(AUXCLK) ) then + deglitch_q <= deglitch_q(6 downto 0) & SIGNAL_IN; + start_q <= start_x; + end if; +end process THE_SYNC_PROC; + +THE_UP_DOWN_COUNTER_PROC: process( AUXCLK, RESET ) +begin + if ( RESET = '1' ) then + counter <= (others => '0'); + elsif( rising_edge(AUXCLK) ) then + if ( ctr_up_x = '1' ) then + counter <= counter + 1; + elsif( ctr_down_x = '1' ) then + counter <= counter - 1; + end if; + end if; +end process THE_UP_DOWN_COUNTER_PROC; + +ctr_up_x <= '1' when ( (SIGNAL_IN = '1') and (deglitch_q(7) = '0') ) else '0'; +ctr_down_x <= '1' when ( (SIGNAL_IN = '0') and (deglitch_q(7) = '1') ) else '0'; + +--start_x <= '1' when ( counter = x"4" ) else '0'; +start_x <= '1' when ( (counter = x"3") and (ctr_up_x = '1') ) else '0'; + +START_OUT <= start_q; + +end architecture; diff --git a/special/phaser.vhd b/special/phaser.vhd index a1c8ae4..68e3b70 100644 --- a/special/phaser.vhd +++ b/special/phaser.vhd @@ -10,10 +10,10 @@ entity phaser is RESET : in std_logic; START_IN : in std_logic; -- TX DLM STOP_IN : in std_logic; -- RX DLM - PING_IN : in std_logic; -- TX K CLK_PING : in std_logic; -- TX CLK + PING_IN : in std_logic; -- TX K PONG_IN : in std_logic; -- RX K - CLK_PONG : in std_logic; -- RX CLK + SELECT_IN : in std_logic_vector(1 downto 0); RESULT_OUT : out std_logic_vector(31 downto 0); UPDATE_OUT : out std_logic ); @@ -63,9 +63,8 @@ begin port map( SAMPLE_CLK => SAMPLE_CLK, PING_IN => PING_IN, - CLK_PING => CLK_PING, PONG_IN => PONG_IN, - CLK_PONG => CLK_PONG, + SELECT_IN => SELECT_IN, PHASE_OUT => phase ); diff --git a/special/phaser_core.vhd b/special/phaser_core.vhd index 7f11e36..0c36978 100644 --- a/special/phaser_core.vhd +++ b/special/phaser_core.vhd @@ -10,9 +10,8 @@ entity phaser_core is port( SAMPLE_CLK : in std_logic; PING_IN : in std_logic; -- TX K - CLK_PING : in std_logic; -- TX CLK PONG_IN : in std_logic; -- RX K - CLK_PONG : in std_logic; -- RX CLK + SELECT_IN : in std_logic_vector(1 downto 0); PHASE_OUT : out std_logic ); end entity phaser_core; @@ -24,16 +23,17 @@ architecture phaser_core_arch of phaser_core is -- state machine signals -- Signals - signal ping_i : std_logic; - signal pong_i : std_logic; - signal ping_i_q : std_logic; - signal pong_i_q : std_logic; + signal ch_up_x : std_logic; + signal ch_up_q : std_logic; + signal ch_dn_x : std_logic; + signal ch_dn_q : std_logic; signal phase_x : std_logic; - + signal phase : std_logic; + attribute HGROUP : string; attribute BBOX : string; attribute HGROUP of phaser_core_arch : architecture is "phaser_core_group"; - attribute BBOX of phaser_core_arch : architecture is "1,2"; + attribute BBOX of phaser_core_arch : architecture is "1,1"; attribute syn_sharing : string; attribute syn_sharing of phaser_core_arch : architecture is "off"; attribute syn_hier : string; @@ -45,25 +45,30 @@ begin -- we want all logic in here in one PFU (defined timing)! --------------------------------------------------------------------------- --- PINGFF : FD1S3AX port map ( CK => CLK_PING, D => PING_IN, Q => ping_i ); --- PONGFF : FD1S3AX port map ( CK => CLK_PONG, D => PONG_IN, Q => pong_i ); --- --- PINQFF : FD1S3AX port map ( CK => SAMPLE_CLK, D => ping_i, Q => ping_i_q ); --- PONQFF : FD1S3AX port map ( CK => SAMPLE_CLK, D => pong_i, Q => pong_i_q ); --- --- PHXLUT: LUT4 generic map ( INIT => b"0000_0000_0000_0110") --- port map ( A => ping_i_q, B => pong_i_q, C => '0', D => '0', Z => phase_x ); - - -- slice 0 - ping_i <= PING_IN when rising_edge(CLK_PING); -- FF - -- slice 1 - pong_i <= PONG_IN when rising_edge(CLK_PONG); -- FF - -- slice 2 - ping_i_q <= ping_i when rising_edge(SAMPLE_CLK); -- FF - pong_i_q <= pong_i when rising_edge(SAMPLE_CLK); -- FF - -- slice 3 - phase_x <= ping_i_q xor pong_i_q; -- LUT4 + -- LUT4 + ch_up_x <= PING_IN when SELECT_IN = b"00" else + PONG_IN when SELECT_IN = b"01" else + PING_IN when SELECT_IN = b"10" else + PONG_IN; - PHASE_OUT <= phase_x; + -- LUT4 + ch_dn_x <= PING_IN when SELECT_IN = b"00" else + PONG_IN when SELECT_IN = b"01" else + PONG_IN when SELECT_IN = b"10" else + PING_IN; + + -- FF + ch_up_q <= ch_up_x when rising_edge(SAMPLE_CLK); + + -- FF + ch_dn_q <= ch_dn_x when rising_edge(SAMPLE_CLK); + + -- LUT4 + phase_x <= ch_up_q xor ch_dn_q; + + -- FF + phase <= phase_x when rising_edge(SAMPLE_CLK); + + PHASE_OUT <= phase; end architecture;