Is this phase-accumulator trick well-known???

  • Thread starter Jonathan Bromley
  • Start date
J

Jonathan Bromley

Guest
hi comp.arch.fpga,

The question - repeated after the explanation -
is: here's what I think is a nifty trick; has
anyone seen it, or been aware of it, before?
I can't believe it's really new.

I have been messing around with baud rate generators
and suchlike - creating a pulse that's active for
one clock period at some required repetition rate -
and wanted to try a phase accumulator technique
instead of a simple divider. That makes it far
easier to specify the frequency - it's simply the
phase-delta input value - and easily allows for
non-integral divide ratios, at the cost of one
master clock period of jitter.

The phase-accumulator produces pulses with a
repetition rate of
Fc * M / N
where Fc is the master clock, M is the phase delta
and N is the counter's modulus. However, to get
the huge convenience of specifying M as the required
frequency, I must make N be equal to the frequency
of Fc, and this is unlikely to be an exact power of 2.
So the phase accumulator works like this:

on every clock pulse...
if (acc < 0) then
add := acc + N;
output_pulse <= '1';
else
output_pulse <= '0';
end if;
acc := acc - M; -- unconditionally

This is fine, but it means that on the "wrap-around"
clock cycle I must add either N-M to the accumulator;
if either M or N are variable, that costs me another
adder.

Today I came up with an intriguing (to me) alternative:
on the wrap-around cycle, add N to the accumulator;
on the immediately subsequent cycle, add (-2M); on
all other cycles, add (-M). This is of course rather
easy to do since 2M is just a left shift. A few
trial synthesis runs convinced me that it will give
measurably better performance than the two-adder
version. VHDL code is appended for anyone who wants
to play.

My question is: has this trick been published anywhere?
Or is it something that "those skilled in the art"
already know about? I haven't seen it before, but that
simply means I probably haven't looked hard enough.

Thanks!

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~ rate generator using novel wrap-around technique
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity rate_gen is
-- Specify the master clock frequency as a generic.
generic ( ref_Hz: positive := 50_000_000 );
port
( clock : in std_logic
; reset : in std_logic -- Synchronous reset.
; rate : in unsigned -- Desired output frequency
; pulse : out std_logic -- The output pulse train
);
end;

architecture RTL of rate_gen is
begin
process (clock)
-- variable "count" is the accumulator
variable count: integer range -2**rate'length to ref_Hz-1 := 0;
-- variable "overflow" is the output pulse and wraparound marker
variable overflow: std_logic := '0';
begin
if rising_edge(clock) then
if reset = '1' then
count := 0;
overflow := '0';
elsif count < 0 then
overflow := '1';
count := count + ref_Hz;
elsif overflow = '1' then
overflow := '0';
count := count - (to_integer(rate) * 2);
else
overflow := '0';
count := count - to_integer(rate);
end if;
pulse <= overflow;
end if;
end process;
end;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

--
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
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

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

My question is: has this trick been published anywhere?
I have not seen those simplifications.
It could be related to Allan's idea below,
but I haven't done the math.

http://groups.google.com/groups/search?q=dual+modulus+prescaler+num_bits

Or is it something that "those skilled in the art"
already know about?
Probably not until today ;)

-- Mike Treseler
 
On Sun, 08 Feb 2009 11:17:43 -0800, Mike Treseler wrote:

My question is: has this trick been published anywhere?

I have not seen those simplifications.
It could be related to Allan's idea below,
[dual modulus prescaler]

No, I don't think so. Allan Herriman's nice description
of the dual-modulus prescaler correctly points out that it
can often be made smaller than a phase accumulator, but
getting the details right for any given output frequency
is tiresome (or scripted, as he proposed). The
phase-accumulator has the property, very desirable
indeed for some applications, that you can simply
give it the desired pulse rate as a number - no other
calculations required.

One limitation that I forgot to mention in my original
post (because I hadn't noticed it, shame on me) is that
unlike a classic phase accumulator it is restricted to
output pulse rates no greater than Fc/2. If you ask
it to exceed that output rate, it will give wrong answers
because it can't cope with an output pulse train having
the output asserted on two consecutive clocks. You
could bullet-proof the design against that by including
the concurrent assertion

assert 2**rate'length-1 <= ref_Hz/2 report
"rate_gen rate input could have unsupported values > "
& integer'image(ref_Hz/2);
--
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
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

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

Welcome to EDABoard.com

Sponsor

Back
Top