Logique séquentielle avec toujours
Un article précédent montrait différents exemples d'utilisation d'un always
bloc pour implémenter la logique combinatoire. Un always
Le bloc est également principalement utilisé pour implémenter séquentiel logique qui a des éléments de mémoire comme des bascules qui peuvent contenir des valeurs.
Tongs JK
Une bascule JK est l'un des nombreux types de bascules utilisées pour stocker des valeurs et possède deux entrées de données j et k avec une pour la réinitialisation rstn et une autre pour l'horloge clk. La table de vérité d'un flop JK est illustrée ci-dessous et est généralement implémentée à l'aide de portes NAND.
rstn | j | k | q | Commentaires |
---|---|---|---|---|
0 | 0 | 0 | 0 | Lorsque la réinitialisation est affirmée, la sortie est toujours zéro |
1 | 0 | 0 | Conserver la valeur | Lorsque j et k valent 0, la sortie reste la même qu'avant |
1 | 0 | 1 | 1 | Lorsque k=1, la sortie devient 1 |
1 | 1 | 0 | 0 | Lorsque k=0, la sortie devient 0 |
1 | 1 | 1 | Basculer la valeur | Lorsque j=1,k=1 la sortie bascule la valeur actuelle |
Le code comportemental Verilog pour une bascule JK peut être écrit comme indiqué ci-dessous
module jk_ff ( input j, // Input J
input k, // Input K
input rstn, // Active-low async reset
input clk, // Input clk
output reg q); // Output Q
always @ (posedge clk or negedge rstn) begin
if (!rstn) begin
q <= 0;
end else begin
q <= (j & ~q) | (~k & q);
end
end
endmodule
Banc de test
Déclarez d'abord toutes les variables utilisées dans le testbench et démarrez une horloge en utilisant un simple always
bloc qui peut être entraîné à la conception. Ensuite, instanciez la conception et connectez ses ports aux variables de banc de test correspondantes. Notez que q est de type wire
car il est connecté à une sortie de la conception qui le pilotera activement. Toutes les autres entrées de la conception sont de type reg
afin qu'ils puissent être pilotés dans un bloc procédural tel que initial
.
Le stimulus initialise d'abord toutes les entrées de la conception à zéro, puis désactive la réinitialisation après un certain temps. Un for
La boucle est utilisée pour conduire différentes valeurs à j et k qui sont pilotées à des moments aléatoires. Une fois la boucle terminée, attendez encore un peu et terminez la simulation.
module tb;
// Declare testbench variables
reg j, k, rstn, clk;
wire q;
integer i;
reg [2:0] dly;
// Start the clock
always #10 clk = ~clk;
// Instantiate the design
jk_ff u0 ( .j(j), .k(k), .clk(clk), .rstn(rstn), .q(q));
// Write the stimulus
initial begin
{j, k, rstn, clk} <= 0;
#10 rstn <= 1;
for (i = 0; i < 10; i = i+1) begin
dly = $random;
#(dly) j <= $random;
#(dly) k <= $random;
end
#20 $finish;
end
endmodule
Notez à partir de l'onde de simulation qu'au bord posé de l'horloge, la sortie q change de valeur en fonction de l'état des entrées j et k comme indiqué dans la table de vérité.
Compteur modulo-10
Les compteurs de module (MOD) comptent simplement jusqu'à un certain nombre avant de revenir à zéro. Un compteur MOD-N comptera de 0 à N-1, puis reviendra à zéro et recommencera à compter. Ces compteurs nécessitent généralement log2 N nombre de flops pour contenir la valeur de comptage. Vous trouverez ci-dessous le code Verilog d'un compteur MOD-10 qui continue de compter à chaque clk d'horloge tant que reset rstn est désactivé.
Les paramètres Verilog peuvent être utilisés pour créer un compteur MOD-N plus évolutif.
module mod10_counter ( input clk,
input rstn,
output reg[3:0] out);
always @ (posedge clk) begin
if (!rstn) begin
out <= 0;
end else begin
if (out == 10)
out <= 0;
else
out <= out + 1;
end
end
endmodule
Banc de test
Le testbench déclare d'abord certaines variables qui peuvent être affectées à certaines valeurs et pilotées vers les entrées de conception. Le module de compteur est ensuite instancié et connecté aux signaux du banc d'essai qui sont ensuite pilotés avec certaines valeurs dans le stimulus. Étant donné que le compteur nécessite également une horloge, l'horloge du banc de test est modélisée avec un always
bloquer. Le stimulus définit simplement les valeurs par défaut au temps 0ns, puis désactive la réinitialisation après 10ns et la conception est autorisée à s'exécuter pendant un certain temps.
module tb;
reg clk, rstn;
reg [3:0] out;
mod10_counter u0 ( .clk(clk), .rstn(rstn), .out(out));
always #10 clk = ~clk;
initial begin
{clk, rstn} <= 0;
#10 rstn <= 1;
#450 $finish;
end
endmodule
Vérifiez que le module compteur compte de zéro à 9, revient à zéro et recommence à compter.
Registre à décalage gauche 4 bits
Ci-dessous, un registre à décalage à gauche de 4 bits qui accepte une entrée d dans LSB et tous les autres bits seront décalés vers la gauche de 1. Par exemple, si d est égal à zéro et que la valeur initiale du registre est 0011, il deviendra 0110 à le bord suivant de l'horloge clk.
module lshift_4b_reg ( input d,
input clk,
input rstn,
output reg [3:0] out
);
always @ (posedge clk) begin
if (!rstn) begin
out <= 0;
end else begin
out <= {out[2:0], d};
end
end
endmodule
Banc de test
Le testbench suit un modèle similaire à celui présenté précédemment où certaines variables sont déclarées, le module de conception est instancié et connecté aux signaux du testbench. Ensuite, une horloge est démarrée et le stimulus est dirigé vers la conception à l'aide d'un initial
bloquer. Dans cet exemple de testbench, différentes valeurs de d doivent être exercées et donc un for
boucle est utilisée pour itérer 20 fois et appliquer des valeurs aléatoires à la conception.
module tb;
reg clk, rstn, d;
wire [3:0] out;
integer i;
lshift_4b_reg u0 ( .d(d), .clk(clk), .rstn(rstn), .out(out));
always #10 clk = ~clk;
initial begin
{clk, rstn, d} <= 0;
#10 rstn <= 1;
for (i = 0; i < 20; i=i+1) begin
@(posedge clk) d <= $random;
end
#10 $finish;
end
endmodule
Notez que chaque bit est décalé vers la gauche de 1 et la nouvelle valeur de d est appliquée au LSB.
Verilog
- Tutoriel - Écriture de code combinatoire et séquentiel
- Circuit avec interrupteur
- Circuits intégrés
- Contrôleurs logiques programmables (PLC)
- Introduction à l'algèbre booléenne
- Simplification de la logique avec Karnaugh Maps
- Compteur Verilog Mod-N
- Comptoir gris Verilog
- Toujours une finition lisse avec les rectifieuses Okamoto