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 47

Go to most recent revision | 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
use work.rio_common.all;
52
 
53
-------------------------------------------------------------------------------
54
-- 
55
-------------------------------------------------------------------------------
56
package TestPortPackage is
57
  constant ADDRESS_WIDTH_MAX : natural := 64;
58
  constant DATA_WIDTH_MAX : natural := 64;
59
  constant SEL_WIDTH_MAX : natural := 8;
60
 
61
  type TestPortMessageWishbone is record
62
    writeAccess : boolean;
63
    address : std_logic_vector(ADDRESS_WIDTH_MAX-1 downto 0);
64
    byteSelect : std_logic_vector(SEL_WIDTH_MAX-1 downto 0);
65
    data : std_logic_vector(DATA_WIDTH_MAX-1 downto 0);
66
    continue : boolean;
67
    latency : natural;
68
  end record;
69
  type TestPortMessageWishboneArray is
70
    array (natural range <>) of TestPortMessageWishbone;
71
 
72
  type TestPortMessageSymbol is record
73
    symbolType : std_logic_vector(1 downto 0);
74
    symbolContent : std_logic_vector(31 downto 0);
75
    ignoreIdle : boolean;
76
  end record;
77
  type TestPortMessageSymbolArray is
78
    array (natural range <>) of TestPortMessageSymbol;
79
 
80
  type TestPortMessagePacketBuffer is record
81
    frame : RioFrame;
82
    willAbort : boolean;
83
  end record;
84
  type TestPortMessagePacketBufferArray is
85
    array (natural range <>) of TestPortMessagePacketBuffer;
86
 
87
  -----------------------------------------------------------------------------
88
  -- 
89
  -----------------------------------------------------------------------------
90
 
91
  component TestPortWishbone is
92
    generic(
93
      ADDRESS_WIDTH : natural := 31;
94
      SEL_WIDTH : natural := 8;
95
      DATA_WIDTH : natural := 64);
96
    port(
97
      clk : in std_logic;
98
      areset_n : in std_logic;
99
 
100
      messageEmpty_o : out std_logic;
101
      messageWrite_i : in std_logic;
102
      message_i : in TestPortMessageWishbone;
103
      messageAck_o : out std_logic;
104
 
105
      cyc_i : in std_logic;
106
      stb_i : in std_logic;
107
      we_i : in std_logic;
108
      adr_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
109
      sel_i : in std_logic_vector(SEL_WIDTH-1 downto 0);
110
      dat_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
111
      dat_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
112
      err_o : out std_logic;
113
      ack_o : out std_logic);
114
  end component;
115
 
116
  component TestPortPacketBuffer is
117
    generic(
118
      READ_CONTENT_END_DATA_VALID : boolean := true);
119
    port(
120
      clk : in std_logic;
121
      areset_n : in std_logic;
122
 
123
      readEmpty_o : out std_logic;
124
      readWrite_i : in std_logic;
125
      readMessage_i : in TestPortMessagePacketBuffer;
126
      readAck_o : out std_logic;
127
 
128
      writeEmpty_o : out std_logic;
129
      writeWrite_i : in std_logic;
130
      writeMessage_i : in TestPortMessagePacketBuffer;
131
      writeAck_o : out std_logic;
132
 
133
      readFrameEmpty_o : out std_logic;
134
      readFrame_i : in std_logic;
135
      readFrameRestart_i : in std_logic;
136
      readFrameAborted_o : out std_logic;
137
      readWindowEmpty_o : out std_logic;
138
      readWindowReset_i : in std_logic;
139
      readWindowNext_i : in std_logic;
140
      readContentEmpty_o : out std_logic;
141
      readContent_i : in std_logic;
142
      readContentEnd_o : out std_logic;
143
      readContentData_o : out std_logic_vector(31 downto 0);
144
 
145
      writeFrame_i : in std_logic;
146
      writeFrameAbort_i : in std_logic;
147
      writeContent_i : in std_logic;
148
      writeContentData_i : in std_logic_vector(31 downto 0));
149
  end component;
150
 
151
  -----------------------------------------------------------------------------
152
  -- 
153
  -----------------------------------------------------------------------------
