Belle II KLM Scint Firmware  1
PedFetchQueue.vhd
1 library IEEE;
2 use IEEE.STD_LOGIC_1164.ALL;
3 use IEEE.NUMERIC_STD.ALL;
4 use IEEE.STD_LOGIC_MISC.ALL;
5 use IEEE.STD_LOGIC_UNSIGNED.ALL;
6 Library work;
7 use work.klm_scint_pkg.all;
8 
19 
20 
21 entity PedFetchQueue is
22  Port (
23  clk : in STD_logic;
24  rst : in STD_logic;
25  ena : in std_logic := '0';
26  busy : out std_logic := '0';
27 
28  -- event info
29  ch_mask : in slv15(4 downto 0) := (others=> (others=>'0'));
30  new_mask : in slv15(4 downto 0) := (others=> (others=>'0'));
31  thr_chk_busy : in std_logic := '0';
32 
33  -- wires to PedestalFetcher
34  fetch_ena : out std_logic := '0';
35  fetch_ack : in std_logic := '0';
36  asic_addr : out std_logic_vector(2 downto 0) := (others => '0');
37  chan_addr : out std_logic_vector(3 downto 0) := (others => '0')--;
38  -- ped_win_samp_start : out std_logic_vector(13 downto 0)
39  );
40 end PedFetchQueue;
41 
42 architecture Behavioral of PedFetchQueue is
43 
44 
45  type pedestal_queue_state_machine is (
46  IDLE,
47  CHECK_UPDATE,
48  ASIC_LOOP,
49  CHAN_LOOP,
50  WAIT_ACKNOWLEDGE,
51  WAIT_DONE
52  );
53  signal ped_queue_state : pedestal_queue_state_machine := IDLE;
54 
55  signal ena_i : std_logic_vector(1 downto 0) := "00";
56  signal thr_chk_busy_i : std_logic_vector(1 downto 0) := "00";
57  -- signal asic_mask_i : std_logic_vector(4 downto 0) := (others => '0');
58  signal not_done : std_logic := '0';
59  signal not_done_v : std_logic_vector(4 downto 0) := (others=>'0');
60  signal ch_mask_i : slv15(4 downto 0) := (others=> (others=>'0'));
61  signal new_mask_rdy : std_logic := '0';
62 
63 begin
64 
65  process(clk, ch_mask_i, ena_i)
66  begin
67  if rising_edge(clk) then
68  for asic in 0 to 4 loop
69  not_done_v(asic) <= or_reduce(ch_mask_i(asic));
70  end loop;
71  not_done <= or_reduce(not_done_v) or or_reduce(ena_i);
72  end if;
73  end process;
74 
75 
76  edge_det: process(clk, ena, thr_chk_busy)
77  begin
78  if rising_edge(clk) then
79  ena_i <= ena_i(0) & ena;
80  thr_chk_busy_i <= thr_chk_busy_i(0) & thr_chk_busy;
81  end if;
82  end process edge_det;
83 
84 
85  process(clk, thr_chk_busy_i, ch_mask, new_mask, ped_queue_state)
86  begin
87  if rising_edge(clk) then
88  if thr_chk_busy_i = "10" then
89  new_mask_rdy <= '1';
90  elsif ped_queue_state = IDLE then
91  new_mask_rdy <= '0';
92  else
93  new_mask_rdy <= new_mask_rdy;
94  end if;
95  end if;
96  end process;
97 
98 
99  pedestal_fetching_queue : process(clk, ena_i, ch_mask_i, not_done, ch_mask, new_mask)
100  variable int_asic : integer range 0 to 4;
101  variable int_chan : integer range 0 to 14;
102  begin
103  if (rising_edge(clk)) then
104  if rst = '1' then
105  ped_queue_state <= IDLE;
106  else
107  case ped_queue_state is
108 
109  when IDLE =>
110  ch_mask_i <= ch_mask;
111  if (ena_i = "01") then
112  busy <= '1';
113  ped_queue_state <= ASIC_LOOP;
114  else
115  busy <= '0';
116  ped_queue_state <= IDLE;
117  end if;
118 
119  when CHECK_UPDATE =>
120  if new_mask_rdy = '1' then
121  update_ch_mask : for i in 0 to 4 loop
122  ch_mask_i(i) <= ch_mask_i(i) and new_mask(i);
123  end loop;
124  end if;
125  ped_queue_state <= ASIC_LOOP;
126 
127  when ASIC_LOOP =>
128  if not_done = '1' then
129  for i in 0 to 4 loop
130  if or_reduce(ch_mask_i(i)) = '1' then
131  asic_addr <= std_logic_vector(to_unsigned(i, 3));
132  int_asic := i;
133  exit;
134  end if;
135  end loop;
136  ped_queue_state <= CHAN_LOOP;
137  else
138  busy <= '0';
139  ped_queue_state <= IDLE;
140  end if;
141 
142 
143  when CHAN_LOOP =>
144  if not_done = '1' then
145  for j in 0 to 14 loop
146  if ch_mask_i(int_asic)(j) = '1' then
147  chan_addr <= std_logic_vector(to_unsigned(j, 4));
148  int_chan := j;
149  exit;
150  end if;
151  end loop;
152  ped_queue_state <= WAIT_ACKNOWLEDGE;
153  else
154  busy <= '0';
155  ped_queue_state <= IDLE;
156  end if;
157 
158 
159  when WAIT_ACKNOWLEDGE =>
160  if not_done = '1' then
161  fetch_ena <= '1';
162  if fetch_ack = '1' then
163  fetch_ena <= '0';
164  ped_queue_state <= WAIT_DONE;
165  else
166  ped_queue_state <= WAIT_ACKNOWLEDGE;
167  end if;
168  else
169  busy <= '0';
170  ped_queue_state <= IDLE;
171  end if;
172 
173 
174  when WAIT_DONE =>
175  if not_done = '1' then
176  if fetch_ack = '1' then
177  ped_queue_state <= WAIT_DONE;
178  else
179  ch_mask_i(int_asic)(int_chan) <= '0';
180  ped_queue_state <= CHECK_UPDATE;
181  end if;
182  else
183  busy <= '0';
184  ped_queue_state <= IDLE;
185  end if;
186 
187 
188  end case;
189  end if;
190  end if;
191  end process;
192 
193 
194 
195 
196 
197 end Behavioral;
### PedFetchQueue Begins pedestal fetching with same asic/chan priority as ShiftOutWindow. If other bus us using PedestalFetcher, this module waits for it&#39;s turn. If ThresholdCheck is finished, the internal channel mask is updated with the new channel mask.If this happens while this module is waiting for it&#39;s turn to use PedestalFetcher, then it goes back and checks the mask again so as to not fetch pedestals for an unhit channel.