En el marco PCI original ("PCI convencional") y también en PCI-X, los dispositivos correspondían a "ranuras", cada una con sus propios conectores conectados al mismo bus paralelo. Cada ranura tenía un pin de identificación único que se afirmó durante la enumeración. La enumeración esencialmente preguntaba (para cada espacio): "Oye, ¿hay algo presente en este espacio?" El dispositivo respondió conduciendo datos al bus en respuesta a esta señal. La falta de respuesta no significaba ningún dispositivo.
Un dispositivo también podría ser un "puente", lo que significaba que formaba un bus subordinado. Ese bus tendría una ID separada (asignada desde el flujo ascendente) y tendría su propio conjunto de ranuras que se enumeraron de forma independiente.
PCI-Express (PCIe) es totalmente diferente. PCIe no es realmente un bus, como en un recurso compartido entre dispositivos; en cambio, cada dispositivo tiene su propia conexión en serie punto a punto individual a su dispositivo ascendente (y a cualquier dispositivo descendente, y si tiene dispositivos descendentes, eso significa que también funciona como un puente). Piense en PCIe como una LAN. Cada puente es análogo a un conmutador, que tiene un montón de puertos conectados a otros dispositivos. Los otros dispositivos pueden ser dispositivos terminales, o pueden ser otros conmutadores (es decir, puentes PCIe).
PCIe fue diseñado de tal manera que su marco conceptual y direccionamiento (y, por lo tanto, el comportamiento proporcionado al software) es compatible con PCI y PCI-X. Sin embargo, la implementación es completamente diferente. En la enumeración de dispositivos, por ejemplo, dado que es punto a punto, la única pregunta que debe determinarse en cada punto de la enumeración es "¿hay algo allí?" Dado que cada dispositivo tiene su propio conjunto independiente de cables, las ID de los dispositivos están esencialmente codificadas (por lo tanto, cada puente, incluido el "complejo raíz" de nivel superior, le dice a cada dispositivo cuál será su ID de dispositivo).
En todos los casos, la parte de "función" del bus / dispositivo / función se maneja estrictamente dentro del periférico. Por ejemplo, un controlador NIC de doble puerto a menudo tendrá dos funciones, una para cada puerto. Se pueden configurar y operar de forma independiente, pero la ruta de datos desde la CPU a la función es la misma para ambos.