I'm programming a Xilinx Spartan-6 on an OpalKelly implementation for my master thesis at university. To be precise, this is the FPGA I'm working on (XEM6010-LX45): https://www.opalkelly.com/products/xem6010/
It is mounted on a board that has to acquire multiple signals (8+), process them and generate multiple ones (16+) to close some feedback loops based on the settings.
As you can imagine I need to drive multiple DACs and ADCs, but I'm struggling with the correct way to impose timing constraints in the .ucf file.
Let's start from the DACs, we'll talk about the ADCs if we figure this out :D
4 DAC chips, each driven by 4 signals: clock, reset, sync, data. Clock is in common among all DACs and it's a 27MHz clock coming from the PLLs, regenerated with a DDR structure and sent along with the other signals.
I've already come up with the correct timing constraints relative to the external clock (the one I'm sending out) but since that is not the one clocking the data/sync/reset flip flops, it seems I have to impose the constraints relative to the internal clock.
How do I manage this situation, basically a BUS structure with the clock in it?
Timing report is fine except for the fact that every timing is relative to the internal clock, and it's ignoring my REFERENCE_PIN instruction (probably because I use it in the wrong way).
How can I impose timing constraints relative to an output pin? After all, the software should be able to calculate the delay to send the clock out of the FPGA (as it does for every pin), so after that is only a matter of subtractions and bus skew!
Here is the .ucf file I've written (only the part we are interested in):
NET "clk_dac" TNM_NET = "TNM_clk_dac";
TIMESPEC TS_clk_dac = PERIOD "TNM_clk_dac" 27 MHz HIGH 50%; #27MHz
# DAC SLOW
NET "dac_slow_sync_pin1" TNM = "dac_slow_sync";
NET "dac_slow_sync_pin2" TNM = "dac_slow_sync";
NET "dac_slow_sync_pin3" TNM = "dac_slow_sync";
NET "dac_slow_sync_pin4" TNM = "dac_slow_sync";
NET "dac_slow_data_pin1" TNM = "dac_slow_data";
NET "dac_slow_data_pin2" TNM = "dac_slow_data";
NET "dac_slow_data_pin3" TNM = "dac_slow_data";
NET "dac_slow_data_pin4" TNM = "dac_slow_data";
OFFSET = OUT AFTER "clk_dac" REFERENCE_PIN "dac_slow_clk" RISING;
OFFSET = OUT AFTER "clk_dac" REFERENCE_PIN "dac_slow_clk" FALLING;
TIMEGRP "dac_slow_sync" OFFSET = OUT 24 ns AFTER "clk_dac" REFERENCE_PIN "dac_slow_clk" FALLING;
TIMEGRP "dac_slow_data" OFFSET = OUT 35 ns AFTER "clk_dac" REFERENCE_PIN "dac_slow_clk" RISING;