154
  procedure TestPortWishboneWrite(
155
    signal writeSignal : out std_logic;
156
    signal messageSignal : out TestPortMessageWishbone;
157
    signal ackSignal : in std_logic;
158
    constant writeAccess : in boolean;
159
    constant address : in std_logic_vector(ADDRESS_WIDTH_MAX-1 downto 0);
160
    constant byteSelect : in std_logic_vector(SEL_WIDTH_MAX-1 downto 0);
161
    constant data : in std_logic_vector(DATA_WIDTH_MAX-1 downto 0);
162
    constant continue : in boolean := false;
163
    constant latency : in natural := 0);
164
 
165
  procedure TestPortPacketBufferWrite(
166
    signal writeSignal : out std_logic;
167
    signal messageSignal : out TestPortMessagePacketBuffer;
168
    signal ackSignal : in std_logic;
169
    constant frame : in RioFrame;
170
    constant willAbort : in boolean := false);
171
 
172
end package;
173
 
174
-------------------------------------------------------------------------------
175
-- 
176
-------------------------------------------------------------------------------
177
package body TestPortPackage is
178
 
179
  -----------------------------------------------------------------------------
180
  -- 
181
  -----------------------------------------------------------------------------
182
  procedure TestPortWishboneWrite(
183
    signal writeSignal : out std_logic;
184
    signal messageSignal : out TestPortMessageWishbone;
185
    signal ackSignal : in std_logic;
186
    constant writeAccess : in boolean;
187
    constant address : in std_logic_vector(ADDRESS_WIDTH_MAX-1 downto 0);
188
    constant byteSelect : in std_logic_vector(SEL_WIDTH_MAX-1 downto 0);
189
    constant data : in std_logic_vector(DATA_WIDTH_MAX-1 downto 0);
190
    constant continue : in boolean := false;
191
    constant latency : in natural := 0) is
192
  begin
193
    writeSignal <= '1';
194
    messageSignal.writeAccess <= writeAccess;
195
    messageSignal.address <= address;
196
    messageSignal.byteSelect <= byteSelect;
197
    messageSignal.data <= data;
198
    messageSignal.continue <= continue;
199
    messageSignal.latency <= latency;
200
    wait until ackSignal = '1';
201
    writeSignal <= '0';
202
    wait until ackSignal = '0';
203
  end procedure;
204
 
205
  -----------------------------------------------------------------------------
206
  -- 
207
  -----------------------------------------------------------------------------
208
  procedure TestPortPacketBufferWrite(
209
    signal writeSignal : out std_logic;
210
    signal messageSignal : out TestPortMessagePacketBuffer;
211
    signal ackSignal : in std_logic;
212
    constant frame : in RioFrame;
213
    constant willAbort : in boolean := false) is
214
  begin
215
    writeSignal <= '1';
216
    messageSignal.frame <= frame;
217
    messageSignal.willAbort <= willAbort;
218
    wait until ackSignal = '1';
219
    writeSignal <= '0';
220
    wait until ackSignal = '0';
221
  end procedure;
222
 
223
end package body;
224
 
225
 
226
 
227
 
228
-------------------------------------------------------------------------------
229
-- 
230
-------------------------------------------------------------------------------
231
library ieee;
232
use ieee.std_logic_1164.all;
233
use ieee.numeric_std.all;
234
library std;
235
use std.textio.all;
236
use work.rio_common.all;
237
use work.TestPortPackage.all;
238
 
239
 
240
-------------------------------------------------------------------------------
241
-- 
242
-------------------------------------------------------------------------------
243
entity TestPortPacketBuffer is
244
  generic(
245
    READ_CONTENT_END_DATA_VALID : boolean := true);
246
  port(
247
    clk : in std_logic;
248
    areset_n : in std_logic;
249
 
250
    readEmpty_o : out std_logic;
251
    readWrite_i : in std_logic;
252
    readMessage_i : in TestPortMessagePacketBuffer;
253
    readAck_o : out std_logic;
254
 
255
    writeEmpty_o : out std_logic;
256
    writeWrite_i : in std_logic;
257
    writeMessage_i : in TestPortMessagePacketBuffer;
258
    writeAck_o : out std_logic;
259
 
260
    readFrameEmpty_o : out std_logic;
261
    readFrame_i : in std_logic;
262
    readFrameRestart_i : in std_logic;
263
    readFrameAborted_o : out std_logic;
264
    readWindowEmpty_o : out std_logic;
265
    readWindowReset_i : in std_logic;
266
    readWindowNext_i : in std_logic;
267
    readContentEmpty_o : out std_logic;
268
    readContent_i : in std_logic;
269
    readContentEnd_o : out std_logic;
270
    readContentData_o : out std_logic_vector(31 downto 0);
271
 
272
    -- writeFrameFull_o is missing yes, but you can control it from the testbench directly
273
    -- instead.
274
    writeFrame_i : in std_logic;
275
    writeFrameAbort_i : in std_logic;
276
    writeContent_i : in std_logic;
277
    writeContentData_i : in std_logic_vector(31 downto 0));
