Simulation du micrologiciel dans l'environnement ModelSim à l'aide de modèles en langage SystemC

Dans le dernier article, nous nous sommes familiarisés avec le processus de modélisation du "firmware" dans l'environnement ModelSim, où le code cible et le générateur d'actions de test sont écrits dans le langage Verilog. C'est dommage, mais cela ne suffit pas pour l'objectif résolu dans le cycle. J'ai encouragé à plusieurs reprises l'idée que le développement du complexe Redd devrait se faire avec le moindre effort. Si le modèle de périphérique est écrit rapidement, il peut être écrit à partir de zéro. La dernière fois, nous avons créé un modèle de bus, que nous avons utilisé pour écrire des octets dans l'additionneur. Mais l'ULPI est une chose très complexe. Ecrire son modèle à partir de zéro - oh, comme c'est difficile. Si vous pouvez en trouver un prêt à l'emploi, il vaut mieux le faire. Et j'ai trouvé ... Hélas et oh, il s'est avéré être dans le langage SystemC. Nous allons maintenant examiner comment commencer à travailler avec ce langage.











En fait, cet article est apparu sous forme de fichier DOC en juin. Ensuite, un bloc de cinq articles a été rédigé simultanément. Mais le téléchargement d'un fichier DOC sur Habr est une autre tâche. Par conséquent, il se trouve que le moment n'est apparu que maintenant (et deux autres languissent par anticipation). Lors du téléchargement, j'ai remarqué que si vous n'entrez pas dans l'esprit des articles précédents, celui-ci a l'air plutôt ennuyeux. Par conséquent, s'il y a une telle envie, rafraîchissez au moins le dernier article de votre mémoire, ou mieux ces deux ( "Faire la tête d'un analyseur de bus USB ..." et "Simuler le comportement d'un projet Quartus ..." ).



introduction



Alors, le modèle fini, où puis-je l'obtenir? Il existe un projet qui résout exactement le même problème que l'analyseur que nous développons, mais qui présente quelques fonctionnalités. La première fonctionnalité concerne les FPGA Xilinx. Deuxièmement, il est complètement non documenté. Cela fonctionne en quelque sorte. Vous pouvez même acheter une maquette prête à l'emploi, la remplir de code binaire prêt à l'emploi ... Et obtenir des fonctionnalités. Quiconque a besoin d'un appareil à tout prix peut simplement suivre cette voie. Mais personne ne sait comment le développer. Ce projet est . Dans le répertoire \ ulpi_wrapper \ testbenchil existe un ensemble de fichiers pour tester le sous-système wrapper autour d'ULPI. Ils recommandent la modélisation dans l'environnement Icarus Verilog, mais j'ai fouillé et je n'ai trouvé aucune description sensée sur la façon de faire cela dans le langage SystemC. Par conséquent, j'ai décidé de continuer à travailler dans l'environnement ModelSim. Si je savais comment ça finirait ... Mais je ne savais pas. Par conséquent, j'ai commencé des recherches. Au cours de la présentation, les réussites et les échecs seront montrés. Commençons par les échecs, afin que chacun puisse voir comment ne pas le faire.



Tentative infructueuse de tout faire "de front"



Au début, j'ai décidé de prendre un exemple prêt à l'emploi et de le faire passer par la modélisation. Avec le mouvement habituel de ma main (et nous nous sommes fourrés la main dans le dernier article ), j'ai créé une suite de tests contenant des fichiers sur Verilog et SystemC. Il s'est avéré quelque chose comme ceci: je







lance ModelSim et je ne vois rien dans le groupe de travail qui serait lié à SystemC. Je vois le code Verilogo, mais pas le code Sishny.







Si vous regardez les journaux, vous pouvez voir qu'ils n'ont pas essayé de les collecter. Quel est le problème?







Informations utiles sur la configuration du fichier * .do



Il est connu que le fichier * .do est utilisé pour exécuter ModelSim. Mais en tant qu'amoureux de tout faire avec une souris, je n'ai jamais regardé en lui. Cherchons-le et ouvrons-le! Il n'y a qu'un seul fichier de ce type dans le répertoire du projet. C'est probablement ce dont nous avons besoin.







