FpgaArchitecture

From ArmadeusWiki
Jump to: navigation, search

Spécifications de conception du FPGA

Evolutions

2006/12/29: MAJ de la partie 1.7 pour décrire plus en détail le programme d'assemblage des IP (Orchestra)

2006/12/21: MAJ en fonction des remarques de tout le monde.

But

Cette page a été créée pour permettre à tous les membres de l'association de discuter de l'architecture qui va être mise en place pour le FPGA présent sur la carte APF9328.

Cette espace doit être vu comme un espace d'échange d'idées. Tout le monde est convié à y participer. Il est préférable d'avoir quelques connaissances en électronique et sur les langages HDL (VHDL ou Verilog), mais ce n'est pas une obligation.

Bonne lecture et merci pour votre participation.


Les grandes lignes

Le FPGA de la carte APF9328 est là pour offrir le maximum de souplesse au projet Armadeus et permettre d'implanter des fonctionnalités coté matériel qui seraient trop pénalisantes ou impossibles à implanter coté logiciel. Bien entendu, pour que cela soit exploitable, il faut également disposer d'un lien entre le FPGA et le processeur i.MX.

Pour réaliser cela, il faut mettre en place un bus de communication entre le FPGA et l'i.MX. Ce bus de communication va permettre le pilotage des fonctionnalités qui seront implantées dans le FPGA. Bref, il faut recréer à l'intérieur du FPGA un bus tel qu'il existe entre l'i.MX et les différents composants de la carte (RAM, Flash, USB, Ethernet, etc.).

Pour gagner en temps de développement et pour pouvoir récupérer des fonctionnalités ou IP (Intellectual Property) déjà existantes, le bus Wishbone a été retenu. Ce bus, dont les spécification ont été placées dans le domaine public, a été conçu spécifiquement pour ce genre de configuration et sur le site www.opencores.com plusieurs IP compatibles avec les spécifications Wishbone sont disponibles.


Le bus Wishbone

Master description Slave
RST_I Reset generated by syscon RST_I
CLK_I Clock generated by syscon CLK_I
ADR_O (13 bits) Address bus ADR_I (=< 13bits)
DAT_I (16 bits) master <- slave data bus DAT_O (16 bits)
DAT_O (16 bits) master -> slave data bus DAT_I (16 bits)
WE_O Write/read signal WE_I
SEL_O (2 bits) Select low or high bytes on bus SEL_I (2 bits)
STB_O strobe or chip select signal STB_I
ACK_I Acknowledges (not supported by imx9328) ACK_O
CYC_O cycle read/write (not supported by imx9328) CYC_I

See Wishbone specification.

La spécification Wishbone décrit un certain nombre de composants de base:

  • Des interfaces maitres, ces interfaces sont implantés dans des composants qui seront alors capable d'initier les transferts sur le bus Wishbone
  • Des interfaces esclaves, ces interfaces sont implantés dans des composants capables de répondre à des demandes de transferts
  • Un composant syscon, ce composant va générer le signal d'horloge qui sera utilisé par tous les composants/interfaces du bus ainsi que le signal de RESET synchrone.
  • Un macro composant intercon, ce composant va gérer la connexion de toutes les interfaces maitres et esclaves qui composent le bus interne. Il prend en charge :
    • Le décodage/transcodage d'adresse (génération des signaux A0 à A3 selon le mode d'adressage 8/16/32/64 bits)
    • le routage du bus de données entre les différentes interfaces maitres et esclaves (conversion big endian/little endian, etc)
    • le routage/génération des signaux de contrôle du bus (Read, Write, Chip Select, Output Enable, ACK, etc.)
  • Un composant arbitre, ce composant va permettre de partager l'accès au bus ou à un composant de type esclave qui est partagé par plusieurs composants de type maitre.


Les spécifications du bus Wishbone permettent de créer différents types de bus:

  • Point to Point: C'est le type de bus le plus simple possible, un composant avec une interface type maitre connecté à un composant avec une interface de type esclave.
  • Data Flow: C'est un bus en cascade, à un bout on trouve un composant avec une interface de type maître et à l'autre bout un composant avec une interface de type esclave. Entre les deux composant se trouve une chaine d'un ou plusieurs composants avec une interface de type maitre et de type esclave.
  • Shared: C'est un bus sur lequel plusieurs composants sont connectés dessus. Tous les composants se partagent ce bus. Si plusieurs maitres sont connectés sur ce bus, un seul pourra initier un transfert à un instant donné.
  • CrossBar: C'est également un bus de type partagé, par contre dans se cas, on dispose de plusieurs bus. Chaque maitre utilise sont propre bus pour communiquer avec ces esclaves. On peut donc avoir plusieurs transferts en simultané. Le seul cas de blocage/arbitrage est le transfert de plusieurs maitre avec le même esclave.