278
end entity;
279
 
280
 
281
-------------------------------------------------------------------------------
282
-- 
283
-------------------------------------------------------------------------------
284
architecture TestPortPacketBufferPortImpl of TestPortPacketBuffer is
285
  constant QUEUE_SIZE : natural := 63;
286
  type QueueArray is array (natural range <>) of TestPortMessagePacketBuffer;
287
 
288
  function QueueIndexInc(constant i : natural) return natural is
289
    variable returnValue : natural;
290
  begin
291
    if(i = QUEUE_SIZE) then
292
      returnValue := 0;
293
    else
294
      returnValue := i + 1;
295
    end if;
296
    return returnValue;
297
  end function;
298
 
299
begin
300
 
301
  -----------------------------------------------------------------------------
302
  -- 
303
  -----------------------------------------------------------------------------
304
  Reader: process
305
    variable frameQueue : QueueArray(0 to QUEUE_SIZE);
306
    variable front, back, window : natural range 0 to QUEUE_SIZE;
307
    variable frameIndex : natural;
308
  begin
309
    wait until areset_n = '1';
310
 
311
    readFrameEmpty_o <= '1';
312
    readFrameAborted_o <= '0';
313
    readWindowEmpty_o <= '1';
314
    readContentEmpty_o <= '1';
315
    readContentEnd_o <= '0';
316
    readContentData_o <= (others=>'0');
317
 
318
    front := 0;
319
    back := 0;
320
    window := 0;
321
    frameIndex := 0;
322
    readEmpty_o <= '1';
323
    readAck_o <= '0';
324
 
325
    loop
326
      wait until clk = '1' or readWrite_i = '1';
327
 
