FSM Based Dual Edge Detector

Verilog Programming

Edge detector waveform

Edge detectors can be realized using many circuits in digital electronics. Here we will try to create a dual edge detector using FSM(Finite state Machine).

Basically, we are trying to detect the rising as well as falling edges of the input signal. These type of designs are important when our application is event driven or where we need to validate the data transfer, etc.

FSM chart:

Moore based FSM Chart for dual edge detector

There are two types of FSM :

  • Moore based FSM
  • Mealy Based FSM

Basically, in Moore based design the output depends only on the current state of the state register, while in Mealy Based design the output depends on both the current state as well as the input logic.

Anyway, the concept of FSM demands a completely new series of blogs which I’ll be working on soon.

Here, in this above example we can clearly see the logic flow of the FSM chart.

Verilog Code:

The code is divided into three different parts

  • next-state logic
  • state register
  • output logic
module dual_edge_detector (
    input wire clk, reset, 
    input wire level, // input signal
    output reg tick1, tick2// the alert signals for rising and falling edge resp.
);
    // all states of the state machine
    localparam [1:0] zero=2'b00, edge1=2'b01, edge2=2'b10, one=2'b11;

    // register required in the FSM
    reg [1:0] state_next, state_reg;

    // state register
    always @(posedge clk, posedge reset)
        if(reset)
            state_reg <= zero;
        else
            state_reg <= state_next;

    // next state logic and output logic
    always @* begin
        // default values
        state_next = state_reg;
        tick1 = 1'b0;
        tick2 = 1'b0;
        case (state_reg)
            zero : 
                if (level) begin
                    state_next = edge1;
                    tick1 = 1'b1;
                end
                else
                    state_next = zero;
            edge1 :
                if (level)
                    state_next = one;
                else
                    state_next = zero;
            one :
                if (~level) begin
                    state_next = edge2;
                    tick2 = 1'b1;
                end
                else
                    state_next = one;
            edge2 :
                if (level) 
                    state_next = one;
                else
                    state_next = zero;
            default: state_next = zero;
        endcase
    end
endmodule

RTL view

Generated using Xilinx ISE

Testbench

Apparently, there are many ways of writing a testbench for such a design. Here, I have tried to write a version, however it is not all, you can always come up with a better testbench and improve the design.

module dual_edge_tb;
    reg clk;
    reg reset;
    reg level;
    wire tick1, tick2;

    // instantiate the design
    dual_edge_detector d1(.clk(clk), 
                          .reset(reset), 
                          .level(level), 
                          .tick1(tick1), .tick2(tick2));

    // initialize the clock
    initial clk = 1'b0;

    always #20 clk = ~clk;

    initial begin
        reset = 1'b1; level = 1'b0;
        #35 reset = 1'b0; level = 1'b0;
        #115 level = 1'b1;
        #90 level = 1'b0;
        #80 level = 1'b1;
        #90 level = 1'b0;
        #80 level = 1'b1;
        #100 level = 1'b0;
    end

endmodule

Stimulation

This is the stimulation of the following design with the give testbench.

Generated using Xilinx ISE

Here, we can see that the tick1 goes high when the design detects a transition from zero to one, whereas the tick2 goes high when the design detects a transition from one to zero.

Great!!😎😎