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 12

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

powered by: WebSVN 2.1.0

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