[VHDL/Verilog] Les FPGA et leur programmation

Les FPGA et leur programmation [VHDL/Verilog] - Divers - Programmation

Marsh Posté le 25-06-2010 à 14:38:54    

Bonjour,
 
J'ai beau chercher, je ne trouve pas de topic d'entraide, bonnes pratiques, news concernant les FPGA/PLD et leurs langages de programmation associés (VHDL/Verilog).
 
En ce qui me concerne, c'est mon boulot et je serai ravi de partager mon XP.
 
Je suis bien conscient que c'est un peu spécifique ne serais pas étonné de faire un joli bide avec ce topic.  [:cyber-mx]


---------------
sheep++
Reply

Marsh Posté le 25-06-2010 à 14:38:54   

Reply

Marsh Posté le 21-08-2010 à 07:17:53    

Tu n'aurais pas quelques bons liens pour les débutants ?
 
C'est possible d'utiliser un FPGA pour réaliser une carte GPIO sur le bus PCI Express ?

Reply

Marsh Posté le 21-08-2010 à 12:36:00    

404 Not Found a écrit :

Tu n'aurais pas quelques bons liens pour les débutants ?


 
Wikipédia: http://fr.wikipedia.org/wiki/VHDL avec pas mal de liens en bas pour les débutants.
Un site avec de tutoriaux hardware, vhdl et verilog (en Anglais): http://www.fpga4fun.com/
 

404 Not Found a écrit :

C'est possible d'utiliser un FPGA pour réaliser une carte GPIO sur le bus PCI Express ?


Oui c'est possible, par contre une carte FPGA sur pci-express coûte un bras... Et le PCIe n'est vraiment pas une bonne option pour débuter c'est relativement compliqué et ça va très vite (même si il existe des IP PCIe gratuites).
 
Pour démarrer, et s'amuser au passage, je conseillerais la carte DE2 d'altera: http://www.altera.com/education/un [...] board.html
ou une carte spartan3 de xilinx (un peu plus limitée): http://www.xilinx.com/products/dev [...] -UNI-G.htm


---------------
sheep++
Reply

Marsh Posté le 23-09-2012 à 12:21:18    

:hello:  
T'utilises quel soft pour programmer en verilog ?

Reply

Marsh Posté le 23-09-2012 à 12:30:48    

Je crois comprendre.  
T'écris dans un txt par exemple et après tu le simules avec des simulateurs, c'est ça ?
 
Il est bien le site fpga4fun  :jap:

Reply

Marsh Posté le 23-09-2012 à 18:18:45    

Oui c'est ça!
 
C'est du code donc n'importe quel éditeur de texte fait l'affaire (mais certains mieux que bloc-note). Ensuite on passe ça à la moulinette (synthèse suivit de placement routage) et on obtient un binaire à flasher dans le FPGA (pour faire simple).
 
Ou alors on peut vérifier le code par simulation, mais le but final est d'obtenir le binaire.
 
Il existe tout un tas d'outils, le plus simple étant d'utiliser un IDE distribué gratuitement par les fournisseurs de FPGA.


---------------
sheep++
Reply

Marsh Posté le 24-09-2012 à 06:17:46    

Ok. J'ai téléchargé notepad++.

 

Peut être un peu hs mais tu connais les trucs genre AIG (And Inverter Graph) ? Ca se situe où par rapport au design en verilog ? Ca vient avant, après, rien à faire ensemble ?


Message édité par Profil supprimé le 24-09-2012 à 06:17:55
Reply

Marsh Posté le 24-09-2012 à 21:44:57    

Jamais utilisé, mais de ce que j'en vois sur wikipedia, ça peut aider la phase de conception.
C'est donc plutôt avant le code.
 
Autre chose, verilog est encore très utilisé aux états unis, mais en Europe on préfère le VHDL, plus moderne et mieux typé.
 


---------------
sheep++
Reply

Marsh Posté le 30-09-2012 à 06:52:19    

