As far as possible minimise the number of clocks used in a design. For example when cascading 2 counters the correct way to do it is:
Code:
process (CK) begin
if rising_edge(CK) then
-- Count from 0 to 1011, then reset to zero
if ACOUNT = "1011" then ACOUNT <= "0000";
else ACOUNT <= ACOUNT + 1;
end if; -- CK
end process;
process (CK) begin
if rising_edge(CK) then
if ACOUNT = "1011" then -- CLock enable
BCOUNT <= BCOUNT + 1;
end if;
end if; -- CK
end process;
Even better, epecially for long counters and high clock speeds, pipeline the terminal count. So within the clocked process write:
A_TERMINAL_COUNT <= ACOUNT = "1010"; -- Note one less due to pipeline
A_TERMINAL_COUNT is conveniently a boolean type.
For long counters it gets tedious writing out the terminal count in binary. You can write in hex but only for exact multiples of 4 bits. You can even write horrors like:
"10" & X"B" for "101011". The nice way to do it is:
conv_std_logic_vector(43,6)
You specify the value as an integer and convert to an SLV. you have to specify the length of the SLV .
Of course you could have specified the counter as an integer in the first place which is fine. Until you need to access individual bits of the counter when you end up with a conversion to SLV (or UNSIGNED) before you can get at the bits separately.
The one occasion where you might want to cascade counters without using colck enables is if you're using a prescaler. This is a real example from a CPLD board that had a 25MHz clock oscillator. This was far higher than I needed so I divided down quite heavily to make the main clock for the design. Meant I didn't have to clock enable everything/
Code:
-------------------------------- Central counters ----------------------------------------------
-- 25MHz down to something more useful
process (CK25MHz) begin
if rising_edge(CK25MHz) then
CK25MHZ_DIVIDER <= CK25MHZ_DIVIDER + 1;
end if; -- CK25MHz
end process;
-- Assign main internal clock
CK <= CK25MHZ_DIVIDER(9);
-- Central counter
process (CK) begin
if rising_edge(CK) then
CENTRAL_COUNTER <= CENTRAL_COUNTER + 1; -- 8 bit should be enough
end if; -- CK
end process;
--===================================================================================================================
One warning when doing this. If you prescale by (say) 10 you'll have a
COUNT = "1001" type of statement. Don't use this as a clock signal until you have put it through a register. It will have glitches on it which will give you random grief.
So just put TERMNAL_COUNT <= "1000" inside the clocked process, thus pipelining it and registering it at the same time. Then you can safely say this outside the clocked process:
MAIN_CLOCK <= TERMINAL_COUNT;
Incidentally, type casting (from boolean to SL, SLV to integer etc does not generate any logic. It's simply changing the way you describe a signal or set of signals. Similarly that statement: MAIN_CLOCK <= TERMINAL_COUNT; doesn't generate any logic though the synthesis engine may introduce a global clock buffer. If I'm doing that sort of thing I will usually instantiate the global buffer explicitly. This can be device dependent, here's a real life example from one of my Xilinx designs:
BLACK2_CLOCK_BUFFER : BUFG port map ( O => BLACK2_CK, I => BLACK2_CK_PRE_BUFG);
PS: The forum software deletes all the indenting