]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
statistics for DDMTD
authorMichael Boehmer <mboehmer@ph.tum.de>
Mon, 18 Apr 2022 06:55:06 +0000 (08:55 +0200)
committerMichael Boehmer <mboehmer@ph.tum.de>
Mon, 18 Apr 2022 06:55:06 +0000 (08:55 +0200)
special/ddmtd.vhd
special/statistics.vhd [new file with mode: 0644]

index c5c3add922e6a32defc95bcc29f85c6e42f51184..0e8b60d2e62397c6d8dce383358ff4a8b547e9fa 100644 (file)
-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;
diff --git a/special/statistics.vhd b/special/statistics.vhd
new file mode 100644 (file)
index 0000000..252f7fb
--- /dev/null
@@ -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;