Sequentiële logica met altijd
Een vorig artikel toonde verschillende voorbeelden van het gebruik van een always
blok om combinatorische logica te implementeren. Een always
blok wordt ook voornamelijk gebruikt om sequentiële . te implementeren logica met geheugenelementen zoals flip-flops die waarden kunnen bevatten.
JK-teenslipper
Een JK-flip-flop is een van de vele soorten flops die worden gebruikt om waarden op te slaan en heeft twee data-ingangen j en k, samen met een voor reset rstn en een andere voor klok clk. De waarheidstabel voor een JK-flop wordt hieronder getoond en wordt meestal geïmplementeerd met behulp van NAND-poorten.
rstn | j | k | q | Opmerkingen |
---|---|---|---|---|
0 | 0 | 0 | 0 | Als reset wordt uitgevoerd, is de output altijd nul |
1 | 0 | 0 | Waarde vasthouden | Als zowel j als k 0 zijn, blijft de uitvoer hetzelfde als voorheen |
1 | 0 | 1 | 1 | Als k=1, wordt de output 1 |
1 | 1 | 0 | 0 | Als k=0, wordt de output 0 |
1 | 1 | 1 | Toggle waarde | Als j=1,k=1 uitgang wisselt van huidige waarde |
De gedragscode van Verilog voor een JK-flip-flop kan worden geschreven zoals hieronder weergegeven
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
Testbank
Declareer eerst alle variabelen die in de testbench worden gebruikt en start een klok met een simpele always
blok dat naar het ontwerp kan worden gereden. Instantieer vervolgens het ontwerp en verbind de poorten met de bijbehorende testbench-variabelen. Merk op dat q van het type wire
. is omdat het is verbonden met een uitgang van het ontwerp die het actief zal aansturen. Alle andere inputs voor het ontwerp zijn van het type reg
zodat ze kunnen worden gereden binnen een procedureel blok zoals initial
.
De stimulus initialiseert eerst alle invoer naar het ontwerp naar nul en wordt vervolgens na enige tijd opnieuw ingesteld. Een for
lus wordt gebruikt om verschillende waarden naar j en k te sturen die op willekeurige tijden worden aangestuurd. Als de lus klaar is, wacht je nog even en voltooi je de simulatie.
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
Merk op uit de simulatiegolf dat op het moment van de klok, output q van waarde verandert op basis van de status van inputs j en k zoals gegeven in de waarheidstabel.
Modulo-10-teller
Modulus (MOD)-tellers tellen gewoon tot een bepaald aantal voordat ze teruggaan naar nul. Een MOD-N-teller telt van 0 tot N-1 en keert dan terug naar nul en begint opnieuw te tellen. Dergelijke tellers vereisen doorgaans log2 N aantal flops om de telwaarde vast te houden. Hieronder wordt de Verilog-code weergegeven voor een MOD-10-teller die bij elke klokklok blijft optellen zolang reset rstn niet is bevestigd.
Verilog-parameters kunnen worden gebruikt om een MOD-N-teller te maken die beter schaalbaar is.
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
Testbank
De testbench declareert eerst enkele variabelen waaraan enkele waarden kunnen worden toegewezen en die naar de ontwerpinvoer kunnen worden gestuurd. De tellermodule wordt dan geïnstantieerd en verbonden met de testbanksignalen die later worden aangestuurd met enkele waarden in de stimulus. Omdat de teller ook een klok nodig heeft, is de testbankklok gemodelleerd met een always
blok. De stimulus stelt eenvoudig de standaardwaarden in op tijd 0ns, wordt vervolgens na 10ns opnieuw ingesteld en het ontwerp mag enige tijd worden uitgevoerd.
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
Zie dat de tellermodule telt van nul tot 9, rolt naar nul en begint opnieuw te tellen.
4bit Left Shift Register
Hieronder wordt een 4-bit linker schuifregister weergegeven dat een invoer d in LSB accepteert en alle andere bits worden met 1 naar links verschoven. Als d bijvoorbeeld gelijk is aan nul en de beginwaarde van het register 0011 is, wordt het 0110 bij de volgende rand van de klok klikt.
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
Testbank
De testbench volgt een soortgelijk sjabloon als het eerder getoonde, waar enkele variabelen worden gedeclareerd, de ontwerpmodule wordt geïnstantieerd en verbonden met de testbench-signalen. Vervolgens wordt een klok gestart en wordt de stimulus naar het ontwerp gestuurd met behulp van een initial
blok. In dit testbench-voorbeeld moeten verschillende waarden van d worden uitgeoefend en dus een for
lus wordt gebruikt om 20 keer te herhalen en willekeurige waarden toe te passen op het ontwerp.
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
Merk op dat elk bit met 1 naar links wordt verschoven en dat de nieuwe waarde van d wordt toegepast op LSB.
Verilog
- Tutorial - Combinatie- en sequentiële code schrijven
- Circuit met een schakelaar
- Geïntegreerde circuits
- Programmable Logic Controllers (PLC)
- Inleiding tot Booleaanse algebra
- Logische vereenvoudiging met Karnaugh-kaarten
- Digitale logica met feedback
- Een RRAM-geïntegreerde 4T SRAM met zelfremmende resistieve schakelbelasting door puur CMOS logisch proces
- Verilog Mod-N-teller
- Verilog grijze toonbank
- Altijd een gladde afwerking met Okamoto-slijpmachines