Design a 2 Bit Counter That When X 1 Continue Otherwise Hold
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.
Electronic Counter Design
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
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.
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.
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
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
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
spellmanbince1936.blogspot.com
Source: https://www.chipverify.com/verilog/verilog-4-bit-counter
0 Response to "Design a 2 Bit Counter That When X 1 Continue Otherwise Hold"
Post a Comment