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

Subversion Repositories rio

[/] [rio/] [branches/] [2.0.0-development/] [bench/] [vhdl/] [TestPortPackage.vhd] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 47 magro732
-------------------------------------------------------------------------------
2
-- 
3
-- RapidIO IP Library Core
4
-- 
5
-- This file is part of the RapidIO IP library project
6
-- http://www.opencores.org/cores/rio/
7
-- 
8
-- Description
9
-- Contains components that can simulate various interfaces used in the RapidIO
10
-- IP library project.
11
-- 
12
-- To Do:
13
-- - Add Symbol-testport from TestRioSerial here.
14
-- 
15
-- Author(s): 
16
-- - Magnus Rosenius, magro732@opencores.org 
17
-- 
18
-------------------------------------------------------------------------------
19
-- 
20
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
21
-- 
22
-- This source file may be used and distributed without 
23
-- restriction provided that this copyright statement is not 
24
-- removed from the file and that any derivative work contains 
25
-- the original copyright notice and the associated disclaimer. 
26
-- 
27
-- This source file is free software; you can redistribute it 
28
-- and/or modify it under the terms of the GNU Lesser General 
29
-- Public License as published by the Free Software Foundation; 
30
-- either version 2.1 of the License, or (at your option) any 
31
-- later version. 
32
-- 
33
-- This source is distributed in the hope that it will be 
34
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
35
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
36
-- PURPOSE. See the GNU Lesser General Public License for more 
37
-- details. 
38
-- 
39
-- You should have received a copy of the GNU Lesser General 
40
-- Public License along with this source; if not, download it 
41
-- from http://www.opencores.org/lgpl.shtml 
42
-- 
43
-------------------------------------------------------------------------------
44
 
45
 
46
-------------------------------------------------------------------------------
47
-- 
48
-------------------------------------------------------------------------------
49
library ieee;
50
use ieee.std_logic_1164.all;
51 51 magro732
use ieee.numeric_std.all;
52
use ieee.math_real.all;
53
use std.textio.all;
54 47 magro732
use work.rio_common.all;
55
 
56
-------------------------------------------------------------------------------
57
-- 
58
-------------------------------------------------------------------------------
59
package TestPortPackage is
60 51 magro732
  -----------------------------------------------------------------------------
61
  -- Types used in simulations.
62
  -----------------------------------------------------------------------------
63
  type ByteArray is array (natural range <>) of
64
    std_logic_vector(7 downto 0);
65
  type HalfwordArray is array (natural range <>) of
66
    std_logic_vector(15 downto 0);
67
  type WordArray is array (natural range <>) of
68
    std_logic_vector(31 downto 0);
69
  type DoublewordArray is array (natural range <>) of
70
    std_logic_vector(63 downto 0);
71
 
72
  -- Type defining a RapidIO frame.
73
  type RioFrame is record
74
    length : natural range 0 to 69;
75
    payload : WordArray(0 to 68);
76
  end record;
77
  type RioFrameArray is array (natural range <>) of RioFrame;
78
 
79
  -- Type defining a RapidIO payload.
80
  type RioPayload is record
81
    length : natural range 0 to 133;
82
    data : HalfwordArray(0 to 132);
83
  end record;
84
 
85
  -----------------------------------------------------------------------------
86
  -- 
87
  -----------------------------------------------------------------------------
88
 
89 47 magro732
  constant ADDRESS_WIDTH_MAX : natural := 64;
90
  constant DATA_WIDTH_MAX : natural := 64;
91
  constant SEL_WIDTH_MAX : natural := 8;
92
 
93
  type TestPortMessageWishbone is record
94
    writeAccess : boolean;
95
    address : std_logic_vector(ADDRESS_WIDTH_MAX-1 downto 0);
96
    byteSelect : std_logic_vector(SEL_WIDTH_MAX-1 downto 0);
97
    data : std_logic_vector(DATA_WIDTH_MAX-1 downto 0);
98
    continue : boolean;
99
    latency : natural;
100
  end record;
101
  type TestPortMessageWishboneArray is
102
    array (natural range <>) of TestPortMessageWishbone;
103
 
104
  type TestPortMessageSymbol is record
105
    symbolType : std_logic_vector(1 downto 0);
106
    symbolContent : std_logic_vector(31 downto 0);
107
    ignoreIdle : boolean;
108
  end record;
109
  type TestPortMessageSymbolArray is
110
    array (natural range <>) of TestPortMessageSymbol;
111
 
112
  type TestPortMessagePacketBuffer is record
113
    frame : RioFrame;
114
    willAbort : boolean;
115
  end record;
116
  type TestPortMessagePacketBufferArray is
117
    array (natural range <>) of TestPortMessagePacketBuffer;
118
 
119
  -----------------------------------------------------------------------------
120
  -- 
121
  -----------------------------------------------------------------------------
122
 
123
  component TestPortWishbone is
124
    generic(
125
      ADDRESS_WIDTH : natural := 31;
126
      SEL_WIDTH : natural := 8;
127
      DATA_WIDTH : natural := 64);
128
    port(
129
      clk : in std_logic;
130
      areset_n : in std_logic;
131
 
132
      messageEmpty_o : out std_logic;
133
      messageWrite_i : in std_logic;
134
      message_i : in TestPortMessageWishbone;
135
      messageAck_o : out std_logic;
136
 
137
      cyc_i : in std_logic;
138
      stb_i : in std_logic;
139
      we_i : in std_logic;
140
      adr_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
141
      sel_i : in std_logic_vector(SEL_WIDTH-1 downto 0);
142
      dat_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
143
      dat_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
144
      err_o : out std_logic;
145
      ack_o : out std_logic);
146
  end component;
147
 
148
  component TestPortPacketBuffer is
149
    generic(
150
      READ_CONTENT_END_DATA_VALID : boolean := true);
151
    port(
152
      clk : in std_logic;
153
      areset_n : in std_logic;
154
 
155
      readEmpty_o : out std_logic;
156
      readWrite_i : in std_logic;
157
      readMessage_i : in TestPortMessagePacketBuffer;
158
      readAck_o : out std_logic;
159
 
160
      writeEmpty_o : out std_logic;
161
      writeWrite_i : in std_logic;
162
      writeMessage_i : in TestPortMessagePacketBuffer;
163
      writeAck_o : out std_logic;
164
 
165
      readFrameEmpty_o : out std_logic;
166
      readFrame_i : in std_logic;
167
      readFrameRestart_i : in std_logic;
168
      readFrameAborted_o : out std_logic;
169
      readWindowEmpty_o : out std_logic;
170
      readWindowReset_i : in std_logic;
171
      readWindowNext_i : in std_logic;
172
      readContentEmpty_o : out std_logic;
173
      readContent_i : in std_logic;
174
      readContentEnd_o : out std_logic;
175
      readContentData_o : out std_logic_vector(31 downto 0);
176
 
177
      writeFrame_i : in std_logic;
178
      writeFrameAbort_i : in std_logic;
179
      writeContent_i : in std_logic;
180
      writeContentData_i : in std_logic_vector(31 downto 0));
181
  end component;
182
 
183
  -----------------------------------------------------------------------------
184
  -- 
185
  -----------------------------------------------------------------------------
186
  procedure TestPortWishboneWrite(
187
    signal writeSignal : out std_logic;
188
    signal messageSignal : out TestPortMessageWishbone;
189
    signal ackSignal : in std_logic;
190
    constant writeAccess : in boolean;
191
    constant address : in std_logic_vector(ADDRESS_WIDTH_MAX-1 downto 0);
192
    constant byteSelect : in std_logic_vector(SEL_WIDTH_MAX-1 downto 0);
193
    constant data : in std_logic_vector(DATA_WIDTH_MAX-1 downto 0);
194
    constant continue : in boolean := false;
195
    constant latency : in natural := 0);
196
 
197
  procedure TestPortPacketBufferWrite(
198
    signal writeSignal : out std_logic;
199
    signal messageSignal : out TestPortMessagePacketBuffer;
200
    signal ackSignal : in std_logic;
201
    constant frame : in RioFrame;
202
    constant willAbort : in boolean := false);
203
 
204 48 magro732
  -----------------------------------------------------------------------------
205
  -- Function to print a std_logic_vector.
206
  -----------------------------------------------------------------------------
