# Verilog Synchronize with External Signal

Status
Not open for further replies.

#### groover

##### Junior Member level 1
Hi, I am learning Verilog and struggling with an aspect. I have an 8MHz clock and I have an external signal called Rxd. I need to detect a falling edge on this signal and reset a counter. It could be anywhere from ns to hours before the falling edge appears.

I have:

Code:
reg Rxd_Buf;

always @ (posedge clk) begin
Rxd_Buf <= { Rxd };
...
end

I then look for the falling edge:

Code:
if (RxdBuf == 1'b0 && !RxD) begin
...
end

This works but the problem is that it delays detection of the falling edge by up to one clk period. I need the delay from the edge to resetting the counter to be as short as possible. Is there a better way of doing this?

Thanks!

#### asdf44

You could use RxD as an asynchronous reset to the counter but this is something you'd typically want to avoid.

How fast does it really need to be? FPGA clocks can easily run into the hundreds of Mhz so <10ns delay isn't a problem.

groover

### groover

Points: 2

#### FvM

##### Super Moderator
Staff member
Using unregistered !RxD in the comparison will cause occasional failure (double or no edge detected) due to clock skew and metastability. Text books require an additional double register synchronizer for sufficient high MTBF. If the application tolerates a certain failure rate, you need at least a single synchronizer to avoid clock skew related errors.

groover

### groover

Points: 2

#### KlausST

##### Super Moderator
Staff member
Hi,

Pleas tell us, why a delay of 125ns is a problem.
Usually there is no problem, because furter processing of the signal(s) is all clocked by the 8MHz

Btw: it is recommended to have both ANDed signals in the same clock domain.
Thus you shoud use RxdBuf1 and RxdBuf2 as the AND inputs.
Then you always get a clean 125ns pulse (aligned to the 8MHz clock) at the falling edge of RxD...

Klaus

#### BlackHelicopter

##### Full Member level 2
Here's the code for your falling edge detect. There's really not another way to do it. :thumbsup:

Code:
reg Rxd_Sync;
reg Rxd_Buf1;
reg Rxd_Buf2;
reg Rxd_Fall;

always @ (posedge clk) begin
Rxd_Sync <= Rxd;
Rxd_Buf1 <= Rxd_Sync;
Rxd_Buf2 <= Rxd_Buf1;
Rxd_Fall <= ~Rxd_Buf1 & Rxd_Buf2;
end

Last edited:

Status
Not open for further replies.