I have a system clock, I would like to use the system clock to drive a DAC clock. I want only send the clock to the DAC when I enable it. "Anding" the signals together is the first thing I tried: enter image description here
DAC_CLK <= DAC_SHIFTOUT_EN_H and SYS_CLK;--Output to DAC clock pin
The problem is in simulation there was a runt from the clock going high and the combinatorial logic delay on the DAC_SHIFTOUT_EN_H signal. So I decided to go a different route: I used a this to try and buffer the clock, which worked in the simulation but doesn't work on an Altera Max10 Fpga.
DAC_CLK_COMB : process(SYS_CLK,DAC_SHIFTOUT_EN_H)
begin
if DAC_SHIFTOUT_EN_H = '0' then
DAC_CLK_TEMP <= '0';
else
DAC_CLK_TEMP <= SYS_CLK;
end if;
end process;
DAC_CLK <= DAC_CLK_TEMP;--Output to DAC clock pin
I found some resources on the internet about Gating clocks, but they make recommendations based solely on timing which I don't care about because I'm not using logic downstream. What is the best way to use a clock enable for an output without delaying it by a clock if a delay of less than a clock cycle is acceptable?
2 Answers 2
In general, FPGA clocks should not be used in combinatorial logic. Clock buses are specially routed through the FPGA and using them for non-clocking purposes can create unexpected problems in timing closure for other portions of your design.
The primary issue in your case though, is that you will almost always end up with a signal which either begins, or ends, with a fraction of a single clock pulse.
Without clocking your output, you are relying on your two signals DAC_SHIFTOUT_EN_H and SYS_CLK to be perfectly aligned, which they will likely never be - due to fanout and routing delays.
First, check to see if your FPGA has a clock buffer with an enable - a tri-state. This will be your easiest solution.
Short of that, you can create two signals and toggle them on alternate clock edges: one on the rising edge and one on the falling. Then xor the two results. Like so:
process(clk, en)
begin
If (en = '0') then
a <= '0';
b <= '0';
else
if (rising_edge(clk)) then
a <= not a;
end if;
if (falling_edge(clk)) then
b <= not b;
end if;
end if;
dac_clk <= a xor b;
end process;
It is likely that your second attempt is failing, for the same reason your first attempt is. As demonstrated by your simulation, your DAC_SHIFTOUT_EN_H signal is delayed very slightly with respect to your SYS_CLK. The glitch occurs in your output with asynchronous logic (in both cases), since your output signal includes the very small portion of the SYS_CLK which is held until your DAC_SHIFTOUT_EN_H finally falls - maybe picoseconds too late.
The fact that your second simulation didn't show the same issue is probably because the layout of the new synthesis didn't cause problems for a behavioral simulation. This doesn't mean problems don't exist though.
Here I have simulated your second attempt. But I manually added a small delay in the DAC_SHIFTOUT_EN_H signal. You can see that it yields the same result as your first attempt. I made the delay large enough to be seen - making it easier to visualize.
Hope this helps. dac clock sim
-
\$\begingroup\$ @laptop2d I understand that. That's why it's ok to create the new clock out of two signals "a" and "b". Otherwise you would not want to do it this way. If you were using the new clock in the same design, this would also be bad practice. \$\endgroup\$Blair Fonville– Blair Fonville2017年07月18日 12:03:44 +00:00Commented Jul 18, 2017 at 12:03
-
\$\begingroup\$ @laptop2d did this not work for you? \$\endgroup\$Blair Fonville– Blair Fonville2017年07月19日 12:13:44 +00:00Commented Jul 19, 2017 at 12:13
-
\$\begingroup\$ @laptop2d I added some info that I hope will help. See second paragraph. Also note that the solution I posted will only work well if the enable signal fanout is less than 1/2 clock period. Also I assume the enable signal itself is clocked. And then output clock will likely be inverted- I assume this isn't an issue though. You can easily invert it again manually. \$\endgroup\$Blair Fonville– Blair Fonville2017年07月19日 13:29:59 +00:00Commented Jul 19, 2017 at 13:29
-
\$\begingroup\$ Yes, but I'm not using the signals elsewhere in my design, its for a DAC so the DAC_CLK is an output of the FPGA \$\endgroup\$2017年07月20日 04:40:22 +00:00Commented Jul 20, 2017 at 4:40
Don't gate clocks. Ever. FPGAs have dedicated logic for clock and for data, and they are not designed to be mixed.
The easiest solution to drive a clock off the IC is to use a DDR primitive. Then for your specific requirement - not driving it unless enabled - you should be able to use the DDR module's enable for it.
-
1\$\begingroup\$ Gating clocks is a way to safe power. Synthesis tool are able to do gated clock conversions. \$\endgroup\$dbosky– dbosky2016年09月15日 02:09:21 +00:00Commented Sep 15, 2016 at 2:09
-
\$\begingroup\$ If you are trying to save power, you can disable the DCM, which effectively gates the clock, but with the proper hardware being used. \$\endgroup\$Aaron D. Marasco– Aaron D. Marasco2016年09月15日 12:34:02 +00:00Commented Sep 15, 2016 at 12:34
-
2\$\begingroup\$ I'm not a big fan of generalizisms, there are times that gating a clock would be useful. I'm not using the gated clock to drive any logic, what is the danger if I'm not driving logic downstream? \$\endgroup\$2016年09月15日 15:26:14 +00:00Commented Sep 15, 2016 at 15:26
-
1\$\begingroup\$ @AaronD.Marasco I assume you don't know too much about gated clocks techniques. Synthesis tool will convert it correctly i.e. in @laptop2d case
SYS_CLK
will be used as clk andDAC_SHIFTOUT_EN_H
will be connected toCE
pin of the flop. Thus, it will use proper hardware (I assume that's what you meant) \$\endgroup\$dbosky– dbosky2016年09月15日 15:53:44 +00:00Commented Sep 15, 2016 at 15:53 -
1\$\begingroup\$ Bravo Aaron, +1, there is no place for hackware in Engineering! BTW, Xilinx FPGAs (at least recent ones) do have special clock buffers that are gateable, properly. xilinx.com/support/documentation/white_papers/… Apparently Altera fails even here. \$\endgroup\$Ale..chenski– Ale..chenski2016年09月20日 19:06:13 +00:00Commented Sep 20, 2016 at 19:06
DAC_SCLK
is generated? Can you paste the code? \$\endgroup\$DAC_CLK <= not DAC_SHIFTOUT_EN_H or SYS_CLK;
which provides a high idle value. Note as is you're currently producing the first rising edge during the high baud ofSYS_CLK
. \$\endgroup\$