How to detect the posedge of two clocks (asynchronous to each other) at the same time in verilog?

StackOverflow https://stackoverflow.com/questions/17102701

  •  31-05-2022
  •  | 
  •  

Question

I am working on a design which should detect the first match of two rising edges of two asynchronous clocks of different frequencies.

code something like this may work for simulation.

fork 
@posedge clkA 
begin 
    a=$time 
end 
@posedge clkB 
begin 
    b=$time 
end 
join 

if (a=b) then some code.

this code may work for simulation but if I want some synthesizable hardware logic what else can I use?

Was it helpful?

Solution 3

Too pull this off, first make dual-edge,dual-clock flip-flop. Start off with a dual clock D flip-flop Patent US6320442 B1. Now substitute the sub flip-flops with dual edge D flip-flops Patent US5793236 A or Patent US5327019 A. Each patent has diagrams of the circuit design.

With the custom flop, create a small pipeline sampling the history of the clocks. Look for a zero to one transition.

Example:

wire [1:0] historyA, historyB;
// dualedge_dualclock_dff     ( output Q, input D, clkA, clkB, rst_n)
dualedge_dualclock_dff dedc_histA1( .Q(historyA[1]), .D(historyA[0]), .* );
dualedge_dualclock_dff dedc_histA0( .Q(historyA[0]), .D(clkA), .* );
dualedge_dualclock_dff dedc_histB1( .Q(historyB[1]), .D(historyB[0]), .* );
dualedge_dualclock_dff dedc_histB0( .Q(historyB[0]), .D(clkB), .* );

wire dual_posedge_match = ({historyA,historyB} == 4'b0101);

Dual-edge flops and dual-clock flops are not common design practices. Excessive timing analysis will be needed and tools might complain about the cell. Plus, steps need to be taken for patent uses compliance with the law.

OTHER TIPS

This one is kind of tricky but if you can get a third clock that is twice as fast as the fastest clock between the two that you need to detect and can accept a one cycle delay of detection (the one cycle is in reference to the third clock domain) then it is possible.

what you will need to do is set up to registers for each clk domain like this:

input clk1, clk2'

...

reg clk1_in, clk1_out;
reg clk2_in, clk2_out;

wire clk1_posedge, clk2_posedge;

//take in the clock value, you should register this so that way jitter on the line does not mess with it 
always@(posedge clk3)begin 
    clk1_in <= clk1;
    clk2_in <= clk2;
end 

always@(posedge clk3)begin
    clk1_out <= clk1_in;
    clk2_out <= clk2_in;
end 

//now you need to detect the posedge for each signal independently, you can use and and gate for this 
assign clk1_posedge = (~clk1_out && clk1_in);
assign clk2_posedge = (~clk2_out && clk2_in);

// now just and the two together 
assign pulse_detected = clk1_posedge && clk2_posedge

you need clk 3 to be twice as fast, otherwise you get aliasing (look up nyquist freq)

so what happens is the first register for the clock domain will be be high and if it is the just getting high then the second register will still be low for that cycle.

It is not possible to reproduce in HW the behavior you described. The reason for this is that you compare the times exactly.

First of all, you need to explain what do you mean by "detect the first match of two rising edges". Given that two async clocks have variable (and unpredictable) phase relationship, the task of detecting simultaneous edges will (usually) be stated in terms of how much time is "simultaneous".

For example: detect when rising edges are spaced at most 5ns in time.

BTW, I assume here that both frequencies in question are known.

Please describe your problem in more details.

EDIT: This question became hardware question, which is not related to Verilog. It is not clear whether any of the solutions proposed here may work (and it is my personal belief that they won't). I submitted the same question at EE Stack Exchange - it is a place for HW questions, and there is higher chance that it will be answered there.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top