]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
Baseline averaging works maybe...
authorAndreas Neiser <neiser@kph.uni-mainz.de>
Wed, 18 Feb 2015 18:26:39 +0000 (19:26 +0100)
committerAndreas Neiser <neiser@kph.uni-mainz.de>
Sat, 13 Jun 2015 15:36:57 +0000 (17:36 +0200)
ADC/source/adc_package.vhd
ADC/source/adc_processor_cfd.vhd
ADC/source/adc_processor_cfd_ch.vhd [new file with mode: 0644]

index 9e7e701e84e2c43f0dbbe1bc29c5a0a6a2b26513..ef5b38cb155ffcdca71c25da42c121d7c152f194 100644 (file)
@@ -57,6 +57,9 @@ type cfg_cfd_t is record
   CFDMultDly       : unsigned(3 downto 0);
   IntegrateWindow  : unsigned(7 downto 0);
   TriggerDelay     : unsigned(11 downto 0);
+  check_word1       : std_logic_vector(RESOLUTION-1 downto 0);
+  check_word2       : std_logic_vector(RESOLUTION-1 downto 0);
+  check_word_enable : std_logic;
 end record;
 
 end package;
index 5f5affb74771353627fc46b9046416311fb22a89..3d54845a92d3474a46b3a877151eb91f63a4b10d 100644 (file)
@@ -31,7 +31,30 @@ entity adc_processor_cfd is
 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'));
 begin
   
+  CONF <= CONFIG when rising_edge(CLK);
+  
+  TRIGGER_OUT <= or_all(trigger);
+    
+  gen_cfd : for i in 0 to CHANNELS-1 generate
+    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,
+               RAM_RD   => '0',
+               RAM_ADDR => (others => '0'),
+               RAM_DATA => open,
+               TRIGGER_OUT => trigger(i)
+               );   
+    
+  end generate;  
+    
+
+  
 end architecture arch;
diff --git a/ADC/source/adc_processor_cfd_ch.vhd b/ADC/source/adc_processor_cfd_ch.vhd
new file mode 100644 (file)
index 0000000..c1e4a15
--- /dev/null
@@ -0,0 +1,129 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.trb_net_std.all;
+use work.trb3_components.all;
+use work.adc_package.all;
+
+entity adc_processor_cfd_ch is
+  port(
+    CLK         : in  std_logic;
+
+    ADC_DATA    : in  std_logic_vector(RESOLUTION - 1 downto 0);
+
+    CONF        : in  cfg_cfd_t;
+
+    RAM_RD      : in  std_logic;
+    RAM_ADDR    : in  std_logic_vector(7 downto 0);
+    RAM_DATA    : out std_logic_vector(31 downto 0);
+
+    TRIGGER_OUT : out std_logic
+  );
+end entity adc_processor_cfd_ch;
+
+architecture arch of adc_processor_cfd_ch is
+  signal invalid_word_count : unsigned(31 downto 0) := (others => '0');
+
+  type unsigned_in_thresh_t is record
+    word   : unsigned(RESOLUTION - 1 downto 0);
+    thresh : std_logic;
+  end record;
+  constant unsigned_in_thresh_t_INIT : unsigned_in_thresh_t := (word => (others => '0'), thresh => '0');
+
+  signal baseline, input : unsigned(RESOLUTION - 1 downto 0);
+
+  signal baseline_average : unsigned(RESOLUTION + 2 ** CONF.BaselineAverage'length - 1 - 1 downto 0);
+
+  type delay_baseline_t is array (31 downto 0) of unsigned_in_thresh_t;
+  signal delay_baseline     : delay_baseline_t     := (others => unsigned_in_thresh_t_INIT);
+  signal delay_baseline_in  : unsigned_in_thresh_t := unsigned_in_thresh_t_INIT;
+  signal delay_baseline_out : unsigned_in_thresh_t := unsigned_in_thresh_t_INIT;
+
+  type subtracted_thresh_t is record
+    word   : signed(RESOLUTION downto 0);
+    thresh : std_logic;
+  end record;
+  constant subtracted_thresh_t_INIT : subtracted_thresh_t := (word => (others => '0'), thresh => '0');
+
+  signal subtracted : subtracted_thresh_t := subtracted_thresh_t_INIT;
+
+  type delay_cfd_t is array (2 ** (CONF.CFDDelay'length) - 1 downto 0) of signed(RESOLUTION downto 0);
+  signal delay_cfd     : delay_cfd_t                 := (others => (others => '0'));
+  signal delay_cfd_in  : signed(RESOLUTION downto 0) := (others => '0');
+  signal delay_cfd_out : signed(RESOLUTION downto 0) := (others => '0');
+
+begin
+  input <= unsigned(ADC_DATA);
+
+  -- word checker, needed for ADC phase adjustment
+  gen_word_checker : for i in 0 to CHANNELS - 1 generate
+    process
+    begin
+      wait until rising_edge(CLK);
+      if ADC_DATA /= CONF.check_word1 and ADC_DATA /= CONF.check_word2 and CONF.check_word_enable = '1' then
+        invalid_word_count <= invalid_word_count + 1;
+      end if;
+    end process;
+  end generate;
+
+  -- baseline subtraction, polarity inverter, threshold bit generator
+  proc_compare_invert : process is
+    variable sub, baseline_s, input_s, thresh_s : signed(RESOLUTION downto 0);
+    variable thresh                             : std_logic;
+  begin
+    wait until rising_edge(CLK);
+
+    -- add sign bit to various inputs
+    baseline_s := signed(resize(baseline, RESOLUTION + 1));
+    input_s    := signed(resize(input, RESOLUTION + 1));
+    thresh_s   := signed(resize(CONF.InputThreshold, RESOLUTION + 1));
+
+    -- subtract baseline such that sub is always positive
+    -- so invert if required
+    if CONF.PolarityInvert = '1' then
+      sub := baseline_s - input_s;
+    else
+      sub := input_s - baseline_s;
+    end if;
+
+    -- output
+    delay_baseline_in.word <= input;
+    subtracted.word        <= sub;
+
+    -- check if signal is above thresh
+    if sub > thresh_s then
+      thresh := '1';
+    else
+      thresh := '0';
+    end if;
+    delay_baseline_in.thresh <= thresh;
+    subtracted.thresh        <= thresh;
+    TRIGGER_OUT              <= thresh;
+  end process proc_compare_invert;
+
+  -- delay for baseline
+  proc_baseline_delay : process is
+  begin
+    wait until rising_edge(CLK);
+    delay_baseline     <= delay_baseline(delay_baseline'high downto 1) & delay_baseline_in;
+    delay_baseline_out <= delay_baseline(delay_baseline'high);
+  end process proc_baseline_delay;
+
+  -- average baseline
+  proc_baseline_average : process is
+    variable avg              : integer range 0 to 2 ** CONF.BaselineAverage'length - 1;
+    constant l                : integer := baseline_average'length;
+    variable input_r, fract_r : unsigned(l - 1 downto 0);
+  begin
+    wait until rising_edge(CLK);
+    avg     := to_integer(CONF.BaselineAverage);
+    input_r := resize(delay_baseline_out.word, l);
+    fract_r := resize(baseline_average(avg + RESOLUTION - 1 downto avg), l);
+    if delay_baseline_out.thresh = '0' or CONF.BaselineAlwaysOn = '1' then
+      baseline_average <= baseline_average + input_r - fract_r;
+    end if;
+    baseline <= baseline_average(avg + RESOLUTION - 1 downto avg);
+  end process proc_baseline_average;
+
+end architecture arch;