OpenCores
URL https://opencores.org/ocsvn/spacewire_light/spacewire_light/trunk

Subversion Repositories spacewire_light

[/] [spacewire_light/] [trunk/] [bench/] [vhdl/] [spwlink_tb.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jorisvr
--
2
-- Test Bench for Link interface.
3
--
4
-- Unfortunately rather incomplete.
5
-- The following items are verified:
6
--  * reset;
7
--  * link start, NULL exchange, FCT exchange;
8
--  * link autostart on first NULL;
9
--  * send/receive time codes, data characters, EOP/EEP;
10
--  * detection of timeout, disconnection, parity error, escape error.
11
--
12
 
13
library ieee;
14
use ieee.std_logic_1164.all, ieee.numeric_std.all;
15
use std.textio.all;
16
use work.spwpkg.all;
17
 
18
entity spwlink_tb is
19
 
20
    -- Tests should be done with several different combinations
21
    -- of values for the generics.
22
    generic (
23
 
24
        -- System clock frequency
25
        sys_clock_freq: real        := 20.0e6 ;
26
 
27
        -- Receiver sample clock frequency
28
        rx_clock_freq:  real        := 20.0e6 ;
29
 
30
        -- Transmitter clock frequency
31
        tx_clock_freq:  real        := 20.0e6 ;
32
 
33
        -- Input bit rate
34
        input_rate:     real        := 10.0e6 ;
35
 
36
        -- TX clock division factor (actual factor is one tx_clock_div+1)
37
        tx_clock_div:   integer     := 1 ;
38
 
39
        -- Receiver implementation
40
        rximpl: spw_implementation_type := impl_generic ;
41
 
42
        -- Bits per sysclk for fast receiver
43
        rxchunk:        integer     := 1 ;
44
 
45
        -- Transmitter implementation
46
        tximpl: spw_implementation_type := impl_generic ;
47
 
48
        -- Wait before starting test bench
49
        startwait:      time        := 0 sec
50
    );
51
 
52
end spwlink_tb;
53
 
54
architecture tb_arch of spwlink_tb is
55
 
56
    -- Bit periods for incoming / outgoing signal
57
    constant inbit_period:      time    := (1 sec) / input_rate ;
58
    constant outbit_period:     time    := (1 sec) * real(tx_clock_div + 1) / tx_clock_freq ;
59
    constant txclk_period:      time    := (1 sec) / tx_clock_freq ;
60
 
61
    -- clock generation
62
    signal sys_clock_enable: std_logic := '0';
63
    signal sysclk:           std_logic;
64
    signal rxclk:            std_logic;
65
    signal txclk:            std_logic;
66
 
67
    -- output monitoring
68
    type t_output_chars is array(natural range <>) of std_logic_vector(9 downto 0);
69
    signal output_collect:   std_logic;
70
    signal output_ptr:       integer;
71
    signal output_bits:      std_logic_vector(0 to 4095);
72
    signal output_nchars:    integer;
73
    signal output_chars:     t_output_chars(0 to 4095);
74
 
75
    -- input generation
76
    signal input_par:        std_logic;
77
    signal input_idle:       std_logic;
78
    signal input_pattern:    integer := 0;
79
 
80
    -- interconnect signals
81
    signal s_linki:     spw_link_in_type;
82
    signal s_linko:     spw_link_out_type;
83
    signal s_rxen:      std_logic;
84
    signal s_recvo:     spw_recv_out_type;
85
    signal s_xmiti:     spw_xmit_in_type;
86
    signal s_xmito:     spw_xmit_out_type;
87
    signal s_inact:     std_logic;
88
    signal s_inbvalid:  std_logic;
89
    signal s_inbits:    std_logic_vector(rxchunk-1 downto 0);
90
 
91
    -- interface signals
92
    signal rst:       std_logic := '1';
93
    signal autostart: std_logic;
94
    signal linkstart: std_logic;
95
    signal linkdis:   std_logic;
96
    signal divcnt:    std_logic_vector(7 downto 0) := (others => '0');
97
    signal tick_in:   std_logic;
98
    signal ctrl_in:   std_logic_vector(1 downto 0);
99
    signal time_in:   std_logic_vector(5 downto 0);
100
    signal rxroom:    std_logic_vector(5 downto 0);
101
    signal txwrite:   std_logic;
102
    signal txflag:    std_logic;
103
    signal txdata:    std_logic_vector(7 downto 0);
104
    signal txrdy:     std_logic;
105
    signal tick_out:  std_logic;
106
    signal ctrl_out:  std_logic_vector(1 downto 0);
107
    signal time_out:  std_logic_vector(5 downto 0);
108
    signal rxchar:    std_logic;
109
    signal rxflag:    std_logic;
110
    signal rxdata:    std_logic_vector(7 downto 0);
111
    signal started:   std_logic;
112
    signal connecting:std_logic;
113
    signal running:   std_logic;
114
    signal errdisc:   std_logic;
115
    signal errpar:    std_logic;
116
    signal erresc:    std_logic;
117
    signal errcred:   std_logic;
118
    signal spw_di:    std_logic;
119
    signal spw_si:    std_logic;
120
    signal spw_do:    std_logic;
121
    signal spw_so:    std_logic;
122
 
123
    -- misc
124
    signal errany:    std_logic;
125
 
126
    procedure print(i: integer) is
127
        variable v: LINE;
128
    begin
129
        write(v, i);
130
        writeline(output, v);
131
    end procedure;
132
 
133
    procedure print(x: std_logic_vector) is
134
        variable v: LINE;
135
    begin
136
        write(v, to_bitvector(x));
137
        writeline(output, v);
138
    end procedure;
139
 
140
    procedure prints(s: string) is
141
        variable v: LINE;
142
    begin
143
        write(v, s);
144
        writeline(output, v);
145
    end procedure;
146
 
147
    procedure print(lbl: string; x: integer) is
148
        variable v: LINE;
149
    begin
150
        write(v, lbl & " = ");
151
        write(v, x);
152
        writeline(output, v);
153
    end procedure;
154
 
155
    procedure print(lbl: string; x: real) is
156
        variable v: LINE;
157
    begin
158
        write(v, lbl & " = ");
159
        write(v, x);
160
        writeline(output, v);
161
    end procedure;
162
 
163
begin
164
 
165
    -- Instantiate components.
166
 
167
    spwlink_inst: spwlink
168
        generic map (
169
            reset_time =>      integer(sys_clock_freq * 0.0000064) )  -- 6.4 us
170
        port map (
171
            clk     => sysclk,
172
            rst     => rst,
173
            linki   => s_linki,
174
            linko   => s_linko,
175
            rxen    => s_rxen,
176
            recvo   => s_recvo,
177
            xmiti   => s_xmiti,
178
            xmito   => s_xmito );
179
 
180
    spwrecv_inst: spwrecv
181
        generic map (
182
            disconnect_time => integer(sys_clock_freq * 0.00000085),   -- 850 ns
183
            rxchunk => rxchunk )
184
        port map (
185
            clk     => sysclk,
186
            rxen    => s_rxen,
187
            recvo   => s_recvo,
188
            inact   => s_inact,
189
            inbvalid => s_inbvalid,
190
            inbits  => s_inbits );
191
 
192
    spwxmit_if: if tximpl = impl_generic generate
193
        spwxmit_inst: spwxmit
194
            port map (
195
                clk     => sysclk,
196
                rst     => rst,
197
                divcnt  => divcnt,
198
                xmiti   => s_xmiti,
199
                xmito   => s_xmito,
200
                spw_so  => spw_so,
201
                spw_do  => spw_do );
202
    end generate;
203
    spwxmit_fast_if: if tximpl = impl_fast generate
204
        spwxmit_fast_inst: spwxmit_fast
205
            port map (
206
                clk     => sysclk,
207
                txclk   => txclk,
208
                rst     => rst,
209
                divcnt  => divcnt,
210
                xmiti   => s_xmiti,
211
                xmito   => s_xmito,
212
                spw_so  => spw_so,
213
                spw_do  => spw_do );
214
    end generate;
215
 
216
    spwrecvfront_generic_if: if rximpl = impl_generic generate
217
        spwrecvfront_generic_inst: spwrecvfront_generic
218
            port map (
219
                clk     => sysclk,
220
                rxen    => s_rxen,
221
                inact   => s_inact,
222
                inbvalid => s_inbvalid,
223
                inbits  => s_inbits,
224
                spw_di  => spw_di,
225
                spw_si  => spw_si );
226
    end generate;
227
    spwrecvfront_fast_if: if rximpl = impl_fast generate
228
        spwrecvfront_fast_inst: spwrecvfront_fast
229
            generic map (
230
                rxchunk => rxchunk )
231
            port map (
232
                clk     => sysclk,
233
                rxclk   => rxclk,
234
                rxen    => s_rxen,
235
                inact   => s_inact,
236
                inbvalid => s_inbvalid,
237
                inbits  => s_inbits,
238
                spw_di  => spw_di,
239
                spw_si  => spw_si );
240
    end generate;
241
 
242
    s_linki <= ( autostart  => autostart,
243
                 linkstart  => linkstart,
244
                 linkdis    => linkdis,
245
                 rxroom     => rxroom,
246
                 tick_in    => tick_in,
247
                 ctrl_in    => ctrl_in,
248
                 time_in    => time_in,
249
                 txwrite    => txwrite,
250
                 txflag     => txflag,
251
                 txdata     => txdata );
252
    started     <= s_linko.started;
253
    connecting  <= s_linko.connecting;
254
    running     <= s_linko.running;
255
    errdisc     <= s_linko.errdisc;
256
    errpar      <= s_linko.errpar;
257
    erresc      <= s_linko.erresc;
258
    errcred     <= s_linko.errcred;
259
    txrdy       <= s_linko.txack;
260
    tick_out    <= s_linko.tick_out;
261
    ctrl_out    <= s_linko.ctrl_out;
262
    time_out    <= s_linko.time_out;
263
    rxchar      <= s_linko.rxchar;
264
    rxflag      <= s_linko.rxflag;
265
    rxdata      <= s_linko.rxdata;
266
 
267
    -- Logic OR of all error signals.
268
    errany <= errdisc or errpar or erresc or errcred;
269
 
270
    -- Generate system clock.
271
    process is
272
    begin
273
        if sys_clock_enable /= '1' then
274
            wait until sys_clock_enable = '1';
275
        end if;
276
        sysclk <= '1';
277
        wait for (0.5 sec) / sys_clock_freq;
278
        sysclk <= '0';
279
        wait for (0.5 sec) / sys_clock_freq;
280
    end process;
281
 
282
    -- Generate rx sample clock.
283
    process is
284
    begin
285
        if sys_clock_enable /= '1' then
286
            wait until sys_clock_enable = '1';
287
        end if;
288
        rxclk <= '1';
289
        wait for (0.5 sec) / rx_clock_freq;
290
        rxclk <= '0';
291
        wait for (0.5 sec) / rx_clock_freq;
292
    end process;
293
 
294
    -- Generate tx clock.
295
    process is
296
    begin
297
        if sys_clock_enable /= '1' then
298
            wait until sys_clock_enable = '1';
299
        end if;
300
        txclk <= '1';
301
        wait for (0.5 sec) / tx_clock_freq;
302
        txclk <= '0';
303
        wait for (0.5 sec) / tx_clock_freq;
304
    end process;
305
 
306
    -- Collect output bits on SPW_DO and SPW_SO.
307
    process is
308
        variable t_last: time;
309
        variable output_last_do: std_logic;
310
        variable output_last_so: std_logic;
311
    begin
312
        if output_collect = '1' then
313
            -- wait for next bit
314
            if output_ptr <= output_bits'high then
315
                output_bits(output_ptr) <= spw_do;
316
                output_ptr <= output_ptr + 1;
317
            end if;
318
            output_last_do := spw_do;
319
            output_last_so := spw_so;
320
            t_last := now;
321
            wait until (output_collect = '0') or (output_last_do /= spw_do) or (output_last_so /= spw_so);
322
            if output_collect = '1' and output_ptr > 1 then
323
                assert now > t_last + outbit_period - 1 ns
324
                    report "output bit period too short";
325
                assert now < t_last + outbit_period + 1 ns
326
                    report "output bit period too long";
327
            end if;
328
        else
329
            -- reset
330
            output_ptr <= 0;
331
            output_last_do := '0';
332
            output_last_so := '0';
333
            wait until output_collect = '1';
334
        end if;
335
    end process;
336
 
337
    -- Collect received data on rxdata and tick_out.
338
    process is
339
    begin
340
        wait until ((output_collect = '1') and rising_edge(sysclk)) or
341
                   ((output_collect = '0') and (output_nchars /= 0));
342
        if output_collect = '0' then
343
            output_nchars <= 0;
344
        elsif rising_edge(sysclk) and (output_nchars <= output_chars'high) then
345
            assert (rxchar = '0') or (tick_out = '0');
346
            if tick_out = '1' then
347
                output_chars(output_nchars) <= "10" & ctrl_out & time_out;
348
                output_nchars <= output_nchars + 1;
349
            elsif rxchar = '1' then
350
                output_chars(output_nchars) <= "0" & (rxflag) & rxdata;
351
                output_nchars <= output_nchars + 1;
352
            end if;
353
        end if;
354
    end process;
355
 
356
    -- Generate input data.
357
    process is
358
        procedure input_reset is
359
        begin
360
            spw_di <= '0';
361
            spw_si <= '0';
362
            input_par <= '0';
363
        end procedure;
364
        procedure genbit(b: std_logic) is
365
        begin
366
            spw_si <= not (spw_si xor spw_di xor b);
367
            spw_di <= b;
368
            wait for inbit_period;
369
        end procedure;
370
        procedure genfct is
371
        begin
372
            genbit(input_par);
373
            genbit('1');
374
            genbit('0');
375
            input_par <= '0';
376
            genbit('0');
377
        end procedure;
378
        procedure genesc is
379
        begin
380
            genbit(input_par);
381
            genbit('1');
382
            genbit('1');
383
            input_par <= '0';
384
            genbit('1');
385
        end procedure;
386
        procedure geneop(e: std_logic) is
387
        begin
388
            genbit(input_par);
389
            genbit('1');
390
            genbit(e);
391
            input_par <= '1';
392
            genbit(not e);
393
        end procedure;
394
        procedure gendat(dat: std_logic_vector(7 downto 0)) is
395
        begin
396
            genbit(not input_par);
397
            genbit('0');
398
            genbit(dat(0)); genbit(dat(1)); genbit(dat(2)); genbit(dat(3));
399
            genbit(dat(4)); genbit(dat(5)); genbit(dat(6));
400
            input_par <= dat(0) xor dat(1) xor dat(2) xor dat(3) xor
401
                         dat(4) xor dat(5) xor dat(6) xor dat(7);
402
            genbit(dat(7));
403
        end procedure;
404
    begin
405
        input_idle <= '1';
406
        input_reset;
407
        wait until input_pattern /= 0;
408
        input_idle <= '0';
409
        while input_pattern /= 0 loop
410
            if input_pattern = 1 then
411
                -- NULL tokens
412
                genesc; genfct;
413
            elsif input_pattern = 2 then
414
                -- FCT tokens
415
                genfct;
416
            elsif input_pattern = 3 then
417
                -- invalid bit pattern
418
                genbit('0');
419
                genbit('1');
420
            elsif input_pattern = 4 then
421
                -- EOP token
422
                geneop('0');
423
            elsif input_pattern = 5 then
424
                -- FCT, TIME, 8 chars, NULLs
425
                genfct;
426
                genesc; gendat("00111000");
427
                gendat("01010101");
428
                gendat("10101010");
429
                gendat("01010101");
430
                gendat("10101010");
431
                gendat("01010101");
432
                gendat("10101010");
433
                gendat("01010101");
434
                gendat("10101010");
435
                while input_pattern = 5 loop
436
                    genesc; genfct;
437
                end loop;
438
            elsif input_pattern = 6 then
439
                -- ESC tokens
440
                genesc;
441
            elsif input_pattern = 7 then
442
                -- FCT, NULL, NULL, EOP, EEP, NULLs
443
                genfct;
444
                genesc; genfct;
445
                genesc; genfct;
446
                geneop('0');
447
                geneop('1');
448
                while input_pattern = 7 loop
449
                    genesc; genfct;
450
                end loop;
451
            elsif input_pattern = 8 then
452
                -- FCT, NULL, NULL, NULL, NULL, NULL, char, parity error
453
                genfct;
454
                genesc; genfct;
455
                genesc; genfct;
456
                genesc; genfct;
457
                genesc; genfct;
458
                genesc; genfct;
459
                gendat("01010101");
460
                genbit(not input_par);
461
                genbit('0');
462
                genbit('1'); genbit('0'); genbit('1'); genbit('0');
463
                genbit('1'); genbit('0'); genbit('1');
464
                input_par <= '1'; -- wrong parity !!
465
                genbit('0');
466
                while input_pattern = 8 loop
467
                    genesc; genfct;
468
                end loop;
469
            else
470
                assert false;
471
            end if;
472
        end loop;
473
    end process;
474
 
475
    -- Main process.
476
    process is
477
 
478
        -- Skip NULL tokens and return position of first non-NULL.
479
        function skip_null(data: in std_logic_vector; start: in integer; len: in integer) return integer is
480
            variable i: integer;
481
        begin
482
            i := start;
483
            if (i + 7 < len) and (data((i+1) to (i+7)) = "1110100") then
484
                i := i + 8;
485
            end if;
486
            while (i + 7 < len) and (data(i to (i+7)) = "01110100") loop
487
                i := i + 8;
488
            end loop;
489
            return i;
490
        end function;
491
 
492
        function check_parity(data: in std_logic_vector; start: in integer; len: in integer) return boolean is
493
            variable i: integer;
494
            variable p: std_logic;
495
        begin
496
            i := start;
497
            p := data(start);
498
            while i + 3 < len loop
499
                if data(i+1) = '1' then
500
                    if data(0) /= p then return false; end if;
501
                    p := data(2) xor data(3);
502
                    i := i + 4;
503
                else
504
                    if i + 9 < len then return true; end if;
505
                    if data(0) /= not p then return false; end if;
506
                    p := not (data(2) xor data(3) xor data(4) xor data(5) xor
507
                              data(6) xor data(7) xor data(8) xor data(9));
508
                    i := i + 10;
509
                end if;
510
            end loop;
511
            return true;
512
        end function;
513
 
514
        variable i: integer;
515
 
516
    begin
517
 
518
        -- Wait for start of test.
519
        wait for startwait;
520
 
521
        -- Initialize.
522
        rst <= '1';
523
        input_pattern <= 0;
524
        sys_clock_enable <= '1';
525
        output_collect <= '0';
526
 
527
        -- Say hello
528
        report "Starting spwlink test bench";
529
        print("  sys_clock_freq", sys_clock_freq);
530
        print("  rx_clock_freq ", rx_clock_freq);
531
        print("  tx_clock_freq ", tx_clock_freq);
532
        print("  input_rate    ", input_rate);
533
        print("  tx_clock_div  ", tx_clock_div);
534
        case rximpl is
535
            when impl_generic => prints("  rximpl         = impl_generic");
536
            when impl_fast =>    prints("  rximpl         = impl_fast");
537
        end case;
538
        print("  rxchunk       ", rxchunk);
539
        case tximpl is
540
            when impl_generic => prints("  tximpl         = impl_generic");
541
            when impl_fast =>    prints("  tximpl         = impl_fast");
542
        end case;
543
 
544
        -- Test 1: Reset.
545
        autostart <= '0'; linkstart <= '0'; linkdis <= '0';
546
        divcnt <= std_logic_vector(to_unsigned(tx_clock_div, divcnt'length));
547
        tick_in <= '0'; ctrl_in <= "00"; time_in <= "000000"; rxroom <= "000000";
548
        txwrite <= '0'; txflag <= '0'; txdata <= "00000000";
549
        wait until rising_edge(sysclk);
550
        wait until rising_edge(sysclk);
551
        wait for 1 ns;
552
        rst <= '0';
553
        assert (txrdy = '0')        report " 1. reset (txrdy = 0)";
554
        assert (tick_out = '0')     report " 1. reset (tick_out = 0)";
555
        assert (rxchar = '0')       report " 1. reset (rxchar = 0)";
556
        assert (started = '0')      report " 1. reset (started = 0)";
557
        assert (connecting = '0')   report " 1. reset (connecting = 0)";
558
        assert (running = '0')      report " 1. reset (running = 0)";
559
        assert (errdisc = '0')      report " 1. reset (errdisc = 0)";
560
        assert (errpar = '0')       report " 1. reset (errpar = 0)";
561
        assert (erresc = '0')       report " 1. reset (erresc = 0)";
562
        assert (errcred = '0')      report " 1. reset (errcred = 0)";
563
        assert (spw_do = '0')       report " 1. reset (spw_do = 0)";
564
        assert (spw_so = '0')       report " 1. reset (spw_so = 0)";
565
 
566
        -- Test 2: Remain idle after one clock cycle.
567
        wait until rising_edge(sysclk);
568
        wait until falling_edge(sysclk);
569
        assert (started = '0') and (running = '0')
570
            report " 2. init (state)";
571
        assert (spw_do =  '0') and (spw_so = '0')
572
            report " 2. init (SPW idle)";
573
 
574
        -- Test 3: Move to Ready state.
575
        wait on started, running, spw_do, spw_so for 50 us;
576
        assert (started = '0') and (running = '0')
577
            report " 3. ready (state)";
578
        assert (spw_do = '0') and (spw_so = '0')
579
            report " 3. ready (SPW idle)";
580
 
581
        -- Test 4: Start link; wait for NULL patterns.
582
        linkstart <= '1';
583
        rxroom <= "001111";
584
        wait on started, connecting, running, spw_do, spw_so for 1 us;
585
        assert (started = '1') and (running = '0')
586
            report " 4. nullgen (started)";
587
        if spw_so = '0' then
588
            wait on started, connecting, running, spw_do, spw_so for 1.2 us;
589
        end if;
590
        assert (started = '1') and (connecting = '0') and (running = '0') and
591
               (spw_do = '0') and (spw_so = '1')
592
            report " 4. nullgen (SPW strobe)";
593
        output_collect <= '1';
594
        wait on started, connecting, running for (7.1 * outbit_period);
595
        assert (started = '1') and (running = '0')
596
            report " 4. nullgen (state 2)";
597
        assert (output_ptr = 8) and (output_bits(0 to 7) = "01110100")
598
            report " 4. nullgen (NULL 1)";
599
        -- got the first NULL, wait for the second one ...
600
        wait on started, connecting, running for (8.0 * outbit_period);
601
        assert (started = '1') and (running = '0')
602
            report " 4. nullgen (state 3)";
603
        assert (output_ptr = 16) and (output_bits(8 to 15) = "01110100")
604
            report " 4. nullgen (NULL 2)";
605
        output_collect <= '0';
606
 
607
        -- Test 5: Timeout in Started state.
608
        wait on started, connecting, running, errany for 9.5 us - (15.0 * outbit_period);
609
        assert (started = '1') and (running = '0') and (errany = '0')
610
            report " 5. started_timeout (wait)";
611
        wait on started, connecting, running, errany for 4 us;
612
        assert (started = '0') and (connecting = '0') and (running = '0') and (errany = '0')
613
            report " 5. started_timeout (trigger)";
614
        wait for (3.1 * outbit_period + 20 * txclk_period);
615
        assert (spw_do = '0') and (spw_so = '0')
616
            report " 5. started_timeout (SPW to zero)";
617
 
618
        -- Test 6: Start link; simulate NULL pattern; wait for FCT pattern.
619
        wait on started, connecting, running, spw_so for 18 us - (3.1 * outbit_period + 20 * txclk_period);
620
        assert (started = '0') and (connecting = '0') and (running = '0') and (spw_so = '0')
621
            report " 6. fctgen (SPW idle)";
622
        wait on started, connecting, running, spw_so for 2 us;
623
        assert (started = '1') and (connecting = '0') and (running = '0')
624
            report " 6. fctgen (started)";
625
        if spw_so = '0' then
626
            wait on started, connecting, running, spw_do, spw_so for 1.2 us;
627
        end if;
628
        assert (spw_do = '0') and (spw_so = '1')
629
            report " 6. fctgen (SPW strobe)";
630
        output_collect <= '1';
631
        input_pattern <= 1;
632
        wait on started, connecting, running for 8 us;
633
        assert (started = '0') and (connecting = '1') and (running = '0')
634
            report " 6. fctgen (detect NULL)";
635
        wait for (1.1 sec) / sys_clock_freq;
636
        wait on started, connecting, running, errany for 12 us;
637
        assert (started = '0') and (connecting = '1') and (running = '0') and (errany = '0')
638
            report " 6. fctgen (connecting failed early)";
639
        assert (output_ptr > 7) and (output_bits(0 to 7) = "01110100")
640
            report " 6. fctgen (gen NULL)";
641
        i := skip_null(output_bits, 0, output_ptr);
642
        assert (i > 0) and (i + 11 < output_ptr) and (output_bits(i to (i+11)) = "010001110100")
643
            report " 6. fctgen (gen FCT NULL)";
644
        output_collect <= '0';
645
 
646
        -- Test 7: Timeout in Connecting state.
647
        wait on started, connecting, running, errany for 4 us;
648
        assert (started = '0') and (connecting = '0') and (running = '0') and (errany = '0')
649
            report " 7. connecting_timeout";
650
        input_pattern <= 0;
651
        wait until rising_edge(sysclk);
652
 
653
        -- Test 8: Autostart link; simulate NULL and FCT; move to Run state; disconnect.
654
        linkstart <= '0';
655
        autostart <= '1';
656
        rxroom <= "010000";
657
        wait on started, connecting, running, errany for 50 us;
658
        assert (started = '0') and (connecting = '0') and (running = '0') and (errany = '0')
659
            report " 8. autostart (wait)";
660
        output_collect <= '1';
661
        input_pattern <= 1;
662
        wait on started, connecting, running for 200 ns + 20 * inbit_period;
663
        assert (started = '1') and (connecting = '0') and (running = '0')
664
            report " 8. autostart (Started)";
665
        input_pattern <= 2;
666
        wait on started, connecting, running for 1 us;
667
        assert (started = '0') and (connecting = '1') and (running = '0')
668
            report " 8. autostart (Connecting)";
669
        wait on started, connecting, running, errany for 200 ns + 24 * inbit_period;
670
        assert (started = '0') and (connecting = '0') and (running = '1') and (errany = '0')
671
            report " 8. autostart (Run)";
672
        input_pattern <= 1;
673
        txwrite <= '1';
674
        if txrdy = '0' then
675
            wait on running, errany, txrdy for (20 * outbit_period);
676
        end if;
677
        assert (running = '1') and (errany = '0') and (txrdy = '1')
678
            report " 8. running (txrdy = 1)";
679
        txwrite <= '0';
680
        wait on running, errany for 50 us;
681
        assert (running = '1') and (errany = '0')
682
            report " 8. running stable";
683
        assert output_bits(1 to 24) = "011101000100010001110100"
684
            report " 8. NULL FCT FCT NULL";
685
        output_collect <= '0';
686
        linkdis <= '1';
687
        wait on started, running, errany for (2.1 sec) / sys_clock_freq;
688
        assert (started = '0') and (running = '0') and (errany = '0')
689
            report " 8. link disable";
690
        autostart <= '0';
691
        linkdis <= '0';
692
        input_pattern <= 0;
693
        wait until rising_edge(sysclk);
694
 
695
        -- Test 9: Start link until Run state; disconnect.
696
        linkstart <= '1';
697
        rxroom <= "001000";
698
        input_pattern <= 1;
699
        wait on started, connecting, running for 20 us;
700
        assert (started = '1') and (connecting = '0') and (running = '0')
701
            report " 9. running_disconnect (Started)";
702
        linkstart <= '0';
703
        wait until rising_edge(sysclk);
704
        input_pattern <= 2;
705
        wait on started, connecting, running, errany for 20 * inbit_period;
706
        assert (started = '0') and (connecting = '1') and (running = '0') and (errany = '0')
707
            report " 9. running_disconnect (Connecting)";
708
        wait on started, connecting, running, errany for 150 ns + 24 * inbit_period;
709
        assert (started = '0') and (connecting = '0') and (running = '1') and (errany = '0')
710
            report " 9. running_disconnect (Run)";
711
        input_pattern <= 0;
712
        wait until input_idle = '1';
713
        wait on started, connecting, running, errany for 1500 ns;
714
        assert errdisc = '1'
715
            report " 9. running_disconnect (errdisc = 1)";
716
        if running = '1' then
717
            wait on started, connecting, running for (1.1 sec) / sys_clock_freq;
718
        end if;
719
        assert (started = '0') and (connecting = '0') and (running = '0')
720
            report " 9. running_disconnect (running = 0)";
721
        wait until rising_edge(sysclk);
722
        assert (started = '0') and (connecting = '0') and (running = '0') and (errany = '0')
723
            report " 9. running_disconnect (reset)";
724
        wait until rising_edge(sysclk);
725
 
726
        -- Test 10: Junk signal before starting link.
727
        autostart <= '1';
728
        input_pattern <= 3;
729
        wait on started, errany for 6 us;
730
        assert (started = '0') and (errany = '0')
731
            report "10. junk signal (ignore noise)";
732
        input_pattern <= 2;
733
        wait on started, errany for 4 us;
734
        assert (started = '0') and (errany = '0')
735
            report "10. junk signal (ignore FCT)";
736
        input_pattern <= 0;
737
        wait until input_idle = '1';
738
        input_pattern <= 1; -- send NULL
739
        wait until input_idle = '0';
740
        input_pattern <= 3; -- send invalid pattern; spw should now reset
741
        wait on started, errany for 8 us;
742
        assert (started = '0') and (errany = '0')
743
            report "10. junk signal (hidden reset)";
744
        input_pattern <= 1; -- send NULL
745
        wait on started, errany for 10 us;
746
        assert (started = '0') and (errany = '0')
747
            report "10. junk signal (waiting)";
748
        wait on started, errany for 10 us;
749
        assert (started = '1') and (errany = '0')
750
            report "10. junk signal (Started)";
751
        autostart <= '0';
752
        rst <= '1';
753
        wait until rising_edge(sysclk);
754
        rst <= '0';
755
        wait until rising_edge(sysclk);
756
        assert (started = '0') and (errany = '0')
757
            report "10. junk signal (rst)";
758
        wait until rising_edge(sysclk);
759
 
760
        -- Test 11: Incoming EOP before first FCT.
761
        linkstart <= '1';
762
        rxroom <= "001000";
763
        input_pattern <= 1;
764
        wait on connecting, running, errany for 21 us;
765
        assert (connecting = '1') and (errany = '0')
766
            report "11. unexpected EOP (Connecting)";
767
        input_pattern <= 4;
768
        linkstart <= '0';
769
        wait on connecting, running, errany for 200 ns + 24 * inbit_period;
770
        assert (connecting = '0') and (running = '0') and (errany = '0')
771
            report "11. unexpected EOP (reset on EOP)";
772
        input_pattern <= 0;
773
        wait for (10 * outbit_period);
774
 
775
        -- Test 12: Send and receive characters, time codes, abort on double ESC.
776
        wait until falling_edge(sysclk);
777
        linkstart <= '1';
778
        wait on started, errany for 21 us;
779
        assert (started = '1') and (errany = '0')
780
            report "12. characters (Started)";
781
        rxroom <= "001000";
782
        input_pattern <= 1;
783
        output_collect <= '1';
784
        tick_in <= '1';
785
        wait on connecting, running, errany for 21 us;
786
        assert (connecting = '1') and (errany = '0')
787
            report "12. characters (Connecting)";
788
        wait until output_ptr > 9 for 2 us;
789
        input_pattern <= 5; -- FCT, TIME, 8 chars, NULLs
790
        time_in <= "000111";
791
        txwrite <= '1';
792
        txflag <= '0';
793
        txdata <= "01101100";
794
        wait on connecting, running, errany for 200 ns + (24 * inbit_period);
795
        assert (running = '1') and (errany = '0')
796
            report "12. characters (Run)";
797
        wait until rising_edge(sysclk);
798
        assert (running = '1') and (errany = '0')
799
            report "12. characters (running = 1)";
800
        tick_in <= '0';
801
        wait for 4 * outbit_period;   -- wait until first FCT sent
802
        rxroom <= "000111";
803
        wait until txrdy = '1' for 200 ns + (20 * outbit_period);
804
        assert (running = '1') and (txrdy = '1')
805
            report "12. characters (txrdy = 1)";
806
        wait on running, errany for 50 us + (80 * outbit_period);
807
        assert (running = '1') and (errany = '0')
808
            report "12. characters (stable)";
809
        input_pattern <= 6; -- just ESC tokens
810
        wait on running, errany for 200 ns + (32 * inbit_period);
811
        assert erresc = '1'
812
            report "12. characters (erresc = 1)";
813
        wait until rising_edge(sysclk);
814
        wait for 1 ns;
815
        assert (started = '0') and (connecting = '0') and (running = '0')
816
            report "12. characters (reset)";
817
        assert (output_ptr > 8) and (output_bits(1 to 8) = "01110100")
818
            report "12. characters (gen NULL 1)";
819
        i := skip_null(output_bits, 1, output_ptr);
820
        assert (i > 0) and (output_bits(i to (i+3)) = "0100")
821
            report "12. characters (gen FCT)";
822
        i := skip_null(output_bits, i + 4, output_ptr);
823
        assert (i + 13 < output_ptr) and (output_bits(i to (i+13)) = "01111011100000")
824
            report "12. characters (gen TimeCode)";
825
        i := i + 14;
826
        assert (i + 79 < output_ptr) and (output_bits(i to (i+79)) = "00001101101000110110100011011010001101101000110110100011011010001101101000110110")
827
            report "12. characters (gen Data)";
828
        i := i + 80;
829
        assert (i + 7 < output_ptr) and (output_bits(i to (i+7)) = "01110100")
830
            report "12. characters (gen NULL 2)";
831
        assert (output_nchars > 0) and (output_chars(0) = "1000111000")
832
            report "12. characters (got TimeCode)";
833
        assert (output_nchars > 1) and (output_chars(1) = "0001010101")
834
            report "12. characters (got byte 1)";
835
        assert (output_nchars > 2) and (output_chars(2) = "0010101010")
836
            report "12. characters (got byte 2)";
837
        assert (output_nchars > 3) and (output_chars(3) = "0001010101")
838
            report "12. characters (got byte 3)";
839
        assert (output_nchars > 4) and (output_chars(4) = "0010101010")
840
            report "12. characters (got byte 4)";
841
        assert check_parity(output_bits, 1, output_ptr)
842
            report "12. parity of output bits";
843
        output_collect <= '0';
844
        input_pattern <= 0;
845
        txwrite <= '0';
846
        linkstart <= '0';
847
        wait for (20 * outbit_period);
848
 
849
        -- Test 13: Send and receive EOP, EEP, abort on credit error.
850
        linkstart <= '1';
851
        rxroom <= "001000";
852
        input_pattern <= 1;
853
        output_collect <= '1';
854
        wait on connecting, running, errany for 21 us;
855
        assert (connecting = '1') and (errany = '0')
856
            report "13. eop, eep (Connecting)";
857
        wait until output_ptr > 9 for 2 us;
858
        input_pattern <= 7; -- FCT, NULL, NULL, EOP, EEP, NULLs
859
        wait for (1.1 sec) / sys_clock_freq;
860
        wait on connecting, running, errany for 12 us;
861
        assert (running = '1') and (errany = '0')
862
            report "13. eop, eep (Run)";
863
        wait for 1 ns;
864
        txwrite <= '1';
865
        txflag <= '1';
866
        txdata <= "01101100";
867
        wait until rising_edge(sysclk) and txrdy = '1' for 1 us + (14 * outbit_period);
868
        assert (txrdy = '1') and (running = '1') and (errany = '0')
869
            report "13. eop, eep (txrdy 1)";
870
        rxroom <= "000111" after 1 ns;
871
        txdata <= "00000001" after 1 ns;
872
        wait until rising_edge(sysclk) and txrdy = '1' for 1 us + (14 * outbit_period);
873
        assert (txrdy = '1') and (running = '1') and (errany = '0')
874
            report "13. eop, eep (txrdy 2)";
875
        txdata <= "00000000" after 1 ns;
876
        wait until rising_edge(sysclk) and txrdy = '1' for (14 * outbit_period);
877
        assert (txrdy = '1') and (running = '1') and (errany = '0')
878
            report "13. eop, eep (txrdy 3)";
879
        txdata <= "11111111" after 1 ns;
880
        wait until rising_edge(sysclk) and txrdy = '1' for (14 * outbit_period);
881
        assert (txrdy = '1') and (running = '1') and (errany = '0')
882
            report "13. eop, eep (txrdy 4)";
883
        txdata <= "11111110" after 1 ns;
884
        wait until rising_edge(sysclk) and txrdy = '1' for (14 * outbit_period);
885
        assert (txrdy = '1') and (running = '1') and (errany = '0')
886
            report "13. eop, eep (txrdy 5)";
887
        txdata <= "01010101" after 1 ns;
888
        wait until rising_edge(sysclk) and txrdy = '1' for (14 * outbit_period);
889
        assert (txrdy = '1') and (running = '1') and (errany = '0')
890
            report "13. eop, eep (txrdy 6)";
891
        txdata <= "10101010" after 1 ns;
892
        wait until rising_edge(sysclk) and txrdy = '1' for (14 * outbit_period);
893
        assert (txrdy = '1') and (running = '1') and (errany = '0')
894
            report "13. eop, eep (txrdy 7)";
895
        txdata <= "01010101" after 1 ns;
896
        wait until rising_edge(sysclk) and txrdy = '1' for (14 * outbit_period);
897
        assert (txrdy = '1') and (running = '1') and (errany = '0')
898
            report "13. eop, eep (txrdy 8)";
899
        txdata <= "10101010" after 1 ns;
900
        wait until rising_edge(sysclk) and (txrdy = '1') for (14 * outbit_period);
901
        assert (txrdy = '0') and (running = '1') and (errany = '0')
902
            report "13. eop, eep (txrdy 9)";
903
        txwrite <= '0';
904
        txflag <= '0';
905
        wait on running, errany for (10 * outbit_period);
906
        assert (running = '1') and (errany = '0')
907
            report "13. eop, eep (flush out)";
908
        input_pattern <= 2; -- FCT tokens
909
        wait on running, errany for (80 * inbit_period);
910
        assert errcred = '1'
911
            report "13. eop, eep (errcred = 1)";
912
        wait until running = '0';
913
        assert (output_ptr > 8) and (output_bits(1 to 8) = "01110100")
914
            report "13. eop, eep (gen NULL 1)";
915
        i := skip_null(output_bits, 1, output_ptr);
916
        assert (i > 0) and (output_bits(i to (i+3)) = "0100")
917
            report "13. eop, eep (gen FCT)";
918
        i := i + 4;
919
        for j in 0 to 3 loop
920
            i := skip_null(output_bits, i, output_ptr);
921
            assert (i + 3 < output_ptr) and (output_bits(i+1 to (i+3)) = "101")
922
                report "13. eop, eep (eop)";
923
            i := skip_null(output_bits, i + 4, output_ptr);
924
            assert (i + 3 < output_ptr) and (output_bits(i+1 to (i+3)) = "110")
925
                report "13. eop, eep (eep)";
926
            i := i + 4;
927
        end loop;
928
        assert (i + 8 < output_ptr) and (output_bits(i to (i+8)) = "111101000")
929
            report "13. eop, eep (gen NULL 2)";
930
        assert check_parity(output_bits, 1, output_ptr)
931
            report "12. parity of output bits";
932
        assert (output_nchars > 0) and (output_chars(0) = "0100000000")
933
            report "13. eop, eep (got EOP)";
934
        assert (output_nchars = 2) and (output_chars(1) = "0100000001")
935
            report "13. eop, eep (got EEP)";
936
        output_collect <= '0';
937
        input_pattern <= 0;
938
        linkstart <= '0';
939
        wait until rising_edge(sysclk);
940
 
941
        -- Test 14: Abort on parity error.
942
        wait for 10 us;
943
        assert spw_do = '0' and spw_so = '0'
944
            report "14. output still babbling";
945
        linkstart <= '1';
946
        rxroom <= "001000";
947
        input_pattern <= 1;
948
        output_collect <= '1';
949
        wait for 1 ns; -- ghdl is totally fucked up
950
        wait on connecting, running, errany for 21 us;
951
        assert (connecting = '1') and (errany = '0')
952
            report "14. partity (Connecting)";
953
        input_pattern <= 8; -- FCT, NULL, NULL, NULL, NULL, NULL, char, error
954
        wait for (1.1 sec) / sys_clock_freq;
955
        wait on running, errany for 12 us;
956
        assert (running = '1') and (errany = '0')
957
            report "14. parity (Run)";
958
        wait on running, errany for 150 ns + (84 * inbit_period);
959
        assert errpar = '1'
960
            report "14. parity (errpar = 1)";
961
        wait until running = '0';
962
        assert (output_nchars = 1) and (output_chars(0) = "0001010101")
963
            report "14. parity (received char)";
964
        output_collect <= '0';
965
        input_pattern <= 0;
966
        linkstart <= '0';
967
        wait until rising_edge(sysclk);
968
 
969
        -- Stop simulation
970
        input_pattern <= 0;
971
        wait for 100 us;
972
        sys_clock_enable <= '0';
973
        report "Done.";
974
        wait;
975
 
976
    end process;
977
 
978
end tb_arch;

powered by: WebSVN 2.1.0

© copyright 1999-2019 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.