Neela Lohith
Neela Lohith

Reputation: 21

How to write a synthesizable RTL that can count rise and fall of a signal

I want to measure the number of rise transitions and fall transitions of a signal. I am using the signal as a clock and implemented 2 counters. One counter increments on every rising edge and another increments on every falling edge. I am adding the result of these 2 counters to get the final count value.

Is there a better way to implement this logic ? What is the most robust method ?

module clock_edge_counter    (
clock_edge_count,    // Output of the counter  , 
clk     ,          // clock Input
stop ,
reset 
);

parameter CNTR_WIDTH = 16;

input clk ;
input stop ;
input reset ;

output [CNTR_WIDTH:0] clock_edge_count;
wire [CNTR_WIDTH:0] clock_edge_count;


reg [CNTR_WIDTH-1:0] clock_negedge_edge_count;
reg [CNTR_WIDTH-1:0] clock_posedge_edge_count;


always @(posedge clk or posedge reset)
 if (reset) begin
   clock_posedge_edge_count <= 0;
 end
 else if (!stop) begin
   clock_posedge_edge_count <= clock_posedge_edge_count + 1;
 end

always @(negedge clk or posedge reset)
 if (reset) begin
   clock_negedge_edge_count <= 0;
 end
 else if (!stop) begin
   clock_negedge_edge_count <= clock_negedge_edge_count + 1;
 end


assign clock_edge_count = clock_negedge_edge_count + clock_posedge_edge_count;

endmodule

Upvotes: 1

Views: 2371

Answers (1)

Rahul Menon
Rahul Menon

Reputation: 792

There is nothing wrong theoritically with this method, but it is not a standard practice to use signals as clocks. This introduces logic into your clock generation which is cumbersome (not impossible) for the physical design or backend flow and tools to deal with.

[There is at least an extra inverter together with the logic the input signal will bring]

example in the link below - Proper way for signal edge detection in Verilog

If the signal is asynchronous and being generated from an external module you can synchronize it , then use edge detector logic. Then use that output to trigger the count. https://www.doulos.com/knowhow/fpga/synchronisation/

If there is access to the clock then it better to get the clock in to detect the falling and rising edge of the signal and use it to count. Example code below.

module clock_edge_counter    (
clock_edge_count,    // Output of the counter  ,
clk     ,          // clock
detect ,  // signal to be checked
stop ,
reset
);

parameter CNTR_WIDTH = 16;

input clk ;
input detect;
input stop ;
input reset ;

output [CNTR_WIDTH:0] clock_edge_count;
reg [CNTR_WIDTH:0] clock_edge_count;


reg                  detect_d;

always @(posedge clk or posedge reset)
 begin
 if (reset)
   detect_d <= 0 ; 
  else
   detect_d <= detect; // delay signal by one cycle
 end

always @(posedge clk or posedge reset)
 if (reset) begin
   clock_edge_count <= 0;
 end
//                       rising edge        or    falling edge      ( xor logic )
 else if (!stop && ( (!detect && detect_d ) || (detect && !detect_d ) ) )
    begin
   clock_edge_count <= clock_edge_count + 1;
 end

endmodule

Also at the end the use of the output ( counter ) would be in a synchronous block , so its better to use the clock of the resulting block in the clock_edge_counter.

Upvotes: 3

Related Questions