Je trouve ça bien sympa le verilog.
Par contre j'ai deux problèmes.
La première c'est que je ne comprends pas vraiment la différence entre wire et reg. D'après ce que je lis on utilise reg quand on veut stocker la valeur pendant qu'on en attend une nouvelle et wire pour le reste. Mais je vois tous le temps les sorties reg et les entrées wire. Ca fait quoi une sortie wire ?

 

Et je m'embrouille aussi avec les représentations des signed.
J'ai trouvé le code suivant.

Citation :

wire [7:0] a;
wire [15:0] ax; // a sign-extended to 16-bit
assign ax = {{8{a[7]}}, a};


On extend de 8 bits à 16 bits ok. Mais est-ce que ça marche pour une représentation avec complément à deux ? A priori non.
Si je veux faire une soustraction entre deux entiers a et b. Disons que a=11 (3) et b=1000 (8) et que je veux le résultat dans une sortie c sur 8 bits (c = a-b) en complément à deux.
Si j'applique le code du dessus et que j'extend a et b. a devient 1111 1111 et b devient 1111 1000. Et a-b= 7 au lieu de -5.


Message édité par Profil supprimé le 30-09-2012 à 06:52:52
Reply

Marsh Posté le 30-09-2012 à 18:55:25    

Avec wire, la valeur change aussitôt qu'une des entrées changes. Avec reg, la valeur change au moment de la condition spécifiée dans le @ du block  always et est maintenue même si les entrées changent.
 
Étendre le signe, ce n'est pas à partir du bit le plus significatif de la valeur, mais un bit donné, le bit de signe. Si 11 devient 1111 1111 alors le bit de signe est le bit 2 et 1000 doit devenir 0000 0000 et si 1000 devient 1111 1000, alors le bit de signe doit être le bit 3 et 11 doit devenir 1111 0011, et si 1000 vaut 8, il ne peut pas devenir 1111 1000 mais le bit de signe doit être au moins le bit 4.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 30-09-2012 à 18:55:25   

Reply

Marsh Posté le 30-09-2012 à 19:28:28    

Un Programmeur a écrit :

Avec wire, la valeur change aussitôt qu'une des entrées changes. Avec reg, la valeur change au moment de la condition spécifiée dans le @ du block  always et est maintenue même si les entrées changent.


Pas bête [:fredmoul:1]  
 

Un Programmeur a écrit :


Étendre le signe, ce n'est pas à partir du bit le plus significatif de la valeur, mais un bit donné, le bit de signe. Si 11 devient 1111 1111 alors le bit de signe est le bit 2 et 1000 doit devenir 0000 0000 et si 1000 devient 1111 1000, alors le bit de signe doit être le bit 3 et 11 doit devenir 1111 0011, et si 1000 vaut 8, il ne peut pas devenir 1111 1000 mais le bit de signe doit être au moins le bit 4.


 [:kolombin:2]  
On verra ça demain là je suis claqué mais merci :jap:

Reply

Marsh Posté le 06-10-2012 à 12:33:46    

C'est normal que les réponses d'un test bench soit différents suivant le code de l'autre fichier ?
Quand je change la manière de faire une opération dans le fichier principal j'ai une réponse attendue différent dans le log du test bench.  
 
edit: J'ai surtout ce problème:
instruction:011 reponse: 0000000011111110, yours: 0000000011111101
instruction:011 reponse: 0000000011111101, yours: 0000000011111100
instruction:011 reponse: 0000000011111100, yours: 0000000011111011
instruction:011 reponse: 0000000011111011, yours: 0000000011111010
 
J'ai un temps d'avance sur chaque réponse. J'arrive pas à trouver la cause. Des idées ?


Message édité par Profil supprimé le 06-10-2012 à 12:45:35
Reply

Marsh Posté le 07-10-2012 à 13:21:25    

Sans avoir le code ou une info sur ce que tu essayes de faire, ça va être difficile de t'aider.


---------------
sheep++
Reply

