This is a sample design for Nios II with Altera PCI host bridge to
connect external PCI devices (such as WiFi,
GigaLAN?, etc). It uses the SOPC Builder flow in the PCI Compiler. The sample design uses external PCI
clock, and internal bus arbitor to support up to two external PCI
masters. The SDRAM on Avalon bus can be accessed by the external
masters. A simple external interrupt wrapping module, "irqn", is used
to connect interrupts from external devices to the Nios II CPU.
Follow the user guide to add PCI timing constraints with the TCL file.
If you are new to PCI, read the book "PCI System Architecture" from MindShare.
You
should configure and enable dev0, bar0 for external PCI devices to
access the SDRAM, e.g. base addr 0.
The CPU accesses the PCI slave via PCI_Bus_Access base address - defined in
the PCI toolbench (Avalon Configuration tab). They are divided into
Configuration, I/O, Memory space 1 and 2, each of 1Mbytes.
#define pcicfg_space (na_pci_compiler_0_PCI_Bus_Access) // Avalon space
#define pciio (pcicfg_space+0x100000) // PCI I/O device base in Avalon space
#define pcimm (pcicfg_space+0x200000) // PCI mem device base in Avalon space
// idsel of ad11=dev0,ad12=dev1 , using type 0 config request
#define pcicfg(dev,fun,reg) (pcicfg_space | ((dev)<<11) | ((fun)<<8) | (reg)) // configuration space
You must assign the address translation table in the Altera PCI core toolbench
(Avalon configuration tab). We use the same address mapping (to/from PCI) so that the PCI auto config code can work. After you add the PCI bridge component, find out the PCI bus access address assignment in SOPC Builder. Next, edit the PCI bridge component again. Remember to "uncache" the access.
eg, PCI bridge Avalon base is 0x02000000, uncache -> 0x82000000,
row 0, PCI config space, PCI base 0, avalon 0x82000000
row 1, PCI io space, PCI base 0x82100000, avalon 0x82100000
row 2, PCI mem space, PCI base 0x82200000, avalon 0x82200000
row 3, unused
Wire Connection Lists(note: the suffix of the PCI pin names are omitted and the Nios II CPU with PCI core is just called "cpu"):
Connect the IDSEL with resistive couple. CPU's DRAM will be device0.
1. ad[11] -- 330R -- IDSEL of CPU (or it can be internal connected in the CPU)
2. ad[12] -- 330R -- IDSEL of PCI device 1
3. ad[13] -- 330R -- IDSEL of PCI device 2
Connect the IRQ lines:
1. the inta of CPU, no connect
2. each int of PCI devices connect to a irqn input
Connect the req/gnt pairs from each PCI devices to CPU
PCI clock should match length.
Other signals are bussed.
Add pull-up to all signals, except for AD.
PAR needs pull-down.
Attached is the sample PTF and Verilog design file for a Cyclone II.
dev0 is sdram,
dev1 is your pci device1, using irqn_0 to irqn_3 for inta..intd
dev2 is your pci device2, using irqn_4 to irqn_7 for inta..intd
(update the number of irqn in the example design to 8)
PCI DriverThe PCI driver is in the attached altpci.zip, which is included in uClinux-dist already.
You have to update arch/nios2nommu/drivers/pci/altpci.c to fix PCI slot and IRQ mappings for your board. Search for "FIX ME".
In kernel config,
Processor type and features -->
--- Platform drivers Options
[*] Altera PCI host bridge
Note, you cannot use NDIS wrapper because the code are x86 objects and cannot run on a Nios II.
Some Altera Nios dev boards have 32 bits PMC connectors, and you can use them with adaptors.
What is PMC? (with schematic drawings)
A PCI to PMC adaptor