Clock_Div

V

Volker

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;
 
M

Mark McDougall

Volker said:
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,
 
E

Enes Erdin

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.
 
T

Tricky

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.
 
V

Volker

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top