SystemVerilog pour la description du materiel

Dans ce cours nous verrons comment décrire des fonctions de l'électronique numérique en SystemVerilog. 

Plus particulièrement, nous nous intéresserons à la description de:

  • la logique combinatoire;
  • la logique séquentielle synchrone;
  • les machines à états finis;
  • les mémoires synchrones.

Les points importants qu'il fat garder sont résumés dans ce qui suit. Pour les détails, référez vous au cour.

Logique combinatoire

  • La sortie d'un bloc combinatoire ne dépend que de la valeur de ses entrées.
  • Pour les mêmes valeurs des entrées on doit toujours avoir les mêmes valeurs de sortie.
  • Pas de mémorisation,
  • Pour ne pas se tromper:
    • liste de sensibilité automatique en utilisant always_comb,
    • n'utiliser que des affectations immediate (=),
    • donner systématiquement une valeur par défaut aux sorties ou être sûr de couvrir tous les cas,

Exemple

  • Un multiplexeur
always_comb
begin
   if(x) y = z;
   else  y = w;
end

// ou

always_comb
begin
   y = w;
   if(x) y = z;
end

Logique séquentielle

  • Dès qu'il y a mémorisation, elle doit être séquentielle.
  • Un processus sensible au seul front d'horloge
    • et éventuellement un signal de remise à zéro si celui-ci est asynchrone
  • Les affectations doivent être différées (<=)
  • L'état initial doit être définit dans le même processus avec une condition de remise à zéro (reset)

Structure de base

  • Avec remise à zéro synchrone, le signal de reset ne fait pas partie de la liste de sensibilité
always_ff@(posedge clk)
if (reset)
begin
   ...
end
else
begin
   ...
end
  • Avec remise à zéro asynchrone, le signal de reset fait partie de la liste de sensibilité.
  1. Le reset est actif sur niveau haut:
always_ff@(posedge clk or posedge reset)
if (reset)
begin
   ...
end
else
begin
   ...
end
  1. Le reset est actif sur niveau bas:
always_ff@(posedge clk or negedge nreset)
if (!nreset)
begin
   ...
end
else
begin
   ...
end

Mémoire synchrone simple port

  • Au front d'horloge on obtient l'élément pour lequel on a présenté l'adresse
  • Au même front on peut modifier ce même élément

Exemples

module sram(input clk, wr,
            input  [7:0] Addr,
            input  [7:0] Di,
            output logic [7:0] Do );


logic[7:0] mem [0:255];

always_ff @(posedge clk)
begin
   if (wr)
      mem[Addr] <= Di;
   Do <= mem[Addr];
end

endmodule

ou

module sram(input clk, wr,
            input  [7:0] Addr,
            input  [7:0] Di,
            output [7:0] Do );


logic[7:0] mem [0:255];
logic[7:0] Addr_r;

always_ff @(posedge clk)
begin
   if (wr)
      mem[Addr] <= Di;
   Addr_r <= Addr;
end

assign Do = mem[Addr_r];

endmodule

Mémoire synchrone dual-port

  • Deux canaux indépendants pour accéder à la même table
module sram_dp(input clk, wr1, wr2,
               input  [7:0] Addr1, Addr2,
               input  [7:0] Di1, Di2,
               output logic [7:0] Do1, Do2 );


logic[7:0] mem [0:255];

always_ff @(posedge clk)
begin
   if (wr1)
      mem[Addr1] <= Di1;
   Do1 <= mem[Addr1];
end

always_ff @(posedge clk)
begin
   if (wr2)
      mem[Addr2] <= Di2;
   Do2 <= mem[Addr2];
end

endmodule

Rom synchrone

  • Initialiser le contenu de la table et interdire l'écriture
  • NE FONCTIONNE QU'AVEC LES FPGAs
module rom (input clk,
            input  [7:0] Addr,
            output logic [7:0] Do );


logic[7:0] mem [0:255];

initial
    $readmemh("init.txt", mem);

always_ff @(posedge clk)
   Do <= mem[Addr];

endmodule
Fichier attachéTaille
PDF icon Les transparents du cours377.45 Ko