Johnson Counter (/verilog/verilog-johnson-counter)
Mod-N Counter (/verilog/verilog-modn-counter)
Gray Counter (/verilog/verilog-gray-counter)
Misc
n-bit Shift Register (/verilog/verilog-n-bit-shift-register)
Priority Encoder (/verilog/verilog-priority-encoder)
4x1 multiplexer (/verilog/verilog-4to1-mux)
Full adder (/verilog/verilog-full-adder)
Single Port RAM (/verilog/verilog-single-port-ram)
4-bit counter
The 4-bit counter starts incrementing from 4'b0000 to 4'h1111
and then rolls over back to 4'b0000. It will keep counting as
long as it is provided with a running clock and reset is held
high.
The rollover happens when the most significant bit of the final
addition gets discarded. When counter is at a maximum value
of 4'b1111 and gets one more count request, the counter tries
to reach 5'b10000 but since it can support only 4-bits, the
MSB will be discarded resulting in 0.
0000
0001
0010
...
1110
1111
rolls over
0000
0001
...
The design contains two inputs one for the clock and another
for an active-low reset. An active-low reset is one where the
design is reset when the value of the reset pin is 0. There is a
4-bit output called out which essentially provides the counter
values.
(/images/verilog/4-bit_counter_1.png)
Electronic Counter Design
1 module counter ( input clk, // Dec
2 input rstn, // Dec
3 output reg[3:0] out); // Dec
4
5 // This always block will be triggered at the r
6 // Once inside this block, it checks if the res
7 // If reset is 1, then design should be allowed
8 always @ (posedge clk) begin
9 if (! rstn)
10 out <= 0;
11 else
12 out <= out + 1;
13 end
14 endmodule
The module counter has a clock and active-low reset
(denoted by n) as inputs and the counter value as a 4-bit
output. The always block is always executed whenever the
clock transitions from 0 to 1 which signifies a rising edge or a
positive edge. The output is incremented only if reset is held
high or 1, achieved by the if-else block. If reset is found
to be low at the positive edge of clock, then output is reset to
a default value of 4'b0000.
Testbench
We can instantiate the design into our testbench module to
verify that the counter is counting as expected.
(/images/verilog/4-bit_counter_2.png)
The testbench module is named tb_counter and ports are not
required since this is the top-module in simulation. However
we do need to have internal variables to generate, store and
drive clock and reset. For that purpose, we have declared two
variables of type reg for clock and reset. We also need a
wire type net to make the connection with the design's
output, else it will default to a 1-bit scalar net.
Clock is generated via always block which will give a period
of 10 time units. The initial block is used to set initial
values to our internal variables and drive the reset value to
the design. The design is instantiated in the testbench and
connected to our internal variables, so that it will get the
values when we drive them from the testbench. We don't have
any $display statements in our testbench and hence we
will not see any message in the console.
1 module tb_counter;
2 reg clk; // Declare an inte
3 reg rstn; // Declare an inte
4 wire [3:0] out; // Declare a wire
5
6 // Instantiate counter design and connect with
7 counter c0 ( .clk (clk),
8 .rstn (rstn),
9 .out (out));
10
11 // Generate a clock that should be driven to de
12 // This clock will flip its value every 5ns ->
13 always #5 clk = ~clk;
14
15 // This initial block forms the stimulus of the
16 initial begin
17 // 1. Initialize testbench variables to 0 at
18 clk <= 0;
19 rstn <= 0;
20
21 // 2. Drive rest of the stimulus, reset is as
22 #20 rstn <= 1;
23 #80 rstn <= 0;
24 #50 rstn <= 1;
25
26 // 3. Finish the stimulus after 200ns
27 #20 $finish;
28 end
29 endmodule
Simulation Log
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
(/images/verilog/waves/4-bit-counter-wave.PNG)
Note that the counter resets to 0 when the active-low reset
becomes 0, and when reset is de-asserted at around 150ns,
the counter starts counting from the next occurence of the
positive edge of clock.
Hardware Schematic
(/images/verilog/schematic/4b_counter_schematic.png)
© 2015 - 2021 ChipVerify
Contact (/contact-us) | Privacy Policy (/info/privacy-policy) | Terms &
Conditions (/info/terms-and-conditions)