1 |
2 |
Lord_Nelso |
--+------------------------------------------------------------------+
|
2 |
|
|
--| |
|
3 |
|
|
--| PCI_TARGET -> Wishbone_MASTER interface (PCI_to_WB) v1.9 |
|
4 |
|
|
--| |
|
5 |
|
|
--| The first, original PCI module is from: |
|
6 |
|
|
--| Ben Jackson, http://www.ben.com/minipci/verilog.php |
|
7 |
|
|
--| |
|
8 |
|
|
--| The second, modified module "pci_mini" is from: |
|
9 |
|
|
--| Istvan Nagy, buenos@freemail.hu |
|
10 |
|
|
--| |
|
11 |
|
|
--| |
|
12 |
|
|
--| DOWNLOADED FROM OPENCORES. License = LGPL. |
|
13 |
|
|
--| |
|
14 |
|
|
--+------------------------------------------------------------------+
|
15 |
|
|
--| I used the code of the original pci_mini module to create |
|
16 |
|
|
--| a PCI to WB interface with direct read accesses (not |
|
17 |
|
|
--| like before, where data would be available only on |
|
18 |
|
|
--| a second PCI read) because that didn't work in my system. |
|
19 |
|
|
--| Thanks to Ben Jackson and Istvan Nagy for their works! |
|
20 |
|
|
--| I would not have been able to design such a core without |
|
21 |
|
|
--| the provided code base. |
|
22 |
|
|
--| Nelson Scheja (Lord_Nelson@opencores.org). |
|
23 |
|
|
--+------------------------------------------------------------------+----------------------------+
|
24 |
|
|
-- ########## General info ##########
|
25 |
|
|
|
26 |
|
|
-- The core implements a 16 MB memory image which is relocable on the WB bus:
|
27 |
|
|
-- WB_address = 4 * baseaddr + PCI_addr[23:2], where baseaddr is the WB image relocation
|
28 |
|
|
-- register (BAR0).
|
29 |
|
|
-- Only Dword aligned Dword accesses are allowed on the PCI. This way we can have access to the
|
30 |
|
|
-- full 32 bit WB address space through a 16 MB PCI window. The addressing on the WB bus is
|
31 |
|
|
-- Dword addressing, while on the PCI bus, it is byte addressing: PCI_addr / 4 = WB_address.
|
32 |
|
|
-- That means, when the PCI address is increasing by 4 ( = 4 Bytes = 1 Dword), the WB address
|
33 |
|
|
-- is increasing by 1 ( = 1 Dword, too).
|
34 |
|
|
|
35 |
|
|
-- Nearly full Wishbone compatible; single exception is master arbitration (through signals
|
36 |
|
|
-- wb_req and wb_gnt) which is not implemented.
|
37 |
|
|
|
38 |
|
|
-- (Remember, most PCI signals are active low, so I call them "asserted" when they are 0!
|
39 |
|
|
-- Only exceptions are clk, idsel and par, which are active high.)
|
40 |
|
|
|
41 |
|
|
-- The duration of a complete PCI cycle depends on the PCI command and the reaction time of the
|
42 |
|
|
-- PCI master and the addressed WB slave. Generally, Memory Reads need the most time to complete
|
43 |
|
|
-- (as the data path is the longest), and Config Writes are fastest.
|
44 |
|
|
|
45 |
|
|
|
46 |
|
|
-- ########## PCI bus support ##########
|
47 |
|
|
|
48 |
|
|
-- Intended PCI operation mode is 33 MHz, 32 bit.
|
49 |
|
|
|
50 |
|
|
-- Supported PCI commands are Config Read / Write, Memory Read / Write. Only single Dword
|
51 |
|
|
-- accesses are supported. (As the cbe bits are ignored for MemRead and MemWrite, a full DWord
|
52 |
|
|
-- is always transferred on these commands. Still, Byte or Word accesses are not recommended.)
|
53 |
|
|
|
54 |
|
|
-- The core supports only single reads / writes, that means only one data phase per PCI
|
55 |
|
|
-- cycle. Bursts are not allowed. In the first data phase, it asserts the stop signal
|
56 |
|
|
-- together with trdy to enforce a so-called "target initiated disconnect". This makes sure
|
57 |
|
|
-- that the PCI master will never try to extend a cycle past the first data phase.
|
58 |
|
|
|
59 |
|
|
-- When no WB response has been sent for WB_MAX_LAT clock cycles during a MemRead or MemWrite,
|
60 |
|
|
-- the core signals "Target-Abort" to the master. WB_MAX_LAT is user-definable in the range
|
61 |
|
|
-- from 0h to Fh.
|
62 |
|
|
|
63 |
|
|
-- DEVSEL timing is "fast". That means, devsel will be asserted the next clock edge after the
|
64 |
|
|
-- assertion of frame.
|
65 |
|
|
|
66 |
|
|
-- Parity of outgoing data is generated (one clock cycle after driving the ad lines). Parity
|
67 |
|
|
-- check of incoming address/data is not implemented. Thus, perr is held in high impedance the
|
68 |
|
|
-- whole time.
|
69 |
|
|
|
70 |
|
|
-- System Error indication is not implemented, thus serr is high impedance the whole time.
|
71 |
|
|
|
72 |
|
|
|
73 |
|
|
-- ########## Wishbone bus support ##########
|
74 |
|
|
|
75 |
|
|
-- Implemented Wishbone signals: wb_adr_o, wb_dat_o, wb_dat_i, wb_sel_o, wb_cyc_o, wb_stb_o,
|
76 |
|
|
-- wb_we_o, wb_ack_i, wb_err_i.
|
77 |
|
|
-- Not implemented Wishbone signals: clk, rst, rty, req, gnt, lock, stall, tag signals.
|
78 |
|
|
|
79 |
|
|
-- The signals wb_rst and wb_clk are not generated as this is actually the job of the Syscon
|
80 |
|
|
-- module and should be done outside this core. Still, it could come in handy to use the core
|
81 |
|
|
-- also as Syscon, so these two ports and their processes are only commented out and can be
|
82 |
|
|
-- quickly reactivated if necessary.
|
83 |
|
|
|
84 |
|
|
-- Attention! The core was intended for a Wishbone bus scenario where it is the only master.
|
85 |
|
|
-- Thus, no arbitration methods are supported, which actually is not 100% WB compatible. Do not
|
86 |
|
|
-- put another master on the same WB bus as this core! The advantage is fewer logic units and
|
87 |
|
|
-- faster bus cycles (because the core asserts wb_cyc and wb_stb at the same time and doesn't
|
88 |
|
|
-- have to wait for a grant in between).
|
89 |
|
|
|
90 |
|
|
-- Supported commands are single read / write. Pipelined mode is not supported.
|
91 |
|
|
|
92 |
|
|
-- All bits of the signal wb_sel are always driven high during normal operation because all WB
|
93 |
|
|
-- accesses use 4 Bytes. Only when reset is asserted, wb_sel = 0000.
|
94 |
|
|
|
95 |
|
|
|
96 |
|
|
-- ########## Device Compatibility ##########
|
97 |
|
|
|
98 |
|
|
-- The core was tested and used on a Xilinx Spartan3 XC3S1000 FT256-4. The PCI master was a
|
99 |
|
|
-- MPC5200 microcontroller.
|
100 |
|
|
|
101 |
|
|
-- There are no Xilinx-specific components defined in the code, so theoretically it should be
|
102 |
|
|
-- compatible to FPGAs of all developers.
|
103 |
|
|
|
104 |
|
|
-- Utilization (extract from Xilinx ISE Map Report): Slices 183; Slice Reg 143; LUTs 194.
|
105 |
|
|
|
106 |
|
|
-- The IEEE library numeric_std is used.
|
107 |
|
|
|
108 |
|
|
|
109 |
|
|
-- ########## Change log ##########
|
110 |
|
|
|
111 |
|
|
-- Merged PCI state machine, WB state machine and Address decoder into a single big process to
|
112 |
|
|
-- allow faster PCI reaction and reduce amount of signals.
|
113 |
|
|
-- Made the interrupt asynchronously to clk to ensure fastest possible interrupt generation.
|
114 |
|
|
-- In Config cycles, it is now paid attention to the Byte Enable bits cbe.
|
115 |
|
|
-- Target-Abort is generated when no response (ack or err) has come from the Wishbone for
|
116 |
|
|
-- WB_MAX_LAT clock cycles.
|
117 |
|
|
-- Completely modified the internal structure of the config signals.
|
118 |
|
|
-- Made the interrupt port information configurable via generic.
|
119 |
|
|
-- Removed everything that's got to do with interrupts, as an INTA pin is not mandatory for PCI
|
120 |
|
|
-- and WB has no definition of an interrupt request protocol.
|
121 |
|
|
-- Realized main_state signal (formerly pci_state) as an enum type and let it also control all
|
122 |
|
|
-- the sub states (deleted former sub_state).
|
123 |
|
|
|
124 |
|
|
|
125 |
|
|
-- ########## ToDos / Problems ##########
|
126 |
|
|
|
127 |
|
|
-- Implement parity check?
|
128 |
|
|
-- Implement WB byte select?
|
129 |
|
|
-- Check WB Timeout counter accuracy! Don't know whether the cycle count is perfectly correct.
|
130 |
|
|
-- Assertion of trdy and stop lasts for about 10 clock cycles when scoped in reality! Reason
|
131 |
|
|
-- unclear, maybe an effect due to the slow pullups?
|
132 |
|
|
-- Uncorrect handling of wb_err assertion (it seems)! Stop isn't asserted sometimes.
|
133 |
|
|
--+-----------------------------------------------------------------------------------------------+
|
134 |
|
|
|
135 |
|
|
library ieee;
|
136 |
|
|
use ieee.STD_LOGIC_1164.all;
|
137 |
|
|
use ieee.numeric_std.all;
|
138 |
|
|
|
139 |
|
|
|
140 |
|
|
entity pci_to_wb is
|
141 |
|
|
port(
|
142 |
|
|
--PCI signals
|
143 |
|
|
reset : in std_logic;
|
144 |
|
|
clk : in std_logic;
|
145 |
|
|
frame : in std_logic;
|
146 |
|
|
irdy : in std_logic;
|
147 |
|
|
trdy : out std_logic;
|
148 |
|
|
devsel : out std_logic;
|
149 |
|
|
idsel : in std_logic;
|
150 |
|
|
ad : inout std_logic_vector(31 downto 0) := (others => 'Z');
|
151 |
|
|
cbe : in std_logic_vector(3 downto 0);
|
152 |
|
|
par : inout std_logic := 'Z';
|
153 |
|
|
stop : out std_logic;
|
154 |
|
|
serr : out std_logic;
|
155 |
|
|
perr : out std_logic;
|
156 |
|
|
--Wishbone signals
|
157 |
|
|
-- wb_clk_o : out std_logic; --uncomment these two signals and their corresponding processes at the
|
158 |
|
|
-- wb_rst_o : out std_logic; --beginning of the architecture body to achieve syscon functionality
|
159 |
|
|
wb_adr_o : out std_logic_vector(31 downto 0);
|
160 |
|
|
wb_dat_o : out std_logic_vector(31 downto 0);
|
161 |
|
|
wb_dat_i : in std_logic_vector(31 downto 0);
|
162 |
|
|
wb_sel_o : out std_logic_vector(3 downto 0) := "0000";
|
163 |
|
|
wb_cyc_o : out std_logic := '0';
|
164 |
|
|
wb_stb_o : out std_logic := '0';
|
165 |
|
|
wb_we_o : out std_logic := '0';
|
166 |
|
|
wb_ack_i : in std_logic;
|
167 |
|
|
wb_err_i : in std_logic
|
168 |
|
|
);
|
169 |
|
|
end pci_to_wb;
|
170 |
|
|
|
171 |
|
|
|
172 |
|
|
architecture Behavioral of pci_to_wb is
|
173 |
|
|
|
174 |
|
|
--+------------------------------------------------------------------------------------+
|
175 |
|
|
--| Constants |
|
176 |
|
|
--+------------------------------------------------------------------------------------+
|
177 |
|
|
|
178 |
|
|
--user specific constants. Change them at your will.
|
179 |
|
|
constant DEVICE_ID : std_logic_vector := x"1337"; --It's leet. Yo.
|
180 |
|
|
constant VENDOR_ID : std_logic_vector := x"1234";
|
181 |
|
|
constant DEVICE_CLASS : std_logic_vector := x"118000"; --(068000=bridge/other, 078000=simple_comm_contr/other, 118000=data_acquisition/other)
|
182 |
|
|
constant DEVICE_REV : std_logic_vector := x"09"; --version of the PCI to WB module
|
183 |
|
|
constant SUBSYSTEM_ID : std_logic_vector := x"0001"; --card identifier
|
184 |
|
|
constant SUBSYSTEM_VENDOR_ID : std_logic_vector := x"9876";
|
185 |
|
|
constant WB_MAX_LAT : unsigned := x"4"; --defines how many clock cycles the WB has time to answer to wb_stb before Target-Abort is activated
|
186 |
|
|
|
187 |
|
|
-- supported PCI commands
|
188 |
|
|
constant CFGREAD : std_logic_vector := "1010";
|
189 |
|
|
constant CFGWRITE : std_logic_vector := "1011";
|
190 |
|
|
constant MEMREAD : std_logic_vector := "0110";
|
191 |
|
|
constant MEMWRITE : std_logic_vector := "0111";
|
192 |
|
|
|
193 |
|
|
|
194 |
|
|
--+------------------------------------------------------------------------------------+
|
195 |
|
|
--| Internal signals |
|
196 |
|
|
--+------------------------------------------------------------------------------------+
|
197 |
|
|
|
198 |
|
|
-- state machine flow
|
199 |
|
|
type main_state_type is (Idle, Cfg_read_1, Cfg_read_2, Cfg_write_1, Cfg_write_2,
|
200 |
|
|
Mem_read_1, Mem_read_2, Mem_read_3, Mem_write_1, Mem_write_2, Mem_write_3);
|
201 |
|
|
signal main_state : main_state_type := Idle;
|
202 |
|
|
signal wait_count : unsigned(3 downto 0) := x"0"; --counts up to WB_MAX_LAT while waiting on WB response
|
203 |
|
|
signal par_create : std_logic := '0'; --controls the parity generator: when 1, parity is generated, else not
|
204 |
|
|
|
205 |
|
|
signal pci_address : std_logic_vector(23 downto 2); --latch of AD lines during the address phase (upper 8 and lower 2 of the 32 bits are never used)
|
206 |
|
|
|
207 |
|
|
-- configuration registers
|
208 |
|
|
signal cfg_reg_0x00 : std_logic_vector(31 downto 0) := DEVICE_ID & VENDOR_ID;
|
209 |
|
|
|
210 |
|
|
signal cfg_reg_0x04 : std_logic_vector(31 downto 0) := x"00000000";
|
211 |
|
|
alias target_abort : std_logic is cfg_reg_0x04(27); --Target-Abort status bit (status register)
|
212 |
|
|
alias mem_ena : std_logic is cfg_reg_0x04(1); --memory space enable bit (command register)
|
213 |
|
|
|
214 |
|
|
signal cfg_reg_0x08 : std_logic_vector(31 downto 0) := DEVICE_CLASS & DEVICE_REV;
|
215 |
|
|
|
216 |
|
|
signal cfg_reg_0x10 : std_logic_vector(31 downto 0) := x"00000000";
|
217 |
|
|
alias baseaddr : std_logic_vector(7 downto 0) is cfg_reg_0x10(31 downto 24); --used for relocating the WB address space
|
218 |
|
|
|
219 |
|
|
signal cfg_reg_0x2c : std_logic_vector(31 downto 0) := SUBSYSTEM_ID & SUBSYSTEM_VENDOR_ID;
|
220 |
|
|
|
221 |
|
|
|
222 |
|
|
begin
|
223 |
|
|
|
224 |
|
|
--+------------------------------------------------------------------------------------+
|
225 |
|
|
--| Small signal processes |
|
226 |
|
|
--+------------------------------------------------------------------------------------+
|
227 |
|
|
--Wishbone clock and (asynchronous) reset:
|
228 |
|
|
-- wb_clk_o <= clk; --uncomment these two processes and their corresponding
|
229 |
|
|
-- wb_rst_o <= not reset; --signals in the entity to achieve syscon functionality
|
230 |
|
|
|
231 |
|
|
--these are not used:
|
232 |
|
|
serr <= 'Z';
|
233 |
|
|
perr <= 'Z';
|
234 |
|
|
|
235 |
|
|
--only dword accesses, so wb_sel can always be high (except during reset):
|
236 |
|
|
process(reset)
|
237 |
|
|
begin
|
238 |
|
|
if reset = '0' then
|
239 |
|
|
wb_sel_o <= "0000";
|
240 |
|
|
else
|
241 |
|
|
wb_sel_o <= "1111";
|
242 |
|
|
end if;
|
243 |
|
|
end process;
|
244 |
|
|
|
245 |
|
|
|
246 |
|
|
--+------------------------------------------------------------------------------------+
|
247 |
|
|
--| MAIN STATE MACHINE |
|
248 |
|
|
--+------------------------------------------------------------------------------------+
|
249 |
|
|
-- This process controls the translation from PCI protocol to Wishbone protocol.
|
250 |
|
|
-- It is realized as a state machine with five main states (defined with main_state).
|
251 |
|
|
-- Most main states are further divided into sub states (defined with sub_state)
|
252 |
|
|
-- to control the flow of execution during a PCI cycle.
|
253 |
|
|
process(reset, clk)
|
254 |
|
|
begin
|
255 |
|
|
if reset = '0' then
|
256 |
|
|
main_state <= Idle;
|
257 |
|
|
|
258 |
|
|
ad <= (others => 'Z');
|
259 |
|
|
devsel <= 'Z';
|
260 |
|
|
trdy <= 'Z';
|
261 |
|
|
stop <= 'Z';
|
262 |
|
|
par_create <= '0';
|
263 |
|
|
wait_count <= (others => '0');
|
264 |
|
|
|
265 |
|
|
target_abort<= '0';
|
266 |
|
|
mem_ena <= '0';
|
267 |
|
|
baseaddr <= (others => '0');
|
268 |
|
|
|
269 |
|
|
wb_adr_o <= (others => '0');
|
270 |
|
|
wb_dat_o <= (others => '0');
|
271 |
|
|
wb_cyc_o <= '0';
|
272 |
|
|
wb_stb_o <= '0';
|
273 |
|
|
wb_we_o <= '0';
|
274 |
|
|
elsif rising_edge(clk) then
|
275 |
|
|
case main_state is
|
276 |
|
|
|
277 |
|
|
-- ########## IDLE STATE ##########
|
278 |
|
|
-- State for between PCI cycles and during the address phase (which is identified by the
|
279 |
|
|
-- assertion of frame). While here, all signals to PCI, WB and internals are in deasserted
|
280 |
|
|
-- state. When the core is being addressed correctly by the PCI master, it asserts devsel
|
281 |
|
|
-- as response and changes to the state defined by the command bits (cbe).
|
282 |
|
|
when Idle =>
|
283 |
|
|
trdy <= 'Z';
|
284 |
|
|
stop <= 'Z';
|
285 |
|
|
devsel <= 'Z';
|
286 |
|
|
|
287 |
|
|
if frame = '0' then
|
288 |
|
|
pci_address <= ad(23 downto 2);
|
289 |
|
|
if idsel = '1' and ad(10 downto 8) = "000" and ad(1 downto 0) = "00" then --correct config space access
|
290 |
|
|
if cbe = CFGREAD then
|
291 |
|
|
devsel <= '0';
|
292 |
|
|
main_state <= Cfg_read_1;
|
293 |
|
|
elsif cbe = CFGWRITE then
|
294 |
|
|
devsel <= '0';
|
295 |
|
|
main_state <= Cfg_write_1;
|
296 |
|
|
end if;
|
297 |
|
|
elsif mem_ena = '1' and ad(31 downto 24) = baseaddr then --correct memory space access
|
298 |
|
|
if cbe = MEMREAD then
|
299 |
|
|
devsel <= '0';
|
300 |
|
|
main_state <= Mem_read_1;
|
301 |
|
|
elsif cbe = MEMWRITE then
|
302 |
|
|
devsel <= '0';
|
303 |
|
|
main_state <= Mem_write_1;
|
304 |
|
|
end if;
|
305 |
|
|
end if;
|
306 |
|
|
end if;
|
307 |
|
|
|
308 |
|
|
|
309 |
|
|
-- ########## CFG READ STATE ##########
|
310 |
|
|
-- The config register at the DWord address pci_address is read. Depending on the Byte Enables
|
311 |
|
|
-- cbe, the data is provided on ad When cbe(0) = 0, then byte 0 is all zeroes, etc. One
|
312 |
|
|
-- clock cycle later, the parity is provided and the PCI cycle is terminated.
|
313 |
|
|
|
314 |
|
|
--STAGE 1: gather register data internally in the first clock cycle where irdy is asserted
|
315 |
|
|
when Cfg_read_1 =>
|
316 |
|
|
if irdy = '0' then
|
317 |
|
|
case pci_address(7 downto 2) is
|
318 |
|
|
when "000000" => --0d*4 = 00h. Device ID (31 - 16), Vendor ID (15 - 0).
|
319 |
|
|
if cbe(3) = '0' then
|
320 |
|
|
ad(31 downto 24) <= cfg_reg_0x00(31 downto 24);
|
321 |
|
|
else
|
322 |
|
|
ad(31 downto 24) <= (others => '0');
|
323 |
|
|
end if;
|
324 |
|
|
if cbe(2) = '0' then
|
325 |
|
|
ad(23 downto 16) <= cfg_reg_0x00(23 downto 16);
|
326 |
|
|
else
|
327 |
|
|
ad(23 downto 16) <= (others => '0');
|
328 |
|
|
end if;
|
329 |
|
|
if cbe(1) = '0' then
|
330 |
|
|
ad(15 downto 8) <= cfg_reg_0x00(15 downto 8);
|
331 |
|
|
else
|
332 |
|
|
ad(15 downto 8) <= (others => '0');
|
333 |
|
|
end if;
|
334 |
|
|
if cbe(0) = '0' then
|
335 |
|
|
ad(7 downto 0) <= cfg_reg_0x00(7 downto 0);
|
336 |
|
|
else
|
337 |
|
|
ad(7 downto 0) <= (others => '0');
|
338 |
|
|
end if;
|
339 |
|
|
when "000001" => --1d*4 = 04h. Status (31 - 16), Command (15 - 0).
|
340 |
|
|
if cbe(3) = '0' then
|
341 |
|
|
ad(31 downto 24) <= cfg_reg_0x04(31 downto 24);
|
342 |
|
|
else
|
343 |
|
|
ad(31 downto 24) <= (others => '0');
|
344 |
|
|
end if;
|
345 |
|
|
ad(23 downto 8) <= (others => '0');
|
346 |
|
|
if cbe(0) = '0' then
|
347 |
|
|
ad(7 downto 0) <= cfg_reg_0x04(7 downto 0);
|
348 |
|
|
else
|
349 |
|
|
ad(7 downto 0) <= (others => '0');
|
350 |
|
|
end if;
|
351 |
|
|
when "000010" => --2d*4 = 08h. Class Code (31 - 8), Revision ID (7 - 0).
|
352 |
|
|
if cbe(3) = '0' then
|
353 |
|
|
ad(31 downto 24) <= cfg_reg_0x08(31 downto 24);
|
354 |
|
|
else
|
355 |
|
|
ad(31 downto 24) <= (others => '0');
|
356 |
|
|
end if;
|
357 |
|
|
if cbe(2) = '0' then
|
358 |
|
|
ad(23 downto 16) <= cfg_reg_0x08(23 downto 16);
|
359 |
|
|
else
|
360 |
|
|
ad(23 downto 16) <= (others => '0');
|
361 |
|
|
end if;
|
362 |
|
|
if cbe(1) = '0' then
|
363 |
|
|
ad(15 downto 8) <= cfg_reg_0x08(15 downto 8);
|
364 |
|
|
else
|
365 |
|
|
ad(15 downto 8) <= (others => '0');
|
366 |
|
|
end if;
|
367 |
|
|
if cbe(0) = '0' then
|
368 |
|
|
ad(7 downto 0) <= cfg_reg_0x08(7 downto 0);
|
369 |
|
|
else
|
370 |
|
|
ad(7 downto 0) <= (others => '0');
|
371 |
|
|
end if;
|
372 |
|
|
when "000100" => --4d*4 = 10h. Base Address Register 0, = baseaddr.
|
373 |
|
|
if cbe(3) = '0' then
|
374 |
|
|
ad(31 downto 24) <= cfg_reg_0x10(31 downto 24);
|
375 |
|
|
else
|
376 |
|
|
ad(31 downto 24) <= (others => '0');
|
377 |
|
|
end if;
|
378 |
|
|
ad(23 downto 0) <= (others => '0');
|
379 |
|
|
when "001011" => --11d*4 = 2Ch. Subsystem ID (31 - 16), Subsystem Vendor ID (15 - 0).
|
380 |
|
|
if cbe(3) = '0' then
|
381 |
|
|
ad(31 downto 24) <= cfg_reg_0x2c(31 downto 24);
|
382 |
|
|
else
|
383 |
|
|
ad(31 downto 24) <= (others => '0');
|
384 |
|
|
end if;
|
385 |
|
|
if cbe(2) = '0' then
|
386 |
|
|
ad(23 downto 16) <= cfg_reg_0x2c(23 downto 16);
|
387 |
|
|
else
|
388 |
|
|
ad(23 downto 16) <= (others => '0');
|
389 |
|
|
end if;
|
390 |
|
|
if cbe(1) = '0' then
|
391 |
|
|
ad(15 downto 8) <= cfg_reg_0x2c(15 downto 8);
|
392 |
|
|
else
|
393 |
|
|
ad(15 downto 8) <= (others => '0');
|
394 |
|
|
end if;
|
395 |
|
|
if cbe(0) = '0' then
|
396 |
|
|
ad(7 downto 0) <= cfg_reg_0x2c(7 downto 0);
|
397 |
|
|
else
|
398 |
|
|
ad(7 downto 0) <= (others => '0');
|
399 |
|
|
end if;
|
400 |
|
|
when others => --unsupported or reserved config registers.
|
401 |
|
|
ad <= (others => '0');
|
402 |
|
|
end case;
|
403 |
|
|
|
404 |
|
|
trdy <= '0';
|
405 |
|
|
stop <= '0';
|
406 |
|
|
par_create <= '1';
|
407 |
|
|
main_state <= Cfg_read_2;
|
408 |
|
|
end if;
|
409 |
|
|
|
410 |
|
|
--STAGE 2: one clock cycle later, end the PCI cycle
|
411 |
|
|
when Cfg_read_2 =>
|
412 |
|
|
ad <= (others => 'Z');
|
413 |
|
|
devsel <= '1';
|
414 |
|
|
trdy <= '1';
|
415 |
|
|
stop <= '1';
|
416 |
|
|
par_create <= '0';
|
417 |
|
|
main_state <= Idle;
|
418 |
|
|
|
419 |
|
|
|
420 |
|
|
-- ########## CFG WRITE STATE ##########
|
421 |
|
|
-- The config register at the DWord address pci_address is written, depending on the Byte Enables
|
422 |
|
|
-- cbe. Some bits are not writable, so nothing will be changed then. The status register
|
423 |
|
|
-- is special: When writing a 1 onto a bit, this bit is cleared; writing a 0 will have no
|
424 |
|
|
-- effect. One clock cycle later, the PCI cycle is terminated.
|
425 |
|
|
|
426 |
|
|
-- STAGE 1: return config values in the first clock cycle where irdy is asserted
|
427 |
|
|
when Cfg_write_1 =>
|
428 |
|
|
trdy <= '0';
|
429 |
|
|
stop <= '0';
|
430 |
|
|
if irdy = '0' then
|
431 |
|
|
case pci_address(7 downto 2) is
|
432 |
|
|
when "000001" => --1d*4 = 04h. Status (31 - 16), Command (15 - 0).
|
433 |
|
|
if cbe(3) = '0' and ad(27) = '1' then
|
434 |
|
|
target_abort<= '0'; --reset status bit Target-Abort when writing a 1 there
|
435 |
|
|
end if;
|
436 |
|
|
if cbe(0) = '0' then
|
437 |
|
|
mem_ena <= ad(1);
|
438 |
|
|
end if;
|
439 |
|
|
when "000100" => --4d*4 = 10h. Base Address Register 0 (BAR0).
|
440 |
|
|
if cbe(3) = '0' then
|
441 |
|
|
baseaddr <= ad(31 downto 24);
|
442 |
|
|
end if;
|
443 |
|
|
when others => --config registers that are reserved, unsupported or don't support writes.
|
444 |
|
|
null;
|
445 |
|
|
end case;
|
446 |
|
|
main_state <= Cfg_write_2;
|
447 |
|
|
end if;
|
448 |
|
|
|
449 |
|
|
--STAGE 2: one clock cycle later, end the PCI cycle
|
450 |
|
|
when Cfg_write_2 =>
|
451 |
|
|
devsel <= '1';
|
452 |
|
|
trdy <= '1';
|
453 |
|
|
stop <= '1';
|
454 |
|
|
main_state <= Idle;
|
455 |
|
|
|
456 |
|
|
|
457 |
|
|
-- ########## MEM READ STATE ##########
|
458 |
|
|
-- The data to be written and the address is provided for the Wishbone bus. Then,
|
459 |
|
|
-- wait for Wishbone response:
|
460 |
|
|
-- When ack_i is asserted (= data ready), signal "Disconnect with data" to PCI master,
|
461 |
|
|
-- provide the data and one clock cycle later the parity.
|
462 |
|
|
-- When err_i is asserted (= access error), signal "Target-Abort". In this case, no
|
463 |
|
|
-- data is provided and the third stage is not activated.
|
464 |
|
|
-- When neither ack_i nor err_i were asserted for WB_MAX_LAT clock cycles, signal
|
465 |
|
|
-- "Target-Abort". The third stage is not activated then, too.
|
466 |
|
|
|
467 |
|
|
--STAGE 1: save address for Wishbone in the first clock cycle where irdy is asserted and initiate WB action
|
468 |
|
|
when Mem_read_1 =>
|
469 |
|
|
if irdy = '0' then
|
470 |
|
|
wb_adr_o <= "0000000000" & pci_address;
|
471 |
|
|
wb_cyc_o <= '1'; --set the Wishbone master signals for a read cycle
|
472 |
|
|
wb_stb_o <= '1';
|
473 |
|
|
wait_count <= x"0"; --reset timeout counter
|
474 |
|
|
main_state <= Mem_read_2;
|
475 |
|
|
end if;
|
476 |
|
|
|
477 |
|
|
--STAGE 2: wait for Wishbone response, react accordingly to the PCI bus and end the WB cycle
|
478 |
|
|
when Mem_read_2 =>
|
479 |
|
|
if wb_ack_i = '1' then --WB transaction completed
|
480 |
|
|
wb_adr_o <= (others => '0');
|
481 |
|
|
wb_cyc_o <= '0';
|
482 |
|
|
wb_stb_o <= '0';
|
483 |
|
|
ad <= wb_dat_i;
|
484 |
|
|
trdy <= '0'; --trdy and stop asserted at the same time -> Disconnect
|
485 |
|
|
stop <= '0';
|
486 |
|
|
par_create <= '1';
|
487 |
|
|
main_state <= Mem_read_3;
|
488 |
|
|
elsif wb_err_i = '1' or wait_count = WB_MAX_LAT then --WB transaction aborted, or no WB answer for WB_MAX_LAT clock cycles
|
489 |
|
|
wb_adr_o <= (others => '0');
|
490 |
|
|
wb_cyc_o <= '0';
|
491 |
|
|
wb_stb_o <= '0';
|
492 |
|
|
devsel <= '1'; --stop asserted and devsel deasserted at the same time -> Target-Abort
|
493 |
|
|
stop <= '0';
|
494 |
|
|
target_abort <= '1'; --status register entry
|
495 |
|
|
main_state <= Idle;
|
496 |
|
|
end if;
|
497 |
|
|
wait_count <= wait_count + 1; --count the wait cycles
|
498 |
|
|
|
499 |
|
|
--STAGE 3: one clock cycle later, end the PCI cycle (only after Disconnect)
|
500 |
|
|
when Mem_read_3 =>
|
501 |
|
|
ad <= (others => 'Z');
|
502 |
|
|
devsel <= '1';
|
503 |
|
|
trdy <= '1';
|
504 |
|
|
stop <= '1';
|
505 |
|
|
par_create <= '0';
|
506 |
|
|
main_state <= Idle;
|
507 |
|
|
|
508 |
|
|
|
509 |
|
|
-- ########## MEM WRITE STATE ##########
|
510 |
|
|
-- The data to be written and the address is provided for the Wishbone bus. Then,
|
511 |
|
|
-- wait for Wishbone response:
|
512 |
|
|
-- When ack_i is asserted (= data was stored), signal "Disconnect with data" to PCI
|
513 |
|
|
-- master and end the PCI cycle on the next clock edge.
|
514 |
|
|
-- When err_i is asserted (= access error, no transaction), signal "Target-Abort". In
|
515 |
|
|
-- this case, no data was changed and the third stage is not activated.
|
516 |
|
|
-- When neither ack_i nor err_i were asserted for WB_MAX_LAT clock cycles, signal
|
517 |
|
|
-- "Target-Abort". The third stage is not activated then, too.
|
518 |
|
|
|
519 |
|
|
--STAGE 1: save write data for WB in the first clock cycle where irdy is asserted and initiate WB action
|
520 |
|
|
when Mem_write_1 =>
|
521 |
|
|
if irdy = '0' then
|
522 |
|
|
wb_adr_o <= x"00" & "00" & pci_address;
|
523 |
|
|
wb_dat_o <= ad;
|
524 |
|
|
wb_cyc_o <= '1'; --set the Wishbone master signals for a write cycle
|
525 |
|
|
wb_stb_o <= '1';
|
526 |
|
|
wb_we_o <= '1';
|
527 |
|
|
wait_count <= x"0"; --reset timeout counter
|
528 |
|
|
main_state <= Mem_write_2;
|
529 |
|
|
end if;
|
530 |
|
|
|
531 |
|
|
--STAGE 2: wait for Wishbone response, react accordingly to the PCI bus and end the WB cycle
|
532 |
|
|
when Mem_write_2 =>
|
533 |
|
|
if wb_ack_i = '1' then --WB transaction completed
|
534 |
|
|
wb_adr_o <= (others => '0');
|
535 |
|
|
wb_dat_o <= (others => '0');
|
536 |
|
|
wb_cyc_o <= '0';
|
537 |
|
|
wb_stb_o <= '0';
|
538 |
|
|
wb_we_o <= '0';
|
539 |
|
|
trdy <= '0'; --trdy and stop asserted at the same time -> Disconnect
|
540 |
|
|
stop <= '0';
|
541 |
|
|
main_state <= Mem_write_3;
|
542 |
|
|
elsif wb_err_i = '1' or wait_count = WB_MAX_LAT then --WB transaction aborted, or no WB answer for WB_MAX_LAT clock cycles
|
543 |
|
|
wb_adr_o <= (others => '0');
|
544 |
|
|
wb_dat_o <= (others => '0');
|
545 |
|
|
wb_cyc_o <= '0';
|
546 |
|
|
wb_stb_o <= '0';
|
547 |
|
|
wb_we_o <= '0';
|
548 |
|
|
devsel <= '1'; --stop asserted and devsel deasserted at the same time -> Target-Abort
|
549 |
|
|
stop <= '0';
|
550 |
|
|
target_abort<= '1'; --status register entry
|
551 |
|
|
main_state <= Idle;
|
552 |
|
|
end if;
|
553 |
|
|
wait_count <= wait_count + 1; --count the wait cycles
|
554 |
|
|
|
555 |
|
|
--STAGE 3: one clock cycle later, end the PCI cycle (only after Disconnect)
|
556 |
|
|
when Mem_write_3 =>
|
557 |
|
|
devsel <= '1';
|
558 |
|
|
trdy <= '1';
|
559 |
|
|
stop <= '1';
|
560 |
|
|
main_state <= Idle;
|
561 |
|
|
|
562 |
|
|
|
563 |
|
|
-- ########## undefined state ##########
|
564 |
|
|
-- This state normally should never occur. Just for completion.
|
565 |
|
|
when others =>
|
566 |
|
|
main_state <= Idle;
|
567 |
|
|
|
568 |
|
|
end case;
|
569 |
|
|
end if;
|
570 |
|
|
end process;
|
571 |
|
|
|
572 |
|
|
|
573 |
|
|
--+------------------------------------------------------------------------------------+
|
574 |
|
|
--| Parity generation |
|
575 |
|
|
--+------------------------------------------------------------------------------------+
|
576 |
|
|
-- This process calcutates the even parity of the ad and cbe lines when par_create is
|
577 |
|
|
-- asserted. The main state machine asserts par_create exactly when trdy is asserted
|
578 |
|
|
-- in a Read cycle (both Config and Memory). Because this process sees the assertion
|
579 |
|
|
-- of par_create only on the following clock edge, parity for the master is always
|
580 |
|
|
-- provided one clock cycle delayed to ad (which is required by PCI).
|
581 |
|
|
process(reset, clk)
|
582 |
|
|
begin
|
583 |
|
|
if reset = '0' then
|
584 |
|
|
par <= 'Z';
|
585 |
|
|
elsif rising_edge(clk) then
|
586 |
|
|
if par_create = '1' then
|
587 |
|
|
par <= ( ad(31) xor ad(30) xor ad(29) xor ad(28) ) xor
|
588 |
|
|
( ad(27) xor ad(26) xor ad(25) xor ad(24) ) xor
|
589 |
|
|
( ad(23) xor ad(22) xor ad(21) xor ad(20) ) xor
|
590 |
|
|
( ad(19) xor ad(18) xor ad(17) xor ad(16) ) xor
|
591 |
|
|
( ad(15) xor ad(14) xor ad(13) xor ad(12) ) xor
|
592 |
|
|
( ad(11) xor ad(10) xor ad(9) xor ad(8) ) xor
|
593 |
|
|
( ad(7) xor ad(6) xor ad(5) xor ad(4) ) xor
|
594 |
|
|
( ad(3) xor ad(2) xor ad(1) xor ad(0) ) xor
|
595 |
|
|
( cbe(3) xor cbe(2) xor cbe(1) xor cbe(0) );
|
596 |
|
|
else
|
597 |
|
|
par <= 'Z';
|
598 |
|
|
end if;
|
599 |
|
|
end if;
|
600 |
|
|
end process;
|
601 |
|
|
|
602 |
|
|
|
603 |
|
|
end Behavioral;
|