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.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
20
-- File:        pcitb_master.vhd
21
-- Author:      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
 
30
library std;
31
use std.textio.all;
32
 
33
library grlib;
34
use grlib.stdlib.all;
35
library gaisler;
36
use gaisler.pcitb.all;
37
use gaisler.pcilib.all;
38
use gaisler.ambatest.all;
39
 
40
library grlib;
41
use grlib.stdlib.xorv;
42
 
43
 
44
entity pcitb_master is
45
  generic (
46
    slot : integer := 0;
47
    tval : time := 7 ns;
48
    dbglevel : integer := 1);
49
  port (
50
    -- PCI signals
51
    pciin     : in pci_type;
52
    pciout    : out pci_type;
53
    -- TB signals
54
    tbi       : in  tb_in_type;
55
    tbo       : out  tb_out_type
56
       );
57
end pcitb_master;
58
 
59
architecture tb of pcitb_master is
60
 
61
constant T_O : integer := 9;
62
 
63
type filedata_type is record
64
  address : std_logic_vector(31 downto 0);
65
  data : std_logic_vector(31 downto 0);
66
  command : std_logic_vector(3 downto 0);
67
  last : std_logic;
68
  openrfile : std_logic;
69
  openwfile : std_logic;
70
end record;
71
 
72
type state_type is(idle,active,done);
73
type reg_type is record
74
  state         : state_type;
75
  pcien         : std_logic_vector(3 downto 0);
76
  paren         : std_logic;
77
  read          : std_logic;
78
  burst         : std_logic;
79
  grant         : std_logic;
80
  address       : std_logic_vector(31 downto 0);
81
  data          : std_logic_vector(31 downto 0);
82
  current_word  : natural;
83
  tocnt         : integer;
84
  running       : std_logic;
85
  pci           : pci_type;
86
  status        : status_type;
87
end record;
88
 
89
signal r,rin : reg_type;
90
signal filedata : filedata_type;
91
 
92
begin
93
 
94
  comb : process(pciin)
95
  variable vpci : pci_type;
96
  variable v : reg_type;
97
  variable i,count,dataintrans : integer;
98
  variable status : status_type;
99
  variable ready,stop : std_logic;
100
  variable comm : std_logic_vector(3 downto 0);
101
  begin
102
    v := r; count := count+1; v.tocnt := 0; ready := '0'; stop := '0';
103
    v.pcien(0) := '1'; v.pcien(3 downto 1) := r.pcien(2 downto 0);
104
 
105
    if tbi.start = '1' then
106
      if (r.running = '0' and r.state = idle) then
107
        v.address := tbi.address(31 downto 2) & "00";
108
        status := OK;
109
        v.running := '1';
110
      end if;
111
      case tbi.command is
112
      when M_READ => v.burst := '0'; v.read := '1'; comm := MEM_READ;
113
      when M_READ_MULT => v.burst := '1'; v.read := '1'; comm := MEM_R_MULT;
114
      when M_READ_LINE => v.burst := '1'; v.read := '1'; comm := MEM_R_LINE;
115
      when M_WRITE =>
116
        if tbi.no_words = 1 then v.burst := '0'; else v.burst := '1'; end if;
117
        v.read := '0'; comm := MEM_WRITE;
118
      when M_WRITE_INV => v.burst := '1'; v.read := '0'; comm := MEM_W_INV;
119
      when C_READ => v.burst := '0'; v.read := '1'; comm := CONF_READ;
120
      when C_WRITE => v.burst := '0'; v.read := '0'; comm := CONF_WRITE;
121
      when others =>
122
      end case;
123
      if not tbi.userfile then v.pci.ad.ad := tbi.data; end if;
124
    end if;
125
 
126
    if tbi.userfile then
127
      v.address := (filedata.address(31 downto 2) + conv_std_logic_vector(v.current_word,30)) & "00";
128
      comm := filedata.command;
129
      v.pci.ad.ad := filedata.data;
130
      v.burst := not filedata.last;
131
      stop := filedata.last;
132
    end if;
133
 
134
    v.pci.ad.par := xorv(r.pci.ad.ad & r.pci.ad.cbe);
135
    v.paren := r.read;
