From 03a6437ec9bcddd3842e3bab851e2cfbc5fb57c4 Mon Sep 17 00:00:00 2001 From: Andreas Neiser Date: Mon, 8 Jun 2015 14:00:02 +0200 Subject: [PATCH] Rework the EPOCH counter handling --- ADC/config.vhd | 2 +- ADC/sim/tb_adcprocessor_cfd.vhd | 3 +- ADC/source/adc_ad9219.vhd | 2 +- ADC/source/adc_handler.vhd | 66 +++++++++++++++++++++++++++-- ADC/source/adc_package.vhd | 3 +- ADC/source/adc_processor_cfd.vhd | 42 +++++++++--------- ADC/source/adc_processor_cfd_ch.vhd | 13 +++--- ADC/trb3_periph_adc.vhd | 17 +++----- 8 files changed, 100 insertions(+), 48 deletions(-) diff --git a/ADC/config.vhd b/ADC/config.vhd index 8727570..b3db5e1 100644 --- a/ADC/config.vhd +++ b/ADC/config.vhd @@ -39,7 +39,7 @@ package config is -- with TDC and lattice diamond version >2.1 constant ADC_CHANNELS : integer := 36; - --Include the TDC (only usefule for CFD readout mode) + --Include the TDC (only useful for CFD readout mode) constant INCLUDE_TDC : integer := c_YES; --double edge type: 0, 1, 2, 3 diff --git a/ADC/sim/tb_adcprocessor_cfd.vhd b/ADC/sim/tb_adcprocessor_cfd.vhd index 80914fa..0eec64f 100644 --- a/ADC/sim/tb_adcprocessor_cfd.vhd +++ b/ADC/sim/tb_adcprocessor_cfd.vhd @@ -120,7 +120,8 @@ begin DEBUG_BUFFER_DATA => open, DEBUG_BUFFER_READY => open, READOUT_TX => readout_tx, - READOUT_RX => readout_rx + READOUT_RX => readout_rx, + EPOCH_COUNTER_IN => (others => '0') ); PROC_ADC : process diff --git a/ADC/source/adc_ad9219.vhd b/ADC/source/adc_ad9219.vhd index d032e1c..b8c6731 100644 --- a/ADC/source/adc_ad9219.vhd +++ b/ADC/source/adc_ad9219.vhd @@ -121,7 +121,7 @@ begin restart_i <= RESTART_IN when rising_edge(clk_data); assert (ADC_CHANNELS = 48 or ADC_CHANNELS = 36) - report "The number of either 48 or 36." severity error; + report "The number of ADC_CHANNELS must be either 48 or 36." severity error; gen_7 : if NUM_DEVICES = 7 and ADC_CHANNELS = 48 generate diff --git a/ADC/source/adc_handler.vhd b/ADC/source/adc_handler.vhd index 27d5ceb..53867a6 100644 --- a/ADC/source/adc_handler.vhd +++ b/ADC/source/adc_handler.vhd @@ -21,7 +21,9 @@ entity adc_handler is TRIGGER_FLAG_OUT : out std_logic; --Readout READOUT_RX : in READOUT_RX; + READOUT_TX_CFD : out READOUT_TX; READOUT_TX : out readout_tx_array_t(0 to (DEVICES_1 + DEVICES_2) - 1); + --Slow control BUS_RX : in CTRLBUS_RX; BUS_TX : out CTRLBUS_TX; @@ -81,7 +83,10 @@ architecture adc_handler_arch of adc_handler is signal adc_clk : std_logic_vector(DEVICES downto 1) := (others => '1'); signal adc_clk_left, adc_clk_right : std_logic := '1'; - signal adc_clk_tdc_out_i : std_logic_vector(DEVICES-1 downto 0); + signal epoch_counter, epoch_counter_save, epoch_counter_save_sys : unsigned(EPOCH_COUNTER_SIZE-1 downto 0) := (others => '0'); + signal trigger_in_i : std_logic; + type state_cfd_t is (IDLE, DO_RELEASE, RELEASE_DIRECT, WAIT_FOR_END, WRITE_EPOCH); + signal state_cfd : state_cfd_t; -- 000 - 0ff configuration -- 000 reset, buffer clear strobes @@ -390,11 +395,66 @@ begin DEBUG_BUFFER_READY => buffer_ready(i), READOUT_RX => READOUT_RX, READOUT_TX => READOUT_TX(i), - ADC_CLK_TDC_OUT => adc_clk_tdc_out_i(i) + EPOCH_COUNTER_IN => epoch_counter ); end generate; - ADC_CLK_TDC_OUT <= adc_clk_tdc_out_i(5); -- select 5 as it's closest to the TDC placement + ADC_CLK_TDC_OUT <= epoch_counter(10); + + PROC_EPOCH_COUNTER : process is + begin + wait until rising_edge(adc_clk_left); + epoch_counter <= epoch_counter + 1; + trigger_in_i <= TRIGGER_IN; + if trigger_in_i = '1' then + epoch_counter_save <= epoch_counter; + end if; + end process PROC_EPOCH_COUNTER; + + PROC_READOUT_CFD : process is + begin + wait until rising_edge(CLK); + epoch_counter_save_sys <= epoch_counter_save; + READOUT_TX_CFD.busy_release <= '0'; + READOUT_TX_CFD.data_finished <= '0'; + READOUT_TX_CFD.data <= (others => '0'); + READOUT_TX_CFD.data_write <= '0'; + + case state_cfd is + when IDLE => + READOUT_TX_CFD.statusbits <= (others => '0'); + if READOUT_RX.valid_notiming_trg = '1' then + state_cfd <= RELEASE_DIRECT; + elsif READOUT_RX.data_valid = '1' then --seems to have missed trigger... + READOUT_TX_CFD.statusbits <= (23 => '1', others => '0'); --event not found + state_cfd <= RELEASE_DIRECT; + elsif READOUT_RX.valid_timing_trg = '1' then + state_cfd <= WRITE_EPOCH; + end if; + + when RELEASE_DIRECT => + state_cfd <= DO_RELEASE; + + when DO_RELEASE => + if READOUT_RX.data_valid = '1' then + READOUT_TX_CFD.busy_release <= '1'; + READOUT_TX_CFD.data_finished <= '1'; + state_cfd <= WAIT_FOR_END; + end if; + + when WAIT_FOR_END => + if READOUT_RX.data_valid = '0' then + state_cfd <= IDLE; + end if; + + when WRITE_EPOCH => + READOUT_TX_CFD.data <= x"1" & std_logic_vector(resize(epoch_counter_save_sys,28)); + READOUT_TX_CFD.data_write <= '1'; + state_cfd <= RELEASE_DIRECT; + end case; + end process PROC_READOUT_CFD; + + config_cfd.BaselineAlwaysOn <= buffer_ctrl_reg(4); diff --git a/ADC/source/adc_package.vhd b/ADC/source/adc_package.vhd index 218e272..cfd39ca 100644 --- a/ADC/source/adc_package.vhd +++ b/ADC/source/adc_package.vhd @@ -9,6 +9,8 @@ package adc_package is constant DEVICES_2 : integer := 5; constant CHANNELS : integer := 4; constant RESOLUTION : integer := 10; + + constant EPOCH_COUNTER_SIZE : integer := 24; type buffer_data_t is array (0 to DEVICES - 1) of std_logic_vector(31 downto 0); @@ -84,7 +86,6 @@ package adc_package is InvalidWordCount : unsigned(31 downto 0); Baseline : unsigned(RESOLUTION - 1 downto 0); LastWord : unsigned(RESOLUTION - 1 downto 0); - EpochCounter : unsigned(23 downto 0); Trigger : std_logic; end record; diff --git a/ADC/source/adc_processor_cfd.vhd b/ADC/source/adc_processor_cfd.vhd index d7a9b4b..3a9931b 100644 --- a/ADC/source/adc_processor_cfd.vhd +++ b/ADC/source/adc_processor_cfd.vhd @@ -28,7 +28,7 @@ entity adc_processor_cfd is READOUT_RX : in READOUT_RX; READOUT_TX : out READOUT_TX; - ADC_CLK_TDC_OUT : out std_logic + EPOCH_COUNTER_IN : in unsigned(EPOCH_COUNTER_SIZE-1 downto 0) ); end entity adc_processor_cfd; @@ -61,15 +61,13 @@ architecture arch of adc_processor_cfd is signal state : state_t; signal statebits : std_logic_vector(7 downto 0); - signal RDO_data_main : std_logic_vector(31 downto 0) := (others => '0'); - signal RDO_write_main : std_logic := '0'; signal readout_reset : std_logic := '0'; signal busy_in_adc, busy_in_sys : std_logic := '0'; signal busy_out_adc, busy_out_sys : std_logic_vector(CHANNELS-1 downto 0) := (others => '0'); - type epoch_counter_t is array(CHANNELS - 1 downto 0) of unsigned(23 downto 0); - signal epoch_counter, epoch_counter_save : epoch_counter_t; - signal epoch_counter_sys, epoch_counter_adc : epoch_counter_t; + --type epoch_counter_t is array(CHANNELS - 1 downto 0) of unsigned(23 downto 0); + --signal epoch_counter, epoch_counter_save : epoch_counter_t; + --signal epoch_counter_sys, epoch_counter_adc : epoch_counter_t; begin CONF_adc <= CONF_sys when rising_edge(CLK_ADC); @@ -82,15 +80,14 @@ begin busy_in_adc <= busy_in_sys when rising_edge(CLK_ADC); busy_out_sys <= busy_out_adc when rising_edge(CLK_SYS); - ADC_CLK_TDC_OUT <= debug_adc(0).EpochCounter(10); gen_cfd : for i in 0 to CHANNELS - 1 generate trigger_gen(i) <= debug_sys(i).Trigger; -- first convert to gray counting, then do clock domain crossing - epoch_counter_adc(i) <= debug_adc(i).EpochCounter xor shift_right(debug_adc(i).EpochCounter,1); - epoch_counter_sys(i) <= epoch_counter_adc(i) when rising_edge(CLK_SYS); - epoch_counter(i) <= epoch_counter_sys(i); -- no back conversion to binary for now + --epoch_counter_adc(i) <= debug_adc(i).EpochCounter xor shift_right(debug_adc(i).EpochCounter,1); + --epoch_counter_sys(i) <= epoch_counter_adc(i) when rising_edge(CLK_SYS); + --epoch_counter(i) <= epoch_counter_sys(i); -- no back conversion to binary for now THE_CFD : entity work.adc_processor_cfd_ch generic map( @@ -104,7 +101,8 @@ begin RAM_DATA => ram_data_adc(i), RAM_BSY_IN => busy_in_adc, RAM_BSY_OUT => busy_out_adc(i), - DEBUG => debug_adc(i) + DEBUG => debug_adc(i), + EPOCH_COUNTER_IN => EPOCH_COUNTER_IN ); ram_addr_sys(i) <= std_logic_vector(resize(ram_counter(i),ram_addr_sys(i)'length)); @@ -121,8 +119,8 @@ begin Q => ram_data_sys(i)); end generate; - READOUT_TX.data_write <= RDO_write_main when rising_edge(CLK_SYS); - READOUT_TX.data <= RDO_data_main when rising_edge(CLK_SYS); + -- <= RDO_write_main when rising_edge(CLK_SYS); + --READOUT_TX.data <= RDO_data_main when rising_edge(CLK_SYS); readout_reset <= CONTROL(12) when rising_edge(CLK_SYS); statebits <= std_logic_vector(to_unsigned(state_t'pos(state), 8)); @@ -133,8 +131,8 @@ begin wait until rising_edge(CLK_SYS); READOUT_TX.busy_release <= '0'; READOUT_TX.data_finished <= '0'; - RDO_data_main <= (others => '0'); - RDO_write_main <= '0'; + READOUT_TX.data <= (others => '0'); + READOUT_TX.data_write <= '0'; busy_in_sys <= '0'; @@ -153,7 +151,7 @@ begin else state <= WAIT_BSY; end if; - epoch_counter_save <= epoch_counter; -- all channels at the same time + --epoch_counter_save <= epoch_counter; -- all channels at the same time end if; when RELEASE_DIRECT => @@ -200,8 +198,8 @@ begin when WAIT_RAM => busy_in_sys <= '1'; ram_counter(channelselect) <= ram_counter(channelselect) + 1; - RDO_data_main <= x"e0" & std_logic_vector(epoch_counter_save(channelselect)); - RDO_write_main <= not CONF_sys.ChannelDisable(DEVICE * CHANNELS + channelselect); + --RDO_data_main <= x"e0" & std_logic_vector(epoch_counter_save(channelselect)); + --RDO_write_main <= not CONF_sys.ChannelDisable(DEVICE * CHANNELS + channelselect); state <= READOUT; @@ -219,15 +217,15 @@ begin state <= WAIT_BSY; end if; else - RDO_data_main <= ram_data_sys(channelselect); - RDO_write_main <= not CONF_sys.ChannelDisable(DEVICE * CHANNELS + channelselect); + READOUT_TX.data <= ram_data_sys(channelselect); + READOUT_TX.data_write <= not CONF_sys.ChannelDisable(DEVICE * CHANNELS + channelselect); ram_counter(channelselect) <= ram_counter(channelselect) + 1; end if; when SEND_STATUS => - RDO_write_main <= '1'; - RDO_data_main <= x"20000000"; + READOUT_TX.data_write <= '1'; + READOUT_TX.data <= x"20000000"; -- nothing implemented yet state <= RELEASE_DIRECT; end case; diff --git a/ADC/source/adc_processor_cfd_ch.vhd b/ADC/source/adc_processor_cfd_ch.vhd index 7c882c3..c26e19c 100644 --- a/ADC/source/adc_processor_cfd_ch.vhd +++ b/ADC/source/adc_processor_cfd_ch.vhd @@ -23,7 +23,9 @@ entity adc_processor_cfd_ch is RAM_BSY_IN : in std_logic; RAM_BSY_OUT : out std_logic; - DEBUG : out debug_cfd_t + DEBUG : out debug_cfd_t; + + EPOCH_COUNTER_IN : in unsigned(EPOCH_COUNTER_SIZE-1 downto 0) ); end entity adc_processor_cfd_ch; @@ -91,7 +93,7 @@ architecture arch of adc_processor_cfd_ch is signal integral_sum : signed(RESOLUTION_CFD - 1 downto 0) := (others => '0'); - signal epoch_counter, epoch_counter_save : unsigned(23 downto 0) := (others => '0'); + signal epoch_counter_save : unsigned(EPOCH_COUNTER_SIZE-1 downto 0) := (others => '0'); type state_t is (IDLE, INTEGRATE, WRITE1, WRITE2, WRITE3, FINISH, LOCKED, DEBUG_DUMP); signal state : state_t := IDLE; @@ -106,7 +108,6 @@ begin DEBUG.InvalidWordCount <= invalid_word_count when rising_edge(CLK); DEBUG.Baseline <= baseline when rising_edge(CLK); DEBUG.LastWord <= input when rising_edge(CLK); - DEBUG.EpochCounter <= epoch_counter when rising_edge(CLK); -- word checker, needed for ADC phase adjustment gen_word_checker : for i in 0 to CHANNELS - 1 generate @@ -233,8 +234,6 @@ begin begin wait until rising_edge(CLK); - epoch_counter <= epoch_counter + 1; - cfd_prev <= cfd.value; if cfd_prev < 0 and cfd.value >= 0 and cfd.thresh = '1' then zeroX := '1'; @@ -252,9 +251,9 @@ begin state <= INTEGRATE; integral_counter := to_integer(CONF.IntegrateWindow); integral_sum <= resize(delay_integral_out, RESOLUTION_CFD); - cfd_prev_save <= cfd_prev; + cfd_prev_save <= cfd_prev; cfd_save <= cfd.value; - epoch_counter_save <= epoch_counter; + epoch_counter_save <= EPOCH_COUNTER_IN; elsif CONF.DebugMode = 0 and RAM_BSY_IN = '1' then state <= LOCKED; elsif CONF.DebugMode /= 0 and RAM_BSY_IN = '1' then diff --git a/ADC/trb3_periph_adc.vhd b/ADC/trb3_periph_adc.vhd index f8cf7ae..4a33e35 100644 --- a/ADC/trb3_periph_adc.vhd +++ b/ADC/trb3_periph_adc.vhd @@ -160,8 +160,9 @@ architecture trb3_periph_adc_arch of trb3_periph_adc is signal regio_tx, busadc_tx, busspi_tx, busmem_tx, bussed_tx : CTRLBUS_TX; -- always have enough signals for TDC - -- readout_tx(0) is then used by TDC - constant NUM_READOUTS : integer := DEVICES+1; + -- readout_tx(0) is used by (possibly available) TDC + -- readout_tx(1) is used by (possibly available) CFD EpochCounter + constant NUM_READOUTS : integer := DEVICES+2; signal readout_rx : READOUT_RX; signal readout_tx : readout_tx_array_t(0 to NUM_READOUTS-1); @@ -424,7 +425,8 @@ gen_reallogic : if READOUT_MODE /= READOUT_MODE_DUMMY generate TRIGGER_IN => TRIGGER_LEFT, READOUT_RX => readout_rx, - READOUT_TX => readout_tx(1 to DEVICES), + READOUT_TX => readout_tx(2 to DEVICES), + READOUT_TX_CFD => readout_tx(1), BUS_RX => busadc_rx, BUS_TX => busadc_tx, @@ -722,15 +724,6 @@ LED_YELLOW <= not med_stat_op(11); CONTROL_REG_IN => tdc_ctrl_reg ); - --tdc_inputs(1) used by CBM-MBS ETM - --tdc_inputs(2) <= cbm_sync_pulser_i; - --tdc_inputs(3) <= cbm_sync_timing_trigger_i; - --tdc_inputs(4) <= JINLVDS(0); --NIM_IN(0); - --JTTL(0 downto 15) <= (others => '0'); - - - - PROC_TDC_CTRL_REG : process variable pos : integer range 0 to TDC_CONTROL_REG_NR-1; begin -- 2.43.0