Il existe également un certain nombre de mécanismes dans la spécification Wishbone pour permettre d'optimiser les temps de transferts sur le bus. Ces optimisations sont de plusieurs nature:

  • utilisation de signaux ACK, ERR et RTY pour signaler la fin de transfert
  • les Registered Feedback Bus Cycles, qui permettent de gagner un cycle d'horloge pour des transferts consécutifs
  • les transferts en mode Burst

Le lien i.MX <=> FPGA

Les timings suivants on été mesurés avec la version 2.2 d'Armadeus

READ
WRITE 16bits


La communication entre l'i.MX et le FPGA passe par les signaux suivants (à vérifier):

  • des signaux de contrôle: RW_n, OE_n, EB_n[3..2] et CS1_n
  • le bus de données sur 16 bits (D[15..0])
  • le bus d'adresses sur 12 bits (A[12..1])


Ces signaux sont alors utilisés pour créer une interface Wishbone maitre qui va permettre de communiquer efficacement avec les autres IPs contenus dans le FPGA qui implémenterons une interface wishbone de type esclave.

Etant donné les erratas du composant i.MX concernant le signal DTACK, il n'est pas possible d'implanter une interface Wishbone maitre classique. Ceci entraine les limitations suivantes:

  • Pas possible d'utiliser le signal ACK Wishbone pour terminer le transfert entre FPGA et i.MX.
  • Pas possible de mettre en place des optimisations du temps de transfert.


Pour contrer ce problème, il faudra s'assurer que toutes les interfaces esclaves qui seront connectées à l'interface maitre du composant Wishbone i.MX répondent dans un temps fixe donné.
Comme le bus Wishbone est un bus entièrement synchrone, le temps minimal d'un transfert est de 3 cycles de l'horloge Wishbone. Il faut ajouter à cela, un cycle pour la synchronisation des signaux du bus i.MX. Cela nous fait donc un minimum de 4 cycles Wishbone pour un transfert entre le FPGA et l'i.MX.

Etant donné les performances des FPGA actuels, on peut tabler sur une fréquence de fonctionnement d'au moins 100MHz pour le bus Wishbone. Cela nous donne donc un taux de transfert approximatif de 50 Moctets/sec (100MHz * 16bits / 4).

La composition du système Wishbone

FPGA Armadeus.png

