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

Subversion Repositories w11

[/] [w11/] [tags/] [w11a_V0.6/] [rtl/] [sys_gen/] [tst_serloop/] [tb/] [tb_tst_serloop.vhd] - Blame information for rev 24

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 wfjm
-- $Id: tb_tst_serloop.vhd 476 2013-01-26 22:23:53Z mueller $
2 16 wfjm
--
3
-- Copyright 2011- by Walter F.J. Mueller <W.F.J.Mueller@gsi.de>
4
--
5
-- This program is free software; you may redistribute and/or modify it under
6
-- the terms of the GNU General Public License as published by the Free
7
-- Software Foundation, either version 2, or at your option any later version.
8
--
9
-- This program is distributed in the hope that it will be useful, but
10
-- WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
11
-- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
-- for complete details.
13
--
14
------------------------------------------------------------------------------
15
-- Module Name:    tb_tst_serloop - sim
16
-- Description:    Generic test bench for sys_tst_serloop_xx
17
--
18 17 wfjm
-- Dependencies:   vlib/simlib/simclkcnt
19
--                 vlib/serport/serport_uart_rxtx
20 16 wfjm
--                 vlib/serport/serport_xontx
21
--
22
-- To test:        sys_tst_serloop_xx
23
--
24
-- Target Devices: generic
25
--
26
-- Revision History: 
27
-- Date         Rev Version  Comment
28 17 wfjm
-- 2011-12-23   444   1.1    use new simclkcnt
29 16 wfjm
-- 2011-11-13   425   1.0    Initial version
30
-- 2011-11-06   420   0.5    First draft
31
------------------------------------------------------------------------------
32
 
33
library ieee;
34
use ieee.std_logic_1164.all;
35
use ieee.numeric_std.all;
36
use ieee.std_logic_textio.all;
37
use std.textio.all;
38
 
39
use work.slvtypes.all;
40
use work.simlib.all;
41 19 wfjm
use work.serportlib.all;
42 16 wfjm
 
43
entity tb_tst_serloop is
44
  port (
45
    CLKS : in slbit;                    -- clock for serport
46
    CLKH : in slbit;                    -- clock for humanio
47
    CLK_STOP : out slbit;               -- clock stop
48
    P0_RXD : out slbit;                 -- port 0 receive data (board view)
49
    P0_TXD : in slbit;                  -- port 0 transmit data (board view)
50
    P0_RTS_N : in slbit;                -- port 0 rts_n
51
    P0_CTS_N : out slbit;               -- port 0 cts_n
52
    P1_RXD : out slbit;                 -- port 1 receive data (board view)
53
    P1_TXD : in slbit;                  -- port 1 transmit data (board view)
54
    P1_RTS_N : in slbit;                -- port 1 rts_n
55
    P1_CTS_N : out slbit;               -- port 1 cts_n
56
    SWI : out slv8;                     -- hio switches
57
    BTN : out slv4                      -- hio buttons
58
  );
59
end tb_tst_serloop;
60
 
61
architecture sim of tb_tst_serloop is
62
 
63
  signal CLK_STOP_L  : slbit := '0';
64 17 wfjm
  signal CLK_CYCLE : integer := 0;
65 16 wfjm
 
66
  signal UART_RESET : slbit := '0';
67
  signal UART_RXD : slbit := '1';
68
  signal UART_TXD : slbit := '1';
69
  signal CTS_N : slbit := '0';
70
  signal RTS_N : slbit := '0';
71
 
72
  signal CLKDIV : slv13 := (others=>'0');
73
  signal RXDATA : slv8 := (others=>'0');
74
  signal RXVAL : slbit := '0';
75
  signal RXERR : slbit := '0';
76
  signal RXACT : slbit := '0';
77
  signal TXDATA : slv8 := (others=>'0');
78
  signal TXENA : slbit := '0';
79
  signal TXBUSY : slbit := '0';
80
 
81
  signal UART_TXDATA : slv8 := (others=>'0');
82
  signal UART_TXENA : slbit := '0';
83
  signal UART_TXBUSY : slbit := '0';
84
 
85
  signal ACTPORT : slbit := '0';
86
  signal BREAK : slbit := '0';
87
 
88
  signal CTS_CYCLE : integer := 0;
89
  signal CTS_FRACT : integer := 0;
90
  signal XON_CYCLE : integer := 0;
91
  signal XON_FRACT : integer := 0;
92
 
93
  signal S2M_ACTIVE : slbit := '0';
94
  signal S2M_SIZE : integer := 0;
95
  signal S2M_ENAESC : slbit := '0';
96
  signal S2M_ENAXON : slbit := '0';