136
 
137
    if (pciin.ifc.devsel and not pciin.ifc.stop) = '1' and r.running = '1' then
138
      status := ERR;
139
    elsif r.tocnt = T_O then
140
      status := TIMEOUT;
141
    else
142
        status := OK;
143
    end if;
144
 
145
    case r.state is
146
    when idle =>
147
      v.pci.arb.req(slot) := not (r.running and r.pcien(1));
148
      v.pci.ifc.irdy := '1'; dataintrans := 0;
149
      if r.grant = '1' then
150
        v.state := active; v.pci.ifc.frame := '0'; v.read := '0';
151
        v.pcien(0) := '0'; v.pci.ad.ad := v.address; v.pci.ad.cbe := comm;
152
      end if;
153
    when active =>
154
      v.tocnt := r.tocnt + 1; v.pcien(0) := '0';
155
      v.pci.ifc.irdy := '0';
156
      v.pci.ad.cbe := (others => '0');
157
      v.pci.arb.req(slot) := not (r.burst and not pciin.ifc.frame);
158
      if (pciin.ifc.irdy or (pciin.ifc.trdy and pciin.ifc.stop)) = '0' then
159
        if pciin.ifc.trdy = '0' then
160
          v.current_word := r.current_word+1; v.data := pciin.ad.ad;
161
          dataintrans := dataintrans+1;
162
        end if;
163
      end if;
164
      if pciin.ifc.devsel = '0' then v.tocnt := 0; end if;
165
      if ((v.current_word+conv_integer(r.burst)) >= tbi.no_words and tbi.userfile = false) then
166
        stop := '1';
167
        if pciin.ifc.frame = '1' then
168
          if pciin.ifc.trdy = '0' then
169
            v.running := '0'; v.pci.ifc.irdy := '1'; v.pcien(0) := '1';
170
          elsif (pciin.ifc.trdy and not pciin.ifc.stop) = '1' then
171
            v.state := idle; v.pci.ifc.irdy := '1'; v.pcien(0) := '1';
172
            if dataintrans > 0 then
173
              v.address := (tbi.address(31 downto 2) + conv_std_logic_vector(v.current_word,30)) & "00";
174
            end if;
175
          end if;
176
        end if;
177
      elsif pciin.ifc.stop = '0' then
178
        v.pcien(0) := pciin.ifc.frame; stop := '1'; v.state := idle; v.pci.ifc.irdy := pciin.ifc.frame;
179
        if not tbi.userfile then v.address := (tbi.address(31 downto 2) + conv_std_logic_vector(v.current_word,30)) & "00"; end if;
180
      end if;
181
--      if (status /= OK or (r.running = '0' and ((pciin.ifc.irdy or not (pciin.ifc.trdy and pciin.ifc.stop)) = '1' or tbi.userfile = true))) then
182
      if (r.status /= OK or ((pciin.ifc.frame and not pciin.ifc.irdy and not pciin.ifc.trdy) = '1')) then
183
        v.state := done; v.pci.ifc.irdy := '1'; v.pcien(0) := '1'; v.pci.arb.req(slot) := '1';
184
      end if;
185
      v.pci.ifc.frame := not (r.burst and not stop);
186
    when done =>
187
      v.running := '0'; ready := '1';
188
      if tbi.start = '0' then
189
        v.state := idle;
190
        v.current_word := 0;
191
      end if;
192
    when others =>
193
    end case;
194
 
195
    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));
196
 
197
    if pciin.syst.rst = '0' then
198
      v.pcien := (others => '1');
199
      v.state := idle;
200
      v.read := '0';
201
      v.burst := '0';
202
      v.grant := '0';
203
      v.address := (others => '0');
204
      v.data := (others => '0');
205
      v.current_word := 0;
206
      v.running := '0';
207
      v.pci := pci_idle;
208
    end if;
209
 
210
    tbo.ready <= ready;
211
    v.status := status;
212
    tbo.status <= status;
213
    tbo.data <= r.data;
214
    rin <= v;
215
  end process;
216
 
217
  clockreg : process(pciin.syst)
218
  file readfile,writefile : text;
219
  variable L : line;
220
  variable datahex : string(1 to 8);
