w11 - vhd 0.794
W11 CPU core and support modules
Loading...
Searching...
No Matches
rlink_tba.vhd
Go to the documentation of this file.
1-- $Id: rlink_tba.vhd 1181 2019-07-08 17:00:50Z mueller $
2-- SPDX-License-Identifier: GPL-3.0-or-later
3-- Copyright 2007-2014 by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4--
5------------------------------------------------------------------------------
6-- Module Name: rlink_tba - syn
7-- Description: rlink test bench adapter
8--
9-- Dependencies: -
10-- Test bench: -
11-- Target Devices: generic [synthesizable, but only used in tb's]
12-- Tool versions: xst 8.2-14.7; ghdl 0.18-0.31
13--
14-- Revision History:
15-- Date Rev Version Comment
16-- 2014-09-27 595 4.0 now full rlink v4 iface
17-- 2014-08-15 583 3.5 rb_mreq addr now 16 bit; add state r_txal;
18-- 2011-11-22 432 3.0.2 now numeric_std clean
19-- 2011-11-19 427 3.0.1 fix crc8_update usage;
20-- 2010-12-24 347 3.0 rename rritba->rlink_tba, CP_*->RL_*; rbus v3 port;
21-- 2010-06-18 306 2.5.1 rename rbus data fields to _rbf_
22-- 2010-06-07 302 2.5 use sop/eop framing instead of soc+chaining
23-- 2010-05-05 289 1.0.3 drop dead snooper code and unneeded unsigned casts
24-- 2008-03-02 121 1.0.2 remove snoopers
25-- 2007-10-12 88 1.0.1 avoid ieee.std_logic_unsigned, use cast to unsigned
26-- 2007-09-09 81 1.0 Initial version
27------------------------------------------------------------------------------
28
29library ieee;
30use ieee.std_logic_1164.all;
31use ieee.numeric_std.all;
32
33use work.slvtypes.all;
34use work.comlib.all;
35use work.rlinklib.all;
36use work.rlinktblib.all;
37
38entity rlink_tba is -- rlink test bench adapter
39 port (
40 CLK : in slbit; -- clock
41 RESET : in slbit; -- reset
42 CNTL : in rlink_tba_cntl_type; -- control port
43 DI : in slv16; -- input data
44 STAT : out rlink_tba_stat_type; -- status port
45 DO : out slv16; -- output data
46 RL_DI : out slv9; -- rlink: data in
47 RL_ENA : out slbit; -- rlink: data enable
48 RL_BUSY : in slbit; -- rlink: data busy
49 RL_DO : in slv9; -- rlink: data out
50 RL_VAL : in slbit; -- rlink: data valid
51 RL_HOLD : out slbit -- rlink: data hold
52 );
53end entity rlink_tba;
54
55
56architecture syn of rlink_tba is
57
58 constant d_f_cflag : integer := 8; -- d9: comma flag
59 subtype d_f_data is integer range 7 downto 0; -- d9: data field
60
61 subtype f_byte1 is integer range 15 downto 8;
62 subtype f_byte0 is integer range 7 downto 0;
63
64 type txstate_type is (
65 s_txidle, -- s_txidle: wait for ENA
66 s_txsop, -- s_txsop: send sop
67 s_txeop, -- s_txeop: send eop
68 s_txcmd, -- s_txcmd: send cmd
69 s_txal, -- s_txal: send addr lsb
70 s_txah, -- s_txah: send addr msb
71 s_txcl, -- s_txcl: send blk count lsb
72 s_txch, -- s_txcl: send blk count msb
73 s_txdl, -- s_txdl: send data lsb
74 s_txdh, -- s_txdh: send data msb
75 s_txcrcl1, -- s_txcrcl1: send cmd crc lsb in wblk
76 s_txcrch1, -- s_txcrch1: send cmd crc msb in wblk
77 s_txwbld, -- s_txwbld: wblk data load
78 s_txwbdl, -- s_txwbdl: wblk send data lsb
79 s_txwbdh, -- s_txwbdh: wblk send data msb
80 s_txcrcl2, -- s_txcrcl2: send final crc lsb
81 s_txcrch2 -- s_txcrch2: send final crc msb
82 );
83
84 type txregs_type is record
85 state : txstate_type; -- state
86 ccmd : slv3; -- current command
87 snum : slv5; -- command sequence number
88 crc : slv16; -- crc (cmd and data)
89 braddr : slv16; -- block read address
90 bdata : slv16; -- block data
91 bloop : slbit; -- block loop flag
92 tcnt : slv16; -- tcnt (down count for wblk)
93 sopdone : slbit; -- sop send
94 eoppend : slbit; -- eop pending
95 end record txregs_type;
96
97 constant txregs_init : txregs_type := (
98 s_txidle, -- state
99 "000", -- ccmd
100 "00000", -- snum
101 (others=>'0'), -- crc
102 (others=>'0'), -- braddr
103 (others=>'0'), -- bdata
104 '0', -- bloop
105 (others=>'0'), -- tcnt
106 '0','0' -- sopdone, eoppend
107 );
108
109 type rxstate_type is (
110 s_rxidle, -- s_rxidle: wait for ENA
111 s_rxcmd, -- s_rxcmd: wait cmd
112 s_rxcl, -- s_rxcl: wait cnt lsb
113 s_rxch, -- s_rxcl: wait cnt msb
114 s_rxbabo, -- s_rxbabo: wait babo
115 s_rxdcl, -- s_rxdcl: wait dcnt lsb
116 s_rxdch, -- s_rxdch: wait dcnt msb
117 s_rxdl, -- s_rxdl: wait data lsb
118 s_rxdh, -- s_rxdh: wait data msb
119 s_rxstat, -- s_rxstat: wait status
120 s_rxcrcl, -- s_rxcrcl: wait crc lsb
121 s_rxcrch, -- s_rxcrch: wait crc msb
122 s_rxapl, -- s_rxapl: wait attn pat lsb
123 s_rxaph, -- s_rxaph: wait attn pat msb
124 s_rxacl, -- s_rxapl: wait attn crc lsb
125 s_rxach -- s_rxaph: wait attn crc msb
126 );
127
128 type rxregs_type is record
129 state : rxstate_type; -- state
130 ccmd : slv3; -- current command
131 crc : slv16; -- crc
132 bwaddr : slv16; -- block write address
133 data : slv16; -- received data
134 dcnt : slv16; -- done count
135 tcnt : slv16; -- tcnt (down count for rblk)
136 ack : slbit; -- ack flag
137 err : slbit; -- crc error flag
138 stat : slv8; -- stat
139 apend : slbit; -- attn pending
140 ano : slbit; -- attn notify seen
141 apat : slv16; -- attn pat
142 end record rxregs_type;
143
144 constant rxregs_init : rxregs_type := (
145 s_rxidle, -- state
146 "000", -- ccmd
147 (others=>'0'), -- crc
148 (others=>'0'), -- bwaddr
149 (others=>'0'), -- data
150 (others=>'0'), -- dcnt
151 (others=>'0'), -- tcnt
152 '0','0', -- ack, err
153 (others=>'0'), -- stat
154 '0','0', -- apend, ano
155 (others=>'0') -- attn pat
156 );
157
158 signal R_TXREGS : txregs_type := txregs_init; -- TX state registers
159 signal N_TXREGS : txregs_type := txregs_init; -- TX next value state regs
160
161 signal R_RXREGS : rxregs_type := rxregs_init; -- RX state registers
162 signal N_RXREGS : rxregs_type := rxregs_init; -- RX next value state regs
163
164 signal TXBUSY : slbit := '0';
165 signal RXBUSY : slbit := '0';
166
167 signal STAT_L : rlink_tba_stat_type := rlink_tba_stat_init; -- local, readable
168
169begin
170
171 proc_regs: process (CLK)
172 begin
173
174 if rising_edge(CLK) then
175 if RESET = '1' then
178 else
181 end if;
182 end if;
183
184 end process proc_regs;
185
186 -- tx FSM ==================================================================
187
188 proc_txnext: process (R_TXREGS, CNTL, DI, RL_BUSY)
189 variable r : txregs_type := txregs_init;
190 variable n : txregs_type := txregs_init;
191
192 variable itxbusy : slbit := '0';
193 variable icpdi : slv9 := (others=>'0');
194 variable iena : slbit := '0';
195 variable ibre : slbit := '0';
196 variable do_crc : slbit := '0';
197
198 begin
199
200 r := R_TXREGS;
201 n := R_TXREGS;
202
203 itxbusy := '1';
204 icpdi := (others=>'0');
205 iena := '0';
206 ibre := '0';
207 do_crc := '0';
208
209 if CNTL.eop='1' and r.state/= s_txidle then -- if eop requested and busy
210 n.eoppend := '1'; -- queue it
211 end if;
212
213 case r.state is
214 when s_txidle => -- s_txidle: wait for ENA ------------
215 itxbusy := '0';
216 if CNTL.ena = '1' then -- cmd requested
217 n.ccmd := CNTL.cmd;
218 if CNTL.eop = '1' then -- if eop requested with ENA
219 n.eoppend := '1'; -- queue it, eop after this cmd
220 end if;
221 if r.sopdone = '0' then -- if not in active packet
222 n.snum := (others=>'0'); -- set snum=0
223 n.state := s_txsop; -- send sop
224 else
225 n.state := s_txcmd;
226 end if;
227 else -- no cmd requested
228 if CNTL.eop='1' and r.sopdone='1' then -- if eop req and in packet
229 n.state := s_txeop; -- send eop
230 end if;
231 end if;
232
233 when s_txsop => -- s_txsop: send sop -----------------
234 n.sopdone := '1';
235 icpdi := c_rlink_dat_sop;
236 iena := '1';
237 if RL_BUSY = '0' then
238 n.crc := (others=>'0');
239 n.state := s_txcmd;
240 end if;
241
242 when s_txeop => -- s_txeop: send eop -----------------
243 n.sopdone := '0';
244 n.eoppend := '0';
245 icpdi := c_rlink_dat_eop;
246 iena := '1';
247 if RL_BUSY = '0' then
248 n.crc := (others=>'0');
249 n.state := s_txidle;
250 end if;
251
252 when s_txcmd => -- s_txcmd: send cmd -----------------
253 n.tcnt := CNTL.cnt;
254 n.braddr := (others=>'0');
255 icpdi(c_rlink_cmd_rbf_seq) := r.snum;
256 icpdi(c_rlink_cmd_rbf_code) := r.ccmd;
257 iena := '1';
258 if RL_BUSY = '0' then
259 do_crc := '1';
260 n.snum := slv(unsigned(r.snum) + 1);-- otherwise just increment snum
261 case r.ccmd is
262 when c_rlink_cmd_labo => n.state := s_txcrcl2;
263 when c_rlink_cmd_attn => n.state := s_txcrcl2;
264 when others => n.state := s_txal;
265 end case;
266 end if;
267
268 when s_txal => -- s_txal: send addr lsb -------------
269 icpdi := '0' & CNTL.addr(f_byte0);
270 iena := '1';
271 if RL_BUSY = '0' then
272 do_crc := '1';
273 n.state := s_txah;
274 end if;
275
276 when s_txah => -- s_txah: send addr msb -------------
277 icpdi := '0' & CNTL.addr(f_byte1);
278 iena := '1';
279 if RL_BUSY = '0' then
280 do_crc := '1';
281 case r.ccmd is
282 when c_rlink_cmd_rreg => n.state := s_txcrcl2;
283 when c_rlink_cmd_rblk => n.state := s_txcl;
284 when c_rlink_cmd_wblk => n.state := s_txcl;
285 when others => n.state := s_txdl;
286 end case;
287 end if;
288
289 when s_txcl => -- s_txcl: send blk count lsb -------
290 icpdi := '0' & CNTL.cnt(f_byte0);
291 iena := '1';
292 if RL_BUSY = '0' then
293 do_crc := '1';
294 n.state := s_txch;
295 end if;
296
297 when s_txch => -- s_txch: send blk count msb -------
298 icpdi := '0' & CNTL.cnt(f_byte1);
299 iena := '1';
300 if RL_BUSY = '0' then
301 do_crc := '1';
302 if r.ccmd = c_rlink_cmd_wblk then
303 n.state := s_txcrcl1;
304 else
305 n.state := s_txcrcl2;
306 end if;
307 end if;
308
309 when s_txdl => -- s_txdl: send data lsb -------------
310 icpdi := '0' & DI(d_f_data);
311 iena := '1';
312 if RL_BUSY = '0' then
313 do_crc := '1';
314 n.state := s_txdh;
315 end if;
316
317 when s_txdh => -- s_txdh: send data msb -------------
318 icpdi := '0' & DI(f_byte1);
319 iena := '1';
320 if RL_BUSY = '0' then
321 do_crc := '1';
322 n.state := s_txcrcl2;
323 end if;
324
325 when s_txcrcl1 => -- s_txcrcl1: send cmd crc lsb in wblk
326 icpdi := '0' & r.crc(f_byte0);
327 iena := '1';
328 if RL_BUSY = '0' then
329 n.state := s_txcrch1;
330 end if;
331
332 when s_txcrch1 => -- s_txcrch1: send cmd crc msb in wblk
333 icpdi := '0' & r.crc(f_byte1);
334 iena := '1';
335 if RL_BUSY = '0' then
336 n.state := s_txwbld;
337 end if;
338
339 when s_txwbld => -- s_txwbld: wblk data load ----------
340 -- this state runs when s_wreg is
341 -- executed in rlink, thus doesn't cost
342 -- an extra cycle in 2nd+ iteration.
343 ibre := '1';
344 n.bdata := DI;
345 n.tcnt := slv(unsigned(r.tcnt) - 1);
346 n.braddr := slv(unsigned(r.braddr) + 1);
347 if unsigned(r.tcnt) = 1 then
348 n.bloop := '0';
349 else
350 n.bloop := '1';
351 end if;
352 n.state := s_txwbdl;
353
354 when s_txwbdl => -- s_txwbdl: wblk send data lsb ------
355 icpdi := '0' & r.bdata(f_byte0);
356 iena := '1';
357 if RL_BUSY = '0' then
358 do_crc := '1';
359 n.state := s_txwbdh;
360 end if;
361
362 when s_txwbdh => -- s_txwbdh: wblk send data msb ------
363 icpdi := '0' & r.bdata(f_byte1);
364 iena := '1';
365 if RL_BUSY = '0' then
366 do_crc := '1';
367 if r.bloop = '1' then
368 n.state := s_txwbld;
369 else
370 n.state := s_txcrcl2;
371 end if;
372 end if;
373
374 when s_txcrcl2 => -- s_txcrcl2: send final crc lsb -----
375 icpdi := '0' & r.crc(f_byte0);
376 iena := '1';
377 if RL_BUSY = '0' then
378 n.state := s_txcrch2;
379 end if;
380
381 when s_txcrch2 => -- s_txcrch2: send final crc msb -----
382 icpdi := '0' & r.crc(f_byte1);
383 iena := '1';
384 if RL_BUSY = '0' then
385 if r.eoppend = '1' or unsigned(r.snum)=31 then
386 n.state := s_txeop;
387 else
388 n.state := s_txidle;
389 end if;
390 end if;
391
392 when others => null; -- <> --------------------------------
393 end case;
394
395 if do_crc = '1' then
396 n.crc := crc16_update(r.crc, icpdi(d_f_data));
397 end if;
398
399 N_TXREGS <= n;
400
401 TXBUSY <= itxbusy;
402
403 STAT_L.braddr <= r.braddr;
404 STAT_L.bre <= ibre;
405
406 RL_DI <= icpdi;
407 RL_ENA <= iena;
408
409 end process proc_txnext;
410
411 -- rx FSM ==================================================================
412
413 proc_rxnext: process (R_RXREGS, CNTL, RL_DO, RL_VAL)
414 variable r : rxregs_type := rxregs_init;
415 variable n : rxregs_type := rxregs_init;
416
417 variable irxbusy : slbit := '0';
418 variable ibwe : slbit := '0';
419 variable do_crc : slbit := '0';
420 variable ido : slv16 := (others=>'0');
421
422 begin
423
424 r := R_RXREGS;
425 n := R_RXREGS;
426
427 n.ack := '0';
428 n.ano := '0';
429
430 irxbusy := '1';
431 ibwe := '0';
432 do_crc := '0';
433 ido := r.data;
434
435 case r.state is
436 when s_rxidle => -- s_rxidle: wait --------------------
437 n.crc := (others=>'0');
438 n.err := '0';
439
440 if RL_VAL = '1' then
441 if RL_DO = c_rlink_dat_attn then -- attn seen ?
442 n.state := s_rxapl;
443 elsif RL_DO = c_rlink_dat_sop then
444 n.state := s_rxcmd;
445 end if;
446 else
447 irxbusy := '0'; -- signal rx not busy
448 end if;
449
450 when s_rxcmd => -- s_rxcmd: wait cmd ----------------
451 if RL_VAL = '1' then
452 if RL_DO = c_rlink_dat_eop then
453 n.state := s_rxidle;
454 else
455 n.bwaddr := (others=>'0');
456 do_crc := '1';
457 n.ccmd := RL_DO(n.ccmd'range);
458 case RL_DO(n.ccmd'range) is
459 when c_rlink_cmd_rreg => n.state := s_rxdl;
460 when c_rlink_cmd_rblk => n.state := s_rxcl;
461 when c_rlink_cmd_wreg => n.state := s_rxstat;
462 when c_rlink_cmd_wblk => n.state := s_rxdcl;
463 when c_rlink_cmd_labo => n.state := s_rxbabo;
464 when c_rlink_cmd_attn => n.state := s_rxdl;
465 when c_rlink_cmd_init => n.state := s_rxstat;
466 when others => null;
467 end case;
468 end if;
469 else
470 irxbusy := '0'; -- signal rx not busy
471 end if;
472
473 when s_rxcl => -- s_rxcl: wait cnt lsb --------------
474 if RL_VAL = '1' then
475 do_crc := '1';
476 n.tcnt(f_byte0) := RL_DO(d_f_data);
477 n.state := s_rxch;
478 end if;
479
480 when s_rxch => -- s_rxch: wait cnt msb --------------
481 if RL_VAL = '1' then
482 do_crc := '1';
483 n.tcnt(f_byte1) := RL_DO(d_f_data);
484 n.state := s_rxdl;
485 end if;
486
487 when s_rxbabo => -- s_rxbabo: wait babo ---------------
488 if RL_VAL = '1' then
489 do_crc := '1';
490 n.data(15 downto 0) := (others=>'0');
491 n.data(f_byte0) := RL_DO(d_f_data);
492 n.state := s_rxstat;
493 end if;
494
495 when s_rxdl => -- s_rxdl: wait data lsb -------------
496 if RL_VAL = '1' then
497 do_crc := '1';
498 n.data(f_byte0) := RL_DO(d_f_data);
499 n.state := s_rxdh;
500 end if;
501
502 when s_rxdh => -- s_rxdh: wait data msb -------------
503 if RL_VAL = '1' then
504 do_crc := '1';
505 n.data(f_byte1) := RL_DO(d_f_data);
506 n.tcnt := slv(unsigned(r.tcnt) - 1);
507 n.bwaddr := slv(unsigned(r.bwaddr) + 1);
508 if r.ccmd = c_rlink_cmd_rblk then
509 ido(f_byte1) := RL_DO(d_f_data);
510 ibwe := '1';
511 end if;
512 if r.ccmd /= c_rlink_cmd_rblk then
513 n.state := s_rxstat;
514 elsif unsigned(r.tcnt) = 1 then
515 n.state := s_rxdcl;
516 else
517 n.state := s_rxdl;
518 end if;
519 end if;
520
521 when s_rxdcl => -- s_rxdcl: wait dcnt lsb ------------
522 if RL_VAL = '1' then
523 do_crc := '1';
524 n.dcnt(f_byte0) := RL_DO(d_f_data);
525 n.state := s_rxdch;
526 end if;
527
528 when s_rxdch => -- s_rxdch: wait dcnt msb ------------
529 if RL_VAL = '1' then
530 do_crc := '1';
531 n.dcnt(f_byte1) := RL_DO(d_f_data);
532 n.state := s_rxstat;
533 end if;
534
535 when s_rxstat => -- s_rxstat: wait status -------------
536 if RL_VAL = '1' then
537 do_crc := '1';
538 n.stat := RL_DO(d_f_data);
539 n.apend := RL_DO(c_rlink_stat_rbf_attn); -- update attn status
540 n.state := s_rxcrcl;
541 end if;
542
543 when s_rxcrcl => -- s_rxcrcl: wait crc lsb ------------
544 if RL_VAL = '1' then
545 if r.crc(f_byte0) /= RL_DO(d_f_data) then
546 n.err := '1';
547 end if;
548 n.state := s_rxcrch;
549 end if;
550
551 when s_rxcrch => -- s_rxcrch: wait crc msb ------------
552 if RL_VAL = '1' then
553 if r.crc(f_byte1) /= RL_DO(d_f_data) then
554 n.err := '1';
555 end if;
556 n.ack := '1';
557 n.state := s_rxcmd;
558 end if;
559
560 when s_rxapl => -- s_rxapl: wait attn pat lsb --------
561 if RL_VAL = '1' then
562 do_crc := '1';
563 n.apat(f_byte0) := RL_DO(d_f_data);
564 n.state := s_rxaph;
565 end if;
566
567 when s_rxaph => -- s_rxaph: wait attn pat msb --------
568 if RL_VAL = '1' then
569 do_crc := '1';
570 n.apat(f_byte1) := RL_DO(d_f_data);
571 n.state := s_rxacl;
572 end if;
573
574 when s_rxacl => -- s_rxacl: wait attn crc lsb --------
575 if RL_VAL = '1' then
576 if r.crc(f_byte0) /= RL_DO(d_f_data) then
577 n.err := '1';
578 end if;
579 n.state := s_rxach;
580 end if;
581
582 when s_rxach => -- s_rxach: wait attn crc msb --------
583 if RL_VAL = '1' then
584 if r.crc(f_byte1) /= RL_DO(d_f_data) then
585 n.err := '1';
586 end if;
587 n.ano := '1';
588 n.state := s_rxidle;
589 end if;
590
591 when others => null; -- <> --------------------------------
592 end case;
593
594 if do_crc = '1' then
595 n.crc := crc16_update(r.crc, RL_DO(d_f_data));
596 end if;
597
598 N_RXREGS <= n;
599
600 RXBUSY <= irxbusy;
601
602 DO <= ido;
603 STAT_L.stat <= r.stat;
604 STAT_L.ack <= r.ack;
605 STAT_L.err <= r.err;
606 STAT_L.bwaddr <= r.bwaddr;
607 STAT_L.bwe <= ibwe;
608 STAT_L.dcnt <= r.dcnt;
609 STAT_L.apend <= r.apend;
610 STAT_L.ano <= r.ano;
611 STAT_L.apat <= r.apat;
612
613 RL_HOLD <= '0';
614
615 end process proc_rxnext;
616
617 STAT_L.busy <= RXBUSY or TXBUSY;
618 STAT <= STAT_L;
619
620end syn;
std_logic_vector( 4 downto 0) slv5
Definition: slvtypes.vhd:37
std_logic_vector( 2 downto 0) slv3
Definition: slvtypes.vhd:35
std_logic_vector( 8 downto 0) slv9
Definition: slvtypes.vhd:41
std_logic_vector( 15 downto 0) slv16
Definition: slvtypes.vhd:48
std_logic slbit
Definition: slvtypes.vhd:30
std_logic_vector( 7 downto 0) slv8
Definition: slvtypes.vhd:40
std_logic_vector slv
Definition: slvtypes.vhd:31