Please post questions, comments, and feedback on the FPGA Digital Delay Generator reference example in this thread.
Could you publish these files for Labview version 8.5? I would like to test it on our neighbors' FPGA system. If it works, we will end up purchasing our own FPGA... as this example looks like exactly what we're looking for.
While we're at it, I'd just like to repost a question to verify that this does what we want, although from the example it looks promising.
We want to be able to send an TTL signal created externally into Labview (or the FPGA), and on each falling edge of the input, have the FPGA create output pulses on the digital lines with a specified delay and duration for the high (or low period). The delay should be with respect to the falling or rising edge of the input TTL.
Heres a picture of our example application:
The FPGA that we are considering is the PXI-7853 R Virtex 5 LX85
It claims to have 96 DIO and 96 hardware counter/timers. So my first question is to verify that we can use or modify the application you developed to create 96 output pulses.. correct?
Also, on the example page, you discuss how the jitter and resolution changes depending on whether we use a 200 Mhz clock, or a 40 Mhz clock. Does the choice of clock limit the number of pulses we can create on output? (ie, higher resolution limits us to creating fewer outputs)
To answer your first question, yes, this example was created for what you are describing. You will have to modify the code for your specific application. One modification will be replacing the Greater Than function used to detect a trigger with a Less Than function. This will make the trigger be a falling edge instead of a rising edge. The Simple Digital Delay Generator example shown in Figure 2 (and included in the LabVIEW Project) contains the logic you will need for the inverted pulses shown in your picture. Namely, look at the logic for output AB*.
You mentioned that you wanted to use all 96 outputs as inverted pulses. Are these pulses all different (individually timed) or do you have 24 groups of the 4 outputs shown in your picture? If the later, the logic is very simple and should fit at 200 or 100 MHz, even with 96 outputs (I have only tested 64). Ultimately, this configuration is only working with 8 delays that get combined into 4 pulses. Those 4 pulses get passed to 96 outputs (24 outputs per individual pulse). Therefore, this should be able to compile at a very fast rate. If all 96 output pulses are individually timed, you will most likely be unable to compile at 200 MHz. You would need 192 delays. This equates to a Delay/Channel (ticks) array of 192 elements being indexed to 192 Greater Than functions that compare against Count. This would then go to 96 OR functions to create the 96 individual pulses. This is a significant amount of logic for a RIO target to execute in a loop running at 200 MHz. The LabVIEW FPGA compiler has to place the FPGA logic very close together to ensure that everything can happen at the specificied rate. The more parallel logic, the less FPGA fabric for the compiler to work with. The compliler will start spreading the code out and soon, you won't be able to finish your code at the desired rate (at which point, the complier fails). Therefore, you will need to work in something like a 40 MHz to 100 MHz clock. You will also want to consider changing the Delay/Channel (ticks) array to a DMA transfer. Front panel objects take a lot of FPGA fabric to allow for communication to a host program (Windows or LabVIEW Real-Time). The bigger the front panel object, the more fabric required. Using a DMA FIFO for transfer would remove the Delay/Channel (ticks) array from the front panel, saving a significant amount of space. Hopefully, this discussion should address your second question. Yes, the amount of logic effects the ability to compile at a given rate. However, the amount of said effect is unknown until you compile. The nice thing is that if you have the LabVIEW FPGA module, you can compile the code for a given RIO target ahead of time, before buying the target. That way, you can know if you can make rate or not before purchasing.
I will update the example to contain LabVIEW 8.5 code by the end the day.
I hope this helps!
Thanks for your detailed reply! I just want to make sure that I understand everything correctly, because that's alot to digest. So I was originally asking about using 96 ouputs with individual timing for each output. In reality, we'll never need that much, so if we don't get to 96, its not a big deal. We were originally planning on purchasing a digital delay generator, but as you all mention in the example, the NI solution is much more cost effective.
So when you refer to a "delay" here:
"Ultimately, this configuration is only working with 8 delays that get combined into 4 pulses."
are you refering to one o fthe 96 hardware timers that is included in the FPGA board? And if that's the case.. that means that for every pulse.. we would need to use 2 hardware timers, correct..? One timer to time the delay time from the trigger, and the other timer to time the actual duration of the pulse.. ? And if that's the case, that means that we could theoretically get up to 48 individually timed pulses output on the digital lines.. right?
And as for the clock rate.. as I understand it.. the clock rate we can set depends only on how much code needs to execute within each loop.. so if we add individually timed pulses.. we need to slow down the clock so that the loop has time to execute... right? That shouldn't be a problem as we previously worked at 20Mhz, so even slowing down to 40 would be an improvement on our end.
So as a rough estimate, would it be possible to say more or less how many individually timed pulses I might expect to be able to create on the 7853R with a clock of 20 Mhz or higher? 10, 20 40..?
Thanks for updating the code! I really appreciate it and can't wait to try it out,
Ok, I'm looking at the code, and I just realized that for all of the pulses on your examlpe, the pulses are set high at variable times (the variable delays Ti), and they seem to all be held high for a time of Ttotal - Tdelay, and thus they all get reset to low once Ttotal has expired.
In fact, i'm looking to have different hold times for each of my individual pulses - some will be reset sooner than others. The pulse Tdelay + Thold) will be less than the input TTL period (which I guess you could call Ttotal).
How could I modify your code to do something such as this?
First, I am going to define a timer as a Greater Than function. That Greater Than function is looking at Count to determine if its time has passed. That said, I think we are confusing hardware timers with digital outputs. With LabVIEW FPGA, you can create as many timers as the FPGA compiler can fit on a particular FPGA. It isn’t limited by the digital IO. We can have hundreds of internal timers if we wanted. We can also combine these timers to create a single timer output. As an example, we could have 192 timers combined in pairs to create 96 physical outputs.
Your comments on the clock rates are close to correct. If you are talking about sequential code, you are correct. The more sequential code, the slower the clock rate will need to be. Again, the amount of code per clock rate is unknown until you compile. If you can compile the code, it will work. If the compile fails specifically due to timing, you need to lower the rate. With parallel code, it is a little more trickery. In LabVIEW FPGA, code happens in true parallel. Therefore, if your FPGA has enough space, you could add tons of code in parallel and still have it compile at the same rate. As an example, I can compile 1 individual timer at 200 MHz or I can compile 32 individual timers at 200 MHz. Because these timers are in parallel and because I have enough space, this isn't a problem. If you want to do 96 pulses, which would require 192 timers, at 40 MHz or possibly 80 MHz, my guess is it would fit as long as you got a RIO board with a large FPGA. Again, until you actually try it, it is just a guess. All FPGAs, not just NI RIO products work this way. It is a little bit science and a little bit art when it comes to figuring this stuff out. :-)
Now to your application. These examples do generate pulses just as you desire by combining two lines that operate as you described () with an XOR function. I commented a block diagram that should help explain this. See the Example.jpg and let me know if this answers your questions.
Ah... I understand now.. that makes alot of sense. Its great too because a pretty flexible way of manipulating the pulses.
So I also tried programming another way, using the In Range block to see if the counter was between T=delay and T=delay+duratio, and if so outputing true.. otherwise false. That's how I had originally imagined things at least. Now when I try to wire the FPGA up, I'm not getting the expected output on the oscilloscope. I suspect its a dumb error somewhere, but I can't seem to find it.
So I set everything in the project to use Connector 0 instead of Connector 1, and changed my FPGA to the one we're using here now, an 7833R with an SCB-68 connector block, left the trigger at DIO0, renamed DIO1, 2,3,4 to A, B, C, and D. I defined two pulses for lines A and B, set line C to display the result from the FPGA IO Trigger, and line D to display the result of "Triggered?". On a previosu test, I also wired a boolean toggle to line D just to test if the output was working. I also plugged my input TTL into the oscilloscope to use as a reference.
So with the toggle button, I was able to togle between high/low states on line D, so I assume the outputs are ok
(Works as expected)
With "Triggered?" wired to line D, line D stays low the whole time
(I expected this to follow my input TTL - at least up until count reached Total Count)
With the FPGA IO Trigger output wired to line C, line C stays high the whole time.
(Here I should expect spikes corresponding teh the input TTL edges...right?)
I used an input total count of 400000 to correspond to 100 Hz
So it seems to me that I can't get the program to trigger properly.. I asume the FPGA Trigger IO is set correctly as an input, since its set in read mode.
Do you see anything obviously wrong in the vi attached?
I actualy got it working.. first there was something wrnog with the DIO0 on my board.. then someoen else mentioned that maybe the DI0:3 have to all be configured one way (either input or output) and the DIO4:7 another way (either niput or output). I haven't verifyed yet whether thats the reason, but in the end, I managed to get pulses out, so everythign looks good. We're going to go ahead and buy our own FPGA now, so it'll be fun.
Thanks for all your help!
TTL Trig in Yellow, output pulses in pinkand blue. Parasitic noise due to shoddy cabling
That is fantastic! Congrats on getting this working and enjoy! Just out of curiosity, what is the end application that this is being used for?
Let me know!