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 16

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

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

powered by: WebSVN 2.1.0

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