Conception VLSI - Introduction à Verilog

Verilog est une LANGUE DE DESCRIPTION DU MATÉRIEL (HDL). C'est un langage utilisé pour décrire un système numérique comme un commutateur réseau ou un microprocesseur ou une mémoire ou une bascule. Cela signifie qu'en utilisant un HDL, nous pouvons décrire n'importe quel matériel numérique à n'importe quel niveau. Les conceptions, qui sont décrites en HDL sont indépendantes de la technologie, très faciles à concevoir et à déboguer, et sont normalement plus utiles que les schémas, en particulier pour les grands circuits.

Verilog prend en charge une conception à de nombreux niveaux d'abstraction. Les trois principaux sont -

  • Niveau comportemental
  • Niveau de transfert de registre
  • Niveau de la porte

Niveau comportemental

Ce niveau décrit un système par algorithmes simultanés (comportemental). Chaque algorithme est séquentiel, ce qui signifie qu'il se compose d'un ensemble d'instructions qui sont exécutées une par une. Les fonctions, tâches et blocs sont les principaux éléments. Il n'y a aucun égard à la réalisation structurelle de la conception.

Registre − Niveau de transfert

Les conceptions utilisant le niveau de transfert de registre spécifient les caractéristiques d'un circuit utilisant des opérations et le transfert de données entre les registres. La définition moderne d'un code RTL est "Tout code synthétisable est appelé code RTL".

Niveau de la porte

Au niveau logique, les caractéristiques d'un système sont décrites par des liens logiques et leurs propriétés de synchronisation. Tous les signaux sont des signaux discrets. Ils ne peuvent avoir que des valeurs logiques définies («0», «1», «X», «Z»). Les opérations utilisables sont des primitives logiques prédéfinies (portes de base). La modélisation au niveau de la porte n'est peut-être pas une bonne idée pour la conception logique. Le code de niveau de porte est généré à l'aide d'outils tels que des outils de synthèse et sa netlist est utilisée pour la simulation de niveau de porte et pour le backend.

Jetons lexicaux

Les fichiers texte source du langage Verilog sont un flux de jetons lexicaux. Un jeton se compose d'un ou plusieurs caractères, et chaque caractère unique est dans exactement un jeton.

Les jetons lexicaux de base utilisés par le Verilog HDL sont similaires à ceux du langage de programmation C. Verilog est sensible à la casse. Tous les mots clés sont en minuscules.

Espace blanc

Les espaces blancs peuvent contenir des caractères pour les espaces, les tabulations, les nouvelles lignes et les flux de formulaires. Ces caractères sont ignorés sauf lorsqu'ils servent à séparer les jetons.

Les espaces blancs sont les espaces vides, les tabulations, les retours chariot, les nouvelles lignes et les sauts de formulaire.

commentaires

Il existe deux formes pour représenter les commentaires

  • 1) Les commentaires sur une seule ligne commencent par le jeton // et se terminent par un retour chariot.

Ex .: // c'est une syntaxe sur une seule ligne

  • 2) Les commentaires multilignes commencent par le jeton / * et se terminent par le jeton * /

Ex .: / * c'est une syntaxe multiligne * /

Nombres

Vous pouvez spécifier un nombre au format binaire, octal, décimal ou hexadécimal. Les nombres négatifs sont représentés dans les nombres de compliment de 2. Verilog autorise les entiers, les nombres réels et les nombres signés et non signés.

La syntaxe est donnée par - <size> <radix> <value>

La taille ou le nombre non dimensionné peut être défini dans <Size> et <radix> définit s'il est binaire, octal, hexadécimal ou décimal.

Identifiants

L'identifiant est le nom utilisé pour définir l'objet, tel qu'une fonction, un module ou un registre. Les identificateurs doivent commencer par des caractères alphabétiques ou des caractères de soulignement. Ex. A_Z, a_z, _

Les identificateurs sont une combinaison de caractères alphabétiques, numériques, de soulignement et $. Ils peuvent contenir jusqu'à 1024 caractères.

Les opérateurs

Les opérateurs sont des caractères spéciaux utilisés pour mettre des conditions ou pour faire fonctionner les variables. Un, deux et parfois trois caractères sont utilisés pour effectuer des opérations sur des variables.

Ex. >, +, ~ Et! =.

Mots-clés Verilog

