]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
add experimental double edge detection to monitor design
authorJan Michel <j.michel@gsi.de>
Mon, 11 Sep 2017 11:17:26 +0000 (13:17 +0200)
committerJan Michel <j.michel@gsi.de>
Mon, 11 Sep 2017 12:01:37 +0000 (14:01 +0200)
base/code/double_edge_detection.vhd [new file with mode: 0644]
monitor/config_compile_frankfurt.pl
monitor/sim/tb_double_edge_detection.vhd [new file with mode: 0644]
monitor/trb3_periph_monitor.lpf
monitor/trb3_periph_monitor.prj
monitor/trb3_periph_monitor.vhd

diff --git a/base/code/double_edge_detection.vhd b/base/code/double_edge_detection.vhd
new file mode 100644 (file)
index 0000000..96207dc
--- /dev/null
@@ -0,0 +1,209 @@
+library ieee;
+  use ieee.std_logic_1164.all;
+  use ieee.numeric_std.all;
+  
+library work;
+  use work.trb_net_std.all;
+  use work.config.all;
+
+entity double_edge_detection is
+  generic(
+    CHANNELS : integer := 32
+    );
+  port(
+    CLK         : in std_logic;
+    RESET       : in std_logic;
+    
+    INP         : in std_logic_vector(CHANNELS-1 downto 0);
+    
+    --Slowcontrol
+    BUS_RX     : in  CTRLBUS_RX;
+    BUS_TX     : out CTRLBUS_TX;
+    
+    READOUT_RX : in  READOUT_RX;
+    READOUT_TX : out READOUT_TX;
+    
+    DEBUG_OUT  : out std_logic_vector(7 downto 0)
+    
+    );
+end entity;
+
+
+architecture arch of double_edge_detection is
+
+  signal maxage          : unsigned(15 downto 0);
+  signal waitage         : unsigned(15 downto 0);
+  signal window          : unsigned(3 downto 0);
+
+  signal timer           : unsigned(27 downto 0);
+
+  type storage_t is array (0 to CHANNELS) of std_logic_vector(31 downto 0);
+  signal storage : storage_t;
+  signal clear_storage : std_logic;
+
+  signal data_counter : integer range 0 to 65535;
+
+  type state_t is (IDLE, WAIT_AFTER, WRITE, FINISH, BUSYEND);
+  signal state : state_t;
+
+  signal found_double    : std_logic_vector(CHANNELS-1 downto 0);
+
+
+--   signal reg_INP                              : std_logic_vector(CHANNELS-1 downto 0);
+--   signal INP_low, reg_INP_low, reg2_INP_low   : std_logic_vector(CHANNELS-1 downto 0);
+--   signal INP_low_long, reg_INP_low_long       : std_logic_vector(CHANNELS-1 downto 0);
+  
+  signal reg_INP, INP_b, reg2_INP, reg3_INP, INP_long        : std_logic_vector(CHANNELS-1 downto 0);
+  signal INP_low, reg_INP_low, reg2_INP_low   : std_logic_vector(CHANNELS-1 downto 0);
+  signal INP_low_long, reg_INP_low_long       : std_logic_vector(CHANNELS-1 downto 0);
+  signal reset_found : std_logic_vector(CHANNELS-1 downto 0);
+   
+  
+  
+begin
+
+PROC_REGS : process begin
+  wait until rising_edge(CLK);
+  BUS_TX.ack     <= '0';
+  BUS_TX.nack    <= '0';
+  BUS_TX.unknown <= '0';
+  BUS_TX.data    <= (others => '0');
+  
+  if BUS_RX.write = '1' then
+    BUS_TX.ack <= '1';
+    case BUS_RX.addr(1 downto 0) is
+--       when "00"   => maxage <= unsigned(BUS_RX.data(15 downto 0));  -- max age to include in data, not implemented yet
+      when "01"   => waitage <= unsigned(BUS_RX.data(15 downto 0)); -- time after reference time
+      when "10"   => window  <= unsigned(BUS_RX.data(3 downto 0));  --clock cycles between rising edges
+      when others => BUS_TX.ack <= '0'; BUS_TX.unknown <= '1';
+    end case;
+  elsif BUS_RX.read = '1' then
+    BUS_TX.ack <= '1';
+    case BUS_RX.addr(1 downto 0) is
+--       when "00"   => BUS_TX.data(15 downto 0) <= std_logic_vector(maxage);
+      when "01"   => BUS_TX.data(15 downto 0) <= std_logic_vector(waitage);
+      when "10"   => BUS_TX.data(3 downto 0)  <= std_logic_vector(window);
+      when others => BUS_TX.ack <= '0'; BUS_TX.unknown <= '1';
+    end case;
+  end if;
+end process;
+
+
+THE_TIME : process begin
+  wait until rising_edge(CLK);
+  timer <= timer + 1;
+end process;
+
+
+THE_RDO : process begin
+  wait until rising_edge(CLK);
+  READOUT_TX.busy_release  <= '0';
+  READOUT_TX.data_write    <= '0';
+  READOUT_TX.data_finished <= '0';
+  clear_storage <= '0';  
+  
+  case state is
+    when IDLE => 
+      if READOUT_RX.valid_timing_trg = '1' or READOUT_RX.valid_notiming_trg = '1' then
+        state <= WAIT_AFTER;
+      end if;
+      if READOUT_RX.invalid_trg = '1' then
+        state <= FINISH;
+      end if;
+      data_counter <= 0;
+    when WAIT_AFTER =>
+      data_counter <= data_counter + 1;
+      if waitage = 0 or to_unsigned(data_counter,16) = waitage then
+        state <= WRITE;
+        data_counter <= 0;
+      end if;  
+    when WRITE =>
+      READOUT_TX.data  <= storage(data_counter);
+      READOUT_TX.data_write <= '1';
+      data_counter <= data_counter + 1;
+      if data_counter = CHANNELS then
+        state <= FINISH;
+      end if;
+    when FINISH =>
+      state <= BUSYEND;
+      READOUT_TX.data_finished <= '1';
+      clear_storage <= '1';
+    when BUSYEND =>
+      state <= IDLE;
+      READOUT_TX.busy_release <= '1';
+  end case;
+end process;
+
+
+THE_STORE : process begin
+  wait until rising_edge(CLK);
+  for i in 0 to CHANNELS-1 loop
+    if found_double(i) = '1' then
+      storage(i+1) <= "1000" & std_logic_vector(timer);
+    elsif clear_storage = '1' then
+      storage(i+1) <= (others => '0');
+    end if;
+  end loop;
+  
+  if READOUT_RX.valid_timing_trg = '1' then
+    storage(0) <= "1000" & std_logic_vector(timer);
+  elsif clear_storage = '1' then
+    storage(0) <= (others => '0');
+  end if;
+end process;
+  
+  
+-- THE_DETECT : process begin
+--   wait until rising_edge(CLK);
+--   for i in 0 to CHANNELS-1 loop
+--     if reg_INP(i) = '1' and reg_INP_low_long(i) = '1' then
+--       found_double(i) <= '1';
+--     else
+--       found_double(i) <= '0';
+--     end if;  
+--   end loop;
+-- end process;
+-- 
+-- 
+-- -- INP_b      <= INP or INP_b and not reg_INP_b;
+-- reg_INP  <= INP      when rising_edge(CLK);
+-- 
+-- -- reg3_INP_b <= reg2_INP_b when rising_edge(CLK);
+-- -- INP_long   <= reg3_INP_b or reg2_INP_b or reg_INP_b or INP_b;
+-- 
+-- INP_low      <= not INP and reg_INP;
+-- 
+-- reg_INP_low  <= INP_low     when rising_edge(CLK);
+-- reg2_INP_low <= reg_INP_low when rising_edge(CLK);
+-- INP_low_long <= INP_low or reg_INP_low or reg2_INP_low;
+-- reg_INP_low_long <= INP_low_long when rising_edge(CLK);
+-- 
+
+
+INP_b    <= (INP or INP_b) and not reg_INP;
+reg_INP  <= INP_b      when rising_edge(CLK);
+reg2_INP <= reg_INP    when rising_edge(CLK);
+reg3_INP <= reg2_INP when rising_edge(CLK);
+INP_long   <= reg3_INP or reg2_INP or reg_INP or INP_b;
+
+THE_DETECT : process(reset_found, INP) begin
+  for i in 0 to CHANNELS-1 loop
+    if reset_found(i) = '1' then
+      found_double(i) <= '0';
+    elsif rising_edge(INP(i)) and INP_long(i) = '1' then
+      found_double(i) <= '1';
+    end if;  
+  end loop;  
+end process;
+
+reset_found <= found_double when rising_edge(CLK);
+
+
+
+
+DEBUG_OUT <= "0000" & found_double(0) & INP_low_long(0) & INP_low(0) & INP(0);
+
+end architecture;
+
+
+
index 5fee652c97bde7e276485346b8f4d828e840404d..c5df8757ab5f700ecc2e65e2e8682a279e51d482 100644 (file)
@@ -21,4 +21,4 @@ twr_number_of_errors         => 20,
 Familyname  => 'LatticeECP3',
 Devicename  => 'LFE3-150EA',
 Package     => 'FPBGA672',
