Verilog Examples - LED blinkning by clock divider

We will now extend out clock Divide by 2N code to blink and LED. Basically we will set the parameters of the clock divider. We will also examine the issue with large data generated in test bench.

Problem - Write verilog code that has a 50 MHz clock and a reset as input. It has an output that can be called clk_out. The clk_out is also a clock that has a frequency of 2.5 Hz of time period of 400 ms. Extend the parameter to calculate the values for the parameter for 1 Hz clk_out.

Solution -

This is the main code ledblink.v

 // LED Blinking Example by Clock Divider// referencedesigner.com tutorial  module clk_div #( parameter WIDTH = 24, // Width of the register requiredparameter [WIDTH-1:0] N = 24'h989680// That is 10,000,000 in decimal)/* We will divide 50 MHz by 20,000,000 ( We are dividing by 2N - which gives 2.5 Hz signal or time period of 400 ms or half time period of 200 ms*/ //Changing N to 25,000,000 or 0x17D7840 will generate a 1 Hz Signal// Increases simulation time  (clk,reset, clk_out); input clk;input reset;output clk_out; reg [WIDTH-1:0] r_reg;wire [WIDTH-1:0] r_nxt;reg clk_track; always @(posedge clk or posedge reset) begin if (reset) begin r_reg <= 0; clk_track <= 1'b0; end  else if (r_nxt == N) begin r_reg <= 0; clk_track <= ~clk_track; end  else r_reg <= r_nxt;end  assign r_nxt = r_reg+1; assign clk_out = clk_track;endmodule

Here is the test bench ledblinktb.v

 `timescale 10ns/1ns module clkdiv2n_tb; reg clk,reset; wire clk_out;  clk_div t1(clk,reset,clk_out); initial clk= 1'b0; always #1 clk=~clk; initial begin #2 reset=1'b1; #3 reset=1'b0; #40000000 #20 \$finish; end  initial \$monitor(\$time, " reset=%b,clk_out=%b",reset,clk_out); initial begin \$dumpfile("clkdiv2n_tb.vcd"); \$dumpvars(1,clk_out); // To reduce file size we are only monitoring clk_out  end endmodule

The waveform generated by this code is here Explanation

The value of the divider 2N to generate 2.5 Hz clock is 20,000,000 which gives N = 10,000,000. In hexadecimal it is 24'h989680. We calculated hex value to find the number of bits required for the register.

 module clk_div #( parameter WIDTH = 24, parameter [WIDTH-1:0] N = 24'h989680 )

In test bench we did monitor clk as it will generate huge output without much value. We can run it just once to make sure that it is 50 MHz. Also note that we have set the timescale to 10 ns which is half clock period.

 \$monitor(\$time, " reset=%b,clk_out=%b",reset,clk_out);

In the \$dumpvars we are dumping only the clk_out as in

 \$dumpvars(1,clk_out);

If we would have done

 \$dumpvars(0,clkdiv2n_tb);

It would have dumped all variables including the clk which will make the size of the dump file unnecessarily large. The reset of the code should be easy to understand