Nous l'ouvrons. Au début - l'assemblage de toutes sortes d'éléments de service et de fichiers inclus dans le projet.

Regardez le texte
transcript on
if ![file isdirectory verilog_libs] {
	file mkdir verilog_libs
}

if ![file isdirectory vhdl_libs] {
	file mkdir vhdl_libs
}

vlib verilog_libs/altera_ver
vmap altera_ver ./verilog_libs/altera_ver
vlog -vlog01compat -work altera_ver {c:/intelfpga_lite/17.1/quartus/eda/sim_lib/altera_primitives.v}

vlib verilog_libs/lpm_ver
vmap lpm_ver ./verilog_libs/lpm_ver
vlog -vlog01compat -work lpm_ver {c:/intelfpga_lite/17.1/quartus/eda/sim_lib/220model.v}

vlib verilog_libs/sgate_ver
vmap sgate_ver ./verilog_libs/sgate_ver
vlog -vlog01compat -work sgate_ver {c:/intelfpga_lite/17.1/quartus/eda/sim_lib/sgate.v}




Mais à la fin - clairement l'assemblage des choses dont nous avons besoin, je juge cela par le nom du fichier ulpi_wrapper.v :

vlog -vlog01compat -work work +incdir+C:/Work/UsbHead1/SystemCPlay {C:/Work/UsbHead1/SystemCPlay/ulpi_wrapper.v}

vsim -t 1ps -L altera_ver -L lpm_ver -L sgate_ver -L altera_mf_ver -L altera_lnsim_ver -L cycloneive_ver -L rtl_work -L work -L UsbHead1 -voptargs="+acc"  lalala

add wave *
view structure
view signals
run 10 us


Vraiment. Il y a un assemblage d'un module Verilog, et il n'y a aucun indice d'assemblage de modules sur SystemC. Le seul dommage est que ce fichier DO est automatiquement créé à chaque fois que vous démarrez la simulation, vous ne pouvez donc pas simplement le prendre et le modifier. Il est créé par un script TCL très complexe. Il n'y a aucun désir de le gouverner. Mais après l' article sur le quartier joyeux , il est probablement clair qu'une telle bagatelle n'est pas une raison d'abandonner. Sûrement, tout est déjà là. Le seul dommage est que la documentation dit que "vous pouvez faire le script de cette façon, ou vous pouvez le faire", et il n'y a pas d'indices pour des exemples. Eh bien, déduisons tout expérimentalement. Créez un fichier C: \ Work \ UsbHead1 \ SystemCPlay \ myrun.do et essayez de lui transférer le contrôle. Tout d'abord, nous essayons de le faire comme ceci:







Le fichier DO principal continue d'être généré, mais sa fin devient comme ceci:

vlog -sv -work UsbHead1 +incdir+C:/Work/UsbHead1/UsbHead1/synthesis/submodules {C:/Work/UsbHead1/UsbHead1/synthesis/submodules/UsbHead1_master_0_b2p_adapter.sv}
vlog -sv -work UsbHead1 +incdir+C:/Work/UsbHead1/UsbHead1/synthesis/submodules {C:/Work/UsbHead1/UsbHead1/synthesis/submodules/UsbHead1_master_0_timing_adt.sv}

vlog -vlog01compat -work work +incdir+C:/Work/UsbHead1/SystemCPlay {C:/Work/UsbHead1/SystemCPlay/ulpi_wrapper.v}

vsim -t 1ps -L altera_ver -L lpm_ver -L sgate_ver -L altera_mf_ver -L altera_lnsim_ver -L cycloneive_ver -L rtl_work -L work -L UsbHead1 -voptargs="+acc"  lalala

do C:/Work/UsbHead1/SystemCPlay/myrun.do