Le système Wishbone qui sera implanté dans le FPGA se compose des éléments suivants:

  • i.MX Wrapper: L'interface i.MX vers le bus Wishbone
  • Syscon: Ce composant va gérer les signaux CLK (généré par une PLL ou directement issu de l'i.MX) et RESET (synchrone).
  • Intercon: Ce composant devra être généré automatiquement par une moulinette, il va faire le lien entre tous les composants faisant parti du Système Wishbone.
  • Gestionnaire d'interruption: Ce composant est un esclave wishbone et va centraliser toutes les demandes d'interruption et les remonter vers l'i.MX.
  • Esclaves whisbone: Ceci représentent tous les autres composants avec une interface wishbone esclave qui sont accessibles via le wrapper i.MX.


Sur le diagramme, il manque un certain nombre de choses:

  • Les signaux non wishbone en entrée ou en sortie sur les esclaves wishbone
  • Le macro composant système wishbone. Ce macro composant est celui qui sera ensuite instancié dans le design du FPGA. Sur ce composant ne seront visibles que les signaux externes au système:
    • Les signaux issus de l'i.MX
    • Le signal RESET (en entrée) qui sera synchronisé sur l'horloge système Le signal RESET synchrone du bus Wishbone sera directement généré par le composant syscon à l'aide d'une simple machine d'état.
    • Le signal CLK (en entrée) qui sera l'horloge utilisée pour la génération des signaux Wishbone
    • Le signal IRQ (en sortie) qui sera utilisé pour remonter les demandes d'interruption vers l'i.MX
    • Les signaux d'entrée et de sortie spécifiques aux autres composants connectés sur le bus Wishbone


L'intérêt de créer le composant Système Wishbone, est que cela simplifie la vision dans l'outil conception du FPGA. Il ne suffit plus alors qu'à relier les signaux sur les broches correspondantes du FPGA.


i.MX Wrapper

Ce composant est le point d'accès au bus Wishbone pour l'i.MX et sera le seul à disposer d'une interface Wishbone maitre.

Les fonctions de ce composants sont:

  • synchronisation des signaux issus de l'i.MX. Ceci est primordial pour assurer la stabilité de tout le système Wishbone. De plus, le bus de sortie étant asynchrone (l'horloge de génération des signaux n'est pas véhiculée), la resynchronisation des signaux par rapport à l'horloge du bus s'impose.
  • gestion du bus de données en 3 états.
  • conversion des signaux de contrôle du bus i.MX en signaux Wishbone.

Syscon

C'est le composant le plus simple du système , il ne fait que synchroniser le signal RESET en entrée avec le signal d'horloge du système.

Il va être en charge de la génération du signal RESET synchrone pour le bus Wishbone.

Le signal d'horloge en entrée du composant syscon sera celui utilisé pour le fonctionnement du bus Wishbone. La fréquence du signal d'horloge devra être assez élevée pour permettre le traitement des signaux issus de l'i.MX. Cela va dépendre de la configuration du chip select utilisé (CS1).

La source du signal d'horloge reste encore à définir, les choix possibles sont:

  • directement issu de l'i.MX
  • utilisation d'un DCM du Spartan 3

Le choix définitif dépendra principalement des essais grandeur nature lors de la génération des premiers systèmes whisbone durant la phase de mise en place des composants de base.

Intercon

Ce composant a la particularité qu'il sera créé automatiquement par un outil (script ou programme). Intercom a comme fonctionnalités:

  • Le décodage d'adresse pour la sélection des différents esclaves du système
  • Le routage des bus d'adresses et de données vers les différents esclaves
  • La génération des signaux de contrôle pour les différents esclaves.

Etant donné les limitations induites par les erratas de l'i.MX, le composant intercom remplira les fonctionnalités suivantes:

  • le bus de données est figé sur 16 bits
  • les cycles de lecture et d'écriture sont de longueur fixe (à priori 3 cycles d'horloge à valider lors des essais du système de base)
  • une interruption est générée en cas de dépassement du temps de cycle d'écriture ou de lecture
  • le bus sera de type shared avec un seul maitre (le Wrapper i.MX).

Gestionnaire d'interruption

Ce composant esclave est le premier qui sera créé spécifiquement pour le système. Il sera capable de:

  • prendre en compte jusqu'à 16 sources d'interruptions différentes (remark: why 16 ???)
  • réaliser l'acquittement de chaque interruption individuellement
  • masquer/autoriser chaque interruption individuellement


Le composant disposera des registres suivants:

  • isr_mask: registre d'autorisation des interruptions. Chaque bit correspond à une interruption (bit0 => IRQ0, bit1 => IRQ1, etc.). Ce registre sera accessible en lecture et en écriture. Par defaut, toutes les interruptions sont masquées. La valeur '0' masque l'interruption et la valeur '1' la valide.
  • isr_pend: ce registre est à double emploi
    • en lecture: Les interruptions en attente de traitement
    • en écriture: Acquittement des interruptions. Chaque bit à 1 va acquitter l'interruption correspondante.

Les composants esclaves

Suite aux divers discussions issues de ce chapitre. L'organisation et la présences des fichiers dans les répertoires doc et HAL n'est pas encore établie. Ce chapitre sera encore à retravailler.


Pour qu'une IP puisse être facilement inclue dans le système, il faut une certaine organisation. Sinon, à moyen ou à long terme cette IP est morte parce qu'elle sera difficilement exploitable et encore plus difficilement maintenable.

Ce sont des notions qui ne sont pas simples à prendre en considération lors du développement d'un nouveau projet, mais lorsque l'on doit se replonger dans un travail fait par quelqu'un d'autre ou un projet qu'on a laissé en sommeil pendant quelque temps, on est content d'avoir quelque chose à quoi se raccrocher.

