Développement du «firmware» le plus simple pour les FPGA installés dans Redd, et débogage en utilisant le test de mémoire comme exemple

D'une certaine manière, je ne peux pas exprimer brièvement mes pensées. L'automne dernier, il y avait un désir de parler plus en détail de l'architecture PSoC que je maîtrisais, ce qui a donné lieu à une série d'articles à ce sujet. Maintenant, je participe à la préparation du matériel pour notre complexe de débogage à distance Redd, qui a été décrit ici , et je veux jeter l'expérience accumulée sous forme de texte. Je ne suis pas encore sûr, mais il me semble que ce n'est pas encore un article, mais un cycle. Premièrement, c'est ainsi que je vais documenter les méthodes de développement développées qui peuvent être utiles à quelqu'un à la fois lorsqu'il travaille avec le complexe et en général, et deuxièmement, le concept est encore nouveau, pas tout à fait établi. Peut-être, au cours de la discussion des articles, certains commentaires apparaîtront, dont on peut tirer quelque chose pour l'étendre (ou même le modifier). Par conséquent, nous procédons.



Introduction longue


Je n'aime pas vraiment théoriser, préférant présenter des choses pratiques à la fois. Mais au début du premier article, sans une longue introduction nulle part. J'y justifie l'approche actuelle du développement. Et tout tourne autour d'une chose: l'heure-homme est une ressource très coûteuse. Et la question n'est pas seulement dans les termes attribués au projet. Il est physiquement cher. S'il est dépensé pour le développement du produit final, eh bien, que pouvez-vous faire sans lui nulle part. Mais quand il est consacré à des travaux auxiliaires, cela, à mon avis, est mauvais. Je me souviens que j'avais eu un différend avec un développeur qui avait dit qu'ayant fait des prototypes par lui-même, il économiserait de l'argent pour son entreprise natale. J'ai fait valoir qu'il passerait environ 3 jours sur la fabrication. C'est 24 heures-homme. Nous prenons son salaire pour ces heures, ajoutons la taxe sociale que "l'employeur paie", ainsi que la location du bureau pour ces heures. Et nous sommes surpris de voir qu'en commandant des planches sur le côté, vous pouvez obtenir des coûts inférieurs. Mais c'est moi, j'exagère. En général, si les coûts de main-d'œuvre peuvent être évités, ils doivent être évités.

Quel est le développement du «firmware» pour le complexe Redd? Il s'agit d'un travail auxiliaire. Le projet principal vivra heureux pour toujours; il doit être réalisé le plus efficacement possible, avec une excellente optimisation, etc. Mais consacrer du temps et de l'énergie à des choses auxiliaires qui iront aux archives après le développement est un gaspillage. C'est sur ce principe que le développement des équipements Redd a été réalisé. Toutes les fonctions, si possible, sont implémentées comme des choses standard. Les bus SPI, I2C et UART sont implémentés sur des microcircuits FTDI standard et sont programmés via des pilotes standard, sans fioritures. La gestion des bobines est implémentée au format d'un port COM virtuel. Il peut être modifié, mais au moins tout a été fait pour qu'un tel désir ne se manifeste pas. En général, tout ce qui est standard, si possible, est implémenté de manière standard. De projet en projet, les développeurs ont simplement besoin d'écrire rapidement du code typique pour que le PC accède à ces bus. La technique de développement en C ++ devrait être évidente pour ceux qui développent des programmes pour microcontrôleurs (nous parlerons de quelques détails techniques dans un autre article).

Mais FPGA est seul dans le complexe. Il est ajouté au système pour les cas où il est nécessaire de mettre en œuvre des protocoles non standard avec une exigence de performance élevée. Si ceux-ci sont nécessaires, vous devrez faire le «firmware» pour cela. Cela concerne la programmation FPGA et je veux parler spécifiquement, juste dans le même but - pour réduire le temps de développement des choses auxiliaires.

Afin de ne pas dérouter le lecteur, je formulerai la pensée dans un cadre:
Il n'est pas nécessaire de réaliser le développement des FPGA dans chaque projet. S'il y a suffisamment de contrôleurs de bus connectés directement au processeur central pour fonctionner avec le périphérique cible, vous devez les utiliser.
FPGA a ajouté au complexe pour la mise en œuvre de protocoles non standard.