Les mots qui ont une signification particulière dans Verilog sont appelés les mots-clés Verilog. Par exemple, attribuez, case, while, wire, reg et, or, nand et module. Ils ne doivent pas être utilisés comme identifiants. Les mots-clés Verilog incluent également les directives du compilateur et les tâches et fonctions système.

Modélisation au niveau de la porte

Verilog a des primitives intégrées telles que des portes logiques, des portes de transmission et des commutateurs. Ceux-ci sont rarement utilisés pour les travaux de conception, mais ils sont utilisés dans le monde de la post-synthèse pour la modélisation des cellules ASIC / FPGA.

La modélisation au niveau de la porte présente deux propriétés -

Drive strength- La force des portes de sortie est définie par la force d'entraînement. La sortie est la plus puissante s'il existe une connexion directe à la source. La force diminue si la connexion se fait via un transistor conducteur et moins lorsqu'elle est connectée via un résistif pull-up / down. La force d'entraînement n'est généralement pas spécifiée, auquel cas les forces par défaut sont strong1 et strong0.

Delays- si les délais ne sont pas spécifiés, les portes n'ont pas de délais de propagation; si deux retards sont spécifiés, alors le premier représente le retard de montée et le second, le retard de chute; si un seul délai est spécifié, alors les deux, montée et descente sont égales. Les retards peuvent être ignorés dans la synthèse.

Primitives de porte

Les portes logiques de base utilisant une sortie et de nombreuses entrées sont utilisées dans Verilog. GATE utilise l'un des mots-clés - et, nand, ou, ni, xor, xnor à utiliser dans Verilog pour N nombre d'entrées et 1 sortie.

Example:  
   Module gate() 
   Wire ot0; 
   Wire ot1; 
   Wire ot2; 
   
   Reg in0,in1,in2,in3; 
   Not U1(ot0,in0); 
   Xor U2(ot1,in1,in2,in3); 
   And U3(ot2, in2,in3,in0)

Primitives de porte de transmission

Les primitives de porte de transmission comprennent à la fois des tampons et des onduleurs. Ils ont une seule entrée et une ou plusieurs sorties. Dans la syntaxe d'instanciation de porte illustrée ci-dessous, GATE représente le mot clé buf ou NOT gate.

Exemple: Not, buf, bufif0, bufif1, notif0, notif1

Not - n outout onduleur

Tampon de sortie Buf - n

Bufifo - tampon à trois états, activation basse active

Bufif1 - tampon à trois états, activation haute active

Notifo - inverseur à trois états, activation basse active

Notif1 - onduleur à trois états, validation haute active

Example:  
   Module gate() 
   Wire out0; 
   Wire out1; 
   
   Reg in0,in1;
   Not U1(out0,in0); 
   Buf U2(out0,in0);

Types de données

Ensemble de valeurs

Verilog se compose principalement de quatre valeurs de base. Tous les types de données Verilog, qui sont utilisés dans Verilog stockent ces valeurs -

0 (zéro logique ou condition fausse)

1 (logique un ou condition vraie)

x (valeur logique inconnue)

z (état haute impédance)

l'utilisation de x et z est très limitée pour la synthèse.

Câble

Un fil est utilisé pour représenter un fil physique dans un circuit et il est utilisé pour la connexion de portes ou de modules. La valeur d'un fil ne peut être lue et non affectée que dans une fonction ou un bloc. Un fil ne peut pas stocker de valeur mais est toujours piloté par une instruction d'affectation continue ou en connectant le fil à la sortie d'une porte / module. D'autres types spécifiques de fils sont -

Wand (wired-AND) - ici la valeur de Wand dépend du ET logique de tous les pilotes de périphériques qui y sont connectés.

Wor (wired-OR) - ici la valeur d'un Wor dépend du OU logique de tous les pilotes de périphériques qui y sont connectés.

Tri (three-state) - ici tous les pilotes connectés à un tri doivent être z, sauf un seul (qui détermine la valeur de tri).

Example: 
   Wire [msb:lsb] wire_variable_list; 
   Wirec // simple wire 
   Wand d; 
   
   Assign d = a; // value of d is the logical AND of 
   Assign d = b; // a and b 
   Wire [9:0] A; // a cable (vector) of 10 wires. 
   
   Wand [msb:lsb] wand_variable_list; 
   Wor [msb:lsb] wor_variable_list; 
   Tri [msb:lsb] tri_variable_list;

S'inscrire