Pour développer efficacement, il faut assurer une organisation logique, figée et compréhensible, et le plus simple dans ce genre de cas est de se baser sur la notion de répertoire. Voici les répertoires qui doivent être utilisés par une IP:

  • doc: Ce répertoire va contenir toute la documentation nécessaire à l'exploitation de l'IP. On y trouvera une notice (readme.txt), un fichier de suivi de modification (ChangeLog.txt), un fichier contenant les évolutions futures prévues (todo.txt) ainsi que tout autre fichier estimé utile par le(s) créateur(s) de l'IP.
  • hdl: Ce répertoire va contenir tous les fichiers VHDL (ou Verilog) qui auront été développés spécifiquement pour cette IP.
  • inc: Ce répertoire va contenir un fichier d'en-tête ANSI C contenant l'adresse de tous les registres interne de l'IP pour permettre de créer simplement un programme en langage C permettant de contrôler l'IP. Ce répertoire est optionnel et ne s'applique évidement qu'à des IPs ayant une interface de type Wishbone.
  • HAL: Ce répertoire va contenir des drivers ou des exemples de logiciels de base permettant l'utilisation de l'IP par un microprocesseur/contrôleur. Avec un sous-répertoire pour chaque système (linux, ulinux, ecos, avr, ...) Ce répertoire est optionnel et ne s'applique évidement qu'à des IPs ayant une interface de type Wishbone.


Le script / programme d'assemblage des IP

Nous allons maintenant parler du coeur du système, du moins de la partie la plus visible de l'iceberg ;-)

La première des priorités, sera de trouver un nom pour cet outil qui reste un peu dans l'esprit du projet. Voici quelques propositions, à vous de compléter ou de voter pour un nom ou plusieurs noms:

  • Concerto
  • Orchestra

D'après les derniers sondage, Orchestra serait finalement le nom retenu pour ce logiciel.


Principe et fonctionnement

Afin de de rendre tout ce système utilisable par le plus grand nombre, il faut être capable de proposer des outils qui vont simplifier la vie de l'utilisateur final ainsi que de l'intégrateur.

Pour cela, il faudra créer un outil soit sous forme de script(s), soit sous forme de programme(s) qui va permettre de réaliser les tâches suivantes:

  • Création/gestion d'une bibliothèque de composants Armadeus Ready
  • Gestion d'une liste de hardware Armadeus
  • Edition d'un système Armadeus
  • Gestion d'un projet
  • Génération automatique du composant system qui sera implanté dans le FPGA
  • Génération automatique d'un banc de tests pour permettre la validation par ModelSim (ou autre logiciel de simulation HDL)
  • Génération d'un fichier mapping mémoire


La bibliothèque de composants