Marsh Posté le 07-10-2012 à 14:47:07    

Je fais une alu et là c'est le résultat d'une addition. c=a+b je vois pas le problème, a et b sont sur 8 bits et c sur 16.
Tu veux tout le code ?

Reply

Marsh Posté le 07-10-2012 à 15:14:57    

Je pense que tu as un cycle d'avance car tu ne doit pas avoir de registre en sortie de ton ALU.


---------------
sheep++
Reply

Marsh Posté le 07-10-2012 à 17:26:04    

Le schéma est le suivant:
http://hfr-rehost.net/self/pic/ff704a34fd60478be6ae534de227a3b3a3187be9.jpeg
Le prof nous a donné un fichier à compléter. Mon code est en dessous.

Spoiler :

module alu(
             clk_p_i,
             reset_n_i,
             data_a_i,
             data_b_i,
             inst_i,
             data_o
             );
  /* ============================================ */
      input           clk_p_i;
      input           reset_n_i;
      input   [7:0]   data_a_i;
      input   [7:0]   data_b_i;
      input   [2:0]   inst_i;
 
      output  [15:0]  data_o;
 
  /* ============================================ */
      wire    [2:0]   out_inst_0;
      wire    [2:0]   out_inst_1;
      wire    [2:0]   out_inst_2;
      wire    [2:0]   out_inst_3;
      wire    [2:0]   out_inst_4;
      wire    [2:0]   out_inst_5;
      wire    [2:0]   out_inst_6;
      wire    [2:0]   out_inst_7;
 
      reg     [15:0]   ALU_out_inst;
      wire    [15:0]   ALU_d2_w;
 
      reg     [15:0]   ALU_d2_r;
 
  assign ALU_d2_w = ALU_out_inst;
  assign data_o     = ALU_d2_r;
   
 
  /* ============================================ */
  // The output MUX
       
   always@ ( posedge clk_p_i or posedge reset_n_i)
      begin
          case(inst_i)
           3'b000:    ALU_out_inst = data_a_i+data_b_i;
           //3'b001:    ALU_out_inst = data_a_i - data_b_i; //à voir
           //3'b010:    ALU_out_inst = data_a_i*data_b_i;
           //3'b011:    ALU_out_inst = {8'b0, ~data_a_i};
           //3'b100:    ALU_out_inst = data_a_i ^ data_b_i;
           //3'b101:    ALU_out_inst = ;
           //3'b110:    ALU_out_inst = ;
           //3'b111:    ALU_out_inst = 16'b0;
           default:   ALU_out_inst = 16'b0;
          endcase
      end
 
  /* ============================================ */
      always@(posedge clk_p_i or negedge reset_n_i)
      begin
          if (reset_n_i == 1'b0)
          begin
    ALU_d2_r <=16'b0;
          end
          else
          begin
              ALU_d2_r <= ALU_d2_w;
          end
      end
  /* ============================================ */
 
endmodule
 


_dx c'est la sortie du registre de niveau x, _w signifie la sortie d'un registre, _r c'est l'entrée d'un registre.
Je comprends même pas à quoi servent tous les out_inst_x.

Reply

Marsh Posté le 07-10-2012 à 18:17:35    

Tu n'as pas de registre à l'entrée, comme indiqué dans le schéma, d'où le décalage d'un cycle d'horloge que tu observes.
 
Concernant les out_inst_x je ne vois pas non plus leur utilité...


---------------
sheep++
Reply

Marsh Posté le 07-10-2012 à 19:58:29    

Ah c'est bon !  
Tu m'as donné le déclic. J'ai compris un truc sur les reg/wire et sur le verilog après ça [:cerveau charlest]
 
J'étais tellement excité d'être en train de comprendre et de tout voir s'éclaircir que j'ai préféré rester debout au lieu d'aller dormir et de le faire plus tard :D
J'ai aussi du mal avec le traitement en parallèle des données. Instinctivement je vois l'odre du code comme l'orde du déroulement des opérations et la fin du code comme ce qu'on doit faire en dernier. J'ai été trop formaté :D
 
C'est pour ça que j'ai jamais aimé labview :o
 
Mais je sais pas pourquoi y a un truc qui me plaît dans le verilog.

Reply

Marsh Posté le 13-10-2012 à 14:14:37    

On peut déclarer une tâche sans déclarer sa sortie? Du genre utiliser une variable globale comme sortie.
J'ai écris une tâche qui lorsqu'on l'appelle met les données d'un bus dans une matrice tampon que je manipulerai par la suite dans d'autres fonctions. Donc si je déclare la sortie dans la tâche je ne pourrais pas y accéder en dehors. Mais je vois pas de code sur internet avec une tâche sans sortie. Du coup j'ai un doute.

Message cité 1 fois
Message édité par Profil supprimé le 13-10-2012 à 14:15:20
Reply

Marsh Posté le 13-10-2012 à 19:57:06    

ça commence à devenir du Verilog avancé, et moi je suis plutôt VHDL, je ne peux pas trop t'aider sur ce point :(


---------------
sheep++
Reply

Marsh Posté le 13-10-2012 à 20:37:45    

C'est pas grave :jap:

Reply

Marsh Posté le 14-10-2012 à 09:41:02    

Et acquérir un bus (8its) à chaque front montant d'horloge c'est possible ? Ou bien on doit acquérir un bit par coup d'horloge ?  
Ca faisait longtemps que j'avais pas étudié ce genre de truc.

Reply

Marsh Posté le 14-10-2012 à 10:04:40    

Ca fait aussi des années que je n'ai pas fait de verilog.
 
 
 
Qu'est-ce que tu appelles tâche?  De mémoire ça ne fait pas partie du vocabulaire verilog, et comme c'est plus un terme de soft que de hard (ce qui veux dire que ça pourrait éventuellement se retrouver dans la partie pure simulation, mais je doute que ça fasse partie de ce qui est synthétisable), j'ai du mal à deviner ce que tu veux dire. J'hésite entre un module et un bloc always.
 

Citation :

Du genre utiliser une variable globale comme sortie.


J'ai pas le souvenir de variables globales en verilog, à nouveau ça me semble être un concept soft plutôt que hard.
 
 
 
Oui, c'est possible.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 14-10-2012 à 10:44:08    

Un Programmeur a écrit :


 
Qu'est-ce que tu appelles tâche?  De mémoire ça ne fait pas partie du vocabulaire verilog, et comme c'est plus un terme de soft que de hard (ce qui veux dire que ça pourrait éventuellement se retrouver dans la partie pure simulation, mais je doute que ça fasse partie de ce qui est synthétisable), j'ai du mal à deviner ce que tu veux dire. J'hésite entre un module et un bloc always.


Une task comme ici http://www.asic-world.com/verilog/task_func1.html

Un Programmeur a écrit :


J'ai pas le souvenir de variables globales en verilog, à nouveau ça me semble être un concept soft plutôt que hard.


Si je déclare un reg après la déclaration des input/output je ne peux pas l'utiliser dans une function/task en dessous ?  
En fait j'ai écris une task qui acquiert, à chaque front montant de la clk, les 8 bits d'un bus pour les ranger dans une case d'une matrice. C'est une matrice 12x9. Donc à la fin j'ai 108 (12*9) vecteurs (je sais pas si c'est le terme en vérilog) de 8bits, organisés en matrice.  
Après je veux créer des fonctions pour manipuler cette matrice(sélectionner quelques cases, effectuer une rotation) et envoyer en sortie une matrice 4x4. Donc ne contenant que 16 vecteurs des 108 précédents.
Donc pour faire des opérations sur ma matrice dans les fonctions il faut bien une sorte de variable globale.
J'ai déclaré ma matrice comme ceci "reg [7:0] buffer [8:0][11:0];" après la liste des I/O.
 
