Articles précédents de la série
- Développement du "firmware" le plus simple pour FPGA, installé dans Redd, et débogage à l'aide de l'exemple d'un test de mémoire
- Développement du "firmware" le plus simple pour FPGA installé dans Redd. Partie 2. Code de programme
- DĂ©veloppement de votre propre cĆur pour intĂ©gration dans un systĂšme de processeur basĂ© sur FPGA
- Redd
- Redd
- ,
- Redd. 1:
- Redd. 2:
- :
- Redd, FTDI
- Redd
- Redd
- USB- Windows 10
- Nios II Nios II
- Redd. DMA Avalon-ST Avalon-MM
- Redd
- Redd â
- USB- Redd
Comment fonctionne un programme informatique ordinaire? Il existe un certain environnement externe (le moniteur et le clavier avec "souris" sont les reprĂ©sentants les plus typiques de cet environnement mĂȘme). Le programme interagit avec eux. Lors du dĂ©bogage, vous pouvez crĂ©er de vĂ©ritables influences Ă partir de l'environnement externe, ou vous pouvez les Ă©muler. Nos testeurs Ă©crivent souvent toutes sortes de scripts qui ne font qu'Ă©muler des influences externes. AprĂšs cela, les analyseurs de journaux sont lancĂ©s, qui vĂ©rifient que les rĂ©ponses sont correctes mercredi.
Et si tout Ă©tait boguĂ© dans ce programme informatique? Vous pouvez dĂ©finir des points d'arrĂȘt et examiner un instantanĂ© du systĂšme au moment oĂč ils frappent. Une tranche du systĂšme correspond aux valeurs des variables. Peut-ĂȘtre les Ă©tats de divers mutex et autres objets de synchronisation. En gĂ©nĂ©ral, un instantanĂ© des paramĂštres internes du systĂšme dĂ©boguĂ©.
Lors du dĂ©bogage des FPGA, vous pouvez faire la mĂȘme chose. Certes, si l'environnement est rĂ©el, alors s'arrĂȘter et Ă©tudier une partie du systĂšme est problĂ©matique, bien que possible. Dans le cadre de l'histoire de Redd, je continue Ă promouvoir l'idĂ©e que tout doit ĂȘtre simple et rapide. Nous ne concevons pas de systĂšmes complexes. Nous faisons une sorte de modules, comme ce qui a Ă©tĂ© fait dans le dernier article . C'est sophistiquĂ©, mais trĂšs, trĂšs simple. En gĂ©nĂ©ral, nous ferons sa modĂ©lisation comportementale.
Et ici se pose la question de l'environnement extĂ©rieur. Comment le simuler? Les modĂšles viennent Ă notre aide. Verilog (ainsi que VHDL et d'autres similaires) est tout Ă fait possible de dĂ©crire le comportement de quoi que ce soit. Nous fabriquons un systĂšme qui fonctionne avec la puce ULPI ... Donc, pour tester son fonctionnement, il doit y avoir quelque chose Ă l'autre extrĂ©mitĂ© qui se comporte exactement comme l'ULPI. Autrement dit, le modĂšle ULPI. Mais ce n'est pas assez. Notre bloc rĂ©agit aux commandes du bus ALAVON_MM. C'est ce bus qui fait vivre le bloc. Par consĂ©quent, nous devons Ă©galement ajouter le modĂšle de bus AVALON_MM, et ce modĂšle doit ĂȘtre actif. C'est elle qui soumettra des influences de test.
En fin de compte, nous devons crĂ©er un tel systĂšme. Et puis nous pourrons enregistrer des chronogrammes de signaux sur tous ses bus et mĂȘme Ă l'intĂ©rieur de n'importe lequel de ses modules. Si une erreur se produit, nous pouvons dĂ©finir des points d'arrĂȘt et examiner des instantanĂ©s du systĂšme pour trouver l'ennemi. Bien que, personnellement, je ne rĂšgle gĂ©nĂ©ralement pas ces points d'arrĂȘt, le plus souvent l'analyse des chronogrammes suffit. Le fait est que les signaux peuvent ĂȘtre visualisĂ©s non seulement les signaux d'interface, mais tous les signaux internes. En extrayant une douzaine ou deux signaux internes sur le graphique, vous pouvez gĂ©nĂ©ralement deviner ce qui est mal implĂ©mentĂ© dans la logique.
Le but de l'article d'aujourd'hui n'est pas de parler de ce qu'est la modĂ©lisation en gĂ©nĂ©ral (c'est une longue histoire), mais de montrer comment faire cette modĂ©lisation le plus rapidement. Et nous considĂ©rerons cela non pas sur une mission de combat, mais sur un exemple simple. Nous allons crĂ©er un systĂšme de test trĂšs simple pour que dans le prochain article, nous comprenions dĂ©jĂ d'oĂč viennent les jambes d'une version plus complexe de celui-ci, car lors de la lecture, il est plus pratique de ne pas s'asseoir et de se demander: «Pourquoi fait-il cela?», Mais connaĂźtre tous les principes de base, dont les complications dĂ©coulent dĂ©jĂ ... Soit dit en passant, rĂ©cemment, il s'est avĂ©rĂ© qu'une de mes connaissances, bien qu'elle possĂšde l'habiletĂ© de la modĂ©lisation, ne savait pas que l'environnement Quartus avait des mĂ©canismes intĂ©grĂ©s qui vous permettent de le faire facilement et naturellement. Il y a consacrĂ© beaucoup plus d'efforts que nĂ©cessaire. Alors peut-ĂȘtre que quelqu'un aussi apprendra maintenant quelque chose de nouveau sur les possibilitĂ©s inhĂ©rentes Ă Quartus. Alors,Commençons.
Verilog
Les gens se divisent en deux catĂ©gories. Ceux qui aiment tout crĂ©er Ă partir de zĂ©ro avec leurs mains et ceux qui aiment le faire avec la souris. Tout crĂ©er avec vos mains est plus correct. Vous pouvez contrĂŽler chaque action et faire tout ce que vous savez parfaitement. Mais la mĂ©moire n'est pas fiable. Si elle fait la mĂȘme chose tout le temps, elle garde les dĂ©tails Ă l'esprit, et si elle doit changer de langue tout le temps, aprĂšs un mois ou deux, elle doit se souvenir de ce qui doit ĂȘtre fait lĂ -bas. Par consĂ©quent, travailler avec l'option "bricoler avec la souris" a le droit d'exister, ne serait-ce qu'Ă cause de cela. Encore une fois, si le module en cours de dĂ©bogage a une douzaine de signaux d'interface, je suis toujours ennuyĂ© de faire le travail de routine de les re-dĂ©clarer et de les transmettre. Par consĂ©quent, nous allons maintenant examiner comment crĂ©er un modĂšle en utilisant la "souris". Et puis - chacun dĂ©cidera pour lui-mĂȘme si cela lui suffit ou s'il doit passer au travail manuel.
Donc, nous voulons simuler un module. Ce qui est «simuler» dĂ©passe le cadre de notre cycle, vous pouvez Ă©crire un grand cycle sĂ©parĂ© sur ce sujet. Autrement dit, dans le cadre de cette section, nous supposons que vous connaissez la mĂ©thodologie de dĂ©veloppement d'un modĂšle. Mais alors tout doit ĂȘtre inclus dans le projet ... Ou pas? Curieusement, vous n'avez mĂȘme pas besoin de crĂ©er votre propre projet pour modĂ©liser un module. Nous pouvons nous attacher en tant que parasite Ă n'importe quel projet sans y inclure quoi que ce soit de nouveau, mais uniquement en crĂ©ant une suite de tests qui ne participera en aucune façon Ă l'assemblage principal.
Par souci d'intĂ©rĂȘt, attachons Ă notre projet ULPI un module aussi amusant sur SystemVerilog, Ă©crit par moi spĂ©cifiquement Ă des fins d'illustration et n'a rien Ă voir avec l'analyseur dĂ©veloppĂ©. Il y a quelque temps, j'ai eu beaucoup de problĂšmes avec le calcul des sommes de contrĂŽle, alors cela m'est venu Ă l'esprit.
module sum(
input clk,
input [7:0] data,
input we,
input sof,
output [15:0] sum
);
logic [15:0] temp;
always @ (posedge clk)
begin
if (we)
begin
if (sof)
temp <= data;
else
temp <= temp + data;
end
end
// -
//assign sum = (~temp)+1;
// :
assign sum = temp;
endmodule
On peut voir que les données y parviennent via un bus, qui rappelle trÚs loin AVALON_MM, et sont simplement sorties en code parallÚle.
Mettons le fichier rĂ©sultant dans le rĂ©pertoire avec notre projet, mais nous ne l'inclurons pas dans le projet de Quartus. Au lieu de cela, nous allons crĂ©er une suite de tests spĂ©cialement pour cela. Pour ce faire, sĂ©lectionnez l'Ă©lĂ©ment de menu Assignmentsâ> Settings:
et dans l'arborescence qui apparaĂźt, recherchez l'Ă©lĂ©ment EDA Tools Settingsâ> Simulation:
A propos du type de simulation mis en Ă©vidence par le cadre vert. Peut-ĂȘtre que quelqu'un se souvient que dans les premiers articles j'ai dit que lors de la crĂ©ation d'un projet, par pure habitude, je choisis ModelSim Altera? C'Ă©tait l'arme mĂȘme sur la scĂšne qui, tĂŽt ou tard, devait tirer. Cependant, si le type de modĂ©lisation n'a pas Ă©tĂ© sĂ©lectionnĂ© lors de la crĂ©ation du projet, vous pouvez le sĂ©lectionner ou le modifier ici.
Nous continuons à créer une suite de tests. Basculez le bouton radio sur Compiler le banc de test (au fait, comment ce terme se traduit-il magnifiquement en russe? Je ne peux pas me résoudre à écrire "banc de test", car je ne vois pas de banc) et appuyez sur le bouton Bancs de test :
dans la boĂźte de dialogue qui s'ouvre, appuyez sur Nouveau :
Si faire cas de test manuellement, vous pouvez remplir les champs en une seule passe. Mais puisque nous faisons tout avec la "souris", maintenant nous ne remplissons qu'une partie des champs, et nous remplirons le reste plus tard. Dans le champ Nom du banc d'essaiJ'ai tapé le mot Parazit (que pouvez-vous appeler un test qui ne fait que parasiter le projet?). Le mot Parazit en dessous était rempli automatiquement. Maintenant, nous ne le changerons pas, mais à l'avenir, nous devons encore le faire. Aussi, en utilisant le bouton "...", j'ai sélectionné le fichier sum.sv avec le code de l'additionneur à déboguer, puis, en utilisant le bouton Ajouter , je l'ai poussé dans la liste des fichiers de test. Pour l'instant, c'est tout. Fermer la boßte de dialogue ...
Ensuite, nous continuerons à former le test dans l'environnement ModelSim. Pour ce faire, sélectionnez l'élément de menu Outils -> Exécuter les outils de simulation -> Simulation RTL:
La fenĂȘtre ModelSim s'ouvre. Peut-ĂȘtre que des erreurs seront trouvĂ©es dans le code Verilog, alors vous devez fermer ModelSim, corriger les erreurs et rouvrir. Mais tĂŽt ou tard, la liste des erreurs deviendra purement organisationnelle. Cela me ressemble:
Aucun module de niveau supérieur trouvé. C'est normal. Nous ne l'avons pas encore créé simplement. Par conséquent, nous allons travailler dans la liste des bibliothÚques et l'ouvrir. Le voici, notre additionneur.
Survolez-le, appuyez sur le bouton droit de la souris et sélectionnez l'élément de menu Créer une vague. Tout cela est tellement ennuyeux dans le texte, si je tournais une vidéo, tout le processus prendrait des dizaines de secondes, alors ne vous inquiétez pas, mais surveillez vos mains plus loin. Alors, Create Wave ...
Les signaux d'interface du module sont automatiquement déplacés vers le graphique:
Il est nĂ©cessaire d'attribuer une valeur Ă l'un d'entre eux. Peu importe lequel, il est important de nommer. Le trĂšs ancien environnement de modĂ©lisation de Quartus Ă©tait bon pour gĂ©nĂ©rer des signaux d'horloge. HĂ©las, il a Ă©tĂ© retirĂ© de la livraison il y a longtemps, depuis qu'ils ont commencĂ© Ă attacher ModelSim, et ici tout n'est pas si beau avec quelque chose comme ça. Je n'ai pas vu l'intĂ©rĂȘt de gĂ©nĂ©rer un gĂ©nĂ©rateur ici, donc je ne le montrerai mĂȘme pas. Alors ... Eh bien, mettons la ligne que nous avons Ă zĂ©ro. Nous visons le signal, appuyez sur le bouton droit, sĂ©lectionnez l'Ă©lĂ©ment de menu Editâ> Wave Editorâ> Create / Modify WaveForm.
Dans la boĂźte de dialogue qui apparaĂźt, sĂ©lectionnez Constante . Et en mĂȘme temps, nous changerons l'heure, disons, de 100 microsecondes:
Ensuite, nous indiquons la valeur 0:
Nous avons crĂ©Ă© l'ensemble de donnĂ©es minimum requis, et le reste sera plus facile Ă faire avec des stylos. Nous exportons le fichier. Pour ce faire, sĂ©lectionnez lâĂ©lĂ©ment de menu
Fichier - > Exporter -> Forme dâonde: sĂ©lectionnez le type de fichier Verilog Testbench (dâailleurs, il est dommage que ce ne soit pas SystemVerilog, mais Ă lâavenir, il sera possible de le corriger avec des stylos). Nous dĂ©finissons Ă©galement le nom du fichier. Je l'ai nommĂ© parazit_tb , en suivant le "pourquoi pas?"
VoilĂ , ModelSim peut ĂȘtre fermĂ©, tandis que la maison temporaire n'a pas besoin d'ĂȘtre sauvĂ©e.
Que faire ensuite avec le modĂšle
Voici un fichier Verilog tellement tordu, mais toujours prĂȘt Ă l'emploi, le systĂšme crĂ©Ă© pour nous:
`timescale 1ns / 1ns
module parazit_tb ;
reg sof ;
reg we ;
wire [15:0] sum ;
reg [7:0] data ;
reg clk ;
sum
DUT (
.sof (sof ) ,
.we (we ) ,
.sum (sum ) ,
.data (data ) ,
.clk (clk ) );
// "Constant Pattern"
// Start Time = 0 ns, End Time = 100 us, Period = 0 ns
initial
begin
end
initial
#0 $stop;
endmodule
L'automatisation nous a évité d'écrire des blocs de construction. De plus, s'il y avait plus de signaux d'interface, l'automatisation enregistrerait et connecterait docilement tous les circuits. Personnellement, lorsque je crée manuellement des suites de tests, c'est le processus de description des signaux et de leur transmission qui est déprimant. Maintenant, dans ce fichier, nous allons maintenant créer un modÚle d'environnement qui affectera le module de somme débogué .
Comme vous pouvez le voir, il n'y a aucun sens Ă dĂ©finir les constantes faites par l'oscillateur. Mais tout de mĂȘme, tous les circuits ont Ă©tĂ© crĂ©Ă©s, le module Ă tester est connectĂ©, mĂȘme la section initiale a Ă©tĂ© crĂ©Ă©e. Affinons le code. La premiĂšre consiste Ă supprimer le point d'arrĂȘt en supprimant les lignes:
initial
#0 $stop;
Ensuite, nous ajouterons un modÚle de générateur d'horloge (comme il me manque un merveilleux générateur, qui a été fabriqué par les anciens Quartus! Là , vous pouvez régler la fréquence en mégahertz et ne pas penser à la recalculer dans une période, et plus encore - une demi-période)
always
begin
clk = 0;
#5;
clk = 1;
#5;
end
Nous devons maintenant envoyer des octets de données. Le moyen le plus simple de le faire est directement dans la section initiale , mais si j'écris chaque phase d'accÚs au bus là -bas, le code de cette section deviendra déroutant. Par conséquent, je vais faire la tùche suivante (c'est elle qui fait office de modÚle de pneu):
task SendByte (input reg[7:0] D);
begin
data = D;
we = 1;
@(posedge clk);
#1
we = 0;
end
endtask
Eh bien, je vais écrire le but des constantes et l'appel de cycles pour travailler avec le bus dans le bloc initial . Permettez-moi de vous rappeler que le type d'enregistrement # 123 signifie "attendre 123 unités de temps". Nous l'avons en nanosecondes. Je vous rappelle également que puisque les affectations sont séquentielles, nous utilisons l'opération "égal" et non la "flÚche". Donc, nous avons le code de test principal suivant:
Regardez ici
initial
begin
sof = 0;
we = 0;
data = 0;
#13;
//
sof = 1;
SendByte (1);
//
sof = 0;
SendByte (5);
SendByte (1);
//
#20;
SendByte (1);
end
Au total, notre code de module complet ressemble Ă ceci:
Affichez le code complet du module.
`timescale 1ns / 1ns
module parazit_tb ;
reg sof ;
reg we ;
wire [15:0] sum ;
reg [7:0] data ;
reg clk ;
sum
DUT (
.sof (sof ) ,
.we (we ) ,
.sum (sum ) ,
.data (data ) ,
.clk (clk ) );
always
begin
clk = 0;
#5;
clk = 1;
#5;
end
task SendByte (input reg[7:0] D);
begin
data = D;
we = 1;
@(posedge clk);
#1
we = 0;
end
endtask
// "Constant Pattern"
// Start Time = 0 ns, End Time = 100 us, Period = 0 ns
initial
begin
sof = 0;
we = 0;
data = 0;
#13;
//
sof = 1;
SendByte (1);
//
sof = 0;
SendByte (5);
SendByte (1);
//
#20;
SendByte (1);
end
endmodule
Terminer la préparation du scénario de test
Il est temps d'ajouter ce texte à la suite de tests. Pour ce faire, accédez à la boßte de dialogue que nous connaissons déjà , mais
maintenant nous ne créons pas notre ensemble, mais le sélectionnons dans la liste. à l'avenir, la liste s'agrandira au fur et à mesure que les ensembles seront ajoutés ... AprÚs avoir sélectionné, appuyez sur le bouton Modifier. J'ai apporté trois modifications aux paramÚtres:
- Ajout du fichier parazit_tb.v Ă la liste.
- Puisque dans le fichier parazit_tb.v , le module de niveau supérieur porte le nom parazit_tb (vous pouvez vous en assurer en regardant la source de la section précédente), j'ai entré ce nom dans le module de niveau supérieur dans la ligne du banc de test .
- J'ai dit d'exécuter la simulation pendant 10 microsecondes, puis de faire une pause. Si quoi que ce soit, je le ferai en appuyant sur les boutons de commande manuelle.
Total
Nous fermons tout. Exécutez à nouveau ModelSim. On voit que tout fonctionne correctement. Les données arrivent et sont comptées dans le montant. S'il n'y a pas de données sur l'horloge ( nous sommes à zéro), le montant n'augmente pas.
L'utilisation de l'environnement de modĂ©lisation lui-mĂȘme fait l'objet de plusieurs articles. Et plutĂŽt au format vidĂ©o. Mais en gĂ©nĂ©ral, nous nous sommes familiarisĂ©s avec la mĂ©thode de prĂ©paration et de rĂ©alisation rapide des tests en langage Verilog depuis l'environnement Quartus.
Maintenant que nous savons comment exĂ©cuter rapidement la simulation, nous pouvons esquisser un modĂšle d'environnement pour notre tĂȘte d'analyseur USB et tester son fonctionnement. Dans le mĂȘme temps, nous n'avons pas mĂ©morisĂ© un seul sort ModelSim, puisque Quartus vous permet de tout configurer Ă l'aide de la "souris". Il gĂ©nĂšre lui-mĂȘme tous les scripts nĂ©cessaires et appelle lui-mĂȘme l'environnement ModelSim. Nous avons Ă©galement crĂ©Ă© la base du modĂšle en mode automatique, bien que nous ayons ensuite dĂ» la modifier manuellement.
HĂ©las et ah. L'un des Ă©lĂ©ments de l'environnement externe est le module ULPI. Pour dĂ©velopper vous-mĂȘme son modĂšle, vous devez tout d'abord bien comprendre la logique de fonctionnement de ce microcircuit. Et dans l'article prĂ©cĂ©dent, j'ai dit que c'Ă©tait trĂšs dĂ©licat. Et, deuxiĂšmement, vous devez passer beaucoup de temps Ă dĂ©velopper le code du modĂšle. Et l'Ă©limination des erreurs ... Il est clair qu'il est plus facile de trouver quelque chose de tout fait. Mais le modĂšle prĂȘt Ă l'emploi n'a Ă©tĂ© trouvĂ© que dans le langage SystemC. Par consĂ©quent, dans le prochain article, nous allons apprendre Ă modĂ©liser un systĂšme en utilisant ce langage.