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

Subversion Repositories mips_enhanced

[/] [mips_enhanced/] [trunk/] [grlib-gpl-1.0.19-b3188/] [lib/] [gaisler/] [pci/] [pcitb_master_script.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 dimamali
------------------------------------------------------------------------------
2
--  This file is a part of the GRLIB VHDL IP LIBRARY
3
--  Copyright (C) 2003, Gaisler Research
4
--
5
--  This program is free software; you can redistribute it and/or modify
6
--  it under the terms of the GNU General Public License as published by
7
--  the Free Software Foundation; either version 2 of the License, or
8
--  (at your option) any later version.
9
--
10
--  This program is distributed in the hope that it will be useful,
11
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
--  GNU General Public License for more details.
14
--
15
--  You should have received a copy of the GNU General Public License
16
--  along with this program; if not, write to the Free Software
17
--  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
18
-----------------------------------------------------------------------------
19
-- Entity:      pcitb_master_script
20
-- File:        pcitb_master_script.vhd
21
-- Author:      Kristoffer Glembo, Alf Vaerneus, Gaisler Research
22
-- Description: PCI Master emulator. Can act as a system host
23
------------------------------------------------------------------------------
24
 
25
-- pragma translate_off
26
 
27
library ieee;
28
use ieee.std_logic_1164.all;
29
use ieee.numeric_std.all;
30
 
31
library std;
32
use std.textio.all;
33
 
34
library grlib;
35
use grlib.stdlib.all;
36
library gaisler;
37
use gaisler.pcitb.all;
38
use gaisler.pcilib.all;
39
use gaisler.ambatest.all;
40
 
41
entity pcitb_master_script is
42
  generic (
43
    slot      : integer := 0;
44
    tval      : time := 7 ns;
45
    dbglevel  : integer := 2;
46
    maxburst  : integer := 1024;
47
    filename  : string := "pci.cmd");
48
  port (
49
    pciin     : in pci_type;
50
    pciout    : out pci_type);
51
end pcitb_master_script;
52
 
53
architecture behav of pcitb_master_script is
54
 
55
type cmd_state_type is (idle, parse, execute, done, finished);
56
 
57
type pci_data_type is record
58
  data  : std_logic_vector(31 downto 0);
59
  cbe   : std_logic_vector(3 downto 0);
60
  ws    : integer;
61
end record;
62
 
63
type databuf_type is array (0 to maxburst) of pci_data_type;
64
 
65
type cmd_type is (rcfg, wcfg, rmem, wmem, idle, comp, ill, print, estop, stop);
66
 
67
type command is record
68
  cmd   : cmd_type;
69
  pcicmd: std_logic_vector(3 downto 0);
70
  addr  : std_logic_vector(31 downto 0);
71
  len   : integer;
72
  file1 : string(1 to 18);
73
  file2 : string(1 to 18);
74
  msg   : string(1 to 80);
75
  check : integer; -- 0 ignore, 1 check, 2 save to file
76
  estop : integer;
77
  data  : databuf_type;
78
  pci   : boolean;
79
  started : std_logic;
80
  done    : std_logic;
81
 
82
end record;
83
 
84
type script_reg_type is record
85
  cmd_state     : cmd_state_type;
86
  cmd_done      : std_logic;
87
  idle_count    : integer;
88
  cmd_count     : integer;
89
end record;
90
 
91
signal sr,srin : script_reg_type;
92
 
93
signal cmd : command;
94
 
95
file cmd_file : text open read_mode is filename;
96
 
97
---------------------------------
98
--- PCI MASTER TYPES AND SIGNALS
99
---------------------------------
100
constant T_O : integer := 9;
101
 
102
constant INT_ACK      : word4 := "0000";
103
constant SPEC_CYCLE   : word4 := "0001";
104
constant IO_READ      : word4 := "0010";
105
constant IO_WRITE     : word4 := "0011";
106
constant MEM_READ     : word4 := "0110";
107
constant MEM_WRITE    : word4 := "0111";
108
constant CONF_READ    : word4 := "1010";
109
constant CONF_WRITE   : word4 := "1011";
110
constant MEM_R_MULT   : word4 := "1100";
111
constant DAC          : word4 := "1101";
112
constant MEM_R_LINE   : word4 := "1110";
113
constant MEM_W_INV    : word4 := "1111";
114
 
115
type state_type is(idle,active,done);
116
type status_type is (OK, ERR, TIMEOUT, RETRY);
117
 
118
type reg_type is record
119
  state         : state_type;
120
  pcien         : std_logic_vector(3 downto 0);
121
  paren         : std_logic;
122
  read          : std_logic;
123
  burst         : std_logic;
124
  grant         : std_logic;
125
  address       : std_logic_vector(31 downto 0);
126
  data          : std_logic_vector(31 downto 0);
127
  current_word  : integer;
128
  tocnt         : integer;
129
  running       : std_logic;
130
  pci           : pci_type;
131
  ready         : std_logic;
132
  last          : std_logic;
133
  f_open        : std_logic;
134
  ws_count      : integer;
135
  ws_done       : boolean;
136
  status        : status_type;
137
end record;
138
 
139
signal r,rin : reg_type;
140
 
141
----------------------------------------------------------------
142
-- PROCEDURES
143
----------------------------------------------------------------
144
 
145
function cbe2mask(cbe : std_logic_vector(3 downto 0)) return std_logic_vector is
146
    variable mask : std_logic_vector(31 downto 0);
147
begin
148
    for i in 0 to 3 loop
149
        mask((i+1)*8-1 downto i*8) := (others => cbe(i));
150
    end loop;
151
 
152
    return mask;
153
 
154
end cbe2mask;
155
 
156
function strlen(str : string) return integer is
157
    variable i : integer;
158
begin
159
    i := 1;
160
    while (str(i) /= ' ' and str(i) /= nul) loop
161
        i := i+1;
162
    end loop;
163
 
164
    return i-1;
165
 
166
end strlen;
167
 
168
procedure get_param(str : string; tok : character; param : out string; index : out integer; done : out boolean) is
169
    variable start_i, end_i : integer;
170
begin
171
    start_i := str'left;
172
    while str(start_i) = ' ' and start_i <= str'right loop
173
        start_i := start_i + 1;
174
    end loop;
175
 
176
    end_i := start_i;
177
 
178
    while end_i <= str'right loop
179
 
180
        if str(end_i) = ' ' or str(end_i) = ';' or str(end_i) = nul  or str(end_i) = tok then
181
             exit;
182
        end if;
183
 
184
        end_i := end_i + 1;
185
    end loop;
186
 
187
    param(1 to (end_i-start_i)) := str(start_i to end_i-1);
188
    for i in end_i-start_i+1 to param'length loop
189
        param(i) := ' ';
190
    end loop;
191
--    param(end_i-start_i+1 to param'length) := (others => ' ');
192
 
193
    if str(end_i) = ';' or str(end_i) = nul or end_i = str'right then
194
        done := true;
195
    else
196
        done := false;
197
    end if;
198
 
199
    index := end_i+1;
200
 
201
end get_param;
202
 
203
procedure parse_cmd(file cmdfile : text; c : out command) is
204
 
205
    variable L : line;
206
    variable line : string(1 to 80);
207
    variable cmdname : string(1 to 5);
208
    variable i,k : integer;
209
    variable done : boolean;
210
    variable tmp : string(1 to 8);
211
    variable tmpstr : string(1 to 18);
212
    variable slvlen : std_logic_vector(31 downto 0);
213
    variable len : integer;
214
    file datafile : text;
215
 
216
begin
217
 
218
    while not endfile(cmdfile) loop
219
 
220
        c.check := 0;
221
        c.data(0).cbe := "0000";
222
        c.data(0).ws := 0;
223
        done := false;
224
        line := (others => nul);
225
        tmp := (others => nul);
226
        tmpstr := (others => nul);
227
        line := (others => nul);
228
 
229
        readline(cmdfile, L);
230
        if L'length < cmdname'length then
231
            read(L, cmdname(1 to L'length));
232
        else
233
            read(L, cmdname);
234
        end if;
235
 
236
        if cmdname(1) = ' ' or cmdname(1) = '#' or cmdname(1) = nul or cmdname(1) = cr then
237
            next;
238
 
239
        elsif cmdname = "rcfg " then
240
            c.cmd := rcfg;
241
            c.pci := true;
242
            c.len := 1;
243
            c.pcicmd := CONF_READ;
244
 
245
            read(L, line(1 to L'length));
246
            get_param(line, ' ',  tmp, i, done);
247
            c.addr := conv_std_logic_vector(tmp, 32);
248
            get_param(line(i to line'length), ' ', tmp, i, done);
249
 
250
            if tmp(1) = '*' then
251
                c.check := 0;
252
            else
253
                c.check := 1;
254
                c.data(0).data := conv_std_logic_vector(tmp, 32);
255
            end if;
256
 
257
            exit;
258
 
259
        elsif cmdname = "wcfg " then
260
            c.cmd := wcfg;
261
            c.pci := true;
262
            c.len := 1;
263
            c.pcicmd := CONF_WRITE;
264
 
265
            read(L, line(1 to L'length));
266
            get_param(line, ' ',  tmp, i, done);
267
            c.addr := conv_std_logic_vector(tmp, 32);
268
 
269
            get_param(line(i to line'length), '.', tmp, i, done);
270
            c.data(0).data := conv_std_logic_vector(tmp, 32);
271
 
272
            get_param(line(i to line'length), ' ', tmp, i, done);
273
            c.data(0).cbe := conv_std_logic_vector(tmp, 4);
274
 
275
            exit;
276
 
277
        elsif cmdname = "rmem " then
278
            c.cmd := rmem;
279
            c.pci := true;
280
 
281
            read(L, line(1 to L'length));
282
 
283
            -- Get read command
284
            get_param(line, ' ', tmp, i, done);
285
            c.pcicmd := conv_std_logic_vector(tmp, 4);
286
 
287
            -- Get read addr
288
            get_param(line(i to line'length), ' ', tmp, i, done);
289
            c.addr := conv_std_logic_vector(tmp, 32);
290
 
291
            -- Get read length
292
            get_param(line(i to line'length), ' ', tmp, i, done);
293
            len := to_integer( unsigned(conv_std_logic_vector(tmp, 16)) );
294
            c.len := len;
295
 
296
            -- Get check data
297
            get_param(line(i to line'length), ' ', tmpstr, i, done);
298
            if tmpstr(1) = '*' then
299
                c.check := 0;
300
            elsif tmpstr(1) = '{' then
301
                c.check := 1;
302
                for j in 1 to line'length loop
303
                    line(j) := nul;
304
                end loop;
305
                for j in 0 to len-1 loop
306
 
307
                    tmpstr := (others => nul);
308
                    line   := (others => nul);
309
 
310
                    readline(cmdfile, L);
311
                    read(L, line(1 to L'length));
312
                    get_param(line, '.', tmpstr, i, done);
313
                    c.data(j).data := conv_std_logic_vector(tmpstr(1 to 8), 32);
314
 
315
                    get_param(line(i to line'length), '.', tmpstr, i, done);
316
                    c.data(j).cbe := conv_std_logic_vector(tmpstr(1 to 8), 4);
317
 
318
                    if not done then
319
                        get_param(line(i to line'length), ' ', tmpstr, i, done);
320
                        c.data(j).ws := to_integer( unsigned(conv_std_logic_vector(tmpstr(1 to 8), 4)) );
321
                    else
322
                        c.data(j).ws := 0;
323
                    end if;
324
 
325
                end loop;
326
 
327
                readline(cmdfile, L);
328
 
329
            else
330
                c.check := 2;
331
                c.file1 := tmpstr;
332
            end if;
333
 
334
            exit;
335
 
336
        elsif cmdname = "wmem " then
337
            c.cmd := wmem;
338
            c.pci := true;
339
 
340
            read(L, line(1 to L'length));
341
 
342
            -- Get write command
343
            get_param(line, ' ', tmp, i, done);
344
            c.pcicmd := conv_std_logic_vector(tmp, 4);
345
 
346
            -- Get write addr
347
            get_param(line(i to line'length), ' ', tmp, i, done);
348
            c.addr := conv_std_logic_vector(tmp, 32);
349
 
350
            -- Get write length
351
            get_param(line(i to line'length), ' ', tmp, i, done);
352
            len := to_integer( unsigned(conv_std_logic_vector(tmp, 16)) );
353
            c.len := len;
354
 
355
            -- Get data
356
            get_param(line(i to line'length), ' ', tmpstr, i, done);
357
            if tmpstr(1) = '{' then
358
 
359
                for j in 1 to line'length loop
360
                    line(j) := nul;
361
                end loop;
362
                for j in 0 to len-1 loop
363
 
364
                    tmpstr := (others => nul);
365
                    line   := (others => nul);
366
 
367
                    readline(cmdfile, L);
368
                    read(L, line(1 to L'length));
369
                    get_param(line, '.', tmpstr, i, done);
370
                    c.data(j).data := conv_std_logic_vector(tmpstr(1 to 8), 32);
371
                    get_param(line(i to line'length), '.', tmpstr, i, done);
372
                    c.data(j).cbe := conv_std_logic_vector(tmpstr(1 to 8), 4);
373
 
374
                     if not done then
375
                        get_param(line(i to line'length), ' ', tmpstr, i, done);
376
                        c.data(j).ws := to_integer( unsigned(conv_std_logic_vector(tmpstr(1 to 8), 4)) );
377
                     else
378
                        c.data(j).ws := 0;
379
                    end if;
380
 
381
                end loop;
382
 
383
                readline(cmdfile, L);
384
 
385
            else
386
                c.file1 := tmpstr;
387
                file_open(datafile, tmpstr(1 to strlen(tmpstr)), read_mode);
388
                for j in 0 to len-1 loop
389
                    tmpstr := (others => nul);
390
                    line   := (others => nul);
391
 
392
                    readline(datafile, L);
393
                    read(L, line(1 to L'length));
394
 
395
                    get_param(line, '.', tmpstr, i, done);
396
                    c.data(j).data := conv_std_logic_vector(tmpstr(1 to 8), 32);
397
 
398
                    get_param(line(i to line'length), '.', tmpstr, i, done);
399
                    c.data(j).cbe := conv_std_logic_vector(tmpstr(1 to 8), 4);
400
 
401
                    if not done then
402
                        get_param(line(i to line'length), ' ', tmpstr, i, done);
403
                        c.data(j).ws := to_integer( unsigned(conv_std_logic_vector(tmpstr(1 to 8), 4)) );
404
                     else
405
                        c.data(j).ws := 0;
406
                    end if;
407
 
408
                end loop;
409
                file_close(datafile);
410
            end if;
411
 
412
            exit;
413
 
414
        elsif cmdname = "wait " then
415
            c.cmd := idle;
416
            c.pci := false;
417
 
418
            read(L, c.len);
419
            exit;
420
 
421
        elsif cmdname = "comp " then
422
            c.cmd := comp;
423
            c.pci := false;
424
 
425
            read(L, line(1 to L'length));
426
            get_param(line, ' ', c.file1, i, done);
427
            assert done = false report "Illegal compare statement. Missing file2";
428
            get_param(line(i to line'length), ' ', c.file2, i, done);
429
            assert done = true report "Illegal compare statement. Missing ;";
430
 
431
            exit;
432
 
433
        elsif cmdname(1 to 4) = "stop" then
434
            c.cmd := stop;
435
            c.pci := false;
436
            exit;
437
 
438
        elsif cmdname = "estop" then
439
            c.cmd := estop;
440
            c.pci := false;
441
            read(L, c.estop);
442
            exit;
443
 
444
        elsif cmdname = "print" then
445
            c.cmd := print;
446
            c.pci := false;
447
            read(L, line(1 to L'length));
448
            i := 1;
449
            while line(i) /= ';' and line(i) /= nul loop
450
                i := i + 1;
451
            end loop;
452
 
453
            c.msg(1 to i-1) := line(1 to i-1);
454
            c.msg(i to 80) := (others => nul);
455
            exit;
456
 
457
        elsif cmdname(1 to 4) = "halt" then
458
 
459
            print ("");
460
            assert false report "*** Simulation ended by halt command in pcitb_master_script ***" severity failure;
461
            print ("");
462
 
463
        else
464
            c.cmd := ill;
465
            exit;
466
 
467
        end if;
468
 
469
 
470
    end loop;
471
 
472
end parse_cmd;
473
 
474
 
475
begin
476
 
477
  script_comb : process(sr, cmd, r, pciin)
478
 
479
  variable vcmd : command;
480
  variable v : script_reg_type;
481
  variable err : boolean;
482
 
483
  begin
484
 
485
    v := sr;
486
    vcmd := cmd;
487
 
488
    case sr.cmd_state is
489
 
490
        when idle =>
491
 
492
            v.cmd_state := parse;
493
 
494
        when parse =>
495
 
496
            if cmd.started = '0' then
497
                parse_cmd(cmd_file, vcmd);
498
                vcmd.started := '1';
499
 
500
                if vcmd.cmd /= print and dbglevel >= 2 then
501
                    printf("");
502
                    printf("Command #%d ", sr.cmd_count+1, timestamp => true);
503
                end if;
504
 
505
                case vcmd.cmd is
506
                    when idle =>
507
                        if dbglevel >= 2 then
508
                            printf("Waiting for %d cycles.", vcmd.len);
509
                        end if;
510
 
511
                    when comp =>
512
                        if dbglevel >= 2 then
513
                            printf("Comparing %s", vcmd.file1(1 to strlen(vcmd.file1)) & " to " & vcmd.file2(1 to strlen(vcmd.file2)));
514
                        end if;
515
 
516
                    when rcfg =>
517
                        if dbglevel >= 2 then
518
                            printf("Configuration read");
519
                            printf(" Address: 0x%x", vcmd.addr);
520
                        end if;
521
 
522
                    when wcfg =>
523
                        if dbglevel >= 2 then
524
                            printf("Configuration write");
525
                            printf(" Address: 0x%x", vcmd.addr);
526
                            printf(" Data   : 0x%x", vcmd.data(0).data);
527
                            printf(" CBE    : 0x%x", vcmd.data(0).cbe);
528
                        end if;
529
 
530
                    when rmem =>
531
                        if dbglevel >= 2 then
532
                            if vcmd.pcicmd = MEM_READ then
533
                                printf("Memory read");
534
                            elsif vcmd.pcicmd = MEM_R_MULT then
535
                                printf("Memory read multiple");
536
                            else
537
                                printf("Memory read line");
538
                            end if;
539
                            printf(" Address: 0x%x", vcmd.addr);
540
                            printf(" Length : %x", vcmd.len);
541
                        end if;
542
 
543
                    when wmem =>
544
                        if dbglevel >= 2 then
545
                            if vcmd.pcicmd = MEM_WRITE then
546
                                printf("Memory write");
547
                            else
548
                                printf("Memory write and invalidate");
549
                            end if;
550
                            printf(" Address: 0x%x", vcmd.addr);
551
                            printf(" Length : %x", vcmd.len);
552
                            if (vcmd.len = 1) then
553
                                printf(" Data   : 0x%x", vcmd.data(0).data);
554
                                printf(" CBE    : 0x%x", vcmd.data(0).cbe);
555
                            end if;
556
                        end if;
557
 
558
                    when print =>
559
                        printf(vcmd.msg);
560
 
561
                    when stop =>
562
                        if dbglevel >= 1 then
563
                            printf("PCI Testmaster done with scriptfile");
564
                        end if;
565
 
566
                    when others =>  vcmd.done := '1';
567
                end case;
568
 
569
            end if;
570
 
571
            v.cmd_state := execute;
572
 
573
        when execute =>
574
 
575
            if vcmd.done = '0' then
576
                case vcmd.cmd is
577
                    when idle =>
578
                        if sr.idle_count < vcmd.len then
579
                            v.idle_count := sr.idle_count + 1;
580
                        else
581
                            vcmd.done := '1';
582
                        end if;
583
                    when comp =>
584
                        compfiles(vcmd.file1, vcmd.file2, 1, dbglevel, err);
585
                        if cmd.estop = 1 then
586
                            printf("");
587
                            assert err = false
588
                                report "Simulation ended due to data compare failure!"
589
                                severity FAILURE;
590
                        end if;
591
                        vcmd.done := '1';
592
                    when rcfg =>
593
                        if r.ready = '1' then
594
                            vcmd.done := '1';
595
                        end if;
596
                    when wcfg =>
597
                        if r.ready = '1' then
598
                            vcmd.done := '1';
599
                        end if;
600
                    when rmem =>
601
                        if r.ready  = '1' then
602
                            vcmd.done := '1';
603
                        end if;
604
                    when wmem =>
605
                        if r.ready  = '1' then
606
                            vcmd.done := '1';
607
                        end if;
608
 
609
                    when stop =>
610
                        v.cmd_state := finished;
611
                        vcmd.done := '1';
612
 
613
                    when others =>  vcmd.done := '1';
614
                end case;
615
            end if;
616
 
617
            v.cmd_done := vcmd.done;
618
 
619
            if sr.cmd_done = '1' and vcmd.cmd /= stop then
620
                v.cmd_count := sr.cmd_count + 1;
621
                v.cmd_state := done;
622
            end if;
623
 
624
        when done =>
625
            vcmd.started := '0';
626
            vcmd.done    := '0';
627
            v.cmd_done   := '0';
628
            v.cmd_state  := idle;
629
            v.idle_count := 0;
630
        when others => null;
631
 
632
    end case;
633
 
634
 
635
    if pciin.syst.rst = '0' then
636
 
637
        vcmd.started := '0';
638
        vcmd.done    := '0';
639
        vcmd.estop   := 0;
640
        v.cmd_state := idle;
641
        v.idle_count := 0;
642
        v.cmd_count := 0;
643
 
644
    end if;
645
 
646
    cmd <= vcmd;
647
    srin <= v;
648
  end process;
649
 
650
  script_regs : process(pciin.syst.clk)
651
  begin
652
      if rising_edge(pciin.syst.clk) then
653
          sr <= srin;
654
      end if;
655
  end process;
656
 
657
-----------------------------------------
658
-- PCI MASTER
659
-----------------------------------------
660
  pci_master_comb : process(cmd, pciin)
661
 
662
      variable vpci : pci_type;
663
      variable v : reg_type;
664
      variable i,count,dataintrans : integer;
665
      variable status : status_type;
666
      variable ready,stop : std_logic;
667
      variable comm : std_logic_vector(3 downto 0);
668
 
669
  begin
670
      v := r; count := count+1; v.tocnt := 0; ready := '0'; stop := '0';
671
      v.pcien(0) := '1'; v.pcien(3 downto 1) := r.pcien(2 downto 0);
672
 
673
      if cmd.started = '1' and cmd.pci = true then
674
          if (r.running = '0' and r.state = idle) then
675
              v.address := cmd.addr(31 downto 2) & "00";
676
              status := OK;
677
              v.running := '1';
678
          end if;
679
 
680
          case cmd.pcicmd is
681
 
682
              when MEM_READ =>
683
                  v.burst := '0';
684
                  v.read := '1';
685
                  comm := MEM_READ;
686
 
687
              when MEM_R_MULT =>
688
                  v.burst := '1';
689
                  v.read := '1';
690
                  comm := MEM_R_MULT;
691
 
692
              when MEM_R_LINE =>
693
                  v.burst := '1';
694
                  v.read := '1';
695
                  comm := MEM_R_LINE;
696
 
697
              when MEM_WRITE =>
698
                  if cmd.len = 1 then
699
                      v.burst := '0';
700
                  else
701
                      v.burst := '1';
702
                  end if;
703
                  v.read := '0';
704
                  comm := MEM_WRITE;
705
 
706
              when MEM_W_INV =>
707
                  v.burst := '1';
708
                  v.read := '0';
709
                  comm := MEM_W_INV;
710
 
711
              when CONF_READ =>
712
                  v.burst := '0';
713
                  v.read := '1';
714
                  comm := CONF_READ;
715
 
716
              when CONF_WRITE =>
717
                  v.burst := '0';
718
                  v.read := '0';
719
                  comm := CONF_WRITE;
720
 
721
              when others =>
722
 
723
          end case;
724
 
725
          v.address := (cmd.addr(31 downto 2) + conv_std_logic_vector(v.current_word,30)) & "00";
726
          comm := cmd.pcicmd;
727
          v.pci.ad.ad := cmd.data(v.current_word).data;
728
          v.burst := not r.last;
729
          stop := r.last;
730
 
731
      end if;
732
 
733
      v.pci.ad.par := xorv(r.pci.ad.ad & r.pci.ad.cbe);
734
      v.paren := r.read;
735
 
736
      if (pciin.ifc.devsel and not pciin.ifc.stop) = '1' and r.running = '1' then
737
          status := ERR;
738
      elsif r.tocnt = T_O then
739
          status := TIMEOUT;
740
      else
741
        status := OK;
742
      end if;
743
 
744
      case r.state is
745
 
746
          when idle =>
747
              v.ws_count := 0;
748
              v.ws_done  := false;
749
 
750
              v.pci.arb.req(slot) := not (r.running and r.pcien(1));
751
              v.pci.ifc.irdy := '1'; dataintrans := 0;
752
              if r.grant = '1' then
753
                  v.state := active; v.pci.ifc.frame := '0'; v.read := '0';
754
                  v.pcien(0) := '0'; v.pci.ad.ad := v.address; v.pci.ad.cbe := comm;
755
              end if;
756
 
757
          when active =>
758
 
759
              v.tocnt := r.tocnt + 1; v.pcien(0) := '0';
760
 
761
              v.pci.ad.cbe := cmd.data(v.current_word).cbe;
762
              v.pci.arb.req(slot) := not (r.burst and not pciin.ifc.frame);
763
 
764
              if (pciin.ifc.irdy or (pciin.ifc.trdy and pciin.ifc.stop)) = '0' then
765
                  if pciin.ifc.trdy = '0' then
766
                      v.current_word := r.current_word+1;
767
                      v.data := pciin.ad.ad;
768
                      v.pci.ad.ad := cmd.data(v.current_word).data;
769
                      v.pci.ad.cbe := cmd.data(v.current_word).cbe;
770
                      dataintrans := dataintrans+1;
771
                      v.ws_count := 0;
772
                      v.ws_done := false;
773
                  end if;
774
              end if;
775
 
776
              -- Wait state insertion
777
              if v.ws_done or r.ws_count = cmd.data(v.current_word).ws then
778
                  v.pci.ifc.irdy := '0';
779
                  v.ws_count := 0;
780
                  v.ws_done := true;
781
              else
782
                  v.pci.ifc.irdy := '1';
783
                  v.ws_count := r.ws_count + 1;
784
              end if;
785
 
786
              if pciin.ifc.devsel = '0' then v.tocnt := 0; end if;
787
 
788
              if pciin.ifc.stop = '0' then
789
                  v.pcien(0) := pciin.ifc.frame; stop := '1'; v.state := idle; v.pci.ifc.irdy := pciin.ifc.frame;
790
              end if;
791
 
792
              if (r.status /= OK or ((pciin.ifc.frame and not pciin.ifc.irdy and not pciin.ifc.trdy) = '1')) then
793
                  v.state := done; v.pci.ifc.irdy := '1'; v.pcien(0) := '1'; v.pci.arb.req(slot) := '1';
794
              end if;
795
              v.pci.ifc.frame := not (r.burst and not stop);
796
 
797
          when done =>
798
              v.running := '0'; ready := '1';
799
              if cmd.started = '0' and cmd.pci = true then
800
                  v.state := idle;
801
                  v.current_word := 0;
802
              end if;
803
 
804
          when others =>
805
 
806
      end case;
807
 
808
      v.grant := to_x01(pciin.ifc.frame) and to_x01(pciin.ifc.irdy) and not r.pci.arb.req(slot) and not to_x01(pciin.arb.gnt(slot));
809
 
810
      if pciin.syst.rst = '0' then
811
          v.ws_count := 0;
812
          v.ws_done  := false;
813
          v.pcien := (others => '1');
814
          v.state := idle;
815
          v.read := '0';
816
          v.burst := '0';
817
          v.grant := '0';
818
          v.address := (others => '0');
819
          v.data := (others => '0');
820
          v.current_word := 0;
821
          v.running := '0';
822
          v.pci := pci_idle;
823
      end if;
824
 
825
      v.ready  := ready;
826
      v.status := status;
827
      rin <= v;
828
 
829
  end process;
830
 
831
  pci_master_reg : process(pciin.syst)
832
 
833
      file writefile : text;
834
      variable L : line;
835
      variable datahex : string(1 to 8);
836
      variable count : integer;
837
 
838
  begin
839
 
840
      if pciin.syst.rst = '0' then
841
 
842
          r.last <= '0';
843
          r.f_open <= '0';
844
 
845
          r.pcien <= (others => '1');
846
          r.state <= idle;
847
          r.read <= '0';
848
          r.burst <= '0';
849
          r.grant <= '0';
850
          r.address <= (others => '0');
851
          r.data <= (others => '0');
852
          r.current_word <= 0;
853
          r.running <= '0';
854
          r.pci <= pci_idle;
855
 
856
      elsif rising_edge(pciin.syst.clk) then
857
 
858
          r <= rin;
859
 
860
          if r.state = active and rin.pci.ifc.irdy = '0' then
861
 
862
              if cmd.len = 2 then
863
                  if rin.current_word = 1 then
864
                      r.last <= '1';
865
                      r.pci.ifc.frame <= '1';
866
                      r.running <= '0';
867
                  else
868
                      r.last <= '0';
869
                  end if;
870
              elsif cmd.len = 1 or r.current_word >= (cmd.len-2) then
871
                  r.last <= '1';
872
                  r.pci.ifc.frame <= '1';
873
                  r.running <= '0';
874
              end if;
875
 
876
          else
877
              r.last <= '0';
878
          end if;
879
 
880
          case r.state is
881
 
882
              when idle =>
883
                  count := 0;
884
 
885
                  if cmd.check = 2 and (cmd.started and not r.f_open) = '1' then
886
                      file_open(writefile, cmd.file1(1 to strlen(cmd.file1)), write_mode);
887
                      r.f_open <= '1';
888
                  end if;
889
 
890
              when active =>
891
                  if (pciin.ifc.trdy or pciin.ifc.irdy) = '0' then
892
 
893
                      if cmd.check = 2 then
894
                          write(L,printhex(pciin.ad.ad,32));
895
                          writeline(writefile,L);
896
 
897
                      elsif cmd.check = 1 then
898
                          if (pciin.ad.ad and not cbe2mask(cmd.data(count).cbe)) /= (cmd.data(count).data and not cbe2mask(cmd.data(count).cbe)) then
899
                              if dbglevel >= 1 then
900
                                  printf("Comparision error at data phase: %d",count+1);
901
                                  printf("   Expected data: %d", cmd.data(count).data);
902
                                  printf("   Expected cbe: %d", to_integer(unsigned(cmd.data(count).cbe)));
903
                                  printf("   Compared data: %d", pciin.ad.ad);
904
                                  printf("");
905
 
906
                                  assert cmd.estop /= 1
907
                                      report "Simulation ended due to data compare failure!"
908
                                      severity FAILURE;
909
 
910
                              end if;
911
                          end if;
912
 
913
                      end if;
914
 
915
                      count := count + 1;
916
 
917
                  end if;
918
 
919
                  if cmd.check = 2 and rin.state = done then
920
                      file_close(writefile);
921
                      r.f_open <= '0';
922
                  end if;
923
 
924
              when others =>
925
          end case;
926
 
927
      end if;
928
 
929
  end process;
930
 
931
  pciout.ad.ad     <= r.pci.ad.ad     after tval when (r.read or r.pcien(0)) = '0'  else (others => 'Z') after tval;
932
  pciout.ad.cbe    <= r.pci.ad.cbe    after tval when r.pcien(0) = '0'              else (others => 'Z') after tval;
933
  pciout.ad.par    <= r.pci.ad.par    after tval when (r.paren or r.pcien(1)) = '0' else 'Z' after tval;
934
  pciout.ifc.frame <= r.pci.ifc.frame after tval when r.pcien(0) = '0'              else 'Z' after tval;
935
  pciout.ifc.irdy  <= r.pci.ifc.irdy  after tval when r.pcien(1) = '0'              else 'Z' after tval;
936
  pciout.err.perr  <= r.pci.err.perr  after tval when r.pcien(2) = '0'              else 'Z' after tval;
937
  pciout.err.serr  <= r.pci.err.serr  after tval when r.pcien(2) = '0'              else 'Z' after tval;
938
  pciout.arb.req(slot) <= r.pci.arb.req(slot) after tval;
939
 
940
end;
941
 
942
-- pragma translate_on

powered by: WebSVN 2.1.0

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