Un reg (registre) est un objet de données, qui contient la valeur d'une affectation procédurale à la suivante et n'est utilisé que dans différentes fonctions et blocs procéduraux. Un reg est un simple registre de type variable Verilog et ne peut pas impliquer un registre physique. Dans les registres multi-bits, les données sont stockées sous la forme de nombres non signés et l'extension de signe n'est pas utilisée.

Exemple -

reg c; // variable de registre unique à 1 bit

reg [5: 0] gemme; // un vecteur 6 bits;

reg [6: 0] d, e; // deux variables 7 bits

Entrée, sortie, entrée

Ces mots-clés sont utilisés pour déclarer les ports d'entrée, de sortie et bidirectionnels d'une tâche ou d'un module. Ici, les ports d'entrée et de sortie, qui sont de type filaire et le port de sortie est configuré pour être de type fil, reg, baguette, wor ou tri. Toujours, la valeur par défaut est le type de fil.

Example

Module sample(a, c, b, d);  
Input c;   // An input where wire is used. 

Output a, b;  // Two outputs where wire is used. 
Output [2:0] d;  /* A three-bit output. One must declare type in a separate statement. */ 
reg [1:0] a;  // The above ‘a’ port is for declaration in reg.

Entier

Les entiers sont utilisés dans les variables à usage général. Ils sont principalement utilisés dans les indications de boucles, les constantes et les paramètres. Ils sont de type de données de type «reg». Ils stockent les données sous forme de nombres signés, tandis que les types reg déclarés explicitement les stockent sous forme de données non signées. Si l'entier n'est pas défini au moment de la compilation, la taille par défaut serait de 32 bits.

Si un entier contient une constante, le synthétiseur les ajuste à la largeur minimale nécessaire au moment de la compilation.

Example

Integer c;   // single 32-bit integer 
Assign a = 63;  // 63 defaults to a 7-bit variable.

Approvisionnement0, Approvisionnement1

Supply0 définit les fils liés à la logique 0 (masse) et alimentation1 définit les fils liés à la logique 1 (alimentation).

Example

supply0 logic_0_wires; 
supply0 gnd1;  // equivalent to a wire assigned as 0 

supply1 logic_1_wires; 
supply1 c, s;

Temps

Le temps est une quantité de 64 bits qui peut être utilisée conjointement avec la tâche système $ time pour conserver le temps de simulation. Le temps n'est pas pris en charge pour la synthèse et n'est donc utilisé qu'à des fins de simulation.

Example

time time_variable_list; 
time c; 
c = $time;   //c = current simulation time

Paramètre

Un paramètre définit une constante qui peut être définie lorsque vous utilisez un module, ce qui permet la personnalisation du module pendant le processus d'instanciation.

Example 
Parameter add = 3’b010, sub = 2’b11; 
Parameter n = 3; 
Parameter [2:0] param2 = 3’b110; 

