4-Bit-Zähler
Der 4-Bit-Zähler beginnt von 4'b0000 bis 4'h1111 zu inkrementieren und springt dann zurück auf 4'b0000. Es zählt weiter, solange es mit einer laufenden Uhr versehen ist und Reset hoch gehalten wird.
Der Rollover findet statt, wenn das signifikanteste Bit der letzten Addition verworfen wird. Wenn der Zähler einen Maximalwert von 4'b1111 erreicht hat und eine weitere Zählanforderung erhält, versucht der Zähler, 5'b10000 zu erreichen, aber da er nur 4 Bits unterstützen kann, wird das MSB verworfen, was zu 0 führt.
0000 0001 0010 ... 1110 1111 rolls over 0000 0001 ...
Das Design enthält zwei Eingänge, einen für die Uhr und einen weiteren für einen Aktiv-Low-Reset. Bei einem Active-Low-Reset wird das Design zurückgesetzt, wenn der Wert des Reset-Pins 0 ist. Es wird ein 4-Bit-Ausgang aufgerufen, der im Wesentlichen die Zählerwerte liefert.
Elektronisches Zählerdesign
module counter ( input clk, // Declare input port for clock to allow counter to count up
input rstn, // Declare input port for reset to allow the counter to be reset to 0 when required
output reg[3:0] out); // Declare 4-bit output port to get the counter values
// This always block will be triggered at the rising edge of clk (0->1)
// Once inside this block, it checks if the reset is 0, if yes then change out to zero
// If reset is 1, then design should be allowed to count up, so increment counter
always @ (posedge clk) begin
if (! rstn)
out <= 0;
else
out <= out + 1;
end
endmodule
Der module
Counter hat eine Uhr und einen Active-Low-Reset (gekennzeichnet durch n ) als Eingänge und der Zählerwert als 4-Bit-Ausgang. Die always
block ist immer ausgeführt, wenn der Takt von 0 auf 1 übergeht, was eine steigende Flanke oder eine positive Flanke bedeutet. Der Ausgang wird nur erhöht, wenn Reset hoch oder 1 gehalten wird, was durch if-else
erreicht wird Block. Wenn festgestellt wird, dass reset an der positiven Flanke von clock niedrig ist, wird der Ausgang auf einen Standardwert von 4'b0000 zurückgesetzt.
Testbench
Wir können das Design in unserem Testbench-Modul instanziieren, um zu überprüfen, ob der Zähler wie erwartet zählt.
Das Testbench-Modul heißt tb_counter und Ports sind nicht erforderlich, da dies das Top-Modul in der Simulation ist. Wir benötigen jedoch interne Variablen zum Generieren, Speichern und Ansteuern der Uhr und zum Zurücksetzen. Dazu haben wir zwei Variablen vom Typ reg
deklariert für Uhr und Reset. Außerdem benötigen wir eine wire
Geben Sie net ein, um die Verbindung mit der Ausgabe des Designs herzustellen, andernfalls wird standardmäßig ein 1-Bit-Skalarnetz verwendet.
Die Uhr wird über always
generiert Block, der einen Zeitraum von 10 Zeiteinheiten ergibt. Die initial
Block wird verwendet, um Anfangswerte für unsere internen Variablen festzulegen und den Rücksetzwert auf das Design zu steuern. Das Design wird instanziiert in der Testbench gespeichert und mit unseren internen Variablen verbunden, sodass es die Werte erhält, wenn wir sie von der Testbench aus steuern. Wir haben keine $display
Anweisungen in unserer Testbench und daher sehen wir keine Meldung in der Konsole.
module tb_counter;
reg clk; // Declare an internal TB variable called clk to drive clock to the design
reg rstn; // Declare an internal TB variable called rstn to drive active low reset to design
wire [3:0] out; // Declare a wire to connect to design output
// Instantiate counter design and connect with Testbench variables
counter c0 ( .clk (clk),
.rstn (rstn),
.out (out));
// Generate a clock that should be driven to design
// This clock will flip its value every 5ns -> time period = 10ns -> freq = 100 MHz
always #5 clk = ~clk;
// This initial block forms the stimulus of the testbench
initial begin
// 1. Initialize testbench variables to 0 at start of simulation
clk <= 0;
rstn <= 0;
// 2. Drive rest of the stimulus, reset is asserted in between
#20 rstn <= 1;
#80 rstn <= 0;
#50 rstn <= 1;
// 3. Finish the stimulus after 200ns
#20 $finish;
end
endmodule
Simulationsprotokoll ncsim> run [0ns] clk=0 rstn=0 out=0xx [5ns] clk=1 rstn=0 out=0x0 [10ns] clk=0 rstn=0 out=0x0 [15ns] clk=1 rstn=0 out=0x0 [20ns] clk=0 rstn=1 out=0x0 [25ns] clk=1 rstn=1 out=0x1 [30ns] clk=0 rstn=1 out=0x1 [35ns] clk=1 rstn=1 out=0x2 [40ns] clk=0 rstn=1 out=0x2 [45ns] clk=1 rstn=1 out=0x3 [50ns] clk=0 rstn=1 out=0x3 [55ns] clk=1 rstn=1 out=0x4 [60ns] clk=0 rstn=1 out=0x4 [65ns] clk=1 rstn=1 out=0x5 [70ns] clk=0 rstn=1 out=0x5 [75ns] clk=1 rstn=1 out=0x6 [80ns] clk=0 rstn=1 out=0x6 [85ns] clk=1 rstn=1 out=0x7 [90ns] clk=0 rstn=1 out=0x7 [95ns] clk=1 rstn=1 out=0x8 [100ns] clk=0 rstn=0 out=0x8 [105ns] clk=1 rstn=0 out=0x0 [110ns] clk=0 rstn=0 out=0x0 [115ns] clk=1 rstn=0 out=0x0 [120ns] clk=0 rstn=0 out=0x0 [125ns] clk=1 rstn=0 out=0x0 [130ns] clk=0 rstn=0 out=0x0 [135ns] clk=1 rstn=0 out=0x0 [140ns] clk=0 rstn=0 out=0x0 [145ns] clk=1 rstn=0 out=0x0 [150ns] clk=0 rstn=1 out=0x0 [155ns] clk=1 rstn=1 out=0x1 [160ns] clk=0 rstn=1 out=0x1 [165ns] clk=1 rstn=1 out=0x2 Simulation complete via $finish(1) at time 170 NS + 0
Beachten Sie, dass der Zähler auf 0 zurückgesetzt wird, wenn der Active-Low-Reset 0 wird, und wenn der Reset bei etwa 150 ns deaktiviert wird, beginnt der Zähler mit dem Zählen ab dem nächsten Auftreten der positiven Taktflanke.
Hardware-Schema
Verilog