clock enable for fixed interval

J

Jim

Guest
What would be the proper way to clock a register at a fixed multiple
of the system clock? I am trying to create a signal that is active
around the rising edge of the system clock as a clock enable. I am
using a counter to generate a signal at the time interval of
interest. I am then performing an edge detection to get a signal that
is active for a single system clock cycle. To get the enable centered
around the rising edge of the system clock, I am clocking the edge
detector with an inverted system clock. I have read not to use
anything other than the system clock as the clock signal to a flip
flop, so I am uncomfortable using the inverted clock. Is the inverted
clock ok? Does anyone have any recommendations on a better way to do
this.

library ieee;
use ieee.std_logic_1164.all;

entity edge_detector is
port (
clock : in std_logic;
d : in std_logic;
rising_edge_out : out std_logic
);
end;

architecture behavioral of edge_detector is
signal sreg : std_logic_vector(1 downto 0);
begin
edge_detector_proc : process(clock)
begin
if rising_edge(clock) then
if sreg(1 downto 0) = "01" then
rising_edge_out <= '1';
else
rising_edge_out <= '0';
end if;

sreg <= sreg(0) & d;
end if;
end process;
end architecture;

entity clock_divider is
port (
clock : in std_logic;
reset : in std_logic;
clock_enable_clock_divided : out std_logic
);
end clock_divider;

architecture behavioral of clock_divider is
signal inverted_clock : std_logic;
signal clock_divided_i : std_logic;
signal count : unsigned(4 downto 0) := (others => '0');
begin
clock_divided_edge_proc : entity work.edge_detector
port map (
clock => inverted_clock,
d => clock_divided_i,
rising_edge_out => clock_enable_clock_divided
);

inverted_clock <= not clock;

clock_divider_counter_proc: process (reset, clock)
begin
if reset = '1' then
count <= (others => '0');
clock_divided_i <= '0';
elsif rising_edge(clock) then
count <= count + 1;
clock_divided_i <= count(4);
end if;
end process;
end behavioral;
 
On 15 Sep., 21:04, Jim <james.kn...@gmail.com> wrote:
What would be the proper way to clock a register at a fixed multiple
of the system clock?  I am trying to create a signal that is active
around the rising edge of the system clock as a clock enable.  I am
using a counter to generate a signal at the time interval of
interest.  I am then performing an edge detection to get a signal that
is active for a single system clock cycle.  To get the enable centered
around the rising edge of the system clock, I am clocking the edge
detector with an inverted system clock.  I have read not to use
anything other than the system clock as the clock signal to a flip
flop, so I am uncomfortable using the inverted clock.  Is the inverted
clock ok?  Does anyone have any recommendations on a better way to do
this.

library ieee;
use ieee.std_logic_1164.all;

entity edge_detector is
    port (
        clock : in std_logic;
        d : in std_logic;
        rising_edge_out : out std_logic
    );
end;

architecture behavioral of edge_detector is
    signal sreg : std_logic_vector(1 downto 0);
begin
    edge_detector_proc : process(clock)
    begin
        if rising_edge(clock) then
            if sreg(1 downto 0) = "01" then
                rising_edge_out <= '1';
            else
                rising_edge_out <= '0';
            end if;

            sreg <= sreg(0) & d;
        end if;
    end process;
end architecture;

entity clock_divider is
    port (
        clock : in std_logic;
        reset : in std_logic;
        clock_enable_clock_divided : out std_logic
    );
end clock_divider;

architecture behavioral of clock_divider is
    signal inverted_clock : std_logic;
    signal clock_divided_i : std_logic;
    signal count : unsigned(4 downto 0) := (others => '0');
begin
    clock_divided_edge_proc : entity work.edge_detector
        port map (
            clock => inverted_clock,
            d => clock_divided_i,
            rising_edge_out => clock_enable_clock_divided
        );

    inverted_clock <= not clock;

    clock_divider_counter_proc: process (reset, clock)
    begin
        if reset = '1' then
            count <= (others => '0');
            clock_divided_i <= '0';
        elsif rising_edge(clock) then
            count <= count + 1;
            clock_divided_i <= count(4);
        end if;
    end process;
end behavioral;
Hi Jim,
using clock enables for multirate systems is a proper way, but you are
trying to do it unneccessary complicated.
It is much simpler.

You have a master clock, and a counter that provides the neccessary
frequency division.
So far so good.
Now you only need to create an impulse for a single clock period.
This can be done like this:

clock_divider_counter_proc: process (reset, clock)
begin
if reset = '1' then
count <= (others => '0');
clock_divided_i <= '0';
elsif rising_edge(clock) then
count <= count + 1;
-- clock_divided_i <= count(4); -- this would be too long
if count = "11111" then
clock_enable_clock_divided <= 1;
else
clock_enable_clock_divided <= 0;
end if;
end if;
end process;
end behavioral;

