sampling an slow freq timer after fast stobe - hard problem detailed below

Status
Not open for further replies.

pruki1

Newbie level 3
i have a very hard problem

there is a timer that is clocked by clock_S
while someone sends a 1 cycle strobe at clock freq X
need to supply a valid value of timer after maximum 4 X clocks from strobe

cdc should be kept

now if clock S is fast no problem, strobe X can be synced to domain Sand it meets the
4 X clocks

what if clock S is slow ??

thanks for any help

lostinxlation

put the pulse to CK pin of the flop and let this flop toggle whenever the pulse comes. Detect the rise or fall edge from this flop in domain S.

however, if you get more than 2 pulses within a one S clock cycle, you need to rethink about whole system again.

pruki1

Newbie level 3
ok, still suppose timer S runs at 100 Mhz (10ns)
while clock X runs at 500 M (2ns)
when there is a strobe X, application must get the timer value up to 4 X cycles (8 ns)
thats less than S clock period

so problem seems to be solved by sampling the timer every 10 ns at S domain

but the transfer to domain X is hard (need prevent cdc problems)

how do we know when is the last valid sample just before strobe X etc

seems easy when thinking but dont find the formulation

FvM

Super Moderator
Staff member
Clock X is fast enough to perform synchronous edge detection of clock S. The synchronized clock S allows to sample timer S safely at clock domain X. So it's continuously available.

pruki1

Newbie level 3
still all solutions submitted are not sufficient
can you write a verilog model for it that has no cross domain clock problems ?

FvM

Super Moderator
Staff member
still all solutions submitted are not sufficient
You mean, you didn't understand it?

pruki1

Newbie level 3
verilog is more easy to understand

FvM

Super Moderator
Staff member
The below construct makes a synchronized counter value available in the fast clock domain:
Code:
always @(clock_S)
cnt <= cnt + 1;

always @(clock_X)
begin
edge_det[1:0] <= {edge_det[0],clock_S};
if (edge_det == '01')
cnt_sync <= cnt;
end;

Alternatively, a gray coded count value can be transferred safely without synchronization. That's the usual method to exchange pointers in domain crossing FIFOs and even works, if both clock domains have almost same frequency.

permute

The above seems to assume there will be no metastability on the registers in edge_det. It probably needs extra registers for the counter and the clock_S, so the edge detection can be reliably done, and the counter can be the correct value associated with the delayed clock edge.

I think the gray codes are probably a better choice overall.

FvM

FvM

Points: 2

FvM

Super Moderator
Staff member
It probably needs extra registers for the counter and the clock_S, so the edge detection can be reliably done.
Yes, at least for the dege detection. With a 4:1 frequency ratio, the below code still works. If the double registering of clock_S achieved in edge_det[1] doesn't give sufficient metastability margin, I would prefer gray encoding.
Code:
  edge_det[2:0] <= {edge_det[1:0],clock_S};
if (edge_det[2:1] == '01')

Status
Not open for further replies.