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_mtf
|
20 |
|
|
-- File: pci_mtf.vhd
|
21 |
|
|
-- Author: Jiri Gaisler - Gaisler Research
|
22 |
|
|
-- Modified: Alf Vaerneus - Gaisler Research
|
23 |
|
|
-- Description: PCI master and target interface
|
24 |
|
|
------------------------------------------------------------------------------
|
25 |
|
|
|
26 |
|
|
library ieee;
|
27 |
|
|
use ieee.std_logic_1164.all;
|
28 |
|
|
use ieee.numeric_std.all;
|
29 |
|
|
|
30 |
|
|
library grlib;
|
31 |
|
|
use grlib.amba.all;
|
32 |
|
|
use grlib.stdlib.all;
|
33 |
|
|
use grlib.devices.all;
|
34 |
|
|
library techmap;
|
35 |
|
|
use techmap.gencomp.all;
|
36 |
|
|
library gaisler;
|
37 |
|
|
use gaisler.pci.all;
|
38 |
|
|
use gaisler.pcilib.all;
|
39 |
|
|
use gaisler.misc.all;
|
40 |
|
|
|
41 |
|
|
entity pci_mtf is
|
42 |
|
|
generic (
|
43 |
|
|
memtech : integer := DEFMEMTECH;
|
44 |
|
|
hmstndx : integer := 0;
|
45 |
|
|
dmamst : integer := NAHBMST;
|
46 |
|
|
readpref : integer := 0;
|
47 |
|
|
abits : integer := 21;
|
48 |
|
|
dmaabits : integer := 26;
|
49 |
|
|
fifodepth : integer := 3; -- FIFO depth
|
50 |
|
|
device_id : integer := 0; -- PCI device ID
|
51 |
|
|
vendor_id : integer := 0; -- PCI vendor ID
|
52 |
|
|
master : integer := 1; -- Enable PCI Master
|
53 |
|
|
hslvndx : integer := 0;
|
54 |
|
|
pindex : integer := 0;
|
55 |
|
|
paddr : integer := 0;
|
56 |
|
|
pmask : integer := 16#fff#;
|
57 |
|
|
haddr : integer := 16#F00#;
|
58 |
|
|
hmask : integer := 16#F00#;
|
59 |
|
|
ioaddr : integer := 16#000#;
|
60 |
|
|
irq : integer := 0;
|
61 |
|
|
irqmask : integer := 0;
|
62 |
|
|
nsync : integer range 1 to 2 := 2; -- 1 or 2 sync regs between clocks
|
63 |
|
|
oepol : integer := 0;
|
64 |
|
|
endian : integer := 0; -- 0 little, 1 big
|
65 |
|
|
class_code: integer := 16#0B4000#;
|
66 |
|
|
rev : integer := 0;
|
67 |
|
|
scanen : integer := 0;
|
68 |
|
|
syncrst : integer := 0;
|
69 |
|
|
hostrst : integer := 0);
|
70 |
|
|
port(
|
71 |
|
|
rst : in std_logic;
|
72 |
|
|
clk : in std_logic;
|
73 |
|
|
pciclk : in std_logic;
|
74 |
|
|
pcii : in pci_in_type;
|
75 |
|
|
pcio : out pci_out_type;
|
76 |
|
|
apbi : in apb_slv_in_type;
|
77 |
|
|
apbo : out apb_slv_out_type;
|
78 |
|
|
ahbmi : in ahb_mst_in_type;
|
79 |
|
|
ahbmo : out ahb_mst_out_type;
|
80 |
|
|
ahbsi : in ahb_slv_in_type;
|
81 |
|
|
ahbso : out ahb_slv_out_type
|
82 |
|
|
);
|
83 |
|
|
end;
|
84 |
|
|
|
85 |
|
|
architecture rtl of pci_mtf is
|
86 |
|
|
|
87 |
|
|
function byte_twist(di : in std_logic_vector(31 downto 0); enable : in std_logic) return std_logic_vector is
|
88 |
|
|
variable do : std_logic_vector(31 downto 0);
|
89 |
|
|
begin
|
90 |
|
|
if enable = '1' then
|
91 |
|
|
for i in 0 to 3 loop
|
92 |
|
|
do(31-i*8 downto 24-i*8) := di(31-(3-i)*8 downto 24-(3-i)*8);
|
93 |
|
|
end loop;
|
94 |
|
|
else
|
95 |
|
|
do := di;
|
96 |
|
|
end if;
|
97 |
|
|
return do;
|
98 |
|
|
end function;
|
99 |
|
|
|
100 |
|
|
function nr_of_1(di : in integer) return integer is
|
101 |
|
|
variable vec : unsigned(31 downto 0);
|
102 |
|
|
variable ones : integer;
|
103 |
|
|
begin
|
104 |
|
|
ones := 0;
|
105 |
|
|
vec := to_unsigned(di,32);
|
106 |
|
|
for i in 0 to 31 loop
|
107 |
|
|
if vec(i) = '1' then
|
108 |
|
|
ones := ones + 1;
|
109 |
|
|
end if;
|
110 |
|
|
end loop;
|
111 |
|
|
return ones;
|
112 |
|
|
end function;
|
113 |
|
|
|
114 |
|
|
constant REVISION : amba_version_type := rev;
|
115 |
|
|
constant CSYNC : integer := nsync-1;
|
116 |
|
|
constant HADDR_WIDTH : integer := 28;
|
117 |
|
|
constant MADDR_WIDTH : integer := abits;
|
118 |
|
|
constant DMAMADDR_WIDTH : integer := dmaabits;
|
119 |
|
|
constant FIFO_DEPTH : integer := fifodepth;
|
120 |
|
|
constant FIFO_FULL : std_logic_vector(FIFO_DEPTH - 2 downto 0) := (others => '1');
|
121 |
|
|
constant FIFO_DATA_BITS : integer := 32; -- One valid bit
|
122 |
|
|
constant NO_CPU_REGS : integer := 6;
|
123 |
|
|
constant NO_PCI_REGS : integer := 6;
|
124 |
|
|
constant HMASK_WIDTH : integer := nr_of_1(hmask);
|
125 |
|
|
|
126 |
|
|
constant pconfig : apb_config_type := (
|
127 |
|
|
|
128 |
|
|
1 => apb_iobar(paddr, pmask));
|
129 |
|
|
|
130 |
|
|
constant hconfig : ahb_config_type := (
|
131 |
|
|
|
132 |
|
|
4 => ahb_membar(haddr, '0', '0', hmask),
|
133 |
|
|
5 => ahb_iobar (ioaddr, 16#E00#),
|
134 |
|
|
others => zero32);
|
135 |
|
|
|
136 |
|
|
type pci_input_type is record
|
137 |
|
|
ad : std_logic_vector(31 downto 0);
|
138 |
|
|
cbe : std_logic_vector(3 downto 0);
|
139 |
|
|
frame : std_logic;
|
140 |
|
|
devsel : std_logic;
|
141 |
|
|
idsel : std_logic;
|
142 |
|
|
trdy : std_logic;
|
143 |
|
|
irdy : std_logic;
|
144 |
|
|
par : std_logic;
|
145 |
|
|
stop : std_logic;
|
146 |
|
|
gnt : std_logic;
|
147 |
|
|
host : std_logic;
|
148 |
|
|
end record;
|
149 |
|
|
|
150 |
|
|
type pci_fifo_in_type is record
|
151 |
|
|
ren : std_logic;
|
152 |
|
|
raddr : std_logic_vector(FIFO_DEPTH - 1 downto 0);
|
153 |
|
|
wen : std_logic;
|
154 |
|
|
waddr : std_logic_vector(FIFO_DEPTH - 1 downto 0);
|
155 |
|
|
wdata : std_logic_vector(FIFO_DATA_BITS - 1 downto 0);
|
156 |
|
|
end record;
|
157 |
|
|
|
158 |
|
|
type pci_fifo_out_type is record
|
159 |
|
|
rdata : std_logic_vector(FIFO_DATA_BITS - 1 downto 0);
|
160 |
|
|
end record;
|
161 |
|
|
|
162 |
|
|
type fifo_type is record
|
163 |
|
|
side : std_logic; -- Owner access side. Receiver accesses the other side
|
164 |
|
|
raddr : std_logic_vector(FIFO_DEPTH - 2 downto 0);
|
165 |
|
|
waddr : std_logic_vector(FIFO_DEPTH - 2 downto 0);
|
166 |
|
|
end record;
|
167 |
|
|
|
168 |
|
|
type pci_target_state_type is (idle, b_busy, s_data, backoff, turn_ar);
|
169 |
|
|
type pci_master_state_type is (idle, addr, m_data, turn_ar, s_tar, dr_bus);
|
170 |
|
|
type pci_master_fifo_state_type is (idle, addr, incr, last1, sync, t_retry, ttermwd, ttermnd, abort, done, wdone);
|
171 |
|
|
|
172 |
|
|
type pci_target_type is record
|
173 |
|
|
state : pci_target_state_type;
|
174 |
|
|
cnt : std_logic_vector(2 downto 0);
|
175 |
|
|
csel : std_logic; -- Configuration chip select
|
176 |
|
|
msel : std_logic; -- Memory hit
|
177 |
|
|
barsel : std_logic; -- Memory hit
|
178 |
|
|
psel : std_logic; -- Page hit
|
179 |
|
|
addr : std_logic_vector(31 downto 0);
|
180 |
|
|
laddr : std_logic_vector(31 downto 0);
|
181 |
|
|
lsize : std_logic_vector(1 downto 0);
|
182 |
|
|
lcbe : std_logic_vector(3 downto 0);
|
183 |
|
|
lwrite : std_logic;
|
184 |
|
|
lburst : std_logic;
|
185 |
|
|
lmult : std_logic;
|
186 |
|
|
mult : std_logic;
|
187 |
|
|
read : std_logic; -- PCI target read
|
188 |
|
|
burst : std_logic;
|
189 |
|
|
pending : std_logic;
|
190 |
|
|
wdel : std_logic;
|
191 |
|
|
last : std_logic;
|
192 |
|
|
fifo : fifo_type;
|
193 |
|
|
trdy_del : std_logic; -- (delay trdy to send last word in fifo) bug fix ***
|
194 |
|
|
end record;
|
195 |
|
|
|
196 |
|
|
type pci_master_type is record
|
197 |
|
|
state : pci_master_state_type;
|
198 |
|
|
fstate : pci_master_fifo_state_type;
|
199 |
|
|
cnt : std_logic_vector(2 downto 0);
|
200 |
|
|
ltim : std_logic_vector(7 downto 0); -- Latency timer
|
201 |
|
|
request : std_logic;
|
202 |
|
|
hwrite : std_logic;
|
203 |
|
|
stop_req : std_logic;
|
204 |
|
|
last : std_logic;
|
205 |
|
|
valid : std_logic;
|
206 |
|
|
split : std_logic;
|
207 |
|
|
first : std_logic;
|
208 |
|
|
firstw : std_logic;
|
209 |
|
|
fifo : fifo_type;
|
210 |
|
|
rmdone : std_logic; -- bug fix ***
|
211 |
|
|
stopframe: std_logic;
|
212 |
|
|
lto : std_logic; -- bug fix latency timer timeout
|
213 |
|
|
end record;
|
214 |
|
|
|
215 |
|
|
type pci_sync_regs is array (0 to NO_PCI_REGS - 1) of std_logic_vector(csync downto 0);
|
216 |
|
|
|
217 |
|
|
type pci_reg_type is record
|
218 |
|
|
pci : pci_sigs_type;
|
219 |
|
|
noe_par : std_logic;
|
220 |
|
|
noe_ad : std_logic;
|
221 |
|
|
noe_ctrl : std_logic;
|
222 |
|
|
noe_cbe : std_logic;
|
223 |
|
|
noe_frame : std_logic;
|
224 |
|
|
noe_irdy : std_logic;
|
225 |
|
|
noe_req : std_logic;
|
226 |
|
|
noe_perr : std_logic;
|
227 |
|
|
m : pci_master_type;
|
228 |
|
|
t : pci_target_type;
|
229 |
|
|
comm : pci_config_command_type; -- Command register
|
230 |
|
|
stat : pci_config_status_type; -- Status register
|
231 |
|
|
bar0 : std_logic_vector(31 downto MADDR_WIDTH); -- Base Address register 0
|
232 |
|
|
bar1 : std_logic_vector(31 downto DMAMADDR_WIDTH); -- Base Address register 1
|
233 |
|
|
bar0_conf : std_logic;
|
234 |
|
|
bar1_conf : std_logic;
|
235 |
|
|
page : std_logic_vector(31 downto MADDR_WIDTH-1); -- AHB page
|
236 |
|
|
bt_enable : std_logic; -- Byte twist enable, page0 bit 0
|
237 |
|
|
ltim : std_logic_vector(7 downto 0); -- Latency timer
|
238 |
|
|
cline : std_logic_vector(7 downto 0); -- Cache Line Size
|
239 |
|
|
intline : std_logic_vector(7 downto 0); -- Interrupt Line
|
240 |
|
|
syncs : pci_sync_regs;
|
241 |
|
|
trans : std_logic_vector(NO_CPU_REGS - 1 downto 0);
|
242 |
|
|
end record;
|
243 |
|
|
|
244 |
|
|
type cpu_master_state_type is (idle, cbe_prepare, write, read_w, read, stop);
|
245 |
|
|
type cpu_slave_state_type is (idle, w_wait, t_data, r_hold, r_wait, w_done, t_done);
|
246 |
|
|
|
247 |
|
|
type cpu_master_type is record
|
248 |
|
|
state : cpu_master_state_type; -- AMBA master state machine
|
249 |
|
|
dmaddr : std_logic_vector(31 downto 0);
|
250 |
|
|
fifo : fifo_type;
|
251 |
|
|
cbe_fifo : fifo_type;
|
252 |
|
|
cur_cbe : std_logic_vector(3 downto 0);
|
253 |
|
|
cbe_prep_cnt : std_ulogic;
|
254 |
|
|
read_half : std_logic;
|
255 |
|
|
last_side_wr : std_ulogic;
|
256 |
|
|
end record;
|
257 |
|
|
|
258 |
|
|
type cpu_slave_type is record
|
259 |
|
|
state : cpu_slave_state_type; -- AMBA slave state machine
|
260 |
|
|
maddr : std_logic_vector(31 downto 0);
|
261 |
|
|
mdata : std_logic_vector(31 downto 0);
|
262 |
|
|
be : std_logic_vector(3 downto 0);
|
263 |
|
|
perror : std_logic;
|
264 |
|
|
hresp : std_logic_vector(1 downto 0);
|
265 |
|
|
hready : std_logic;
|
266 |
|
|
htrans : std_logic_vector(1 downto 0);
|
267 |
|
|
hmaster : std_logic_vector(3 downto 0);
|
268 |
|
|
pcicomm : std_logic_vector(3 downto 0);
|
269 |
|
|
hold : std_logic;
|
270 |
|
|
fifos_write : std_logic;
|
271 |
|
|
fifo : fifo_type;
|
272 |
|
|
last_side : std_logic;
|
273 |
|
|
end record;
|
274 |
|
|
|
275 |
|
|
type cpu_sync_regs is array (0 to NO_CPU_REGS - 1) of std_logic_vector(csync downto 0);
|
276 |
|
|
|
277 |
|
|
type cpu_reg_type is record
|
278 |
|
|
m : cpu_master_type;
|
279 |
|
|
s : cpu_slave_type;
|
280 |
|
|
syncs : cpu_sync_regs;
|
281 |
|
|
trans : std_logic_vector(NO_PCI_REGS - 1 downto 0);
|
282 |
|
|
pciba : std_logic_vector(HMASK_WIDTH-1 downto 0);
|
283 |
|
|
cfto : std_logic;
|
284 |
|
|
wcomm : std_logic;
|
285 |
|
|
rcomm : std_logic;
|
286 |
|
|
werr : std_logic;
|
287 |
|
|
clscnt : std_logic_vector(8 downto 0);
|
288 |
|
|
dmapage : std_logic_vector(31 downto DMAMADDR_WIDTH); -- DMA page
|
289 |
|
|
ioba : std_logic_vector(15 downto 0);
|
290 |
|
|
pciirq : std_logic_vector(1 downto 0);
|
291 |
|
|
bus_nr : std_logic_vector(3 downto 0);
|
292 |
|
|
end record;
|
293 |
|
|
|
294 |
|
|
signal clk_int : std_logic;
|
295 |
|
|
signal pr : pci_input_type;
|
296 |
|
|
signal r, rin : pci_reg_type;
|
297 |
|
|
signal r2, r2in : cpu_reg_type;
|
298 |
|
|
signal dmai : ahb_dma_in_type;
|
299 |
|
|
signal dmao : ahb_dma_out_type;
|
300 |
|
|
signal fifo1i, fifo2i, fifo3i, fifo4i, cbe_fifoi : pci_fifo_in_type;
|
301 |
|
|
signal fifo1o, fifo2o, fifo3o, fifo4o, cbe_fifoo : pci_fifo_out_type;
|
302 |
|
|
signal roe_ad, rioe_ad : std_logic_vector(31 downto 0);
|
303 |
|
|
signal pcirst : std_logic;
|
304 |
|
|
signal prrst : std_logic;
|
305 |
|
|
signal pcirstin : std_logic;
|
306 |
|
|
attribute sync_set_reset : string;
|
307 |
|
|
attribute sync_set_reset of prrst : signal is "true";
|
308 |
|
|
attribute async_set_reset : string;
|
309 |
|
|
attribute async_set_reset of pcirst : signal is "true";
|
310 |
|
|
|
311 |
|
|
attribute syn_preserve : boolean;
|
312 |
|
|
attribute syn_preserve of roe_ad : signal is true;
|
313 |
|
|
begin
|
314 |
|
|
|
315 |
|
|
-----------------------------------------------
|
316 |
|
|
-- Back-end state machine (AHB clock domain) --
|
317 |
|
|
-----------------------------------------------
|
318 |
|
|
|
319 |
|
|
comb : process (rst, r2, r, dmao, ahbsi, fifo2o, fifo4o, apbi)
|
320 |
|
|
|
321 |
|
|
variable vdmai : ahb_dma_in_type;
|
322 |
|
|
variable v : cpu_reg_type;
|
323 |
|
|
variable hready : std_logic;
|
324 |
|
|
variable hresp, hsize : std_logic_vector(1 downto 0);
|
325 |
|
|
variable p_done, wsdone, wmdone, rtdone, rmdone : std_logic;
|
326 |
|
|
variable pstart, habort, hstart_ack : std_logic;
|
327 |
|
|
variable hstart, pabort, pstart_ack, pcidc : std_logic;
|
328 |
|
|
variable i : integer range 0 to NO_CPU_REGS;
|
329 |
|
|
variable fifom_write, fifos_write : std_logic;
|
330 |
|
|
variable prdata : std_logic_vector(31 downto 0);
|
331 |
|
|
variable wmvalid, wsvalid, rmvalid, rsvalid, burst_read, hold : std_logic;
|
332 |
|
|
variable fifors_limit, fifows_limit,fiform_limit, fifowm_limit, fifows_stop : std_logic;
|
333 |
|
|
variable comp, request, s_read_side, m_read_side : std_logic;
|
334 |
|
|
variable ahb_access : std_logic; -- *** access control fix
|
335 |
|
|
variable start, single_access : std_logic;
|
336 |
|
|
variable next_cbe : std_logic_vector(3 downto 0);
|
337 |
|
|
variable byteaddr : std_logic_vector(1 downto 0);
|
338 |
|
|
|
339 |
|
|
begin
|
340 |
|
|
|
341 |
|
|
|
342 |
|
|
v := r2;
|
343 |
|
|
vdmai.start := '0';
|
344 |
|
|
vdmai.irq := '0'; vdmai.busy := '0'; vdmai.burst := '1';
|
345 |
|
|
vdmai.wdata := fifo2o.rdata(31 downto 0); vdmai.write := r.t.lwrite;
|
346 |
|
|
rmvalid := '1'; wmvalid := '1'; request := '0'; hold := '0';
|
347 |
|
|
rsvalid := '1'; wsvalid := '1'; burst_read := '0';
|
348 |
|
|
hready := '1'; hresp := HRESP_OKAY; hsize := "10";
|
349 |
|
|
fifom_write := '0'; v.s.fifos_write := '0';
|
350 |
|
|
comp := '0'; prdata := (others => '0'); v.s.hold := '0';
|
351 |
|
|
s_read_side := not r.m.fifo.side; m_read_side := not r.t.fifo.side;
|
352 |
|
|
ahb_access := '0'; -- *** access control fix
|
353 |
|
|
|
354 |
|
|
-- Synch registers
|
355 |
|
|
pstart := r2.trans(0);
|
356 |
|
|
habort := r2.trans(1);
|
357 |
|
|
hstart_ack := r2.trans(2);
|
358 |
|
|
-- fifows_limit := r2.trans(3);
|
359 |
|
|
wsdone := r2.trans(4);
|
360 |
|
|
wmdone := r2.trans(5);
|
361 |
|
|
|
362 |
|
|
for i in 0 to NO_CPU_REGS - 1 loop
|
363 |
|
|
v.syncs(i)(csync) := r.trans(i);
|
364 |
|
|
if csync /= 0 then v.syncs(i)(0) := r2.syncs(i)(csync); end if;
|
365 |
|
|
end loop;
|
366 |
|
|
|
367 |
|
|
hstart := r2.syncs(0)(0);
|
368 |
|
|
pabort := r2.syncs(1)(0);
|
369 |
|
|
pstart_ack := r2.syncs(2)(0);
|
370 |
|
|
pcidc := r2.syncs(3)(0);
|
371 |
|
|
rtdone := r2.syncs(4)(0);
|
372 |
|
|
rmdone := r2.syncs(5)(0);
|
373 |
|
|
|
374 |
|
|
p_done := pstart_ack or pabort;
|
375 |
|
|
|
376 |
|
|
if r2.m.fifo.raddr = FIFO_FULL then fiform_limit := '1'; else fiform_limit := '0'; end if;
|
377 |
|
|
|
378 |
|
|
if r2.m.fifo.waddr = FIFO_FULL then fifowm_limit := '1'; else fifowm_limit := '0'; end if;
|
379 |
|
|
if r2.s.fifo.raddr = FIFO_FULL then fifors_limit := '1'; else fifors_limit := '0'; end if;
|
380 |
|
|
if r2.s.fifo.waddr = FIFO_FULL then fifows_limit := '1'; else fifows_limit := '0'; end if;
|
381 |
|
|
if r2.s.fifo.waddr(FIFO_DEPTH - 2 downto 1) = FIFO_FULL(FIFO_DEPTH - 2 downto 1) then fifows_stop := '1'; else fifows_stop := '0'; end if;
|
382 |
|
|
|
383 |
|
|
-----------------------------------
|
384 |
|
|
---- APB Control & Status regs ----
|
385 |
|
|
-----------------------------------
|
386 |
|
|
|
387 |
|
|
if (apbi.psel(pindex) and apbi.penable) = '1' then
|
388 |
|
|
case apbi.paddr(4 downto 2) is
|
389 |
|
|
when "000" =>
|
390 |
|
|
if apbi.pwrite = '1' then
|
391 |
|
|
v.pciba := apbi.pwdata(31 downto 31-HMASK_WIDTH+1);
|
392 |
|
|
v.bus_nr := apbi.pwdata(26 downto 23);
|
393 |
|
|
v.werr := r2.werr and not apbi.pwdata(14);
|
394 |
|
|
v.wcomm := apbi.pwdata(10) and r.comm.mwie;
|
395 |
|
|
v.rcomm := apbi.pwdata(9);
|
396 |
|
|
end if;
|
397 |
|
|
prdata(31 downto 31-HMASK_WIDTH+1) := r2.pciba;
|
398 |
|
|
prdata(26 downto 23) := r2.bus_nr;
|
399 |
|
|
prdata(22 downto 0) := r.ltim & r2.werr & not pr.host & r.comm.msen & r.comm.men & r2.wcomm & r2.rcomm & r2.cfto & r.cline;
|
400 |
|
|
when "001" =>
|
401 |
|
|
prdata := r.bar0(31 downto MADDR_WIDTH) & addzero(MADDR_WIDTH-1 downto 0);
|
402 |
|
|
when "010" =>
|
403 |
|
|
prdata := r.page(31 downto MADDR_WIDTH-1) & addzero(MADDR_WIDTH-2 downto 1) & r.bt_enable;
|
404 |
|
|
when "011" =>
|
405 |
|
|
prdata := r.bar1(31 downto DMAMADDR_WIDTH) & addzero(DMAMADDR_WIDTH-1 downto 0);
|
406 |
|
|
when "100" =>
|
407 |
|
|
if apbi.pwrite = '1' then
|
408 |
|
|
v.dmapage(31 downto DMAMADDR_WIDTH) := apbi.pwdata(31 downto DMAMADDR_WIDTH);
|
409 |
|
|
end if;
|
410 |
|
|
prdata := r2.dmapage(31 downto DMAMADDR_WIDTH) & addzero(DMAMADDR_WIDTH-1 downto 0);
|
411 |
|
|
when "101" =>
|
412 |
|
|
if apbi.pwrite = '1' then
|
413 |
|
|
v.ioba := apbi.pwdata(31 downto 16);
|
414 |
|
|
end if;
|
415 |
|
|
prdata := r2.ioba & addzero(15 downto 4) & hstart & hstart_ack & pstart & pstart_ack;
|
416 |
|
|
when "110" =>
|
417 |
|
|
prdata(1) := r.comm.men; prdata(2) := r.comm.msen;
|
418 |
|
|
prdata(4) := r.comm.mwie; prdata(6) := r.comm.per;
|
419 |
|
|
prdata(24) := r.stat.dped; prdata(26) := '1';
|
420 |
|
|
prdata(27) := r.stat.sta; prdata(28) := r.stat.rta;
|
421 |
|
|
prdata(29) := r.stat.rma; prdata(31) := r.stat.dpe;
|
422 |
|
|
when others =>
|
423 |
|
|
end case;
|
424 |
|
|
end if;
|
425 |
|
|
|
426 |
|
|
---------------------
|
427 |
|
|
---- AHB MASTER ----
|
428 |
|
|
---------------------
|
429 |
|
|
|
430 |
|
|
-- Burst control
|
431 |
|
|
if (r2.m.state = read or r2.m.state = read_w) then
|
432 |
|
|
if r.t.lmult = '1' then
|
433 |
|
|
comp := fifowm_limit and r2.m.fifo.side;
|
434 |
|
|
elsif r.t.lburst = '1' then
|
435 |
|
|
if r2.clscnt(8) = '1' then comp := '1';
|
436 |
|
|
else v.clscnt := r2.clscnt - (dmao.active and dmao.ready); end if;
|
437 |
|
|
else comp := '1'; end if;
|
438 |
|
|
else
|
439 |
|
|
v.clscnt := '0' & (r.cline - '1'); -- set burst counter to cache line size
|
440 |
|
|
end if;
|
441 |
|
|
|
442 |
|
|
if (rtdone = '1' and (r2.m.fifo.raddr + '1') = r.t.fifo.waddr) then rmvalid := '0'; end if;
|
443 |
|
|
|
444 |
|
|
-- step DMA address
|
445 |
|
|
if dmao.ready = '1' then
|
446 |
|
|
v.m.dmaddr(31 downto 2) := r2.m.dmaddr(31 downto 2) + '1';
|
447 |
|
|
end if;
|
448 |
|
|
|
449 |
|
|
-- Translate current CBE to hsize and address
|
450 |
|
|
byteaddr := "00";
|
451 |
|
|
if endian = 0 then -- pci is little endian
|
452 |
|
|
case r2.m.cur_cbe is
|
453 |
|
|
when "0000" => -- 32 bit access
|
454 |
|
|
vdmai.size := "10"; byteaddr := "00";
|
455 |
|
|
when "1100" => -- 16 bit
|
456 |
|
|
vdmai.size := "01"; byteaddr := "00";
|
457 |
|
|
when "0011" =>
|
458 |
|
|
vdmai.size := "01"; byteaddr := "10";
|
459 |
|
|
when "1110" => -- 8 bit
|
460 |
|
|
vdmai.size := "00"; byteaddr := "00";
|
461 |
|
|
when "1101" =>
|
462 |
|
|
vdmai.size := "00"; byteaddr := "01";
|
463 |
|
|
when "1011" =>
|
464 |
|
|
vdmai.size := "00"; byteaddr := "10";
|
465 |
|
|
when "0111" =>
|
466 |
|
|
vdmai.size := "00"; byteaddr := "11";
|
467 |
|
|
when others => vdmai.size := "10";
|
468 |
|
|
end case;
|
469 |
|
|
else -- big endian
|
470 |
|
|
case r2.m.cur_cbe is
|
471 |
|
|
when "0000" => -- 32 bit access
|
472 |
|
|
vdmai.size := "10"; byteaddr := "00";
|
473 |
|
|
when "0011" => -- 16 bit
|
474 |
|
|
vdmai.size := "01"; byteaddr := "00";
|
475 |
|
|
when "1100" =>
|
476 |
|
|
vdmai.size := "01"; byteaddr := "10";
|
477 |
|
|
when "0111" => -- 8 bit
|
478 |
|
|
vdmai.size := "00"; byteaddr := "00";
|
479 |
|
|
when "1011" =>
|
480 |
|
|
vdmai.size := "00"; byteaddr := "01";
|
481 |
|
|
when "1101" =>
|
482 |
|
|
vdmai.size := "00"; byteaddr := "10";
|
483 |
|
|
when "1110" =>
|
484 |
|
|
vdmai.size := "00"; byteaddr := "11";
|
485 |
|
|
when others => vdmai.size := "10";
|
486 |
|
|
end case;
|
487 |
|
|
end if;
|
488 |
|
|
|
489 |
|
|
vdmai.address := r2.m.dmaddr(31 downto 2) & byteaddr;
|
490 |
|
|
next_cbe := cbe_fifoo.rdata(3 downto 0);
|
491 |
|
|
|
492 |
|
|
-- AHB master state machine
|
493 |
|
|
case r2.m.state is
|
494 |
|
|
|
495 |
|
|
when idle =>
|
496 |
|
|
v.m.read_half := '0';
|
497 |
|
|
v.m.last_side_wr := '0';
|
498 |
|
|
v.m.cur_cbe := (others => '0');
|
499 |
|
|
v.m.fifo.waddr := (others => '0');
|
500 |
|
|
|
501 |
|
|
if hstart = '1' then
|
502 |
|
|
|
503 |
|
|
wmdone := '0';
|
504 |
|
|
fifowm_limit := '0';
|
505 |
|
|
-- v.m.fifo.waddr := (others => '0');
|
506 |
|
|
|
507 |
|
|
if r.t.lwrite = '1' then
|
508 |
|
|
|
509 |
|
|
v.m.dmaddr := r.t.laddr;
|
510 |
|
|
v.m.state := write;
|
511 |
|
|
v.m.cur_cbe := cbe_fifoo.rdata(3 downto 0);
|
512 |
|
|
|
513 |
|
|
-- burst access
|
514 |
|
|
if rtdone = '0' or conv_integer(r.t.fifo.waddr) /= 1 then
|
515 |
|
|
v.m.cbe_fifo.raddr := r2.m.cbe_fifo.raddr + 1;
|
516 |
|
|
v.m.state := cbe_prepare;
|
517 |
|
|
v.m.cbe_prep_cnt := '1';
|
518 |
|
|
end if;
|
519 |
|
|
|
520 |
|
|
-- vdmai.busy := '1';
|
521 |
|
|
-- if rmvalid = '1' then v.m.state := write;
|
522 |
|
|
-- else vdmai.start := '0'; v.m.state := stop; end if;
|
523 |
|
|
|
524 |
|
|
else
|
525 |
|
|
vdmai.start := '1';
|
526 |
|
|
v.m.state := read_w;
|
527 |
|
|
end if;
|
528 |
|
|
|
529 |
|
|
else v.m.dmaddr := r.t.laddr; end if;
|
530 |
|
|
|
531 |
|
|
when cbe_prepare =>
|
532 |
|
|
v.m.cur_cbe := next_cbe;
|
533 |
|
|
|
534 |
|
|
-- Need to wait for correct cycle to sample next
|
535 |
|
|
-- cbe if we have switched FIFO side.
|
536 |
|
|
if r2.m.cbe_prep_cnt = '1' then
|
537 |
|
|
v.m.state := write;
|
538 |
|
|
else
|
539 |
|
|
v.m.cbe_prep_cnt := '1';
|
540 |
|
|
end if;
|
541 |
|
|
|
542 |
|
|
when write =>
|
543 |
|
|
|
544 |
|
|
start := '0';
|
545 |
|
|
|
546 |
|
|
--if fiform_limit = '1' then
|
547 |
|
|
--if fiform_limit = '1' and dmao.start = '1' then -- 1k bug fix (store last word in first
|
548 |
|
|
-- v.m.read_half := '1'; -- fifo half if addr = 0x400 ...)
|
549 |
|
|
--end if;
|
550 |
|
|
if fiform_limit = '1' and dmao.start = '1' and dmao.ready = '1' then -- 1k bug fix (store last word in first
|
551 |
|
|
v.m.read_half := '1'; -- fifo half if addr = 0x400 ...)
|
552 |
|
|
end if;
|
553 |
|
|
|
554 |
|
|
-- Don't start again until PCI side is done filling second half of fifo (bug fix kc)
|
555 |
|
|
if r2.m.read_half = '1' then
|
556 |
|
|
if rtdone = '1' then
|
557 |
|
|
start := ((rmvalid and not fiform_limit) or (not dmao.active and not rmvalid));
|
558 |
|
|
end if;
|
559 |
|
|
else
|
560 |
|
|
-- vdmai.start := ((rmvalid and not fiform_limit) or (not dmao.active and not rmvalid));
|
561 |
|
|
-- 1k bug fix (store last word in first fifo half if addr = 0x400 ...)
|
562 |
|
|
|
563 |
|
|
start := ((rmvalid and not v.m.read_half) or (not dmao.active and not rmvalid));
|
564 |
|
|
end if;
|
565 |
|
|
|
566 |
|
|
-- Burst CBE handling
|
567 |
|
|
if rtdone = '0' or conv_integer(r.t.fifo.waddr) /= 1 then
|
568 |
|
|
|
569 |
|
|
-- Current or access is subword. Must be forced to single access
|
570 |
|
|
if r2.m.cur_cbe /= "0000" then
|
571 |
|
|
|
572 |
|
|
vdmai.burst := '0';
|
573 |
|
|
|
574 |
|
|
if dmao.active = '1' then
|
575 |
|
|
start := '0';
|
576 |
|
|
end if;
|
577 |
|
|
|
578 |
|
|
end if;
|
579 |
|
|
|
580 |
|
|
-- Next access is subword. Make current access last in burst
|
581 |
|
|
if rmvalid = '1' and next_cbe /= "0000" then
|
582 |
|
|
|
583 |
|
|
if dmao.active = '1' then
|
584 |
|
|
start := '0';
|
585 |
|
|
end if;
|
586 |
|
|
|
587 |
|
|
end if;
|
588 |
|
|
|
589 |
|
|
end if;
|
590 |
|
|
|
591 |
|
|
vdmai.start := start;
|
592 |
|
|
|
593 |
|
|
-- End of data phase for access with cur_cbe
|
594 |
|
|
if (dmao.active and dmao.ready) = '1' then
|
595 |
|
|
|
596 |
|
|
v.m.fifo.raddr := r2.m.fifo.raddr + (rmvalid and not fiform_limit and not dmao.mexc);
|
597 |
|
|
v.m.cbe_fifo.raddr := r2.m.cbe_fifo.raddr + (rmvalid and not fiform_limit and not dmao.mexc);
|
598 |
|
|
|
599 |
|
|
v.m.last_side_wr := m_read_side;
|
600 |
|
|
|
601 |
|
|
-- First half of FIFO
|
602 |
|
|
if v.m.read_half = '0' then
|
603 |
|
|
v.m.cur_cbe := next_cbe;
|
604 |
|
|
|
605 |
|
|
-- FIFO side switch
|
606 |
|
|
elsif r2.m.read_half = '0' then
|
607 |
|
|
v.m.cbe_prep_cnt := '0';
|
608 |
|
|
v.m.state := cbe_prepare;
|
609 |
|
|
|
610 |
|
|
elsif v.m.last_side_wr = '0' then
|
611 |
|
|
v.m.cbe_prep_cnt := '0';
|
612 |
|
|
v.m.state := cbe_prepare;
|
613 |
|
|
|
614 |
|
|
-- Second side of FIFO
|
615 |
|
|
else
|
616 |
|
|
v.m.cur_cbe := next_cbe;
|
617 |
|
|
end if;
|
618 |
|
|
|
619 |
|
|
if (dmao.mexc = '1' or rmvalid = '0') then
|
620 |
|
|
habort := dmao.mexc and not r.t.lwrite;
|
621 |
|
|
v.werr := r2.werr or (dmao.mexc and r.t.lwrite);
|
622 |
|
|
v.m.state := stop;
|
623 |
|
|
end if;
|
624 |
|
|
end if;
|
625 |
|
|
|
626 |
|
|
when read_w =>
|
627 |
|
|
|
628 |
|
|
vdmai.start := not (comp and dmao.active);
|
629 |
|
|
|
630 |
|
|
if dmao.mexc = '1' then
|
631 |
|
|
habort := not r.t.lwrite;
|
632 |
|
|
v.werr := '1';
|
633 |
|
|
v.m.state := stop;
|
634 |
|
|
|
635 |
|
|
elsif dmao.ready = '1' then
|
636 |
|
|
fifom_write := '1';
|
637 |
|
|
wmvalid := not (comp or dmao.mexc);
|
638 |
|
|
if comp = '1' then
|
639 |
|
|
v.m.state := stop;
|
640 |
|
|
v.m.fifo.waddr := r2.m.fifo.waddr + '1';
|
641 |
|
|
|
642 |
|
|
else
|
643 |
|
|
v.m.fifo.waddr := r2.m.fifo.waddr + (not fifowm_limit);
|
644 |
|
|
v.m.state := read; end if;
|
645 |
|
|
end if;
|
646 |
|
|
|
647 |
|
|
when read =>
|
648 |
|
|
|
649 |
|
|
vdmai.start := not (comp and dmao.active);
|
650 |
|
|
fifom_write := dmao.ready; wmvalid := not (comp or dmao.mexc);
|
651 |
|
|
-- if ((comp and dmao.ready) or dmao.retry) = '1' then
|
652 |
|
|
if (comp and dmao.ready) = '1' then
|
653 |
|
|
v.m.state := stop; v.m.fifo.waddr := r2.m.fifo.waddr + '1';
|
654 |
|
|
elsif (dmao.active and dmao.ready) = '1' then
|
655 |
|
|
v.m.fifo.waddr := r2.m.fifo.waddr + (not dmao.mexc and not fifowm_limit);
|
656 |
|
|
if dmao.mexc = '1' then habort := not r.t.lwrite; v.werr := r2.werr or r.t.lwrite; v.m.state := stop; end if;
|
657 |
|
|
end if;
|
658 |
|
|
|
659 |
|
|
when stop =>
|
660 |
|
|
|
661 |
|
|
if hstart = '0' and ((r.t.lwrite and not fiform_limit) = '1' or wmdone = '1') then
|
662 |
|
|
v.m.state := idle; hstart_ack := '0';
|
663 |
|
|
v.m.fifo.side := '0'; habort := '0';
|
664 |
|
|
|
665 |
|
|
v.m.fifo.raddr := (others => '0');
|
666 |
|
|
v.m.cbe_fifo.raddr := (others => '0');
|
667 |
|
|
else
|
668 |
|
|
comp := '1';
|
669 |
|
|
fiform_limit := r.t.lwrite;
|
670 |
|
|
fifowm_limit := not r.t.lwrite;
|
671 |
|
|
end if;
|
672 |
|
|
end case;
|
673 |
|
|
|
674 |
|
|
-- FIFO control
|
675 |
|
|
if fifowm_limit = '1' then
|
676 |
|
|
-- if (((r2.m.fifo.side or hstart_ack or (not hstart)) = '0' and not (dmao.active and not dmao.ready) = '1')
|
677 |
|
|
if (((r2.m.fifo.side or hstart_ack or (not hstart)) = '0' and (dmao.ready or comp) = '1')
|
678 |
|
|
or ((hstart_ack and not hstart) = '1' and v.m.state = stop)) then
|
679 |
|
|
if v.m.state = stop then wmdone := '1';
|
680 |
|
|
else v.m.fifo.waddr := (others => '0'); end if;
|
681 |
|
|
hstart_ack := '1';
|
682 |
|
|
v.m.fifo.side := not r2.m.fifo.side;
|
683 |
|
|
end if;
|
684 |
|
|
elsif fiform_limit = '1' then
|
685 |
|
|
-- if dmao.active = '0' then
|
686 |
|
|
if dmao.active = '0' and dmai.start = '0' then -- 1k bug fix ***
|
687 |
|
|
m_read_side := '1';
|
688 |
|
|
hstart_ack := '1';
|
689 |
|
|
-- v.m.fifo.raddr := (others => hstart);
|
690 |
|
|
|
691 |
|
|
v.m.fifo.raddr := (others => '0'); -- 1k bug fix ***
|
692 |
|
|
v.m.cbe_fifo.raddr := conv_std_logic_vector(1, FIFO_DEPTH-1);
|
693 |
|
|
|
694 |
|
|
end if;
|
695 |
|
|
end if;
|
696 |
|
|
|
697 |
|
|
-----------------------
|
698 |
|
|
--- AHB MASTER END ----
|
699 |
|
|
-----------------------
|
700 |
|
|
|
701 |
|
|
|
702 |
|
|
-------------------
|
703 |
|
|
---- AHB SLAVE ----
|
704 |
|
|
-------------------
|
705 |
|
|
|
706 |
|
|
-- if MASTER = 1 then
|
707 |
|
|
|
708 |
|
|
-- Access decode
|
709 |
|
|
if (ahbsi.hready and ahbsi.hsel(hslvndx)) = '1' then
|
710 |
|
|
if (ahbsi.hmbsel(0) or ahbsi.hmbsel(1)) = '1' then
|
711 |
|
|
hsize := ahbsi.hsize(1 downto 0); v.s.htrans := ahbsi.htrans;
|
712 |
|
|
--if (v.s.htrans(1) and r.comm.msen) = '1' then request := '1'; end if;
|
713 |
|
|
if (v.s.htrans(1) and r.comm.msen) = '1' then -- fix access control ***
|
714 |
|
|
ahb_access := '1';
|
715 |
|
|
--if (r2.s.state /= r_wait and r2.s.state /= r_hold) or r2.s.hmaster = ahbsi.hmaster then
|
716 |
|
|
--if (r2.s.state = idle or r2.s.state = t_done) or r2.s.hmaster = ahbsi.hmaster then
|
717 |
|
|
if (r2.s.state = idle) or r2.s.hmaster = ahbsi.hmaster then
|
718 |
|
|
request := '1';
|
719 |
|
|
end if;
|
720 |
|
|
end if;
|
721 |
|
|
end if;
|
722 |
|
|
end if;
|
723 |
|
|
|
724 |
|
|
-- Access latches
|
725 |
|
|
if (request = '1' and r2.s.state = idle) then
|
726 |
|
|
|
727 |
|
|
if ahbsi.hmbsel(1) = '1' then
|
728 |
|
|
if ahbsi.haddr(16) = '1' then -- Configuration cycles
|
729 |
|
|
|
730 |
|
|
v.s.maddr := (others => '0');
|
731 |
|
|
|
732 |
|
|
if r2.bus_nr = "0000" then -- Type 0
|
733 |
|
|
|
734 |
|
|
v.s.maddr(conv_integer(ahbsi.haddr(15 downto 11)) + 10) := '1';
|
735 |
|
|
v.s.maddr(10 downto 0) := ahbsi.haddr(10 downto 2) & "00";
|
736 |
|
|
|
737 |
|
|
else -- Type 1
|
738 |
|
|
|
739 |
|
|
v.s.maddr(19 downto 0) := r2.bus_nr & ahbsi.haddr(15 downto 2) & "01";
|
740 |
|
|
|
741 |
|
|
end if;
|
742 |
|
|
|
743 |
|
|
v.s.pcicomm := "101" & ahbsi.hwrite;
|
744 |
|
|
|
745 |
|
|
else -- I/O space access
|
746 |
|
|
|
747 |
|
|
v.s.maddr(31 downto 16) := r2.ioba;
|
748 |
|
|
v.s.maddr(15 downto 0) := ahbsi.haddr(15 downto 0);
|
749 |
|
|
v.s.pcicomm := "001" & ahbsi.hwrite;
|
750 |
|
|
|
751 |
|
|
end if;
|
752 |
|
|
|
753 |
|
|
else -- Memory space access
|
754 |
|
|
|
755 |
|
|
if conv_integer(ahbsi.hmaster) = dmamst then
|
756 |
|
|
v.s.maddr := ahbsi.haddr;
|
757 |
|
|
else
|
758 |
|
|
v.s.maddr := r2.pciba & ahbsi.haddr(31-HMASK_WIDTH downto 2) & "00";
|
759 |
|
|
end if;
|
760 |
|
|
|
761 |
|
|
if ahbsi.hwrite = '1' then
|
762 |
|
|
v.s.pcicomm := r2.wcomm & "111";
|
763 |
|
|
else
|
764 |
|
|
v.s.pcicomm := ahbsi.hburst(0) & '1' & (r2.rcomm or not ahbsi.hburst(0)) & '0';
|
765 |
|
|
end if;
|
766 |
|
|
|
767 |
|
|
end if;
|
768 |
|
|
|
769 |
|
|
-- Decode HSIZE and HADDR
|
770 |
|
|
if endian = 0 then -- pci is little endian
|
771 |
|
|
|
772 |
|
|
case hsize is
|
773 |
|
|
when "00" => -- Decode byte enable
|
774 |
|
|
case ahbsi.haddr(1 downto 0) is
|
775 |
|
|
when "00" => v.s.be := "1110";
|
776 |
|
|
when "01" => v.s.be := "1101";
|
777 |
|
|
when "10" => v.s.be := "1011";
|
778 |
|
|
when "11" => v.s.be := "0111";
|
779 |
|
|
when others => v.s.be := "1111";
|
780 |
|
|
end case;
|
781 |
|
|
when "01" =>
|
782 |
|
|
case ahbsi.haddr(1 downto 0) is
|
783 |
|
|
when "00" => v.s.be := "1100";
|
784 |
|
|
when "10" => v.s.be := "0011";
|
785 |
|
|
when others => v.s.be := "1111";
|
786 |
|
|
end case;
|
787 |
|
|
when "10" => v.s.be := "0000";
|
788 |
|
|
when others => v.s.be := "1111";
|
789 |
|
|
end case;
|
790 |
|
|
|
791 |
|
|
else -- pci is big endian
|
792 |
|
|
|
793 |
|
|
case hsize is
|
794 |
|
|
when "00" => -- Decode byte enable
|
795 |
|
|
case ahbsi.haddr(1 downto 0) is
|
796 |
|
|
when "00" => v.s.be := "0111";
|
797 |
|
|
when "01" => v.s.be := "1011";
|
798 |
|
|
when "10" => v.s.be := "1101";
|
799 |
|
|
when "11" => v.s.be := "1110";
|
800 |
|
|
when others => v.s.be := "1111";
|
801 |
|
|
end case;
|
802 |
|
|
when "01" =>
|
803 |
|
|
case ahbsi.haddr(1 downto 0) is
|
804 |
|
|
when "00" => v.s.be := "0011";
|
805 |
|
|
when "10" => v.s.be := "1100";
|
806 |
|
|
when others => v.s.be := "1111";
|
807 |
|
|
end case;
|
808 |
|
|
when "10" => v.s.be := "0000";
|
809 |
|
|
when others => v.s.be := "1111";
|
810 |
|
|
end case;
|
811 |
|
|
|
812 |
|
|
end if;
|
813 |
|
|
|
814 |
|
|
end if;
|
815 |
|
|
|
816 |
|
|
if ((rmdone and not r2.s.pcicomm(0)) = '1' and (r2.s.fifo.raddr + '1' + pcidc) = r.m.fifo.waddr) then rsvalid := '0'; end if;
|
817 |
|
|
|
818 |
|
|
-- FIFO address counters
|
819 |
|
|
-- if (r2.s.state = t_data or r2.s.state = w_wait) then
|
820 |
|
|
if (r2.s.state = t_data or r2.s.state = w_wait or -- bug fix ***
|
821 |
|
|
(r2.s.state = r_hold and fifors_limit = '0' and ((pstart_ack or pstart) = '0') and request = '1')) then -- (r_hold -> t_data) bug fix ***
|
822 |
|
|
v.s.fifos_write := r2.s.pcicomm(0) and r2.s.htrans(1);
|
823 |
|
|
v.s.fifo.waddr := r2.s.fifo.waddr + r2.s.fifos_write;
|
824 |
|
|
v.s.fifo.raddr := r2.s.fifo.raddr + ((ahbsi.htrans(1) and not r2.s.pcicomm(0) and not fifors_limit and rsvalid) or not ahbsi.hready);
|
825 |
|
|
|
826 |
|
|
end if;
|
827 |
|
|
|
828 |
|
|
if pstart_ack = '1' then
|
829 |
|
|
if pabort = '1' then
|
830 |
|
|
if (r2.s.pcicomm = CONF_WRITE or r2.s.pcicomm = CONF_READ) then v.cfto := '1';
|
831 |
|
|
else v.s.perror := '1'; end if;
|
832 |
|
|
else v.s.perror := '0'; v.cfto := '0'; end if;
|
833 |
|
|
end if;
|
834 |
|
|
|
835 |
|
|
--
|
836 |
|
|
|
837 |
|
|
|
838 |
|
|
-- AHB slave state machine
|
839 |
|
|
case r2.s.state is
|
840 |
|
|
|
841 |
|
|
when idle =>
|
842 |
|
|
|
843 |
|
|
if request = '1' and p_done = '0' then
|
844 |
|
|
if ahbsi.hwrite = '1' then
|
845 |
|
|
v.s.state := w_wait;
|
846 |
|
|
v.s.fifo.side := '0';
|
847 |
|
|
else
|
848 |
|
|
pstart := '1'; v.s.state := r_wait;
|
849 |
|
|
end if;
|
850 |
|
|
v.s.hmaster := ahbsi.hmaster;
|
851 |
|
|
end if;
|
852 |
|
|
|
853 |
|
|
when w_wait =>
|
854 |
|
|
|
855 |
|
|
if ((ahbsi.hready and not ahbsi.htrans(0)) = '1') then
|
856 |
|
|
v.s.state := w_done; fifows_limit := not wsvalid;
|
857 |
|
|
else
|
858 |
|
|
v.s.state := t_data;
|
859 |
|
|
end if;
|
860 |
|
|
|
861 |
|
|
when t_data =>
|
862 |
|
|
|
863 |
|
|
burst_read := ahbsi.htrans(1) and not fifors_limit;
|
864 |
|
|
|
865 |
|
|
if (fifows_stop and r2.s.fifos_write) = '1' then
|
866 |
|
|
if r2.s.fifo.side = '1' then
|
867 |
|
|
v.s.state := w_done;
|
868 |
|
|
end if;
|
869 |
|
|
|
870 |
|
|
elsif ((fifors_limit or not rsvalid) = '1' and v.s.htrans(1) = '1') then
|
871 |
|
|
if (r.m.fifo.side = '0') or (rsvalid = '0') then
|
872 |
|
|
v.s.state := t_done;
|
873 |
|
|
else v.s.state := r_hold; end if;
|
874 |
|
|
end if;
|
875 |
|
|
|
876 |
|
|
if ((ahbsi.hready and not ahbsi.htrans(0)) = '1') then
|
877 |
|
|
if r2.s.pcicomm(0) = '1' then
|
878 |
|
|
--v.s.state := w_done; wsvalid := '0';
|
879 |
|
|
v.s.state := w_done;
|
880 |
|
|
if ahbsi.htrans /= "00" then wsvalid := '0'; end if; -- fix dont set wsvalid if amba idle
|
881 |
|
|
else -- (if wsvalid = 0 side is changed before last write
|
882 |
|
|
v.s.state := t_done; -- to fifo if hrans = 00)
|
883 |
|
|
wsvalid := '0'; -- Bug fix, must give RETRY here! /KC
|
884 |
|
|
end if;
|
885 |
|
|
end if;
|
886 |
|
|
|
887 |
|
|
when r_hold =>
|
888 |
|
|
|
889 |
|
|
s_read_side := '1';
|
890 |
|
|
if fifors_limit = '0' and ((pstart_ack or pstart) = '0') and request = '1' then
|
891 |
|
|
if rmdone = '0' then -- bug fix ***
|
892 |
|
|
v.s.state := t_data;
|
893 |
|
|
burst_read := ahbsi.htrans(1) and not fifors_limit; -- bug fix ***
|
894 |
|
|
else
|
895 |
|
|
v.s.state := t_done;
|
896 |
|
|
end if;
|
897 |
|
|
elsif (ahbsi.hready = '1' and ahbsi.htrans = "00" and r2.s.hresp = HRESP_OKAY) then -- (idle -> t_done) bug fix ***
|
898 |
|
|
v.s.state := t_done;
|
899 |
|
|
else v.s.hold := '1'; end if;
|
900 |
|
|
when r_wait =>
|
901 |
|
|
|
902 |
|
|
s_read_side := '0';
|
903 |
|
|
if (pstart_ack and request) = '1' then
|
904 |
|
|
v.s.state := t_data; hready := '0';
|
905 |
|
|
end if;
|
906 |
|
|
|
907 |
|
|
if r2.s.hmaster /= ahbsi.hmaster and conv_integer(ahbsi.hmaster) = dmamst and pstart_ack = '1' then -- if pcidma cancel read
|
908 |
|
|
v.s.state := t_done;
|
909 |
|
|
end if;
|
910 |
|
|
|
911 |
|
|
when w_done =>
|
912 |
|
|
|
913 |
|
|
v.s.state := t_done; wsvalid := '0';
|
914 |
|
|
-- if (r2.s.htrans(1) or not fifows_limit) = '1' then
|
915 |
|
|
-- if (r2.s.htrans(1) and fifows_limit) = '1' then
|
916 |
|
|
v.s.fifo.waddr := r2.s.fifo.waddr + r2.s.fifos_write;
|
917 |
|
|
|
918 |
|
|
|
919 |
|
|
-- end if;
|
920 |
|
|
|
921 |
|
|
fifows_limit := '1';
|
922 |
|
|
when t_done =>
|
923 |
|
|
|
924 |
|
|
wsvalid := '0';
|
925 |
|
|
fifors_limit := not r2.s.pcicomm(0);
|
926 |
|
|
if (pstart or pstart_ack) = '0' then
|
927 |
|
|
v.s.state := idle; v.s.perror := '0';
|
928 |
|
|
v.s.fifo.waddr := (others => '0'); wsdone := '0'; fifows_limit := '0';
|
929 |
|
|
v.s.pcicomm := (0 => '1', others => '0'); -- default write
|
930 |
|
|
else fifows_limit := r2.s.pcicomm(0); end if;
|
931 |
|
|
end case;
|
932 |
|
|
|
933 |
|
|
-- Respond encoder
|
934 |
|
|
if v.s.state = t_data
|
935 |
|
|
or (v.s.state = r_hold and v.s.hold = '0') -- bug fix ***
|
936 |
|
|
or (v.s.state = t_done and r2.s.state = t_data) -- (end of trans) bug fix ***
|
937 |
|
|
or (v.s.state = w_wait and ahbsi.hwrite = '1') then
|
938 |
|
|
if r2.s.perror = '1' then hresp := HRESP_ERROR;
|
939 |
|
|
elsif wsvalid = '1' then hresp := HRESP_OKAY;
|
940 |
|
|
else hresp := HRESP_RETRY; end if;
|
941 |
|
|
v.s.perror := '0';
|
942 |
|
|
else hresp := HRESP_RETRY; end if;
|
943 |
|
|
|
944 |
|
|
if r.comm.msen = '0' then hresp := HRESP_ERROR; end if; -- Master disabled
|
945 |
|
|
--if (v.s.htrans(1) and request) = '0' then hresp := HRESP_OKAY; end if; -- Response OK for BUSY and IDLE
|
946 |
|
|
if (v.s.htrans(1) and ahb_access) = '0' then hresp := HRESP_OKAY; end if; -- Response OK for BUSY and IDLE -- *** access control fix
|
947 |
|
|
if (hresp /= HRESP_OKAY or hready = '0') then v.s.hready := '0'; else v.s.hready := '1'; end if;
|
948 |
|
|
|
949 |
|
|
-- Dont change hresp during wait states
|
950 |
|
|
if ahbsi.hready = '0' then hresp := r2.s.hresp; end if;
|
951 |
|
|
v.s.hresp := hresp;
|
952 |
|
|
|
953 |
|
|
-- FIFO controller
|
954 |
|
|
if fifows_limit = '1' then
|
955 |
|
|
if (r2.s.fifos_write or not wsvalid) = '1' and (r2.s.fifo.side = '0' or pstart_ack = '1') then
|
956 |
|
|
--if wsvalid = '0' then wsdone := '1';
|
957 |
|
|
if wsvalid = '0' or v.s.state = w_done then wsdone := '1'; -- fix set wsdone and pstart at the same time
|
958 |
|
|
else v.s.fifo.waddr := (others => '0'); end if;
|
959 |
|
|
pstart := not pstart_ack;
|
960 |
|
|
v.s.fifo.side := pstart;
|
961 |
|
|
end if;
|
962 |
|
|
elsif ((r2.s.state = t_done or r2.s.state = r_hold) and fifors_limit = '1') then
|
963 |
|
|
if pstart_ack = '1' then pstart := '0'; v.s.fifo.raddr := (others => '0');
|
964 |
|
|
else v.s.fifo.raddr := (others => '0'); end if;
|
965 |
|
|
end if;
|
966 |
|
|
|
967 |
|
|
-- Set last fifo side written so that PCI master knows when to stop
|
968 |
|
|
if (r2.s.fifos_write = '1') then
|
969 |
|
|
v.s.last_side := r2.s.fifo.side;
|
970 |
|
|
end if;
|
971 |
|
|
|
972 |
|
|
-- end if;
|
973 |
|
|
|
974 |
|
|
-----------------------
|
975 |
|
|
---- AHB SLAVE END ----
|
976 |
|
|
-----------------------
|
977 |
|
|
|
978 |
|
|
-- Sync registers
|
979 |
|
|
v.trans(0) := pstart;
|
980 |
|
|
v.trans(1) := habort;
|
981 |
|
|
v.trans(2) := hstart_ack;
|
982 |
|
|
v.trans(3) := fifows_limit;
|
983 |
|
|
v.trans(4) := wsdone;
|
984 |
|
|
v.trans(5) := wmdone;
|
985 |
|
|
|
986 |
|
|
-- input data for write accesses
|
987 |
|
|
if r2.s.pcicomm(0) = '1' then v.s.mdata := ahbsi.hwdata; end if;
|
988 |
|
|
-- output data for read accesses
|
989 |
|
|
-- if (ahbsi.htrans(1) and not r2.s.hold and not r2.s.pcicomm(0)) = '1' then v.s.mdata := fifo4o.rdata(31 downto 0); end if;
|
990 |
|
|
if (ahbsi.htrans(1) and not r2.s.pcicomm(0)) = '1' then v.s.mdata := fifo4o.rdata(31 downto 0); end if; -- bug fix ***
|
991 |
|
|
|
992 |
|
|
-- irq
|
993 |
|
|
apbo.pirq <= (others => '0');
|
994 |
|
|
if irq /= 0 then
|
995 |
|
|
if to_x01(pcii.host) = '0' then
|
996 |
|
|
apbo.pirq(irq) <= orv((not pcii.int) and conv_std_logic_vector(irqmask,4));
|
997 |
|
|
end if;
|
998 |
|
|
end if;
|
999 |
|
|
|
1000 |
|
|
if rst = '0' then
|
1001 |
|
|
v.s.state := idle;
|
1002 |
|
|
v.m.state := idle;
|
1003 |
|
|
v.s.perror := '0';
|
1004 |
|
|
v.pciba := (others => '0');
|
1005 |
|
|
v.trans := (others => '0');
|
1006 |
|
|
v.m.cbe_fifo.waddr := (others => '0');
|
1007 |
|
|
v.m.cbe_fifo.raddr := (others => '0');
|
1008 |
|
|
v.m.fifo.waddr := (others => '0');
|
1009 |
|
|
v.m.fifo.raddr := (others => '0');
|
1010 |
|
|
v.s.fifo.waddr := (others => '0');
|
1011 |
|
|
v.s.fifo.raddr := (others => '0');
|
1012 |
|
|
v.m.fifo.side := '0';
|
1013 |
|
|
v.s.fifo.side := '0';
|
1014 |
|
|
v.wcomm := '0';
|
1015 |
|
|
v.rcomm := '0';
|
1016 |
|
|
v.werr := '0';
|
1017 |
|
|
v.cfto := '0';
|
1018 |
|
|
v.dmapage := (others => '0');
|
1019 |
|
|
v.ioba := (others => '0');
|
1020 |
|
|
v.pciirq := "11";
|
1021 |
|
|
v.bus_nr := (others => '0');
|
1022 |
|
|
end if;
|
1023 |
|
|
|
1024 |
|
|
apbo.prdata <= prdata;
|
1025 |
|
|
ahbso.hready <= r2.s.hready;
|
1026 |
|
|
ahbso.hresp <= r2.s.hresp;
|
1027 |
|
|
ahbso.hrdata <= byte_twist(r2.s.mdata, r.bt_enable);
|
1028 |
|
|
ahbso.hindex <= hslvndx;
|
1029 |
|
|
|
1030 |
|
|
fifo1i.wen <= fifom_write;
|
1031 |
|
|
fifo1i.waddr <= r2.m.fifo.side & r2.m.fifo.waddr;
|
1032 |
|
|
fifo1i.wdata <= dmao.rdata;
|
1033 |
|
|
|
1034 |
|
|
fifo2i.ren <= '1';
|
1035 |
|
|
fifo2i.raddr <= m_read_side & (r2.m.fifo.raddr + dmao.ready);
|
1036 |
|
|
|
1037 |
|
|
fifo3i.wen <= r2.s.fifos_write;
|
1038 |
|
|
fifo3i.waddr <= r2.s.fifo.side & r2.s.fifo.waddr;
|
1039 |
|
|
fifo3i.wdata <= byte_twist(r2.s.mdata, r.bt_enable);
|
1040 |
|
|
|
1041 |
|
|
fifo4i.ren <= '1';
|
1042 |
|
|
fifo4i.raddr <= s_read_side & (r2.s.fifo.raddr + burst_read);
|
1043 |
|
|
|
1044 |
|
|
cbe_fifoi.ren <= '1';
|
1045 |
|
|
cbe_fifoi.raddr <= m_read_side & (r2.m.cbe_fifo.raddr + dmao.ready); -- read one cycle before data fifo
|
1046 |
|
|
|
1047 |
|
|
r2in <= v; dmai <= vdmai;
|
1048 |
|
|
|
1049 |
|
|
end process;
|
1050 |
|
|
|
1051 |
|
|
ahbso.hconfig <= hconfig when MASTER = 1 else (others => zero32);
|
1052 |
|
|
ahbso.hcache <= '0';
|
1053 |
|
|
apbo.pconfig <= pconfig;
|
1054 |
|
|
apbo.pindex <= pindex;
|
1055 |
|
|
ahbso.hsplit <= (others => '0');
|
1056 |
|
|
ahbso.hirq <= (others => '0');
|
1057 |
|
|
|
1058 |
|
|
|
1059 |
|
|
---------------------------------
|
1060 |
|
|
-- PCI core (PCI clock domain) --
|
1061 |
|
|
---------------------------------
|
1062 |
|
|
|
1063 |
|
|
pcicomb : process(pr, pcii, r, r2, fifo1o, fifo3o, roe_ad, prrst)
|
1064 |
|
|
|
1065 |
|
|
variable v : pci_reg_type;
|
1066 |
|
|
variable chit, mhit0, mhit1, phit, hit, hosthit, ready, cwrite, retry : std_logic;
|
1067 |
|
|
variable cdata, cwdata : std_logic_vector(31 downto 0);
|
1068 |
|
|
variable comp : std_logic; -- Last transaction cycle on PCI bus
|
1069 |
|
|
variable mto, tto, term, ben_err, lto : std_logic;
|
1070 |
|
|
variable i : integer range 0 to NO_PCI_REGS;
|
1071 |
|
|
variable tad, mad : std_logic_vector(31 downto 0);
|
1072 |
|
|
variable pstart, habort, hstart_ack, wsdone, wmdone : std_logic;
|
1073 |
|
|
variable hstart, pabort, pstart_ack, pcidc, rtdone, rmdone : std_logic;
|
1074 |
|
|
variable fifort_limit, fifowt_limit, fiform_limit, fifowm_limit, fifowm_stop, t_valid : std_logic;
|
1075 |
|
|
variable d_ready, tabort, backendnr : std_logic;
|
1076 |
|
|
variable m_fifo_write, t_fifo_write, grant : std_logic;
|
1077 |
|
|
variable write_access, memwrite, memread, read_match, m_read_side, t_read_side : std_logic;
|
1078 |
|
|
variable readt_dly : std_logic; -- 1 turnaround cycle
|
1079 |
|
|
variable bus_idle, data_transfer, data_transfer_r, data_phase, targ_d_w_data, targ_abort, m_request : std_logic;
|
1080 |
|
|
variable voe_ad : std_logic_vector(31 downto 0);
|
1081 |
|
|
variable oe_par : std_logic;
|
1082 |
|
|
variable oe_ad : std_logic;
|
1083 |
|
|
variable oe_ctrl : std_logic;
|
1084 |
|
|
variable oe_cbe : std_logic;
|
1085 |
|
|
variable oe_frame : std_logic;
|
1086 |
|
|
variable oe_irdy : std_logic;
|
1087 |
|
|
variable oe_req : std_logic;
|
1088 |
|
|
variable oe_perr : std_logic;
|
1089 |
|
|
|
1090 |
|
|
begin
|
1091 |
|
|
|
1092 |
|
|
-- Process defaults
|
1093 |
|
|
v := r; v.pci.trdy := '1'; v.pci.stop := '1'; v.pci.frame := '1';
|
1094 |
|
|
v.pci.oe_ad := '1'; v.pci.devsel := '1'; v.pci.oe_frame := '1';
|
1095 |
|
|
v.pci.irdy := '1'; v.pci.req := '1'; hosthit := '0'; m_request := '0';
|
1096 |
|
|
v.pci.oe_req := '0'; v.pci.oe_cbe := '1'; v.pci.oe_irdy := '1';
|
1097 |
|
|
mto := '0'; tto := '0'; v.m.stop_req := '0'; lto := '0';
|
1098 |
|
|
cdata := (others => '0'); retry := '0'; t_fifo_write := '0';
|
1099 |
|
|
chit := '0'; phit := '0'; mhit0 := '0'; mhit1 := '0'; tabort := '0';
|
1100 |
|
|
readt_dly := '0'; m_fifo_write := '0'; voe_ad := roe_ad;
|
1101 |
|
|
tad := r.pci.ad; mad := r.pci.ad; grant := pcii.gnt; d_ready := '0';
|
1102 |
|
|
m_read_side := not r2.s.fifo.side; t_read_side := not r2.m.fifo.side;
|
1103 |
|
|
v.m.rmdone := '0';
|
1104 |
|
|
|
1105 |
|
|
write_access := not r.t.read and not pr.irdy and not pr.trdy;
|
1106 |
|
|
memwrite := r.t.msel and r.t.lwrite and not r.t.read;
|
1107 |
|
|
memread := r.t.msel and not r.t.lwrite and r.t.read;
|
1108 |
|
|
|
1109 |
|
|
-- Synch registers
|
1110 |
|
|
hstart := r.trans(0);
|
1111 |
|
|
pabort := r.trans(1);
|
1112 |
|
|
pstart_ack := r.trans(2);
|
1113 |
|
|
pcidc := r.trans(3);
|
1114 |
|
|
rtdone := r.trans(4);
|
1115 |
|
|
rmdone := r.trans(5);
|
1116 |
|
|
|
1117 |
|
|
for i in 0 to NO_PCI_REGS - 1 loop
|
1118 |
|
|
v.syncs(i)(csync) := r2.trans(i);
|
1119 |
|
|
if csync /= 0 then v.syncs(i)(0) := r.syncs(i)(csync); end if;
|
1120 |
|
|
end loop;
|
1121 |
|
|
|
1122 |
|
|
pstart := r.syncs(0)(0);
|
1123 |
|
|
habort := r.syncs(1)(0);
|
1124 |
|
|
hstart_ack := r.syncs(2)(0);
|
1125 |
|
|
backendnr := r.syncs(3)(0);
|
1126 |
|
|
wsdone := r.syncs(4)(0);
|
1127 |
|
|
wmdone := r.syncs(5)(0);
|
1128 |
|
|
|
1129 |
|
|
-- FIFO limit detector
|
1130 |
|
|
if r.t.fifo.raddr = FIFO_FULL then fifort_limit := '1'; else fifort_limit := '0'; end if;
|
1131 |
|
|
if r.t.fifo.waddr = FIFO_FULL then fifowt_limit := '1'; else fifowt_limit := '0'; end if;
|
1132 |
|
|
if r.m.fifo.raddr = FIFO_FULL then fiform_limit := '1'; else fiform_limit := '0'; end if;
|
1133 |
|
|
if r.m.fifo.waddr = FIFO_FULL then fifowm_limit := '1'; else fifowm_limit := '0'; end if;
|
1134 |
|
|
if r.m.fifo.waddr(FIFO_DEPTH - 2 downto 1) = FIFO_FULL(FIFO_DEPTH - 2 downto 1) then fifowm_stop := '1'; else fifowm_stop := '0'; end if;
|
1135 |
|
|
|
1136 |
|
|
-- useful control variables
|
1137 |
|
|
--if (r.t.laddr = r.page & r.t.addr(MADDR_WIDTH-2 downto 0) or r.t.laddr = r2.dmapage & r.t.addr(DMAMADDR_WIDTH-1 downto 0))
|
1138 |
|
|
if (r.t.laddr(31 downto 2) = r.page & r.t.addr(MADDR_WIDTH-2 downto 2) -- bug fix match if byte access
|
1139 |
|
|
or r.t.laddr(31 downto 2) = r2.dmapage & r.t.addr(DMAMADDR_WIDTH-1 downto 2))
|
1140 |
|
|
and (r.t.lcbe = pr.cbe) -- bug fix match byte access
|
1141 |
|
|
and (r.t.lburst = r.t.burst) then read_match := r.t.pending; else read_match := r.t.csel or r.t.psel; end if;
|
1142 |
|
|
|
1143 |
|
|
-- if (pr.cbe = "0000" and r.t.lsize = "10") or (pr.cbe = "1100" and r.t.lsize = "01") or (pr.cbe = "1110" and r.t.lsize = "00")
|
1144 |
|
|
-- pragma translate_off
|
1145 |
|
|
-- or (pr.cbe = "XXXX") -- For simulation purposes
|
1146 |
|
|
-- pragma translate_on
|
1147 |
|
|
-- then ben_err := '0'; else ben_err := '1'; end if;
|
1148 |
|
|
ben_err := '0';
|
1149 |
|
|
|
1150 |
|
|
if r.stat.dpe = '0' then v.stat.dpe := not r.pci.perr; end if;
|
1151 |
|
|
|
1152 |
|
|
-------------------------
|
1153 |
|
|
----- PCI TARGET --------
|
1154 |
|
|
-------------------------
|
1155 |
|
|
|
1156 |
|
|
-- Data valid?
|
1157 |
|
|
if ((wmdone and not r.t.lwrite) = '1' and (r.t.fifo.raddr + '1') = r2.m.fifo.waddr) then t_valid := '0';
|
1158 |
|
|
else t_valid := not fifowt_limit or not r.t.fifo.side; end if;
|
1159 |
|
|
|
1160 |
|
|
-- Step addresses
|
1161 |
|
|
if (r.t.state = s_data or r.t.state = turn_ar or r.t.state = backoff) then
|
1162 |
|
|
if (pcii.irdy or r.pci.trdy) = '0' then
|
1163 |
|
|
v.t.addr := r.t.addr + ((r.t.csel and r.t.read) & "00");
|
1164 |
|
|
readt_dly := '1';
|
1165 |
|
|
if r.t.msel = '1' then
|
1166 |
|
|
v.t.wdel := (fifort_limit and r2.m.fifo.side) or r.t.lwrite;
|
1167 |
|
|
v.t.fifo.raddr := r.t.fifo.raddr + (r.t.read and not fifort_limit and t_valid);
|
1168 |
|
|
end if;
|
1169 |
|
|
end if;
|
1170 |
|
|
if write_access = '1' then
|
1171 |
|
|
v.t.fifo.waddr := r.t.fifo.waddr + (r.t.msel and not r.t.read and not ben_err);
|
1172 |
|
|
t_fifo_write := r.t.msel;
|
1173 |
|
|
v.t.addr := r.t.addr + ((r.t.csel and not r.t.read) & "00");
|
1174 |
|
|
end if;
|
1175 |
|
|
tabort := habort;
|
1176 |
|
|
else v.t.wdel := '0'; end if;
|
1177 |
|
|
|
1178 |
|
|
-- Config space read access
|
1179 |
|
|
case r.t.addr(7 downto 2) is
|
1180 |
|
|
when "000000" => -- 0x00, device & vendor id
|
1181 |
|
|
cdata := conv_std_logic_vector(DEVICE_ID, 16) &
|
1182 |
|
|
conv_std_logic_vector(VENDOR_ID, 16);
|
1183 |
|
|
when "000001" => -- 0x04, status & command
|
1184 |
|
|
cdata(1) := r.comm.men; cdata(2) := r.comm.msen;
|
1185 |
|
|
cdata(4) := r.comm.mwie; cdata(6) := r.comm.per;
|
1186 |
|
|
cdata(24) := r.stat.dped; cdata(26) := '1';
|
1187 |
|
|
cdata(27) := r.stat.sta; cdata(28) := r.stat.rta;
|
1188 |
|
|
cdata(29) := r.stat.rma; cdata(31) := r.stat.dpe;
|
1189 |
|
|
when "000010" => -- 0x08, class code & revision
|
1190 |
|
|
cdata(31 downto 0) := conv_std_logic_vector(CLASS_CODE,24) & conv_std_logic_vector(REV,8) ;
|
1191 |
|
|
when "000011" => -- 0x0C, latency & cacheline size
|
1192 |
|
|
cdata(7 downto 0) := r.cline;
|
1193 |
|
|
cdata(15 downto 8) := r.ltim;
|
1194 |
|
|
when "000100" => -- 0x10, BAR0
|
1195 |
|
|
cdata(31 downto MADDR_WIDTH) := r.bar0;
|
1196 |
|
|
when "000101" => -- 0x14, BAR1
|
1197 |
|
|
cdata(31 downto DMAMADDR_WIDTH) := r.bar1;
|
1198 |
|
|
when "001111" => -- 0x3C, Interrupts & Latency timer settings
|
1199 |
|
|
cdata(7 downto 0) := r.intline; -- Interrupt line
|
1200 |
|
|
cdata(8) := '1'; -- Use interrupt pin INTA#
|
1201 |
|
|
if fifodepth < 11 then cdata(fifodepth+13) := '1'; end if; --Define wanted burst period
|
1202 |
|
|
when others =>
|
1203 |
|
|
end case;
|
1204 |
|
|
|
1205 |
|
|
-- Config space write access
|
1206 |
|
|
cwdata := pr.ad;
|
1207 |
|
|
if pr.cbe(3) = '1' then cwdata(31 downto 24) := cdata(31 downto 24); end if;
|
1208 |
|
|
if pr.cbe(2) = '1' then cwdata(23 downto 16) := cdata(23 downto 16); end if;
|
1209 |
|
|
if pr.cbe(1) = '1' then cwdata(15 downto 8) := cdata(15 downto 8); end if;
|
1210 |
|
|
if pr.cbe(0) = '1' then cwdata( 7 downto 0) := cdata( 7 downto 0); end if;
|
1211 |
|
|
if (r.t.csel and write_access) = '1' then
|
1212 |
|
|
case r.t.addr(7 downto 2) is
|
1213 |
|
|
when "000001" => -- 0x04, status & command
|
1214 |
|
|
v.comm.men := cwdata(1);
|
1215 |
|
|
if MASTER = 1 then v.comm.msen := cwdata(2); end if;
|
1216 |
|
|
v.comm.mwie := cwdata(4); v.comm.per := cwdata(6);
|
1217 |
|
|
v.stat.dped := r.stat.dped and not cwdata(24); -- Sticky bit
|
1218 |
|
|
v.stat.sta := r.stat.sta and not cwdata(27); -- Sticky bit
|
1219 |
|
|
v.stat.rta := r.stat.rta and not cwdata(28); -- Sticky bit
|
1220 |
|
|
v.stat.rma := r.stat.rma and not cwdata(29); -- Sticky bit
|
1221 |
|
|
v.stat.dpe := r.stat.dpe and not cwdata(31); -- Sticky bit
|
1222 |
|
|
when "000011" => -- 0x0c, latency & cacheline size
|
1223 |
|
|
if FIFO_DEPTH <= 7 then v.cline(FIFO_DEPTH - 1 downto 0) := cwdata(FIFO_DEPTH - 1 downto 0);
|
1224 |
|
|
else v.cline := cwdata(7 downto 0); end if;
|
1225 |
|
|
v.ltim := cwdata(15 downto 8);
|
1226 |
|
|
when "000100" => -- 0x10, BAR0
|
1227 |
|
|
v.bar0 := cwdata(31 downto MADDR_WIDTH);
|
1228 |
|
|
if v.bar0 = zero(31 downto MADDR_WIDTH) then v.bar0_conf := '0'; else v.bar0_conf := '1'; end if;
|
1229 |
|
|
when "000101" => -- 0x14, BAR1
|
1230 |
|
|
v.bar1 := cwdata(31 downto DMAMADDR_WIDTH);
|
1231 |
|
|
if v.bar1 = zero(31 downto DMAMADDR_WIDTH) then v.bar1_conf := '0'; else v.bar1_conf := '1'; end if;
|
1232 |
|
|
when "001111" => -- 0x3C, Interrupts & Latency timer settings
|
1233 |
|
|
v.intline := cwdata(7 downto 0); -- Interrupt line
|
1234 |
|
|
when others =>
|
1235 |
|
|
end case;
|
1236 |
|
|
end if;
|
1237 |
|
|
|
1238 |
|
|
-- Page bar write
|
1239 |
|
|
if (r.t.psel and write_access) = '1' then
|
1240 |
|
|
v.page := pr.ad(31 downto MADDR_WIDTH - 1);
|
1241 |
|
|
v.bt_enable := pr.ad(0);
|
1242 |
|
|
end if;
|
1243 |
|
|
|
1244 |
|
|
-- Command and address decode
|
1245 |
|
|
case pr.cbe is
|
1246 |
|
|
when CONF_READ | CONF_WRITE =>
|
1247 |
|
|
if pr.ad(1 downto 0) = "00" then chit := '1'; end if;
|
1248 |
|
|
if pr.host = '0' then --Active low
|
1249 |
|
|
if pr.ad(31 downto 11) = "000000000000000000000" then hosthit := '1'; end if;
|
1250 |
|
|
end if;
|
1251 |
|
|
when MEM_READ | MEM_WRITE =>
|
1252 |
|
|
if pr.ad(31 downto MADDR_WIDTH) = r.bar0 then
|
1253 |
|
|
phit := r.bar0_conf and pr.ad(MADDR_WIDTH - 1);
|
1254 |
|
|
mhit0 := r.bar0_conf and not pr.ad(MADDR_WIDTH - 1);
|
1255 |
|
|
elsif pr.ad(31 downto DMAMADDR_WIDTH) = r.bar1 then
|
1256 |
|
|
mhit1 := r.bar1_conf;
|
1257 |
|
|
end if;
|
1258 |
|
|
when MEM_R_MULT | MEM_R_LINE | MEM_W_INV =>
|
1259 |
|
|
if pr.ad(31 downto MADDR_WIDTH - 1) = r.bar0 & '0' then mhit0 := r.bar0_conf;
|
1260 |
|
|
elsif pr.ad(31 downto DMAMADDR_WIDTH) = r.bar1 then mhit1 := r.bar1_conf; end if;
|
1261 |
|
|
when others => phit := '0'; mhit0 := '0'; chit := '0'; mhit1 := '0';
|
1262 |
|
|
end case;
|
1263 |
|
|
|
1264 |
|
|
-- Hit detect
|
1265 |
|
|
hit := r.t.csel or r.t.msel or r.t.psel;
|
1266 |
|
|
|
1267 |
|
|
if (hstart and r.pci.devsel) = '1' then
|
1268 |
|
|
if (r.t.pending or r.t.lwrite) = '0' then
|
1269 |
|
|
hstart := not hstart_ack;
|
1270 |
|
|
v.t.fifo.raddr := (others => '0');
|
1271 |
|
|
end if;
|
1272 |
|
|
end if;
|
1273 |
|
|
|
1274 |
|
|
-- Ready to transfer data
|
1275 |
|
|
if ((r.t.csel and not readt_dly) or r.t.psel) = '1'
|
1276 |
|
|
or ((((memwrite and not r.pci.devsel) = '1')
|
1277 |
|
|
or (memread = '1' and not (hstart_ack and v.t.wdel) = '1')) and ben_err = '0')
|
1278 |
|
|
then ready := '1'; else ready := '0'; t_read_side := r.t.read and not hstart; end if;
|
1279 |
|
|
|
1280 |
|
|
-- Target timeout counter
|
1281 |
|
|
--if (hit and pr.trdy and not (pr.frame and pr.irdy)) = '1' then
|
1282 |
|
|
--if (hit and pr.trdy and not (pr.frame and pr.irdy) and v.t.wdel) = '1' then
|
1283 |
|
|
if (hit and pr.trdy and not (pr.frame and pr.irdy) and not ready) = '1' then
|
1284 |
|
|
if r.t.cnt /= "000" then v.t.cnt := r.t.cnt - 1;
|
1285 |
|
|
else tto := '1'; end if;
|
1286 |
|
|
else v.t.cnt := (0 => '0', others => '1'); end if;
|
1287 |
|
|
|
1288 |
|
|
-- -- Ready to transfer data
|
1289 |
|
|
-- if ((r.t.csel and not readt_dly) or r.t.psel) = '1'
|
1290 |
|
|
-- or ((((memwrite and not r.pci.devsel) = '1')
|
1291 |
|
|
-- or (memread = '1' and not (hstart_ack and v.t.wdel) = '1')) and ben_err = '0')
|
1292 |
|
|
-- then ready := '1'; else ready := '0'; t_read_side := r.t.read and not hstart; end if;
|
1293 |
|
|
|
1294 |
|
|
-- Terminate current transaction
|
1295 |
|
|
if (((r.t.fifo.waddr >= (FIFO_FULL - "10") and r.t.fifo.side = '1')
|
1296 |
|
|
or (t_valid = '0') or r.pci.stop = '0') and pcii.frame = '0')
|
1297 |
|
|
or ((r.t.read xor r.t.lwrite) = '0' and r.pci.devsel = '0')
|
1298 |
|
|
or (tto = '1') or (ben_err = '1')
|
1299 |
|
|
then
|
1300 |
|
|
term := '1';
|
1301 |
|
|
else term := '0'; end if;
|
1302 |
|
|
|
1303 |
|
|
-- Retry transfer
|
1304 |
|
|
if r.t.state = b_busy then
|
1305 |
|
|
if not ((r.t.read and not r.t.lwrite and hstart_ack and read_match) = '1'
|
1306 |
|
|
or (r.t.read or hstart or hstart_ack) = '0'
|
1307 |
|
|
or ((r.t.csel or r.t.psel) and not hstart and not hstart_ack) = '1')
|
1308 |
|
|
then
|
1309 |
|
|
retry := '1';
|
1310 |
|
|
end if;
|
1311 |
|
|
end if;
|
1312 |
|
|
|
1313 |
|
|
-- target state machine
|
1314 |
|
|
case r.t.state is
|
1315 |
|
|
|
1316 |
|
|
when idle =>
|
1317 |
|
|
|
1318 |
|
|
if pr.frame = '0' then v.t.state := b_busy; end if; -- !HIT ?
|
1319 |
|
|
v.t.addr := pr.ad;
|
1320 |
|
|
if readpref = 1 then v.t.burst := '1';
|
1321 |
|
|
else v.t.burst := pr.cbe(3); end if;
|
1322 |
|
|
v.t.read := not pr.cbe(0); v.t.mult := not pr.cbe(1);
|
1323 |
|
|
v.t.csel := (pr.idsel or hosthit) and chit; v.t.psel := phit;
|
1324 |
|
|
v.t.msel := r.comm.men and (mhit0 or mhit1); v.t.barsel := mhit1;
|
1325 |
|
|
when turn_ar =>
|
1326 |
|
|
|
1327 |
|
|
if pr.frame = '1' then
|
1328 |
|
|
v.t.state := idle;
|
1329 |
|
|
v.t.fifo.raddr := (others => '0'); -- fix reset fifo read address
|
1330 |
|
|
else v.t.state := b_busy; end if; -- !HIT ?
|
1331 |
|
|
v.t.addr := pr.ad; v.t.wdel := '1';
|
1332 |
|
|
if readpref = 1 then v.t.burst := '1';
|
1333 |
|
|
else v.t.burst := pr.cbe(3); end if;
|
1334 |
|
|
v.t.read := not pr.cbe(0); v.t.mult := not pr.cbe(1);
|
1335 |
|
|
v.t.csel := (pr.idsel or hosthit) and chit; v.t.psel := phit;
|
1336 |
|
|
v.t.msel := r.comm.men and (mhit0 or mhit1); v.t.barsel := mhit1;
|
1337 |
|
|
when b_busy =>
|
1338 |
|
|
|
1339 |
|
|
if (pr.frame and pr.irdy) = '1' then
|
1340 |
|
|
v.t.state := idle;
|
1341 |
|
|
|
1342 |
|
|
elsif hit = '1' then
|
1343 |
|
|
v.t.state := s_data;
|
1344 |
|
|
v.t.fifo.raddr := r.t.fifo.raddr + (r.t.read and r.t.msel);
|
1345 |
|
|
readt_dly := '1';
|
1346 |
|
|
|
1347 |
|
|
if r.t.pending = '0' then
|
1348 |
|
|
v.t.pending := retry and not hstart_ack;
|
1349 |
|
|
end if;
|
1350 |
|
|
|
1351 |
|
|
end if;
|
1352 |
|
|
-- else v.t.state := backoff; end if;
|
1353 |
|
|
-- We should not go to back off if the access wasn't to us
|
1354 |
|
|
|
1355 |
|
|
when s_data =>
|
1356 |
|
|
|
1357 |
|
|
if r.t.pending = '1' then v.t.pending := not ((habort or not r.pci.trdy) and read_match); end if;
|
1358 |
|
|
if (pcii.frame = '0' and r.pci.stop ='0' and (r.pci.trdy or not pcii.irdy) = '1') then
|
1359 |
|
|
v.t.state := backoff;
|
1360 |
|
|
if r.t.last = '0' then v.t.last := r.t.msel and r.t.lwrite and v.t.wdel; end if;
|
1361 |
|
|
v.t.fifo.raddr := r.t.fifo.raddr - (r.t.read and r.t.msel and not fifort_limit);
|
1362 |
|
|
-- elsif (pcii.frame = '1' and (r.pci.trdy = '0' or r.pci.stop = '0')) then
|
1363 |
|
|
elsif (pcii.frame = '1' and (r.t.trdy_del = '0' or r.pci.stop = '0')) then -- (send last word in fifo) bug fix ***
|
1364 |
|
|
v.t.state := turn_ar;
|
1365 |
|
|
if r.t.last = '0' then v.t.last := r.t.msel and r.t.lwrite and v.t.wdel; end if;
|
1366 |
|
|
v.t.fifo.raddr := r.t.fifo.raddr - (r.t.read and r.t.msel and not fifort_limit);
|
1367 |
|
|
end if;
|
1368 |
|
|
when backoff =>
|
1369 |
|
|
|
1370 |
|
|
if pcii.frame = '1' then v.t.state := turn_ar; end if;
|
1371 |
|
|
end case;
|
1372 |
|
|
|
1373 |
|
|
-- #TRDY assert
|
1374 |
|
|
if (v.t.state = s_data and habort = '0' and ready = '1' and retry = '0') then v.pci.trdy := '0'; end if;
|
1375 |
|
|
|
1376 |
|
|
-- #STOP assert
|
1377 |
|
|
if (v.t.state = backoff or (v.t.state = s_data and ((tabort or ((term or retry) and not habort)) = '1'))) then
|
1378 |
|
|
v.pci.stop := '0'; end if;
|
1379 |
|
|
|
1380 |
|
|
-- #DEVSEL assert
|
1381 |
|
|
if (((v.t.state = backoff and r.pci.devsel = '0') or v.t.state = s_data) and (read_match and tabort) = '0') then v.pci.devsel := '0'; end if;
|
1382 |
|
|
|
1383 |
|
|
-- Enable #TRDY, #STOP and #DEVSEL
|
1384 |
|
|
if (v.t.state = s_data) or (v.t.state = backoff) or (v.t.state = turn_ar) then
|
1385 |
|
|
v.pci.oe_ctrl := not hit;
|
1386 |
|
|
else v.pci.oe_ctrl := '1'; end if;
|
1387 |
|
|
|
1388 |
|
|
-- Signaled target abort
|
1389 |
|
|
if (r.pci.devsel and not (r.pci.stop or r.pci.oe_ctrl)) = '1' then v.stat.sta := '1'; end if;
|
1390 |
|
|
|
1391 |
|
|
if r.t.state = s_data and v.t.state = s_data and r.pci.trdy = '0'
|
1392 |
|
|
and v.pci.trdy = '1' and v.t.wdel = '1' and pcii.frame = '0' then -- (send last word in fifo) bug fix ***
|
1393 |
|
|
v.t.trdy_del := '0';
|
1394 |
|
|
else
|
1395 |
|
|
v.t.trdy_del := v.pci.trdy;
|
1396 |
|
|
end if;
|
1397 |
|
|
|
1398 |
|
|
if r.t.state = s_data and r.pci.trdy = '1' and v.pci.trdy = '0' and pcii.frame = '0' then -- bug fix ***
|
1399 |
|
|
readt_dly := '1';
|
1400 |
|
|
v.t.fifo.raddr := r.t.fifo.raddr + (r.t.read and not fifort_limit and t_valid);
|
1401 |
|
|
end if;
|
1402 |
|
|
|
1403 |
|
|
-- Latched signals to AHB backend
|
1404 |
|
|
if (r.t.state = b_busy) then
|
1405 |
|
|
if (hstart or hstart_ack) = '0' then -- must be idle
|
1406 |
|
|
v.t.lwrite := not r.t.read;
|
1407 |
|
|
|
1408 |
|
|
if r.t.msel = '1' then
|
1409 |
|
|
v.t.lburst := r.t.burst;
|
1410 |
|
|
v.t.lcbe := pr.cbe;
|
1411 |
|
|
if r.t.barsel = '0' then v.t.laddr := r.page & r.t.addr(MADDR_WIDTH-2 downto 2) & "00";
|
1412 |
|
|
else v.t.laddr := r2.dmapage & r.t.addr(DMAMADDR_WIDTH-1 downto 2) & "00"; end if;
|
1413 |
|
|
v.t.lmult := r.t.mult;
|
1414 |
|
|
rtdone := '0'; v.t.fifo.waddr := (others => '0');
|
1415 |
|
|
hstart := r.t.read and r.t.msel;
|
1416 |
|
|
end if;
|
1417 |
|
|
end if;
|
1418 |
|
|
end if;
|
1419 |
|
|
|
1420 |
|
|
-- Read data mux
|
1421 |
|
|
if r.t.csel = '1' then tad := cdata;
|
1422 |
|
|
elsif r.t.psel = '1' then
|
1423 |
|
|
tad(31 downto MADDR_WIDTH-1) := r.page;
|
1424 |
|
|
tad(MADDR_WIDTH-2 downto 0) := zero32(MADDR_WIDTH-2 downto 1) & r.bt_enable;
|
1425 |
|
|
-- elsif (r.t.state = b_busy or (r.pci.trdy or pcii.irdy) = '0') then tad := fifo1o.rdata(31 downto 0);
|
1426 |
|
|
elsif (r.t.state = b_busy or (r.pci.trdy or pcii.irdy) = '0' or r.t.wdel = '1') then tad := byte_twist(fifo1o.rdata(31 downto 0), r.bt_enable); -- bug fix ***
|
1427 |
|
|
end if;
|
1428 |
|
|
|
1429 |
|
|
-- FIFO controller
|
1430 |
|
|
if ((fifowt_limit and write_access) = '1' or (r.t.last or rtdone) = '1') then
|
1431 |
|
|
if hstart = hstart_ack then
|
1432 |
|
|
if rtdone = '0' then hstart := not hstart_ack; v.t.fifo.side := hstart; end if;
|
1433 |
|
|
if r.t.last = '1' then rtdone := '1'; v.t.last := '0';
|
1434 |
|
|
else v.t.fifo.waddr := (others => '0');
|
1435 |
|
|
if rtdone = '1' then
|
1436 |
|
|
rtdone := '0'; hstart := '0'; v.t.fifo.side := '0';
|
1437 |
|
|
end if;
|
1438 |
|
|
end if;
|
1439 |
|
|
end if;
|
1440 |
|
|
end if;
|
1441 |
|
|
|
1442 |
|
|
if (fifort_limit and v.t.wdel) = '1' then
|
1443 |
|
|
if hstart_ack = '1' then hstart := '0'; v.t.fifo.raddr := (others => '0');
|
1444 |
|
|
else v.t.fifo.raddr := (others => '0'); end if;
|
1445 |
|
|
end if;
|
1446 |
|
|
|
1447 |
|
|
----------------------
|
1448 |
|
|
--- PCI TARGET END ---
|
1449 |
|
|
----------------------
|
1450 |
|
|
|
1451 |
|
|
------------------
|
1452 |
|
|
--- PCI MASTER ---
|
1453 |
|
|
------------------
|
1454 |
|
|
|
1455 |
|
|
if MASTER = 1 then
|
1456 |
|
|
|
1457 |
|
|
bus_idle := pcii.frame and pcii.irdy;
|
1458 |
|
|
data_transfer := not (pcii.trdy or r.pci.irdy);
|
1459 |
|
|
data_transfer_r := not (pr.trdy or pr.irdy);
|
1460 |
|
|
data_phase := not ((pcii.trdy and pcii.stop) or r.pci.irdy);
|
1461 |
|
|
targ_d_w_data := not (pr.stop or pr.trdy);
|
1462 |
|
|
targ_abort := pr.devsel and not pr.stop;
|
1463 |
|
|
|
1464 |
|
|
|
1465 |
|
|
-- Request from AHB backend to start PCI transaction
|
1466 |
|
|
if (pstart and not pstart_ack) = '1' then
|
1467 |
|
|
if (r.m.fstate = idle and r.m.request = '0') then
|
1468 |
|
|
v.m.request := '1';
|
1469 |
|
|
rmdone := '0'; v.m.valid := '1';
|
1470 |
|
|
v.m.fifo.waddr := (others => '0');
|
1471 |
|
|
v.m.hwrite := r2.s.pcicomm(0);
|
1472 |
|
|
end if;
|
1473 |
|
|
end if;
|
1474 |
|
|
|
1475 |
|
|
-- Master timeout and DEVSEL timeout
|
1476 |
|
|
if ((pr.irdy and not pr.frame) or (pr.devsel and not r.pci.oe_frame)) = '1' then
|
1477 |
|
|
if r.m.cnt /= "000" then v.m.cnt := r.m.cnt - 1;
|
1478 |
|
|
else mto := '1'; end if;
|
1479 |
|
|
else v.m.cnt := (others => '1'); end if;
|
1480 |
|
|
|
1481 |
|
|
-- Latency counter
|
1482 |
|
|
if r.pci.frame = '0' then
|
1483 |
|
|
if r.m.ltim > "00000000" then v.m.ltim := r.m.ltim - '1';
|
1484 |
|
|
else lto := '1'; end if;
|
1485 |
|
|
else
|
1486 |
|
|
v.m.ltim := r.ltim;
|
1487 |
|
|
end if;
|
1488 |
|
|
|
1489 |
|
|
-- Last data
|
1490 |
|
|
case r2.s.pcicomm is
|
1491 |
|
|
when MEM_R_MULT | MEM_R_LINE =>
|
1492 |
|
|
if (r.m.fifo.waddr >= (FIFO_FULL - "10") and r.m.fifo.side = '1') then
|
1493 |
|
|
comp := '1';
|
1494 |
|
|
else comp := '0'; end if;
|
1495 |
|
|
when MEM_WRITE | MEM_W_INV => comp := not r.m.valid;
|
1496 |
|
|
when others => comp := '1';
|
1497 |
|
|
end case;
|
1498 |
|
|
|
1499 |
|
|
-- Minimun latency
|
1500 |
|
|
--if lto = '0' then grant := '0'; end if;
|
1501 |
|
|
if lto = '0' then grant := '0'; -- latency timer bug fix
|
1502 |
|
|
elsif pcii.gnt = '1' then v.m.lto := '1'; end if;
|
1503 |
|
|
|
1504 |
|
|
-- Data parity error detected
|
1505 |
|
|
if (r.m.fstate /= idle and r.stat.dped = '0') then v.stat.dped := r.comm.per and not pcii.perr; end if;
|
1506 |
|
|
|
1507 |
|
|
-- FIFO control state machine
|
1508 |
|
|
case r.m.fstate is
|
1509 |
|
|
when idle =>
|
1510 |
|
|
|
1511 |
|
|
v.m.lto := '0';
|
1512 |
|
|
if (r.m.request and bus_idle and not pcii.gnt) = '1' and (r.m.state = idle or r.m.state = dr_bus) then
|
1513 |
|
|
v.m.fstate := addr; v.m.fifo.waddr := (others => '0'); v.m.fifo.side := '0'; m_request := '1';
|
1514 |
|
|
end if;
|
1515 |
|
|
when addr =>
|
1516 |
|
|
|
1517 |
|
|
-- if (wsdone = '1' and (r.m.fifo.raddr + '1') = r2.s.fifo.waddr) then v.m.valid := '0'; end if;
|
1518 |
|
|
if (wsdone = '1' and ((r.m.fifo.raddr + '1') = r2.s.fifo.waddr) and (m_read_side = r2.s.last_side)) then v.m.valid := '0'; end if; --bug fix kc
|
1519 |
|
|
|
1520 |
|
|
if fiform_limit = '1' then v.m.fstate := last1;
|
1521 |
|
|
else v.m.fstate := incr; end if;
|
1522 |
|
|
v.m.fifo.raddr := r.m.fifo.raddr + r.m.hwrite;
|
1523 |
|
|
v.m.first := '1'; v.m.firstw := '1';
|
1524 |
|
|
when incr =>
|
1525 |
|
|
|
1526 |
|
|
d_ready := '1';
|
1527 |
|
|
|
1528 |
|
|
if r.m.valid = '0' then v.m.lto := '0'; end if; -- dont look at latency timer if done
|
1529 |
|
|
|
1530 |
|
|
if data_transfer = '1' then
|
1531 |
|
|
|
1532 |
|
|
--if fiform_limit = '1' then v.m.fstate := last1; v.m.split := not backendnr; end if;
|
1533 |
|
|
if fiform_limit = '1' and r.m.lto = '0' then v.m.fstate := last1; v.m.split := not backendnr; end if; -- bug fix latency timer
|
1534 |
|
|
|
1535 |
|
|
-- if (wsdone = '1' and (r.m.fifo.raddr + pcii.stop) = r2.s.fifo.waddr) then v.m.valid := '0'; end if;
|
1536 |
|
|
if (wsdone = '1' and ((r.m.fifo.raddr + pcii.stop) = r2.s.fifo.waddr) and (m_read_side = r2.s.last_side)) then v.m.valid := '0'; end if; --bug fix kc
|
1537 |
|
|
|
1538 |
|
|
v.m.fifo.raddr := r.m.fifo.raddr + r.m.hwrite;
|
1539 |
|
|
v.m.first := '0';
|
1540 |
|
|
end if;
|
1541 |
|
|
if data_transfer_r = '1' then
|
1542 |
|
|
if fifowm_stop = '1' then
|
1543 |
|
|
if r.m.firstw = '1' then
|
1544 |
|
|
if (fifowm_limit and pr.stop) = '1' then v.m.fifo.side := not r.m.fifo.side; v.m.firstw := '0'; pstart_ack := pstart; end if;
|
1545 |
|
|
end if;
|
1546 |
|
|
end if;
|
1547 |
|
|
v.m.fifo.waddr := r.m.fifo.waddr + (not r.m.hwrite);
|
1548 |
|
|
end if;
|
1549 |
|
|
if pr.stop = '0' then
|
1550 |
|
|
if targ_abort = '1' then v.m.fstate := abort;
|
1551 |
|
|
elsif targ_d_w_data = '1' then v.m.fstate := ttermwd;
|
1552 |
|
|
elsif r.m.first = '1' then v.m.fstate := t_retry;
|
1553 |
|
|
-- else v.m.fstate := ttermnd; end if;
|
1554 |
|
|
else -- bug fix ***
|
1555 |
|
|
-- if r.m.fifo.waddr = "0000000" then v.m.rmdone := '1'; end if;
|
1556 |
|
|
if r.m.fifo.waddr = zero32(FIFO_DEPTH - 2 downto 0) then v.m.rmdone := '1'; end if;
|
1557 |
|
|
v.m.fstate := ttermnd;
|
1558 |
|
|
end if;
|
1559 |
|
|
elsif mto = '1' then v.m.fstate := abort;
|
1560 |
|
|
--elsif grant = '1' then -- pci_gnt bug fix
|
1561 |
|
|
-- if r.m.hwrite = '0' then rmdone := not r.m.fifo.side; v.m.fifo.side := '1'; v.m.fstate := done; pstart_ack := pstart;
|
1562 |
|
|
-- else v.m.fstate := idle; end if;
|
1563 |
|
|
|
1564 |
|
|
--elsif (pr.frame and not r.m.first) = '1' then
|
1565 |
|
|
elsif (pr.frame and not pr.trdy and not r.m.first) = '1' then -- not done if target not ready *** bug fix
|
1566 |
|
|
if r.m.hwrite = '0' then rmdone := not r.m.fifo.side; v.m.fifo.side := '1'; v.m.fstate := done; pstart_ack := pstart;
|
1567 |
|
|
--else v.m.fstate := done; pstart_ack := pstart; end if;
|
1568 |
|
|
else
|
1569 |
|
|
if r.m.lto = '1' then -- latency timer bug fix
|
1570 |
|
|
v.m.fifo.raddr := r.m.fifo.raddr - r.m.hwrite;
|
1571 |
|
|
v.m.fstate := idle;
|
1572 |
|
|
else
|
1573 |
|
|
v.m.fstate := done; pstart_ack := pstart;
|
1574 |
|
|
end if;
|
1575 |
|
|
end if;
|
1576 |
|
|
elsif (pr.devsel and not r.m.first) = '1' then
|
1577 |
|
|
if r.m.hwrite = '0' then rmdone := not r.m.fifo.side; v.m.fifo.side := '1'; v.m.fstate := done; pstart_ack := pstart;
|
1578 |
|
|
else v.m.fstate := idle; end if;
|
1579 |
|
|
end if;
|
1580 |
|
|
when last1 =>
|
1581 |
|
|
|
1582 |
|
|
if (pr.trdy and not pr.stop) = '1' then
|
1583 |
|
|
if targ_abort = '1' then v.m.fstate := abort;
|
1584 |
|
|
elsif targ_d_w_data = '1' then v.m.fstate := ttermwd;
|
1585 |
|
|
else v.m.fstate := ttermnd; v.m.valid := '1'; end if;
|
1586 |
|
|
--elsif (pr.frame and not r.m.first and not r.m.split) = '1' then v.m.fstate := done; rmdone := not r.m.fifo.side; pstart_ack := pstart;
|
1587 |
|
|
-- not done if target not ready *** bug fix
|
1588 |
|
|
elsif (pr.frame and not pr.trdy and not r.m.first and not r.m.split) = '1' then v.m.fstate := done; rmdone := not r.m.fifo.side; pstart_ack := pstart;
|
1589 |
|
|
elsif data_transfer = '1' then
|
1590 |
|
|
if r.m.valid = '1' then v.m.fstate := sync; pstart_ack := pstart;
|
1591 |
|
|
else v.m.fstate := done; rmdone := not r.m.fifo.side; pstart_ack := pstart; end if;
|
1592 |
|
|
else d_ready := '1';
|
1593 |
|
|
end if;
|
1594 |
|
|
when sync =>
|
1595 |
|
|
|
1596 |
|
|
if pstart = not pstart_ack then
|
1597 |
|
|
v.m.split := '0';
|
1598 |
|
|
if ((r.m.split or (pr.trdy and not pr.stop and not r.m.split)) = '1' or r.m.state /= m_data) then v.m.fstate := idle; d_ready := '1';
|
1599 |
|
|
else
|
1600 |
|
|
--if (wsdone = '1' and (r.m.fifo.raddr + '1') = r2.s.fifo.waddr) then v.m.valid := '0'; end if;
|
1601 |
|
|
if (r2.trans(4) = '1' and (r.m.fifo.raddr + '1') = r2.s.fifo.waddr) then v.m.valid := '0'; end if; -- not synced wsdone
|
1602 |
|
|
v.m.fstate := incr; data_transfer := '1'; v.m.fifo.raddr := r.m.fifo.raddr + r.m.hwrite; d_ready := '1';
|
1603 |
|
|
end if;
|
1604 |
|
|
else m_read_side := '1';
|
1605 |
|
|
end if;
|
1606 |
|
|
when t_retry =>
|
1607 |
|
|
|
1608 |
|
|
v.m.fifo.raddr := r.m.fifo.raddr - r.m.hwrite; v.m.fstate := idle;
|
1609 |
|
|
|
1610 |
|
|
when ttermwd =>
|
1611 |
|
|
|
1612 |
|
|
if data_transfer = '1' then v.m.fifo.raddr := r.m.fifo.raddr + r.m.hwrite;
|
1613 |
|
|
elsif pr.trdy = '1' then v.m.fifo.raddr := r.m.fifo.raddr - r.m.hwrite;
|
1614 |
|
|
if (r.m.hwrite and r.m.valid) = '1' then v.m.fstate := idle;
|
1615 |
|
|
else v.m.fstate := done; rmdone := not r.m.fifo.side; v.m.fifo.side := '1'; pstart_ack := pstart; end if;
|
1616 |
|
|
end if;
|
1617 |
|
|
when ttermnd =>
|
1618 |
|
|
|
1619 |
|
|
if r.m.hwrite = '1' then
|
1620 |
|
|
v.m.fifo.raddr := r.m.fifo.raddr - '1';
|
1621 |
|
|
-- if (r.m.fifo.raddr /= (r2.s.fifo.waddr + '1') or wsdone = '0') then v.m.valid := '1'; v.m.fstate := idle; -- bug fix ***
|
1622 |
|
|
if (r.m.fifo.raddr /= (r2.s.fifo.waddr + '1') or wsdone = '0' or r.m.valid = '1') then v.m.valid := '1'; v.m.fstate := idle;
|
1623 |
|
|
else v.m.fstate := done; rmdone := not r.m.fifo.side; v.m.fifo.side := '1'; pstart_ack := pstart; end if;
|
1624 |
|
|
-- else v.m.fstate := done; rmdone := not r.m.fifo.side; v.m.fifo.side := '1'; pstart_ack := pstart; end if;
|
1625 |
|
|
else v.m.fstate := done; rmdone := (not r.m.fifo.side or r.m.rmdone); v.m.fifo.side := '1'; pstart_ack := pstart; end if; -- bug fix ***
|
1626 |
|
|
when abort =>
|
1627 |
|
|
|
1628 |
|
|
v.m.fifo.raddr := (others => '0'); v.m.fifo.waddr := (others => '0');
|
1629 |
|
|
v.m.fstate := done; pstart_ack := pstart; pabort := '1';
|
1630 |
|
|
when done =>
|
1631 |
|
|
|
1632 |
|
|
d_ready := '1'; comp := '1'; v.m.request := '0';
|
1633 |
|
|
if (pstart or pstart_ack) = '0' then
|
1634 |
|
|
v.m.fstate := wdone; v.m.fifo.raddr := (others => '0'); v.m.fifo.side := '0'; rmdone := '1';
|
1635 |
|
|
else pstart_ack := pstart; end if;
|
1636 |
|
|
when wdone =>
|
1637 |
|
|
|
1638 |
|
|
d_ready := '1'; comp := '1';
|
1639 |
|
|
if (r.m.state = idle or r.m.state = dr_bus) then v.m.fstate := idle; pabort := '0'; end if;
|
1640 |
|
|
end case;
|
1641 |
|
|
|
1642 |
|
|
-- PCI master state machine
|
1643 |
|
|
case r.m.state is
|
1644 |
|
|
when idle => -- Master idle
|
1645 |
|
|
v.m.stopframe := '0';
|
1646 |
|
|
if (pcii.gnt = '0' and bus_idle = '1') then
|
1647 |
|
|
if m_request = '1' then v.m.state := addr;
|
1648 |
|
|
else v.m.state := dr_bus; end if;
|
1649 |
|
|
end if;
|
1650 |
|
|
when addr => -- Always one address cycle at the beginning of an transaction
|
1651 |
|
|
v.m.stopframe := '0';
|
1652 |
|
|
v.m.state := m_data;
|
1653 |
|
|
when m_data => -- Master transfers data
|
1654 |
|
|
if r.pci.frame = '1' then v.m.stopframe := '1'; end if; -- ***
|
1655 |
|
|
if (r.pci.frame = '0') or ((r.pci.frame and pcii.trdy and pcii.stop and not mto) = '1') then
|
1656 |
|
|
v.m.state := m_data;
|
1657 |
|
|
if (r.pci.frame and not d_ready) = '1' then d_ready := '1'; end if;
|
1658 |
|
|
elsif ((r.pci.frame and (mto or not pcii.stop)) = '1') then
|
1659 |
|
|
v.m.state := s_tar;
|
1660 |
|
|
v.m.stop_req := '1';
|
1661 |
|
|
else v.m.state := turn_ar; end if;
|
1662 |
|
|
when turn_ar => -- Transaction complete
|
1663 |
|
|
|
1664 |
|
|
if pcii.gnt = '0' then
|
1665 |
|
|
if m_request = '1' then v.m.state := addr;
|
1666 |
|
|
else v.m.state := dr_bus; end if;
|
1667 |
|
|
else v.m.state := idle; end if;
|
1668 |
|
|
when s_tar => -- Stop was asserted
|
1669 |
|
|
|
1670 |
|
|
if pcii.gnt = '0' then v.m.state := dr_bus;
|
1671 |
|
|
else v.m.state := idle; end if;
|
1672 |
|
|
when dr_bus => -- Drive bus when parked on this agent
|
1673 |
|
|
|
1674 |
|
|
if pcii.gnt = '1' then v.m.state := idle;
|
1675 |
|
|
elsif m_request = '1' then v.m.state := addr; end if;
|
1676 |
|
|
end case;
|
1677 |
|
|
|
1678 |
|
|
-- FIFO write strobe
|
1679 |
|
|
m_fifo_write := not r.m.hwrite and not pr.irdy and not (pr.trdy and (pr.stop or not r.trans(3))) and not r.pci.oe_irdy;
|
1680 |
|
|
|
1681 |
|
|
-- PCI data mux
|
1682 |
|
|
if v.m.state = addr then
|
1683 |
|
|
if r.m.hwrite = '1' then mad := (r2.s.maddr + ((((not r2.s.fifo.side) & r.m.fifo.raddr)) & "00"));
|
1684 |
|
|
else mad := r2.s.maddr; end if;
|
1685 |
|
|
elsif (r.m.state = addr or data_transfer = '1') then mad := fifo3o.rdata(31 downto 0);
|
1686 |
|
|
end if;
|
1687 |
|
|
|
1688 |
|
|
-- Target abort
|
1689 |
|
|
if ((pr.devsel and pr.trdy and not pr.gnt and not pr.stop) = '1') then v.stat.rta := '1'; end if;
|
1690 |
|
|
|
1691 |
|
|
-- Master abort
|
1692 |
|
|
if mto = '1' then v.stat.rma := '1'; end if;
|
1693 |
|
|
|
1694 |
|
|
-- Drive FRAME# and IRDY#
|
1695 |
|
|
if (v.m.state = addr or v.m.state = m_data) then v.pci.oe_frame := '0'; end if;
|
1696 |
|
|
|
1697 |
|
|
-- Drive CBE#
|
1698 |
|
|
if (v.m.state = addr or v.m.state = m_data or v.m.state = dr_bus) then v.pci.oe_cbe := '0'; end if;
|
1699 |
|
|
|
1700 |
|
|
-- Drive IRDY# (FRAME# delayed one pciclk)
|
1701 |
|
|
v.pci.oe_irdy := r.pci.oe_frame;
|
1702 |
|
|
|
1703 |
|
|
-- FRAME# assert
|
1704 |
|
|
if (v.m.state = addr or (v.m.state = m_data and mto = '0' and v.m.stopframe = '0' -- stopframe fix frame when pci_gnt is deasserted
|
1705 |
|
|
--and ((((pcii.stop or not d_ready) and not (comp or v.m.split or not v.m.valid)) and not grant)) = '1')) -- dont change frame when gnt = 1 if not irdy and trdy or stop
|
1706 |
|
|
and ((((pcii.stop or not d_ready) and not (comp or v.m.split or not v.m.valid)) and not (grant and not pr.irdy and (not pcii.trdy or not pcii.stop) ) )) = '1'))
|
1707 |
|
|
then
|
1708 |
|
|
v.pci.frame := '0';
|
1709 |
|
|
end if;
|
1710 |
|
|
|
1711 |
|
|
-- IRDY# assert
|
1712 |
|
|
if (v.m.state = m_data and ((d_ready or mto or (not r.m.valid) or (v.pci.frame and not r.pci.frame)) = '1')) then v.pci.irdy := '0'; end if;
|
1713 |
|
|
|
1714 |
|
|
-- REQ# assert
|
1715 |
|
|
if ((v.m.request = '1' and (r.m.fstate = idle or comp = '0')) and (v.m.stop_req or r.m.stop_req) = '0') then v.pci.req := '0'; end if;
|
1716 |
|
|
|
1717 |
|
|
-- C/BE# assert
|
1718 |
|
|
if v.m.state = addr then v.pci.cbe := r2.s.pcicomm; else v.pci.cbe := r2.s.be; end if;
|
1719 |
|
|
|
1720 |
|
|
end if;
|
1721 |
|
|
|
1722 |
|
|
---------------------
|
1723 |
|
|
---PCI MASTER END ---
|
1724 |
|
|
---------------------
|
1725 |
|
|
|
1726 |
|
|
----------------------
|
1727 |
|
|
--- SHARED SIGNALS ---
|
1728 |
|
|
----------------------
|
1729 |
|
|
|
1730 |
|
|
-- Default assertions
|
1731 |
|
|
v.pci.oe_par := r.pci.oe_ad; --Delayed one clock
|
1732 |
|
|
v.pci.oe_perr := not(r.comm.per and not r.pci.oe_par and not (pr.irdy and pr.trdy)) and (r.pci.oe_perr or r.pci.perr);
|
1733 |
|
|
v.pci.par := xorv(r.pci.ad & r.pci.cbe); -- Default asserted by master
|
1734 |
|
|
v.pci.ad := mad; -- Default asserted by master
|
1735 |
|
|
v.pci.perr := not (pcii.par xor xorv(pr.ad & pr.cbe)) or pr.irdy or pr.trdy; -- Detect parity error
|
1736 |
|
|
|
1737 |
|
|
-- Drive AD
|
1738 |
|
|
-- Master
|
1739 |
|
|
if (v.m.state = addr or (v.m.state = m_data and r.m.hwrite = '1') or v.m.state = dr_bus) then
|
1740 |
|
|
v.pci.oe_ad := '0';
|
1741 |
|
|
end if;
|
1742 |
|
|
-- Target
|
1743 |
|
|
if r.t.read = '1' then
|
1744 |
|
|
if v.t.state = s_data then
|
1745 |
|
|
v.pci.oe_ad := '0';
|
1746 |
|
|
v.pci.ad := tad; end if;
|
1747 |
|
|
if r.t.state = s_data then
|
1748 |
|
|
v.pci.par := xorv(r.pci.ad & pcii.cbe);
|
1749 |
|
|
end if;
|
1750 |
|
|
end if;
|
1751 |
|
|
|
1752 |
|
|
v.noe_ad := not v.pci.oe_ad; v.noe_ctrl := not v.pci.oe_ctrl;
|
1753 |
|
|
v.noe_par := not v.pci.oe_par; v.noe_req := not v.pci.oe_req;
|
1754 |
|
|
v.noe_frame := not v.pci.oe_frame; v.noe_cbe := not v.pci.oe_cbe;
|
1755 |
|
|
v.noe_irdy := not v.pci.oe_irdy; v.noe_perr := not v.pci.oe_perr;
|
1756 |
|
|
|
1757 |
|
|
if (scanen = 1) and (syncrst = 1) and (ahbmi.testen = '1') then
|
1758 |
|
|
voe_ad := (others => ahbmi.testoen); oe_ad := '1'; oe_ctrl := '1';
|
1759 |
|
|
oe_par := '1'; oe_req := '1'; oe_frame := '1'; oe_cbe := '1';
|
1760 |
|
|
oe_irdy := '1'; oe_perr := '1';
|
1761 |
|
|
elsif oepol = 0 then
|
1762 |
|
|
if (syncrst = 1) and (pcirstin = '0') then
|
1763 |
|
|
voe_ad := (others => '1'); oe_ad := '1'; oe_ctrl := '1';
|
1764 |
|
|
oe_par := '1'; oe_req := '1'; oe_frame := '1'; oe_cbe := '1';
|
1765 |
|
|
oe_irdy := '1'; oe_perr := '1';
|
1766 |
|
|
else
|
1767 |
|
|
voe_ad := (others => v.pci.oe_ad);
|
1768 |
|
|
oe_ad := r.pci.oe_ad; oe_ctrl := r.pci.oe_ctrl;
|
1769 |
|
|
oe_par := r.pci.oe_par; oe_req := r.pci.oe_req;
|
1770 |
|
|
oe_frame := r.pci.oe_frame; oe_cbe := r.pci.oe_cbe;
|
1771 |
|
|
oe_irdy := r.pci.oe_irdy; oe_perr := r.pci.oe_perr;
|
1772 |
|
|
end if;
|
1773 |
|
|
else
|
1774 |
|
|
if (syncrst = 1) and (pcirstin = '0') then
|
1775 |
|
|
voe_ad := (others => '0'); oe_ad := '0'; oe_ctrl := '0';
|
1776 |
|
|
oe_par := '0'; oe_req := '0'; oe_frame := '0'; oe_cbe := '0';
|
1777 |
|
|
oe_irdy := '0'; oe_perr := '0';
|
1778 |
|
|
else
|
1779 |
|
|
voe_ad := (others => v.noe_ad);
|
1780 |
|
|
oe_ad := r.noe_ad; oe_ctrl := r.noe_ctrl;
|
1781 |
|
|
oe_par := r.noe_par; oe_req := r.noe_req;
|
1782 |
|
|
oe_frame := r.noe_frame; oe_cbe := r.noe_cbe;
|
1783 |
|
|
oe_irdy := r.noe_irdy; oe_perr := r.noe_perr;
|
1784 |
|
|
end if;
|
1785 |
|
|
end if;
|
1786 |
|
|
|
1787 |
|
|
--------------------------
|
1788 |
|
|
--- SHARED SIGNALS END ---
|
1789 |
|
|
--------------------------
|
1790 |
|
|
|
1791 |
|
|
v.trans(0) := hstart;
|
1792 |
|
|
v.trans(1) := pabort;
|
1793 |
|
|
v.trans(2) := pstart_ack;
|
1794 |
|
|
v.trans(3) := pcidc;
|
1795 |
|
|
v.trans(4) := rtdone;
|
1796 |
|
|
v.trans(5) := rmdone;
|
1797 |
|
|
|
1798 |
|
|
if prrst = '0' then
|
1799 |
|
|
v.t.state := idle; v.m.state := idle; v.m.fstate := idle;
|
1800 |
|
|
v.bar0 := (others => '0'); v.bar0_conf := '0';
|
1801 |
|
|
v.bar1 := (others => '0'); v.bar1_conf := '0';
|
1802 |
|
|
v.t.msel := '0'; v.t.csel := '0';
|
1803 |
|
|
v.t.pending := '0'; v.t.lwrite := '0';
|
1804 |
|
|
v.bt_enable := '1'; -- twisting enabled by default, changed through page0
|
1805 |
|
|
v.page(31 downto 30) := "01";
|
1806 |
|
|
v.page(29 downto MADDR_WIDTH-1) := zero32(29 downto MADDR_WIDTH-1);
|
1807 |
|
|
v.pci.par := '0';
|
1808 |
|
|
v.comm.msen := not pr.host; v.comm.men := '0';
|
1809 |
|
|
v.comm.mwie := '0'; v.comm.per := '0';
|
1810 |
|
|
v.stat.rta := '0'; v.stat.rma := '0';
|
1811 |
|
|
v.stat.sta := '0'; v.stat.dped := '0';
|
1812 |
|
|
v.stat.dpe := '0';
|
1813 |
|
|
v.cline := (others => '0');
|
1814 |
|
|
v.ltim := (others => '0');
|
1815 |
|
|
v.intline := (others => '0');
|
1816 |
|
|
v.trans := (others => '0');
|
1817 |
|
|
v.t.fifo.waddr := (others => '0');
|
1818 |
|
|
v.t.fifo.raddr := (others => '0');
|
1819 |
|
|
v.m.fifo.waddr := (others => '0');
|
1820 |
|
|
v.m.fifo.raddr := (others => '0');
|
1821 |
|
|
v.t.fifo.side := '0';
|
1822 |
|
|
v.m.fifo.side := '0';
|
1823 |
|
|
v.m.request := '0';
|
1824 |
|
|
v.m.hwrite := '0';
|
1825 |
|
|
v.m.valid := '1';
|
1826 |
|
|
v.m.split := '0';
|
1827 |
|
|
v.m.last := '0'; v.t.last := '0';
|
1828 |
|
|
end if;
|
1829 |
|
|
|
1830 |
|
|
|
1831 |
|
|
cbe_fifoi.wen <= t_fifo_write;
|
1832 |
|
|
cbe_fifoi.waddr <= r.t.fifo.side & r.t.fifo.waddr;
|
1833 |
|
|
cbe_fifoi.wdata(3 downto 0) <= pr.cbe;
|
1834 |
|
|
|
1835 |
|
|
fifo2i.wen <= t_fifo_write;
|
1836 |
|
|
fifo2i.waddr <= r.t.fifo.side & r.t.fifo.waddr;
|
1837 |
|
|
fifo2i.wdata <= byte_twist(pr.ad, r.bt_enable);
|
1838 |
|
|
|
1839 |
|
|
fifo1i.ren <= '1';
|
1840 |
|
|
fifo1i.raddr <= t_read_side & (r.t.fifo.raddr + readt_dly);
|
1841 |
|
|
|
1842 |
|
|
fifo4i.wen <= m_fifo_write;
|
1843 |
|
|
fifo4i.waddr <= r.m.fifo.side & r.m.fifo.waddr;
|
1844 |
|
|
fifo4i.wdata <= pr.ad;
|
1845 |
|
|
|
1846 |
|
|
fifo3i.ren <= '1';
|
1847 |
|
|
fifo3i.raddr <= m_read_side & (r.m.fifo.raddr + data_transfer);
|
1848 |
|
|
|
1849 |
|
|
rin <= v;
|
1850 |
|
|
rioe_ad <= voe_ad;
|
1851 |
|
|
|
1852 |
|
|
|
1853 |
|
|
pcio.cbeen <= (others => oe_cbe);
|
1854 |
|
|
pcio.cbe <= r.pci.cbe;
|
1855 |
|
|
|
1856 |
|
|
pcio.vaden <= roe_ad;
|
1857 |
|
|
pcio.aden <= oe_ad;
|
1858 |
|
|
pcio.ad <= r.pci.ad;
|
1859 |
|
|
|
1860 |
|
|
-- pcio.trdy <= r.pci.trdy;
|
1861 |
|
|
pcio.trdy <= r.t.trdy_del; -- (send last word in fifo) bug fix ***
|
1862 |
|
|
pcio.ctrlen <= oe_ctrl;
|
1863 |
|
|
pcio.trdyen <= oe_ctrl;
|
1864 |
|
|
pcio.devselen <= oe_ctrl;
|
1865 |
|
|
pcio.stopen <= oe_ctrl;
|
1866 |
|
|
pcio.stop <= r.pci.stop;
|
1867 |
|
|
pcio.devsel <= r.pci.devsel;
|
1868 |
|
|
pcio.par <= r.pci.par;
|
1869 |
|
|
pcio.paren <= oe_par;
|
1870 |
|
|
pcio.perren <= oe_perr;
|
1871 |
|
|
pcio.perr <= r.pci.perr;
|
1872 |
|
|
|
1873 |
|
|
pcio.reqen <= oe_req;
|
1874 |
|
|
pcio.req <= r.pci.req;
|
1875 |
|
|
pcio.frameen <= oe_frame;
|
1876 |
|
|
pcio.frame <= r.pci.frame;
|
1877 |
|
|
pcio.irdyen <= oe_irdy;
|
1878 |
|
|
pcio.irdy <= r.pci.irdy;
|
1879 |
|
|
|
1880 |
|
|
end process;
|
1881 |
|
|
|
1882 |
|
|
rstinputgen : if hostrst = 0 generate
|
1883 |
|
|
pcirstin <= pcii.rst;
|
1884 |
|
|
pcio.rst <= '1';
|
1885 |
|
|
end generate;
|
1886 |
|
|
hostrstgen : if hostrst = 1 generate
|
1887 |
|
|
--pcirstin <= rst when pcii.host = '0' else pcii.rst;
|
1888 |
|
|
pcirstin <= pcii.rst;
|
1889 |
|
|
pcio.rst <= rst when pcii.host = '0' else '1';
|
1890 |
|
|
end generate;
|
1891 |
|
|
|
1892 |
|
|
|
1893 |
|
|
pcirst <= ahbmi.testrst when (scanen = 1) and (ahbmi.testen = '1')
|
1894 |
|
|
else pcirstin;
|
1895 |
|
|
|
1896 |
|
|
pr_regs : process (pciclk)
|
1897 |
|
|
begin
|
1898 |
|
|
if rising_edge (pciclk) then
|
1899 |
|
|
pr.ad <= to_x01(pcii.ad);
|
1900 |
|
|
pr.cbe <= to_x01(pcii.cbe);
|
1901 |
|
|
pr.devsel <= to_x01(pcii.devsel);
|
1902 |
|
|
pr.frame <= to_x01(pcii.frame);
|
1903 |
|
|
pr.idsel <= to_x01(pcii.idsel);
|
1904 |
|
|
pr.irdy <= to_x01(pcii.irdy);
|
1905 |
|
|
pr.trdy <= to_x01(pcii.trdy);
|
1906 |
|
|
pr.par <= to_x01(pcii.par);
|
1907 |
|
|
pr.stop <= to_x01(pcii.stop);
|
1908 |
|
|
prrst <= to_x01(pcirstin);
|
1909 |
|
|
pr.gnt <= to_x01(pcii.gnt);
|
1910 |
|
|
pr.host <= to_x01(pcii.host);
|
1911 |
|
|
end if;
|
1912 |
|
|
end process;
|
1913 |
|
|
|
1914 |
|
|
regs : process (pciclk, pcirst)
|
1915 |
|
|
begin
|
1916 |
|
|
if rising_edge (pciclk) then
|
1917 |
|
|
r <= rin;
|
1918 |
|
|
end if;
|
1919 |
|
|
if (syncrst = 0) and (pcirst = '0') then -- asynch reset required
|
1920 |
|
|
r.pci.oe_ad <= '1'; r.pci.oe_ctrl <= '1'; r.pci.oe_par <= '1';
|
1921 |
|
|
r.pci.oe_req <= '1'; r.pci.oe_frame <= '1'; r.pci.oe_cbe <= '1';
|
1922 |
|
|
r.pci.oe_irdy <= '1'; r.pci.oe_perr <= '1';
|
1923 |
|
|
r.noe_ad <= '0'; r.noe_ctrl <= '0'; r.noe_par <= '0';
|
1924 |
|
|
r.noe_req <= '0'; r.noe_frame <= '0'; r.noe_cbe <= '0';
|
1925 |
|
|
r.noe_irdy <= '0'; r.noe_perr <= '0';
|
1926 |
|
|
end if;
|
1927 |
|
|
end process;
|
1928 |
|
|
|
1929 |
|
|
oeregs_pol0 : if oepol = 0 generate
|
1930 |
|
|
oeregs : process (pciclk, pcirst)
|
1931 |
|
|
begin
|
1932 |
|
|
if rising_edge (pciclk) then
|
1933 |
|
|
roe_ad <= rioe_ad;
|
1934 |
|
|
end if;
|
1935 |
|
|
if (syncrst = 0) and (pcirst = '0') then -- asynch reset required
|
1936 |
|
|
roe_ad <= (others => '1');
|
1937 |
|
|
end if;
|
1938 |
|
|
end process;
|
1939 |
|
|
end generate;
|
1940 |
|
|
|
1941 |
|
|
oeregs_pol1 : if oepol = 1 generate
|
1942 |
|
|
oeregs : process (pciclk, pcirst)
|
1943 |
|
|
begin
|
1944 |
|
|
if rising_edge (pciclk) then
|
1945 |
|
|
roe_ad <= rioe_ad;
|
1946 |
|
|
end if;
|
1947 |
|
|
if (syncrst = 0) and (pcirst = '0') then -- asynch reset required
|
1948 |
|
|
roe_ad <= (others => '0');
|
1949 |
|
|
end if;
|
1950 |
|
|
end process;
|
1951 |
|
|
end generate;
|
1952 |
|
|
|
1953 |
|
|
cpur : process (clk)
|
1954 |
|
|
begin
|
1955 |
|
|
if rising_edge (clk) then
|
1956 |
|
|
r2 <= r2in;
|
1957 |
|
|
end if;
|
1958 |
|
|
end process;
|
1959 |
|
|
|
1960 |
|
|
oe0 : if oepol = 0 generate
|
1961 |
|
|
pcio.serren <= '1';
|
1962 |
|
|
pcio.inten <= '1';
|
1963 |
|
|
pcio.locken <= '1';
|
1964 |
|
|
end generate;
|
1965 |
|
|
|
1966 |
|
|
oe1 : if oepol = 1 generate
|
1967 |
|
|
pcio.serren <= '0';
|
1968 |
|
|
pcio.inten <= '0';
|
1969 |
|
|
pcio.locken <= '0';
|
1970 |
|
|
end generate;
|
1971 |
|
|
|
1972 |
|
|
pcio.serr <= '1';
|
1973 |
|
|
pcio.int <= '1';
|
1974 |
|
|
pcio.lock <= '1';
|
1975 |
|
|
|
1976 |
|
|
pcio.power_state <= (others => '0');
|
1977 |
|
|
pcio.pme_enable <= '0';
|
1978 |
|
|
pcio.pme_clear <= '0';
|
1979 |
|
|
|
1980 |
|
|
|
1981 |
|
|
msttgt : if MASTER = 1 generate
|
1982 |
|
|
|
1983 |
|
|
ahbmst0 : pciahbmst generic map (hindex => hmstndx, devid => GAISLER_PCIFBRG, incaddr => 1)
|
1984 |
|
|
port map (rst, clk, dmai, dmao, ahbmi, ahbmo);
|
1985 |
|
|
|
1986 |
|
|
fifo1 : syncram_2p generic map (tech => memtech, abits => FIFO_DEPTH, dbits => FIFO_DATA_BITS, sepclk => 1)
|
1987 |
|
|
port map (pciclk, fifo1i.ren, fifo1i.raddr, fifo1o.rdata, clk, fifo1i.wen, fifo1i.waddr, fifo1i.wdata);
|
1988 |
|
|
|
1989 |
|
|
fifo2 : syncram_2p generic map (tech => memtech, abits => FIFO_DEPTH, dbits => FIFO_DATA_BITS, sepclk => 1)
|
1990 |
|
|
port map (clk, fifo2i.ren, fifo2i.raddr, fifo2o.rdata, pciclk, fifo2i.wen, fifo2i.waddr, fifo2i.wdata);
|
1991 |
|
|
|
1992 |
|
|
fifo3 : syncram_2p generic map (tech => memtech, abits => FIFO_DEPTH, dbits => FIFO_DATA_BITS, sepclk => 1)
|
1993 |
|
|
port map (pciclk, fifo3i.ren, fifo3i.raddr, fifo3o.rdata, clk, fifo3i.wen, fifo3i.waddr, fifo3i.wdata);
|
1994 |
|
|
|
1995 |
|
|
fifo4 : syncram_2p generic map (tech => memtech, abits => FIFO_DEPTH, dbits => FIFO_DATA_BITS, sepclk => 1)
|
1996 |
|
|
port map (clk, fifo4i.ren, fifo4i.raddr, fifo4o.rdata, pciclk, fifo4i.wen, fifo4i.waddr, fifo4i.wdata);
|
1997 |
|
|
|
1998 |
|
|
cbe_fifo : syncram_2p generic map (tech => 0, abits => FIFO_DEPTH, dbits => 4, sepclk => 1)
|
1999 |
|
|
port map (clk, cbe_fifoi.ren, cbe_fifoi.raddr, cbe_fifoo.rdata(3 downto 0), pciclk, cbe_fifoi.wen, cbe_fifoi.waddr, cbe_fifoi.wdata(3 downto 0));
|
2000 |
|
|
|
2001 |
|
|
-- pragma translate_off
|
2002 |
|
|
bootmsg : report_version
|
2003 |
|
|
generic map ("pci_mtf" & tost(hslvndx) &
|
2004 |
|
|
": 32-bit PCI/AHB bridge rev " & tost(REVISION) &
|
2005 |
|
|
", " & tost(2**abits/2**20) & " Mbyte PCI memory BAR, " &
|
2006 |
|
|
tost(2**FIFO_DEPTH) & "-word FIFOs" );
|
2007 |
|
|
-- pragma translate_on
|
2008 |
|
|
|
2009 |
|
|
end generate;
|
2010 |
|
|
|
2011 |
|
|
tgtonly : if MASTER = 0 generate
|
2012 |
|
|
ahbmst0 : pciahbmst generic map (hindex => hmstndx, devid => GAISLER_PCIFBRG, incaddr => 1)
|
2013 |
|
|
port map (rst, clk, dmai, dmao, ahbmi, ahbmo);
|
2014 |
|
|
|
2015 |
|
|
fifo1 : syncram_2p generic map (tech => memtech, abits => FIFO_DEPTH, dbits => FIFO_DATA_BITS, sepclk => 1)
|
2016 |
|
|
port map (pciclk, fifo1i.ren, fifo1i.raddr, fifo1o.rdata, clk, fifo1i.wen, fifo1i.waddr, fifo1i.wdata);
|
2017 |
|
|
|
2018 |
|
|
fifo2 : syncram_2p generic map (tech => memtech, abits => FIFO_DEPTH, dbits => FIFO_DATA_BITS, sepclk => 1)
|
2019 |
|
|
port map (clk, fifo2i.ren, fifo2i.raddr, fifo2o.rdata, pciclk, fifo2i.wen, fifo2i.waddr, fifo2i.wdata);
|
2020 |
|
|
|
2021 |
|
|
cbe_fifo : syncram_2p generic map (tech => 0, abits => FIFO_DEPTH, dbits => 4, sepclk => 1)
|
2022 |
|
|
port map (clk, cbe_fifoi.ren, cbe_fifoi.raddr, cbe_fifoo.rdata(3 downto 0), pciclk, cbe_fifoi.wen, cbe_fifoi.waddr, cbe_fifoi.wdata(3 downto 0));
|
2023 |
|
|
|
2024 |
|
|
-- pragma translate_off
|
2025 |
|
|
bootmsg : report_version
|
2026 |
|
|
generic map ("pci_mtf" & tost(hmstndx) &
|
2027 |
|
|
": 32-bit PCI/AHB bridge rev, target-only, " & tost(REVISION) &
|
2028 |
|
|
", " & tost(2**abits/2**20) & " Mbyte PCI memory BAR, " &
|
2029 |
|
|
tost(2**FIFO_DEPTH) & "-word FIFOs" );
|
2030 |
|
|
-- pragma translate_on
|
2031 |
|
|
end generate;
|
2032 |
|
|
|
2033 |
|
|
end;
|