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..

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.

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
```

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.