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/] [pci_mt.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:      pci_mt
20
-- File:        pci_mt.vhd
21
-- Author:      Jiri Gaisler - Gaisler Research
22
-- Modified:    Alf Vaerneus - Gaisler Research
23
-- Description: Simple PCI master and target interface
24
------------------------------------------------------------------------------
25
 
26
library ieee;
27
use ieee.std_logic_1164.all;
28
library grlib;
29
use grlib.amba.all;
30
use grlib.stdlib.all;
31
use grlib.devices.all;
32
library gaisler;
33
use gaisler.pci.all;
34
use gaisler.misc.all;
35
use gaisler.pcilib.all;
36
 
37
entity pci_mt is
38
  generic (
39
    hmstndx   : integer := 0;
40
    abits     : integer := 21;
41
    device_id : integer := 0;            -- PCI device ID
42
    vendor_id : integer := 0;            -- PCI vendor ID
43
    master    : integer := 1;           -- Enable PCI Master
44
    hslvndx   : integer := 0;
45
    haddr     : integer := 16#F00#;
46
    hmask     : integer := 16#F00#;
47
    ioaddr    : integer := 16#000#;
48
    nsync     : integer range 1 to 2 := 1;      -- 1 or 2 sync regs between clocks
49
    oepol     : integer := 0
50
);
51
   port(
52
      rst       : in std_logic;
53
      clk       : in std_logic;
54
      pciclk    : in std_logic;
55
      pcii      : in  pci_in_type;
56
      pcio      : out pci_out_type;
57
      ahbmi     : in  ahb_mst_in_type;
58
      ahbmo     : out ahb_mst_out_type;
59
      ahbsi     : in  ahb_slv_in_type;
60
      ahbso     : out ahb_slv_out_type
61
);
62
end;
63
 
64
architecture rtl of pci_mt is
65
 
66
constant REVISION : amba_version_type := 0;
67
 
68
constant hconfig : ahb_config_type := (
69
 
70
  4 => ahb_membar(haddr, '0', '0', hmask),
71
  5 => ahb_iobar (ioaddr, 16#E00#),
72
  others => zero32);
73
 
74
constant CSYNC : integer := nsync-1;
75
constant MADDR_WIDTH : integer := abits;
76
constant HADDR_WIDTH : integer := 28;
77
 
78
type pci_input_type is record
79
  ad       : std_logic_vector(31 downto 0);
80
  cbe      : std_logic_vector(3 downto 0);
81
  frame    : std_logic;
82
  devsel   : std_logic;
83
  idsel    : std_logic;
84
  trdy     : std_logic;
85
  irdy     : std_logic;
86
  par      : std_logic;
87
  stop     : std_logic;
88
  rst      : std_logic;
89
  gnt      : std_logic;
90
end record;
91
 
92
type ahbs_input_type is record
93
  haddr    : std_logic_vector(HADDR_WIDTH - 1 downto 0);
94
  htrans   : std_logic_vector(1 downto 0);
95
  hwrite   : std_logic;
96
  hsize    : std_logic_vector(1 downto 0);
97
  hburst   : std_logic_vector(2 downto 0);
98
  hwdata   : std_logic_vector(31 downto 0);
99
  hsel     : std_logic;
100
  hiosel     : std_logic;
101
  hready   : std_logic;
102
end record;
103
 
104
 
105
type pci_target_state_type is (idle, b_busy, s_data, backoff, turn_ar);
106
type pci_master_state_type is (idle, addr, m_data, turn_ar, s_tar, dr_bus);
107
type pci_config_command_type is record
108
  ioen     : std_logic; -- I/O access enable
109
  men      : std_logic; -- Memory access enable
110
  msen     : std_logic; -- Master enable
111
  spcen    : std_logic; -- Special cycle enable
112
  mwie     : std_logic; -- Memory write and invalidate enable
113
  vgaps    : std_logic; -- VGA palette snooping enable
114
  per      : std_logic; -- Parity error response enable
115
  wcc      : std_logic; -- Address stepping enable
116
  serre    : std_logic; -- Enable SERR# driver
117
  fbtbe    : std_logic; -- Fast back-to-back enable
118
end record;
119
type pci_config_status_type is record
120
  c66mhz   : std_logic; -- 66MHz capability
121
  udf      : std_logic; -- UDF supported
122
  fbtbc    : std_logic; -- Fast back-to-back capability
123
  dped     : std_logic; -- Data parity error detected
124
  dst      : std_logic_vector(1 downto 0); -- DEVSEL timing
125
  sta      : std_logic; -- Signaled target abort
126
  rta      : std_logic; -- Received target abort
127
  rma      : std_logic; -- Received master abort
128
  sse      : std_logic; -- Signaled system error
129
  dpe      : std_logic; -- Detected parity error
130
end record;
131
type pci_reg_type is record
132
  addr     : std_logic_vector(MADDR_WIDTH-1 downto 0);
133
  ad     : std_logic_vector(31 downto 0);
134
  cbe      : std_logic_vector(3 downto 0);
135
  lcbe      : std_logic_vector(3 downto 0);
136
  t_state  : pci_target_state_type; -- PCI target state machine
137
  m_state  : pci_master_state_type; -- PCI master state machine
138
  csel     : std_logic; -- Configuration chip select
139
  msel     : std_logic; -- Memory hit
140
  read     : std_logic;
141
  devsel   : std_logic; -- PCI device select
142
  trdy     : std_logic; -- Target ready
143
  irdy     : std_logic; -- Master ready
144
  stop     : std_logic; -- Target stop request
145
  par      : std_logic; -- PCI bus parity
146
  req      : std_logic; -- Master bus request
147
  oe_par   : std_logic;
148
  oe_ad    : std_logic;
149
  oe_trdy  : std_logic;
150
  oe_devsel: std_logic;
151
  oe_ctrl  : std_logic;
152
  oe_cbe   : std_logic;
153
  oe_stop  : std_logic;
154
  oe_frame : std_logic;
155
  oe_irdy  : std_logic;
156
  oe_req   : std_logic;
157
  noe_par   : std_logic;
158
  noe_ad    : std_logic;
159
  noe_trdy  : std_logic;
160
  noe_devsel: std_logic;
161
  noe_ctrl  : std_logic;
162
  noe_cbe   : std_logic;
163
  noe_stop  : std_logic;
164
  noe_frame : std_logic;
165
  noe_irdy  : std_logic;
166
  noe_req   : std_logic;
167
  request  : std_logic; -- Request from Back-end
168
  frame    : std_logic; -- Master frame
169
  bar0     : std_logic_vector(31 downto MADDR_WIDTH);
170
  page     : std_logic_vector(31 downto MADDR_WIDTH-1);
171
  comm     : pci_config_command_type;
172
  stat     : pci_config_status_type;
173
  laddr    : std_logic_vector(31 downto 0);
174
  ldata    : std_logic_vector(31 downto 0);
175
  pwrite   : std_logic;
176
  hwrite   : std_logic;
177
  start    : std_logic;
178
  hreq     : std_logic;
179
  hreq_ack : std_logic_vector(csync downto 0);
180
  preq     : std_logic_vector(csync downto 0);
181
  preq_ack : std_logic;
182
  rready   : std_logic_vector(csync downto 0);
183
  wready   : std_logic_vector(csync downto 0);
184
  sync     : std_logic_vector(csync downto 0);
185
  pabort   : std_logic;
186
  mcnt     : std_logic_vector(2 downto 0);
187
  maddr    : std_logic_vector(31 downto 0);
188
  mdata    : std_logic_vector(31 downto 0);
189
  stop_req : std_logic;
190
end record;
191
 
192
type cpu_master_state_type is (idle, sync1, busy, sync2);
193
type cpu_slave_state_type is (idle, getd, req, sync, read, sync2, t_done);
194
 
195
type cpu_reg_type is record
196
  tdata     : std_logic_vector(31 downto 0); -- Target data
197
  maddr     : std_logic_vector(31 downto 0); -- Master data
198
  mdata     : std_logic_vector(31 downto 0); -- Master data
199
  be       : std_logic_vector(3 downto 0);
200
  m_state  : cpu_master_state_type; -- AMBA master state machine
201
  s_state  : cpu_slave_state_type; -- AMBA slave state machine
202
  start    : std_logic_vector(csync downto 0);
203
  hreq     : std_logic_vector(csync downto 0);
204
  hreq_ack : std_logic;
205
  preq     : std_logic;
206
  preq_ack : std_logic_vector(csync downto 0);
207
  sync     : std_logic;
208
  hwrite   : std_logic; -- AHB write on PCI
209
  pabort   : std_logic_vector(csync downto 0);
210
  perror   : std_logic;
211
  rready   : std_logic;
212
  wready   : std_logic;
213
  hrdata   : std_logic_vector(31 downto 0);
214
  hresp    : std_logic_vector(1 downto 0);
215
  pciba    : std_logic_vector(3 downto 0);
216
end record;
217
 
218
signal clk_int : std_logic;
219
signal pr : pci_input_type;
220
signal hr : ahbs_input_type;
221
signal r, rin : pci_reg_type;
222
signal r2, r2in : cpu_reg_type;
223
signal dmai : ahb_dma_in_type;
224
signal dmao : ahb_dma_out_type;
225
signal roe_ad, rioe_ad : std_logic_vector(31 downto 0);
226
attribute syn_preserve : boolean;
227
attribute syn_preserve of roe_ad : signal is true;
228
begin
229
 
230
-- Back-end state machine (AHB clock domain)
231
 
232
  comb : process (rst, r2, r, dmao, hr, ahbsi)
233
  variable vdmai : ahb_dma_in_type;
234
  variable v : cpu_reg_type;
235
  variable request : std_logic;
236
  variable hready : std_logic;
237
  variable hresp, hsize, htrans : std_logic_vector(1 downto 0);
238
  variable p_done : std_logic;
239
  begin
240
    v := r2;
241
    vdmai.start := '0'; vdmai.burst := '0'; vdmai.size := "10";
242
    vdmai.address := r.laddr; v.sync := '1';
243
    vdmai.wdata := r.ldata; vdmai.write := r.pwrite;
244
    v.start(0) := r2.start(csync); v.start(csync) := r.start;
245
    v.hreq(0) := r2.hreq(csync); v.hreq(csync) := r.hreq;
246
 
247
    v.pabort(0) := r2.pabort(csync); v.pabort(csync) := r.pabort;
248
    v.preq_ack(0) := r2.preq_ack(csync); v.preq_ack(csync) := r.preq_ack;
249
    hready := '1'; hresp := HRESP_OKAY; request := '0';
250
    hsize := "10"; htrans := "00";
251
    p_done := r2.hreq(0) or r2.pabort(0);
252
 
253
---- *** APB register access *** ----
254
 
255
    --if (apbi.psel and apbi.penable and apbi.pwrite) = '1' then
256
      --v.pciba := apbi.pwdata(31 downto 28);
257
    --end if;
258
    --apbo.prdata <= r2.pciba & addzero;
259
 
260
    if hr.hiosel = '1' then
261
      if hr.hwrite = '1' then v.pciba := ahbsi.hwdata(31 downto 28); end if;
262
      v.hrdata := r2.pciba & addzero(27 downto 0);
263
    end if;
264
 
265
---- *** AHB MASTER *** ----
266
 
267
    case r2.m_state is
268
    when idle =>
269
      v.sync := '0';
270
      if r2.start(0) = '1' then
271
        if  r.pwrite = '1' then v.m_state := sync1; v.wready := '0';
272
        else v.m_state := busy; vdmai.start := '1'; end if;
273
      end if;
274
    when sync1 =>
275
      if r2.start(0) = '0' then v.m_state := busy; vdmai.start := '1'; end if;
276
    when busy =>
277
      if dmao.active = '1' then
278
        if dmao.ready = '1' then
279
          v.rready := not r.pwrite; v.tdata := dmao.rdata; v.m_state := sync2;
280
        end if;
281
      else vdmai.start := '1'; end if;
282
    when sync2 =>
283
      if r2.start(0) = '0' then
284
        v.m_state := idle;  v.wready := '1'; v.rready := '0';
285
      end if;
286
    end case;
287
 
288
---- *** AHB MASTER END *** ----
289
 
290
---- *** AHB SLAVE *** ----
291
 
292
    if MASTER = 1 then
293
 
294
      if (hr.hready and hr.hsel) = '1' then
295
        hsize := hr.hsize; htrans := hr.htrans;
296
        if (hr.htrans(1) and r.comm.msen) = '1' then request := '1'; end if;
297
      end if;
298
 
299
      if (request = '1' and r2.s_state = idle) then
300
  v.maddr := r2.pciba & hr.haddr;
301
  v.hwrite := hr.hwrite;
302
  case hsize is
303
  when "00" => v.be := "1110"; -- Decode byte enable
304
  when "01" => v.be := "1100";
305
  when "10" => v.be := "0000";
306
  when others => v.be := "1111";
307
  end case;
308
      elsif r2.s_state = getd and r2.hwrite = '1' then
309
  v.mdata := hr.hwdata;
310
      end if;
311
 
312
      if r2.hreq(0) = '1' then v.hrdata := r.ldata; end if;
313
      if r2.preq_ack(0) = '1' then v.preq := '0'; end if;
314
      if r2.pabort(0) = '1' then v.perror := '1'; end if;
315
      if p_done = '0' then v.hreq_ack := '0'; end if;
316
 
317
    -- AHB slave state machine
318
      case r2.s_state is
319
      when idle => if request = '1' then v.s_state := getd; end if;
320
      when getd => v.s_state := req; v.preq := '1';
321
      when req => if r2.preq_ack(0) = '1' then v.s_state := sync; end if;
322
      when sync => if r2.preq_ack(0) = '0' then v.s_state := read; end if;
323
      when read =>
324
        if p_done = '1' then v.hreq_ack := '1'; v.s_state := sync2; end if;
325
      when sync2 => if p_done = '0' then v.s_state := t_done; end if;
326
      when t_done => if request = '1' then v.s_state := idle; end if;
327
      when others => v.s_state := idle;
328
      end case;
329
 
330
      if request = '1' then
331
        if r2.s_state = t_done then
332
      if r2.perror = '1' then hresp := HRESP_ERROR;
333
      else hresp := HRESP_OKAY; end if;
334
      v.perror := '0';
335
        else hresp := HRESP_RETRY; end if;
336
      end if;
337
 
338
      if r.comm.msen = '0' then hresp := HRESP_ERROR; end if; -- Master disabled
339
      if htrans(1) = '0' then hresp := HRESP_OKAY; end if; -- Response OK for BUSY and IDLE
340
      if (hresp /= HRESP_OKAY and (hr.hready and hr.hsel) = '1') then  -- insert one wait cycle
341
        hready := '0';
342
      end if;
343
 
344
      if hr.hready = '0' then hresp := r2.hresp; end if;
345
      v.hresp := hresp;
346
 
347
    end if;
348
 
349
---- *** AHB SLAVE END *** ----
350
 
351
    if rst = '0' then
352
      v.s_state := idle; v.rready := '0'; v.wready := '1';
353
      v.m_state := idle; v.preq := '0'; v.hreq_ack := '0';
354
      v.perror := '0'; v.be := (others => '1');
355
      v.pciba := (others => '0'); v.hresp := (others => '0');
356
    end if;
357
 
358
    r2in <= v; dmai <= vdmai;
359
 
360
    ahbso.hready <= hready;
361
    ahbso.hresp  <= hresp;
362
    ahbso.hrdata <= r2.hrdata;
363
 
364
  end process;
365
 
366
  ahbso.hconfig <= hconfig when MASTER = 1 else (others => zero32);
367
  ahbso.hsplit <= (others => '0');
368
  ahbso.hirq   <= (others => '0');
369
  ahbso.hindex <= hslvndx;
370
 
371
-- PCI target core (PCI clock domain)
372
 
373
  pcicomb : process(pcii.rst, pr, pcii, r, r2, roe_ad)
374
  variable v : pci_reg_type;
375
  variable chit, mhit, hit, ready, cwrite : std_logic;
376
  variable cdata, cwdata : std_logic_vector(31 downto 0);
377
  variable comp : std_logic; -- Last transaction cycle on PCI bus
378
  variable iready : std_logic;
379
  variable mto : std_logic;
380
  variable tad, mad : std_logic_vector(31 downto 0);
381
--      variable cbe : std_logic_vector(3 downto 0);
382
  variable caddr : std_logic_vector(7 downto 2);
383
  variable voe_ad : std_logic_vector(31 downto 0);
384
  variable oe_par   : std_logic;
385
  variable oe_ad    : std_logic;
386
  variable oe_ctrl  : std_logic;
387
  variable oe_trdy  : std_logic;
388
  variable oe_devsel: std_logic;
389
  variable oe_cbe   : std_logic;
390
  variable oe_stop  : std_logic;
391
  variable oe_frame : std_logic;
392
  variable oe_irdy  : std_logic;
393
  variable oe_req   : std_logic;
394
  begin
395
 
396
  -- Process defaults
397
    v := r; v.trdy := '1'; v.stop := '1'; v.frame := '1';
398
    v.oe_ad := '1'; v.devsel := '1'; v.oe_frame := '1';
399
    v.irdy := '1'; v.req := '1'; voe_ad := roe_ad;
400
    v.oe_req := '0'; v.oe_cbe := '1'; v.oe_irdy := '1';
401
    v.rready(0) := r.rready(csync); v.rready(csync) := r2.rready;
402
    v.wready(0) := r.wready(csync); v.wready(csync) := r2.wready;
403
    v.sync(0) := r.sync(csync); v.sync(csync) := r2.sync;
404
    v.preq(0) := r.preq(csync); v.preq(csync) := r2.preq;
405
    v.hreq_ack(0) := r.hreq_ack(csync); v.hreq_ack(csync) := r2.hreq_ack;
406
    comp := '0'; mto := '0'; tad := r.ad; mad := r.ad; v.stop_req := '0';
407
    --cbe := r.cbe;
408
 
409
 
410
----- *** PCI TARGET *** --------
411
 
412
-- address decoding
413
 
414
    if (r.t_state = s_data) and ((pr.irdy or r.trdy or r.read) = '0') then
415
      cwrite := r.csel;
416
      if ((r.msel and r.addr(MADDR_WIDTH-1)) = '1') and (pr.cbe = "0000") then
417
        v.page := pr.ad(31 downto MADDR_WIDTH-1);
418
      end if;
419
      if (pr.cbe = "0000") and  (r.addr(MADDR_WIDTH-1) = '1') then
420
      end if;
421
    else cwrite := '0'; end if;
422
    cdata := (others => '0'); caddr :=  r.addr(7 downto 2);
423
    case caddr is
424
    when "000000" =>                    -- 0x00, device & vendor id
425
      cdata := conv_std_logic_vector(DEVICE_ID, 16) &
426
      conv_std_logic_vector(VENDOR_ID, 16);
427
    when "000001" =>                    -- 0x04, status & command
428
      cdata(1) := r.comm.men; cdata(2) := r.comm.msen; cdata(25) := '1';
429
      cdata(28) := r.stat.rta; cdata(29) := r.stat.rma;
430
    when "000010" =>                    -- 0x08, class code & revision
431
    when "000011" =>                    -- 0x0c, latency & cacheline size
432
    when "000100" =>                    -- 0x10, BAR0
433
      cdata(31 downto MADDR_WIDTH) := r.bar0;
434
    when others =>
435
    end case;
436
 
437
    cwdata := pr.ad;
438
    if pr.cbe(3) = '1' then cwdata(31 downto 24) := cdata(31 downto 24); end if;
439
    if pr.cbe(2) = '1' then cwdata(23 downto 16) := cdata(23 downto 16); end if;
440
    if pr.cbe(1) = '1' then cwdata(15 downto  8) := cdata(15 downto  8); end if;
441
    if pr.cbe(0) = '1' then cwdata( 7 downto  0) := cdata( 7 downto  0); end if;
442
    if cwrite = '1' then
443
      case caddr is
444
      when "000001" =>                  -- 0x04, status & command
445
        v.comm.men := cwdata(1);
446
        v.comm.msen := cwdata(2);
447
        v.stat.rta := r.stat.rta and not cwdata(28);
448
        v.stat.rma := r.stat.rma and not cwdata(29);
449
      when "000100" =>                  -- 0x10, BAR0
450
        v.bar0 := cwdata(31 downto MADDR_WIDTH);
451
      when others =>
452
      end case;
453
    end if;
454
 
455
    if (((pr.cbe = pci_config_read) or (pr.cbe = pci_config_write))
456
    and (pr.ad(1 downto 0) = "00"))
457
    then chit := '1'; else chit := '0'; end if;
458
    if ((pr.cbe = pci_memory_read) or (pr.cbe = pci_memory_write))
459
  and (r.bar0 = pr.ad(31 downto MADDR_WIDTH))
460
  and (r.bar0 /= zero(31 downto MADDR_WIDTH))
461
    then mhit := '1'; else mhit := '0'; end if;
462
    hit := r.csel or r.msel;
463
    ready := r.csel or (r.rready(0) and r.read) or (r.wready(0) and not r.read and not r.start) or
464
   r.addr(MADDR_WIDTH-1);
465
 
466
-- target state machine
467
 
468
    case r.t_state is
469
    when idle  =>
470
      if pr.frame = '0' then v.t_state := b_busy; end if; -- !HIT ?
471
      v.addr := pr.ad(MADDR_WIDTH-1 downto 0); -- v.cbe := pr.cbe;
472
      v.csel := pr.idsel and chit;
473
      v.msel := r.comm.men and mhit; v.read := not pr.cbe(0);
474
      if (r.sync(0) and r.start and r.pwrite)  = '1' then v.start := '0'; end if;
475
    when turn_ar =>
476
      if pr.frame = '1' then v.t_state := idle; end if;
477
      if pr.frame = '0' then v.t_state := b_busy; end if; -- !HIT ?
478
      v.addr := pr.ad(MADDR_WIDTH-1 downto 0); -- v.cbe := pr.cbe;
479
      v.csel := pr.idsel and chit;
480
      v.msel := r.comm.men and mhit; v.read := not pr.cbe(0);
481
      if (r.sync(0) and r.start and r.pwrite)  = '1' then v.start := '0'; end if;
482
    when b_busy  =>
483
      if hit = '1' then
484
        v.t_state := s_data; v.trdy := not ready; v.stop := pr.frame and ready;
485
        v.devsel := '0';
486
      else
487
        v.t_state := backoff;
488
      end if;
489
    when s_data  =>
490
      v.stop := r.stop; v.devsel := '0';
491
      v.trdy := r.trdy or not pcii.irdy;
492
      if (pcii.frame and not pcii.irdy) = '1' then
493
        v.t_state := turn_ar; v.stop := '1'; v.trdy := '1'; v.devsel := '1';
494
      end if;
495
    when backoff =>
496
      if pr.frame = '1' then v.t_state := idle; end if;
497
    end case;
498
 
499
    if ((r.t_state = s_data) or (r.t_state = turn_ar)) and
500
       (((pr.irdy or pr.trdy) = '0') or
501
        ((not pr.irdy and not pr.stop and pr.trdy and not r.start and r.wready(0)) = '1'))
502
    then
503
      if (pr.trdy and r.read)= '0' then v.start := '0'; end if;
504
      if (r.start = '0') and ((r.msel and not r.addr(MADDR_WIDTH-1)) = '1') and
505
      (((pr.trdy and r.read and not r.rready(0)) or (not pr.trdy and not r.read)) = '1')
506
      then
507
        v.laddr := r.page & r.addr(MADDR_WIDTH-2 downto 0);
508
        v.ldata := pr.ad; v.pwrite := not r.read; v.start := '1';
509
      end if;
510
    end if;
511
 
512
--    if (v.t_state = s_data) and (r.read = '1') then v.oe_ad := '0'; end if;
513
--    v.oe_par := r.oe_ad;
514
 
515
    if r.csel = '1' then tad := cdata;
516
    elsif r.addr(MADDR_WIDTH-1) = '1' then
517
      tad(31 downto MADDR_WIDTH-1) := r.page;
518
      tad(MADDR_WIDTH-2 downto 0) := (others => '0');
519
    else tad := r2.tdata; end if;
520
 
521
    if (v.t_state = s_data) or (r.t_state = s_data) then
522
      v.oe_ctrl := '0';
523
    else v.oe_ctrl := '1'; end if;
524
 
525
----- *** PCI TARGET END*** --------
526
 
527
----- *** PCI MASTER *** --------
528
 
529
  if MASTER = 1 then
530
 
531
    if r.preq(0) = '1' then
532
          if (r.m_state = idle or r.m_state = dr_bus) and r.request = '0' and r.hreq = '0' then
533
        v.request := '1';
534
        v.hwrite := r2.hwrite;
535
        v.lcbe := r2.be;
536
        v.mdata := r2.mdata;
537
        v.maddr :=r2.maddr;
538
      end if;
539
    end if;
540
 
541
    if r.hreq_ack(0) = '1' then v.hreq := '0'; v.pabort := '0'; end if;
542
    if r.preq(0) = '0' then v.preq_ack := '0'; end if;
543
 
544
    comp := not(pcii.trdy or pcii.irdy);
545
 
546
    if ((pr.irdy and not pr.frame) or (pr.devsel and r.frame and not r.oe_frame)) = '1' then -- Covers both master timeout and devsel timeout
547
      if r.mcnt /= "000" then v.mcnt := r.mcnt - 1;
548
      else mto := '1'; end if;
549
    else v.mcnt := (others => '1'); end if;
550
 
551
 
552
    -- PCI master state machine
553
    case r.m_state is
554
    when idle => -- Master idle
555
      if (pr.gnt = '0' and (pr.frame and pr.irdy) = '1') then
556
        if r.request = '1' then v.m_state := addr; v.preq_ack := '1';
557
        else v.m_state := dr_bus; end if;
558
      end if;
559
    when addr => -- Always one address cycle at the beginning of an transaction
560
      v.m_state := m_data;
561
    when m_data => -- Master transfers data
562
        --if (r.request and not pr.gnt and pr.frame and not pr.trdy -- Not supporting address stepping!
563
        --and pr.stop and l_cycle and sa) = '1' then
564
        --v.m_state <= addr;
565
      v.hreq := comp;
566
      if (pr.frame = '0') or ((pr.frame and pcii.trdy and pcii.stop and not mto) = '1') then
567
        v.m_state := m_data;
568
      elsif ((pr.frame and (mto or not pcii.stop)) = '1') then
569
        v.m_state := s_tar;
570
      else v.m_state := turn_ar; v.request := '0'; end if;
571
    when turn_ar => -- Transaction complete
572
      if (r.request and not pr.gnt) = '1' then v.m_state := addr;
573
      elsif (r.request or pr.gnt) = '0' then v.m_state := dr_bus;
574
      else v.m_state := idle; end if;
575
    when s_tar => -- Stop was asserted
576
      v.request := pr.trdy and not pr.stop and not pr.devsel;
577
      v.stop_req := '1';
578
      if (pr.stop or pr.devsel or pr.trdy) = '0' then -- Disconnect with data
579
        v.m_state := turn_ar;
580
      elsif pr.gnt = '0' then
581
        v.pabort := not v.request;
582
        v.m_state := dr_bus;
583
      else v.m_state := idle; v.pabort := not v.request; end if;
584
    when dr_bus => -- Drive bus when parked on this agent
585
      if (r.request = '1' and (pcii.gnt or r.req) = '0') then v.m_state := addr; v.preq_ack := '1';
586
      elsif pcii.gnt = '1' then v.m_state := idle; end if;
587
    end case;
588
 
589
    if v.m_state = addr then mad := r.maddr; else mad := r.mdata; end if;
590
 
591
    if (pr.irdy or pr.trdy or r.hwrite) = '0'  then v.ldata := pr.ad; end if;
592
 
593
    -- Target abort
594
    if ((pr.devsel and pr.trdy and not pr.gnt and not pr.stop) = '1') then v.stat.rta := '1'; end if;
595
    -- Master abort
596
    if mto = '1' then v.stat.rma := '1'; end if;
597
 
598
    -- Drive FRAME# and IRDY#
599
    if (v.m_state = addr or v.m_state = m_data) then v.oe_frame := '0'; end if;
600
 
601
    -- Drive CBE#
602
    if (v.m_state = addr or v.m_state = m_data or v.m_state = dr_bus) then v.oe_cbe := '0'; end if;
603
 
604
    -- Drive IRDY# (FRAME# delayed one pciclk)
605
    v.oe_irdy := r.oe_frame;
606
 
607
    -- FRAME# assert
608
      if v.m_state = addr then v.frame := '0'; end if; -- Only single transfers valid
609
 
610
    -- IRDY# assert
611
    if v.m_state = m_data then v.irdy := '0'; end if;
612
 
613
    -- REQ# assert
614
    if (v.request = '1' and (v.m_state = idle or r.m_state = idle) and (v.stop_req or r.stop_req) = '0') then v.req := '0'; end if;
615
 
616
    -- C/BE# assert
617
    if v.m_state = addr then v.cbe := "011" & r.hwrite; else v.cbe := r.lcbe; end if;
618
 
619
  end if;
620
 
621
----- *** PCI MASTER END *** --------
622
 
623
----- *** SHARED BUS SIGNALS *** -------
624
 
625
    -- Drive PAR
626
    v.oe_par := r.oe_ad; --Delayed one clock
627
    v.par := xorv(r.ad & r.cbe); -- Default asserted by master
628
    v.ad := mad;  -- Default asserted by master
629
    -- Master
630
    if (v.m_state = addr or (v.m_state = m_data and r.hwrite = '1') or v.m_state = dr_bus) then
631
      v.oe_ad := '0';
632
    end if;
633
 
634
    -- Drive AD
635
    -- Target
636
    if r.read = '1' then
637
      if v.t_state = s_data then
638
        v.oe_ad := '0';
639
        v.ad := tad;
640
      elsif r.t_state = s_data then
641
        v.par := xorv(r.ad & pcii.cbe);
642
      end if;
643
    end if;
644
 
645
    v.oe_stop := v.oe_ctrl; v.oe_devsel := v.oe_ctrl; v.oe_trdy := v.oe_ctrl;
646
    v.noe_ad := not v.oe_ad; v.noe_ctrl := not v.oe_ctrl;
647
    v.noe_par := not v.oe_par; v.noe_req := not v.oe_req;
648
    v.noe_frame := not v.oe_frame; v.noe_cbe := not v.oe_cbe;
649
    v.noe_irdy := not v.oe_irdy;
650
    v.noe_stop := not v.oe_ctrl; v.noe_devsel := not v.oe_ctrl;
651
    v.noe_trdy := not v.oe_ctrl;
652
 
653
    if oepol  = 0 then
654
      voe_ad := (others => v.oe_ad);
655
      oe_ad := r.oe_ad; oe_ctrl := r.oe_ctrl; oe_par := r.oe_par;
656
      oe_req := r.oe_req; oe_frame := r.oe_frame; oe_cbe := r.oe_cbe;
657
      oe_irdy := r.oe_irdy; oe_stop := r.oe_stop; oe_trdy := r.oe_trdy;
658
      oe_devsel := r.oe_devsel;
659
    else
660
      voe_ad := (others => v.noe_ad);
661
      oe_ad := r.noe_ad; oe_ctrl := r.noe_ctrl; oe_par := r.noe_par;
662
      oe_req := r.noe_req; oe_frame := r.noe_frame; oe_cbe := r.noe_cbe;
663
      oe_irdy := r.noe_irdy; oe_stop := r.noe_stop; oe_trdy := r.noe_trdy;
664
      oe_devsel := r.noe_devsel;
665
    end if;
666
 
667
----- *** SHARED BUS SIGNALS END *** -------
668
 
669
    if pr.rst = '0' then
670
      v.t_state := idle; v.m_state := idle; v.comm.men := '0'; v.start := '0';
671
      v.bar0 := (others => '0'); v.msel := '0'; v.csel := '0';
672
      v.page := (others => '0'); v.page(31 downto 30) := "01"; v.par := '0';
673
      v.hwrite := '0'; v.request := '0'; v.comm.msen := '0';
674
      v.laddr := (others => '0'); v.ldata := (others => '0');
675
      v.hreq := '0'; v.preq_ack := '0'; v.pabort := '0';
676
      v.mcnt := (others => '1'); v.maddr := (others => '0');
677
      v.lcbe := (others => '0'); v.mdata := (others => '0');
678
      v.pwrite := '0'; v.stop_req := '0';
679
      v.stat.rta := '0'; v.stat.rma := '0';
680
    end if;
681
    rin <= v;
682
    rioe_ad <= voe_ad;
683
 
684
    pcio.reqen    <= oe_req;
685
    pcio.req      <= r.req;
686
    pcio.frameen  <= oe_frame;
687
    pcio.frame    <= r.frame;
688
    pcio.irdyen   <= oe_irdy;
689
    pcio.irdy     <= r.irdy;
690
 
691
    pcio.cbeen    <= (others => oe_cbe);
692
    pcio.cbe      <= r.cbe;
693
 
694
    pcio.vaden    <= roe_ad;
695
    pcio.aden     <= oe_ad;
696
    pcio.ad       <= r.ad;
697
 
698
    pcio.trdy     <= r.trdy;
699
    pcio.ctrlen   <= oe_ctrl;
700
    pcio.trdyen   <= oe_trdy;
701
    pcio.devselen <= oe_devsel;
702
    pcio.stopen   <= oe_stop;
703
    pcio.stop     <= r.stop;
704
    pcio.devsel   <= r.devsel;
705
    pcio.par      <= r.par;
706
    pcio.paren    <= oe_par;
707
 
708
    pcio.rst      <= '1';
709
 
710
  end process;
711
 
712
  pcir : process (pciclk, pcii.rst)
713
  begin
714
    if rising_edge (pciclk) then
715
      pr.ad         <= to_x01(pcii.ad);
716
      pr.cbe        <= to_x01(pcii.cbe);
717
      pr.devsel     <= to_x01(pcii.devsel);
718
      pr.frame      <= to_x01(pcii.frame);
719
      pr.idsel      <= to_x01(pcii.idsel);
720
      pr.irdy       <= to_x01(pcii.irdy);
721
      pr.trdy       <= to_x01(pcii.trdy);
722
      pr.par        <= to_x01(pcii.par);
723
      pr.stop       <= to_x01(pcii.stop);
724
      pr.rst        <= to_x01(pcii.rst);
725
      pr.gnt        <= to_x01(pcii.gnt);
726
      r <= rin;
727
      roe_ad <= rioe_ad;
728
    end if;
729
    if pcii.rst = '0' then       -- asynch reset required
730
        r.oe_ad <= '1'; r.oe_ctrl <= '1'; r.oe_par <= '1'; r.oe_stop <= '1';
731
        r.oe_req <= '1'; r.oe_frame <= '1'; r.oe_cbe <= '1'; r.oe_irdy <= '1';
732
        r.oe_trdy <= '1'; r.oe_devsel <= '1';
733
 
734
        r.noe_ad <= '0'; r.noe_ctrl <= '0'; r.noe_par <= '0'; r.noe_req <= '0';
735
        r.noe_frame <= '0'; r.noe_cbe <= '0'; r.noe_irdy <= '0'; r.noe_stop <= '0';
736
        r.noe_trdy <= '0'; r.noe_devsel <= '0';
737
 
738
        if oepol = 0 then roe_ad <= (others => '1');
739
        else roe_ad <= (others => '0'); end if;
740
    end if;
741
  end process;
742
 
743
  cpur : process (rst,clk)
744
  begin
745
    if rising_edge (clk) then
746
      hr.haddr    <= ahbsi.haddr(HADDR_WIDTH - 1 downto 0);
747
      hr.htrans   <= ahbsi.htrans;
748
      hr.hwrite   <= ahbsi.hwrite;
749
      hr.hsize    <= ahbsi.hsize(1 downto 0);
750
      hr.hburst   <= ahbsi.hburst;
751
      hr.hwdata   <= ahbsi.hwdata;
752
      hr.hsel     <= ahbsi.hsel(hslvndx) and ahbsi.hmbsel(0);
753
      hr.hiosel   <= ahbsi.hsel(hslvndx) and ahbsi.hmbsel(1);
754
      hr.hready   <= ahbsi.hready;
755
      r2 <= r2in;
756
    end if;
757
  end process;
758
 
759
 
760
  oe0 : if oepol = 0 generate
761
    pcio.perren   <= '1';
762
    pcio.serren   <= '1';
763
    pcio.inten    <= '1';
764
    pcio.locken   <= '1';
765
  end generate;
766
 
767
  oe1 : if oepol = 1 generate
768
    pcio.perren   <= '0';
769
    pcio.serren   <= '0';
770
    pcio.inten    <= '0';
771
    pcio.locken   <= '0';
772
  end generate;
773
 
774
 
775
  pcio.perr     <= '1';
776
  pcio.serr     <= '1';
777
  pcio.int      <= '1';
778
 
779
 
780
 
781
 
782
 
783
  msttgt : if MASTER = 1 generate
784
 
785
    ahbmst0 : ahbmst generic map (hindex => hmstndx, devid => GAISLER_PCISBRG)
786
        port map (rst, clk, dmai, dmao, ahbmi, ahbmo);
787
 
788
-- pragma translate_off
789
    bootmsg : report_version
790
    generic map ("pci_mt" & tost(hslvndx) &
791
        ": Simple 32-bit PCI Bridge, rev " & tost(REVISION) &
792
        ", " & tost(2**abits/2**20) & " Mbyte PCI memory BAR" );
793
-- pragma translate_on
794
 
795
  end generate;
796
 
797
  tgtonly : if MASTER = 0 generate
798
    ahbmst0 : ahbmst generic map (hindex => hmstndx, devid => GAISLER_PCITRG)
799
        port map (rst, clk, dmai, dmao, ahbmi, ahbmo);
800
 
801
-- pragma translate_off
802
    bootmsg : report_version
803
    generic map ("pci_mt" & tost(hmstndx) &
804
        ": Simple 32-bit Bridge, target-only, rev " & tost(REVISION) &
805
        ", " & tost(2**abits/2**20) & " Mbyte PCI memory BAR" );
806
-- pragma translate_on
807
  end generate;
808
 
809
end;
810
 

powered by: WebSVN 2.1.0

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