207
  function to_string(constant value : std_logic_vector)
208
    return string;
209
 
210
  ---------------------------------------------------------------------------
211
  -- Procedures for test control.
212
  ---------------------------------------------------------------------------
213
 
214 51 magro732
  procedure TestSpec(constant str : string);
215
  procedure TestCaseStart(constant str : string);
216
 
217 48 magro732
  procedure TestWarning(constant tag : in string);
218
  procedure TestError(constant tag : in string;
219
                      constant stopAtError : in boolean := true);
220
  procedure TestCompare(constant expression : in boolean;
221
                        constant tag : in string := "";
222
                        constant stopAtError : in boolean := true);
223
  procedure TestCompare(constant got : in std_logic;
224
                        constant expected : in std_logic;
225
                        constant tag : in string := "";
226
                        constant stopAtError : in boolean := true);
227
  procedure TestCompare(constant got : in std_logic_vector;
228
                        constant expected : in std_logic_vector;
229
                        constant tag : in string := "";
230
                        constant stopAtError : in boolean := true);
231
  procedure TestCompare(constant got : in natural;
232
                        constant expected : in natural;
233
                        constant tag : in string := "";
234
                        constant stopAtError : in boolean := true);
235
  procedure TestCompare(constant got : in time;
236
                        constant expected : in time;
237
                        constant tag : in string := "";
238
                        constant stopAtError : in boolean := true);
239
 
240
  procedure TestWait(signal waitSignal : in std_logic;
241
                     constant waitValue : in std_logic;
242
                     constant tag : in string := "";
243
                     constant waitTime : in time := 1 ms;
244
                     constant stopAtError : in boolean := true);
245
  procedure TestWait(signal waitSignal : in std_logic;
246
                     constant waitValue : in std_logic;
247
                     signal ackSignal : inout std_logic;
248
                     constant tag : in string := "";
249
                     constant waitTime : in time := 1 ms;
250
                     constant stopAtError : in boolean := true);
251
 
252
  procedure TestEnd;
253
 
254 51 magro732
  -----------------------------------------------------------------------------
255
  -- 
256
  -----------------------------------------------------------------------------
257
 
258
  -----------------------------------------------------------------------------
259
  -- Crc5 calculation function.
260
  -- ITU, polynom=0x15.
261
  -----------------------------------------------------------------------------
262
  function Crc5(constant data : in std_logic_vector(18 downto 0);
263
                constant crc : in std_logic_vector(4 downto 0))
264
    return std_logic_vector;
265
 
266
  ---------------------------------------------------------------------------
267
  -- Create a RapidIO physical layer control symbol.
268
  ---------------------------------------------------------------------------
269
  function RioControlSymbolCreate(
270
    constant stype0 : in std_logic_vector(2 downto 0);
271
    constant parameter0 : in std_logic_vector(4 downto 0);
272
    constant parameter1 : in std_logic_vector(4 downto 0);
273
    constant stype1 : in std_logic_vector(2 downto 0);
274
    constant cmd : in std_logic_vector(2 downto 0))
275
    return std_logic_vector;
276
 
277
  -----------------------------------------------------------------------------
278
  -- Crc16 calculation function.
279
  -- CITT, polynom=0x1021.
280
  -----------------------------------------------------------------------------
281
  function Crc16(constant data : in std_logic_vector(15 downto 0);
282
                 constant crc : in std_logic_vector(15 downto 0))
283
    return std_logic_vector;
284
 
285
  ---------------------------------------------------------------------------
286
  -- Create a randomly initialized data array.
287
  ---------------------------------------------------------------------------
288
  procedure CreateRandomPayload(
289
    variable payload : out HalfwordArray;
290
    variable seed1 : inout positive;
291
    variable seed2 : inout positive);
292
  procedure CreateRandomPayload(
293
    variable payload : out DoublewordArray;
294
    variable seed1 : inout positive;
295
    variable seed2 : inout positive);
296
 
297
  ---------------------------------------------------------------------------
298
  -- Create a generic RapidIO frame.
299
  ---------------------------------------------------------------------------
300
  function RioFrameCreate(
301
    constant ackId : in std_logic_vector(4 downto 0);
302
    constant vc : in std_logic;
303
    constant crf : in std_logic;
304
    constant prio : in std_logic_vector(1 downto 0);
305
    constant tt : in std_logic_vector(1 downto 0);
306
    constant ftype : in std_logic_vector(3 downto 0);
307
    constant sourceId : in std_logic_vector(15 downto 0);
308
    constant destId : in std_logic_vector(15 downto 0);
309
    constant payload : in RioPayload)
310
    return RioFrame;
311
 
312
  ---------------------------------------------------------------------------
313
  -- Create a NWRITE RapidIO frame.
314
  ---------------------------------------------------------------------------
315
  function RioNwrite(
316
    constant wrsize : in std_logic_vector(3 downto 0);
317
    constant address : in std_logic_vector(28 downto 0);
318
    constant wdptr : in std_logic;
319
    constant xamsbs : in std_logic_vector(1 downto 0);
320
    constant dataLength : in natural range 1 to 32;
321
    constant data : in DoublewordArray(0 to 31))
322
    return RioPayload;
323
 
324
  ---------------------------------------------------------------------------
325
  -- Create a NWRITER RapidIO frame.
326
  ---------------------------------------------------------------------------
327
  function RioNwriteR(
328
    constant wrsize : in std_logic_vector(3 downto 0);
329
    constant tid : in std_logic_vector(7 downto 0);
330
    constant address : in std_logic_vector(28 downto 0);
331
    constant wdptr : in std_logic;
332
    constant xamsbs : in std_logic_vector(1 downto 0);
333
    constant dataLength : in natural range 1 to 32;
334
    constant data : in DoublewordArray(0 to 31))
335
    return RioPayload;
336
 
337
  ---------------------------------------------------------------------------
338
  -- Create a NREAD RapidIO frame.
339
  ---------------------------------------------------------------------------
340
  function RioNread(
341
    constant rdsize : in std_logic_vector(3 downto 0);
342
    constant tid : in std_logic_vector(7 downto 0);
343
    constant address : in std_logic_vector(28 downto 0);
344
    constant wdptr : in std_logic;
345
    constant xamsbs : in std_logic_vector(1 downto 0))
346
    return RioPayload;
347
 
348
  ---------------------------------------------------------------------------
349
  -- Create a RESPONSE RapidIO frame.
350
  ---------------------------------------------------------------------------
351
  function RioResponse(
352
    constant status : in std_logic_vector(3 downto 0);
353
    constant tid : in std_logic_vector(7 downto 0);
354
    constant dataLength : in natural range 0 to 32;
355
    constant data : in DoublewordArray(0 to 31))
356
    return RioPayload;
357
 
358
  ---------------------------------------------------------------------------
359
  -- Create a Maintenance RapidIO frame.
360
  ---------------------------------------------------------------------------
361
  function RioMaintenance(
362
    constant transaction : in std_logic_vector(3 downto 0);
363
    constant size : in std_logic_vector(3 downto 0);
364
    constant tid : in std_logic_vector(7 downto 0);
365
    constant hopCount : in std_logic_vector(7 downto 0);
366
    constant configOffset : in std_logic_vector(20 downto 0);
367
    constant wdptr : in std_logic;
368
    constant dataLength : in natural range 0 to 8;
369
    constant data : in DoublewordArray(0 to 7))
370
    return RioPayload;
371
 
372
  -----------------------------------------------------------------------------
373
  -- Function to convert a std_logic_vector to a string.
374
  -----------------------------------------------------------------------------
375
  function byteToString(constant byte : std_logic_vector(7 downto 0))
376
    return string;
377
 
378 47 magro732
end package;
379
 
380
-------------------------------------------------------------------------------
381
-- 
382
-------------------------------------------------------------------------------
383
package body TestPortPackage is
384
 
385
  -----------------------------------------------------------------------------
386
  -- 
387
  -----------------------------------------------------------------------------
