[SOLVED] Synchronous clock division

Status
Not open for further replies.

rajesh0therascal

Newbie level 3
Joined
May 22, 2013
Messages
4
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,317
Hi,

I have 16 KHz clock on board. I have to derive 1 Hz clock for internal logic application. Kindly suggest me a methodology for that. Derived clock should be synchronous with master clock. I've written a VHDL code, but it is out of sync and it has glitches in post synthesis simulation. Kindly help..

Regards,
Rajesh.
 

use a synchronous counter. Post your code so we can see what you've done wrong.
 

Or even better, generate a 1 HZ clock enable.
 

I think the below code will solve it, it is a clock divider with 50% duty cycle

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY FDIVIDER IS
GENERIC
(
div_num : integer := 16000
);
PORT
(
clk : IN STD_LOGIC;
rst : IN STD_LOGIC;
clkout : OUT STD_LOGIC
);
END FDIVIDER;

ARCHITECTURE rtl OF FDIVIDER IS

signal clkout_t : std_logic;
signal clkout_t_r : std_logic;
signal clkout_t_f : std_logic;
signal clkout_sig : std_logic;
signal count : integer range 0 to div_num-1 := 0;

begin
process (rst,clk)
begin
if(rst = '1') then
count <= 0;
clkout_t <= '0';
elsif(rising_edge(clk)) then
if(count < div_num/2)then
count <= count + 1;
clkout_t <= '1';
elsif(count >= div_num/2 and count <= (div_num - 2)) then
count <= count + 1;
clkout_t <= '0';
elsif(count = div_num-1) then
count <= 0;
end if;
end if;
end process;

process (rst,clk)
begin
if(rst = '1') then
clkout <= '0';
elsif (div_num = 1) then
clkout <= clk;
elsif (div_num = 2) then
if(rising_edge(clk)) then
clkout <= clkout_sig;
end if;
elsif (div_num mod 2 = 0) then
if (rising_edge(clk)) then
clkout <= clkout_t;
end if;
else
clkout <= clkout_t_r or clkout_t_f;
end if;
end process;

process (rst,clk)
begin
if(rst = '1') then
clkout_t_r <= '0';
clkout_t_f <= '0';
elsif(rising_edge(clk)) then
clkout_t_r <= clkout_t;
elsif(falling_edge(clk)) then
clkout_t_f <= clkout_t;
end if;
end process;

process (rst,clk)
begin
if(rst = '1') then
clkout_sig <= '0';
elsif(rising_edge(clk)) then
clkout_sig <= not(clkout_sig);
end if;
end process;

END rtl;
 

Here is my code..

 

You've made that a lot harder than it needs to be: (Besides the fact that double spacing everything makes it REALLY hard to read, and including code that you've commented out is pointless)

Code:
signal qtemp: natural;
|
|
process(reset,clk)
begin
       if reset='1' then
              qtemp<=0;
              q1<='0';
      elsif clk='1' and clk'event then
              qtemp<=qtemp+1;
              if qtemp=7999 then
                     q1<=not q1;
                     qtemp<=0;
             end if;
      end if;
end process;
 

Or even better, generate a 1 HZ clock enable.

In theory - the code of barry will generate clean pulses - using a clock enable will save you A LOT OF frustrations afterwards
 

In theory - the code of barry will generate clean pulses - using a clock enable will save you A LOT OF frustrations afterwards

In reality, the code of Barry will generate clean pulses. This is a synchronous counter and the tools will ensure that timing is met and there will be no glitches.
 

Of course - that's why we avoid this construct for clock signals

there are several treads about using clock enable to divide clock signals
 

Not sure what you're working on, but creating clock enable as Tricky mentioned may make more sense. Here is Barry's fine code implementing a clock enable:

Code:
process(reset,clk)
begin
    if reset='1' then
        qtemp <= 0;
        q1    <= '0';
    elsif clk='1' and clk'event then

        if qtemp = 7999 then
            qtemp <= 0;
            q1    <= '1';               -- clock enable (tick)
        else
            qtemp <= qtemp+1;
            q1    <= '0';
        end if;

    end if;
end process;

-- do something with clock enable
process(reset, clk)
    if reset = '1' then
        ..some_signals
    elsif rising_edge(clk) then
            if q1 = '1' then            -- using the clock enable (tick)
                ..do something 
            end if;
    end if;
 end process;
 

In theory - the code of barry will generate clean pulses - using a clock enable will save you A LOT OF frustrations afterwards

hello, can you explain more about clock enable, what does it mean and why it's better?
 

hello, can you explain more about clock enable, what does it mean and why it's better?
Here is an example...
Code:
process(clock)
begin
   if rising_edge(clock) then
      if (clock_enable = '1') then
         -- Put anything here that needs to be clocked only on those clock
         -- cycles where the clock_enable signal is '1'
     end if;
   end if;
end process;

Clock enables are 'better' in non-ASIC environments because no matter how hard you try, when you generate one clock from another clock implemented in logic the following will almost inevitably occur:
- There will be skew between the two clocks. Specifically, the edges of the generated clock will occur after the edges of the original clock
- There will be signals generated in the original clock domain that you will want to use in the generated clock domain. You will have absolutely no control over how quickly that signal will get through the logic and the final signal that is to get sampled in the generated clock domain will violate either setup or hold time...your design will eventually fail under certain conditions...if you're lucky it will fail immediately and you will abandon the approach. If you're not lucky it will fail just as you're about to leave work and you can't because the production line has a pile of boards that are 'flaky'.

Kevin Jennings
 
My bad... please delete this post.


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
process(reset,clk)
begin
    if reset='1' then
        qtemp <= 0;
        q1    <= '0';
    elsif clk='1' and clk'event then
        if qtemp = 7999 then
            qtemp <= 0;
            q1    <= '1';               -- clock enable (tick)
        else
            qtemp <= qtemp+1;
            q1    <= '0';
        end if;
 
    end if;
end process;
 
-- do something with clock enable
process(reset, clk)
    if reset = '1' then
        ..some_signals
    elsif rising_edge(clk) then
            if q1 = '1' then            -- using the clock enable (tick)
                ..do something 
            end if;
    end if;
 end process;

 
Last edited:

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…