Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
21615 Discussions

My FPGA is not detecting the XOR edge..

Altera_Forum
Honored Contributor II
3,284 Views

I have this verilog code, which depends on either the posedge of the clock or the XOR of my data with its delayed version. 

 

assign x1 = data; assign x2 = ~x1; assign x3 = ~x2; assign XORData = x3 ^ data; //x3 XOR data always @(posedge clock or posedge XORData) begin . . . . end 

 

my FPGA is not responding to the XOR results. I feel the edge is not occuring or its occuring very very fastly, eventhough simulation is OK. 

 

Whats the problem here? 

How do u suggest I write a replacement code?
0 Kudos
13 Replies
Altera_Forum
Honored Contributor II
1,581 Views

If X2 = NOT data 

and X3 = NOT X2 

Then X3 = data 

 

it follows that ... 

 

X3 ^ data = data ^ data = 0 for all cases. 

 

There is no XOR edge because you are merely XORing data with itself. 

 

Jake
0 Kudos
Altera_Forum
Honored Contributor II
1,581 Views

 

--- Quote Start ---  

If X2 = NOT data 

and X3 = NOT X2 

Then X3 = data 

 

it follows that ... 

 

X3 ^ data = data ^ data = 0 for all cases. 

 

There is no XOR edge because you are merely XORing data with itself. 

 

Jake 

--- Quote End ---  

 

 

True. Except that I am XORing my data with its DELAYED version. The above inversion procedures act as a delay. So that finally I XOR my data with delayed version of data. Such XOR will give me a 1 whenever there is an edge transition in my data. 

 

But this is not working on FPGA. Not sure why. 

I am working at 40MHz by the way.
0 Kudos
Altera_Forum
Honored Contributor II
1,581 Views

A Verilog assign surely causes no delay, it defines an alias signal in logic synthesis. It would require a /* synthesis keep = 1 */ attribute for the wire signals to physically synthesize logic cells. But you most likely need more than two logic cells to build a usable delay line.

0 Kudos
Altera_Forum
Honored Contributor II
1,581 Views

Well it looks like you are still trying to resolve the same issue you were with your previous post. Let's start with the problem. You've got this input signal data and you want something to occur whenever there is a rising or falling edge transition on the signal correct? If I remember correctly it has something to do with a counter that you want to reset to 3. 

 

Anyway, what is the edge rate of the data signal? Is the edge rate of the signal faster than your clock? By far the most typical method we use for edge detection is to register the input signal on every clock and compare the current input value to the last input value.  

e.g. 

 

input din; reg din_r; wire flag; assign flag = ^{din,din_r}; always @(posedge clk) din_r <= din; 

 

Obviously this only works if the sampling rate obeys the Nyquist criteria. Your sampling clock must be at least twice the data rate of what your trying to sample (the edge rate of your data signal). 

 

Now if you want to continue to purse your current approach, you can try using the "keep" attribute on your not gate signal declarations as FvM as indicated. 

(* keep = 1 *) 

wire x2; 

(* keep = 1 *) 

wire x3; 

 

The synthesis tool is smart enough to figure out that the delayed signal you've created is equivalent in logic to the original signal. Therefore, it completely does away with what it considers to be your silly NOT gates. Now if you put the keep attribute in, it tells the synthesis tool that they are not in fact silly gates but you intend them to be there and the synthesis tool will leave well enough alone. 

 

However, you will likely not get a long enough pulse with a delay of only two NOT gates unless you can force the fitter to add a significant routing delay between them or by placing them manually in the fabric. 

 

Jake
0 Kudos
Altera_Forum
Honored Contributor II
1,581 Views

 

--- Quote Start ---  

 

 

Jake 

--- Quote End ---  

 

 

Yes its for the same issue. Thanx for the reply. 

Your first suggestion is OK for me. But about the second one, here is what I understood from your reply: 

The synthesis tool is clever enough to know that the inverters I am using r actually dummies, so it actually removes them. So I have to tell the synthesizer to KEEP those gates. Right? 

 

I am working on 5Mbps rate and I am receiving with 40MHz clock. I am keeping the Nyquist rate by having 8 times faster clock. 

 

So how many inverters do u advice me to use, ofcourse with KEEP? How would I make a long enough pulse for my XOR signal?
0 Kudos
Altera_Forum
Honored Contributor II
1,581 Views

 

--- Quote Start ---  

A Verilog assign surely causes no delay, it defines an alias signal in logic synthesis. It would require a /* synthesis keep = 1 */ attribute for the wire signals to physically synthesize logic cells. But you most likely need more than two logic cells to build a usable delay line. 

--- Quote End ---  

 

 

