One of the features that the Xilinx Spartan-6 series of FPGAs has over their older Spartan-3E cousins (ancestors?) is the ability to reprogram the DCM (digital clock manager) block's multiply and divide ratio "on the fly," thereby allowing you to dynamically change the clock signals being generated by the Digital Frequency Synthesizer.
Programming is achieved with a dedicated Serial Peripheral Interface (SPI) bus. (See also the Using the SPI Bus columns by my fellow All Programmable Planet blogger, Duane Benson.) First, two ten-bit words are written, with the initial 2-bit value indicating whether it is the multiply or divide register that is being updated, followed by the new 8-bit value for the register. The values used are the "terminal counts," which means they are one less than the actual multiply or divide values you require.
Once these two words have been sent, a single "0" bit is transferred to start the DCM's reconfiguration. There is a minimal gap requirement between these transactions of one or two cycles.
Coding this in a HDL (hardware description language) is pretty easy. Here's my design in VHDL (click here to see a larger, more detailed version of this image):
And here is how to add a DCM_CLKGEN component in your design and connect up the programming signals:
If you plan to switch modes often, then you should also monitor the "PROGDONE" line to check that programming completes correctly. Also, you can monitor the "LOCKED" signal to see when the DCM has correctly synchronized and is now generating the new frequency (this can take up to 5ms).
I've still got a few questions, such as what happens if the DCM's "RST" (reset) signal is asserted? Do the registers default back to their "generic" values? Maybe a few minutes at my test bench are required.
And there you have it -- how to switch clock frequencies on the fly! Now, the next question is: Can you think of anywhere you might want to use this technique?
Hi Hamster, thanks for your help. You really like to look into these Xilinx databases, great.
Sure, constraining false paths is a solution. The drawback is the runtime and I would love to have a more natural solution to a common problem.
When you generate n clocks by a DLL, they are most likely async. They are definitely async if they have different periods like 60MHz and 70MHz as in the given example.
So I was wondering why Xilinx assumes the clocks have valid paths by default. Shouldn't it be the case, that you have to constrain it if they are sync, instead of painfully define them as asyc – which is most likely case. A simple button in the GUI might do the job.
It would be just convenient to specify the input clock, specify the periods of the output clock in the GUI and that's it, without false paths settings. If you want to have them sync, then add some constrains.
(If I have 2 sync. clocks, I would prefer a functional solution (clock gating) instead of running them through the PLL with 2 clock trees.)
The phase alignment option in the clocking wizard doesn't make a change.
The current solution is that I don't constrain the input clock. Instead I constrain the output clocks of the PLL individually. I looks good during the flow, although the Constraint Generator complains about it when rereading the ucf. I still assume there is a nice solution for this.
Hi Tobais, I'm pretty weak on constraints - (it sort of reflects the Constraints Users guide documentation, which is very sparse).
Yes, you have to treat any domain crossings as being completely async unless you know exactly what multi/div ratios you will be using, but anything other a simple integer ratio might as well be async.
The trick is to add a Timing Ignore ('TIG') constraint. Examples can be found at http://www.xilinx.com/support/answers/2449.htm, but it always takes me ages to get the "from/to" expressions just right.
...and what ive done is modified your camera driver code to allow arbitary mapping between the frame buffer memory and the VGA driver so you can do tricks like point the camera at a mirrored ball and then remap the frame buffer to give a linear 'panorama' type view.
just as a slight diversion, your ov7670 camera module could be used to drive the HDMI as the 7670 produces YCrCb data.
As an aside for anyone not familar the releationship between RGB and YCrCb colour space is
R=Y +1.402(Cr)
G=Y-0.34414(Cb) - 0.71414(Cr)
B=Y+1.772(Cb)
and the way its transmitted by the camera means that the data is slightly compressed, but there is room for fun with colour space converters, and you can get a simple black and white image just from the Y component.
Hi Hamster and all, may I ask you a clocking question?
It looks as if you can generate 2 asynchronous clocks with the clock wizard (let's say a 60MHZ and a 70MHz clock from a 50MHz source). If this not possible, than sorry for my question and my understanding of the clock wizard GUI is false. I know it would be a challenge for the circuit. But if this is possible, why do I get timing reports for paths between registers of these 2 obviously asynchronous clock domains. How can I avoid it then, defining it as asynchronous, geeee ?
I found the problem, register 0x9D needs to be set to 0x01, and registers 0x15 and 0x16 get set twice.
in fact you can break it in all kinds of interesting ways by playing with the register settings, I think the register setting has got to be a bit more sophistimicated, the hdmi transmitter doesnt cope well with being told to wake up when its already awake.
There is something very odd going on, first there are colour components in the test bar patterns, which vary everytime you restart the code.Secondly the bar patterns dont match what you would expect, and the standard linux disribution drives the hdmi with standard RGB quite happily.
I suggest there is some misunderstanding on how to drive the HDMI transmitter.I will investigate at some point today
After banging my head against a brick wall I have found what is going on...
The D0 through D15 ports are actually connected to D8 through D23 on the transmitter. Verified this on the schematics too - a big thanks to the designer & documentation authors
RGB input is not possible. :-(
(yes, and make "initial_pause" 22 bits, to have about a 200ms pause before sending).
Will upload a newer version soon, that uses the only possible colourspace :-(
Mike
I had a play with your hdmi driver, and it has some issues , I am not convinced that the spi driver is correct partly because of the tri-stating of the driver screwing with the data being sent to the hdmi controller, and the initial wait is too short, I haven't had much time to explore these, at least it meets timing :)
If I were an evil genius working on a plan for world domination (with regard to enterprise-level data storage solutions) I would be seriously considering building my design around a Zynq All Programmable SoC.
I would like to present to fellow readers of All Programmable Planet a new technique that I have invented to serialize data within the FPGA's main fabric at 1.5Gb/s.
As with most things, my feeling is that there is no better way to understand high-speed serial links than to implement one from the ground up, so that is what I've set out to do.
To save this item to your list of favorite All Programmable Planet content so you can find it later in your Profile page, click the "Save It" button next to the item.
If you found this interesting or useful, please use the links to the services below to share it with other readers. You will need a free account with each service to share an item via that service.