Belle II KLM Scint Firmware  1
b2tt_fifo_s6.vhd
1 ------------------------------------------------------------------------
2 -- b2tt_fifo component
3 --
4 -- 20131127 duplicated header fix (sta_drd was not properly cleared)
5 --
6 -- RAMB18 usage
7 --
8 -- - V5LX30(FTSW) has 64 ramb18
9 -- V5LX30T(MGTF) has 72 ramb18
10 -- V5LX50T(HSLB) has 120 ramb18
11 --
12 -- - each ramb18 has address space of
13 -- (13 downto 0) for 16384 bit
14 -- (13 downto 3) for 2048 byte
15 -- (13 downto 4) for 1024 word (16-bit)
16 --
17 -- - one event uses 64-bit, i.e., 4 16-bit words
18 --
19 -- - one ramb18 can store up to 255 event
20 -- (256th event is not used to distinguish full and empty)
21 --
22 -- (RAMB36 is not used)
23 -- RAMB36 usage (ug190 v4.3 p111)
24 -- port A - 8-bit I/O, auto incrementing address
25 -- port B - 8 or 16 or 32-bit I/O, read only
26 --
27 -- - 21 bit address space (20 downto 0) to cover 2 Mbit space,
28 -- or up to 64 ramb36 blocks (each ramb36 has 4096 bytes).
29 --
30 -- - V5LX30(FTSW) has 32 ramb36
31 -- V5LX30T(MGTF) has 36 ramb36
32 -- V5LX50T(HSLB) has 60 ramb36
33 --
34 -- - each ramb36 has address space of
35 -- (14 downto 0) for 32768 bit
36 -- (14 downto 3) for 4096 byte
37 -- (14 downto 4) for 2048 word (16-bit)
38 -- (14 downto 5) for 1024 long (32-bit)
39 ------------------------------------------------------------------------
40 library ieee;
41 use ieee.std_logic_1164.all;
42 use ieee.std_logic_unsigned.all;
43 use ieee.numeric_std.all;
44 library unisim;
45 use unisim.vcomponents.ALL;
46 
47 entity b2tt_fifo is
48  port (
49  clock : in std_logic;
50  enfifo : in std_logic;
51  clr : in std_logic;
52  wr : in std_logic;
53  din : in std_logic_vector (95 downto 0);
54  rd : in std_logic;
55  ready : out std_logic;
56  dout : out std_logic_vector (95 downto 0);
57  drd : out std_logic_vector (95 downto 0);
58  errs : out std_logic_vector (3 downto 0);
59  dbg : out std_logic_vector (17 downto 0);
60  err : out std_logic;
61  empty : out std_logic;
62  full : out std_logic );
63 end b2tt_fifo;
64 
65 architecture implementation of b2tt_fifo is
66 
67  signal buf_addra : std_logic_vector (9 downto 0) := (others => '0');
68  signal buf_addrb : std_logic_vector (9 downto 0) := (others => '0');
69  signal sta_adiff : std_logic_vector (9 downto 0) := (others => '0');
70 
71  signal seq_wr : std_logic := '0';
72  signal seq_rd : std_logic_vector (1 downto 0) := (others => '0');
73 
74  signal seq_dwr : std_logic_vector (5 downto 0) := (others => '0');
75  signal buf_dwr : std_logic_vector (95 downto 0) := (others => '0');
76 
77  signal sta_drd : std_logic := '0';
78  signal sig_drd : std_logic_vector (15 downto 0) := (others => '0');
79  signal seq_drd : std_logic_vector (5 downto 0) := (others => '0');
80  signal buf_drd : std_logic_vector (95 downto 0) := (others => '0');
81  signal sta_dout : std_logic := '0';
82  signal sta_ready : std_logic := '0';
83  signal buf_dout : std_logic_vector (95 downto 0) := (others => '0');
84 
85  signal sta_orun : std_logic := '0';
86  signal sta_empty : std_logic := '0';
87  signal sta_empty2 : std_logic := '0';
88  signal sta_half : std_logic := '0';
89  signal sta_full : std_logic := '0';
90  signal cnt_skip : std_logic_vector (1 downto 0) := (others => '0');
91  signal sta_err : std_logic_vector (2 downto 0) := (others => '0');
92  signal sig_dbg : std_logic_vector (23 downto 0) := (others => '0');
93 
94  signal open_doa : std_logic_vector (31 downto 0) := (others => '0');
95  signal open_dob : std_logic_vector (15 downto 0) := (others => '0');
96  signal open_dopa : std_logic_vector (3 downto 0) := (others => '0');
97  signal open_dopb : std_logic_vector (3 downto 0) := (others => '0');
98 begin
99  -- in
100  sta_adiff <= buf_addra - buf_addrb when buf_addra >= buf_addrb else
101  buf_addra + 1024 - buf_addrb;
102  sta_empty <= '1' when sta_adiff < (seq_drd'left+1) else '0';
103  sta_empty2 <= '1' when sta_adiff < (seq_drd'left+2) else '0';
104 
105  proc: process (clock)
106  begin
107  if clock'event and clock = '1' then
108 
109  -- sta_err
110  if clr = '1' or enfifo = '0' then
111  sta_err <= (others => '0');
112  else
113  if wr = '1' and seq_dwr /= 0 then
114  sta_err(0) <= '1';
115  end if;
116  if wr = '1' and sta_full = '1' then
117  sta_err(1) <= '1';
118  end if;
119  if wr = '1' and seq_wr = '1' then
120  sta_err(2) <= '1';
121  end if;
122  end if;
123 
124  -- buf_dout, sta_dout, sta_ready
125  if clr = '1' then
126  buf_dout <= (others => '1');
127  sta_dout <= '0';
128  sta_ready <= '0';
129  elsif rd = '1' then
130  sta_ready <= '0'; -- need at least one clock gap
131  elsif (seq_rd = "01" or sta_dout = '0') and sta_drd = '1' then
132  buf_dout <= buf_drd; -- from cache buffer
133  sta_dout <= '1';
134  sta_ready <= '1';
135  elsif sta_dout = '0' and sta_drd = '0' and -- not in cache buffer
136  sta_empty2 = '1' and (cnt_skip /= 0 or seq_drd = 0) and
137  seq_wr = '0' and wr = '1' then -- and at write timing
138  buf_dout <= din;
139  sta_dout <= '1';
140  sta_ready <= '1';
141  elsif seq_rd = "01" then
142  buf_dout(buf_dout'left downto 8) <= (others => '1');
143  buf_dout(7 downto 0) <= x"f2";
144  sta_dout <= '0';
145  end if;
146 
147  -- cnt_skip
148  if clr = '1' then
149  cnt_skip <= (others => '0');
150  elsif (seq_rd = "01" or sta_dout = '0') and sta_drd = '1' then
151  --
152  elsif sta_dout = '0' and sta_drd = '0' and -- not in cache buffer
153  sta_empty2 = '1' and (cnt_skip /= 0 or seq_drd = 0) and
154  seq_wr = '0' and wr = '1' then -- and at write timing
155  cnt_skip <= cnt_skip + 1;
156  if cnt_skip = 0 then
157  sig_dbg <= "00" & buf_addra & "00" & buf_addrb;
158  end if;
159  elsif seq_drd(seq_drd'left) = '1' and
160  seq_drd(seq_drd'left-1 downto 0) = 0 and cnt_skip /= 0 then
161  cnt_skip <= cnt_skip - 1;
162  end if;
163 
164  -- buf_dwr, seq_dwr
165  if seq_wr = '0' and wr = '1' and seq_dwr = 0 and sta_full = '0' then
166  buf_dwr <= din;
167  seq_dwr <= (others => '1');
168  else
169  buf_dwr <= buf_dwr(buf_dwr'left-16 downto 0) & x"0000";
170  seq_dwr <= seq_dwr(seq_dwr'left-1 downto 0) & '0';
171  end if;
172 
173  -- seq_drd
174  if clr = '1' then
175  seq_drd <= (others => '0');
176  elsif sta_drd = '0' and sta_empty = '0' and seq_drd = 0 then
177  seq_drd <= (others => '1');
178  else
179  seq_drd <= seq_drd(seq_drd'left-1 downto 0) & '0';
180  end if;
181 
182  -- sta_drd
183  if clr = '1' then
184  sta_drd <= '0';
185  elsif (seq_rd = "01" or sta_dout = '0') and sta_drd = '1' then
186  sta_drd <= '0';
187  elsif seq_drd(seq_drd'left) = '1' and
188  seq_drd(seq_drd'left-1 downto 0) = 0 and cnt_skip = 0 then
189  sta_drd <= '1';
190  end if;
191 
192  -- buf_drd
193  if clr = '1' then
194  buf_drd <= (others => '1');
195  elsif cnt_skip /= 0 then
196  --buf_drd <= (others => '1');
197  buf_drd(buf_drd'left downto 40) <= (others => '1');
198  buf_drd(39 downto 16) <= sig_dbg;
199  buf_drd(15 downto 12) <= "00" & cnt_skip;
200  buf_drd(11 downto 8) <= '0' & sta_err;
201  buf_drd(7 downto 0) <= x"f1";
202  elsif seq_drd(seq_drd'left) = '1' then
203  buf_drd <= buf_drd(buf_drd'left - 16 downto 0) & sig_drd;
204  elsif seq_rd = "01" then
205  --buf_drd <= (others => '1');
206  buf_drd(buf_drd'left downto 8) <= (others => '1');
207  buf_drd(7 downto 0) <= x"f0";
208  end if;
209 
210  -- seq_rd, seq_wr
211  seq_wr <= wr;
212  seq_rd <= seq_rd(0) & rd;
213 
214  -- buf_addra
215  if clr = '1' then
216  buf_addra <= (others => '0');
217  elsif seq_dwr(seq_dwr'left) = '1' then
218  buf_addra <= buf_addra + 1; -- turn over to 0
219  end if;
220 
221  -- buf_addrb
222  if clr = '1' then
223  buf_addrb <= (others => '0');
224  elsif sta_drd = '0' and sta_empty = '0' and seq_drd = 0 then
225  buf_addrb <= buf_addrb + 1; -- condition to set seq_drd all '1'
226  elsif seq_drd(seq_drd'left-1) = '1' then
227  buf_addrb <= buf_addrb + 1; -- turns over to 0
228  end if;
229 
230  -- sta_orun
231  if clr = '1' or enfifo = '0' then
232  sta_orun <= '0';
233  elsif sta_dout = '0' and seq_rd = "01" then
234  sta_orun <= '1';
235  end if;
236 
237  -- sta_full
238  -- one event consumes 6 16-bit words
239  -- fifo size : 1024x16-bit word = 170 x (16-bit x 6) event
240  -- full limit set at 168 event
241  -- half limit set at 150 event, 18 trigger may still come
242  if clr = '1' or enfifo = '0' then
243  sta_full <= '0';
244  sta_half <= '0';
245  elsif sta_adiff >= 150*6 and sta_orun = '0' then
246  sta_half <= '1';
247  elsif sta_adiff >= 168*6 and sta_orun = '0' then
248  sta_full <= '1';
249  else
250  sta_half <= '0';
251  end if;
252  end if; -- event
253  end process;
254 
255  -- RAMB16BWER
256  map_ram: ramb16bwer
257  generic map (
258  DATA_WIDTH_A => 18, DATA_WIDTH_B => 18 )
259 
260  port map (
261  -- port A
262  addra(13 downto 4) => buf_addra,
263  addra(3 downto 0) => "0000",
264  dia(31 downto 16) => x"0000",
265  dia(15 downto 0) => buf_dwr(buf_dwr'left downto buf_dwr'left-15),
266  dipa => "0000",
267  doa => open_doa,
268  dopa => open_dopa,
269  wea(3 downto 2) => "00",
270  wea(1) => seq_dwr(seq_dwr'left),
271  wea(0) => seq_dwr(seq_dwr'left),
272  ena => '1',
273  regcea => '1',
274  rsta => '0',
275  clka => clock,
276 
277  -- port B
278  addrb(13 downto 4) => buf_addrb,
279  addrb(3 downto 0) => "0000",
280  dib => x"00000000",
281  dipb => "0000",
282  dob(31 downto 16) => open_dob,
283  dob(15 downto 0) => sig_drd,
284  dopb => open_dopb,
285  web => "0000",
286  enb => '1',
287  regceb => '1',
288  rstb => '0',
289  clkb => clock );
290 
291  -- out (async)
292  empty <= sta_empty;
293 
294  -- out
295  ready <= sta_ready;
296  errs <= sta_orun & sta_err;
297  err <= '1' when sta_err /= 0 else (sta_full or sta_orun);
298  full <= sta_half;
299  dout <= buf_dout;
300  drd <= buf_drd;
301  dbg <= sta_dout & sta_drd & buf_addrb(7 downto 0) & buf_addra(7 downto 0);
302 
303 end implementation;