97
 
98
  signal M2S_XONSEEN : slbit := '0';
99
  signal M2S_XOFFSEEN : slbit := '0';
100
 
101
  signal R_XONRXOK : slbit := '1';
102
  signal R_XONTXOK : slbit := '1';
103
 
104
begin
105
 
106 17 wfjm
  CLKCNT : simclkcnt port map (CLK => CLKS, CLK_CYCLE => CLK_CYCLE);
107 16 wfjm
 
108
  UART : serport_uart_rxtx
109
    generic map (
110
      CDWIDTH => 13)
111
    port map (
112
      CLK    => CLKS,
113
      RESET  => UART_RESET,
114
      CLKDIV => CLKDIV,
115
      RXSD   => UART_RXD,
116
      RXDATA => RXDATA,
117
      RXVAL  => RXVAL,
118
      RXERR  => RXERR,
119
      RXACT  => RXACT,
120
      TXSD   => UART_TXD,
121
      TXDATA => UART_TXDATA,
122
      TXENA  => UART_TXENA,
123
      TXBUSY => UART_TXBUSY
124
    );
125
 
126
  XONTX : serport_xontx
127
    port map (
128
      CLK         => CLKS,
129
      RESET       => UART_RESET,
130
      ENAXON      => S2M_ENAXON,
131
      ENAESC      => S2M_ENAESC,
132
      UART_TXDATA => UART_TXDATA,
133
      UART_TXENA  => UART_TXENA,
134
      UART_TXBUSY => UART_TXBUSY,
135
      TXDATA      => TXDATA,
136
      TXENA       => TXENA,
137
      TXBUSY      => TXBUSY,
138
      RXOK        => R_XONRXOK,
139
      TXOK        => R_XONTXOK
140
    );
141
 
142
  proc_port_mux: process (ACTPORT, BREAK, UART_TXD, CTS_N,
143
                          P0_TXD, P0_RTS_N, P1_TXD, P1_RTS_N)
144
    variable eff_txd : slbit := '0';
145
  begin
146
 
147
    if BREAK = '0' then                 -- if no break active
148
      eff_txd := UART_TXD;                -- send uart
149
    else                                -- otherwise
150
      eff_txd := '0';                     -- force '0'
151
    end if;
152
 
153
    if ACTPORT = '0' then               -- use port 0
154
      P0_RXD   <= eff_txd;                -- write port 0 inputs
155
      P0_CTS_N <= CTS_N;
156
      UART_RXD <= P0_TXD;                 -- get port 0 outputs
157
      RTS_N    <= P0_RTS_N;
158
      P1_RXD   <= '1';                    -- port 1 inputs to idle state
159
      P1_CTS_N <= '0';
160
    else                                -- use port 1
161
      P1_RXD   <= eff_txd;                -- write port 1 inputs
162
      P1_CTS_N <= CTS_N;
163
      UART_RXD <= P1_TXD;                 -- get port 1 outputs
164
      RTS_N    <= P1_RTS_N;
165
      P0_RXD   <= '1';                    -- port 0 inputs to idle state
166
      P0_CTS_N <= '0';
167
    end if;
168
  end process proc_port_mux;
169
 
170
  proc_cts: process(CLKS)
171
    variable cts_timer : integer := 0;
172
  begin
173
 
174
    if rising_edge(CLKS) then
175
      if CTS_CYCLE = 0 then               -- if cts throttle off
176
        CTS_N <= '0';                       -- cts permanently asserted
177
 
178
      else                                -- otherwise determine throttling
179
 
180
        if cts_timer>0 and cts_timer<CTS_CYCLE then  -- unless beyond ends
181
          cts_timer := cts_timer - 1;                  -- decrement
182
        else
183
          cts_timer := CTS_CYCLE-1;                    -- otherwise reload
184
        end if;
185
 
186
        if cts_timer < cts_fract then     -- if in lower 'fract' counts
187
          CTS_N <= '1';                     -- throttle: deassert CTS
188
        else                              -- otherwise
189
          CTS_N <= '0';                     -- let go: assert CTS
190
        end if;
191
 
192
      end if;
193
    end if;
194
 
195
  end process proc_cts;
196
 
197
  proc_xonrxok: process(CLKS)
198
    variable xon_timer : integer := 0;
199
  begin
200
    if rising_edge(CLKS) then
201
      if XON_CYCLE = 0 then               -- if xon throttle off
202
        R_XONRXOK <= '1';                   -- xonrxok permanently asserted
203
 
204
      else                                -- otherwise determine throttling
205
 
