Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > Clock_Div

Reply
Thread Tools

Clock_Div

 
 
Volker
Guest
Posts: n/a
 
      12-01-2008
Hi,

following entity should divide a 50 MHz clock into 8khz, 2Hz and 1 Hz. In
principle it would work, but 2 Hz clock is 1 Hz and the duty cycle ist about
30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view the
implementation of Q24 and Q25 looks a little bit strange. Did anyone know
how the design ist not working well?

Thanks
Volker

Code:
-- DIV_COUNTER is a VHDL Design
--
-- Author: V.Meiss
--
-- Version 1.0 from 13.08.2008
-- Altera QuartusII 8.0 SP1


library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;


entity DIV_COUNTER is
port(CLK : in STD_LOGIC;
CLK1, CLK2, CLK8k : out STD_LOGIC);
end DIV_COUNTER;

architecture BEHAVIOR of DIV_COUNTER is
signal Q : std_logic_vector(25 downto 0);
signal LOAD : STD_LOGIC;
begin


process(CLK, LOAD)
constant PRESET : NATURAL :=50000000; -- input 50 MHz
begin
if (LOAD = '0') then
Q <= CONV_STD_LOGIC_VECTOR(PRESET, 26);
LOAD <= '1';
elsif (CLK'EVENT and CLK='1') then
Q <= Q - 1;
end if;

if (Q = "00000000000000000000000000") then
LOAD <= '0';
end if;

CLK1 <= Q(25); -- 1HZ CLK
CLK2 <= Q(24); -- 2HZ CLK
CLK8k <= Q(12);-- 8 kHZ CLK
end process;

end BEHAVIOR;


 
Reply With Quote
 
 
 
 
Mark McDougall
Guest
Posts: n/a
 
      12-01-2008
Volker wrote:

> In principle it would work, but 2 Hz clock is 1 Hz and the duty cycle
> ist about 30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view
> the implementation of Q24 and Q25 looks a little bit strange. Did
> anyone know how the design ist not working well?


In principle, it *won't* work as you hope.

The '1Hz' clock has 30/70 duty cycle because (2^25)/50e6 is about 70%.

IMHO don't feed back an async preset from the process logic, just preset
the counter explicitly. And your 1Hz clock should be asserted whenever Q
reaches a certain (any) value. The other clocks don't divide nicely into
50e6 so you can't really do what you're trying to do.

I'd probably derive an 8KHz clock enable and use that to increment a
counter that you can derive the 1Hz and 2Hz clock enables from... you're
not clocking logic with these clocks, are you!?!

Regards,

--
Mark McDougall, Engineer
Virtual Logic Pty Ltd, <http://www.vl.com.au>
21-25 King St, Rockdale, 2216
Ph: +612-9599-3255 Fax: +612-9599-3266
 
Reply With Quote
 
 
 
 
Enes Erdin
Guest
Posts: n/a
 
      12-01-2008
On 1 Aralęk, 06:15, "Volker" <(E-Mail Removed)> wrote:
> Hi,
>
> following entity should divide a 50 MHz clock into 8khz, 2Hz and 1 Hz. In
> principle it would work, but 2 Hz clock is 1 Hz and the duty cycle ist about
> 30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view the
> implementation of Q24 and Q25 looks a little bit strange. Did anyone know
> how the design ist not working well?
>
> Thanks
> Volker
>
> Code:
> -- DIV_COUNTER is a VHDL Design
> --
> -- Author: V.Meiss
> --
> -- Version 1.0 from 13.08.2008
> -- Altera QuartusII 8.0 SP1
>
> library IEEE;
> use IEEE.STD_LOGIC_1164.all;
> use IEEE.STD_LOGIC_ARITH.all;
> use IEEE.STD_LOGIC_UNSIGNED.all;
>
> entity DIV_COUNTER is
> * * *port(CLK * : in STD_LOGIC;
> * * * * * *CLK1, CLK2, CLK8k : out STD_LOGIC);
> end DIV_COUNTER;
>
> architecture BEHAVIOR of DIV_COUNTER is
> * * *signal Q *: std_logic_vector(25 downto 0);
> * * *signal LOAD *: STD_LOGIC;
> begin
>
> *process(CLK, LOAD)
> * * * constant PRESET : NATURAL :=50000000; -- input 50 MHz
> *begin
> * * * if (LOAD = '0') then
> * * * * * *Q <= CONV_STD_LOGIC_VECTOR(PRESET, 26);
> * * * * * *LOAD <= '1';
> * * * elsif (CLK'EVENT and CLK='1') then
> * * * *Q <= Q - 1;
> * * * *end if;
>
> * * * if (Q = "00000000000000000000000000") then
> * * * *LOAD <= '0';
> * * * end if;
>
> * * * CLK1 <= Q(25); -- 1HZ CLK
> * * * CLK2 <= Q(24); -- 2HZ CLK
> * * * CLK8k <= Q(12);-- 8 kHZ CLK
> *end process;
>
> end BEHAVIOR;


The duty cycle of 1 Hz is about 164/500 how did I calculate this?

Try to write a code which counts a less number. The problem is that
50_000_000 is something like 1011111010.. so when you say that Q(25)
is a 1 Hz signal you will get a wrong result. the same applies for
others too (also for 8 khz)

If I were you I would create an enable signal to create a 8 Khz signal
and using this enable signal I would create the clock signals for 1 Hz
and 2 Hz signals by the help of another counter.

Good luck.

 
Reply With Quote
 
Enes Erdin
Guest
Posts: n/a
 
      12-01-2008
On 1 Aralęk, 06:51, Mark McDougall <(E-Mail Removed)> wrote:

>
> The '1Hz' clock has 30/70 duty cycle because (2^25)/50e6 is about 70%.
>

That's better

 
Reply With Quote
 
Tricky
Guest
Posts: n/a
 
      12-01-2008
On 1 Dec, 14:15, "Volker" <(E-Mail Removed)> wrote:
> Hi,
>
> following entity should divide a 50 MHz clock into 8khz, 2Hz and 1 Hz. In
> principle it would work, but 2 Hz clock is 1 Hz and the duty cycle ist about
> 30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view the
> implementation of Q24 and Q25 looks a little bit strange. Did anyone know
> how the design ist not working well?
>
> Thanks
> Volker
>
> Code:
> -- DIV_COUNTER is a VHDL Design
> --
> -- Author: V.Meiss
> --
> -- Version 1.0 from 13.08.2008
> -- Altera QuartusII 8.0 SP1
>
> library IEEE;
> use IEEE.STD_LOGIC_1164.all;
> use IEEE.STD_LOGIC_ARITH.all;
> use IEEE.STD_LOGIC_UNSIGNED.all;
>
> entity DIV_COUNTER is
> * * *port(CLK * : in STD_LOGIC;
> * * * * * *CLK1, CLK2, CLK8k : out STD_LOGIC);
> end DIV_COUNTER;
>
> architecture BEHAVIOR of DIV_COUNTER is
> * * *signal Q *: std_logic_vector(25 downto 0);
> * * *signal LOAD *: STD_LOGIC;
> begin
>
> *process(CLK, LOAD)
> * * * constant PRESET : NATURAL :=50000000; -- input 50 MHz
> *begin
> * * * if (LOAD = '0') then
> * * * * * *Q <= CONV_STD_LOGIC_VECTOR(PRESET, 26);
> * * * * * *LOAD <= '1';
> * * * elsif (CLK'EVENT and CLK='1') then
> * * * *Q <= Q - 1;
> * * * *end if;
>
> * * * if (Q = "00000000000000000000000000") then
> * * * *LOAD <= '0';
> * * * end if;
>
> * * * CLK1 <= Q(25); -- 1HZ CLK
> * * * CLK2 <= Q(24); -- 2HZ CLK
> * * * CLK8k <= Q(12);-- 8 kHZ CLK
> *end process;
>
> end BEHAVIOR;


If you are using individual bits from a counter for your output clocks
(as you are) you can only get a nice 50/50 mark space ratio on clocks
outputs that are 1/2^n speeds. Using an asyncronous reset will just
skew the duty cycle as you have seen. So as you have a 50MHz clock,
you can only get a nice 50/50 duty cycle if you want 25Mhz, 12.5Hz,
6.25MHz etc.

As for the synthesisor implementing something odd, its probably
because you have an asyncronous load, which is never a good idea. Ive
built it myself, and yes, theres alot of unnessary logic. You also
havent put Q in the sensitivity list so this code will not simulate
properly (it wont reset when Q gets to 0, it will just wrap).

I would recommend using a fully syncronous version:

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;

entity DIV_COUNTER is
port(CLK : in STD_LOGIC;
CLK1, CLK2, CLK8k : out STD_LOGIC);
end test_build;

architecture BEHAVIOR of DIV_COUNTER is
signal Q : unsigned(25 downto 0);
begin

process(CLK, LOAD)
constant PRESET : NATURAL :=50000000; -- input 50 MHz
begin

if rising_edge(clk) then
if Q = 0 then
Q <= unsigned(PRESET)
else
Q <= Q - 1;
end if;
end if;


CLK1 <= Q(25); -- 1HZ CLK
CLK2 <= Q(24); -- 2HZ CLK
CLK8k <= Q(12);-- 8 kHZ CLK
end process;

end BEHAVIOR;


NOTE: It is HIGHLY recommended to use enables rather than logic-
generated clocks on other registers.
 
Reply With Quote
 
Tricky
Guest
Posts: n/a
 
      12-01-2008

> * * * * Q <= unsigned(PRESET)



whooops, that should be:

Q <= to_unsigned(PRESET, Q'length)
 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      12-01-2008
Tricky wrote:

> entity DIV_COUNTER is
> port(CLK : in STD_LOGIC;
> CLK1, CLK2, CLK8k : out STD_LOGIC);
> end test_build;


Make that "end div_counter;"

>
> NOTE: It is HIGHLY recommended to use enables rather than logic-
> generated clocks on other registers.


Clock enables can be implied for variable registers.
For example:
http://mysite.verizon.net/miketreseler/count_enable.vhd

-- Mike Treseler
 
Reply With Quote
 
Volker
Guest
Posts: n/a
 
      12-09-2008
Thanks for your answers,
My problem is not the 50/50 duty cycle but that the 1HzCLK and the 2HzClk
are at the same frequency (1Hz). Making the load synchronous will not help.
Is there a limiting of type NATURAL?

Thanks for help
Volker

"Mark McDougall" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed)...
> Volker wrote:
>
>> In principle it would work, but 2 Hz clock is 1 Hz and the duty cycle
>> ist about 30/70. If I check Q23 is OK but Q24 and Q25 not. In RTL view
>> the implementation of Q24 and Q25 looks a little bit strange. Did
>> anyone know how the design ist not working well?

>
> In principle, it *won't* work as you hope.
>
> The '1Hz' clock has 30/70 duty cycle because (2^25)/50e6 is about 70%.
>
> IMHO don't feed back an async preset from the process logic, just preset
> the counter explicitly. And your 1Hz clock should be asserted whenever Q
> reaches a certain (any) value. The other clocks don't divide nicely into
> 50e6 so you can't really do what you're trying to do.
>
> I'd probably derive an 8KHz clock enable and use that to increment a
> counter that you can derive the 1Hz and 2Hz clock enables from... you're
> not clocking logic with these clocks, are you!?!
>
> Regards,
>
> --
> Mark McDougall, Engineer
> Virtual Logic Pty Ltd, <http://www.vl.com.au>
> 21-25 King St, Rockdale, 2216
> Ph: +612-9599-3255 Fax: +612-9599-3266
>



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off




Advertisments