Nous voyons que le fichier Verilog est toujours compilé, puis le processus de modélisation est toujours lancé (bien que je l'ai vu pendant les tests, mais maintenant je peux dire avec certitude que la commande vsim démarre ce processus), après quoi le contrôle est transféré à notre scénario. Ce script doit contrôler le processus d'affichage. Mais nous ne pouvons toujours pas gérer l'assemblage. Si les fichiers collectés ne suffisent pas, le système tombera par erreur avant que nous ne soyons autorisés à faire quoi que ce soit. Eh bien, super, essayons le dernier réglage.







Et ici, le plaisir commence. C'est tellement important que je l'encadre.



Je sélectionne un script, mais il n'est pas sélectionné. Je vais dans les paramètres (j'ai l'option sélectionnée précédemment). Je choisis, pas choisi. Et ainsi - même au bleu dans le visage. Jusqu'à ce que je m'en aperçoive, jusqu'à ce que je trouve comment gagner - j'ai tué le soir! Il s'est avéré que si vous sélectionnez simplement un fichier, le bouton Appliquer restera gris. Et les changements ne seront pas retenus. Il est impératif de rendre le bouton Appliquer noir en modifiant d'autres paramètres de dialogue! Dans l'image ci-dessus, c'est exactement noir. S'il reste grisé, les modifications ne seront pas enregistrées et tout ne sera pas reconfiguré pour utiliser le script.




Le script est toujours en cours de formation, mais sa fin est devenue plus pratique pour nous.

vlog -sv -work UsbHead1 +incdir+C:/Work/UsbHead1/UsbHead1/synthesis/submodules {C:/Work/UsbHead1/UsbHead1/synthesis/submodules/UsbHead1_master_0_timing_adt.sv}

do "C:/Work/UsbHead1/SystemCPlay/myrun.do"


Enfin, le processus de construction des sources pour le projet est entièrement à notre merci! Merveilleux! À ce moment-là, je ne pouvais trouver que le document de vérification SystemC avec ModelSim écrit pour Xilinx. Mais ModelSim est en Afrique ModelSim. En utilisant les exemples de ce document et les échantillons du fichier DO créés lors d'expériences passées, j'ai créé le texte de script suivant (ne vous inquiétez pas de l'abondance de clés, ci-dessous nous allons jeter presque tout, puis nous remplacerons également les chemins absolus par des chemins relatifs, à ce stade, je viens de tout tirer des exemples et des échantillons générés automatiquement).

vlog -vlog01compat -work work +incdir+C:/Work/UsbHead1/SystemCPlay {C:/Work/UsbHead1/SystemCPlay/ulpi_wrapper.v}

vlib sc_work
sccom –g –I C:/intelFPGA_lite/17.1/quartus/cusp/systemc/include –work sc_work C:/Work/UsbHead1/SystemCPlay/ulpi_driver.cpp


Roulement de tambour ... Et ModelSim nous déclare:







Si nous omettons tous les mots obscènes, alors je n'ai rien à dire ... Mais un tel chemin est passé! Et où puis-je me procurer un autre modèle ULPI? Bien sûr, j'ai passé un accord avec des amis étrangers qui sont professionnellement impliqués dans des projets sérieux pour les FPGA. Surtout pour moi, ils ont ouvert l'accès à distance à une machine avec un ModelSim sous licence pour le week-end. La deuxième crêpe s'est également avérée grumeleuse: la version 64 bits, même sous la forme sous licence, ne fonctionne pas avec SystemC. Mais à la fin, j'ai pu jouer avec la version 32 bits du ModelSim sous licence. Par conséquent, nous continuons l'histoire ...



Quelques mots sur la documentation



Alors. Maintenant que j'ai accès au logiciel sous licence, il est temps de parler de l'endroit où chercher des informations et où trouver l'inspiration. Sur le Web, les informations sur la langue sont assez sommaires. Mais dans la livraison du système, il existe les répertoires utiles suivants:



C: \ modeltech_10.2c \ docs \ pdfdocs - documentation, y compris les fichiers au format PDF. J'ai aimé les fichiers modelsim_se_ref.pdf (ModelSim SE Command Reference Manual), modelsim_se_user.pdf (ModelSim SE User Manual) et modelsim_se_tut.pdf (ModelSim SE Tutorial). Il n'y a pas grand-chose sur la langue elle-même, mais sur la façon de connecter les fichiers et de résoudre les problèmes de dialecte - tout à fait.



Ensuite, répertoire utile C: \ modeltech_10.2c \ examples... Il existe des exemples de fichiers * .do prêts à l'emploi et de fichiers cpp et h prêts à l'emploi. L'exemple le plus utile pour nous est C: \ modeltech_10.2c \ examples \ systemc \ vlog_sc . Il vous montre comment accéder au code SystemC à partir du code Verilog. Nous, à la fin, irons exactement dans cette direction.



Le répertoire C: \ modeltech_10.2c \ include \ systemc contient le code source de la bibliothèque de types de langage. Pas un mauvais livre de référence. Comme on dit, il y a des poissons pour la non-pêche et le cancer.



Tout à partir de catalogues. Maintenant, le titre d'un livre merveilleux, à partir duquel vous pouvez en apprendre beaucoup sur le langage et sur les méthodes de programmation qu'il contient. SystemC - From the Ground Up, deuxième édition. Par David C. Black, Jack Donovan, Bill Bunton, Anna Keist.



Dialectes SystemC



Alors. Ayant eu accès au système de travail, j'ai assemblé joyeusement le projet, selon le script créé précédemment. Il s'est assemblé sans erreur! Le premier modèle de GitHub a accepté de travailler avec nous! Voulant exécuter le benchmark, j'ai ajouté le fichier ulpi_wrapper_tb.cpp du même répertoire au projet et j'ai eu des tonnes d'erreurs. Disons qu'il y a une erreur dans la ligne:

m_vpi_handle = vpi_handle_by_name ((const char *) name, NULL);

difficile à réparer, mais toujours possible. Mais la ligne

        // Update systemC TB
        if(sc_pending_activity())
            sc_start((int)(time_value-m_last_time),SC_NS);


évoqué de mauvaises pensées. Il n'y a pas sc_pending_activity () fonction dans les bibliothèques. Il existe une fonction sc_pending_activity_at_current_time () , mais je n'ai même pas pris la peine de m'en occuper . Au lieu de mille mots d'explication, je vais donner un dump:







Et il y avait 44 fichiers avec ce texte (* .exe, * .dll, etc.).



Vous pourriez essayer de tout réécrire ... Mais est-ce nécessaire? Permettez-moi de vous rappeler que j'ai en fait commencé tout cela, parce que je voulais utiliser tout ce qui était prêt. Je peux tout développer dans un environnement libre sur un pur SystemVerilog, si je perds vraiment beaucoup de temps ... j'y suis allé pour ne pas perdre de temps, mais pour économiser! Mais en fait ... L'essentiel est de ne pas oublier ce que nous faisons. Nous voulons utiliser le modèle de bus ULPI. Elle se ressaisit. Des problèmes sont survenus lors de la tentative de construction d'un système de test complet à partir de l'exemple ... Pourquoi cela? Eh bien, le système complet ne fonctionne pas, et d'accord. Nous maîtriserons un modèle, sans regarder le fonctionnement du système, par essais et erreurs.



Éliminer les malentendus liés aux dialectes



Alors. Nous ferons un système mixte. Le module avec le modèle sera écrit dans le langage SystemC, et je lui soumettrai des actions de test ainsi que le module en cours de développement dans le langage Verilog. Autrement dit, vous devez faire apparaître le module ulpi_driver dans le groupe de travail .



En examinant des exemples de fichiers * .do de la livraison de ModelSim, j'ai grandement simplifié le script, et à la fin, j'ai fait ceci:

vlog +../../SystemCPlay {../../MyCores/ULPIhead.sv}

sccom -g ../../SystemCPlay/ulpi_driver.cpp
sccom -link


Il n'y a pas d'erreurs, mais le module n'apparaît pas non plus dans le groupe. En examinant les fichiers d'exemple (rappelez-vous, le meilleur exemple d'implémentation d'un tel mélange de langues se trouve dans le répertoire C: \ modeltech_10.2c \ examples \ systemc \ vlog_sc ), j'ai réalisé que la ligne suivante devait être ajoutée à la fin du fichier ulpi_driver.cpp :

SC_MODULE_EXPORT(ulpi_driver);


La documentation de ModelSim indique qu'il s'agit de fonctionnalités de dialecte. Et voila! Le voici, notre module:







Certes, le menu Create Wave (nous avons discuté de ce menu dans le dernier article ) n'est pas disponible pour cela. Et il n'a pas de ports. Historiquement, j'ai d'abord traité des ports, mais méthodiquement - je reporterai l'histoire à leur sujet à plus tard. Sinon, vous devez éditer le code deux fois. Afin de ne pas faire cela, nous allons d'abord faire un peu de préparation.



Faire un générateur d'horloge



Il s'est avéré que le modèle présente quelques différences par rapport au véritable ULPI. La première différence est que l'horloge à 66 MHz doit être générée par la puce. Que voyons-nous dans le modèle?

    sc_in<bool>             clk_i;


Désordre! Commençons le retravail! Tous les travaux, sauf indication contraire, sont effectués dans le fichier ulpi_driver.h.

Modifiez le type de port. C'était:

    sc_in<bool>             clk_i;


est devenu (j'ai également changé le nom du port):

    sc_inout<bool>             clk;


J'ai appris du livre qu'un vrai générateur est inséré en ajoutant une variable:

    sc_clock oscillator;


Nous définissons les paramètres dans le constructeur. En conséquence, le constructeur prend la forme:

    //-------------------------------------------------------------
    // Constructor
    //-------------------------------------------------------------
    SC_HAS_PROCESS(ulpi_driver);
    ulpi_driver(sc_module_name name): sc_module(name),
                                      m_tx_fifo(1024), 
                                      m_rx_fifo(1024),
                                      oscillator ("clk66",sc_time(15,SC_NS))
    {


La dernière ligne est juste pour ça. Si vous le souhaitez, vous pouvez même démarrer la simulation, double-cliquez sur le module usb_driver , puis tirez clk66 vers la hutte temporaire et lancez un peu le processus de simulation . On voit déjà comment fonctionne le générateur:







n'oublions pas de changer le nom du signal d'horloge à l'endroit où le thread principal démarre. C'était:

        SC_CTHREAD(drive, clk_i.pos());


Devenu:

        SC_CTHREAD(drive, clk.pos());




Les liens internes ont été remplacés. Mais comme il est beau d'amener le signal à l'extérieur, je n'ai pas trouvé. Peut-être que je manque simplement de qualifications. Mais d'une manière ou d'une autre, toutes les tentatives de retrait du port ont échoué. Il y avait toujours quelque chose sur le chemin. J'ai même trouvé une discussion sur un forum où l'auteur devait faire de même. L'équipe a décidé qu'il ne pouvait être transmis qu'aux ports d'entrée. Mais nous devons sortir! Par conséquent, nous faisons cela.



Ajoutez une fonction de flux sous le constructeur:

    void clkThread(void) 
    {
       while (true)
       {
           wait(oscillator.posedge_event());
           clk.write (true);
           wait(oscillator.negedge_event());
           clk.write (false);
       }
    }


Et ajoutez un lien vers celui-ci dans le constructeur de classe:

        SC_THREAD(clkThread);


Permettez-moi de montrer la zone de constructeur actuelle pour donner une vue holistique du résultat actuel:

    SC_HAS_PROCESS(ulpi_driver);
    ulpi_driver(sc_module_name name): sc_module(name),
                                      m_tx_fifo(1024), 
                                      m_rx_fifo(1024),
                                      oscillator ("clk66",sc_time(15,SC_NS))
    {
        SC_CTHREAD(drive,clk.pos());
        SC_THREAD(clkThread);

        m_reg[ULPI_REG_VIDL]    = 0x24;
        m_reg[ULPI_REG_VIDH]    = 0x04;
        m_reg[ULPI_REG_PIDL]    = 0x04;
        m_reg[ULPI_REG_PIDH]    = 0x00;
        m_reg[ULPI_REG_FUNC]    = 0x41;
        m_reg[ULPI_REG_OTG]     = 0x06;
        m_reg[ULPI_REG_SCRATCH] = 0x00;
    }

    void clkThread(void) 
    {
       while (true)
       {
           wait(oscillator.posedge_event());
           clk.write (true);
           wait(oscillator.negedge_event());
           clk.write (false);
       }
    }


Tout. La première modification est terminée.



Créer un bus de données bidirectionnel



ULPI dispose d'un bus de données bidirectionnel. Et dans le modèle, nous en voyons la description suivante:

    sc_out <sc_uint<8> >    ulpi_data_o;
    sc_in  <sc_uint<8> >    ulpi_data_i;


Désordre! Nous allons d'abord créer un blanc basé sur le bus de sortie, puis nous allons tout basculer dessus. Où commencer? Du fait que le bus doit pouvoir passer dans le troisième état, et le type sc_uint <8> ne fonctionne qu'avec des données binaires. Le type sc_lv <8> nous aidera . Par conséquent, nous modifions la déclaration des pneus en:

    sc_inout <sc_lv<8> >    ulpi_data_o;


Accédez maintenant au fichier ulpi_driver.cpp et recherchez tous les appels au bus ulpi_data_o . Intuitivement, j'ai réalisé qu'il n'y avait qu'un seul endroit à réparer:





Le même texte.
void ulpi_driver::drive_input(void)
{
    // Turnaround
    ulpi_dir_o.write(false);
    ulpi_nxt_o.write(false);
    ulpi_data_o.write(0x00);

    wait(oscillator.posedge_event());
}






Remplacez la ligne sélectionnée par

    ulpi_data_o.write("ZZZZZZZZ");


Tout. Maintenant, vous pouvez au lieu de deux lignes:

    sc_inout <sc_lv<8> >    ulpi_data_o;
    sc_in  <sc_uint<8> >    ulpi_data_i;


écrivez-en un:

    sc_inout <sc_lv<8> >    ulpi_data;


et remplacez toutes les références aux anciennes variables à la fois dans le h-nick et dans le cpp-shnik par des références à la variable ulpi_data .



Ajouter des alias de port



Alors. Après une longue recherche, je suis arrivé à la conclusion (peut-être erronée) que dans l'environnement ModelSim, il est facile de prendre et de voir les ports d'un module séparé sur SystemC en utilisant l'interface graphique, pas de chance. Cependant, si ce module est inséré dans le système de test, ils apparaîtront. Mais en fouillant avec la théorie, j'ai trouvé comment définir magnifiquement des alias pour les noms de port. Le constructeur de classe final ressemble maintenant à ceci:

    SC_HAS_PROCESS(ulpi_driver);
    ulpi_driver(sc_module_name name): sc_module(name),
                                      m_tx_fifo(1024), 
                                      m_rx_fifo(1024),
                                      oscillator ("clk66",sc_time(15,SC_NS)),
                                      rst_i ("rst"),     
                                      ulpi_data ("data"),
                                      ulpi_dir_o ("dir"),
                                      ulpi_nxt_o ("nxt"),
                                      ulpi_stp_i ("stp")
    {
        SC_CTHREAD(drive,clk.pos());
        SC_THREAD(clkThread);

        m_reg[ULPI_REG_VIDL]    = 0x24;
        m_reg[ULPI_REG_VIDH]    = 0x04;
        m_reg[ULPI_REG_PIDL]    = 0x04;
        m_reg[ULPI_REG_PIDH]    = 0x00;
        m_reg[ULPI_REG_FUNC]    = 0x41;
        m_reg[ULPI_REG_OTG]     = 0x06;
        m_reg[ULPI_REG_SCRATCH] = 0x00;
    }


Faire un système de test



Eh bien. Je ne pouvais pas tout faire automatiquement pour que deux modules débogués (la tête de l'analyseur et le modèle de bus ULPI) sautent eux-mêmes dans le fichier de test. Mais faisons au moins un test de tête, puis ajoutons-y ULPI. En utilisant la technique du dernier article , j'ai créé un système de test pour le fichier ULPIhead.sv . J'ai un fichier appelé sim1.v et immédiatement rebaptisèrent sim1.sv .



Ensuite, j'ai ajouté le module ulpi_driver avec les poignées . Le script final myrun.do ressemble à ceci:

vlog +../../SystemCPlay {../../MyCores/ULPIhead.sv}

sccom -g ../../SystemCPlay/ulpi_driver.cpp
sccom -link

vlog +../../SystemCPlay {../../SystemCPlay/sim1.sv}
vsim -voptargs="+acc" sim1


La dernière ligne est torturée. Sans cela, le code Verilog n'avait pas de ports. En modifiant les paramètres d'optimisation, nous éliminons ce problème. Je l'ai vu dans ce fichier * .do qui a été créé pour simuler notre système au tout début, alors que tout était encore fait sur la machine. Certes, il y a une longue file d'attente. Je viens de trouver la clé qui résout le problème et je l'ai copiée. Et donc - je n'aime pas les longues files d'attente, j'ai jeté tout ce qui n'était pas nécessaire.



Maintenant, nous ajoutons le bloc ULPI au système de test et faisons un test factice. Juste pour vous assurer que tous les signaux d'horloge coïncident et que les bus sont réglés sur les valeurs correctes.



J'ai eu ce test.

Regardez le texte.
`timescale 1ns / 1ns
module sim1  ; 
 
  reg    ulpi_dir   ; 
  wire   source_valid   ; 
  wire    ulpi_stp   ; 
  reg    ulpi_clk   ; 
  reg    ulpi_nxt   ; 
  reg    reset_n   ; 
  reg    read   ; 
  reg  [31:0]  writedata   ; 
  wire    ulpi_rst   ; 
  reg    clk   ; 
  wire  [7:0]  source_data   ; 
  reg    write   ; 
  wire  [7:0]  ulpi_data   ; 
  reg    source_ready   ; 
  reg  [1:0]  address   ; 
  wire  [31:0]  readdata   ; 

  always 
  begin
     clk = 1;
     #5;
     clk = 0;
     #5;
  end

  ULPIhead  DUT  
  ( 
      .ulpi_dir (ulpi_dir ) ,
      .source_valid (source_valid ) ,
      .ulpi_stp (ulpi_stp ) ,
      .ulpi_clk (ulpi_clk ) ,
      .ulpi_nxt (ulpi_nxt ) ,
      .reset_n (reset_n ) ,
      .read (read ) ,
      .writedata (writedata ) ,
      .ulpi_rst (ulpi_rst ) ,
      .clk (clk ) ,
      .source_data (source_data ) ,
      .write (write ) ,
      .ulpi_data (ulpi_data ) ,
      .source_ready (source_ready ) ,
      .address (address ) ,
      .readdata (readdata ) ); 


  ulpi_driver ULPI
  (
      .clk (ulpi_clk),
      .rst (ulpi_rst),
      .data (ulpi_data),
      .dir (ulpi_dir),
      .nxt (ulpi_nxt),
      .stp (ulpi_stp)

  );

  initial
  begin
     reset_n  = 1'b0;
     source_ready = 1;
     writedata = 0;
     address = 0;
     read = 0;
     write = 0;
     #20
     reset_n  = 1'b1;
  end

endmodule










Conclusion



À tout le moins, nous maîtrisons la modélisation en langage SystemC en utilisant le système ModelSim. Cependant, il s'est avéré que cela nécessite l'accès à la version 32 bits sous licence. La version gratuite et la version 64 bits sous licence ne fournissent pas une telle opportunité. Si je comprends bien, tout peut être fait de manière totalement gratuite dans le système Icarus Verilog, mais je n'ai pas compris exactement comment y parvenir. Il s'est avéré plus facile pour moi d'accéder au ModelSim requis. Dans le prochain article, nous utiliserons ces connaissances pour modéliser notre tête.



Au cours des travaux, des modifications assez complexes des modèles ont été apportées. Les fichiers résultants peuvent être téléchargés ici .



All Articles