-Speedgrade  => '8',
\ No newline at end of file
+Speedgrade  => '8',
diff --git a/monitor/sim/tb_double_edge_detection.vhd b/monitor/sim/tb_double_edge_detection.vhd
new file mode 100644 (file)
index 0000000..fb31fa5
--- /dev/null
@@ -0,0 +1,80 @@
+library ieee;
+  use ieee.std_logic_1164.all;
+  use ieee.numeric_std.all;
+  
+
+entity double_edge_detection is
+end entity;
+
+
+
+architecture arch of double_edge_detection is
+  constant CHANNELS :integer := 1;
+
+  signal CLK : std_logic := '1';
+  
+  signal found_double    : std_logic := '0';
+
+
+  signal reg_INP, INP, INP_b, reg2_INP, reg3_INP, INP_long        : std_logic := '0';
+  signal INP_low, reg_INP_low, reg2_INP_low   : std_logic := '0';
+  signal INP_low_long, reg_INP_low_long       : std_logic := '0';
+  signal reset_found : std_logic := '0';
+  
+
+begin
+
+CLK <= not CLK after 5 ns;
+
+PROC_STIM : process begin
+  INP <= '0';  wait for 105.3 ns;
+  INP <= '1';  wait for 1 ns;
+  INP <= '0';  wait for 1 ns;
+  INP <= '1';  wait for 1 ns;
+  INP <= '0';
+  wait for 101 ns;
+
+end process;
+  
+-- THE_DETECT : process begin
+--   wait until rising_edge(CLK);
+--     if (reg_INP = '1') and reg_INP_low_long = '1' then
+--       found_double <= '1';
+--     else
+--       found_double <= '0';
+--     end if;  
+-- end process;
+-- 
+-- 
+-- 
+-- INP_b    <= (INP or INP_b) and not reg_INP;
+-- reg_INP  <= INP_b      when rising_edge(CLK);
+-- reg2_INP <= reg_INP    when rising_edge(CLK);
+-- -- reg3_INP_b <= reg2_INP_b when rising_edge(CLK);
+-- -- INP_long   <= reg3_INP_b or reg2_INP_b or reg_INP_b or INP_b;
+-- 
+-- INP_low      <= (not INP and reg_INP) or (INP_low  and not reg_INP_low);
+-- 
+-- reg_INP_low  <= INP_low     when rising_edge(CLK);
+-- reg2_INP_low <= reg_INP_low when rising_edge(CLK);
+-- INP_low_long <= INP_low or reg_INP_low or reg2_INP_low;
+-- reg_INP_low_long <= INP_low_long when rising_edge(CLK);
+-- 
+
+INP_b    <= (INP or INP_b) and not reg_INP;
+reg_INP  <= INP_b      when rising_edge(CLK);
+reg2_INP <= reg_INP    when rising_edge(CLK);
+reg3_INP <= reg2_INP when rising_edge(CLK);
+INP_long   <= reg3_INP or reg2_INP or reg_INP or INP_b;
+
+THE_DETECT : process(reset_found, INP) begin
+  if reset_found = '1' then
+    found_double <= '0';
+  elsif rising_edge(INP) and INP_long = '1' then
+    found_double <= '1';
+  end if;  
+end process;
+
+reset_found <= found_double when rising_edge(CLK);
+
+end architecture;
index bb534d0d9467fe99dd4799d83e5bcb5f14d92754..ba318c5c75b95186a21e25c3ab9125e3e217e2b7 100644 (file)
@@ -31,6 +31,8 @@ LOCATE UGROUP        "THE_MEDIA_UPLINK/media_interface_group" REGION "MEDIA_UPLI
 MULTICYCLE TO CELL  "THE_SPI_RELOAD_THE_SPI_MASTER_THE_SPI_SLIM_tx_sreg_oregio*" 20 ns;
 
 