reg [n-1:0] jam; /* A 3-bit register with length of n or above. */ 
always @(z) 
y = {{(add - sub){z}};  

if (z)
begin 
   state = param2[1];
else
   state = param2[2]; 
end

Les opérateurs

Opérateurs arithmétiques

Ces opérateurs effectuent des opérations arithmétiques. Les + et −sont utilisés comme opérateurs unaires (x) ou binaires (z − y).

Les opérateurs qui sont inclus dans l'opération arithmétique sont -

+ (addition), - (soustraction), * (multiplication), / (division),% (module)

Example -

parameter v = 5;
reg[3:0] b, d, h, i, count; 
h = b + d; 
i = d - v; 
cnt = (cnt +1)%16; //Can count 0 thru 15.

Opérateurs relationnels

Ces opérateurs comparent deux opérandes et renvoient le résultat dans un seul bit, 1 ou 0.

Les variables Wire et Reg sont positives. Ainsi (−3'd001) = = 3'd111 et (−3b001)> 3b110.

Les Opérateurs qui sont inclus dans l'opération relationnelle sont -

  • == (égal à)
  • ! = (différent de)
  • > (supérieur à)
  • > = (supérieur ou égal à)
  • < (Inférieur à)
  • <= (inférieur ou égal à)

Example

if (z = = y) c = 1; 
   else c = 0; // Compare in 2’s compliment; d>b 
reg [3:0] d,b; 

if (d[3]= = b[3]) d[2:0] > b[2:0]; 
   else b[3]; 
Equivalent Statement 
e = (z == y);

Opérateurs bit par bit

Opérateurs bit par bit qui effectuent une comparaison bit par bit entre deux opérandes.

Les opérateurs qui sont inclus dans l'opération par bit sont -

  • & (ET au niveau du bit)
  • | (bit à bit OU)
  • ~ (PAS au niveau du bit)
  • ^ (XOR au niveau du bit)
  • ~ ^ ou ^ ~ (XNOR au niveau du bit)

Example

module and2 (d, b, c); 
input [1:0] d, b; 
output [1:0] c; 
assign c = d & b; 
end module

Opérateurs logiques

Les opérateurs logiques sont des opérateurs de bits et ne sont utilisés que pour les opérandes à un seul bit. Ils renvoient une valeur de bit unique, 0 ou 1. Ils peuvent travailler sur des entiers ou des groupes de bits, des expressions et traiter toutes les valeurs non nulles comme 1. Les opérateurs logiques sont généralement utilisés dans les instructions conditionnelles car ils fonctionnent avec des expressions.

Les opérateurs inclus dans l'opération logique sont -

  • ! (NON logique)
  • && (ET logique)
  • || (OU logique)

Example

wire[7:0] a, b, c; // a, b and c are multibit variables. 
reg x; 

if ((a == b) && (c)) x = 1; //x = 1 if a equals b, and c is nonzero. 
   else x = !a; // x =0 if a is anything but zero.

Opérateurs de réduction

Les opérateurs de réduction sont la forme unaire des opérateurs binaires et opèrent sur tous les bits d'un vecteur d'opérande. Ceux-ci renvoient également une valeur sur un seul bit.

Les opérateurs qui sont inclus dans l'opération de réduction sont -

  • & (réduction ET)
  • | (réduction OU)
  • ~ & (réduction NAND)
  • ~ | (réduction NOR)
  • ^ (réduction XOR)
  • ~ ^ ou ^ ~ (réduction XNOR)

Example

Module chk_zero (x, z); 

Input [2:0] x; 
Output z; 
Assign z = & x; // Reduction AND 
End module

Opérateurs de quart

Opérateurs de décalage, qui décalent le premier opérande du nombre de bits spécifié par le second opérande dans la syntaxe. Les postes vacants sont remplis de zéros pour les deux directions, les décalages gauche et droit (il n'y a pas d'extension de signe d'utilisation).

Les opérateurs qui sont inclus dans l'opération Shift sont -

  • << (décalage vers la gauche)
  • >> (décalage vers la droite)

Example

Assign z = c << 3; /* z = c shifted left 3 bits;

Les postes vacants sont pourvus de 0 * /

Opérateur de concaténation

L'opérateur de concaténation combine deux opérandes ou plus pour former un vecteur plus grand.

L'opérateur inclus dans l'opération de concaténation est - {} (concaténation)

Example

wire [1:0] a, h; wire [2:0] x; wire [3;0] y, Z; 
assign x = {1’b0, a}; // x[2] = 0, x[1] = a[1], x[0] = a[0] 
assign b = {a, h}; /* b[3] = a[1], b[2] = a[0], b[1] = h[1], 
b[0] = h[0] */ 
assign {cout, b} = x + Z; // Concatenation of a result

Opérateur de réplication

L'opérateur de réplication effectue plusieurs copies d'un élément.

L'opérateur utilisé dans l'opération de réplication est - {n {élément}} (réplication n fois d'un élément)

Example

Wire [1:0] a, f; wire [4:0] x; 
Assign x = {2{1’f0}, a}; // Equivalent to x = {0,0,a } 
Assign y = {2{a}, 3{f}}; //Equivalent to y = {a,a,f,f} 
For synthesis, Synopsis did not like a zero replication.

For example:- 
Parameter l = 5, k = 5; 
Assign x = {(l-k){a}}

Opérateur conditionnel

L'opérateur conditionnel synthétise vers un multiplexeur. Il est du même type que celui utilisé en C / C ++ et évalue l'une des deux expressions en fonction de la condition.

L'opérateur utilisé en opération conditionnelle est -

(État) ? (Résultat si la condition est vraie) -

(résultat si la condition est fausse)

Example

Assign x = (g) ? a : b; 
Assign x = (inc = = 2) ? x+1 : x-1; 
/* if (inc), x = x+1, else x = x-1 */

Opérandes

Littéraux

Les littéraux sont des opérandes à valeurs constantes utilisés dans les expressions Verilog. Les deux littéraux Verilog couramment utilisés sont -

  • String - Un opérande littéral de chaîne est un tableau unidimensionnel de caractères, qui sont placés entre guillemets ("").

  • Numeric - Un opérande de nombre constant est spécifié en nombre binaire, octal, décimal ou hexadécimal.

Example

n - entier représentant le nombre de bits

F - l'un des quatre formats de base possibles -

b pour binaire, o pour octal, d pour décimal, h pour hexadécimal.

“time is”  // string literal 
267        // 32-bit decimal number 
2’b01      // 2-bit binary 
20’hB36F   // 20-bit hexadecimal number 
‘062       // 32-bit octal number

Fils, regs et paramètres

Les fils, regs et paramètres sont les types de données utilisés comme opérandes dans les expressions Verilog.

Sélection de bit "x [2]" et sélection de partie "x [4: 2]"

Les sélections de bits et les sélections partielles sont utilisées pour sélectionner respectivement un bit et plusieurs bits à partir d'un vecteur de fil, de reg ou de paramètre avec l'utilisation de crochets «[]». Les sélections de bits et les sélections partielles sont également utilisées comme opérandes dans les expressions de la même manière que leurs principaux objets de données sont utilisés.

Example

reg [7:0] x, y; 
reg [3:0] z; 
reg a; 
a = x[7] & y[7];      // bit-selects 
z = x[7:4] + y[3:0];  // part-selects

Appels de fonction

Dans les appels de fonction, la valeur de retour d'une fonction est utilisée directement dans une expression sans qu'il soit nécessaire de l'affecter au préalable à un registre ou à un câble. Il suffit de placer l'appel de fonction comme l'un des types d'opérandes. Il est nécessaire de s'assurer que vous connaissez la largeur en bits de la valeur de retour de l'appel de fonction.

Example  
Assign x = y & z & chk_yz(z, y); // chk_yz is a function 

. . ./* Definition of the function */ 
Function chk_yz; // function definition 
Input z,y; 
chk_yz = y^z; 
End function

Modules

Déclaration du module

Dans Verilog, un module est la principale entité de conception. Cela indique le nom et la liste des ports (arguments). Les quelques lignes suivantes qui spécifient le type d'entrée / sortie (entrée, sortie ou inout) et la largeur de chaque port. La largeur de port par défaut n'est que de 1 bit. Les variables de port doivent être déclarées par fil, baguette ,. . ., reg. La variable de port par défaut est wire. Normalement, les entrées sont câblées car leurs données sont verrouillées à l'extérieur du module. Les sorties sont de type reg si leurs signaux sont stockés à l'intérieur.

Example

module sub_add(add, in1, in2, out); 
input add; // defaults to wire 
input [7:0] in1, in2; wire in1, in2; 

output [7:0] out; reg out; 
... statements ... 
End module

Affectation continue

L'affectation continue dans un module est utilisée pour attribuer une valeur à un fil, qui est l'affectation normale utilisée à l'extérieur des blocs toujours ou initiaux. Cette affectation se fait avec une instruction d'affectation explicite ou pour affecter une valeur à un fil lors de sa déclaration. Les affectations continues sont exécutées en continu au moment de la simulation. L'ordre des instructions d'assignation ne l'affecte pas. Si vous modifiez l'un des signaux d'entrée du côté droit, le signal de sortie du côté gauche sera modifié.

Example

Wire [1:0] x = 2’y01;   // assigned on declaration 
Assign y = c | d;       // using assign statement 
Assign d = a & b; 
/* the order of the assign statements does not matter. */

Instanciations de module

Les déclarations de module sont des modèles pour créer des objets réels. Les modules sont instanciés à l'intérieur d'autres modules, et chaque instanciation crée un seul objet à partir de ce modèle. L'exception est le module de niveau supérieur qui est sa propre instanciation. Les ports du module doivent correspondre à ceux définis dans le modèle. Il est précisé -

  • By name, en utilisant un point «.template port name (nom du fil connecté au port)». Ou

  • By position, en plaçant les ports au même endroit dans les listes de ports du modèle et de l'instance.

Example

MODULE DEFINITION 
Module and4 (x, y, z); 
Input [3:0] x, y; 
Output [3:0] z; 
Assign z = x | y; 
End module