That's all you need.
When assigning to clock_enable_clock_divided the clock to output
delay and routing delay are sufficient to
keep the signal valid beyond the next rising clock edge.
(If that wouldn't work this way pipelining data from one register to
the next wouldn't work too, but it does.)


Have a nice synthesis
Eilert
 
On Thu, 15 Sep 2011 12:04:12 -0700, Jim wrote:

... I am clocking the edge detector with an
inverted system clock. I have read not to use anything other than the
system clock as the clock signal to a flip flop, so I am uncomfortable
using the inverted clock. Is the inverted clock ok? Does anyone have
any recommendations on a better way to do this.
I'll let others comment on the overall strategy. Just want to point out
that you can clock on negative edges ... "if falling_edge(clk) then "
So an inverted clock is unnecessary.

- Brian
 
On Sep 15, 3:04 pm, Jim <james.kn...@gmail.com> wrote:
What would be the proper way to clock a register at a fixed multiple
of the system clock?  I am trying to create a signal that is active
around the rising edge of the system clock as a clock enable.  I am
using a counter to generate a signal at the time interval of
interest.
Once you have the counter, then the clock enable is simply...

Clock_Enable <= '1' when (Counter = xx) else '0';

Where 'xx' is the precise value of 'Counter' that you want to use to
enable the other logic that uses the clock enable. Depending on how
many bits there are in 'Counter', you might find that it is better
from a timing perspective for the clock enable to be the output of a
flip flop. This can be implemented like this...

if rising_edge(Clock) then
if (Counter = (xx - 1)) then
Clock_Enable <= '1';
else
Clock_Enable <= '0';
end if;
end if;

 I am then performing an edge detection to get a signal that
is active for a single system clock cycle.  To get the enable centered
around the rising edge of the system clock, I am clocking the edge
detector with an inverted system clock.  I have read not to use
anything other than the system clock as the clock signal to a flip
flop, so I am uncomfortable using the inverted clock.  Is the inverted
clock ok?  Does anyone have any recommendations on a better way to do
this.
Simple synchronous logic like what you're describing here will never
need anything more than the rising edge of one clock. Falling edges
are rarely needed.

Kevin Jennings
 
Your approach is flawed. It will not work well because it is not in
line with the generally accepted way of FPGA programming. It uses
asynchronous logic, which is frowned upon because the tools don't
support it well. Insisting on using asynchronous logic will do you no
favor.

It's perfectly valid that you want a clock-enable. However, it's
unusual that you want the clock-enable to be centered "around the
clock edge". It probably stems from working with discrete chips, where
THAT was most reliable way to enable clocks.

In logic (discrete or FPGA), it's also possible to "enable" clocks by
adding the enable as extra logic input, plus feedback of the previous
output. Then you can "always clock" the register, yet make it only
accept (honor) the change when "enable" is active. From the logic
point of view, this is equivalent to a real clock-enable. But from
other points of view, like for example power consumption, it may not
be.

Yet it is good enough, and it helps achieving another goal: make a
whole design from nothing but synchronous logic! This has been a
major milestone in FPGA architecture. It's so much easier to do timing
analysis on purely synchronous designs. In fact, the current tools do
almost exclusively synchronous analysis ("static timing"). It was
easier to make designs synchronous, than to make the tools handle
asynchronous designs..

Using synchronous logic is very important for you. If you have any
timing problems with your design, then you've either not read the
timing report, or you've used non-synchronous tricks and are about to
regret them.

Your desire to enable clocks is very wide spread, and so the FPGA
makers have implemented support for their synchronous equivalent,
right in the hardware. The necessary extra logic input and the
feedback of the previous state is "free" in all modern (and not so
modern) FPGAs. There is dedicated circuitry just for this purpose.

The following code shows how to register something on every other
cycle. The tools will recognize it and use none of "your" resouces
for it.

process (clk)
begin
if rising_edge(clk) then
clkenable <= not(clkenable);
end if;
end process;

process (clk)
begin
if rising_edge(clk) then
if clkenable='1' then
reg_something <= combinatorial_something;
end if;
end if;
end process;

PS: There is another common desire for asynchronous logic in many
designs, specifically for RESET. Read about it in other threads on
this group or elsewhere. There's more opinion about it because doing
it wrong doesn't fail right away. Yet (in my opinion) you should also
go strictly synchronous because that's what the tools can handle.
 
Your approach is flawed. It will not work well because it is not in
line with the generally accepted way of FPGA programming. It uses
asynchronous logic, which is frowned upon because the tools don't
support it well. Insisting on using asynchronous logic will do you no
favor.

It's perfectly valid that you want a clock-enable. However, it's
unusual that you want the clock-enable to be centered "around the
clock edge". It probably stems from working with discrete chips, where
THAT was most reliable way to enable clocks.

In logic (discrete or FPGA), it's also possible to "enable" clocks by
adding the enable as extra logic input, plus feedback of the previous
output. Then you can "always clock" the register, yet make it only
accept (honor) the change when "enable" is active. From the logic
point of view, this is equivalent to a real clock-enable. But from
other points of view, like for example power consumption, it may not
be.

Yet it is good enough, and it helps achieving another goal: make a
whole design from nothing but synchronous logic! This has been a
major milestone in FPGA architecture. It's so much easier to do timing
analysis on purely synchronous designs. In fact, the current tools do
almost exclusively synchronous analysis ("static timing"). It was
easier to make designs synchronous, than to make the tools handle
asynchronous designs..

Using synchronous logic is very important for you. If you have any
timing problems with your design, then you've either not read the
timing report, or you've used non-synchronous tricks and are about to
regret them.

Your desire to enable clocks is very wide spread, and so the FPGA
makers have implemented support for their synchronous equivalent,
right in the hardware. The necessary extra logic input and the
feedback of the previous state is "free" in all modern (and not so
modern) FPGAs. There is dedicated circuitry just for this purpose.

The following code shows how to register something on every other
cycle. The tools will recognize it and use none of "your" resouces
for it.

process (clk)
begin
if rising_edge(clk) then
clkenable <= not(clkenable);
end if;
end process;

process (clk)
begin
if rising_edge(clk) then
if clkenable='1' then
reg_something <= combinatorial_something;
end if;
end if;
end process;

PS: There is another common desire for asynchronous logic in many
designs, specifically for RESET. Read about it in other threads on
this group or elsewhere. There's more opinion about it because doing
it wrong doesn't fail right away. Yet (in my opinion) you should also
go strictly synchronous because that's what the tools can handle.
 
Hi Jim,
using clock enables for multirate systems is a proper way, but you are
trying to do it unneccessary complicated.
It is much simpler.

You have a master clock, and a counter that provides the neccessary
frequency division.
So far so good.
Now you only need to create an impulse for a single clock period.
This can be done like this:

    clock_divider_counter_proc: process (reset, clock)
    begin
        if reset = '1' then
            count <= (others => '0');
            clock_divided_i <= '0';
        elsif rising_edge(clock) then
            count <= count + 1;
            -- clock_divided_i <= count(4); -- this would be too long
            if count = "11111" then
               clock_enable_clock_divided  <= 1;
           else
              clock_enable_clock_divided  <= 0;
           end if;
        end if;
    end process;
end behavioral;

That's all you need.
When assigning to  clock_enable_clock_divided the clock to output
delay and routing delay are sufficient to
keep the signal valid beyond the next rising clock edge.
(If that wouldn't work this way pipelining data from one register to
the next wouldn't work too, but it does.)

Have a nice synthesis
   Eilert
Eilert,

Thanks for the quick response. After I posted, I read that FPGAs
typically have 0 hold times so your approach seems great. Thanks for
the help.
 
On 16 Sep., 21:14, Jim <james.kn...@gmail.com> wrote:
Hi Jim,
using clock enables for multirate systems is a proper way, but you are
trying to do it unneccessary complicated.
It is much simpler.

You have a master clock, and a counter that provides the neccessary
frequency division.
So far so good.
Now you only need to create an impulse for a single clock period.
This can be done like this:

    clock_divider_counter_proc: process (reset, clock)
    begin
        if reset = '1' then
            count <= (others => '0');
            clock_divided_i <= '0';
        elsif rising_edge(clock) then
            count <= count + 1;
            -- clock_divided_i <= count(4); -- this would be too long
            if count = "11111" then
               clock_enable_clock_divided  <= 1;
           else
              clock_enable_clock_divided  <= 0;
           end if;
        end if;
    end process;
end behavioral;

That's all you need.
When assigning to  clock_enable_clock_divided the clock to output
delay and routing delay are sufficient to
keep the signal valid beyond the next rising clock edge.
(If that wouldn't work this way pipelining data from one register to
the next wouldn't work too, but it does.)

Have a nice synthesis
   Eilert

Eilert,

Thanks for the quick response.  After I posted, I read that FPGAs
typically have 0 hold times so your approach seems great.  Thanks for
the help.
Hi Jim,
well, it should be good, because it's been recommended in some XILINX
papers and used in their System Generator tool as the default method
for multirate systems. :)

Have a nice synthesis
Eilert
 

Welcome to EDABoard.com

Sponsor

Back
Top