206
        if xon_timer>0 and xon_timer<XON_CYCLE then  -- unless beyond ends
207
          xon_timer := xon_timer - 1;                  -- decrement
208
        else
209
          xon_timer := XON_CYCLE-1;                    -- otherwise reload
210
        end if;
211
 
212
        if xon_timer < xon_fract then     -- if in lower 'fract' counts
213
          R_XONRXOK <= '0';                 -- throttle: deassert xonrxok
214
        else                              -- otherwise
215
          R_XONRXOK <= '1';                 -- let go: assert xonrxok
216
        end if;
217
 
218
      end if;
219
    end if;
220
  end process proc_xonrxok;
221
 
222
  proc_xontxok: process(CLKS)
223
  begin
224
    if rising_edge(CLKS) then
225
      if M2S_XONSEEN = '1' then
226
        R_XONTXOK <= '1';
227
      elsif M2S_XOFFSEEN = '1' then
228
        R_XONTXOK <= '0';
229
      end if;
230
    end if;
231
  end process proc_xontxok;
232
 
233
  proc_stim: process
234
    file fstim : text open read_mode is "tb_tst_serloop_stim";
235
    variable iline : line;
236
    variable oline : line;
237
    variable idelta : integer := 0;
238
    variable iactport : slbit := '0';
239
    variable iswi : slv8 := (others=>'0');
240
    variable btn_num : integer := 0;
241
    variable i_cycle : integer := 0;
242
    variable i_fract : integer := 0;
243
    variable nbyte : integer := 0;
244
    variable enaesc : slbit := '0';
245
    variable enaxon : slbit := '0';
246
    variable bcnt : integer := 0;
247
    variable itxdata : slv8 := (others=>'0');
248
    variable ok : boolean;
249
    variable dname : string(1 to 6) := (others=>' ');
250
 
251
    procedure waitclk(ncyc  : in integer) is
252
    begin
253
     for i in 1 to ncyc loop
254
       wait until rising_edge(CLKS);
255
     end loop;  -- i
256
    end procedure waitclk;
257
 
258
  begin
259
 
260
    -- initialize some top level out signals
261
    SWI <= (others=>'0');
262
    BTN <= (others=>'0');
263
 
264
    wait until rising_edge(CLKS);
265
 
266
    file_loop: while not endfile(fstim) loop
267
 
268
      readline (fstim, iline);
269
 
270
      readcomment(iline, ok);
271
      next file_loop when ok;
272
 
273
      readword(iline, dname, ok);
274
      if ok then
275
        case dname is
276
          when "wait  " =>              -- wait  
277
            read_ea(iline, idelta);
278
            writetimestamp(oline, CLK_CYCLE, ": wait  ");
279
            write(oline, idelta, right, 5);
280
            writeline(output, oline);
281
            waitclk(idelta);
282
 
283
          when "port  " =>              -- switch rs232 port
284
            read_ea(iline, iactport);
285
            ACTPORT <= iactport;
286
            writetimestamp(oline, CLK_CYCLE, ": port  ");
287
            write(oline, iactport, right, 5);
288
            writeline(output, oline);
289
 
290
          when "cts   " =>              -- setup cts throttling
291
            read_ea(iline, i_cycle);
292
            read_ea(iline, i_fract);
293
            CTS_CYCLE <= i_cycle;
294
            CTS_FRACT <= i_fract;
295
            writetimestamp(oline, CLK_CYCLE, ": cts   ");
296
            write(oline, i_cycle, right, 5);
297
            write(oline, i_fract, right, 5);
298
            writeline(output, oline);
299
 
300
          when "xon   " =>              -- setup xon throttling
301
            read_ea(iline, i_cycle);
302
            read_ea(iline, i_fract);
303
            XON_CYCLE <= i_cycle;
304
            XON_FRACT <= i_fract;
305
            writetimestamp(oline, CLK_CYCLE, ": cts   ");
306
            write(oline, i_cycle, right, 5);
307
            write(oline, i_fract, right, 5);
308
            writeline(output, oline);
309
 
310
          when "swi   " =>              -- new SWI settings
311
            read_ea(iline, iswi);
312
            read_ea(iline, idelta);
313
            writetimestamp(oline, CLK_CYCLE, ": swi   ");
314
            write(oline, iswi, right, 10);
315
              write(oline, idelta, right, 5);
316
            writeline(output, oline);
317
            wait until rising_edge(CLKH);
318
            SWI <= iswi;
319
            wait until rising_edge(CLKS);
320
            waitclk(idelta);
321
 
322
          when "btn   " =>              -- BTN push (3 cyc down + 3 cyc wait)
323
            read_ea(iline, btn_num);