+PROHIBIT PRIMARY NET "INP";
+PROHIBIT SECONDARY NET "INP";
 
 #################################################################
 # Clocks
index 05a6aa78ab6615842c0725736c9e1a0bf511c486..c0daae213df9d82eea6b8c4a9ecf04e5cca508e2 100644 (file)
@@ -156,6 +156,7 @@ add_file -vhdl -lib work "../../trb3sc/code/spi_master_generic.vhd"
 add_file -vhdl -lib work "../base/code/input_to_trigger_logic_record.vhd"
 add_file -vhdl -lib work "../base/code/input_statistics.vhd"
 add_file -vhdl -lib work "../base/code/sedcheck.vhd"
+add_file -vhdl -lib work "../base/code/double_edge_detection.vhd"
 
 
 add_file -vhdl -lib work "trb3_periph_monitor.vhd"
index fa60f1501ffc4120d7d00d60dae8f83d34be5297..6dd5169d4d1e1adee52645ca32a0bc56979558ae 100644 (file)
@@ -117,6 +117,8 @@ architecture arch of trb3_periph_monitor is
   signal serdes_i          : std_logic_vector(3 downto 0);
   attribute nopad : string;
   attribute nopad of  serdes_i : signal is "true";  
+  
+  signal debug_double_edge : std_logic_vector(7 downto 0);
 
 begin
 ---------------------------------------------------------------------------