Schéma fonctionnel du complexe


Regardons le schéma de principe du complexe



Au bas du circuit se trouve une «calculatrice». En fait, c'est un PC standard avec Linux. Les développeurs peuvent écrire des programmes réguliers en C, C ++, Python, etc., qui seront exécutés par l'ordinateur. Dans la partie supérieure droite se trouvent les ports standard des pneus standard. Sur la gauche se trouve un commutateur pour les appareils standard (Flash SPI, carte SD et plusieurs relais statiques à faible courant, qui peuvent, par exemple, simuler des pressions de bouton). Et au centre se trouve précisément cette partie, dont le travail devrait être envisagé dans cette série d'articles. Son cœur est un FPGA de classe FPGA, à partir duquel des lignes droites sortent (peuvent être utilisées comme paires différentielles ou lignes ordinaires sans tampon), des lignes GPIO avec un niveau logique configurable, ainsi qu'un bus USB 2.0 implémenté via une puce ULPI.

Poursuite de l'introduction sur l'approche de programmation FPGA


Lors du développement d'une logique de contrôle hautes performances pour les FPGA, généralement Sa Majesté est joué le premier violon par une machine d'état. C'est sur les machines qu'il est possible d'implémenter une logique rapide mais complexe. Mais d'un autre côté, un automate se développe plus lentement qu'un programme pour un processeur, et sa modification est un autre processus. Il existe des systèmes qui simplifient le développement et la maintenance des machines. L'un d'eux a même été développé par notre entreprise, mais le processus de conception de tout type de logique complexe n'est pas rapide. Lorsque le système développé est le produit final, il est logique de préparer, de concevoir une bonne machine de contrôle et de consacrer du temps à sa mise en œuvre. Mais comme déjà indiqué, le développement de Redd est un travail auxiliaire. Il est conçu pour faciliter le processus, pas pour le compliquer. Par conséquent, il a été décidé que le développement ne serait pas automatique, mais des systèmes de processeur.