I am using 40MHz clock for 5Mbps data rate. 

How many gates do u think is enough?
0 Kudos
Altera_Forum
Honored Contributor II
1,581 Views

If your data rate is only 5Mbps, then you don't need any inverters whatsoever. Use the approach I described above. Register the data on every clock edge. Then compare the current input data to the last input data. If they are not equal, you have an edge. Use only your clock to adjust the counter. Look at the code I gave in your previous post. 

 

Jake
0 Kudos
Altera_Forum
Honored Contributor II
1,581 Views

The discussed methods of asynchronous edge detection by delay line/XOR may be useful for special cases, where a suitable clock is missing. Apart from the fact, that these design methods aren't supported by usual FPGA compilers (neither Quartus nor any third party tool), they bring a risk of timing violations in the connected logic modules and should be handled with care. So with 40mhz clock for 5mbpsI wouldn't even think of using these techniques. Synchronous edge detection as explained by jakobjones is the means.

0 Kudos
Altera_Forum
Honored Contributor II
1,581 Views

As a supplement, I append an asynchronous delay line, basically copied from the stx_cookbook V3.0, used as edge detector. The 10 element line produces a pulse width of about 3 ns according to Quartus timing simulator with Cyclone III. 

 

module edge_detect (inp,out); parameter DELAY = 10; input inp; output out; wire delay_line /* synthesis keep */; genvar i; generate for (i=1; i<DELAY; i=i+1) begin : del assign delay_line = delay_line; end endgenerate assign delay_line = inp; assign out = delay_line ^ inp; endmodule
0 Kudos
Altera_Forum
Honored Contributor II
1,581 Views

Okay going with the first suggestion, I sampled my data on each clock and compared my current data level with the previous one to detect the edge. 

 

It worked okay but.. 

its giving a huge amount of error. 

 

to test the design I sent alternating sequence (1010101...) for 100 million bits. I got more than 4% of that wrong!! (i.e i used a counter to count how many bits I am receiving and I am getting 4% less!) eventhough the bits are accurately transmitted as shown on my display. 

 

Whenever there is an edge, using the above mentioned method, I increment my bit counter. 

 

Whats the problem here? I expected to have some noise but not THAT much! 

btw, I am transmitting from 1 FPGA to another.
0 Kudos
Altera_Forum
Honored Contributor II
1,581 Views

I confess, that I didn't examine the suggested synchronous edge detector thorougly. It has a nasty design flaw when used with unrelated input signals. The input has to be synchronized to the clock before, otherwise you get occasional errors when the input edge coincides with the clock edge. 

 

// original code input din; reg din_r; wire flag; assign flag = ^{din,din_r}; always @(posedge clk) din_r <= din; 

 

// modified code, sync input data input din; reg din_r; reg din_sync; wire flag; assign flag = ^{din_sync,din_r}; always @(posedge clk) begin din_sync <= din; din_r <= din_sync; end
0 Kudos
Altera_Forum
Honored Contributor II
1,581 Views

My suggestion was for synchronous edge detection in general. In reality, as FvM is suggesting, any time you have unrelated clock domains you have to take care of a condition called metastability. Metastability occurs when you sample a data signal while it is transitioning from a 1->0 or 0->1. In this case, you may clock the flip-flop when the input signal has not yet reached a logic 1 or 0. Essentially the flip-flop cannot determine whether it should be a 1 or 0. Now over time it will eventually settle to one or the other. However, it may not occur before the next clock edge. 

 

To take care of this we use a technique called metastability retiming. That's a fancy way of saying just register the input multiple times (like FvM's code). The idea is that even if the first flip-flop is metastable, it's less likely that the second one will be. The more times you register the input signal the lower your probability of having metastability at the final stage. Each FPGA part family actually has different recommendations for how many stages should be used for metastability retiming. I would recommend you use three in your case. And in actuality, There is a setting in Quartus that controls this. Quartus will actually determine where you are doing metastability retiming in your code and adjust the number of stages if you desire. 

 

Jake
0 Kudos
Altera_Forum
Honored Contributor II
1,581 Views

Metastability may occur, but actually with a very low likelihood. The present problem is much simpler than metastability, I think.  

 

Because of the undefined timing of input related to clock, the resulting flag has an arbitrary pulswidth starting from zero to a full clock cycle, possibly violating setup and hold times of following logic. 

 

If flag is fed to more than one register, each one will see a different version of the signal due to delay differences. One may see a one and another see a zero. If you use flag as input to a state machine, it may even accept an illegal state and never recover without user action (unless you have a safe state machine). Just a short view into the abyss of missing signal synchronisation.
0 Kudos
Reply