View Single Post
07-25-2007, 07:43 PM
 Jonathan Bromley Guest Posts: n/a
Re: variable clock frequency generation issue

On Wed, 25 Jul 2007 02:33:14 -0700, SB <[email protected]> wrote:

>Can anybody suggest what how I should correct this and
>ensure that the "always" block will instantaneously pick-up
>the new value of the "half_period"?

This is actually much trickier than it sounds - tricky to
specify correctly. Suppose your current "half-period" is
10. Suppose, too, that the last transition happened at
time 10, so the next transition is going to happen at 20.
Consider the following possibilities:

1) At time 15, change the half-period to 7.
I think you're saying that you want to have the next
transitions happen at 17, 24, ... whereas at present
your code of course waits until 20 before doing
anything, so you get transitions at 20, 27, 34, ...

2) At time 15, change the half-period to 20.
In this case, I guess you want the next transitions
to be 30, 50, ... whereas your existing code
would give 20, 40, 60, ...

3) At time 15, change the half-period to 2.
What do you want to happen here? The only sensible
behaviour I can see is to put transitions at 15, 17, 19 ...
but that has the odd effect that you get a half-period of
5 (10->15) which is neither of the two values.

So here's the algorithm I see:

- At any given time, the next transition should happen
at (previous transition) + half_period.
- If that next-transition time is earlier than "now",
we have case (3) - the half-period was suddenly made
much shorter - and we should make a transition
immediately.

In any case, this means that whenever the half-period
changes, you need to kill off the code that would otherwise
generate the next transition, and replace it. Something
like this...

integer half_period; // external controller can set this
reg clock; // this is the clock signal

initial begin : special_clock_generator

// internal variables for the clock generator
integer generator_delay;
time last_transition;

// Common initialisations
clock = 0;
half_period = <appropriate initial value>;
generator_delay = half_period;

// Parallel threads to monitor half_period and to generate clock
fork
forever begin : transition_generator
#generator_delay clock = ~clock;
last_transition = \$time;
generator_delay = half_period;
end
forever @(half_period) begin : transition_calculator
integer next_transition;
// compute appropriate delay
next_transition = (last_transition + half_period) - \$time;
if (next_transition < 0) next_transition = 0;
generator_delay = next_transition;
disable transition_generator; // kill off generator
end
join
end

Does this make sense?
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
[email protected]
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.