Belle II KLM Scint Firmware  1
b2tt_ddr_s6.vhd
1 ------------------------------------------------------------------------
2 --
3 -- b2tt_ddr_s6.vhd -- TT-link DDR and delay hander for Belle2link
4 -- frontend for Spartan-6
5 --
6 -- Mikihiko Nakao, KEK IPNS
7 --
8 -- 20131002 separated from b2tt_decode.vhd and b2tt_encode.vhd
9 -- 20131013 Spartan-6 support
10 -- 20131101 no more std_logic_arith
11 -- 20131113 merging changes to ddr_v5 into ddr_s6
12 -- 20131119 bitddr output from dataout2, sig_inc was forgotten
13 -- 20131120 cal to be asserted with data - once in 1024 times of sig_inc
14 -- 20140614 dbg added for chipscope
15 -- 20140711 new scheme to find the stable delay
16 -- 20150722 "not clock" instead of 180 deg shifted invclock
17 -- (somehow ise14 could not build sp605_b2l006)
18 --
19 -- tap calibration based on SP605 (sp605_b2tt09.bit)
20 -- 2.32 ns per 100 inc => about 170 inc to cover (7.86ns/2)
21 --
22 -- VARIABLE_FROM_HALF_MAX resets to somewhere not zero
23 -- DIFF_PHASE_DETECTOR does not increment
24 -- VARIABLE_FROM_ZERO resets to zero at 163 inc (maybe internally measured)
25 --
26 ------------------------------------------------------------------------
27 
28 ------------------------------------------------------------------------
29 -- - b2tt_iddr
30 ------------------------------------------------------------------------
31 library ieee;
32 use ieee.std_logic_1164.all;
33 use ieee.std_logic_unsigned.all;
34 use ieee.numeric_std.all;
35 library unisim;
36 use unisim.vcomponents.ALL;
37 
38 entity b2tt_iddr is
39  generic (
40  FLIPIN : std_logic := '0';
41  REFFREQ : real := 203.546;
42  SLIPBIT : integer := 0; -- 0 for v5/s6, 1 for v6
43  WRAPCOUNT : integer := 170; -- 51 for v5, 25 for v6, 170 for s6
44  FULLCOUNT : integer := 340; -- *2 for v5/s6, *4 for v6
45  SIM_SPEEDUP : std_logic := '0' ); -- to speedup simulation
46  --
47  -- Virtex-5 and Virtex-6 (both):
48  -- 1 tap = 7.8 ns / ((8/5*64)) = 78 ps
49  -- [for V5, idelayctrl clock tick = 7.8 ns / (8/5)]
50  -- Virtex-5: 51 taps to cover the delay range (V5)
51  -- Virtex-6: there is no way to cover half clock width of 3.9ns
52  -- since 31 is the max tap which is about 2.4ns
53  -- => oversample with iserdes for 1.95ns period to be covered
54  -- by 25 taps (cnt_islip=0..3)
55  --
56  port (
57  clock : in std_logic;
58  invclock : in std_logic; -- spartan6 only
59  dblclock : in std_logic; -- virtex6 only
60  dblclockb : in std_logic; -- virtex6 only
61  inp : in std_logic;
62  inn : in std_logic;
63  staoctet : in std_logic;
64  stacrc8ok : in std_logic;
65  manual : in std_logic;
66  incdelay : in std_logic;
67  clrdelay : in std_logic;
68  caldelay : in std_logic; -- spartan6 only
69  staiddr : out std_logic_vector (1 downto 0);
70  bitddr : out std_logic;
71  bit2 : out std_logic_vector (1 downto 0);
72  cntdelay : out std_logic_vector (6 downto 0);
73  cntwidth : out std_logic_vector (5 downto 0);
74  iddrdbg : out std_logic_vector (9 downto 0) );
75 
76 end b2tt_iddr;
77 ------------------------------------------------------------------------
78 architecture implementation of b2tt_iddr is
79  signal sig_i : std_logic := '0';
80  signal sig_q : std_logic := '0';
81  signal sig_inc : std_logic := '0';
82  signal clr_inc : std_logic := '0';
83  signal sig_islip : std_logic := '0';
84  signal clr_islip : std_logic := '0';
85 
86  signal sig_bit2 : std_logic_vector (1 downto 0) := "00";
87  signal sig_raw2 : std_logic_vector (1 downto 0) := "00";
88  signal sta_slip : std_logic := '0';
89  signal buf_bit : std_logic := '0';
90 
91  -- spartan6 only
92  signal open_do : std_logic := '0';
93  signal open_to : std_logic := '0';
94  signal sig_busy : std_logic := '0';
95  signal sig_caldelay : std_logic := '0';
96  signal seq_caldelay : std_logic_vector (1 downto 0) := "01";
97  signal sig_invclock : std_logic := '0';
98 begin
99  -- in
100  sig_invclock <= not clock;
101 
102  map_ibufds: ibufds
103  port map ( o => sig_i, i => inp, ib => inn );
104 
105  map_idelay: iodelay2
106  generic map (
107  IDELAY_VALUE => 0,
108  IDELAY2_VALUE => 0,
109  IDELAY_MODE => "NORMAL",
110  IDELAY_TYPE => "VARIABLE_FROM_ZERO",
111  DATA_RATE => "DDR",
112  COUNTER_WRAPAROUND => "WRAPAROUND",
113  DELAY_SRC => "IDATAIN" )
114  port map (
115  idatain => sig_i,
116  odatain => '0',
117  dataout => sig_q,
118  ioclk0 => clock,
119  ioclk1 => sig_invclock,
120  clk => clock,
121  ce => sig_inc,
122  rst => clr_inc,
123  inc => '1',
124  t => '1', -- 1 for input only / 0 for output only
125  cal => sig_caldelay, -- no auto-caldelay
126  dataout2 => bitddr,
127  busy => sig_busy,
128  dout => open_do,
129  tout => open_to );
130 
131  map_id: iddr2
132  generic map (
133  DDR_ALIGNMENT => "C0" )
134  port map (
135  s => '0',
136  d => sig_q,
137  ce => '1',
138  c0 => clock,
139  c1 => sig_invclock,
140  r => '0',
141  q0 => sig_raw2(0),
142  q1 => sig_raw2(1) );
143 
144  sig_bit2(0) <= sig_raw2(0) xor FLIPIN;
145  sig_bit2(1) <= sig_raw2(1) xor FLIPIN;
146 
147  process(clock)
148  begin
149  if rising_edge(clock) then
150  -- slipped bit is generated upon clock,
151  -- as asynchronous bit2 was timing-tight
152  if sta_slip = '0' then
153  bit2 <= sig_bit2;
154  else
155  bit2 <= buf_bit & sig_bit2(1);
156  end if;
157  buf_bit <= sig_bit2(0);
158 
159  -- sta_slip
160  if clr_islip = '1' then
161  sta_slip <= '0';
162  elsif sig_islip = '1' then
163  sta_slip <= not sta_slip;
164  end if;
165 
166  -- sig_caldelay
167  sig_caldelay <= caldelay or seq_caldelay(1);
168  seq_caldelay <= seq_caldelay(0) & '0';
169 
170  end if; -- clock
171  end process;
172 
173  map_iscan: entity work.b2tt_iscan
174  generic map (
175  FLIPIN => FLIPIN,
176  REFFREQ => REFFREQ,
177  SLIPBIT => SLIPBIT,
178  WRAPCOUNT => WRAPCOUNT,
179  FULLCOUNT => FULLCOUNT,
180  SIM_SPEEDUP => SIM_SPEEDUP )
181  port map (
182  -- from/to b2tt_decode
183  clock => clock,
184  staoctet => staoctet,
185  stacrc8ok => stacrc8ok,
186  manual => manual,
187  incdelay => incdelay,
188  clrdelay => clrdelay,
189  staiddr => staiddr, -- out
190  cntdelay => cntdelay, -- out
191  cntwidth => cntwidth, -- out
192  iddrdbg => iddrdbg, -- out
193  -- from/to b2tt_iddr
194  siginc => sig_inc, -- out
195  sigislip => sig_islip, -- out
196  clrinc => clr_inc, -- out
197  clrislip => clr_islip) ; -- out
198 
199 end implementation;
200 
201 ------------------------------------------------------------------------
202 -- b2tt_oddr
203 ------------------------------------------------------------------------
204 library ieee;
205 use ieee.std_logic_1164.all;
206 use ieee.std_logic_unsigned.all;
207 use ieee.numeric_std.all;
208 library unisim;
209 use unisim.vcomponents.ALL;
210 
211 entity b2tt_oddr is
212  generic (
213  FLIPOUT : std_logic := '0';
214  REFFREQ : real := 203.546 );
215  port (
216  clock : in std_logic;
217  invclock : in std_logic;
218  mask : in std_logic;
219  bit2 : in std_logic_vector (1 downto 0);
220  bitddr : out std_logic;
221  outp : out std_logic;
222  outn : out std_logic
223  );
224 end b2tt_oddr;
225 ------------------------------------------------------------------------
226 architecture implementation of b2tt_oddr is
227  signal sig_o : std_logic := '0';
228  signal sig_oq : std_logic := '0';
229  signal sig_bit2 : std_logic_vector (1 downto 0) := "00";
230  signal sig_invclock : std_logic := '0';
231 begin
232  -- in
233  sig_invclock <= not clock;
234  sig_bit2(0) <= bit2(0) xor FLIPOUT;
235  sig_bit2(1) <= bit2(1) xor FLIPOUT;
236 
237  map_obufds: obuftds
238  port map ( i => sig_o, o => outp, ob => outn, t => mask );
239 
240  map_odelay: iodelay2
241  generic map (
242  ODELAY_VALUE => 0,
243  DELAY_SRC => "ODATAIN" )
244  port map (
245  idatain => '0',
246  t => '0',
247  odatain => sig_oq,
248  cal => '0',
249  ioclk0 => '0',
250  ioclk1 => '0',
251  clk => '0',
252  inc => '1',
253  ce => '0',
254  rst => '0',
255  dataout2 => bitddr,
256  dout => sig_o );
257 
258  map_od: oddr2
259  generic map (
260  DDR_ALIGNMENT => "C0",
261  SRTYPE => "ASYNC" )
262  port map (
263  s => '0',
264  d0 => sig_bit2(1), -- order: d1 first, d2 second
265  d1 => sig_bit2(0), -- (10b: left-most-bit first, right-most last)
266  ce => '1',
267  c0 => clock,
268  c1 => sig_invclock,
269  r => '0',
270  q => sig_oq );
271 
272  -- out
273  --bitddr <= sig_o;
274  --bitddr <= '0';
275 
276 end implementation;