-library ieee;\r
-use ieee.std_logic_1164.all;\r
-use ieee.numeric_std.all;\r
-\r
-library work;\r
-\r
-entity ddmtd is\r
-port(\r
- AUXCLK : in std_logic; -- auxiliary clock for sampling\r
- RESET : in std_logic;\r
- PING_IN : in std_logic; -- TX_K signal\r
- PONG_IN : in std_logic; -- RX_K signal\r
- PING_OUT : out std_logic; -- stretched TX_K signal\r
- PONG_OUT : out std_logic; -- stretched RX_K signal\r
- START_PING_OUT : out std_logic; -- rising edge of stretched TX_K signal\r
- START_PONG_OUT : out std_logic; -- rising edge of stretched RX_K signal\r
- DELAY_VALUE_OUT : out std_logic_vector(15 downto 0);\r
- DELAY_VALID_OUT : out std_logic;\r
- TOGGLE_OUT : out std_logic -- for checking by scope\r
-);\r
-end entity ddmtd;\r
-\r
-architecture ddmtd_arch of ddmtd is\r
-\r
- signal ping_q : std_logic_vector(2 downto 0);\r
- signal pong_q : std_logic_vector(2 downto 0);\r
- signal toggle_q : std_logic;\r
- signal start_ping_i : std_logic;\r
- signal start_pong_i : std_logic;\r
- \r
- signal delay_ce : std_logic;\r
- signal delay_rst : std_logic;\r
- signal delay_ctr : unsigned(9 downto 0);\r
- signal delay_store : std_logic;\r
- signal delay_valid : std_logic;\r
- signal delay_data : std_logic_vector(15 downto 0);\r
-\r
- attribute HGROUP : string;\r
--- attribute BBOX : string;\r
- attribute HGROUP of ddmtd_arch : architecture is "ddmtd_group";\r
--- attribute BBOX of ddmtd_arch : architecture is "2,2";\r
- attribute syn_sharing : string;\r
- attribute syn_sharing of ddmtd_arch : architecture is "off";\r
- attribute syn_hier : string;\r
- attribute syn_hier of ddmtd_arch : architecture is "hard";\r
-\r
-begin\r
-\r
-THE_SAMPLER_PROC: process( AUXCLK )\r
-begin\r
- if( rising_edge(AUXCLK) ) then\r
- -- shift register for metastability\r
- ping_q <= ping_q(1 downto 0) & PING_IN;\r
- pong_q <= pong_q(1 downto 0) & PONG_IN;\r
- -- register stages\r
- end if;\r
-end process THE_SAMPLER_PROC;\r
-\r
--- PING deglitcher\r
-THE_PING_DEGLITCH: entity deglitch\r
-port map(\r
- AUXCLK => AUXCLK,\r
- RESET => RESET,\r
- SIGNAL_IN => ping_q(1),\r
- START_OUT => start_ping_i\r
-);\r
-\r
--- PONG deglitcher\r
-THE_PONG_DEGLITCH: entity deglitch\r
-port map(\r
- AUXCLK => AUXCLK,\r
- RESET => RESET,\r
- SIGNAL_IN => pong_q(1),\r
- START_OUT => start_pong_i\r
-);\r
-\r
--- delay counter\r
-THE_DELAY_CTR_PROC: process( AUXCLK, RESET )\r
-begin\r
- if ( RESET = '1' ) then\r
- delay_ctr <= (others => '0');\r
- elsif( rising_edge(AUXCLK) ) then\r
- if ( delay_rst = '1' ) then\r
- delay_ctr <= (others => '0');\r
- elsif( delay_ce = '1' ) then\r
- delay_ctr <= delay_ctr + 1;\r
- end if;\r
- end if;\r
-end process THE_DELAY_CTR_PROC;\r
-\r
-delay_rst <= start_pong_i;\r
-delay_store <= start_pong_i;\r
-\r
-THE_DELAY_CE_PROC: process( AUXCLK, RESET )\r
-begin\r
- if ( RESET = '1' ) then\r
- delay_ce <= '0';\r
- elsif( rising_edge(AUXCLK) ) then\r
- if ( (start_ping_i = '1') and (start_pong_i = '0') ) then\r
- delay_ce <= '1';\r
- elsif( (start_pong_i = '1') ) then\r
- delay_ce <= '0';\r
- end if;\r
- end if;\r
-end process THE_DELAY_CE_PROC;\r
-\r
-THE_DELAY_STORE_PROC: process( AUXCLK, RESET )\r
-begin\r
- if ( RESET = '1' ) then\r
- delay_data <= (others => '0');\r
- elsif( rising_edge(AUXCLK) ) then\r
- if( delay_store = '1' ) then\r
- delay_data <= b"000000" & std_logic_vector(delay_ctr);\r
- end if;\r
- end if;\r
-end process THE_DELAY_STORE_PROC;\r
-\r
--- toggle bit for clock check\r
-THE_TOGGLE_PROC: process( AUXCLK, RESET )\r
-begin\r
- if ( RESET = '1' ) then\r
- toggle_q <= '0';\r
- elsif( rising_edge(AUXCLK) ) then\r
- toggle_q <= not toggle_q;\r
- end if;\r
-end process THE_TOGGLE_PROC;\r
-\r
-PING_OUT <= ping_q(1);\r
-PONG_OUT <= pong_q(1);\r
-START_PING_OUT <= start_ping_i;\r
-START_PONG_OUT <= start_pong_i;\r
-DELAY_VALUE_OUT <= delay_data;\r
-DELAY_VALID_OUT <= delay_valid;\r
-TOGGLE_OUT <= toggle_q;\r
-\r
-end architecture;\r
+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;
--- /dev/null
+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;