Im ursprünglichen PCI-Framework ("konventionelle PCI") und auch in PCI-X entsprachen Geräte "Steckplätzen", von denen jeder seine eigenen Anschlüsse an denselben parallelen Bus angeschlossen hatte. Jeder Steckplatz hatte einen eindeutigen ID-Pin, der während der Aufzählung bestätigt wurde. Die Aufzählung fragte im Wesentlichen (für jeden Slot): "Hey, ist in diesem Slot etwas vorhanden?" Das Gerät reagierte, indem es als Reaktion auf dieses Signal Daten auf den Bus fuhr. Mangelnde Reaktion bedeutete kein Gerät.
Ein Gerät könnte auch eine "Brücke" sein, was bedeutet, dass es einen untergeordneten Bus bildet. Dieser Bus hätte eine separate ID (vom Upstream zugewiesen) und einen eigenen Satz von Steckplätzen, die unabhängig voneinander aufgelistet wurden.
PCI-Express (PCIe) ist völlig anders. PCIe ist nicht wirklich ein Bus - wie bei einer Ressource, die von Geräten gemeinsam genutzt wird. Stattdessen verfügt jedes Gerät über eine eigene serielle Punkt-zu-Punkt-Verbindung zu seinem Upstream-Gerät (und zu allen Downstream-Geräten - und wenn es Downstream-Geräte hat, bedeutet dies, dass es auch als Brücke fungiert). Stellen Sie sich PCIe wie ein LAN vor. Jede Bridge ist analog zu einem Switch, an dem mehrere Ports mit anderen Geräten verbunden sind. Die anderen Geräte können Endgeräte oder andere Switches (dh PCIe-Bridges) sein.
PCIe wurde so konzipiert, dass sein konzeptioneller Rahmen und seine Adressierung (und damit das Verhalten der Software) mit PCI und PCI-X kompatibel sind. Die Implementierung ist jedoch völlig anders. Zum Beispiel bei der Aufzählung von Geräten, da es Punkt-zu-Punkt ist, ist die einzige Frage, die an jedem Punkt in der Aufzählung bestimmt werden muss, "irgendetwas da?" Da jedes Gerät über einen eigenen unabhängigen Kabelsatz verfügt, sind die Geräte-IDs im Wesentlichen alle fest codiert (daher teilt jede Brücke, einschließlich des "Root-Komplexes" der obersten Ebene, jedem Gerät mit, wie seine Geräte-ID lautet).
In allen Fällen wird der "Funktionsteil" des Busses / Geräts / der Funktion streng innerhalb des Peripheriegeräts behandelt. Beispielsweise hat ein NIC-Controller mit zwei Ports häufig zwei Funktionen, eine für jeden Port. Sie können unabhängig voneinander konfiguriert und betrieben werden, aber der Datenpfad von der CPU zur Funktion ist für beide gleich.