Home > Uncategorized > Level change detection in Verilog

Level change detection in Verilog

September 25th, 2015

A level detector detects the change is the level, either from high to low or from low to high and takes some action based upon the change in the level. We will develop a circuit that will detect a level change from high to low. It will give an output high for a duration of one clock cycle for every change from high to low.

The basic concept is simple. Consider the moment the Input has just changed from High to low. The diagram below shows the implementation of the high to low level change detector..

EdgeDetector_circuit

The present output level_out depends upon

1. The present input
2. The input one clock cycle earlier.

The level_out, when the present input is 1, is zero because it inverts the present input and ANDs with the input a clock cycle earlier. Now consider the moment the input level switched from high to low somewhere in the middle of clock at the point shown in the diagram below.

EdgeDetector1

In the diagram above, the delay_reg represents the output of the flip flop. When the input level goes 0, the output of the NOT gate turns high. This is ANDed with the level_in in previous clock cycle - which was one. The result is a logic high level_out. This logic high stays only till the next rising edge of the clock. At the next rising edge of clock

This is the verilog implementation of this scheme.

module  edgedetect 
	(
	input 	wire level_in, clk, n_reset,	// inputs
	output wire level_out
	);
	reg  delay_reg  ;
	always @(posedge  clk,  negedge  n_reset)
	if  ( n_reset == 0)
	delay_reg  <=  0;
	else
	delay_reg  <=  level_in;
	assign  level_out  =  (delay_reg)  &  (~level_in);
	endmodule

The following test bench can be used to verify the circuit.

`timescale 1 us / 1 us
 
module tb_edgedetect();
    reg clk;
    reg n_reset;
    reg level_in;
    wire level_out;
 
    edgedetect UUT (
        .clk(clk), 
        .n_reset(n_reset), 
        .level_in(level_in),
        .level_out(level_out)
        );
 
 
    initial begin
            clk = 1'b0;
            n_reset = 1'b1;
            #5 n_reset = 1'b0;  
			#10 n_reset = 1'b1;
            level_in = 1'b1;
            #25 level_in = 1'b0; 
            #40 level_in = 1'b1;            
            #80 level_in = 1'b0;   
            #20 level_in = 1'b1;       
            #80 level_in = 1'b0;
            #40 level_in = 1'b1;
            #40 level_in = 1'b0;     
            #40 level_in = 1'b1;
            $finish;
    end
    always
            #10 clk = ~clk;  // 20 mirco seconds = 50 KHz Clock cycle   
 
initial
      begin
      $dumpfile ("edgedetect.vcd");
      $dumpvars (0,tb_edgedetect);
      end
endmodule

EdgeDetector

Concern

The tick output may be smaller that one clock cycle period. Which makes it faster, but at the same time, less useful, you you wish to do some synchronous task based upon the tick. One way to fix it may be the insertion of two flip flops in place of one flip flop between level_in and level_out.

Some Exercise for readers

For a better understanding, do the following exercizes

1. What change will be required to implement a low to high in place of high to low level detection.
2. Change the code so that it generates a tick on both level changes high to low as well as low to high.
3. Develop the code for a Moore Machine.
4. Implement a 4 bit counter that counts from 0 to 9 and then to 0 on each high to low level change.

Uncategorized

  1. Rana Ihtsham
    May 15th, 2017 at 21:56 | #1

    I was searching for this code. As my instructor gave me this as an assignment. Hoping that this code should work!

  1. No trackbacks yet.