Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

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

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_arith.ALL;
USE IEEE.std_logic_unsigned.ALL;

entity clock_div1 is

port (

clk:in std_logic;

reset: in std_logic;

q1: out std_logic

);

end clock_div1;

architecture counter1 of clock_div1 is

signal qtemp: std_logic_vector(11 downto 0);

signal rst: std_logic;

begin

process(qtemp,reset)

begin

if (reset='1') then

rst<='1';

q1<= '0';

elsif(qtemp = 3999) then

q1<= '1';

elsif(qtemp = 4000) then

q1<='0';

rst<='1';

else

q1<='0';

rst <= '0';

end if;

end process;

process(rst,clk)

begin

if (rst='1') then

qtemp<=(others=> '0');

elsif (clk'event AND clk ='1') then

qtemp <= qtemp + 1;

end if;

end process;


-- process(clk, reset)
--
-- begin
--
-- if (clk'event and clk='1') then
--
-- qtemp <= qtemp + 1;
--
-- elsif(reset = '1' or qtemp = 4000) then
--
-- qtemp <= (others=> '0');
--
-- end if;
--
-- if (qtemp < 2000) then
--
-- q1 <= '0';
--
-- else
--
-- q1 <= '1';
--
--
-- end if;
--
--end process;

end counter1;
 

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;
 

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.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top