You've already forked gitified_old_clb_svn
473 lines
14 KiB
VHDL
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;
|