Au final je veux une mémoire de 12*9*8 bits dans mon module.  

Un Programmeur a écrit :


Oui, c'est possible.


Ok.

Reply

Marsh Posté le 14-10-2012 à 12:05:56    

Je pense que tu compliques un peu le truc.

 

Voici une implémentation de RAM:

 

http://www.angelfire.com/in/rajesh52/tip2.html

 

En espérant que ça t'aide!


Message édité par h3bus le 14-10-2012 à 12:06:22

---------------
sheep++
Reply

Marsh Posté le 21-11-2012 à 14:06:21    

Salut, j'ai une question conne de théorie en VHDL :jap:  
 

Code :
  1. BEGIN
  2. PROCESS(...)
  3. BEGIN
  4.     signal1 <= signal2;
  5.     signal2 <= signal1;
  6. END PROCESS;


 
Je pensais qu'à l'intérieur d'un process, les commandes étaient séquentielles.
Donc je m'attendais à avoir signal2 qui ne change pas de valeur et signal1 qui prend la valeur de signal2.
Pourtant, quand je lance ça avec Modelsim, les valeurs des signaux permuttent. :??:  
C'est quoi qui m'échappe ? :pt1cable:  
 
Thx :jap:

Reply

Marsh Posté le 21-11-2012 à 16:40:48    