221
  variable count : integer;
222
  begin
223
    if pciin.syst.rst = '0' then
224
      filedata.address <= (others => '0');
225
      filedata.data <= (others => '0');
226
      filedata.command <= (others => '0');
227
      filedata.last <= '0';
228
      filedata.openrfile <= '0';
229
      filedata.openwfile <= '0';
230
    elsif rising_edge(pciin.syst.clk) then
231
--      r <= rin;
232
      if tbi.usewfile then
233
        case r.state is
234
        when idle =>
235
          if (tbi.start and not filedata.openwfile) = '1' then
236
            file_open(writefile, external_name => tbi.wfile(18 downto trimlen(tbi.wfile)), open_kind => write_mode);
237
            filedata.openwfile <= '1';
238
            count := 0;
239
          end if;
240
        when active =>
241
          if (pciin.ifc.trdy or pciin.ifc.irdy) = '0' then
242
            if (tbi.userfile = false or count > 0) then
243
              write(L,printhex(pciin.ad.ad,32));
244
              writeline(writefile,L);
245
            end if;
246
            count := count+1;
247
          end if;
248
          if rin.state = done then
249
            file_close(writefile);
250
            filedata.openwfile <= '0';
251
          end if;
252
        when others =>
253
        end case;
254
      end if;
255
      if tbi.userfile then
256
        case r.state is
257
        when idle =>
258
          if (tbi.start and not filedata.openrfile) = '1' then
259
            filedata.last <= '0'; filedata.openrfile <= '1';
260
            file_open(readfile,external_name => tbi.rfile(18 downto trimlen(tbi.rfile)), open_kind => read_mode);
261
            readline(readfile,L); -- Dummy read for header
262
            readline(readfile,L); read(L,datahex);
263
            filedata.address <= conv_std_logic_vector(datahex,32);
264
            readline(readfile,L); read(L,datahex);
265
            filedata.command <= conv_std_logic_vector(datahex,4);
266
            readline(readfile,L); -- Dummy read for header
267
            readline(readfile,L); read(L,datahex);
268
            filedata.data <= conv_std_logic_vector(datahex,32);
269
          end if;
270
        when active =>
271
          if (pciin.ifc.trdy or pciin.ifc.irdy) = '0' then
272
            if not endfile(readfile) then
273
              readline(readfile,L); read(L,datahex);
274
              filedata.data <= conv_std_logic_vector(datahex,32);
275
              r.pci.ad.ad <= conv_std_logic_vector(datahex,32);
276
            end if;
277
            if endfile(readfile) then filedata.last <= '1'; r.pci.ifc.frame <= '1'; r.running <= '0'; end if;
278
          end if;
279
        when done =>
280
            if tbi.start = '0' then
281
              file_close(readfile); filedata.openrfile <= '0';
282
            end if;
283
        when others =>
284
        end case;
285
      end if;
286
    end if;
287
    if rising_edge(pciin.syst.clk) then
288
      r <= rin;
289
    end if;
290
  end process;
291
 
292
  pciout.ad.ad <= r.pci.ad.ad after tval when (r.read or r.pcien(0)) = '0' else (others => 'Z') after tval;
293
  pciout.ad.cbe <= r.pci.ad.cbe after tval when r.pcien(0) = '0' else (others => 'Z') after tval;
294
  pciout.ad.par <= r.pci.ad.par after tval when (r.paren or r.pcien(1)) = '0' else 'Z' after tval;
295
  pciout.ifc.frame <= r.pci.ifc.frame after tval when r.pcien(0) = '0' else 'Z' after tval;
296
  pciout.ifc.irdy <= r.pci.ifc.irdy after tval when r.pcien(1) = '0' else 'Z' after tval;
297
  pciout.err.perr <= r.pci.err.perr after tval when r.pcien(2) = '0' else 'Z' after tval;
298
  pciout.err.serr <= r.pci.err.serr after tval when r.pcien(2) = '0' else 'Z' after tval;
299
  pciout.arb.req(slot) <= r.pci.arb.req(slot) after tval;
300
 
301
end;
302
 
303
-- pragma translate_on

powered by: WebSVN 2.1.0

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