388
  procedure TestPortWishboneWrite(
389
    signal writeSignal : out std_logic;
390
    signal messageSignal : out TestPortMessageWishbone;
391
    signal ackSignal : in std_logic;
392
    constant writeAccess : in boolean;
393
    constant address : in std_logic_vector(ADDRESS_WIDTH_MAX-1 downto 0);
394
    constant byteSelect : in std_logic_vector(SEL_WIDTH_MAX-1 downto 0);
395
    constant data : in std_logic_vector(DATA_WIDTH_MAX-1 downto 0);
396
    constant continue : in boolean := false;
397
    constant latency : in natural := 0) is
398
  begin
399
    writeSignal <= '1';
400
    messageSignal.writeAccess <= writeAccess;
401
    messageSignal.address <= address;
402
    messageSignal.byteSelect <= byteSelect;
403
    messageSignal.data <= data;
404
    messageSignal.continue <= continue;
405
    messageSignal.latency <= latency;
406
    wait until ackSignal = '1';
407
    writeSignal <= '0';
408
    wait until ackSignal = '0';
409
  end procedure;
410
 
411
  -----------------------------------------------------------------------------
412
  -- 
413
  -----------------------------------------------------------------------------
414
  procedure TestPortPacketBufferWrite(
415
    signal writeSignal : out std_logic;
416
    signal messageSignal : out TestPortMessagePacketBuffer;
417
    signal ackSignal : in std_logic;
418
    constant frame : in RioFrame;
419
    constant willAbort : in boolean := false) is
420
  begin
421
    writeSignal <= '1';
422
    messageSignal.frame <= frame;
423
    messageSignal.willAbort <= willAbort;
424
    wait until ackSignal = '1';
425
    writeSignal <= '0';
426
    wait until ackSignal = '0';
427
  end procedure;
428
 
429 48 magro732
  -----------------------------------------------------------------------------
430
  -- Function to print std_logic_vector.
431
  -----------------------------------------------------------------------------
432
  function to_string(constant value : std_logic) return string is
433
    variable s : string(1 to 1);
434
  begin
435
    if (value = '0') then
436
      s(1) := '0';
437
    elsif (value = '1') then
438
      s(1) := '1';
439
    elsif (value = 'U') then
440
      s(1) := 'U';
441
    elsif (value = 'X') then
442
      s(1) := 'X';
443
    else
444
      s(1) := '?';
445
    end if;
446
    return s;
447
  end function;
448
  function to_string(constant value : std_logic_vector) return string is