Ils échangent leur états ?
Si c'est ça oui je me souviens d'avoir vu ça en vérilog il y a quelques cours. C'est les blocking assignenment si je ne dis pas de bêtise. Il y a non blocking et blocking. Blocking calcule d'abord (prévoit la futur valeur) et après assigne la valeur calculée.  
 Je vais vérifier.

Reply

Marsh Posté le 21-11-2012 à 16:41:17    

Reply

Marsh Posté le 21-11-2012 à 17:10:47    

[:ojap]

Reply

Marsh Posté le 21-11-2012 à 17:16:10    

Apprends ton cours :o
Mon cours est en chinois et je me souviens de ça :o

Reply

Marsh Posté le 21-11-2012 à 19:59:28    

Ton processus est asynchrone.
 
Ce qu'il se passe c'est que signal 1 prend la valeur de signal2 et signal2 prend la valeur précédente de signal1.
Puis, signal1 ayant changé le processus est ré exécuté.
 
Si au début signal1=signal2 le processus est exécuté une fois et rien de change. Sinon le processus est exécuté en continu et tu observe une jolie oscillation...


Message édité par h3bus le 22-11-2012 à 18:06:50

---------------
sheep++
Reply

Marsh Posté le 21-11-2012 à 22:06:39    

Petit rappel, le VHDL est d'abord un langage de simulation avant d'être un langage utilisé en synthèse.

 

Le temps en VHDL est donc une notion de temps simulé. Il a deux composantes, une "physique" mesurée en seconde auquel on ajoute une composante infinitésimale, en delta.

 

La forme complète de

 
Code :
  1. s <= v;
 

c'est

 
Code :
  1. s <= b after delai;
 

quand la clause after n'est pas spécifiée, c'est après 1 delta.

 

donc l'exécution de

Code :
  1. s1 <= s2;
  2. s2 <= s1;


prépare l'assignation de la valeur actuelle de s2 à s1 et celle de s1 à s2 pour le delta suivant. Ce qui donne bien un effet de permutation, tout comme si on avait écrit

Code :
  1. s1 <= s2 after 1ns;
  2. s2 <= s2 after 1ns;

on aurait une permutation après 1ns.

 


Message édité par Un Programmeur le 21-11-2012 à 22:07:56

---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 23-11-2013 à 14:16:48    

Coucou c'est encore moi :D
 
Cette fois je fais du vhdl.
 
Ca passe ça ?  
 

Code :
  1. entity AND_3 is
  2. port(a1: in bit; a2: in bit; a3: in bit; s: out bit);
  3. end entity;
  4. architecture arc of AND_3 is
  5. signal z : bit;
  6. component and2
  7. port (a1 : bit; a2 : bit; s : bit);
  8. end component;
  9. --
  10. begin
  11. inst1 : and2 port map (a1=>a1, a2=>a2 , s=>z);
  12. inst2 : and2 port map (z, a3, s);
  13. end arc


 
