Belle II KLM Scint Firmware  1
DigitizeAndShiftOutData.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;
26 
28  port (
29  clk : in std_logic := '0';
30  rst : in std_logic := '0';
31  ena : in std_logic := '0';
32  busy : out std_logic := '0';
33 
34  -- state machine input parameters
35  win_samp_start_asic : in slv14(4 downto 0) := (others => (others=>'0'));
36  -- samp_start : in slv5(4 downto 0) := (others => "00000");
37  asic_mask : in std_logic_vector(4 downto 0) := (others=>'0');
38  first_dig_win : in std_logic_vector(8 downto 0);
39  last_dig_win : in std_logic_vector(8 downto 0);
40 
41  -- wires to ThresholdCheck
42  sample_data : out slv12(14 downto 0) := (others=>"000000000000");
43  samples_valid : out std_logic := '0'; -- samplesel & valid flag
44  -- samples_sel : out std_logic_vector(4 downto 0) := (others=>'0');
45  current_asic : out std_logic_vector(4 downto 0) := "00001";
46 
47  -- control registers
48  ramp_length : in std_logic_vector (11 downto 6);
49  -- force_test_pattern : in std_logic := '0';
50  t_samp_addr_settle : in std_logic_vector(3 downto 0) := "0110";-- 6
51  t_setup_ss_any : in std_logic_vector(3 downto 0) := "0110";-- 6
52  t_strobe_settle : in std_logic_vector(3 downto 0) := "0100";-- 4
53  t_sr_clk_high : in std_logic_vector(3 downto 0) := "0010";-- 2
54  t_sr_clk_low : in std_logic_vector(3 downto 0) := "0010";-- 2
55  t_sr_clk_strobe : in std_logic_vector(3 downto 0) := "0110";-- 6
56  N_readout_samples : in std_logic_vector(7 downto 0);
57  -- status registers
58  DigBusy : out std_logic := '0';
59  ShiftOutWinBusy : out std_logic := '0';
60  ShiftOutSampBusy : out std_logic := '0';
61 
62  -- pins to TargetX
63  ---- digitization control
64  BUS_RD_ENA : out std_logic := '0';
65  BUS_CLR : out std_logic := '0';
66  BUS_RAMP : out std_logic := '0';
67  BUS_RD_WINSEL : out std_logic_vector(8 downto 0) := (others=>'0');
68 
69  ---- shift register data and control
70  BUS_DO : in std_logic_vector(14 downto 0) := (others=>'0');
71  SR_CLR : out std_logic := '0';
72  SR_CLK : out std_logic_vector(4 downto 0) := (others=>'0');
73  SR_SEL : out std_logic := '0';
74  SAMPLESEL : out std_logic_vector(4 downto 0) := (others=>'0');
75  SAMPLESEL_ANY : out std_logic_vector(4 downto 0) := (others=>'0')
76  );
77 end DigitizeAndShiftOutData;
78 
79 
80 architecture Behavioral of DigitizeAndShiftOutData is
81 
82 
83  type digitize_and_shift_out_window_data is (
84  IDLE,
85  WAIT_DIG_BUSY_TO_COME_UP, -- next_state = (WAIT_DIG_BUSY_TO_COME_UP) or (IDLE)
86  WAIT_DIG_WINDOW,
87  WAIT_SHIFT_BUSY_TO_COME_UP,
88  WAIT_SHIFT_OUT ---- next_state = WAIT_DIG_BUSY_TO_COME_UP
89  );
90  signal digNshift_state : digitize_and_shift_out_window_data := IDLE;
91 
92  -- internal state machine signals
93  signal ena_i : std_logic := '0';
94  -- signal count : std_logic_vector(7 downto 0) := "00000000";
95  -- signal earliest_win_samp : std_logic_vector(8 downto 0) := (others=>'0');
96  signal first_dig_win_i : std_logic_vector(8 downto 0) := (others=>'0');
97  signal BUS_RD_WINSEL_i : std_logic_vector(8 downto 0) := (others=>'0');
98  signal i_win_samp_start_asic : slv14(4 downto 0) := (others => (others=>'0'));
99 
100  -- ShiftOutWindow signals
101  signal shift_ena : std_logic := '0';
102  signal shift_asic_mask : std_logic_vector(4 downto 0);
103  signal shift_samp_start : slv5(4 downto 0) := (others=>(others=>'0'));
104  signal shift_samp_stop : slv5(4 downto 0) := (others=>(others=>'1'));
105  signal shift_busy : std_logic := '0';
106 
107 
108  -- DigitizingLgcTX signals
109  signal dig_ena : std_logic := '0';
110  signal dig_busy : std_logic := '0';
111 
112 ----------------------------------------
113 begin
114 
115  BUS_RD_WINSEL <= BUS_RD_WINSEL_i;
116  ShiftOutWinBusy <= shift_busy;
117  DigBusy <= dig_busy;
118 
119  DigLgc_i : entity work.DigitizingLgcTX
120  port map (
121  clk => clk,
122  rst => rst,
123  ena => dig_ena,
124  busy => dig_busy,
125 
126  -- control registers
127  -- force_test_pattern => force_test_pattern,
128  ramp_length => ramp_length,
129 
130  -- pins to TargetX
131  BUS_RD_ENA => BUS_RD_ENA,
132  BUS_CLR => BUS_CLR,
133  BUS_RAMP => BUS_RAMP
134  );
135 
136 
137  ShftWin_i : entity work.ShiftOutWindow
138  port map (
139  clk => clk,
140  rst => rst,
141  ena => shift_ena,
142  busy => shift_busy,
143  -- force_test_pattern => force_test_pattern,
144  t_samp_addr_settle => t_samp_addr_settle,
145  t_setup_ss_any => t_setup_ss_any,
146  t_strobe_settle => t_strobe_settle,
147  t_sr_clk_high => t_sr_clk_high ,
148  t_sr_clk_low => t_sr_clk_low ,
149  t_sr_clk_strobe => t_sr_clk_strobe ,
150  ShiftOutSampBusy => ShiftOutSampBusy,
151  asic_mask => shift_asic_mask,
152  samp_start_asic => shift_samp_start,
153  samp_stop_asic => shift_samp_stop,
154  samples_valid => samples_valid,
155  -- sample_sel => sample_sel,
156  sample_data => sample_data,
157  current_asic => current_asic,
158  BUS_DO => BUS_DO,
159  SR_CLR => SR_CLR,
160  SR_CLK => SR_CLK,
161  SR_SEL => SR_SEL,
162  SAMPLESEL => SAMPLESEL,
163  SAMPLESEL_ANY => SAMPLESEL_ANY
164  );
165 
166 
167  --detect start rising edge
168  process (clk, ena)
169  begin
170  if rising_edge(clk) then
171  ena_i <= ena;
172  end if;
173  end process;
174 
175 
176  process (clk, first_dig_win)
177  begin
178  if rising_edge(clk) then
179  first_dig_win_i <= first_dig_win;
180  end if;
181  end process;
182 
183 
184 
185  process(clk, ena_i, ena, first_dig_win_i, win_samp_start_asic, asic_mask,
186  dig_busy, BUS_RD_WINSEL_i, i_win_samp_start_asic, shift_busy, last_dig_win)
187  variable i_asic_mask : std_logic_vector(4 downto 0);
188  begin
189  if rising_edge(clk) then
190  if rst = '1' then
191  digNshift_state <= IDLE;
192  else
193  Case digNshift_state is
194 
195  When IDLE =>
196  shift_asic_mask <= (others=>'0');
197  shift_samp_stop <= (others=>"11111");
198  if ( ena_i = '0' and ena = '1' ) then
199  busy <= '1';
200  BUS_RD_WINSEL_i <= first_dig_win_i; -- set initial window address
201  -- count <= "00100000" - ("000" & samp_start); -- num samps shifted out in first win
202  i_win_samp_start_asic <= win_samp_start_asic;
203  -- samp_start_asic <= samp_start;
204  dig_ena <= '1';
205  i_asic_mask := asic_mask;
206  digNshift_state <= WAIT_DIG_BUSY_TO_COME_UP;
207  else
208  -- count <= (others=>'0');
209  i_win_samp_start_asic <= (others=>(others=>'0'));
210  BUS_RD_WINSEL_i <= (others=>'0');
211  shift_ena <= '0';
212  dig_ena <= '0';
213  busy <= '0';
214  digNshift_state <= IDLE;
215  end if;
216 
217  When WAIT_DIG_BUSY_TO_COME_UP =>
218  dig_ena <= '1';
219  if dig_busy = '1' then
220  digNshift_state <= WAIT_DIG_WINDOW;
221  else
222  digNshift_state <= WAIT_DIG_BUSY_TO_COME_UP;
223  end if;
224 
225  When WAIT_DIG_WINDOW =>
226  dig_ena <= '0';
227  if dig_busy = '1' then
228  digNshift_state <= WAIT_DIG_WINDOW;
229  else
230  digNshift_state <= WAIT_SHIFT_BUSY_TO_COME_UP;
231  shift_ena <= '1';
232  for i in 0 to 4 loop
233  if i_asic_mask(i) = '1' then
234 
235  if BUS_RD_WINSEL_i & "11111" - i_win_samp_start_asic(i) < N_readout_samples then
236  shift_asic_mask(i) <= '1';
237  else
238  shift_asic_mask(i) <= '0';
239  end if;
240 
241  if BUS_RD_WINSEL_i = i_win_samp_start_asic(i)(13 downto 5) then
242  shift_samp_start(i) <= i_win_samp_start_asic(i)(4 downto 0);
243  else
244  shift_samp_start(i) <= "00000";
245  end if;
246 
247  if BUS_RD_WINSEL_i = i_win_samp_start_asic(i)(13 downto 5) + "000000" & N_readout_samples(7 downto 5) then
248  shift_samp_stop(i) <= "11111" - i_win_samp_start_asic(i)(4 downto 0);
249  else
250  shift_samp_stop(i) <= "11111";
251  end if;
252 
253  end if;
254  end loop;
255  end if;
256 
257  When WAIT_SHIFT_BUSY_TO_COME_UP =>
258  shift_ena <= '1';
259  if shift_busy = '1' then
260  digNshift_state <= WAIT_SHIFT_OUT;
261  else
262  digNshift_state <= WAIT_SHIFT_BUSY_TO_COME_UP;
263  end if;
264 
265  When WAIT_SHIFT_OUT =>
266  shift_ena <= '0';
267  if shift_busy = '1' then
268  digNshift_state <= WAIT_SHIFT_OUT;
269  else
270  BUS_RD_WINSEL_i <= BUS_RD_WINSEL_i + "000000001"; -- automatically rolls over at window 512
271  -- shift_samp_start <= "00000";
272  if BUS_RD_WINSEL_i /= last_dig_win then
273  dig_ena <= '1';
274  digNshift_state <= WAIT_DIG_BUSY_TO_COME_UP;
275  else
276  dig_ena <= '0';
277  busy <= '0';
278  digNshift_state <= IDLE;
279  end if;
280 
281  end if;
282 
283  When OTHERS =>
284  digNshift_state <= IDLE;
285 
286  end case;
287  end if;
288  end if;
289  end process;
290 
291 
292 end Behavioral;