449
    variable s : string(1 to value'length);
450
    variable index : positive;
451
    variable i : natural;
452
  begin
453
    index := 1;
454
    for i in value'range loop
455
      if (value(i) = '0') then
456
        s(index) := '0';
457
      elsif (value(i) = '1') then
458
        s(index) := '1';
459
      elsif (value(i) = 'U') then
460
        s(index) := 'U';
461
      elsif (value(i) = 'X') then
462
        s(index) := 'X';
463
      else
464
        s(index) := '?';
465
      end if;
466
      index := index + 1;
467
    end loop;
468
    return s;
469
  end function;
470
 
471
  ---------------------------------------------------------------------------
472
  -- Procedures to handle tests.
473
  ---------------------------------------------------------------------------
474
 
475 51 magro732
  procedure TestSpec(constant str : string) is
476
    file specFile  : text;
477
    variable specLine, outputLine : line;
478
    variable fStatus: FILE_OPEN_STATUS;
479
  begin
480
    file_open(fStatus, specFile, "testspec.txt", append_mode);
481
    write(specLine, string'(str));
482
    writeline (specFile, specLine);
483
    file_close(specFile);
484
  end procedure;
485
 
486
  procedure TestCaseStart(constant str : string) is
487
    file reportFile  : text;
488
    variable reportLine, outputLine : line;
489
    variable fStatus: FILE_OPEN_STATUS;
490
  begin
491
    report str severity note;
492
  end procedure;
493
 
494 48 magro732
  procedure TestWarning(constant tag : in string) is
495
    variable writeBuffer : line;
496
  begin
497
    write(writeBuffer, now);
498
    write(writeBuffer, string'(":WARNING:"));
499
    write(writeBuffer, tag);
500
    writeline(OUTPUT, writeBuffer);
501
  end procedure;
502
 
503
  procedure TestError(constant tag : in string;
504
                      constant stopAtError : in boolean := true) is
505
    variable writeBuffer : line;
506
  begin
507
    write(writeBuffer, now);
508
    write(writeBuffer, string'(":FAILED:"));
509
    write(writeBuffer, tag);
510
    writeline(OUTPUT, writeBuffer);
511
 
512
    if (stopAtError) then
513
      std.env.stop(0);
514
    end if;
515
  end procedure;
516
 
517
  procedure TestCompare(constant expression : in boolean;
518
                        constant tag : in string := "";
519
                        constant stopAtError : in boolean := true) is
520
    variable writeBuffer : line;
521
  begin
522
    write(writeBuffer, now);
523
    if (not expression) then
524
      write(writeBuffer, string'(":FAILED:"));
525
    else
526
      write(writeBuffer, string'(":PASSED:"));
527
    end if;
528
    write(writeBuffer, tag);
529
    writeline(OUTPUT, writeBuffer);
530
 
531
    if (stopAtError) and (not expression) then
532
      std.env.stop(0);
533
    end if;
534
  end procedure;
535
 
536
  procedure TestCompare(constant got : in std_logic;
537
                        constant expected : in std_logic;
538
                        constant tag : in string := "";
539
                        constant stopAtError : in boolean := true) is
540
    variable writeBuffer : line;
541
  begin
542
    write(writeBuffer, now);
543
    if (expected /= got) then
544
      write(writeBuffer, string'(":FAILED:"));
545
      write(writeBuffer, tag);
546
      write(writeBuffer, ":got=" & to_string(got));
547
      write(writeBuffer, ":expected=" & to_string(expected));
548
    else
549
      write(writeBuffer, string'(":PASSED:"));
550
      write(writeBuffer, tag);
551
    end if;
552
    writeline(OUTPUT, writeBuffer);
553
 
554
    if (stopAtError) and (expected /= got) then
555
      std.env.stop(0);
556
    end if;
557
  end procedure;
558
 
559
  procedure TestCompare(constant got : in std_logic_vector;
560
                        constant expected : in std_logic_vector;
561
                        constant tag : in string := "";
562
                        constant stopAtError : in boolean := true) is
563
    variable writeBuffer : line;
564
  begin
565
    write(writeBuffer, now);
566
    if (expected /= got) then
567
      write(writeBuffer, string'(":FAILED:"));
568
      write(writeBuffer, tag);
569
      write(writeBuffer, ":got=" & to_string(got));
570
      write(writeBuffer, ":expected=" & to_string(expected));
571
    else
572
      write(writeBuffer, string'(":PASSED:"));
573
      write(writeBuffer, tag);
574
    end if;
575
    writeline(OUTPUT, writeBuffer);
576
 
577
    if (stopAtError) and (expected /= got) then
578
      std.env.stop(0);
579
    end if;
580
  end procedure;
581
 
582
  procedure TestCompare(constant got : in natural;
583
                        constant expected : in natural;
584
                        constant tag : in string := "";
585
                        constant stopAtError : in boolean := true) is
586
    variable writeBuffer : line;
587
  begin
588
    write(writeBuffer, now);
589
    if (expected /= got) then
590
      write(writeBuffer, string'(":FAILED:"));
591
      write(writeBuffer, tag);
592
      write(writeBuffer, ":got=" & integer'image(got));
593
      write(writeBuffer, ":expected=" & integer'image(expected));
594
    else
595
      write(writeBuffer, string'(":PASSED:"));
596
      write(writeBuffer, tag);
597
    end if;
598
    writeline(OUTPUT, writeBuffer);
599
 
600
    if (stopAtError) and (expected /= got) then
601
      std.env.stop(0);
602
    end if;
603
  end procedure;
604
 
605
  procedure TestCompare(constant got : in time;
606
                        constant expected : in time;
607
                        constant tag : in string := "";
608
                        constant stopAtError : in boolean := true) is
609
    variable writeBuffer : line;
610
  begin
611
    write(writeBuffer, now);
612
    if (expected /= got) then
613
      write(writeBuffer, string'(":FAILED:"));
614
      write(writeBuffer, tag);
615
      write(writeBuffer, string'(":got="));
616
      write(writeBuffer, got);
617
      write(writeBuffer, string'(":expected="));
618
      write(writeBuffer, expected);
619
    else
620
      write(writeBuffer, string'(":PASSED:"));
621
      write(writeBuffer, tag);
622
    end if;
623
    writeline(OUTPUT, writeBuffer);
624
 
625
    if (stopAtError) and (expected /= got) then
626
      std.env.stop(0);
627
    end if;
628
  end procedure;
629
 
630
  procedure TestWait(signal waitSignal : in std_logic;
631
                     constant waitValue : in std_logic;
632
                     constant tag : in string := "";
633
                     constant waitTime : in time := 1 ms;
634
                     constant stopAtError : in boolean := true) is
635
    variable writeBuffer : line;
636
  begin
637
    if (waitSignal /= waitValue) then
638
      wait until waitSignal = waitValue for waitTime;
639
      if (waitSignal /= waitValue) then
640
        write(writeBuffer, now);
641
        write(writeBuffer, string'(":FAILED:"));
642
        write(writeBuffer, tag);
643
        writeline(OUTPUT, writeBuffer);
644
 
645
        if (stopAtError) then
646
          std.env.stop(0);
647
        end if;
648
      end if;
649
    end if;
650
  end procedure;
651
 
652
  procedure TestWait(signal waitSignal : in std_logic;
653
                     constant waitValue : in std_logic;
654
                     signal ackSignal : inout std_logic;
655
                     constant tag : in string := "";
656
                     constant waitTime : in time := 1 ms;
657
                     constant stopAtError : in boolean := true) is
658
    variable writeBuffer : line;
659
  begin
660
    if (waitSignal /= waitValue) then
661
 
662
      wait until waitSignal = waitValue for waitTime;
663
 
664
      if (waitSignal /= waitValue) then
665
        write(writeBuffer, now);
666
        write(writeBuffer, string'(":FAILED:"));
667
        write(writeBuffer, tag);
668
        writeline(OUTPUT, writeBuffer);
669
 
670
        if (stopAtError) then
671
          std.env.stop(0);
672
        end if;
673
      end if;
674
    end if;
675
 
676
    ackSignal <= not ackSignal;
677
 
678
    wait until waitSignal /= waitValue for waitTime;
679
 
680
    if (waitSignal = waitValue) then
681
      write(writeBuffer, now);
682
      write(writeBuffer, string'(":FAILED:"));
683
      write(writeBuffer, tag);
684
      writeline(OUTPUT, writeBuffer);
685
 
686
      if (stopAtError) then
687
        std.env.stop(0);
688
      end if;
689
    end if;
690
  end procedure;
691
 
692
  procedure TestEnd is
693
    variable writeBuffer : line;
694
  begin
695
    write(writeBuffer, now);
696
    write(writeBuffer, string'(":COMPLETED"));
697
    writeline(OUTPUT, writeBuffer);
698
    std.env.stop(0);
699
  end TestEnd;
700
 
701 51 magro732
  -----------------------------------------------------------------------------
702
  -- 
703
  -----------------------------------------------------------------------------
704
  -----------------------------------------------------------------------------
705
  -- Crc5 calculation function.
706
  -- ITU, polynom=0x15.
707
  -----------------------------------------------------------------------------
708
  function Crc5(constant data : in std_logic_vector(18 downto 0);
709
                constant crc : in std_logic_vector(4 downto 0))
710
    return std_logic_vector is
711
    type crcTableType is array (0 to 31) of std_logic_vector(7 downto 0);
712
    constant crcTable : crcTableType := (
713
      x"00", x"15", x"1f", x"0a", x"0b", x"1e", x"14", x"01",
714
      x"16", x"03", x"09", x"1c", x"1d", x"08", x"02", x"17",
715
      x"19", x"0c", x"06", x"13", x"12", x"07", x"0d", x"18",
716
      x"0f", x"1a", x"10", x"05", x"04", x"11", x"1b", x"0e" );
717
    variable index : natural range 0 to 31;
718
    variable result : std_logic_vector(4 downto 0);
719
  begin
720
    result := crc;
721
    index := to_integer(unsigned(data(18 downto 14) xor result));
722
    result := crcTable(index)(4 downto 0);
723
    index := to_integer(unsigned(data(13 downto 9) xor result));
724
    result := crcTable(index)(4 downto 0);
725
    index := to_integer(unsigned(data(8 downto 4) xor result));
726
    result := crcTable(index)(4 downto 0);
727
    index := to_integer(unsigned((data(3 downto 0) & '0') xor result));
728
    return crcTable(index)(4 downto 0);
729
  end Crc5;
730
 
731
  ---------------------------------------------------------------------------
732
  -- Create a RapidIO physical layer control symbol.
733
  ---------------------------------------------------------------------------
734
  function RioControlSymbolCreate(
735
    constant stype0 : in std_logic_vector(2 downto 0);
736
    constant parameter0 : in std_logic_vector(4 downto 0);
737
    constant parameter1 : in std_logic_vector(4 downto 0);
738
    constant stype1 : in std_logic_vector(2 downto 0);
739
    constant cmd : in std_logic_vector(2 downto 0))
740
    return std_logic_vector is
741
    variable returnValue : std_logic_vector(23 downto 0);
742
    variable symbolData : std_logic_vector(18 downto 0);
743
  begin
744
    symbolData(18 downto 16) := stype0;
745
    symbolData(15 downto 11) := parameter0;
746
    symbolData(10 downto 6) := parameter1;
747
    symbolData(5 downto 3) := stype1;
748
    symbolData(2 downto 0) := cmd;
749
 
750
    returnValue(23 downto 5) := symbolData;
751
    returnValue(4 downto 0) := Crc5(symbolData, "11111");
752
 
753
    return returnValue;
754
  end function;
755
 
756
  -----------------------------------------------------------------------------
757
  -- Crc16 calculation function.
758
  -- CITT, polynom=0x1021.
759
  -----------------------------------------------------------------------------
760
  function Crc16(constant data : in std_logic_vector(15 downto 0);
761
                 constant crc : in std_logic_vector(15 downto 0))
762
    return std_logic_vector is
763
    type crcTableType is array (0 to 255) of std_logic_vector(15 downto 0);
764
    constant crcTable : crcTableType := (
765
      x"0000", x"1021", x"2042", x"3063", x"4084", x"50a5", x"60c6", x"70e7",
766
      x"8108", x"9129", x"a14a", x"b16b", x"c18c", x"d1ad", x"e1ce", x"f1ef",
767
      x"1231", x"0210", x"3273", x"2252", x"52b5", x"4294", x"72f7", x"62d6",
768
      x"9339", x"8318", x"b37b", x"a35a", x"d3bd", x"c39c", x"f3ff", x"e3de",
769
      x"2462", x"3443", x"0420", x"1401", x"64e6", x"74c7", x"44a4", x"5485",
770
      x"a56a", x"b54b", x"8528", x"9509", x"e5ee", x"f5cf", x"c5ac", x"d58d",
771
      x"3653", x"2672", x"1611", x"0630", x"76d7", x"66f6", x"5695", x"46b4",
772
      x"b75b", x"a77a", x"9719", x"8738", x"f7df", x"e7fe", x"d79d", x"c7bc",
773
      x"48c4", x"58e5", x"6886", x"78a7", x"0840", x"1861", x"2802", x"3823",
774
      x"c9cc", x"d9ed", x"e98e", x"f9af", x"8948", x"9969", x"a90a", x"b92b",
775
      x"5af5", x"4ad4", x"7ab7", x"6a96", x"1a71", x"0a50", x"3a33", x"2a12",
776
      x"dbfd", x"cbdc", x"fbbf", x"eb9e", x"9b79", x"8b58", x"bb3b", x"ab1a",
777
      x"6ca6", x"7c87", x"4ce4", x"5cc5", x"2c22", x"3c03", x"0c60", x"1c41",
778
      x"edae", x"fd8f", x"cdec", x"ddcd", x"ad2a", x"bd0b", x"8d68", x"9d49",
779
      x"7e97", x"6eb6", x"5ed5", x"4ef4", x"3e13", x"2e32", x"1e51", x"0e70",
780
      x"ff9f", x"efbe", x"dfdd", x"cffc", x"bf1b", x"af3a", x"9f59", x"8f78",
781
      x"9188", x"81a9", x"b1ca", x"a1eb", x"d10c", x"c12d", x"f14e", x"e16f",
782
      x"1080", x"00a1", x"30c2", x"20e3", x"5004", x"4025", x"7046", x"6067",
783
      x"83b9", x"9398", x"a3fb", x"b3da", x"c33d", x"d31c", x"e37f", x"f35e",
784
      x"02b1", x"1290", x"22f3", x"32d2", x"4235", x"5214", x"6277", x"7256",
785
      x"b5ea", x"a5cb", x"95a8", x"8589", x"f56e", x"e54f", x"d52c", x"c50d",
786
      x"34e2", x"24c3", x"14a0", x"0481", x"7466", x"6447", x"5424", x"4405",
787
      x"a7db", x"b7fa", x"8799", x"97b8", x"e75f", x"f77e", x"c71d", x"d73c",
788
      x"26d3", x"36f2", x"0691", x"16b0", x"6657", x"7676", x"4615", x"5634",
789
      x"d94c", x"c96d", x"f90e", x"e92f", x"99c8", x"89e9", x"b98a", x"a9ab",
790
      x"5844", x"4865", x"7806", x"6827", x"18c0", x"08e1", x"3882", x"28a3",
791
      x"cb7d", x"db5c", x"eb3f", x"fb1e", x"8bf9", x"9bd8", x"abbb", x"bb9a",
792
      x"4a75", x"5a54", x"6a37", x"7a16", x"0af1", x"1ad0", x"2ab3", x"3a92",
793
      x"fd2e", x"ed0f", x"dd6c", x"cd4d", x"bdaa", x"ad8b", x"9de8", x"8dc9",
794
      x"7c26", x"6c07", x"5c64", x"4c45", x"3ca2", x"2c83", x"1ce0", x"0cc1",
795
      x"ef1f", x"ff3e", x"cf5d", x"df7c", x"af9b", x"bfba", x"8fd9", x"9ff8",
796
      x"6e17", x"7e36", x"4e55", x"5e74", x"2e93", x"3eb2", x"0ed1", x"1ef0" );
797
    variable index : natural range 0 to 255;
798
    variable result : std_logic_vector(15 downto 0);
799
  begin
800
    result := crc;
801
    index := to_integer(unsigned(data(15 downto 8) xor result(15 downto 8)));
802
    result := crcTable(index) xor (result(7 downto 0) & x"00");
803
    index := to_integer(unsigned(data(7 downto 0) xor result(15 downto 8)));
804
    result := crcTable(index) xor (result(7 downto 0) & x"00");
805
    return result;
806
  end Crc16;
807
 
808
  ---------------------------------------------------------------------------
809
  -- Create a randomly initialized data array.
810
  ---------------------------------------------------------------------------
811
  procedure CreateRandomPayload(
812
    variable payload : out HalfwordArray;
813
    variable seed1 : inout positive;
814
    variable seed2 : inout positive) is
815
    variable rand: real;
816
    variable int_rand: integer;
817
    variable stim: std_logic_vector(7 downto 0);
818
  begin
819
    for i in payload'range loop
820
      uniform(seed1, seed2, rand);
821
      int_rand := integer(trunc(rand*256.0));
822
      payload(i)(7 downto 0) := std_logic_vector(to_unsigned(int_rand, 8));
823
      uniform(seed1, seed2, rand);
824
      int_rand := integer(trunc(rand*256.0));
825
      payload(i)(15 downto 8) := std_logic_vector(to_unsigned(int_rand, 8));
826
    end loop;
827
  end procedure;
828
 
829
  procedure CreateRandomPayload(
830
    variable payload : out DoublewordArray;
831
    variable seed1 : inout positive;
832
    variable seed2 : inout positive) is
833
    variable rand: real;
834
    variable int_rand: integer;
835
    variable stim: std_logic_vector(7 downto 0);
836
  begin
837
    for i in payload'range loop
838
      uniform(seed1, seed2, rand);
839
      int_rand := integer(trunc(rand*256.0));
840
      payload(i)(7 downto 0) := std_logic_vector(to_unsigned(int_rand, 8));
841
      uniform(seed1, seed2, rand);
842
      int_rand := integer(trunc(rand*256.0));
843
      payload(i)(15 downto 8) := std_logic_vector(to_unsigned(int_rand, 8));
844
      uniform(seed1, seed2, rand);
845
      int_rand := integer(trunc(rand*256.0));
846
      payload(i)(23 downto 16) := std_logic_vector(to_unsigned(int_rand, 8));
847
      uniform(seed1, seed2, rand);
848
      int_rand := integer(trunc(rand*256.0));
849
      payload(i)(31 downto 24) := std_logic_vector(to_unsigned(int_rand, 8));
850
      uniform(seed1, seed2, rand);
851
      int_rand := integer(trunc(rand*256.0));
852
      payload(i)(39 downto 32) := std_logic_vector(to_unsigned(int_rand, 8));
853
      uniform(seed1, seed2, rand);
854
      int_rand := integer(trunc(rand*256.0));
855
      payload(i)(47 downto 40) := std_logic_vector(to_unsigned(int_rand, 8));
856
      uniform(seed1, seed2, rand);
857
      int_rand := integer(trunc(rand*256.0));
858
      payload(i)(55 downto 48) := std_logic_vector(to_unsigned(int_rand, 8));
859
      uniform(seed1, seed2, rand);
860
      int_rand := integer(trunc(rand*256.0));
861
      payload(i)(63 downto 56) := std_logic_vector(to_unsigned(int_rand, 8));
862
    end loop;
863
  end procedure;
864
  ---------------------------------------------------------------------------
865
  -- Create a generic RapidIO frame.
866
  ---------------------------------------------------------------------------
867
  function RioFrameCreate(
868
    constant ackId : in std_logic_vector(4 downto 0);
869
    constant vc : in std_logic;
870
    constant crf : in std_logic;
871
    constant prio : in std_logic_vector(1 downto 0);
872
    constant tt : in std_logic_vector(1 downto 0);
873
    constant ftype : in std_logic_vector(3 downto 0);
874
    constant sourceId : in std_logic_vector(15 downto 0);
875
    constant destId : in std_logic_vector(15 downto 0);
876
    constant payload : in RioPayload) return RioFrame is
877
    variable frame : RioFrame;
878
    variable result : HalfwordArray(0 to 137);
879
    variable crc : std_logic_vector(15 downto 0) := x"ffff";
880
  begin
881
    -- Add the header and addresses.
882
    result(0) := ackId & "0" & vc & crf & prio & tt & ftype;
883
    result(1) := destId;
884
    result(2) := sourceId;
885
 
886
    -- Update the calculated CRC with the header contents.
887
    crc := Crc16("00000" & result(0)(10 downto 0), crc);
888
    crc := Crc16(result(1), crc);
889
    crc := Crc16(result(2), crc);
890
 
891
    -- Check if a single CRC should be added or two.
892
    if (payload.length <= 37) then
893
      -- Single CRC.
894
      for i in 0 to payload.length-1 loop
895
        result(i+3) := payload.data(i);
896
        crc := Crc16(payload.data(i), crc);
897
      end loop;
898
      result(payload.length+3) := crc;
899
 
900
      -- Check if paddning is needed to make the payload even 32-bit.
901
      if ((payload.length mod 2) = 1) then
902
        result(payload.length+4) := x"0000";
903
        frame.length := (payload.length+5) / 2;
904
      else
905
        frame.length := (payload.length+4) / 2;
906
      end if;
907
    else
908
      -- Double CRC.
909
      for i in 0 to 36 loop
910
        result(i+3) := payload.data(i);
911
        crc := Crc16(payload.data(i), crc);
912
      end loop;
913
 
914
      -- Add in-the-middle crc.
915
      result(40) := crc;
916
      crc := Crc16(crc, crc);
917
 
918
      for i in 37 to payload.length-1 loop
919
        result(i+4) := payload.data(i);
920
        crc := Crc16(payload.data(i), crc);
921
      end loop;
922
      result(payload.length+4) := crc;
923
 
924
      -- Check if paddning is needed to make the payload even 32-bit.
925
      if ((payload.length mod 2) = 0) then
926
        result(payload.length+5) := x"0000";
927
        frame.length := (payload.length+6) / 2;
928
      else
929
        frame.length := (payload.length+5) / 2;
930
      end if;
931
    end if;
932
 
933
    -- Update the result length.
934
    for i in 0 to frame.length-1 loop
935
      frame.payload(i) := result(2*i) & result(2*i+1);
936
    end loop;
937
 
938
    return frame;
939
  end function;
940
 
941
  -----------------------------------------------------------------------------
942
  -- 
943
  -----------------------------------------------------------------------------
944
  function RioNwrite(
945
    constant wrsize : in std_logic_vector(3 downto 0);
946
    constant address : in std_logic_vector(28 downto 0);
947
    constant wdptr : in std_logic;
948
    constant xamsbs : in std_logic_vector(1 downto 0);
949
    constant dataLength : in natural range 1 to 32;
950
    constant data : in DoublewordArray(0 to 31))
951
    return RioPayload is
952
    variable payload : RioPayload;
953
  begin
954
    payload.data(0)(15 downto 12) := "0100";
955
    payload.data(0)(11 downto 8) := wrsize;
956
    payload.data(0)(7 downto 0) := (others=>'0');
957
 
958
    payload.data(1) := address(28 downto 13);
959
 
960
    payload.data(2)(15 downto 3) := address(12 downto 0);
961
    payload.data(2)(2) := wdptr;
962
    payload.data(2)(1 downto 0) := xamsbs;
963
 
964
    for i in 0 to dataLength-1 loop
965
      payload.data(3+4*i) := data(i)(63 downto 48);
966
      payload.data(4+4*i) := data(i)(47 downto 32);
967
      payload.data(5+4*i) := data(i)(31 downto 16);
968
      payload.data(6+4*i) := data(i)(15 downto 0);
969
    end loop;
970
 
971
    payload.length := 3 + 4*dataLength;
972
 
973
    return payload;
974
  end function;
975
 
976
  -----------------------------------------------------------------------------
977
  -- 
978
  -----------------------------------------------------------------------------
979
  function RioNwriteR(
980
    constant wrsize : in std_logic_vector(3 downto 0);
981
    constant tid : in std_logic_vector(7 downto 0);
982
    constant address : in std_logic_vector(28 downto 0);
983
    constant wdptr : in std_logic;
984
    constant xamsbs : in std_logic_vector(1 downto 0);
985
    constant dataLength : in natural range 1 to 32;
986
    constant data : in DoublewordArray(0 to 31))
987
    return RioPayload is
988
    variable payload : RioPayload;
989
  begin
990
    payload.data(0)(15 downto 12) := "0101";
991
    payload.data(0)(11 downto 8) := wrsize;
992
    payload.data(0)(7 downto 0) := tid;
993
 
994
    payload.data(1) := address(28 downto 13);
995
 
996
    payload.data(2)(15 downto 3) := address(12 downto 0);
997
    payload.data(2)(2) := wdptr;
998
    payload.data(2)(1 downto 0) := xamsbs;
999
 
1000
    for i in 0 to dataLength-1 loop
1001
      payload.data(3+4*i) := data(i)(63 downto 48);
1002
      payload.data(4+4*i) := data(i)(47 downto 32);
1003
      payload.data(5+4*i) := data(i)(31 downto 16);
1004
      payload.data(6+4*i) := data(i)(15 downto 0);
1005
    end loop;
1006
 
1007
    payload.length := 3 + 4*dataLength;
1008
 
1009
    return payload;
1010
  end function;
1011
 
1012
  -----------------------------------------------------------------------------
1013
  -- 
1014
  -----------------------------------------------------------------------------
1015
  function RioNread(
1016
    constant rdsize : in std_logic_vector(3 downto 0);
1017
    constant tid : in std_logic_vector(7 downto 0);
1018
    constant address : in std_logic_vector(28 downto 0);
1019
    constant wdptr : in std_logic;
1020
    constant xamsbs : in std_logic_vector(1 downto 0))
1021
    return RioPayload is
1022
    variable payload : RioPayload;
1023
  begin
1024
    payload.data(0)(15 downto 12) := "0100";
1025
    payload.data(0)(11 downto 8) := rdsize;
1026
    payload.data(0)(7 downto 0) := tid;
1027
 
1028
    payload.data(1) := address(28 downto 13);
1029
 
1030
    payload.data(2)(15 downto 3) := address(12 downto 0);
1031
    payload.data(2)(2) := wdptr;
1032
    payload.data(2)(1 downto 0) := xamsbs;
1033
 
1034
    payload.length := 3;
1035
 
1036
    return payload;
1037
  end function;
1038
 
1039
  ---------------------------------------------------------------------------
1040
  -- Create a RESPONSE RapidIO frame.
1041
  ---------------------------------------------------------------------------
1042
  function RioResponse(
1043
    constant status : in std_logic_vector(3 downto 0);
1044
    constant tid : in std_logic_vector(7 downto 0);
1045
    constant dataLength : in natural range 0 to 32;
1046
    constant data : in DoublewordArray(0 to 31))
1047
    return RioPayload is
1048
    variable payload : RioPayload;
1049
  begin
1050
    payload.data(0)(11 downto 8) := status;
1051
    payload.data(0)(7 downto 0) := tid;
1052
 
1053
    if (dataLength = 0) then
1054
      payload.data(0)(15 downto 12) := "0000";
1055
      payload.length := 1;
1056
    else
1057
      payload.data(0)(15 downto 12) := "1000";
1058
 
1059
      for i in 0 to dataLength-1 loop
1060
        payload.data(1+4*i) := data(i)(63 downto 48);
1061
        payload.data(2+4*i) := data(i)(47 downto 32);
1062
        payload.data(3+4*i) := data(i)(31 downto 16);
1063
        payload.data(4+4*i) := data(i)(15 downto 0);
1064
      end loop;
1065
 
1066
      payload.length := 1 + 4*dataLength;
1067
    end if;
1068
 
1069
    return payload;
1070
  end function;
1071
 
1072
  ---------------------------------------------------------------------------
1073
  -- Create a Maintenance RapidIO frame.
1074
  ---------------------------------------------------------------------------
1075
  function RioMaintenance(
1076
    constant transaction : in std_logic_vector(3 downto 0);
1077
    constant size : in std_logic_vector(3 downto 0);
1078
    constant tid : in std_logic_vector(7 downto 0);
1079
    constant hopCount : in std_logic_vector(7 downto 0);
1080
    constant configOffset : in std_logic_vector(20 downto 0);
1081
    constant wdptr : in std_logic;
1082
    constant dataLength : in natural range 0 to 8;
1083
    constant data : in DoublewordArray(0 to 7))
1084
    return RioPayload is
1085
    variable payload : RioPayload;
1086
  begin
1087
    payload.data(0)(15 downto 12) := transaction;
1088
    payload.data(0)(11 downto 8) := size;
1089
    payload.data(0)(7 downto 0) := tid;
1090
 
1091
    payload.data(1)(15 downto 8) := hopCount;
1092
    payload.data(1)(7 downto 0) := configOffset(20 downto 13);
1093
 
1094
    payload.data(2)(15 downto 3) := configOffset(12 downto 0);
1095
    payload.data(2)(2) := wdptr;
1096
    payload.data(2)(1 downto 0) := "00";
1097
 
1098
    if (dataLength = 0) then
1099
      payload.length := 3;
1100
    else
1101
      for i in 0 to dataLength-1 loop
1102
        payload.data(3+4*i) := data(i)(63 downto 48);
1103
        payload.data(4+4*i) := data(i)(47 downto 32);
1104
        payload.data(5+4*i) := data(i)(31 downto 16);
1105
        payload.data(6+4*i) := data(i)(15 downto 0);
1106
      end loop;
1107
 
1108
      payload.length := 3 + 4*dataLength;
1109
    end if;
1110
 
1111
    return payload;
1112
  end function;
1113
 
1114
  -----------------------------------------------------------------------------
1115
  -- Function to convert a std_logic_vector to a string.
1116
  -----------------------------------------------------------------------------
1117
  function byteToString(constant byte : std_logic_vector(7 downto 0))
1118
    return string is
1119
    constant table : string(1 to 16) := "0123456789abcdef";
1120
    variable returnValue : string(1 to 2);
1121
  begin
1122
    returnValue(1) := table(to_integer(unsigned(byte(7 downto 4))) + 1);
1123
    returnValue(2) := table(to_integer(unsigned(byte(3 downto 0))) + 1);
1124
    return returnValue;
1125
  end function;
1126
 
1127 47 magro732
end package body;
1128
 
1129
 
1130
 
1131
 
1132
-------------------------------------------------------------------------------
1133
-- 
1134
-------------------------------------------------------------------------------
1135
library ieee;
1136
use ieee.std_logic_1164.all;
1137
use ieee.numeric_std.all;
1138
library std;
1139
use std.textio.all;
1140
use work.rio_common.all;
1141
use work.TestPortPackage.all;
1142
 
1143
 
1144
-------------------------------------------------------------------------------
1145
-- 
1146
-------------------------------------------------------------------------------
1147
entity TestPortPacketBuffer is
1148
  generic(
1149
    READ_CONTENT_END_DATA_VALID : boolean := true);
1150
  port(
1151
    clk : in std_logic;
1152
    areset_n : in std_logic;
1153
 
1154
    readEmpty_o : out std_logic;
1155
    readWrite_i : in std_logic;
1156
    readMessage_i : in TestPortMessagePacketBuffer;
1157
    readAck_o : out std_logic;
1158
 
1159
    writeEmpty_o : out std_logic;
1160
    writeWrite_i : in std_logic;
1161
    writeMessage_i : in TestPortMessagePacketBuffer;
1162
    writeAck_o : out std_logic;
1163
 
1164
    readFrameEmpty_o : out std_logic;
1165
    readFrame_i : in std_logic;
1166
    readFrameRestart_i : in std_logic;
1167
    readFrameAborted_o : out std_logic;
1168
    readWindowEmpty_o : out std_logic;
1169
    readWindowReset_i : in std_logic;
1170
    readWindowNext_i : in std_logic;
1171
    readContentEmpty_o : out std_logic;
1172
    readContent_i : in std_logic;
1173
    readContentEnd_o : out std_logic;
1174
    readContentData_o : out std_logic_vector(31 downto 0);
1175
 
1176
    -- writeFrameFull_o is missing yes, but you can control it from the testbench directly
1177
    -- instead.
1178
    writeFrame_i : in std_logic;
1179
    writeFrameAbort_i : in std_logic;
1180
    writeContent_i : in std_logic;
1181
    writeContentData_i : in std_logic_vector(31 downto 0));
1182
end entity;
1183
 
1184
 
1185
-------------------------------------------------------------------------------
1186
-- 
1187
-------------------------------------------------------------------------------
1188
architecture TestPortPacketBufferPortImpl of TestPortPacketBuffer is
1189 48 magro732
  constant QUEUE_SIZE : natural := 255;
1190 47 magro732
  type QueueArray is array (natural range <>) of TestPortMessagePacketBuffer;
1191
 
1192
  function QueueIndexInc(constant i : natural) return natural is
1193
    variable returnValue : natural;
1194
  begin
1195
    if(i = QUEUE_SIZE) then
1196
      returnValue := 0;
1197
    else
1198
      returnValue := i + 1;
1199
    end if;
1200
    return returnValue;
1201
  end function;
1202
 
1203
begin
1204
 
1205
  -----------------------------------------------------------------------------
1206
  -- 
1207
  -----------------------------------------------------------------------------
1208
  Reader: process
1209
    variable frameQueue : QueueArray(0 to QUEUE_SIZE);
1210
    variable front, back, window : natural range 0 to QUEUE_SIZE;
1211
    variable frameIndex : natural;
1212
  begin
1213
    wait until areset_n = '1';
1214
 
1215
    readFrameEmpty_o <= '1';
1216
    readFrameAborted_o <= '0';
1217
    readWindowEmpty_o <= '1';
1218
    readContentEmpty_o <= '1';
1219
    readContentEnd_o <= '0';
1220
    readContentData_o <= (others=>'0');
1221
 
1222
    front := 0;
1223
    back := 0;
1224
    window := 0;
1225
    frameIndex := 0;
1226
    readEmpty_o <= '1';
1227
    readAck_o <= '0';
1228
 
1229
    loop
1230
      wait until clk = '1' or readWrite_i = '1';
1231
 
1232
      if (clk'event) then
1233
        if (readFrame_i = '1') then
1234 48 magro732
          if ((not frameQueue(back).willAbort) and (frameIndex < frameQueue(back).frame.length)) then
1235
            TestError("READ:BACK:reading unfinished frame");
1236
          end if;
1237 47 magro732
          if (back /= front) then
1238
            back := QueueIndexInc(back);
1239
          else
1240
            TestError("READ:BACK:reading when no frame is present");
1241
          end if;
1242
        end if;
1243
 
1244
        if (readFrameRestart_i = '1') then
1245
          frameIndex := 0;
1246
        end if;
1247
 
1248
        if (readWindowReset_i = '1') then
1249
          window := back;
1250
          frameIndex := 0;
1251
        end if;
1252
 
1253
        if (readWindowNext_i = '1') then
1254
          if (window /= front) then
1255
            window := QueueIndexInc(window);
1256
            frameIndex := 0;
1257
          else
1258
            TestError("READ:WINDOW:reading when no frame is present");
1259
          end if;
1260
        end if;
1261
 
1262
        if (readContent_i = '1') then
1263
          if (back /= front) then
1264
            if (READ_CONTENT_END_DATA_VALID) then
1265
              if (frameIndex < frameQueue(window).frame.length) then
1266
                readContentData_o <= frameQueue(window).frame.payload(frameIndex);
1267
                frameIndex := frameIndex + 1;
1268
                if (frameIndex = frameQueue(window).frame.length) then
1269
                  readContentEnd_o <= '1';
1270
                else
1271
                  readContentEnd_o <= '0';
1272
                end if;
1273
              else
1274
                TestError("READ:CONTENT:reading when frame has ended");
1275
              end if;
1276
            else
1277
              if (frameIndex < frameQueue(window).frame.length) then
1278
                readContentData_o <= frameQueue(window).frame.payload(frameIndex);
1279
                readContentEnd_o <= '0';
1280
                frameIndex := frameIndex + 1;
1281
              elsif (frameIndex = frameQueue(window).frame.length) then
1282
                readContentData_o <= (others=>'U');
1283
                readContentEnd_o <= '1';
1284
              else
1285
                TestError("READ:CONTENT:reading when frame has ended");
1286
              end if;
1287
            end if;
1288
          else
1289
            TestError("READ:CONTENT:reading when no frame is present");
1290
          end if;
1291
        end if;
1292
 
1293
        if (front = back) then
1294
          readFrameEmpty_o <= '1';
1295
        else
1296
          readFrameEmpty_o <= '0';
1297
        end if;
1298
 
1299
        if (front = window) then
1300
          readWindowEmpty_o <= '1';
1301
          readContentEmpty_o <= '1';
1302
        else
1303
          readWindowEmpty_o <= '0';
1304
          if (frameIndex /= frameQueue(window).frame.length) then
1305
            readContentEmpty_o <= '0';
1306
          else
1307
            readContentEmpty_o <= '1';
1308
          end if;
1309
        end if;
1310
 
1311
        if (front = back) then
1312
          readEmpty_o <= '1';
1313
        else
1314
          readEmpty_o <= '0';
1315
        end if;
1316
      elsif (readWrite_i'event) then
1317
        frameQueue(front) := readMessage_i;
1318
        front := QueueIndexInc(front);
1319 48 magro732
        if (front = back) then
1320
          TestError("Queue full");
1321
        end if;
1322 47 magro732
 
1323
        readEmpty_o <= '0';
1324
        readAck_o <= '1';
1325
        wait until readWrite_i = '0';
1326
        readAck_o <= '0';
1327
      end if;
1328
    end loop;
1329
  end process;
1330
 
1331
  -----------------------------------------------------------------------------
1332
  -- 
1333
  -----------------------------------------------------------------------------
1334
  Writer: process
1335
    variable frameQueue : QueueArray(0 to QUEUE_SIZE);
1336
    variable front, back : natural range 0 to QUEUE_SIZE;
1337
    variable frameIndex : natural range 0 to 69;
1338
  begin
1339
    wait until areset_n = '1';
1340
 
1341
    writeEmpty_o <= '1';
1342
    writeAck_o <= '0';
1343
 
1344
    front := 0;
1345
    back := 0;
1346
    frameIndex := 0;
1347
 
1348
    loop
1349
      wait until clk = '1' or writeWrite_i = '1';
1350
 
1351
      if (clk'event) then
1352
 
1353
        if (writeFrame_i = '1') then
1354
          if (frameIndex = 0) then
1355
            TestError("WRITE:Empty frame written.");
1356
          end if;
1357
          if (frameIndex /= frameQueue(back).frame.length) then
1358
            TestError("WRITE:Frame with unmatching length was written.");
1359
          end if;
1360
          if (back /= front) then
1361
            back := QueueIndexInc(back);
1362
          else
1363
            TestError("WRITE:Unexpected frame written.");
1364
          end if;
1365
          frameIndex := 0;
1366
        end if;
1367
 
1368
        if (writeFrameAbort_i = '1') then
1369
          if (back /= front) then
1370
            if (frameQueue(back).willAbort) then
1371
              TestCompare(frameIndex,
1372
                          frameQueue(back).frame.length,
1373
                          "frameIndex abort");
1374
              back := QueueIndexInc(back);
1375
            else
1376
              TestError("WRITE:Not expecting this frame to abort.");
1377
            end if;
1378
          end if;
1379
          frameIndex := 0;
1380
        end if;
1381
 
1382
        if (writeContent_i = '1') then
1383
          if (frameIndex < frameQueue(back).frame.length) then
1384
            TestCompare(writeContentData_i,
1385
                        frameQueue(back).frame.payload(frameIndex),
1386
                        "frame content");
1387
            frameIndex := frameIndex + 1;
1388
          else
1389
            TestError("WRITE:Receiving more frame content than expected.");
1390
          end if;
1391
        end if;
1392
 
1393
        if (front = back) then
1394
          writeEmpty_o <= '1';
1395
        else
1396
          writeEmpty_o <= '0';
1397
        end if;
1398
      elsif (writeWrite_i'event) then
1399
        frameQueue(front) := writeMessage_i;
1400
        front := QueueIndexInc(front);
1401 48 magro732
        if (front = back) then
1402
          TestError("Queue full");
1403
        end if;
1404 47 magro732
 
1405
        writeEmpty_o <= '0';
1406
        writeAck_o <= '1';
1407
        wait until writeWrite_i = '0';
1408
        writeAck_o <= '0';
1409
      end if;
1410
    end loop;
1411
  end process;
1412
 
1413
end architecture;
1414
 
1415
 
1416
 
1417
-------------------------------------------------------------------------------
1418
-- 
1419
-------------------------------------------------------------------------------
1420
library ieee;
1421
use ieee.std_logic_1164.all;
1422
use ieee.numeric_std.all;
1423
library std;
1424
use std.textio.all;
1425
use work.rio_common.all;
1426
use work.TestPortPackage.all;
1427
 
1428
 
1429
-------------------------------------------------------------------------------
1430
-- 
1431
-------------------------------------------------------------------------------
1432
entity TestPortWishbone is
1433
  generic(
1434
    ADDRESS_WIDTH : natural := 31;
1435
    SEL_WIDTH : natural := 8;
1436
    DATA_WIDTH : natural := 64);
1437
  port(
1438
    clk : in std_logic;
1439
    areset_n : in std_logic;
1440
 
1441
    messageEmpty_o : out std_logic;
1442
    messageWrite_i : in std_logic;
1443
    message_i : in TestPortMessageWishbone;
1444
    messageAck_o : out std_logic;
1445
 
1446
    cyc_i : in std_logic;
1447
    stb_i : in std_logic;
1448
    we_i : in std_logic;
1449
    adr_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
1450
    sel_i : in std_logic_vector(SEL_WIDTH-1 downto 0);
1451
    dat_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
1452
    dat_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
1453
    err_o : out std_logic;
1454
    ack_o : out std_logic);
1455
end entity;
1456
 
1457
 
1458
-------------------------------------------------------------------------------
1459
-- 
1460
-------------------------------------------------------------------------------
1461
architecture TestPortWishboneImpl of TestPortWishbone is
1462
  constant QUEUE_SIZE : natural := 63;
1463
  type QueueArray is array (natural range <>) of TestPortMessageWishbone;
1464
 
1465
  function QueueIndexInc(constant i : natural) return natural is
1466
    variable returnValue : natural;
1467
  begin
1468
    if(i = QUEUE_SIZE) then
1469
      returnValue := 0;
1470
    else
1471
      returnValue := i + 1;
1472
    end if;
1473
    return returnValue;
1474
  end function;
1475
 
1476
begin
1477
 
1478
  -----------------------------------------------------------------------------
1479
  -- 
1480
  -----------------------------------------------------------------------------
1481
  Slave: process
1482
    variable queue : QueueArray(0 to QUEUE_SIZE);
1483
    variable front, back : natural range 0 to QUEUE_SIZE;
1484
    variable latencyCounter : natural;
1485
    variable activeCycle : boolean;
1486
  begin
1487
    wait until areset_n = '1';
1488
 
1489
    messageEmpty_o <= '1';
1490
    messageAck_o <= '0';
1491
 
1492
    dat_o <= (others=>'U');
1493
    err_o <= '0';
1494
    ack_o <= '0';
1495
 
1496
    front := 0;
1497
    back := 0;
1498
    latencyCounter := 0;
1499
    activeCycle := false;
1500
 
1501
    loop
1502
      wait until clk = '1' or messageWrite_i = '1';
1503
 
1504
      if (clk'event) then
1505
        if (cyc_i = '1') then
1506
          if (front /= back) then
1507
            if (stb_i = '1') then
1508
              if (latencyCounter <= queue(back).latency) then
1509
                TestCompare(stb_i, '1', "stb_i");
1510
                if (queue(back).writeAccess) then
1511
                  TestCompare(we_i, '1', "we_i");
1512
                else
1513
                  TestCompare(we_i, '0', "we_i");
1514
                end if;
1515
                TestCompare(adr_i, queue(back).address(ADDRESS_WIDTH-1 downto 0), "adr_i");
1516
                TestCompare(sel_i, queue(back).byteSelect(SEL_WIDTH-1 downto 0), "sel_i");
1517
                if (queue(back).writeAccess) then
1518
                  TestCompare(dat_i, queue(back).data(DATA_WIDTH-1 downto 0), "dat_i");
1519
                end if;
1520
              end if;
1521
 
1522
              if (latencyCounter < queue(back).latency) then
1523
                dat_o <= (others=>'U');
1524
                ack_o <= '0';
1525
                latencyCounter := latencyCounter + 1;
1526
              elsif (latencyCounter = queue(back).latency) then
1527
                if (queue(back).writeAccess) then
1528
                  dat_o <= (others=>'U');
1529
                else
1530
                  dat_o <= queue(back).data(DATA_WIDTH-1 downto 0);
1531
                end if;
1532
                ack_o <= '1';
1533
                latencyCounter := latencyCounter + 1;
1534
              else
1535
                dat_o <= (others=>'U');
1536
                ack_o <= '0';
1537
                latencyCounter := 0;
1538
                activeCycle := queue(back).continue;
1539
                back := QueueIndexInc(back);
1540
              end if;
1541
            end if;
1542
          else
1543
            TestError("Unexpected access.");
1544
          end if;
1545
        else
1546
          if (activeCycle or (latencyCounter /= 0)) then
1547
            TestError("Cycle unexpectedly aborted.");
1548
            latencyCounter := 0;
1549
          end if;
1550
          TestCompare(stb_i, '0', "stb_i");
1551
        end if;
1552
 
1553
        if (front = back) then
1554
          messageEmpty_o <= '1';
1555
        else
1556
          messageEmpty_o <= '0';
1557
        end if;
1558
      elsif (messageWrite_i'event) then
1559
        queue(front) := message_i;
1560
        front := QueueIndexInc(front);
1561
 
1562
        messageEmpty_o <= '0';
1563
        messageAck_o <= '1';
1564
        wait until messageWrite_i = '0';
1565
        messageAck_o <= '0';
1566
      end if;
1567
    end loop;
1568
  end process;
1569
 
1570
end architecture;
1571
 
1572
 

powered by: WebSVN 2.1.0

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