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.
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.
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
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
This is the stimulation of the following design with the give testbench.
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.