-- Tyler Lutz; July 26, 2011; -- Baseline averager operation; --Input->digital signal from ASIC, time from onboard clock; --Output->zero when signal is above threshold, average of last (savescope) # of data points if else; ------------------------------------------------------------------------- --((o))--((o))--((o))--((o))--((o))--((o))--((o))--((o))--((o))--((o))-- ------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity fitting_etc_BLA is port( pulse: in std_logic_vector (0 to 11); --assumed that ASIC readout is in parallel(?), and if not it is easy to parallelize serial input clk: in std_logic; OBLA: out std_logic_vector (0 to 11); --Output baseline average end fitting_etc_BLA; -- ==I==I==I==I==I==I==I==I==I==I==I== -- architecture Herjolfssen7 of fitting_etc_BLA is begin process(clk) variable accsec: integer :=0; --"seconds" or any other arbitrary time unit, to be adjusted based on the frequency of clock used. type gaul is array(natural range <>) of integer; --define unconstrained array type variable pulsebit: gaul (0 to 11); --pulse is converted later to an integer for calculation purposes; this is an intermediate step variable multithreshold: gaul (0 to 2); --stores our three constant threshold values for the multithresh mode variable baselineaverage: integer:=0; -- outputs to OBLA (Output Base Line Average) variable pulsesum: integer :=0; --for baseline averager, stores sum of non-important background data variable pulsar: integer:=0; -- intergized value of incoming pulse constant savescope: integer:=100; --scope size of CFD delay memory and base line averager (here, last 1000 data points) -- variable pulsarsave: gaul (0 to savescope+4); --allows us to delay the pulse (the 10^10 is totally arbitrary) variable pulsarbasesave: gaul (0 to savescope+4); --memory of last savescope non-pulse reading heights variable letop: integer:=0; variable time1: integer:=0; --in integral calculator, time of first threshold crossing variable time2: integer:=0; --" " time of falling below threshold constant delay: integer:=4; --delay length for CFD (150-200 ps = 4 using our clock specs (see testbench)) variable eventprint: gaul (0 to 4); --array output, listing arrival time against event number variable eventprintread: gaul (0 to 3); --"scratchpaper" variable variable basecounter: integer:=0; --numbers the initial data for early baseline averaging variable signalmean: integer:=0; --for calculating number of electrons -- variable standarddev: integer:=0; -- standard deviation of baseline -- variable standarddevsum: integer:=0; -- a running sum of stored baseline data (last savescope # of points) minus baseline mean all squared -- variable peakdeviation: integer:=0; --largest deviation from mean of baseline -- variable significance: integer:=0; --largest deviation of baseline devided by its standard deviation -- variable squirt: integer:=0; --a dummy variable whihc facilitates square root calculation using a continued fraction algorithm -- variable sumcounter: integer:=0; -- ==I==I==I==I==I==I==I==I==I==I==I== -- begin if clk'event and clk='1' then --program loops at clock rising edge letop:=(letop+1)mod 50;--1000000; --slow down clock to 10MHz if letop=0 then accsec:=(accsec+1) mod 2**12; --our stopwatch --our oscilloscope data is converted to decimal stored in 'pulsar' for j in 0 to 11 loop -- intigerizing the input pulse; logic vector to binary array to integer(pulsar) if pulse(j)='0' then pulsebit(j):=1; --binary array elsif pulse(j)='1' then pulsebit(j):=0; end if; if j=0 then pulsar:=pulsebit(0); --a clever way to reinitialize the summand 'pulsar' else pulsar:= pulsar+(pulsebit(j))*(2**(j)); --actual binary to integer conversion end if; end loop; multithreshold(0):=5; --specify desired threshold values for multithreshold claculations multithreshold(1):=36; multithreshold(2):=37; if pulsar>--0--O--o--+--o--O--0--<< >>--0--O--o--+--o--O--0--<< >>--0--O--o--+--o--O--0--<< >>--0--O--o--+--o--O--0--<< -- if pulsarsavescope+2 then --averaging too many data points becomes untenable => only consider stored points, not all prior points pulsesum:= pulsesum+pulsarbasesave(0)-pulsarbasesave(savescope+1); --include latest data point, let an old one fall out the back end baselineaverage:=pulsesum/savescope; --definition of average over savescope data points end if; signalmean:=baselineaverage; --store for later else signalmean:=0; baselineaverage:=0; end if; for w in 11 downto 0 loop --readout in parallel if baselineaverage>=(2**w) then --... OBLA(w)<='0'; baselineaverage:=baselineaverage-2**w; else OBLA(w)<='1'; end if; end loop; -- >>--0--O--o--+--o--O--0--<< >>--0--O--o--+--o--O--0--<< >>--0--O--o--+--o--O--0--<< >>--0--O--o--+--o--O--0--<< -- end if; end if; end process; end Herjolfssen7;