Divided clock seems synchronous to original clk in terms it is stable on
clk
edage. On the other hand, synchronous signals should switch simultaneusly
while divided signal is calculated on the clk egdage; hence, it switches
after Thold and the condition is not met. I understand principles of
asynchronous communication. Should I treat divided clock as an
asynchronous
clock domain? Any references are appretiated.
Valentin,
For all but the simplest of designs divided clocks should be treated as
asynchronous and avoided if possible. There are several reasons for this.
1) Your divided clock will have a small delay relative to the real clock.
If you use this to clock a register which takes in a signal clocked from
the original clock domain it may be possible for the setup/hold to be
violated or data to be taken when it shouldn't have been (i.e a clock
early). I think you were implying this above.
2) If you have logic which works accross the two clock domains e.g. data
clocked from main clock domain goes through logic and is registed on
divided clock domain or vice-versa then the synthesis tool may have a hard
time performing optimization on logic in that part of the design.
3) Unless you have spare high-speed global resources in your design and
the target technology allows the connection of a register output onto
these nets (most modern fpga's are okay with this!) then the divided clock
may get routed on the normal routing nets. If you have lots of registers
driven from the divided clock the fanout may start to become significant
and hence the skew between the clock domains will get larger. If the skew
starts to become significant it then becomes more difficult to ensure that
the design will work over all temperature/voltage conditions as this will
introduce skew between registers on the divided domain aswell as between
the divided and main clock domain. To overcome this the
synthesis/place&route tools may try to insert buffers to split down the
net. This may in turn introduce more skew between some registers on your
divided net.
So to overcome these issues I would suggest trying alternative method of
coding to reduce this problem to a minimum. The way I do things if I want
a slower clock is as follows:
For example, say I want a clock that is 1/3 the system clock, I would
create a 2-bit counter that counts 0 to 2 and rolls over. When the counter
equals 2 a signal EnableDiv3 is asserted to '1' (and is '0' for all other
values). I then use this signal as a synchronous enable to the registers I
want to run a 1/3 speed but still clock the registers off the system
clock.
EnableGen : process (nReset, Clock)
begin
if (nReset = '0') then
EnableCount <= 0;
EnableDiv3 <= '0';
elsif rising_edge (Clock) then
if (EnableCount = 2) then
EnableCount <= 0;
EnableDiv3 <= '1';
else
EnableCount <= EnableCount + 1;
EnableDiv3 <= '0';
end if;
end if;
end process;
SomeRegister : process (nReset, Clock)
begin
if (nReset = '0') then
MySignalReg <= '0';
elsif rising_edge (Clock) then
if (EnableDiv3) then
MySignalReg <= MyDataValue;
else
MySignalReg <= MySignalReg;
end if;
end if;
end process;
This solves 1) and 2) above. For item 3) there is still the problem of
high fan-out on the enable signal. This will be solved by the
synthesis/place&route tool by inserting buffers. However, in this case the
registers are still clocked by the system clock so any skew on enable will
be okay so long as it dosen't violate setup/hold at the destination
registers.
I hope this is what you were asking for. If you need anything else please
let me know.
Cheers,
Pete.