FPGA Central - World's 1st FPGA / CPLD Portal

FPGA Central

World's 1st FPGA Portal

 

Go Back   FPGA Groups > NewsGroup > Verilog

Verilog comp.lang.verilog newsgroup / usenet

Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 07-25-2007, 11:33 AM
SB
Guest
 
Posts: n/a
Default variable clock frequency generation issue

Hi there,

I am working with a verilog behavioral model of a variable frequency
clock.
The model has two parts. The first part, through a series of case
statements selects the period
of the output clock signal. The second part of the model the
generates
the clock signal using the newly defined clock period.

Hence the second part looks similar to:
always
begin
#(half_period) clk_sig <= ~clk_sig;
end

The "half_period" term is a "real" quantity and its
value is decided by a set of case statements of inputs
to the block. I am using a real as the half_period is often assigned
very large decimal values with fractional components.

I wish that once the half_period value is updated, that the
clock signal generation code in the always block uses this new value
immediately. However, I
am finding that the clk_sig waveform does not use a new
value of half_period until the previous value of half_period has
completely
elapsed in the timing waveform.

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"?

I have tried using $realtobits on the half_period and using
the resulting wire in a sensitivity list on the always statement
but this does not work.

Thanks in advance

SB

Reply With Quote
  #2 (permalink)  
Old 07-25-2007, 05:11 PM
gabor
Guest
 
Posts: n/a
Default Re: variable clock frequency generation issue

On Jul 25, 5:33 am, SB <[email protected]> wrote:
> Hi there,
>
> I am working with a verilog behavioral model of a variable frequency
> clock.
> The model has two parts. The first part, through a series of case
> statements selects the period
> of the output clock signal. The second part of the model the
> generates
> the clock signal using the newly defined clock period.
>
> Hence the second part looks similar to:
> always
> begin
> #(half_period) clk_sig <= ~clk_sig;
> end
>


I wouldn't use a non-blocking assignment for this. In fact
I suspect you didn't either or your clock wouldn't work at
all.

> The "half_period" term is a "real" quantity and its
> value is decided by a set of case statements of inputs
> to the block. I am using a real as the half_period is often assigned
> very large decimal values with fractional components.
>
> I wish that once the half_period value is updated, that the
> clock signal generation code in the always block uses this new value
> immediately. However, I
> am finding that the clk_sig waveform does not use a new
> value of half_period until the previous value of half_period has
> completely
> elapsed in the timing waveform.
>
> 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"?
>
> I have tried using $realtobits on the half_period and using
> the resulting wire in a sensitivity list on the always statement
> but this does not work.
>


This sounds similar to what I would suggest. In what way
didn't it work? Did the compiler give an error or does it
just not do what you want? Did you write something like...

always @ (clk_sig or half_period_bits)
begin
clk_sig = #(half_period) ~clk_sig;
end

> Thanks in advance
>
> SB



Reply With Quote
  #3 (permalink)  
Old 07-25-2007, 05:45 PM
Chris Briggs
Guest
 
Posts: n/a
Default Re: variable clock frequency generation issue

SB wrote:
> I am working with a verilog behavioral model of a variable frequency
> clock.
> The model has two parts. The first part, through a series of case
> statements selects the period
> of the output clock signal. The second part of the model the
> generates
> the clock signal using the newly defined clock period.
>
> Hence the second part looks similar to:
> always
> begin
> #(half_period) clk_sig <= ~clk_sig;
> end


Has nothing to do with it being a real value. Has to do with that
thread blocking on a # delay and you can't change it while it's
waiting. However, you can abort it using disable. After the begin-end
is disabled, the always will restart it and it will use the new
half_period. Note: disable is non-synthesizable, but then, so are #
delays.

First, label the clock generator block, as in:

always begin : clock_gen
#(half_period) clk_sig = ~clk_sig;
end

And then, whenever half_period is updated, disable the block, as in:

always @(half_period)
disable clock_gen;

Alternatively, you could just add 'disable clock_gen;' after the
line(s) that changes half_period.

Also, as the other poster mentioned, there's usually no reason to use
a nonblocking assign in a clock generator.

-cb

Reply With Quote
  #4 (permalink)  
Old 07-25-2007, 07:43 PM
Jonathan Bromley
Guest
 