Mais d'un autre côté, lors du développement du matériel, l'option la plus en vogue à ce jour, le FPGA avec noyau ARM, a été rejetée. Tout d'abord, pour des raisons de prix. Une carte prototype basée sur SoC Cyclone V est modérément chère, mais curieusement, un FPGA séparé est beaucoup plus cher. Très probablement, le prix des cartes de prototypage est sous-évalué afin d'inciter les développeurs à utiliser les données FPGA, et les cartes sont vendues individuellement. La série devra prendre des jetons individuels. Mais en plus, il y a aussi une "seconde". Deuxièmement, lorsque j'expérimentais avec Cyclone V SoC, il s'est avéré que ce système de processeur n'est pas le cas et est productif en ce qui concerne l'accès unique aux ports. Lot - oui, le travail est rapide. Et dans le cas des accès uniques à une fréquence d'horloge du cœur du processeur de 925 MHz, vous pouvez accéder aux ports à une fréquence de quelques mégahertz. À tout le monde, je propose d'appeler la fonction standard de saisie de données dans le FIFO du bloc UART, qui vérifie le débordement de la file d'attente, mais en l'appelant lorsque la file d'attente est évidemment vide, c'est-à-dire que rien n'interfère avec les opérations. Ma productivité est passée d'un million à cinq cent mille appels par seconde (bien sûr, travailler avec la mémoire est allé à vitesse normale, tous les caches ont été réglés, même la variante de fonction qui n'a pas vérifié FIFO pour le débordement a fonctionné plus rapidement, seule la fonction en discussion a abondamment mélangé écrire et lire à partir des ports). C'est FIFO! En fait, FIFO a été inventé pour y déposer des données et oublier! Quittez vite! Et pas avec des performances, moins d'une méga-opération par seconde à une fréquence processeur de 925 MHz ...

La latence est à blâmer. Entre le cœur du processeur et l'équipement se trouve à partir de trois ponts ou plus. De plus, la vitesse d'accès aux ports dépend du contexte (plusieurs enregistrements consécutifs iront rapidement, mais la première lecture arrêtera le processus jusqu'à ce que les données mises en cache soient complètement déchargées, trop d'enregistrements consécutifs ralentiront également, car les tampons d'écriture sont épuisés). Enfin, l'examen des traces accumulées dans le tampon de débogage a montré que l'architecture Cortex A peut exécuter la même partie pour un nombre différent de cycles d'horloge en raison du système de cache complexe. En somme, en considérant tous ces facteurs (prix, baisse des performances lors du travail avec les équipements, instabilité de la vitesse d'accès aux équipements, dépendance générale au contexte), il a été décidé de ne pas mettre une telle puce dans le complexe.

Les expériences avec le PSoC de Cypress ont montré que le noyau Cortex M donne des résultats plus prévisibles et reproductibles, mais la capacité logique et la fréquence de fonctionnement maximale de ces contrôleurs ne correspondaient pas aux spécifications techniques, ils ont donc également été jetés.

Il a été décidé d'installer un FPGA Cyclone IV typique peu coûteux et de recommander l'utilisation d'un cœur de processeur NIOS II synthétisé. Eh bien, et si nécessaire - pour effectuer le développement en utilisant d'autres méthodes (machines automatiques, logique dure, etc.).

Je mentionnerai séparément (et même soulignerai ce paragraphe) que le processeur principal du complexe est x86 (x64). C'est lui qui est le processeur central du système. C'est sur lui que s'exécute la logique principale du complexe. Le système de processeur, qui sera discuté ci-dessous, est conçu pour fournir simplement la logique du fonctionnement de l'équipement "flashé" dans le FPGA. De plus, cet équipement n'est vendu que si les développeurs n'ont pas suffisamment de modules à temps plein connectés directement au processeur central.


Le processus de développement et de débogage du "firmware"


Si le complexe Redd exécute Linux, cela ne signifie pas que le développement doit être effectué dans ce système d'exploitation. Redd est un exécuteur distant, et le développement doit être effectué sur votre ordinateur, quel que soit le système d'exploitation. Celui qui a Linux est d'autant plus facile, mais qui est habitué à Windows (j'aimais beaucoup WIN 3.1, mais j'ai été forcé de travailler, mais quelque part au moment de WIN95 OSR2, je m'y suis habitué, et maintenant il est inutile de le gérer, il est plus facile d'accepter) , ceux-ci peuvent continuer à en diriger le développement.

Étant donné que mon amitié avec Linux n'a pas fonctionné, je ne donnerai pas d'instructions étape par étape pour configurer l'environnement sous celui-ci, mais je me limiterai à des mots généraux. Qui travaille avec ce système d'exploitation sera suffisant pour cela, et pour le reste ... Croyez-moi, il est plus facile de contacter les administrateurs système. Au final, c'est exactement ce que j'ai fait. Mais néanmoins.

Vous devez télécharger et installer Quartus Prime Programmer et Tools de la même version que votre environnement de développement. Si les versions ne correspondent pas, il peut y avoir des surprises. J'ai passé toute la soirée à comprendre ce fait. Par conséquent, téléchargez simplement l'outil de la même version que l'environnement de développement.

Après l'installation, entrez le répertoire dans lequel le programme a été installé, le sous-répertoire bin. En général, le fichier le plus important doit être jtagconfig. Si vous l'exécutez sans arguments (au fait, j'ai constamment demandé à entrer ./jtagconfig et seulement ainsi), alors une liste des programmeurs disponibles dans le système et des FPGA connectés à eux sera affichée. Il devrait y avoir un USB Blaster. Et le premier problème que le système lance n'est pas assez de droits d'accès pour fonctionner avec USB. Comment le résoudre sans recourir à sudo est décrit ici: radiotech.kz/threads/nastrojka-altera-usb-blaster-v-ubuntu-16-04.1244

Mais voici une liste des appareils affichés. Vous devez maintenant écrire:
./jtagconfig --enableremote <password> 

après quoi le serveur est lancé, accessible de n'importe où sur le réseau.

Tout irait bien, mais le pare-feu du système ne permettra à personne de voir ce serveur. Une vérification sur Google a montré que pour chaque type de Linux (dont il y en a beaucoup), les ports du pare-feu s'ouvrent à leur manière, et autant de sorts doivent être lancés que je préfère contacter les administrateurs.
Il convient également de considérer que si jtagd n'était pas enregistré en exécution automatique, alors lorsque vous ouvrirez l'accès à distance, vous serez informé qu'il est impossible de définir un mot de passe. Pour éviter que cela ne se produise, jtagd doit être démarré non pas au moyen de jtagconfig lui-même, mais avant lui.

En général, le chamanisme est sur le chamanisme. Permettez-moi de corriger la thèse:
  • le port entrant 1309 doit être ouvert dans le système. Quel protocole, je n'ai pas bien compris, pour plus de fiabilité, vous pouvez ouvrir à la fois tcp et udp;
  • lors du démarrage de jtagconfig sans argument, l'USB Blaster et le FPGA connecté doivent être affichés, et non un message d'erreur;
  • Avant d'ouvrir un travail à distance, jtagd avec des droits suffisants doit être en cours d'exécution. Si jtagd avec des droits insuffisants a déjà été lancé, son processus doit être terminé avant un nouveau démarrage, sinon un nouveau démarrage n'aura pas lieu;
  • en fait, l'accès à distance est ouvert avec la ligne
     jtagconfig --enableremote <password> 

Il existe bien sûr un chemin similaire qui passe par l'interface graphique, mais il est plus logique de tout faire en batch. Par conséquent, j'ai décrit une version batch. Lorsque toutes ces thèses sont terminées (et que les administrateurs système les ont terminées), nous lançons le programmateur sur notre machine, nous voyons un message sur le manque d'équipement. Cliquez sur Configuration matérielle:


Accédez à l'onglet Paramètres JTAG et cliquez sur Ajouter un serveur:


Nous entrons l'adresse réseau de Redd (pour moi c'est 192.168.1.100) et le mot de passe:


Nous nous assurons que la connexion a réussi.

J'ai passé trois vacances en mai pour y parvenir, puis les administrateurs ont tout décidé.


Basculez vers l'onglet Paramètres du matériel, ouvrez la liste déroulante et sélectionnez le programmeur à distance:


Tout, maintenant il peut être utilisé. Le bouton Démarrer est déverrouillé.


Le premier "firmware"


Eh bien. Pour que l'article ait une réelle valeur pratique, analysons le «firmware» le plus simple réalisé à l'aide des méthodes ci-dessus. La chose la plus simple que j'ai vraiment réussi à implémenter pour le complexe est un test de la puce SDRAM. Ici sur cet exemple et pratique.

Il existe un certain nombre de cœurs amateurs pour prendre en charge la SDRAM, mais ils fonctionnent tous de manière délicate. Et rendre compte de toutes les astuces est le travail. Nous allons essayer d'utiliser des solutions prêtes à l'emploi qui peuvent être insérées dans le système informatique NIOS II, nous allons donc utiliser le noyau de contrôleur SDRAM standard. Le cœur lui-même est décrit dans le document Embedded Peripherals IP User Guide , et beaucoup d'espace dans la description est consacré au décalage d'horloge pour la SDRAM par rapport à l'horloge du cœur. Des calculs théoriques complexes et des formules sont donnés, mais ce qu'il faut faire n'est pas particulièrement rapporté. Que faire peut être trouvé dans le document Utilisation de la SDRAM sur la carte DE0 d'Altera avec Verilog Designs . Au cours de l'analyse, j'appliquerai les connaissances de ce document.

Je développerai la version gratuite de Quartus Prime 17.0. Je me concentre sur cela, car lors de l'assemblage, ils me disent qu'à l'avenir, le noyau du contrôleur SDRAM sera expulsé de la version gratuite. Si cela s'est déjà produit dans votre environnement de développement, personne ne se soucie de télécharger la 17e version gratuite et de l'installer sur une machine virtuelle. Le travail principal se fait où que vous soyez, et le firmware pour Redd avec SDRAM est dans la 17e version. Eh bien, c'est si vous utilisez les options gratuites. Personne n'a encore menacé de le jeter de ceux payés. Mais j'étais distrait. Créez un nouveau projet:


Appelons-le SDRAM_DEMO. Le nom doit être rappelé: je vais effectuer un développement ultra-rapide, donc le système de processeur lui-même devrait être au niveau supérieur, sans aucune couche Verilog. Et pour que cela se produise, le nom du système de processeur doit correspondre au nom du projet. Alors souviens-toi.


En accord avec les valeurs par défaut en quelques étapes, nous arrivons au choix d'un cristal. Nous sélectionnons l'EP4CE10E22C7 utilisé dans le complexe.


Dans l'étape suivante, par habitude, je choisis la modélisation dans ModelSim-Altera. Aujourd'hui, nous ne modéliserons rien, mais tout peut être utile. Il vaut mieux développer une telle habitude et la suivre:


Le projet est créé. Passez immédiatement à la création du système de processeur (Tools-> Platform Designer):


Nous avons créé un système contenant une horloge et un module de réinitialisation:


Mais comme je l'ai déjà mentionné, une synchronisation spéciale est requise pour le noyau SDRAM. Par conséquent, le module standard est jeté sans pitié


Et à la place, ajoutez le bloc University Program-> System et SDRAM Clock for DE-series boards:


Dans les propriétés, sélectionnez DE0-Nano, car l'inspiration pour le circuit de commutation SDRAM a été tirée de cette planche à pain:


Nous commençons à bourrer notre système de processeur. Bien sûr, la première chose à ajouter est le cœur du processeur lui-même. Que ce soit Processeur et périphériques-> Processeurs intégrés-> Processeur NIOS II.


Pour lui, nous ne remplissons pas encore de propriétés. Cliquez simplement sur Terminer, même si nous avons formé une série de messages d'erreur. Jusqu'à présent, aucun équipement ne permet d'éliminer ces erreurs.

Ajoutez maintenant la SDRAM réelle. Interfaces et contrôleurs de mémoire-> SDRAM-> Contrôleur SDRAM.


Ici, nous devons nous accrocher au remplissage des propriétés. Sélectionnez le microcircuit le plus proche dans l'organisation similaire dans la liste et cliquez sur Apppy. Ses propriétés tombent dans les champs Memory Profile:


Maintenant, nous modifions la largeur du bus de données à 16, le nombre de lignes d'adresse à 13 et les colonnes à 9.


Je ne corrige pas encore l'heure, peut-être qu'à l'avenir, cette recommandation sera modifiée.
Le système processeur implique un programme. Le programme doit être stocké quelque part. Nous allons tester la puce SDRAM. Pour le moment, nous ne pouvons pas lui faire confiance. Par conséquent, pour stocker le programme, ajoutez de la mémoire basée sur le bloc RAM FPGA. Fonctions de base -> Mémoire sur puce -> Mémoire sur puce (RAM ou ROM):


Volume ... Eh bien, que ce soit 32 kilo-octets.


Cette mémoire doit être chargée quelque part. Pour cela, cochez la case Activer le fichier d'initialisation non par défaut et entrez un nom de fichier significatif. Disons firmware.hex:


L'article est déjà compliqué, nous ne le surchargerons donc pas. Nous afficherons simplement le résultat physique du test sous la forme de lignes PASS / FAIL (et nous verrons le résultat logique avec mon débogage JTAG préféré). Pour ce faire, ajoutez le port GPIO. Processeurs et périphériques-> Périphériques-> PIO (Parallel IO):


Dans les propriétés que nous définissons 2 bits, j'aime aussi cocher la case pour le contrôle individuel des bits. Aussi juste une habitude.


Nous avons un tel système avec un tas d'erreurs:


Nous commençons à les éliminer. Pour commencer, nous allons casser l'horloge et réinitialiser. Au niveau de l'unité d'horloge et de réinitialisation, les entrées doivent être supprimées. Pour ce faire, il existe des champs qui disent "Double-cliquez pour exporter":


On clique, mais on donne des noms plus ou moins courts.


Vous devez également supprimer la sortie d'horloge SDRAM:


Nous séparons maintenant sys_clk à toutes les entrées d'horloge et reset_source à toutes les lignes de réinitialisation. Vous pouvez frapper doucement les points reliant les lignes correspondantes avec la «souris», ou vous pouvez aller à la sortie correspondante, appuyer sur le bouton droit de la souris, puis aller dans le sous-menu Connexions dans le menu déroulant et sélectionner les connexions là-bas.




Ensuite, nous connectons les pneus ensemble. Nous connectons Data Master à tous les bus de tous les appareils, et Inctruction Master - à presque tous. Il n'est pas nécessaire de le connecter au bus PIO_0. À partir de là, les instructions ne seront certainement pas lues.


Vous pouvez maintenant résoudre les conflits d'adresses. Pour ce faire, sélectionnez l'élément de menu Système-> Attribuer des adresses de base:


Et lorsque nous avons des adresses, nous pouvons également attribuer des vecteurs. Pour ce faire, accédez aux propriétés du cœur du processeur (pointez-le, appuyez sur le bouton droit de la souris et sélectionnez l'élément de menu Modifier) ​​et configurez-y les vecteurs sur la mémoire Onchip. Sélectionnez simplement ce type de mémoire dans les listes déroulantes, les numéros seront eux-mêmes substitués.


Il ne reste aucune erreur. Mais deux avertissements demeurent. J'ai oublié d'exporter les lignes SDRAM et PIO.


Comme nous l'avons déjà fait pour la réinitialisation et le bloc d'horloge, double-cliquez sur les jambes requises et donnez-leur les noms les plus courts (mais compréhensibles):


Tout, il n'y a plus d'erreurs ou d'avertissements. Enregistrez le système. De plus, le nom doit coïncider avec le nom du projet, afin que le système de processeur devienne un élément de niveau supérieur dans le projet. N'avez-vous pas oublié ce que nous l'appelions?




Eh bien, nous appuyons sur le bouton le plus important - générer du HDL.


Tout, la partie processeur est créée. Cliquez sur Terminer. On nous rappelle qu'il serait bien d'ajouter ce système de processeur au projet:


Ajouter:


Et là, en utilisant le bouton Ajouter, nous obtenons l'image suivante:


Le fichier SIP n'a pas encore été créé. Oui, et nous n'en avons pas besoin dans le cadre de cet article.

Uhhhh La première étape a été franchie. Nous rédigeons le projet afin que le système découvre la hiérarchie du projet et les étapes utilisées. Les erreurs de compilation ne sont pas effrayantes. Juste dans la version gratuite de l'environnement, des noyaux ont été créés qui ne fonctionnent que lorsque l'adaptateur JTAG est connecté. Mais dans le complexe Redd, il est toujours connecté, car il est divorcé sur un tableau commun, c'est-à-dire que nous n'avons rien à craindre. Nous ignorons donc ces erreurs.


Revenons maintenant à la description du noyau SDRAM. Il indique que la ligne CKE n'est pas utilisée et est toujours connectée à l'unité. En effet, dans le cadre du complexe, les jambes FPGA ne sont pas seulement chères, mais une ressource précieuse. Et il serait idiot d'écarter la jambe, qui est toujours dans l'unité (et sur la carte DE0-NANO elle n'est pas non plus divorcée). Il y aurait un calque Verilog, la chaîne correspondante pourrait y être coupée, mais je gagne du temps (rires nerveux, en regardant le volume du document déjà obtenu, mais sans le sauvegarder il se serait avéré encore plus). Par conséquent, il n'y a pas de couche. Comment être Accédez à l'éditeur d'affectation. Il y est, car dans Pin Planner, à en juger par les descriptions, il n'y a pas de fonctionnalité similaire.


Il n'y a toujours pas de ligne. Bon. Créez-en un nouveau


Nous sélectionnons l'icône suivante:


Dans le système de recherche que nous avons défini, cliquez sur Liste et dans les résultats de recherche, nous trouvons notre CKE:


Ajoutez-le à la colonne de droite, cliquez sur OK.


Nous obtenons la liste suivante:


Dans le champ jaune, cliquez sur la liste déroulante et recherchez Virtual Pin. Nous choisissons. Le jaune s'est déplacé vers une autre cellule:


Là, nous sélectionnons On:


Tout jaunissement a disparu. Et la chaîne est désormais marquée comme virtuelle, ce qui signifie qu'elle ne nécessite pas de jambe physique. Par conséquent, nous ne pouvons pas l'assigner à la conclusion physique du FPGA. Fermez l'éditeur d'affectation, ouvrez le planificateur de broches. Vous pouvez attribuer les jambes, en vous référant à la figure, ou vous pouvez prendre la liste du fichier * .qsf, qui fait partie du projet, que je joindrai à l'article.



Ça y est, fermez Pin Planner, nous réalisons la compilation finale du projet. Le matériel est prêt, nous procédons au développement du logiciel pour le système de processeur résultant. Mais l'article s'est avéré si énorme que nous le ferons la prochaine fois .

Source: https://habr.com/ru/post/fr452656/


All Articles