- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello again and more inane questions from yours truly!
I have a design which relies on many different clock sources: A lot of inter-dependent timing going on. What therefore is the best (or 'proper') approach to creating many different clocking sources (from the same basic clock source input of course). I know it is not 'good practice' to gate clocks to create another clock which is then used to clock say a latch or a register etc. So, what is considered a good / acceptable clock source? The output of a state machine perhaps? The output of a counter? Any guidelines / comments / suggestions much appreciated! I include below VHDL of something I have written that creates an 8MHz clock from my 24MHz source:
proc_8MHz : PROCESS (nPowerSettleDelay, M24MHz)
BEGIN
IF nPowerSettleDelay='0' THEN
uM8MHz <= '1';
u_nM8MHz <= '0';
Next_State <= State_1;
ELSIF RISING_EDGE(M24MHz) THEN
CASE Next_State IS
WHEN State_1 =>
Next_State <= State_2;
uM8MHz <= '1'; -- 1
u_nM8MHz <= '0'; -- 0
WHEN State_2 =>
Next_State <= State_3;
uM8MHz <= '0'; -- 0
u_nM8MHz <= '1'; -- 1
WHEN State_3 =>
Next_State <= State_1;
uM8MHz <= '0'; -- 0
u_nM8MHz <= '0'; -- 0
END CASE;
END IF;
END PROCESS proc_8MHz;
Is it 'safe' then to use either the uM8MHz or the nM8MHz signal as clock sources? Cheers again all, Andy
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I know it is not 'good practice' to gate clocks to create another clock which is then used to clock say a latch or a register etc. So, what is considered a good / acceptable clock source? The output of a state machine perhaps? The output of a counter? --- Quote End --- The only good clock is either a real clock or the output of a PLL, thats it. A state machine output and counter output are the same thing - a register, and these are bad. Using logic to create a clock is bad. For what you are doing, you want clock enables. Ie. the enable is high for one clock in a number of clocks, and you clock all your logic using the same system clock. And then your logic looks like this:
process(clk)
begin
if rising_edge(clk) then
cnt <= cnt + 1;
div_by_2 <= cnt (0);
if cnt(1 downto 0) = "00" then
div_by_4 <= '1';
else
div_by_4 <= '0';
end if;
if div_by_2 then
--stuff happens at half the system clock
end if;
if div_by_4 then
--stuff happens at 1/4 of the system clock
end if;
--etc
end if;
end process;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Riiiiight.
So, reading into your kind response, in effect I can see that basically everything that is clock event driven should therefore be in ONE big process? I had often wondered what exactly was meant by 'clock enables' - not quite the same as an enable pin on an IC as I had thought of it. Now I am wondering how to rewire 2,000 lines of my VHDL code to suit this approach (and if it is worth it TBH). LOL. Having said that, what I have written so far is 95% complete and seems to work, all be it with some issues that need sorting out. Like most 'code' the closer one gets to completion, the more difficult the bugs become. Thank you again Mr. Tricky Andy- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It doesnt have to be one big process. Remember, its all about the logic, not the code. So one big process or several separate processes can map to the same hardware.
But the theory is the same. Use the same system clock for all of your processes and have clock enables as appropriate. The same enable can go to many processes.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, good my friend.
If you can please, can you show me an example of such inter-process clock enabling (of for example different clock 'sources / frequencies'). Such an example will quickly open my mind up to exactly the right approach! ;) Many thanks yet again for your help. Andy- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The following code:
signal cnt : unsigned(2 downto 0) := "000";
signal div_by_2, div_by_4, div_by_8 : std_logic;
process(clk)
begin
if rising_edge(clk) then
cnt <= cnt + 1;
div_by_2 <= cnt(0);
if cnt(1 downto 0) = 0 then
div_by_4 <= '1';
else
div_by_4 <= '0';
end if;
if cnt = 0 then
div_by_8 <= '1';
else
div_by_8 <= '0';
end if;
if div_by_2 then
--do something every 2 clocks
end if;
if div_by_4 then
-- do something every 4 clocks
end if;
if div_by_8 then
-- do something every 8 clocks
end if;
end if;
end if;
Is functionally the same as, and will produce the same hardware as this code:
process(clk)
begin
if rising_edge(clk) then
cnt <= cnt + 1;
end if;
end process;
process(clk)
begin
if rising_edge(clk) then
div_by_2 <= cnt(0);
end if;
end if;
process(clk)
begin
if rising_edge(clk) then
if cnt(1 downto 0) = 0 then
div_by_4 <= '1';
else
div_by_4 <= '0';
end if;
end if;
end if;
process(clk)
begin
if rising_edge(clk) then
if cnt = 0 then
div_by_8 <= '1';
else
div_by_8 <= '0';
end if;
end if;
end if
process(clk)
begin
if rising_edge(clk) then
if div_by_2 then
--do something every 2 clocks
end if;
end if;
end if;
process(clk)
begin
if rising_edge(clk) then
if div_by_4 then
-- do something every 4 clocks
end if;
end if;
end if;
process(clk)
begin
if rising_edge(clk) then
if div_by_8 then
-- do something every 8 clocks
end if;
end if;
end if;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, just the answer I was looking for! Spot on. :)
So, going back to my original post, could I rewrite it as below to suit what I need to achieve?
--The main clock source for everything is running at 24MHz
--Create an 8MHz & n8Mhz clock enable
proc_8MHz : PROCESS (nPowerSettleDelay, M24MHz)
BEGIN
IF nPowerSettleDelay='0' THEN
en_uM8MHz <= '1';
en_u_nM8MHz <= '0';
Next_State <= State_1;
ELSIF RISING_EDGE(M24MHz) THEN
CASE Next_State IS
WHEN State_1 =>
Next_State <= State_2;
en_uM8MHz <= '1'; -- 1
en_u_nM8MHz <= '0'; -- 0
WHEN State_2 =>
Next_State <= State_3;
en_uM8MHz <= '0'; -- 0
en_u_nM8MHz <= '1'; -- 1
WHEN State_3 =>
Next_State <= State_1;
en_uM8MHz <= '0'; -- 0
en_u_nM8MHz <= '0'; -- 0
END CASE;
END IF;
END PROCESS proc_8MHz;
--Do something that is @ 8MHz
proc_DoSomething_8MHz : PROCESS(M24MHz)
BEGIN
IF RISING_EDGE(M24MHz) THEN
IF en_uM8MHz THEN
--do something every @ 8MHz
END IF;
END IF;
END PROCESS proc_DoSomething_8MHz;
--Do something that is @ /8MHz
proc_DoSomething_n8MHz : PROCESS(M24MHz)
BEGIN
IF RISING_EDGE(M24MHz) THEN
IF en_u_nM8MHz THEN
--do something every @ /8MHz
END IF;
END IF;
END PROCESS proc_DoSomething_n8MHz;
Thanks Tricky, Andy
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Taking for example my last post, I have created an 8MHz clock enable based on my common 24MHz clock source.
When the enable is true, any process such as:
proc_8MHz_freq : PROCESS (M24MHz)
BEGIN
IF RISING_EDGE(M24MHz) THEN
IF en_uM8MHz='1' THEN
--some_counter + 1
END IF;
END IF;
END PROCESS proc_8MHz_freq;
Here, some_counter will +1, not a frequency of 8MHz, rather it will see a bust of M24MHz clocks for the 8MHz enable period. This is obvious and not what I want to have happen with some_counter. Is there an elegant way to better create the en_uM8MHz enable signal such that only ONE clocking event drives some_counter? Thanks again, Andy
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
how is the enabled generated? it should not be a 4 clock wide pulse, but a 1 clock wide pulse every 4 clocks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Generated as per post# 7, but I see what you are saying...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If your enable is longer than a single clock cycle, there must be something wrong somewhere.
With the posted code snippets, assuming the 24HMz clock is constant, the some_counter signal should only increment once every 3 clocks. Are you simulating this design? have you got a testbench? are you tracing back the cause of these "bursts"- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The clock source is constant and a 'true' clock.
I think maybe I am implementing the enable signal incorrectly....
proc_Counters : PROCESS(IN_RESETn, M24MHz)
BEGIN
IF IN_RESETn='0' THEN
usg_Counter_7_0 <= (OTHERS => '0');
ELSIF RISING_EDGE(M24MHz) THEN
IF en_uM8MHz ='1' THEN
IF usg_Counter_7_0 = usg_MAXCOUNT THEN
--Reset the counter...
usg_Counter_7_0 <= (OTHERS => '0');
ELSE
--... or increment the counter
usg_Counter_7_0 <= usg_Counter_7_0 + 1;
END IF;
END IF;
END IF;
END PROCESS proc_Counters;
Yes in my sim, I see the counter increasing in bursts.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sorry, yes the en_uM8MHz signal is high for 3 M24MHz clocks. Hence the source of the bursts.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page