C'est pas mon code, j'ai piqué ce code ailleurs et je l'ai adapté pour vous illustrer ma question. Ma question qui porte donc sur le fait que deux ports aient le même nom. Est-ce que l'association a1=>a1 est autorisée ?

Reply

Marsh Posté le 23-11-2013 à 16:11:15    

Oui!


---------------
sheep++
Reply

Marsh Posté le 23-11-2013 à 16:29:40    

Cool ça.
 
Merci  :jap:

Reply

Marsh Posté le 16-12-2013 à 20:32:10    

Je n'aurais pas cru avoir trouvé un topic VHDL avec de l'activité :)
 
Je pose un drapeau, j'aurais probablement quelques questions à poser prochainement. J'utilise l'ide de xilinx (Ise Project Navigator), en webpack.


---------------
Creepy boy - ヾ(⌐■_■)ノ♪
Reply

Marsh Posté le 04-01-2014 à 01:39:01    

N'hésite pas :D

Reply

Marsh Posté le 04-01-2014 à 02:02:54    


Alors, c'était comment ce dernier mois ? [:xenobrandt]

Reply

Marsh Posté le 04-01-2014 à 10:54:11    


Tranquille, t'as pas idée de tout ce qui s'est passé [:xenobrandt:2]  

Reply

Marsh Posté le 04-01-2014 à 22:48:50    

Bonsoir  [:hellov]

 

Mon professeur nous a donné un fichier vhdl représentant une ROM, et j'essaye de lire les données (tableau 10*10) mais j'ai quelques soucis.

 

Le process de la rom utilise ceci :

Code :
  1. color(2 downto 0) <=  rom_img(to_integer(unsigned(y)))(to_integer(unsigned(x)))(2 downto 0);


Je ne comprends pas, j'ai l'impression que les parenthèses ne sont pas au bon endroit, mais pourtant ça marche :pt1cable:

 
Code :
  1. color      : out STD_LOGIC_VECTOR(2 DOWNTO 0)    );
 
Code :
  1. TYPE memory_slv is array ( 0 to 10 ) OF STD_LOGIC_VECTOR( 2 DOWNTO 0 );
  2. TYPE memory_img is array ( 0 to 10 ) OF memory_slv;
  3. constant rom_img : memory_img := (


1) Est-ce que la façon d'écrire est correcte (pour color(2 downto 0) <=  rom_img(to_integer(unsigned(y)))(to_integer(unsigned(x)))(2 downto 0)), ou bien les parenthèses ne sont pas bien mises ? Si c'est la bonne façon j'aurais besoin de quelques explications [:fleur de vanille]

 


Dans mon autre fichier vhdl, quand j'essaye de lire la rom j'utilise ceci pour l'instant :

Code :
  1. address := to_integer(internal_counter_hsync);
  2.   case address is
  3.    when 143 to 200 =>
  4.     internal_x <= "0011";
  5.     internal_y <= "0001";
  6.    when 201 to 400 =>
  7.     internal_x <= "0001";
  8.     internal_y <= "0001";
  9.    when others =>
  10.     internal_x <= "0000";
  11.     internal_y <= "0000";
  12.   end case;
 

2) Ça marche bien sauf pour le when others qui est complètement ignoré. De 0 à 143 et de 401 à 800, pourquoi mes deux signaux ne passent pas à 0000 ? Je suis sûr qu'il y a beaucoup plus élégant pour lire mon tableau de 10*10 que de lister tous les cas dans des when, mais j'ai toujours des messages d'erreurs.

 

Un peu d'aide n'est pas de refus ;)

Message cité 1 fois
Message édité par Hippo-fr le 04-01-2014 à 22:50:04

---------------
Creepy boy - ヾ(⌐■_■)ノ♪
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed