Files
2020-08-05 08:06:17 +00:00

473 lines
14 KiB
VHDL

------------------------------------------------------------------------------
-- Title : Wishbone TDC
------------------------------------------------------------------------------
-- Author : David Calvo
-- Company : IFIC
-- Platform : FPGA-generic
-------------------------------------------------------------------------------
-- Description: Recovery Unit
--
-------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;
library work;
use work.tdc_pkg.all;
entity DRU is
Port (
enable : in std_logic;
e_channel : in std_logic;
e_veto : in std_logic;
e_multihit : in std_logic;
n_channel : in std_logic_vector(7 downto 0);
min_tot : in std_logic_vector(7 downto 0);
almost_full_ctrl : in std_logic;
clk : in std_logic;
ref_clk_lock : in std_logic;
rst : in std_logic;
d_in : in std_logic_vector (3 downto 0);
offset : in std_logic_vector(27 downto 0);
fifo_almostfull_flag : in std_logic;
fifo_full_flag : in std_logic;
d_out : out std_logic_vector (50 downto 0);
new_time_slice : in std_logic;
veto_value : in std_logic_vector(31 downto 0);
hits_cnt : out hit;
new_data : out std_logic);
--test_stop : out std_logic);
end DRU;
architecture Behavioral of DRU is
SIGNAL count: unsigned(7 downto 0);
signal count_ts:unsigned(3 downto 0);
signal flag_rem,n_d:std_logic;
signal s_offset,s2_offset:unsigned(27 downto 0);
signal p_state:std_logic_vector(2 downto 0);
signal s_d_out:std_logic_vector(50 downto 0);
signal s_d_in:std_logic_vector(3 downto 0);
signal hits:unsigned(31 downto 0);
signal stop_data,stop_data_prev,stop_data_prev2,veto,veto_info,fifo_accumulate:std_logic;
signal short_pulse:std_logic;
begin
ync_offset:process(clk,rst)
begin
if(rst='1') then
s_offset<=(others=>'0');
s2_offset<=(others=>'0');
elsif(rising_edge(clk)) then
s_offset<=unsigned(offset);
s2_offset<=s_offset;
end if;
end process;
--Sync Fine time Stamp with offset
sync_time_stamp:process(clk,rst)
begin
if(rst='1') then
count_ts<=(others=>'0');
elsif(rising_edge(clk)) then
if s_offset/=s2_offset then
count_ts<=(others=>'0');
else
count_ts<=count_ts+4;
end if;
end if;
end process;
Sync_signals:process(clk,rst)
begin
if (rst='1') then
s_d_in <= (others=>'0');
d_out <= (others=>'0');
new_data <= '0';
elsif(rising_edge(clk)) then
s_d_in <= d_in;
d_out <= s_d_out;
new_data <= n_d;
end if;
end process;
veto <= '0' when (e_veto='0' or hits < unsigned(veto_value)) else '1';
veto_info <= '0' when (e_veto='0' or hits < unsigned(veto_value)-1) else '1';
-- Forward TDC front-end FIFO full directly to the registers and IRQ of the LM32
hits_cnt.full<=fifo_almostfull_flag;
-- Forward other front-end information to Monitoring Channel
hits_cnt.status <= veto;
hits_cnt.channel<=n_channel;
hits_cnt.cnt<=std_logic_vector(hits);--tota_hits---> real hits.
-- Accumulate any occurence of a TDC front-end FIFO full condition for the current time slice.
process (rst, clk)
begin
if rst = '1' then
hits_cnt.accumulate_full <= '0';
hits_cnt.full_stop<='0';
stop_data_prev<='0';
fifo_accumulate<='0';
elsif rising_edge(clk) then
if new_time_slice = '1' then
hits_cnt.accumulate_full <= '0';
hits_cnt.full_stop<='0';
stop_data_prev<='0';
fifo_accumulate<='0';
else
if fifo_almostfull_flag = '1' then-- or almost_full_ctrl='1' then
hits_cnt.accumulate_full <= '1';
fifo_accumulate<='1';
stop_data_prev<='1';
if fifo_full_flag='1' then
hits_cnt.full_stop <= '1';
end if;
end if;
end if;
end if;
end process;
------------------------
---TDC READOUT----------
------------------------
PROCESS (clk,rst)
variable next_time_stamp:unsigned(31 downto 0):=(others=>'0');
variable cnt_bits_s_d_in: integer range 0 to 4;
variable p_width:std_logic_vector(7 downto 0);
--variable short_pulse:std_logic;
BEGIN
if (rst='1') then
short_pulse<='0';
p_state<="111";
count<=(others=>'0');
n_d<='0';
flag_rem<='0';
s_d_out<=(others=>'0');
hits<=(others=>'0');
--total_hits<=(others=>'0');
next_time_stamp:=(others=>'0');
elsif rising_edge(clk) then
if (enable='1' and e_channel='1' and ref_clk_lock='1') then
case p_state is
When "111"=>--waiting for first change of time slice mark to start storing data
if (new_time_slice='1') then
p_state<="110";
else
p_state<="111";
end if;
n_d <='0';
stop_data<='0';
When "110" =>--waiting until change time slice mark is null
if (new_time_slice='1') then
p_state<="110";
else
p_state<="000";
end if;
n_d <='0';
stop_data<='0';
When "000" => --count time stamp
if (new_time_slice='1' or flag_rem='1')then --new time slice in "low level" signal. Flag rem when the new_ts is produces it "high level"
s_d_out(49)<='1';
s_d_out(48)<=veto_info;
--s_d_out(47)<=fifo_accumulate;
count<=(others=>'0');
p_state<="100";--to avoid storing more than 1 timeslice mark when its bigger than 4 ns.
n_d<='1'; --always stored
flag_rem<='0';
next_time_stamp:=(others=>'0');
stop_data<='0';
--short_pulse:='0';
elsif (s_d_in="0000") then
p_state<="000";
count<="00000000";
n_d<='0';
--short_pulse:='0';
elsif (s_d_in>"0000") then
if (short_pulse='0') then
hits<=hits+1;
end if;
p_state<="001";
n_d<='0';
cnt_bits_s_d_in := 0;
for x in 0 to 3 loop
if s_d_in(x) = '1' then
cnt_bits_s_d_in := cnt_bits_s_d_in + 1;
end if;
end loop;
count<=count + cnt_bits_s_d_in;
next_time_stamp(3 downto 0):=count_ts + 4 - cnt_bits_s_d_in;
next_time_stamp(31 downto 4):=s2_offset;
--hits<=hits+1;
short_pulse<='1';
else
n_d<='0';
p_state<="000";
short_pulse<='0';
end if;
When "100" =>--mirar tb eventos-----------------
n_d<='0';
count<="00000000";
if (new_time_slice='1' )then
p_state<="100";
stop_data<='0';
else
p_state<="000";
hits<=(others=>'0');
short_pulse<='0';
--total_hits<=(others=>'0');
end if;
-- When "100" =>
-- if(new_time_slice='0')then
-- p_state<="000";
-- n_d<='0';
-- count<="00000000";
-- hits<=(others=>'0');
-- elsif (s_d_in="0000") then
-- p_state<="100";
-- count<="00000000";
-- hits<=(others=>'0');
-- n_d<='0';
-- else --new hit during time_slice is still '1'
-- p_state<="101";
-- n_d<='0';
-- cnt_bits_s_d_in := 0;
-- for x in 0 to 3 loop
-- if s_d_in(x) = '1' then
-- cnt_bits_s_d_in := cnt_bits_s_d_in + 1;
-- end if;
-- end loop;
-- count<=count + cnt_bits_s_d_in;
-- next_time_stamp(3 downto 0):=count_ts + 4 - cnt_bits_s_d_in;
-- next_time_stamp(31 downto 4):=s2_offset;
-- hits<=1;
-- end if;
When "101" => --multihit disable
if (new_time_slice='1') then
flag_rem<='1';
-- if(veto='0' and fifo_full_flag='0') then
-- n_d<='1';
-- else
n_d<='0';
stop_data<='0';
-- end if;
-- s_d_out(50)<='0';
-- s_d_out(49 downto 42)<=n_channel;
-- s_d_out(41 downto 34)<=std_logic_vector(next_time_stamp(31 downto 24));
-- s_d_out(33)<='0';
-- s_d_out(32 downto 17)<=std_logic_vector(next_time_stamp(23 downto 8));
-- s_d_out(16)<='0';
-- s_d_out(15 downto 12)<=std_logic_vector(next_time_stamp(7 downto 4));
-- s_d_out(11 downto 8)<=std_logic_vector(next_time_stamp(3 downto 0));--s_count_ts;
-- s_d_out(7 downto 0)<="00000000";
p_state<="000";
elsif (s_d_in="1111" and count<251) then
p_state<="101";
count<=count+4;
n_d<='0';
elsif (s_d_in="1111") then
if(count = 251) then
count<="00000000";
elsif(count = 252) then
count<="00000001";
elsif(count = 253) then
count<="00000010";
else --254
count<="00000011";
end if;
--if(veto='0' and fifo_full_flag='0') then
-- n_d<='1';
-- else
n_d<='0';
-- end if;
--total_hits<=total_hits+1;
-- s_d_out(50)<='0';
-- s_d_out(49 downto 42)<=n_channel;
-- s_d_out(41 downto 34)<=std_logic_vector(next_time_stamp(31 downto 24));
-- s_d_out(33)<='0';
-- s_d_out(32 downto 17)<=std_logic_vector(next_time_stamp(23 downto 8));
-- s_d_out(16)<='0';
-- s_d_out(15 downto 12)<=std_logic_vector(next_time_stamp(7 downto 4));
-- s_d_out(11 downto 8)<=std_logic_vector(next_time_stamp(3 downto 0));
-- s_d_out(7 downto 0)<="11111111";
next_time_stamp:=next_time_stamp+x"000000FF";
p_state<="101";
else
-- if(veto='0' and fifo_full_flag='0') then
-- n_d<='1';
-- else
n_d<='0';
--end if;
-- total_hits<=total_hits+1;
-- s_d_out(50)<='0';
-- s_d_out(49 downto 42)<=n_channel;
-- s_d_out(41 downto 34)<=std_logic_vector(next_time_stamp(31 downto 24));
-- s_d_out(33)<='0';
-- s_d_out(32 downto 17)<=std_logic_vector(next_time_stamp(23 downto 8));
-- s_d_out(16)<='0';
-- s_d_out(15 downto 12)<=std_logic_vector(next_time_stamp(7 downto 4));
-- s_d_out(11 downto 8)<=std_logic_vector(next_time_stamp(3 downto 0));
-- cnt_bits_s_d_in := 0;
-- for x in 0 to 3 loop
-- if s_d_in(x) = '1' then
-- cnt_bits_s_d_in := cnt_bits_s_d_in + 1;
-- end if;
-- end loop;
-- s_d_out(7 downto 0)<=std_logic_vector(count + cnt_bits_s_d_in);
count<=(others=>'0');
p_state<="000";
end if;
When "001" => --count width
if (new_time_slice='1') then
flag_rem<='1';
stop_data<='0';
if(veto='0' and stop_data='0') then --fifo_full_flag='0'
n_d<='1';
else
n_d<='0';
end if;
s_d_out(50)<='0';
s_d_out(49)<='0';
s_d_out(48)<=veto_info;
s_d_out(47)<=fifo_accumulate;
s_d_out(46 downto 42)<=n_channel(4 downto 0);
--s_d_out(49 downto 42)<=n_channel;
s_d_out(41 downto 34)<=std_logic_vector(next_time_stamp(31 downto 24));
s_d_out(33)<='0';
s_d_out(32 downto 17)<=std_logic_vector(next_time_stamp(23 downto 8));
s_d_out(16)<='0';
s_d_out(15 downto 12)<=std_logic_vector(next_time_stamp(7 downto 4));
s_d_out(11 downto 8)<=std_logic_vector(next_time_stamp(3 downto 0));--s_count_ts;
s_d_out(7 downto 0)<="00000000";
p_state<="000";
elsif (s_d_in="1111" and count<251) then
p_state<="001";
count<=count+4;
n_d<='0';
short_pulse<='0';
elsif (s_d_in="1111") then
short_pulse<='0';
if(count = 251) then
count<="00000000";
elsif(count = 252) then
count<="00000001";
elsif(count = 253) then
count<="00000010";
else --254
count<="00000011";
end if;
if(veto='0' and stop_data='0') then --fifo_full_flag='0'
if (stop_data_prev='1') then
stop_data<='1';
--s_d_out(47)<='1';
else
stop_data<='0';
--s_d_out(47)<='0';
end if;
n_d<='1';
--total_hits<=total_hits+1;
else
n_d<='0';
end if;
s_d_out(50)<='0';
s_d_out(49)<='0';
s_d_out(48)<=veto_info;
s_d_out(47)<=fifo_accumulate;
s_d_out(46 downto 42)<=n_channel(4 downto 0);
--s_d_out(49 downto 42)<=n_channel;
s_d_out(41 downto 34)<=std_logic_vector(next_time_stamp(31 downto 24));
s_d_out(33)<='0';
s_d_out(32 downto 17)<=std_logic_vector(next_time_stamp(23 downto 8));
s_d_out(16)<='0';
s_d_out(15 downto 12)<=std_logic_vector(next_time_stamp(7 downto 4));
s_d_out(11 downto 8)<=std_logic_vector(next_time_stamp(3 downto 0));
s_d_out(7 downto 0)<="11111111";
next_time_stamp:=next_time_stamp+x"000000FF";
if e_multihit='1' then
p_state<="001";
else
p_state<="101";
end if;
else
cnt_bits_s_d_in := 0;
for x in 0 to 3 loop
if s_d_in(x) = '1' then
cnt_bits_s_d_in := cnt_bits_s_d_in + 1;
end if;
end loop;
p_width:=std_logic_vector(cnt_bits_s_d_in+count);
if(veto='0' and stop_data='0') then--fifo_full_flag='0'
if (stop_data_prev='1') then
stop_data<='1';
--s_d_out(47)<='1';
else
stop_data<='0';
--s_d_out(47)<='0';
end if;
if (unsigned(p_width)>=unsigned(min_tot)) then
n_d<='1';
short_pulse<='0';
--hits<=hits-1;
else
n_d<='0';
end if;
else
n_d<='0';
end if;
s_d_out(50)<='0';
s_d_out(49)<='0';
s_d_out(48)<=veto_info;
s_d_out(47)<=fifo_accumulate;
s_d_out(46 downto 42)<=n_channel(4 downto 0);
--s_d_out(49 downto 42)<=n_channel;
s_d_out(41 downto 34)<=std_logic_vector(next_time_stamp(31 downto 24));
s_d_out(33)<='0';
s_d_out(32 downto 17)<=std_logic_vector(next_time_stamp(23 downto 8));
s_d_out(16)<='0';
s_d_out(15 downto 12)<=std_logic_vector(next_time_stamp(7 downto 4));
s_d_out(11 downto 8)<=std_logic_vector(next_time_stamp(3 downto 0));
s_d_out(7 downto 0)<=p_width;
count<=(others=>'0');
p_state<="000";
end if;
when others=>p_state<="111";n_d<='0';s_d_out<=(others=>'0');short_pulse<='0';
end case;
else
p_state<="000";
count<=(others=>'0');
n_d<='0';
flag_rem<='0';
end if;
end if;
END PROCESS;
end Behavioral;