@@ -370,30 +372,34 @@ THE_ENDPOINT : entity work.trb_net16_endpoint_hades_full_handler_record
 ---------------------------------------------------------------------------
 -- Test Connector - Additional Features
 ---------------------------------------------------------------------------
-  TEST_LINE <= feature_outputs_i;
+--   TEST_LINE <= feature_outputs_i;
+TEST_LINE(7 downto 0) <= debug_double_edge;
 
 -------------------------------------------------------------------------------
 -- Your logic
 -------------------------------------------------------------------------------
---   THE_Logic : entity work.XXXXX
---     port map (
---       RESET              => reset_i,
---       CLK                => clk_100_i,
---       REFERENCE_TIME     => timing_trg_received_i,  -- Reference time input
---       --Inputs from AddOn and trigger signal to CTS (4 lines)
---       SIGNAL_IN          => INP,
---       TRIGGER_OUT        => trig_gen_out_i,
---       -- Trigger signals from handler & readout data
---       BUSRDO_RX          => readout_rx,
---       BUSRDO_TX          => readout_tx(0),
---       -- Slow control bus
---       BUS_RX             => busrdo_rx,
---       BUS_TX             => busrdo_tx
--- 
---       );
-readout_tx(0).data_finished <= '1';
-readout_tx(0).data_write    <= '0';
-readout_tx(0).busy_release  <= '1';
 
 
+THE_DOUBLE_EDGE_DETECTOR : entity work.double_edge_detection
+  generic map(
+    CHANNELS => 32
+    )
+  port map(
+    CLK         => clk_100_i,
+    RESET       => reset_i,
+    
+    INP         => INP(31 downto 0),
+    
+    -- Trigger signals from handler & readout data
+    READOUT_RX          => readout_rx,
+    READOUT_TX          => readout_tx(0),
+    
+    -- Slow control bus
+    BUS_RX             => busrdo_rx,
+    BUS_TX             => busrdo_tx,
+    
+    DEBUG_OUT => debug_double_edge
+    
+    );
+
 end architecture;