-- Tyler Lutz; July 28, 2011; -- Full Width at Half Maximum of the incoming pulse; --Input->digital signal from ASIC, time from onboard clock; --Output->digital width readout (in units of time); ------------------------------------------------------------------------- --((o))--((o))--((o))--((o))--((o))--((o))--((o))--((o))--((o))--((o))-- ------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; entity fitting_etc_FWHM 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; OPEAK: out std_logic_vector (0 to 11); --Dedicated output for peak of pulse OTEST: out std_logic_vector (0 to 11); --for simulating miscellaneous calculations end fitting_etc_FWHM; -- ==I==I==I==I==I==I==I==I==I==I==I== -- architecture Herjolfssen7 of fitting_etc_FWHM 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 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 letop: integer:=0; variable time1: integer:=0; --in integral calculator, time of first threshold crossing variable peak: integer:=0; -- height of the peak variable peaktime: integer:=0; --time at which peak occurs variable risetime: integer:=0; --time pulse takes to rise from first threshold to 90% of peak variable falltime: integer:=0; --time pulse takes to fall from 90% of first threshold down to first threshold variable FWHM: integer:=0; --full width at half maximum variable halffronttime: integer:=0; --for FWHM calculation; absolute time at which pulse rises to reache half its maximum variable halfbacktime: integer:=0; --" " falls " " variable tester: 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):=14; --specify desired threshold values for multithreshold claculations multithreshold(1):=15; multithreshold(2):=17; if (pulsar>))]|[((<< (([|])) >>))]|[((<< (([|]) >>))]|[((<< (([|])) >>))]|[((<< (([|])) >>))]|[((<< (([|])) >>))]|[((<<-- if pulsar>=multithreshold(0) then --PEAK FINDER if pulsar>=peak then --find largest pulsar peak:=pulsar; --and store it in "peak" peaktime:=accsec; end if; end if; -->>))]|[((<< (([|])) >>))]|[((<< (([|]) >>))]|[((<< (([|])) >>))]|[((<< (([|])) >>))]|[((<< (([|])) >>))]|[((<<-- ---- if pulsar>=multithreshold(0) then if pulsarsave(1)><<(([|]))>><<(([|]))>><<(([|]))>><<(([|]))>><<(([|]))>><<(([|]))>><<(([|]))>><<(([|]))>><<(([|]))>>-- if pulsar <= multithreshold(0) and pulsarsave(1)>multithreshold(0) then --GET FWHM TIME for z in savescope downto 0 loop if z<=(accsec-peaktime) then --Quartus doesn't like variables in its for-loop ranges... if pulsarsave(z)<= 5*peak/10 then --success halfbacktime:=accsec-z; --record time exit; --and stop looping end if; end if; end loop; for z in 0 to savescope loop if z>=(accsec-peaktime) and z<=(accsec-time1)then --Quartus doesn't like variables in its for-loop ranges... if pulsarsave(z)<= 5*peak/10 then --same as above halffronttime:=accsec-z; exit; end if; end if; end loop; FWHM:=halfbacktime-halffronttime; peak:=0; end if; -- >>--0--O--o--+--o--O--0--<< >>--0--O--o--+--o--O--0--<< >>--0--O--o--+--o--O--0--<< >>--0--O--o--+--o--O--0--<< -- tester:=FWHM; for x in 11 downto 0 loop --readout in parallel if tester>=(2**x) then OTEST(x)<='1'; tester:=tester -2**x; else OTEST(x)<='0'; end if; end loop; end if; end process; end Herjolfssen7;