324
            read_ea(iline, idelta);
325
            if btn_num>=0 and btn_num<=3 then
326
              writetimestamp(oline, CLK_CYCLE, ": btn   ");
327
              write(oline, btn_num, right, 5);
328
              write(oline, idelta, right, 5);
329
              writeline(output, oline);
330
              wait until rising_edge(CLKH);
331
              BTN(btn_num) <= '1';      -- 3 cycle BTN pulse
332
              wait until rising_edge(CLKH);
333
              wait until rising_edge(CLKH);
334
              wait until rising_edge(CLKH);
335
              BTN(btn_num) <= '0';
336
              wait until rising_edge(CLKH);
337
              wait until rising_edge(CLKH);
338
              wait until rising_edge(CLKH);
339
              wait until rising_edge(CLKS);
340
              waitclk(idelta);
341
            else
342
              write(oline, string'("!! btn: btn number out of range"));
343
              writeline(output, oline);
344
            end if;
345
 
346
          when "expect" =>              -- expect n bytes data
347
            read_ea(iline, nbyte);
348
            read_ea(iline, enaesc);
349
            read_ea(iline, enaxon);
350
            writetimestamp(oline, CLK_CYCLE, ": expect");
351
            write(oline, nbyte, right, 5);
352
            write(oline, enaesc, right, 3);
353
            write(oline, enaxon, right, 3);
354
            writeline(output, oline);
355
 
356
            if nbyte > 0 then
357
              S2M_ACTIVE  <= '1';
358
              S2M_SIZE   <= nbyte;
359
            else
360
              S2M_ACTIVE  <= '0';
361
            end if;
362
            S2M_ENAESC <= enaesc;
363
            S2M_ENAXON <= enaxon;
364
            wait until rising_edge(CLKS);
365
 
366
          when "send  " =>              -- send n bytes data
367
            read_ea(iline, nbyte);
368
            read_ea(iline, enaesc);
369
            read_ea(iline, enaxon);
370
            writetimestamp(oline, CLK_CYCLE, ": send  ");
371
            write(oline, nbyte, right, 5);
372
            write(oline, enaesc, right, 3);
373
            write(oline, enaxon, right, 3);
374
            writeline(output, oline);
375
            bcnt := 0;
376
            itxdata := (others=>'0');
377
 
378
            wait until falling_edge(CLKS);
379
            while bcnt < nbyte loop
380
              while TXBUSY='1' or RTS_N='1' loop
381
                wait until falling_edge(CLKS);
382
              end loop;
383
 
384
              TXDATA <= itxdata;
385
              itxdata := slv(unsigned(itxdata) + 1);
386
              bcnt   := bcnt + 1;
387
 
388
              TXENA  <= '1';
389
              wait until falling_edge(CLKS);
390
              TXENA  <= '0';
391
              wait until falling_edge(CLKS);
392
            end loop;
393
            while TXBUSY='1' or RTS_N='1' loop -- wait till last char send...
394
              wait until falling_edge(CLKS);
395
            end loop;
396
            wait until rising_edge(CLKS);
397
 
398
          when "break " =>              -- send a break for n cycles
399
            read_ea(iline, idelta);
400
            writetimestamp(oline, CLK_CYCLE, ": break ");
401
            write(oline, idelta, right, 5);
402
            writeline(output, oline);
403
            -- send break for n cycles
404
            BREAK <= '1';
405
            waitclk(idelta);
406
            BREAK <= '0';
407
            -- wait for 3 bit cell width
408
            waitclk(3*to_integer(unsigned(CLKDIV)+1));
409
            -- send 'sync' character
410
            wait until falling_edge(CLKS);
411
            TXDATA <= "10000000";
412
            TXENA  <= '1';
413
            wait until falling_edge(CLKS);
414
            TXENA  <= '0';
415
            wait until rising_edge(CLKS);
416
 
417
          when "clkdiv" =>              -- set new clock divider
418
            read_ea(iline, idelta);
419
            writetimestamp(oline, CLK_CYCLE, ": clkdiv");
420
            write(oline, idelta, right, 5);
421
            writeline(output, oline);
422
            CLKDIV <= slv(to_unsigned(idelta, CLKDIV'length));
423
            UART_RESET <= '1';
424
            wait until rising_edge(CLKS);
425
            UART_RESET <= '0';
426
 
427
          when others =>                -- unknown command
428
            write(oline, string'("?? unknown command: "));
429
            write(oline, dname);
430
            writeline(output, oline);
431
            report "aborting" severity failure;
432
        end case;
433
 
434
      else
435
        report "failed to find command" severity failure;
436
 
437
      end if;
438
 
439
      testempty_ea(iline);
440
    end loop;   -- file_loop
441
 
442
    writetimestamp(oline, CLK_CYCLE, ": DONE ");
443
    writeline(output, oline);
444
 
445
    -- extra wait for at least two character times (20 bit times)
446
    -- to allow tx and rx of the last character
447
    waitclk(20*(to_integer(unsigned(CLKDIV))+1));
448
 
449
    CLK_STOP_L <= '1';
450
 
451
    wait for 500 ns;                    -- allows dcm's to stop
452
 
453
    wait;                               -- suspend proc_stim forever
454
                                        -- clock is stopped, sim will end
455
 
456
  end process proc_stim;
457
 
458
  CLK_STOP <= CLK_STOP_L;
459
 
460
  proc_moni: process
461
    variable oline : line;
462
    variable dclk : integer := 0;
463
    variable active_1 : slbit := '0';
464
    variable irxdata : slv8 := (others=>'0');
465
    variable irxeff : slv8 := (others=>'0');
466
    variable irxval : slbit := '0';
467
    variable doesc : slbit := '0';
468
    variable bcnt : integer := 0;
469
    variable xseen : slbit := '0';
470
  begin
471
 
472
    loop
473
      wait until falling_edge(CLKS);
474
 
475
      M2S_XONSEEN  <= '0';
476
      M2S_XOFFSEEN <= '0';
477
 
478
      if S2M_ACTIVE='1' and active_1='0' then -- start expect message
479
        irxdata := (others=>'0');
480
        bcnt := 0;
481
      end if;
482
 
483
      if S2M_ACTIVE='0' and active_1='1' then -- end expect message
484
        if bcnt = S2M_SIZE then
485
          writetimestamp(oline, CLK_CYCLE, ": OK: message seen");
486
        else
487
          writetimestamp(oline, CLK_CYCLE, ": FAIL: missing chars, seen=");
488
          write(oline, bcnt, right, 5);
489
          write(oline, string'("  expect="));
490
          write(oline, S2M_SIZE, right, 5);
491
        end if;
492
        writeline(output, oline);
493
      end if;
494
 
495
      active_1 := S2M_ACTIVE;
496
 
497
      if RXVAL = '1' then
498
        writetimestamp(oline, CLK_CYCLE, ": char: ");
499
        write(oline, RXDATA, right, 10);
500
        write(oline, string'(" ("));
501
        writeoct(oline, RXDATA, right, 3);
502
        write(oline, string'(") dt="));
503
        write(oline, dclk, right, 4);
504
 
505
        irxeff := RXDATA;
506
        irxval := '1';
507
        if doesc = '1' then
508
          irxeff := not RXDATA;
509
          irxval := '1';
510
          doesc  := '0';
511
          write(oline, string'("  eff="));
512
          write(oline, irxeff, right, 10);
513
          write(oline, string'(" ("));
514
          writeoct(oline, irxeff, right, 3);
515
          write(oline, string'(")"));
516
        elsif S2M_ENAESC='1' and RXDATA=c_serport_xesc then
517
          doesc  := '1';
518
          irxval := '0';
519
          write(oline, string'("  XESC seen"));
520
        end if;
521
 
522
        xseen := '0';
523
        if S2M_ENAXON = '1' then
524
          if RXDATA = c_serport_xon then
525
            write(oline, string'("  XON seen"));
526
            M2S_XONSEEN <= '1';
527
            xseen := '1';
528
          elsif RXDATA = c_serport_xoff then
529
            write(oline, string'("  XOFF seen"));
530
            M2S_XOFFSEEN <= '1';
531
            xseen := '1';
532
          end if;
533
        end if;
534
 
535
        if S2M_ACTIVE='1' and irxval='1' and xseen='0' then
536
          if irxeff = irxdata then
537
            write(oline, string'("  OK"));
538
          else
539
            write(oline, string'("  FAIL: expect="));
540
            write(oline, irxdata, right, 10);
541
          end if;
542
          irxdata := slv(unsigned(irxdata) + 1);
543
          bcnt := bcnt + 1;
544
        end if;
545
 
546
        writeline(output, oline);
547
        dclk := 0;
548
 
549
      end if;
550
 
551
      if RXERR = '1' then
552
        writetimestamp(oline, CLK_CYCLE, ": FAIL: RXERR='1'");
553
        writeline(output, oline);
554
      end if;
555
 
556
      dclk := dclk + 1;
557
 
558
    end loop;
559
 
560
  end process proc_moni;
561
 
562
end sim;

powered by: WebSVN 2.1.0

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