Posts: n/a
Default 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.
Reply With Quote
  #5 (permalink)  
Old 07-25-2007, 07:44 PM
Guest
 
Posts: n/a
Default Re: variable clock frequency generation issue


SB 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"?


When the #(half_period) is executed, the delay will be evaluated and
the process scheduled for that time in the future. Changing the delay
value will have no effect after that. As someone else said, the only
way to get it to wake up before that time would be a disable
statement.

I assume that when the half_period is modified, you want the time from
the previous edge to the next edge to become the half_period. You
don't say what should happen if the half_period gets changed at a time
that is already delayed from the previous edge by more than the new
delay. I would assume that you want the next edge to occur
immediately, since that is the best you can do in that situation.

As someone said, you can get the old delay to terminate with a
disable. But then you still need to get the next edge scheduled at
the proper time. The best mechanism I can see is to record the time
of each edge when you generate it. You need that information when the
delay gets disabled due to half_period changing, to figure out when
the next edge needs to be. With the time of the last edge plus the
new half_period, you can determine the new time for the next edge.
Then you can subtract the current time to get the required delay. If
the result is negative, you should delay by 0, since that is the best
you can do. This will be messy code. You should be considering
whether you really need this capability to respond before the next
edge.

Reply With Quote
  #6 (permalink)  
Old 07-26-2007, 08:38 PM
SB
Guest
 
Posts: n/a
Default Re: variable clock frequency generation issue

On Jul 25, 4:45 pm, Chris Briggs <[email protected]> wrote:
> SB wrote:
> > I am working with a verilog behavioral model of a variable frequency
> > clock.
> > The model has two parts. The first part, through a series of case
> > statements selects the period
> > of the output clock signal. The second part of the model the
> > generates
> > the clock signal using the newly defined clock period.

>
> > Hence the second part looks similar to:
> > always
> > begin
> > #(half_period) clk_sig <= ~clk_sig;
> > end

>
> Has nothing to do with it being a real value. Has to do with that
> thread blocking on a # delay and you can't change it while it's
> waiting. However, you can abort it using disable. After the begin-end
> is disabled, the always will restart it and it will use the new
> half_period. Note: disable is non-synthesizable, but then, so are #
> delays.
>
> First, label the clock generator block, as in:
>
> always begin : clock_gen
> #(half_period) clk_sig = ~clk_sig;
> end
>
> And then, whenever half_period is updated, disable the block, as in:
>
> always @(half_period)
> disable clock_gen;
>
> Alternatively, you could just add 'disable clock_gen;' after the
> line(s) that changes half_period.
>
> Also, as the other poster mentioned, there's usually no reason to use
> a nonblocking assign in a clock generator.
>
> -cb




Hi All,

I tried the method of labelling the always block and then
aborting the wait time with a disable command when the new
half_period has been defined. The labelled always
block then picks up the new half_period value and it
progresses properly. This has worked for the
preliminary testing so far. I will test this with further
values going forward and update soon if there are any further
issues.

Thank you to everyone for taking an interest in this.

SB

Reply With Quote
  #7 (permalink)  
Old 07-26-2007, 08:40 PM
SB
Guest
 
Posts: n/a
Default Re: variable clock frequency generation issue

On Jul 25, 6:43 pm, Jonathan Bromley <[email protected]>
wrote:
> 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]://www.MYCOMPANY.com
>
> The contents of this message may contain personal views which
> are not the views of Doulos Ltd., unless specifically stated.



Hi Jonathan

I have replied to the other post whose solution
got me out of this particular rut. I like the
analysis that you have done on the problem and I
must adopt this method to other problems in future.

SB

Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Generation of Divided-by-3 clock K. Sudheer Kumar Verilog 3 01-19-2007 03:14 PM
Divide by 3/2 clock generation with 50% duty cycle? rsk Verilog 7 07-25-2005 09:36 PM
frequency divider bharathi Verilog 5 12-30-2004 07:16 AM
Random number generation in Windows - how to use wall clock? FGreen Verilog 2 10-27-2004 04:40 PM
frequency synthesizer Carson Verilog 1 08-27-2004 05:38 PM


All times are GMT +1. The time now is 02:04 PM.


Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
Copyright 2008 @ FPGA Central. All rights reserved