328
      if (clk'event) then
329
        if (readFrame_i = '1') then
330
          if (back /= front) then
331
            back := QueueIndexInc(back);
332
          else
333
            TestError("READ:BACK:reading when no frame is present");
334
          end if;
335
        end if;
336
 
337
        if (readFrameRestart_i = '1') then
338
          frameIndex := 0;
339
        end if;
340
 
341
        if (readWindowReset_i = '1') then
342
          window := back;
343
          frameIndex := 0;
344
        end if;
345
 
346
        if (readWindowNext_i = '1') then
347
          if (window /= front) then
348
            window := QueueIndexInc(window);
349
            frameIndex := 0;
350
          else
351
            TestError("READ:WINDOW:reading when no frame is present");
352
          end if;
353
        end if;
354
 
355
        if (readContent_i = '1') then
356
          if (back /= front) then
357
            if (READ_CONTENT_END_DATA_VALID) then
358
              if (frameIndex < frameQueue(window).frame.length) then
359
                readContentData_o <= frameQueue(window).frame.payload(frameIndex);
360
                frameIndex := frameIndex + 1;
361
                if (frameIndex = frameQueue(window).frame.length) then
362
                  readContentEnd_o <= '1';
363
                else
364
                  readContentEnd_o <= '0';
365
                end if;
366
              else
367
                TestError("READ:CONTENT:reading when frame has ended");
368
              end if;
369
            else
370
              if (frameIndex < frameQueue(window).frame.length) then
371
                readContentData_o <= frameQueue(window).frame.payload(frameIndex);
372
                readContentEnd_o <= '0';
373
                frameIndex := frameIndex + 1;
374
              elsif (frameIndex = frameQueue(window).frame.length) then
375
                readContentData_o <= (others=>'U');
376
                readContentEnd_o <= '1';
377
              else
378
                TestError("READ:CONTENT:reading when frame has ended");
379
              end if;
380
            end if;
381
          else
382
            TestError("READ:CONTENT:reading when no frame is present");
383
          end if;
384
        end if;
385
 
386
        if (front = back) then
387
          readFrameEmpty_o <= '1';
388
        else
389
          readFrameEmpty_o <= '0';
390
        end if;
391
 
392
        if (front = window) then
393
          readWindowEmpty_o <= '1';
394
          readContentEmpty_o <= '1';
395
        else
396
          readWindowEmpty_o <= '0';
397
          if (frameIndex /= frameQueue(window).frame.length) then
398
            readContentEmpty_o <= '0';
399
          else
400
            readContentEmpty_o <= '1';
401
          end if;
402
        end if;
403
 
404
        if (front = back) then
405
          readEmpty_o <= '1';
406
        else
407
          readEmpty_o <= '0';
408
        end if;
409
      elsif (readWrite_i'event) then
410
        frameQueue(front) := readMessage_i;
411
        front := QueueIndexInc(front);
412
 
413
        readEmpty_o <= '0';
414
        readAck_o <= '1';
415
        wait until readWrite_i = '0';
416
        readAck_o <= '0';
417
      end if;
418
    end loop;
419
  end process;
420
 
421
  -----------------------------------------------------------------------------
422
  -- 
423
  -----------------------------------------------------------------------------
424
  Writer: process
425
    variable frameQueue : QueueArray(0 to QUEUE_SIZE);
426
    variable front, back : natural range 0 to QUEUE_SIZE;
427
    variable frameIndex : natural range 0 to 69;
428
  begin
429
    wait until areset_n = '1';
430
 
431
    writeEmpty_o <= '1';
432
    writeAck_o <= '0';
433
 
434
    front := 0;
435
    back := 0;
436
    frameIndex := 0;
437
 
438
    loop
439
      wait until clk = '1' or writeWrite_i = '1';
440
 
441
      if (clk'event) then
442
 
443
        if (writeFrame_i = '1') then
444
          if (frameIndex = 0) then
445
            TestError("WRITE:Empty frame written.");
446
          end if;
447
          if (frameIndex /= frameQueue(back).frame.length) then
448
            TestError("WRITE:Frame with unmatching length was written.");
449
          end if;
450
          if (back /= front) then
451
            back := QueueIndexInc(back);
452
          else
453
            TestError("WRITE:Unexpected frame written.");
454
          end if;
455
          frameIndex := 0;
456
        end if;
457
 
458
        if (writeFrameAbort_i = '1') then
459
          if (back /= front) then
460
            if (frameQueue(back).willAbort) then
461
              TestCompare(frameIndex,
462
                          frameQueue(back).frame.length,
463
                          "frameIndex abort");
464
              back := QueueIndexInc(back);
465
            else
466
              TestError("WRITE:Not expecting this frame to abort.");
467
            end if;
468
          end if;
469
          frameIndex := 0;
470
        end if;
471
 
472
        if (writeContent_i = '1') then
473
          if (frameIndex < frameQueue(back).frame.length) then
474
            TestCompare(writeContentData_i,
475
                        frameQueue(back).frame.payload(frameIndex),
476
                        "frame content");
477
            frameIndex := frameIndex + 1;
478
          else
479
            TestError("WRITE:Receiving more frame content than expected.");
480
          end if;
481
        end if;
482
 
483
        if (front = back) then
484
          writeEmpty_o <= '1';
485
        else
486
          writeEmpty_o <= '0';
487
        end if;
488
      elsif (writeWrite_i'event) then
489
        frameQueue(front) := writeMessage_i;
490
        front := QueueIndexInc(front);
491
 
492
        writeEmpty_o <= '0';
493
        writeAck_o <= '1';
494
        wait until writeWrite_i = '0';
495
        writeAck_o <= '0';
496
      end if;
497
    end loop;
498
  end process;
499
 
500
end architecture;
501
 
502
 
503
 
504
-------------------------------------------------------------------------------
505
-- 
506
-------------------------------------------------------------------------------
507
library ieee;
508
use ieee.std_logic_1164.all;
509
use ieee.numeric_std.all;
510
library std;
511
use std.textio.all;
512
use work.rio_common.all;
513
use work.TestPortPackage.all;
514
 
515
 
516
-------------------------------------------------------------------------------
517
-- 
518
-------------------------------------------------------------------------------
519
entity TestPortWishbone is
520
  generic(
521
    ADDRESS_WIDTH : natural := 31;
522
    SEL_WIDTH : natural := 8;
523
    DATA_WIDTH : natural := 64);
524
  port(
525
    clk : in std_logic;
526
    areset_n : in std_logic;
527
 
528
    messageEmpty_o : out std_logic;
529
    messageWrite_i : in std_logic;
530
    message_i : in TestPortMessageWishbone;
531
    messageAck_o : out std_logic;
532
 
533
    cyc_i : in std_logic;
534
    stb_i : in std_logic;
535
    we_i : in std_logic;
536
    adr_i : in std_logic_vector(ADDRESS_WIDTH-1 downto 0);
537
    sel_i : in std_logic_vector(SEL_WIDTH-1 downto 0);
538
    dat_i : in std_logic_vector(DATA_WIDTH-1 downto 0);
539
    dat_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
540
    err_o : out std_logic;
541
    ack_o : out std_logic);
542
end entity;
543
 
544
 
545
-------------------------------------------------------------------------------
546
-- 
547
-------------------------------------------------------------------------------
548
architecture TestPortWishboneImpl of TestPortWishbone is
549
  constant QUEUE_SIZE : natural := 63;
550
  type QueueArray is array (natural range <>) of TestPortMessageWishbone;
551
 
552
  function QueueIndexInc(constant i : natural) return natural is
553
    variable returnValue : natural;
554
  begin
555
    if(i = QUEUE_SIZE) then
556
      returnValue := 0;
557
    else
558
      returnValue := i + 1;
559
    end if;
560
    return returnValue;
561
  end function;
562
 
563
begin
564
 
565
  -----------------------------------------------------------------------------
566
  -- 
567
  -----------------------------------------------------------------------------
568
  Slave: process
569
    variable queue : QueueArray(0 to QUEUE_SIZE);
570
    variable front, back : natural range 0 to QUEUE_SIZE;
571
    variable latencyCounter : natural;
572
    variable activeCycle : boolean;
573
  begin
574
    wait until areset_n = '1';
575
 
576
    messageEmpty_o <= '1';
577
    messageAck_o <= '0';
578
 
579
    dat_o <= (others=>'U');
580
    err_o <= '0';
581
    ack_o <= '0';
582
 
583
    front := 0;
584
    back := 0;
585
    latencyCounter := 0;
586
    activeCycle := false;
587
 
588
    loop
589
      wait until clk = '1' or messageWrite_i = '1';
590
 
591
      if (clk'event) then
592
        if (cyc_i = '1') then
593
          if (front /= back) then
594
            if (stb_i = '1') then
595
              if (latencyCounter <= queue(back).latency) then
596
                TestCompare(stb_i, '1', "stb_i");
597
                if (queue(back).writeAccess) then
598
                  TestCompare(we_i, '1', "we_i");
599
                else
600
                  TestCompare(we_i, '0', "we_i");
601
                end if;
602
                TestCompare(adr_i, queue(back).address(ADDRESS_WIDTH-1 downto 0), "adr_i");
603
                TestCompare(sel_i, queue(back).byteSelect(SEL_WIDTH-1 downto 0), "sel_i");
604
                if (queue(back).writeAccess) then
605
                  TestCompare(dat_i, queue(back).data(DATA_WIDTH-1 downto 0), "dat_i");
606
                end if;
607
              end if;
608
 
609
              if (latencyCounter < queue(back).latency) then
610
                dat_o <= (others=>'U');
611
                ack_o <= '0';
612
                latencyCounter := latencyCounter + 1;
613
              elsif (latencyCounter = queue(back).latency) then
614
                if (queue(back).writeAccess) then
615
                  dat_o <= (others=>'U');
616
                else
617
                  dat_o <= queue(back).data(DATA_WIDTH-1 downto 0);
618
                end if;
619
                ack_o <= '1';
620
                latencyCounter := latencyCounter + 1;
621
              else
622
                dat_o <= (others=>'U');
623
                ack_o <= '0';
624
                latencyCounter := 0;
625
                activeCycle := queue(back).continue;
626
                back := QueueIndexInc(back);
627
              end if;
628
            end if;
629
          else
630
            TestError("Unexpected access.");
631
          end if;
632
        else
633
          if (activeCycle or (latencyCounter /= 0)) then
634
            TestError("Cycle unexpectedly aborted.");
635
            latencyCounter := 0;
636
          end if;
637
          TestCompare(stb_i, '0', "stb_i");
638
        end if;
639
 
640
        if (front = back) then
641
          messageEmpty_o <= '1';
642
        else
643
          messageEmpty_o <= '0';
644
        end if;
645
      elsif (messageWrite_i'event) then
646
        queue(front) := message_i;
647
        front := QueueIndexInc(front);
648
 
649
        messageEmpty_o <= '0';
650
        messageAck_o <= '1';
651
        wait until messageWrite_i = '0';
652
        messageAck_o <= '0';
653
      end if;
654
    end loop;
655
  end process;
656
 
657
end architecture;
658
 
659
 

powered by: WebSVN 2.1.0

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