architecture tb_arch of tb is
signal clock100 : std_logic := '1';
signal clock200 : std_logic := '1';
+ signal clock_adc : std_logic := '1';
signal adc_data : std_logic_vector(39 downto 0) := (others => '0');
signal stop_in : std_logic := '0';
signal trigger_out : std_logic := '0';
port map(CLK => clock100,
CLK_ADCRAW => clock200,
RESTART_IN => restart,
- ADCCLK_OUT => open,
+ ADCCLK_OUT => clock_adc,
ADC_DATA => (others => '0'),
ADC_DCO => (others => '0'),
DATA_OUT => adc_data,
DEVICE => 0
)
port map(
- CLK => clock100,
+ CLK_SYS => clock100,
+ CLK_ADC => clock_adc,
ADC_DATA => adc_data,
STOP_IN => stop_in,
TRIGGER_OUT => trigger_out,
use work.trb_net_std.all;
package adc_package is
-
-
-
-constant DEVICES : integer := 12;
-constant DEVICES_1 : integer := 7;
-constant DEVICES_2 : integer := 5;
-constant CHANNELS : integer := 4;
-constant RESOLUTION : integer := 10;
-
-
-type buffer_data_t is array(0 to DEVICES-1) of std_logic_vector(31 downto 0);
-
-type std_logic_vector_array_18 is array (integer range <>) of std_logic_vector(17 downto 0);
-type std_logic_vector_array_10 is array (integer range <>) of std_logic_vector( 9 downto 0);
-
-type unsigned_array_18 is array (integer range <>) of unsigned(17 downto 0);
-type unsigned_array_10 is array (integer range <>) of unsigned( 9 downto 0);
-type unsigned_array_8 is array (integer range <>) of unsigned( 7 downto 0);
-
-
-type cfg_t is record
- processing_mode : integer range 0 to 3; --0: normal block processing, 1: pulse shape processing
- buffer_depth : unsigned(10 downto 0);
- samples_after : unsigned(10 downto 0);
- block_count : unsigned( 1 downto 0);
- trigger_threshold : unsigned(17 downto 0);
- readout_threshold : unsigned(17 downto 0);
- presum : unsigned( 7 downto 0);
- averaging : unsigned( 3 downto 0);
- trigger_enable : std_logic_vector(47 downto 0);
- channel_disable : std_logic_vector(47 downto 0);
- baseline_always_on: std_logic;
- baseline_reset_value : unsigned(31 downto 0);
- block_avg : unsigned_array_8(0 to 3);
- block_sums : unsigned_array_8(0 to 3);
- block_scale : unsigned_array_8(0 to 3);
- check_word1 : std_logic_vector(RESOLUTION-1 downto 0);
- check_word2 : std_logic_vector(RESOLUTION-1 downto 0);
- check_word_enable : std_logic;
- cfd_window : unsigned( 7 downto 0);
- cfd_delay : unsigned( 3 downto 0);
-end record;
-
-type cfg_cfd_t is record
- InputThreshold : unsigned(9 downto 0);
- PolarityInvert : std_logic;
- BaselineAverage : unsigned(3 downto 0);
- BaselineAlwaysOn : std_logic;
- CFDDelay : unsigned(4 downto 0);
- CFDMult : unsigned(3 downto 0);
- CFDMultDly : unsigned(3 downto 0);
- IntegrateWindow : unsigned(7 downto 0);
- TriggerDelay : unsigned(11 downto 0);
- CheckWord1 : std_logic_vector(RESOLUTION-1 downto 0);
- CheckWord2 : std_logic_vector(RESOLUTION-1 downto 0);
- CheckWordEnable : std_logic;
-end record;
+ constant DEVICES : integer := 12;
+ constant DEVICES_1 : integer := 7;
+ constant DEVICES_2 : integer := 5;
+ constant CHANNELS : integer := 4;
+ constant RESOLUTION : integer := 10;
+
+ type buffer_data_t is array (0 to DEVICES - 1) of std_logic_vector(31 downto 0);
+
+ type std_logic_vector_array_18 is array (integer range <>) of std_logic_vector(17 downto 0);
+ type std_logic_vector_array_10 is array (integer range <>) of std_logic_vector(9 downto 0);
+
+ type unsigned_array_18 is array (integer range <>) of unsigned(17 downto 0);
+ type unsigned_array_10 is array (integer range <>) of unsigned(9 downto 0);
+ type unsigned_array_8 is array (integer range <>) of unsigned(7 downto 0);
+
+ type cfg_t is record
+ processing_mode : integer range 0 to 3; --0: normal block processing, 1: pulse shape processing
+ buffer_depth : unsigned(10 downto 0);
+ samples_after : unsigned(10 downto 0);
+ block_count : unsigned(1 downto 0);
+ trigger_threshold : unsigned(17 downto 0);
+ readout_threshold : unsigned(17 downto 0);
+ presum : unsigned(7 downto 0);
+ averaging : unsigned(3 downto 0);
+ trigger_enable : std_logic_vector(47 downto 0);
+ channel_disable : std_logic_vector(47 downto 0);
+ baseline_always_on : std_logic;
+ baseline_reset_value : unsigned(31 downto 0);
+ block_avg : unsigned_array_8(0 to 3);
+ block_sums : unsigned_array_8(0 to 3);
+ block_scale : unsigned_array_8(0 to 3);
+ check_word1 : std_logic_vector(RESOLUTION - 1 downto 0);
+ check_word2 : std_logic_vector(RESOLUTION - 1 downto 0);
+ check_word_enable : std_logic;
+ cfd_window : unsigned(7 downto 0);
+ cfd_delay : unsigned(3 downto 0);
+ end record;
+
+ type cfg_cfd_t is record
+ InputThreshold : unsigned(9 downto 0);
+ PolarityInvert : std_logic;
+ BaselineAverage : unsigned(3 downto 0);
+ BaselineAlwaysOn : std_logic;
+ CFDDelay : unsigned(4 downto 0);
+ CFDMult : unsigned(3 downto 0);
+ CFDMultDly : unsigned(3 downto 0);
+ IntegrateWindow : unsigned(7 downto 0);
+ TriggerDelay : unsigned(11 downto 0);
+ CheckWord1 : std_logic_vector(RESOLUTION - 1 downto 0);
+ CheckWord2 : std_logic_vector(RESOLUTION - 1 downto 0);
+ CheckWordEnable : std_logic;
+ TriggerEnable : std_logic_vector(47 downto 0);
+ ChannelDisable : std_logic_vector(47 downto 0);
+ end record;
+
+ type debug_cfd_t is record
+ InvalidWordCount : unsigned(31 downto 0);
+ Baseline : unsigned(RESOLUTION - 1 downto 0);
+ LastWord : unsigned(RESOLUTION - 1 downto 0);
+ Trigger : std_logic;
+ end record;
end package;
-
package body adc_package is
end package body;
DEVICE : integer range 0 to 15 := 15
);
port(
- CLK : in std_logic;
+ CLK_SYS : in std_logic;
+ CLK_ADC : in std_logic;
ADC_DATA : in std_logic_vector(RESOLUTION * CHANNELS - 1 downto 0);
STOP_IN : in std_logic;
end entity adc_processor_cfd;
architecture arch of adc_processor_cfd is
- signal CONF : cfg_cfd_t;
-
- signal trigger : std_logic_vector(CHANNELS-1 downto 0);
- type invalid_word_count_t is array (0 to CHANNELS - 1) of unsigned(31 downto 0);
- signal invalid_word_count : invalid_word_count_t := (others => (others => '0'));
+ attribute syn_hier : string;
+ attribute syn_keep : boolean;
+ attribute syn_preserve : boolean;
+ attribute syn_hier of arch : architecture is "hard";
+
+ signal CONF_adc, CONF_sys : cfg_cfd_t;
+ attribute syn_keep of CONF_adc, CONF_sys : signal is true;
+ attribute syn_preserve of CONF_adc, CONF_sys : signal is true;
+
+ signal trigger_gen, trigger_mask : std_logic_vector(CHANNELS - 1 downto 0);
+ type debug_t is array (CHANNELS - 1 downto 0) of debug_cfd_t;
+ signal debug_adc, debug_sys : debug_t;
+
+ signal reg_buffer_addr : std_logic_vector(4 downto 0);
+ signal reg_buffer_read : std_logic;
+
begin
-
- CONF <= CONFIG when rising_edge(CLK);
-
- TRIGGER_OUT <= or_all(trigger);
-
- gen_cfd : for i in 0 to CHANNELS-1 generate
+ CONF_adc <= CONFIG when rising_edge(CLK_ADC);
+ CONF_sys <= CONFIG when rising_edge(CLK_SYS);
+
+ trigger_mask <= CONF_sys.TriggerEnable((DEVICE + 1) * CHANNELS - 1 downto DEVICE * CHANNELS);
+ TRIGGER_OUT <= or_all(trigger_gen and trigger_mask) when rising_edge(CLK_SYS);
+
+ debug_sys <= debug_adc when rising_edge(CLK_SYS);
+ gen_cfd : for i in 0 to CHANNELS - 1 generate
+ trigger_gen(i) <= debug_sys(i).Trigger;
THE_CFD : entity work.adc_processor_cfd_ch
- port map(CLK => CLK,
- ADC_DATA => ADC_DATA(RESOLUTION*(i+1)-1 downto RESOLUTION*i),
- CONF => CONF,
+ port map(CLK => CLK_ADC,
+ ADC_DATA => ADC_DATA(RESOLUTION * (i + 1) - 1 downto RESOLUTION * i),
+ CONF => CONF_adc,
RAM_RD => '0',
RAM_ADDR => (others => '0'),
RAM_DATA => open,
- TRIGGER_OUT => trigger(i)
- );
-
- end generate;
-
+ DEBUG => debug_adc(i)
+ );
+ end generate;
+
+ PROC_DEBUG_BUFFER : process
+ variable c : integer range 0 to 3;
+ begin
+ wait until rising_edge(CLK_SYS);
+ reg_buffer_addr <= DEBUG_BUFFER_ADDR;
+ reg_buffer_read <= DEBUG_BUFFER_READ;
+ c := to_integer(unsigned(reg_buffer_addr(1 downto 0)));
+ DEBUG_BUFFER_DATA <= (others => '0');
+ if reg_buffer_read = '1' then
+ if reg_buffer_addr(4) = '0' then
+ DEBUG_BUFFER_READY <= '1';
+ case reg_buffer_addr(3 downto 2) is
+ when "00" => DEBUG_BUFFER_DATA <= std_logic_vector(resize(debug_sys(c).LastWord, 32));
+ when "01" => DEBUG_BUFFER_DATA <= std_logic_vector(resize(debug_sys(c).Baseline, 32));
+ when "11" => DEBUG_BUFFER_DATA <= std_logic_vector(resize(debug_sys(c).InvalidWordCount, 32));
+ when others => null;
+ end case;
+ else
+ DEBUG_BUFFER_READY <= '1';
+ case reg_buffer_addr(3 downto 0) is
+ when x"2" =>
+ DEBUG_BUFFER_DATA(2) <= STOP_IN;
+ DEBUG_BUFFER_DATA(12) <= '1'; -- ADC_VALID
+ DEBUG_BUFFER_DATA(19 downto 16) <= trigger_gen;
+ when others => null;
+ end case;
+ end if;
+ end if;
+
+ DEBUG_BUFFER_READY <= reg_buffer_read;
+
+ end process;
-
end architecture arch;
RAM_ADDR : in std_logic_vector(7 downto 0);
RAM_DATA : out std_logic_vector(31 downto 0);
- TRIGGER_OUT : out std_logic
+ DEBUG : out debug_cfd_t
+
);
end entity adc_processor_cfd_ch;
architecture arch of adc_processor_cfd_ch is
- signal invalid_word_count : unsigned(31 downto 0) := (others => '0');
+ signal invalid_word_count : unsigned(DEBUG.InvalidWordCount'length-1 downto 0) := (others => '0');
type unsigned_in_thresh_t is record
word : unsigned(RESOLUTION - 1 downto 0);
signal delay_cfd_out : signed(RESOLUTION downto 0) := (others => '0');
begin
+ -- input ADC data interpreted as unsigned
input <= unsigned(ADC_DATA);
+ -- Tell the outer word some useful debug infos
+ DEBUG.InvalidWordCount <= invalid_word_count;
+ DEBUG.Baseline <= baseline;
+ DEBUG.LastWord <= input;
+
-- word checker, needed for ADC phase adjustment
gen_word_checker : for i in 0 to CHANNELS - 1 generate
process
end if;
delay_baseline_in.thresh <= thresh;
subtracted.thresh <= thresh;
- TRIGGER_OUT <= thresh;
+ DEBUG.Trigger <= thresh;
end process proc_compare_invert;
-- delay for baseline