- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page