From: Michael Boehmer Date: Mon, 18 Apr 2022 06:55:06 +0000 (+0200) Subject: statistics for DDMTD X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=baadfdf0e970632274b621b78716bac624ed4c8b;p=trbnet.git statistics for DDMTD --- diff --git a/special/ddmtd.vhd b/special/ddmtd.vhd index c5c3add..0e8b60d 100644 --- a/special/ddmtd.vhd +++ b/special/ddmtd.vhd @@ -1,136 +1,157 @@ -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 - DELAY_VALUE_OUT : out std_logic_vector(15 downto 0); - DELAY_VALID_OUT : out std_logic; - TOGGLE_OUT : out std_logic -- for checking by scope -); -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 toggle_q : std_logic; - signal start_ping_i : std_logic; - signal start_pong_i : std_logic; - - signal delay_ce : std_logic; - signal delay_rst : std_logic; - signal delay_ctr : unsigned(9 downto 0); - signal delay_store : std_logic; - signal delay_valid : std_logic; - signal delay_data : std_logic_vector(15 downto 0); - - 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 - 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 -); - --- delay counter -THE_DELAY_CTR_PROC: process( AUXCLK, RESET ) -begin - if ( RESET = '1' ) then - delay_ctr <= (others => '0'); - elsif( rising_edge(AUXCLK) ) then - if ( delay_rst = '1' ) then - delay_ctr <= (others => '0'); - elsif( delay_ce = '1' ) then - delay_ctr <= delay_ctr + 1; - end if; - end if; -end process THE_DELAY_CTR_PROC; - -delay_rst <= start_pong_i; -delay_store <= start_pong_i; - -THE_DELAY_CE_PROC: process( AUXCLK, RESET ) -begin - if ( RESET = '1' ) then - delay_ce <= '0'; - elsif( rising_edge(AUXCLK) ) then - if ( (start_ping_i = '1') and (start_pong_i = '0') ) then - delay_ce <= '1'; - elsif( (start_pong_i = '1') ) then - delay_ce <= '0'; - end if; - end if; -end process THE_DELAY_CE_PROC; - -THE_DELAY_STORE_PROC: process( AUXCLK, RESET ) -begin - if ( RESET = '1' ) then - delay_data <= (others => '0'); - elsif( rising_edge(AUXCLK) ) then - if( delay_store = '1' ) then - delay_data <= b"000000" & std_logic_vector(delay_ctr); - end if; - end if; -end process THE_DELAY_STORE_PROC; - --- 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; -DELAY_VALUE_OUT <= delay_data; -DELAY_VALID_OUT <= delay_valid; -TOGGLE_OUT <= toggle_q; - -end architecture; +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; + -- input signals + PING_IN : in std_logic; -- TX_K signal + PONG_IN : in std_logic; -- RX_K signal + -- test signals + 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; -- for checking by scope + -- result + DELAY_VALUE_OUT : out std_logic_vector(9 downto 0); -- result of measurement + DELAY_VALID_OUT : out std_logic; -- result of measurement is valid + -- remote control + FSM_ACTIVE_IN : in std_logic; + FSM_CE_IN : in std_logic; + FSM_RST_IN : in std_logic; + FSM_CLR_DONE_OUT : out std_logic +); +end entity ddmtd; + +architecture ddmtd_arch of ddmtd is + + component deglitch is + port( + AUXCLK : in std_logic; + RESET : in std_logic; + SIGNAL_IN : in std_logic; + START_OUT : out std_logic + ); + end component deglitch; + + signal ping_q : std_logic_vector(2 downto 0); + signal pong_q : std_logic_vector(2 downto 0); + signal toggle_q : std_logic; + signal start_ping_i : std_logic; + signal start_pong_i : std_logic; + + signal delay_ce : std_logic; + signal delay_ce_x : std_logic; + signal delay_rst : std_logic; + signal delay_ctr : unsigned(10 downto 0); + signal delay_store : std_logic; + signal delay_valid : std_logic; + signal delay_data : std_logic_vector(9 downto 0); + + 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 + delay_valid <= delay_store; + end if; +end process THE_SAMPLER_PROC; + +-- PING deglitcher +THE_PING_DEGLITCH: deglitch +port map( + AUXCLK => AUXCLK, + RESET => RESET, + SIGNAL_IN => ping_q(1), + START_OUT => start_ping_i +); + +-- PONG deglitcher +THE_PONG_DEGLITCH: deglitch +port map( + AUXCLK => AUXCLK, + RESET => RESET, + SIGNAL_IN => pong_q(1), + START_OUT => start_pong_i +); + +-- delay counter +THE_DELAY_CTR_PROC: process( AUXCLK, RESET ) +begin + if ( RESET = '1' ) then + delay_ctr <= (others => '0'); + elsif( rising_edge(AUXCLK) ) then + if ( delay_rst = '1' ) then + delay_ctr <= (others => '0'); + elsif( delay_ce_x = '1' ) then + delay_ctr <= delay_ctr + 1; + end if; + end if; +end process THE_DELAY_CTR_PROC; + +delay_rst <= start_pong_i when FSM_ACTIVE_IN = '0' else FSM_RST_IN; +delay_store <= start_pong_i when FSM_ACTIVE_IN = '0' else '1'; +delay_ce_x <= delay_ce when FSM_ACTIVE_IN = '0' else FSM_CE_IN; + +THE_DELAY_CE_PROC: process( AUXCLK, RESET ) +begin + if ( RESET = '1' ) then + delay_ce <= '0'; + elsif( rising_edge(AUXCLK) ) then + if ( (start_ping_i = '1') and (start_pong_i = '0') ) then + delay_ce <= '1'; + elsif( (start_pong_i = '1') ) then + delay_ce <= '0'; + end if; + end if; +end process THE_DELAY_CE_PROC; + +THE_DELAY_STORE_PROC: process( AUXCLK, RESET ) +begin + if ( RESET = '1' ) then + delay_data <= (others => '0'); + elsif( rising_edge(AUXCLK) ) then + if( delay_store = '1' ) then + delay_data <= std_logic_vector(delay_ctr(9 downto 0)); + end if; + end if; +end process THE_DELAY_STORE_PROC; + +-- 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; +DELAY_VALUE_OUT <= delay_data; +DELAY_VALID_OUT <= delay_valid; +TOGGLE_OUT <= toggle_q; +FSM_CLR_DONE_OUT <= std_logic(delay_ctr(10)); + +end architecture; diff --git a/special/statistics.vhd b/special/statistics.vhd new file mode 100644 index 0000000..252f7fb --- /dev/null +++ b/special/statistics.vhd @@ -0,0 +1,267 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity statistics is +port( + AUXCLK : in std_logic; + RESET : in std_logic; + DELAY_VALUE_IN : in std_logic_vector(9 downto 0); + DELAY_VALID_IN : in std_logic; + FSM_START_IN : in std_logic; + FSM_CLR_DONE_IN : in std_logic; + FSM_ACTIVE_OUT : out std_logic; + FSM_CE_OUT : out std_logic; + FSM_RST_OUT : out std_logic; + FSM_DONE_OUT : out std_logic; + RD_CLK : in std_logic; + RD_ADDRESS_IN : in std_logic_vector(9 downto 0); + RD_DATA_OUT : out std_logic_vector(17 downto 0) +); +end; + +architecture behavioural of statistics is + +-- Statemachine signals + type state_t is (IDLE,RSTCTR,DLY0,WCLR,PCTR,DLY1,WFD,WFD1,WFD2,WFD3,SDONE); + signal STATE, NEXT_STATE : state_t; + + signal bsm : std_logic_vector(3 downto 0); + +-- Signals + signal fsm_act_x : std_logic; + signal fsm_act_q : std_logic; + signal fsm_ce_x : std_logic; + signal fsm_ce_q : std_logic; + signal fsm_rst_x : std_logic; + signal fsm_rst_q : std_logic; + signal fsm_we_x : std_logic; + signal fsm_we_q : std_logic; + signal fsm_done_x : std_logic; + signal fsm_done_q : std_logic; + + signal sum_ctr : unsigned(18 downto 0); + signal sum_ctr_rst_x : std_logic; + signal sum_ctr_rst : std_logic; + signal sum_ctr_ce_x : std_logic; + signal sum_ctr_ce : std_logic; + signal sum_ctr_done : std_logic; + + signal old_entry : std_logic_vector(17 downto 0); + signal new_entry_x : unsigned(17 downto 0); + signal new_entry : std_logic_vector(17 downto 0); + signal clr_entry : std_logic; + + signal mean_sum_x : unsigned(31 downto 0); + signal mean_sum_q : unsigned(31 downto 0); + + component stat_mem is + port( + DATAINA : in std_logic_vector(17 downto 0); + DATAINB : in std_logic_vector(17 downto 0); + ADDRESSA : in std_logic_vector(9 downto 0); + ADDRESSB : in std_logic_vector(9 downto 0); + CLOCKA : in std_logic; + CLOCKB : in std_logic; + CLOCKENA : in std_logic; + CLOCKENB : in std_logic; + WRA : in std_logic; + WRB : in std_logic; + RESETA : in std_logic; + RESETB : in std_logic; + QA : out std_logic_vector(17 downto 0); + QB : out std_logic_vector(17 downto 0) + ); + end component stat_mem; + +attribute HGROUP: string; +--attribute BBOX: string; +attribute HGROUP of behavioural: architecture is "statistics"; +--attribute BBOX of behavioural: architecture is "5,5"; + +begin + +----------------------------------------------------------- +-- statemachine: clocked process +----------------------------------------------------------- + THE_STATEMACHINE: process( AUXCLK, RESET ) + begin + if ( RESET = '1' ) then + STATE <= IDLE; + fsm_act_q <= '0'; + fsm_ce_q <= '0'; + fsm_we_q <= '0'; + fsm_rst_q <= '0'; + fsm_done_q <= '0'; + sum_ctr_ce <= '0'; + sum_ctr_rst <= '0'; + elsif( rising_edge(AUXCLK) ) then + STATE <= NEXT_STATE; + fsm_act_q <= fsm_act_x; + fsm_ce_q <= fsm_ce_x; + fsm_we_q <= fsm_we_x; + fsm_rst_q <= fsm_rst_x; + fsm_done_q <= fsm_done_x; + sum_ctr_ce <= sum_ctr_ce_x; + sum_ctr_rst <= sum_ctr_rst_x; + end if; + end process THE_STATEMACHINE; + +----------------------------------------------------------- +-- state machine transition table +----------------------------------------------------------- + THE_STATE_TRANSITIONS: process( STATE, FSM_START_IN, FSM_CLR_DONE_IN, DELAY_VALID_IN, sum_ctr_done ) + begin + NEXT_STATE <= IDLE; + fsm_act_x <= '0'; + fsm_ce_x <= '0'; + fsm_we_x <= '0'; + fsm_rst_x <= '0'; + fsm_done_x <= '0'; + sum_ctr_ce_x <= '0'; + sum_ctr_rst_x <= '0'; + case STATE is + when IDLE => bsm <= x"0"; + if( FSM_START_IN = '1') then + NEXT_STATE <= RSTCTR; + fsm_act_x <= '1'; + fsm_rst_x <= '1'; + sum_ctr_rst_x <= '1'; + else + NEXT_STATE <= IDLE; + end if; + when RSTCTR => bsm <= x"1"; + NEXT_STATE <= DLY0; + fsm_act_x <= '1'; + fsm_we_x <= '1'; + when DLY0 => bsm <= x"2"; + NEXT_STATE <= WCLR; + fsm_act_x <= '1'; + fsm_ce_x <= '1'; + fsm_we_x <= '1'; + when WCLR => bsm <= x"3"; + if( FSM_CLR_DONE_IN = '1' ) then + NEXT_STATE <= PCTR; + fsm_act_x <= '1'; + fsm_rst_x <= '1'; + fsm_we_x <= '1'; + else + NEXT_STATE <= WCLR; + fsm_act_x <= '1'; + fsm_ce_x <= '1'; + fsm_we_x <= '1'; + end if; + when PCTR => bsm <= x"4"; + NEXT_STATE <= DLY1; + fsm_act_x <= '1'; + when DLY1 => bsm <= x"5"; + if( DELAY_VALID_IN = '1' ) then + NEXT_STATE <= WFD; + else + NEXT_STATE <= DLY1; + fsm_act_x <= '1'; + end if; + when WFD => bsm <= x"6"; + if( DELAY_VALID_IN = '1' ) then + NEXT_STATE <= WFD1; + sum_ctr_ce_x <= '1'; + else + NEXT_STATE <= WFD; + end if; + when WFD1 => bsm <= x"7"; + NEXT_STATE <= WFD2; + when WFD2 => bsm <= x"8"; + NEXT_STATE <= WFD3; + when WFD3 => bsm <= x"9"; + if ( sum_ctr_done = '1' ) then + NEXT_STATE <= SDONE; + fsm_done_x <= '1'; + else + NEXT_STATE <= WFD; + fsm_we_x <= '1'; + end if; + when SDONE => bsm <= x"a"; + NEXT_STATE <= SDONE; -- BUG + fsm_done_x <= '1'; + when others => bsm <= x"f"; + NEXT_STATE <= IDLE; + end case; + end process THE_STATE_TRANSITIONS; + +-- Memory for statistics data + THE_STAT_MEM: stat_mem + port map( + DATAINA => new_entry, + DATAINB => (others => '0'), + ADDRESSA => DELAY_VALUE_IN, + ADDRESSB => RD_ADDRESS_IN, + CLOCKA => AUXCLK, + CLOCKB => RD_CLK, + CLOCKENA => '1', + CLOCKENB => '1', + WRA => fsm_we_q, + WRB => '0', + RESETA => RESET, + RESETB => RESET, + QA => old_entry, + QB => RD_DATA_OUT + ); + + -- increment bin value + new_entry_x <= unsigned(old_entry) + 1; + + -- store or provide "0" + THE_STORE_PROC: process( AUXCLK ) + begin + if( rising_edge(AUXCLK) ) then + if( clr_entry = '1' ) then + new_entry <= (others => '0'); + else + new_entry <= std_logic_vector(new_entry_x); + end if; + end if; + end process THE_STORE_PROC; + + clr_entry <= fsm_act_q; + +-- counter for number of entries + THE_SUM_CTR_PROC: process( AUXCLK, RESET ) + begin + if ( RESET = '1' ) then + sum_ctr <= (others => '0'); + elsif( rising_edge(AUXCLK) ) then + if ( sum_ctr_rst = '1' ) then + sum_ctr <= (others => '0'); + elsif( sum_ctr_ce = '1' ) then + sum_ctr <= sum_ctr + 1; + end if; + end if; + end process THE_SUM_CTR_PROC; + +-- sum_ctr_done <= std_logic(sum_ctr(18)); +-- sum_ctr_done <= std_logic(sum_ctr(13)); + sum_ctr_done <= std_logic(sum_ctr(16)); + +-- mean value + mean_sum_x <= mean_sum_q + unsigned(DELAY_VALUE_IN); + + THE_MEAN_SUM_PROC: process( AUXCLK, RESET ) + begin + if ( RESET = '1' ) then + mean_sum_q <= (others => '0'); + elsif( rising_edge(AUXCLK) ) then + if ( fsm_act_q = '1' ) then + mean_sum_q <= (others => '0'); + elsif( fsm_we_q = '1' ) then + mean_sum_q <= mean_sum_x; + end if; + end if; + end process THE_MEAN_SUM_PROC; + +-- Outputs + FSM_ACTIVE_OUT <= fsm_act_q; + FSM_CE_OUT <= fsm_ce_q; + FSM_RST_OUT <= fsm_rst_q; + FSM_DONE_OUT <= fsm_done_q; + +end behavioural;