Pour qu'un composant, c'est-à-dire une IP, soit exploitable par le système, il faut passer par une phase d'intégration qui va permettre de décrire ce composant:

  • Nom de l'IP
  • Description
  • Version
  • Identification des fichiers HDL utilisés (VHDL ou Verilog)
  • Identification du fichier Top (le point d'entrée de l'IP)
  • Identification des paramètres GENERIC (dans le cas d'une IP en VHDL):
    • Type de paramètre (entier, std_logic, etc)
    • Valeur par défaut
    • Valeurs ou plages de valeurs autorisées
    • Description du paramètre
  • Identification des signaux Wishbone utilisés par le composant
  • Identification du type (maitre ou esclave) et du nombre d'interfaces Wishbone utilisés par ce composant
  • Identification des registres internes
    • Adresse (Offset par rapport à l'adresse de base)
    • Taille (8 ou 16 bits)
    • Nom et/ou description


Toutes ces informations seront alors sauvegardées dans un fichier, de préférence dans un format compréhensible et lisible à l'aide de n'importe quel éditeur de texte (XML, fichier INI ou fichier plat).


Chaque composant identifié par le logiciel se trouvera dans un sous-répertoire (ou dans un fichier archive ?!?) placé dans le répertoire Armadeus Components, chaque sous-répertoire (ou archive) de composant contiendra les données suivantes:

  • Le fichier de description du composant Armadeus Ready
  • un répertoire HDL avec les fichiers VHDL/Verilog de l'IP
  • un répertoire HAL avec les fichiers d'un drivers de base (pour Linux ou générique ?!?)


Le gestionnaire de composants Armadeus doit être capable de réaliser les opérations suivantes:

  • Importer un composant ou une liste de composants
  • Exporter un composant ou une liste de composants
  • Gérer des versions de composants (à voir si cette fonctionnalité est importante/utile)
  • Permettre l'ajout/création de composants
  • Permettre de supprimer un composant


Gestionnaire de plateformes

Il faut avoir confiance dans l'avenir, pour l'instant nous ne disposons que d'une seul plateforme de travail, mais ce n'est qu'un début et très certainement d'autres cartes à base de l'i.MX et d'un FPGA vont voir le jour.

Il faut donc prévoir d'ores et déjà cette possibilité et proposer un outil qui va permettre de définir une plateforme. Chaque descripteur de plateforme devra fournir les informations suivantes:

  • Type de FPGA
  • Emplacement (niveau FPGA, c'est-à-dire la broche utilisée), type (sortie i.MX, oscillateur ou quartz) et fréquence (ou plage de fréquence ?!?) des horloges
  • Emplacements/broche du FPGA utilisées ainsi que leur fonctionnalité (signal Wishbone, comme d'un composant externe, signal d'interruption, etc.)


Toutes ces informations seront utilisées par la suite lors de la création d'un projet Orchestra/Armadeus.


Gestionnaire de projet

Le rôle du gestionnaire de projet est de permettre de créer, reprendre ou modifier le plus simplement possible une configuration du FPGA pour une carte donnée. Cette configuration sera appelée par la suite un système.


Tout système est entièrement décrit par un fichier projet qui contiendra les éléments suivants:

  • Le nom du système (éventuellement le même que le nom du projet ?!?)
  • Une description du système
  • Le type de plateforme utilisé pour ce système
  • La source de la fréquence d'horloge du bus Wishbone (broche du FPGA ou DLL/DCM). On pourra éventuellement imaginer la création d'un Wizard pour simplifier la configuration du DCM.
  • La liste de tous les composants Armadeus Ready inclus dans le système, avec pour chacun de ces composants, les détails suivantes:
    • La référence du composant (par rapport à la bibliothèque de composants Armadeus Ready)
    • Le nom de l'instance du composant (e.g. UART1, PWM_MOTOR, etc.)
    • La connexion des entrées/sorties (vers une broche du FPGA, non utilisé ou relié manuellement)
    • La valeur de chaque paramètre GENERIC du composant, par exemple l'adresse du base de chacune de ses interfaces esclaves connectées au bus Wishbone
    • L'horloge utilisée (pour l'instant ce sera toujours celle du bus Wishbone mais peut-être que plus tard ce ne sera plus forcément le cas ;-) )
    • Le numéro d'interruption attribué au composant, s'il est capable de généré une demande d'interruption


Comme pour le fichier de description d'un composant Armadeus, le fichier projet devra être dans un format texte compréhensible et lisible à l'aide de n'importe quel éditeur texte (XML, fichier INI ou fichier plat).


Le fichier projet est le coeur du système et, à partir de celui-ci ainsi que de la librairie de composants Armadeus Ready + la librairie de plateforme, toute la partie liée au FPGA doit pouvoir être recrée. Bref c'est le seul fichier dont l'utilisateur final aura à ce soucier (sauvegarde, archivage, etc).


Lors de la création d'un nouveau projet, l'utilisateur devra fournir les éléments de base suivants:

  • Le nom du système
  • Une description
  • Le type de plateforme utilisé
  • La source de l'horloge Wishbone (broche du FPGA ou DCM) avec éventuellement un wizard pour la saisie des informations relatives à la programmation du DCM.
  • La fréquence du bus Wishbone (éventuellement obtenue automatiquement à partir de la sélection de la source de l'horloge)
  • Le nombre de sources d'interruptions autorisées ainsi que l'emplacement en mémoire des registres du gestionnaire d'interruption (par défaut à l'adresse 0x0000).


Une fois que le projet aura été créé, les composants suivants seront ajouté automatiquement au système:

  • Un Wrapper i.MX pour faire le lien avec l'i.MX
  • Un syscon pour la générations des signaux CLK et RESET du bus Wishbone
  • Un Gestionnaire d'interruptions si le système doit être capable de remonter des demandes d'interruption.


Par la suite, l'utilisateur pourra modifier le système de base à l'aide des opérations suivantes:

  • choisir dans la librairie un composant pour l'ajouter au système
  • modifier les paramètres d'un composant du système
  • modifier les caractéristiques du projet (nom, fréquence du bus Wishbone, etc.)
  • supprimer un composant du système
  • attribution automatique des adresses de base sur le bus Wishbone
  • attribution automatique des numéros d'interruption
  • annulation des dernières modifications (éventuellement)
  • sauvegarde/restauration d'un fichier projet


Générateur de fichiers

C'est ici que va se trouver la partie la plus ardue du projet Orchestra, et c'est en fonction de ce que l'on sera capable de proposer à l'utilisateur final que se fera l'adhésion au projet ou non.

Une fois que l'on aura créer son projet/système Armadeus, il faut encore pouvoir générer au minimum le fichier bitstream qui va être utiliser pour configurer le FPGA.

C'est ici qu'entre en jeu le générateur de fichiers, qui devra être capable, à l'aide du fichier projet + la librairie de composant + la librairie de plateforme, de générer le fichiers suivants:

  • un fichier HDL Intercon reliant tous les composants placés dans le système qui a été créé par l'utilisateur
  • un fichier HDL system qui va englober tout le système Wishbone tel qu'il a été défini par l'utilisateur
  • un fichier HDL system_tb et un fichier .DO qui vont pouvoir être utilisés pour la simulation à partir de ModelSim
  • un fichier system.h qui va contenir le plan mémoire du système créé
  • un fichier tcl qui va permettre de créer entièrement et de manière automatique le projet dans l'environnement Xilinx ISE, c'est-à-dire:
    • sélection du bon FPGA
    • sélection du bon format de sortie (bitstream)
    • saisie du pinout du FPGA (nom de chaque broche par rapport au nom du signal sur le schéma)
    • programmation du DCM le cas échéant
    • définition des signaux d'horloge
    • inclusion des fichiers HDL nécessaires au projet
    • instanciation du fichier HDL sytem
    • connexion des entrées et sorties du composant system

(remark: an include file for the operating system has to be generated, so that the drivers know the base address of the hardware-modules)

Comme on peut le voir, le travail pour Orchestra ne manque pas, reste encore la question du mode de développement ainsi que du langage et la bibliothèque graphique.

Mais ceci est encore une autre histoire, qui pourra être débattu lorsque les premières composants système seront prêt à l'emploi... Peut-être très bientôt :-)

Gestionnaire d'interruption

Ce chapitre est donné à titre informatif/propositon et ne tiens pas lieu de spécification.

Afin de simplifier la vie des programmeurs systèmes, il faut pouvoir offrir un mécanisme simple de mise en place et de gestion des demandes d'interruption du FPGA.

Pour cela, je propose la solution suivante:

  • Mise en place d'un gestionnaire d'interruption générique pour le FPGA. Ce gestionnaire d'interruption sera capable de lire le registre d'interruption (lecture de isr_pend) et de déterminer les interruptions à traiter (via isr_mask). Il va en suite aiguiller l'exécution de la routine d'interruption vers les routines adéquates pour chaque bit d'interruption valide. L'interruption traitée sera alors acquitée (écriture vers isr_pend).
  • Création d'une routine d'enregistrement de vecteur d'interruption. Cette routine va permettre d'ajouter une routine de traitement d'interruption pour un bit d'interruption donné. Pour cela il faudra lui fournir les informations suivantes (via une structure ?!?):
    • Le numéro du bit d'interruption (0 à 31)
    • La routine de traitement d'interruption pour ce driver
    • Un paramètre additionnel à fournir à la routine de traitement d'interruption (pointeur de type void *)
    • Le nom du drivers (optionnel, permet d'identifier/visualiser les drivers installer éventuellement)
  • Création d'une routine de validation d'une interruption FPGA par son numéro (0 à 31)
  • Création d'une routine pour masquer une interruption FPGA par son numéro (0 à 31)
  • Création d'une routine pour désinstaller une interruption FPGA par son numéro (0 à 31)
  • Création d'une routine ou méthode pour visualiser tous les drivers Wishbone installés:
    • Leur numéro
    • Leur nom
    • Leur état (validé/masqué)
    • Le nombre de fois qu'ils ont été appelé
    • etc.