Non-binary NCO Modulus

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
I recall digging deeply into NCO design some years ago.  I am trying to rem
ember the dirty details of what I had learned.  In particular I have a non-
binary modulus.  I'd like to find the simplest way to implement this.  This
 is the best I can think of now, but I want to say someone had come up with
 a really nice way to code this that was optimally simple and produced opti
mally simple implementation.  

  elsif (rising_edge(Clk)) then
    if (PWM_Clk) then
      if (NCO_Accum - Phase_Step < 0) then
        NCO_Accum  := NCO_Accum - Phase_Step;
      else
        NCO_Accum  := NCO_Accum - Phase_Step + NCO_Mod;
      end if;
    end if;
  end if;

I use the condition (NCO_Accum - Phase_Step < 0) in the IF because it in th
eory can use the same hardware as the subtractor borrow out.  

I can't recall the detail, but I want to say someone had a solution that co
uld do this with one adder, but maybe with a mux.  Or maybe I'm not remembe
ring right and it was a mux with another adder that was not part of the cri
tical timing path.  I just can't see how to do this without the two adders  
(subtractors).  

Maybe it is the sum of the step size and the modulus which is then muxed wi
th the step size before the subtraction.  I bet that's what I'm thinking of
.  I believe that will mess up the idea of sharing the carry chain for the  
conditional logic.  I need to pull the difference out of the conditional I  
guess.  I don't really need speed, so that's not an issue.  I am just tryin
g to remember how it all went.  

--  

  Rick C.

  - Get 1,000 miles of free Supercharging
We've slightly trimmed the long signature. Click to see the full one.
Re: Non-binary NCO Modulus
On Tuesday, September 15, 2020 at 2:12:16 PM UTC-6, snipped-for-privacy@gmail.com
 wrote:
Quoted text here. Click to load it
member the dirty details of what I had learned. In particular I have a non-
binary modulus. I'd like to find the simplest way to implement this. This i
s the best I can think of now, but I want to say someone had come up with a
 really nice way to code this that was optimally simple and produced optima
lly simple implementation.  
Quoted text here. Click to load it
theory can use the same hardware as the subtractor borrow out.  
Quoted text here. Click to load it
could do this with one adder, but maybe with a mux. Or maybe I'm not rememb
ering right and it was a mux with another adder that was not part of the cr
itical timing path. I just can't see how to do this without the two adders  
(subtractors).  
Quoted text here. Click to load it
with the step size before the subtraction. I bet that's what I'm thinking o
f. I believe that will mess up the idea of sharing the carry chain for the  
conditional logic. I need to pull the difference out of the conditional I g
uess. I don't really need speed, so that's not an issue. I am just trying t
o remember how it all went.  
Quoted text here. Click to load it

By "non-binary" I guess you mean not a power-of-2.  The important ratio is  
Phase_Step/NCO_Mod, so there's no reason that NCO_Mod can't be a power of 2
.  Just change Phase_Step accordingly.  For example, say I want the accumul
ator phase vector to rotate at a rate of 7/22 * Fclk and I'm using a 16-bit
 accumulator, then, in Verilog:

parameter Phase_Step = 2**16*7/22; // Returns floor of result
reg [15:0] NCO_Accum; // phase vector; multiply by 2*Pi/2**16 to get radian
s

always@(posedge clk) NCO_Accum <= NCO_Accum + Phase_Step;  // NCO_Mod =
 2**16


Then you can use the rising edge of the MSB of NCO_Accum as a clk enable wi
th a frequency of Fclk*7/22.


Re: Non-binary NCO Modulus
Am 16.09.20 um 18:17 schrieb Kevin Neilson:

Quoted text here. Click to load it

Stanford once had a BCD DDS. It had the advantage that you can get
EXACTLY 10 MHz from a 100 MHz clock, and that the frequencies are
just like dialed in.

I have put a sinetab on opencores some years ago, that could
be changed to BCD or whatever quite easily.

cheers, Gerhard


Re: Non-binary NCO Modulus
On Wednesday, September 16, 2020 at 12:53:58 PM UTC-4, Gerhard Hoffmann wro
te:
Quoted text here. Click to load it
 is Phase_Step/NCO_Mod, so there's no reason that NCO_Mod can't be a power  
of 2.  Just change Phase_Step accordingly.  For example, say I want the acc
umulator phase vector to rotate at a rate of 7/22 * Fclk and I'm using a 16
-bit accumulator, then, in Verilog:
Quoted text here. Click to load it
dians
 = 2**16
Quoted text here. Click to load it
e with a frequency of Fclk*7/22.
Quoted text here. Click to load it

I used a partly non-binary NCO in a program I wrote some years ago.  On ret
urning to the code I couldn't figure out what I was doing.  It had to do wi
th getting the sample rate to exactly the right number from a clock or some
thing.  Heck, I still don't recall, but it looked weird to program the step
 size.  In essence it was split into two parts, an upper binary part and a  
lower non-binary part.  Maybe it was so the top two bits were binary to all
ow folding of the sine table.  

This project uses a sawtooth wave, so I can use the phase output directly w
ith no sine lookup.  Great!  They say it will sound like an oboe.  The samp
le files do sound like that.  

--  

  Rick C.

  -- Get 1,000 miles of free Supercharging
We've slightly trimmed the long signature. Click to see the full one.
Re: Non-binary NCO Modulus
On Wednesday, September 16, 2020 at 12:17:26 PM UTC-4, Kevin Neilson wrote:
Quoted text here. Click to load it
om wrote:
Quoted text here. Click to load it
remember the dirty details of what I had learned. In particular I have a no
n-binary modulus. I'd like to find the simplest way to implement this. This
 is the best I can think of now, but I want to say someone had come up with
 a really nice way to code this that was optimally simple and produced opti
mally simple implementation.  
Quoted text here. Click to load it
n theory can use the same hardware as the subtractor borrow out.  
Quoted text here. Click to load it
t could do this with one adder, but maybe with a mux. Or maybe I'm not reme
mbering right and it was a mux with another adder that was not part of the  
critical timing path. I just can't see how to do this without the two adder
s (subtractors).  
Quoted text here. Click to load it
d with the step size before the subtraction. I bet that's what I'm thinking
 of. I believe that will mess up the idea of sharing the carry chain for th
e conditional logic. I need to pull the difference out of the conditional I
 guess. I don't really need speed, so that's not an issue. I am just trying
 to remember how it all went.  
Quoted text here. Click to load it
s Phase_Step/NCO_Mod, so there's no reason that NCO_Mod can't be a power of
 2.  Just change Phase_Step accordingly.  For example, say I want the accum
ulator phase vector to rotate at a rate of 7/22 * Fclk and I'm using a 16-b
it accumulator, then, in Verilog:
Quoted text here. Click to load it
ans
= 2**16
Quoted text here. Click to load it
with a frequency of Fclk*7/22.

For various reasons the step size is defined rather than being an arbitrary
 value.  But more importantly, the output value range is defined.  So outpu
tting 2^n-1 is not a valid value.  

I'm generating a sawtooth waveform using a PWM output.  The PWM is set for  
0 to 999.  This means I can't output any value from the phase accumulator o
utside this range.  If I make the PWM a 10 bit binary counter of 0 to 1023,
 other constraints then make the master clock frequency 2^n*1024*1000 or 32
,768,000 with a sample rate of 32000.  Yes, this can work if the phase step
 is not a integer divisor of 1, but I prefer to not do that.  

I don't know who will take over this code at some point so I want to make i
t easy to use.  I don't think using a non binary modulus is less confusing  
than non integer step sizes.  The ratios would be more like 1000/1024.  It  
also approximates the required step values well using an eighth of a Hz res
olution.  

I was just trying to remember if I am missing something simple for using no
n-binarly moduli.  Is that a word, moduli?  

--  

  Rick C.

  + Get 1,000 miles of free Supercharging
We've slightly trimmed the long signature. Click to see the full one.
Re: Non-binary NCO Modulus
onsdag den 16. september 2020 kl. 19.47.03 UTC+2 skrev Rick C:
Quoted text here. Click to load it
e:
Quoted text here. Click to load it
.com wrote:
Quoted text here. Click to load it
o remember the dirty details of what I had learned. In particular I have a  
non-binary modulus. I'd like to find the simplest way to implement this. Th
is is the best I can think of now, but I want to say someone had come up wi
th a really nice way to code this that was optimally simple and produced op
timally simple implementation.  
Quoted text here. Click to load it
 in theory can use the same hardware as the subtractor borrow out.  
Quoted text here. Click to load it
hat could do this with one adder, but maybe with a mux. Or maybe I'm not re
membering right and it was a mux with another adder that was not part of th
e critical timing path. I just can't see how to do this without the two add
ers (subtractors).  
Quoted text here. Click to load it
xed with the step size before the subtraction. I bet that's what I'm thinki
ng of. I believe that will mess up the idea of sharing the carry chain for  
the conditional logic. I need to pull the difference out of the conditional
 I guess. I don't really need speed, so that's not an issue. I am just tryi
ng to remember how it all went.  
Quoted text here. Click to load it
 is Phase_Step/NCO_Mod, so there's no reason that NCO_Mod can't be a power  
of 2.  Just change Phase_Step accordingly.  For example, say I want the acc
umulator phase vector to rotate at a rate of 7/22 * Fclk and I'm using a 16
-bit accumulator, then, in Verilog:
Quoted text here. Click to load it
dians
 = 2**16
Quoted text here. Click to load it
e with a frequency of Fclk*7/22.
Quoted text here. Click to load it
ry value.  But more importantly, the output value range is defined.  So out
putting 2^n-1 is not a valid value.  
Quoted text here. Click to load it
r 0 to 999.  This means I can't output any value from the phase accumulator
 outside this range.  If I make the PWM a 10 bit binary counter of 0 to 102
3, other constraints then make the master clock frequency 2^n*1024*1000 or  
32,768,000 with a sample rate of 32000.  Yes, this can work if the phase st
ep is not a integer divisor of 1, but I prefer to not do that.  
Quoted text here. Click to load it
 it easy to use.  I don't think using a non binary modulus is less confusin
g than non integer step sizes.  The ratios would be more like 1000/1024.  I
t also approximates the required step values well using an eighth of a Hz r
esolution.  
Quoted text here. Click to load it
non-binarly moduli.  Is that a word, moduli?  
Quoted text here. Click to load it

what the point of the non binary numbers? upper ten bits out of the  
+10bit bit phase accumulator, into 10bit pwm, done

  




Re: Non-binary NCO Modulus
On Thursday, September 17, 2020 at 12:37:34 PM UTC-4, lasselangwad...@gmail
.com wrote:
Quoted text here. Click to load it
ote:
Quoted text here. Click to load it
il.com wrote:
Quoted text here. Click to load it
 to remember the dirty details of what I had learned. In particular I have  
a non-binary modulus. I'd like to find the simplest way to implement this.  
This is the best I can think of now, but I want to say someone had come up  
with a really nice way to code this that was optimally simple and produced  
optimally simple implementation.  
Quoted text here. Click to load it
it in theory can use the same hardware as the subtractor borrow out.  
Quoted text here. Click to load it
 that could do this with one adder, but maybe with a mux. Or maybe I'm not  
remembering right and it was a mux with another adder that was not part of  
the critical timing path. I just can't see how to do this without the two a
dders (subtractors).  
Quoted text here. Click to load it
muxed with the step size before the subtraction. I bet that's what I'm thin
king of. I believe that will mess up the idea of sharing the carry chain fo
r the conditional logic. I need to pull the difference out of the condition
al I guess. I don't really need speed, so that's not an issue. I am just tr
ying to remember how it all went.  
Quoted text here. Click to load it
io is Phase_Step/NCO_Mod, so there's no reason that NCO_Mod can't be a powe
r of 2.  Just change Phase_Step accordingly.  For example, say I want the a
ccumulator phase vector to rotate at a rate of 7/22 * Fclk and I'm using a  
16-bit accumulator, then, in Verilog:
Quoted text here. Click to load it
radians
od = 2**16
Quoted text here. Click to load it
ble with a frequency of Fclk*7/22.
Quoted text here. Click to load it
rary value.  But more importantly, the output value range is defined.  So o
utputting 2^n-1 is not a valid value.  
Quoted text here. Click to load it
for 0 to 999.  This means I can't output any value from the phase accumulat
or outside this range.  If I make the PWM a 10 bit binary counter of 0 to 1
023, other constraints then make the master clock frequency 2^n*1024*1000 o
r 32,768,000 with a sample rate of 32000.  Yes, this can work if the phase  
step is not a integer divisor of 1, but I prefer to not do that.  
Quoted text here. Click to load it
ke it easy to use.  I don't think using a non binary modulus is less confus
ing than non integer step sizes.  The ratios would be more like 1000/1024.  
 It also approximates the required step values well using an eighth of a Hz
 resolution.  
Quoted text here. Click to load it
g non-binarly moduli.  Is that a word, moduli?  
Quoted text here. Click to load it

The math.  I need the frequency of the clock to be a multiple of 1 kHz so I
 can time 1 ms and also keep the step size a multiple of 1 Hz, or binary fr
action actually.  So it has to have a factor of 1000 no matter what.  Add i
n the 1k count for the PWM and the 1k count for the top of the phase accumu
lator to drive the PWM and you need a frequency of 125 * 2^20 (131.072 MHz)
 to be able to produce a 1 ms enable strobe for other parts of the circuit.
  Too high..  I could cut the PWM to 9 bits and use a 32.768 MHz clock.  It
 would give a 64 kHz sample clock, but I think that's ok.  

The phase accumulator has to be a lot more than 10 bits to get enough resol
ution to be accurate.  Those are bits of added resolution at the low end an
d other than wanting to make the step  size a simple binary multiple of 1 H
z, not a factor.  

So the PWM can be binary 9 bits binary.  The phase accumulator does need to
 have a non-binary factor to get the 1 Hz resolution though.  That is what  
I did on the other NCO with the split radix.  Hmmm... this may require an e
ven more complex phase accumulator because the upper part will be binary, t
he middle have 125 in it and the bottom binary again.  lol    

Maybe I should just stick to having a non-binary modulus.  It's not really  
hard at all.  I was just trying to remember some "trick" someone had posted
 about this some 10 years ago.  

--  

  Rick C.

  -+ Get 1,000 miles of free Supercharging
We've slightly trimmed the long signature. Click to see the full one.
Re: Non-binary NCO Modulus
torsdag den 17. september 2020 kl. 19.58.57 UTC+2 skrev Rick C:
Quoted text here. Click to load it
il.com wrote:
Quoted text here. Click to load it
wrote:
Quoted text here. Click to load it
mail.com wrote:
Quoted text here. Click to load it
ng to remember the dirty details of what I had learned. In particular I hav
e a non-binary modulus. I'd like to find the simplest way to implement this
. This is the best I can think of now, but I want to say someone had come u
p with a really nice way to code this that was optimally simple and produce
d optimally simple implementation.  
Quoted text here. Click to load it
e it in theory can use the same hardware as the subtractor borrow out.  
Quoted text here. Click to load it
on that could do this with one adder, but maybe with a mux. Or maybe I'm no
t remembering right and it was a mux with another adder that was not part o
f the critical timing path. I just can't see how to do this without the two
 adders (subtractors).  
Quoted text here. Click to load it
n muxed with the step size before the subtraction. I bet that's what I'm th
inking of. I believe that will mess up the idea of sharing the carry chain  
for the conditional logic. I need to pull the difference out of the conditi
onal I guess. I don't really need speed, so that's not an issue. I am just  
trying to remember how it all went.  
Quoted text here. Click to load it
atio is Phase_Step/NCO_Mod, so there's no reason that NCO_Mod can't be a po
wer of 2.  Just change Phase_Step accordingly.  For example, say I want the
 accumulator phase vector to rotate at a rate of 7/22 * Fclk and I'm using  
a 16-bit accumulator, then, in Verilog:
Quoted text here. Click to load it
t radians
_Mod = 2**16
Quoted text here. Click to load it
nable with a frequency of Fclk*7/22.
Quoted text here. Click to load it
itrary value.  But more importantly, the output value range is defined.  So
 outputting 2^n-1 is not a valid value.  
Quoted text here. Click to load it
t for 0 to 999.  This means I can't output any value from the phase accumul
ator outside this range.  If I make the PWM a 10 bit binary counter of 0 to
 1023, other constraints then make the master clock frequency 2^n*1024*1000
 or 32,768,000 with a sample rate of 32000.  Yes, this can work if the phas
e step is not a integer divisor of 1, but I prefer to not do that.  
Quoted text here. Click to load it
make it easy to use.  I don't think using a non binary modulus is less conf
using than non integer step sizes.  The ratios would be more like 1000/1024
.  It also approximates the required step values well using an eighth of a  
Hz resolution.  
Quoted text here. Click to load it
ing non-binarly moduli.  Is that a word, moduli?  
Quoted text here. Click to load it
 I can time 1 ms and also keep the step size a multiple of 1 Hz, or binary  
fraction actually.  So it has to have a factor of 1000 no matter what.  Add
 in the 1k count for the PWM and the 1k count for the top of the phase accu
mulator to drive the PWM and you need a frequency of 125 * 2^20 (131.072 MH
z) to be able to produce a 1 ms enable strobe for other parts of the circui
t.  Too high..  I could cut the PWM to 9 bits and use a 32.768 MHz clock.  
It would give a 64 kHz sample clock, but I think that's ok.  
Quoted text here. Click to load it
olution to be accurate.  Those are bits of added resolution at the low end  
and other than wanting to make the step  size a simple binary multiple of 1
 Hz, not a factor.  
Quoted text here. Click to load it
to have a non-binary factor to get the 1 Hz resolution though.  That is wha
t I did on the other NCO with the split radix.  Hmmm... this may require an
 even more complex phase accumulator because the upper part will be binary,
 the middle have 125 in it and the bottom binary again.  lol    
Quoted text here. Click to load it
y hard at all.  I was just trying to remember some "trick" someone had post
ed about this some 10 years ago.  
Quoted text here. Click to load it

by why it exactly 1Hz important?  


Re: Non-binary NCO Modulus
On Thursday, September 17, 2020 at 2:44:04 PM UTC-4, lasselangwad...@gmail.
com wrote:
Quoted text here. Click to load it
mail.com wrote:
Quoted text here. Click to load it
n wrote:
Quoted text here. Click to load it
@gmail.com wrote:
Quoted text here. Click to load it
ying to remember the dirty details of what I had learned. In particular I h
ave a non-binary modulus. I'd like to find the simplest way to implement th
is. This is the best I can think of now, but I want to say someone had come
 up with a really nice way to code this that was optimally simple and produ
ced optimally simple implementation.  
Quoted text here. Click to load it
use it in theory can use the same hardware as the subtractor borrow out.  
Quoted text here. Click to load it
tion that could do this with one adder, but maybe with a mux. Or maybe I'm  
not remembering right and it was a mux with another adder that was not part
 of the critical timing path. I just can't see how to do this without the t
wo adders (subtractors).  
Quoted text here. Click to load it
hen muxed with the step size before the subtraction. I bet that's what I'm  
thinking of. I believe that will mess up the idea of sharing the carry chai
n for the conditional logic. I need to pull the difference out of the condi
tional I guess. I don't really need speed, so that's not an issue. I am jus
t trying to remember how it all went.  
Quoted text here. Click to load it
 ratio is Phase_Step/NCO_Mod, so there's no reason that NCO_Mod can't be a  
power of 2.  Just change Phase_Step accordingly.  For example, say I want t
he accumulator phase vector to rotate at a rate of 7/22 * Fclk and I'm usin
g a 16-bit accumulator, then, in Verilog:
Quoted text here. Click to load it
get radians
CO_Mod = 2**16
Quoted text here. Click to load it
 enable with a frequency of Fclk*7/22.
Quoted text here. Click to load it
rbitrary value.  But more importantly, the output value range is defined.  
So outputting 2^n-1 is not a valid value.  
Quoted text here. Click to load it
set for 0 to 999.  This means I can't output any value from the phase accum
ulator outside this range.  If I make the PWM a 10 bit binary counter of 0  
to 1023, other constraints then make the master clock frequency 2^n*1024*10
00 or 32,768,000 with a sample rate of 32000.  Yes, this can work if the ph
ase step is not a integer divisor of 1, but I prefer to not do that.  
Quoted text here. Click to load it
o make it easy to use.  I don't think using a non binary modulus is less co
nfusing than non integer step sizes.  The ratios would be more like 1000/10
24.  It also approximates the required step values well using an eighth of  
a Hz resolution.  
Quoted text here. Click to load it
using non-binarly moduli.  Is that a word, moduli?  
Quoted text here. Click to load it
  
Quoted text here. Click to load it
so I can time 1 ms and also keep the step size a multiple of 1 Hz, or binar
y fraction actually.  So it has to have a factor of 1000 no matter what.  A
dd in the 1k count for the PWM and the 1k count for the top of the phase ac
cumulator to drive the PWM and you need a frequency of 125 * 2^20 (131.072  
MHz) to be able to produce a 1 ms enable strobe for other parts of the circ
uit.  Too high..  I could cut the PWM to 9 bits and use a 32.768 MHz clock.
  It would give a 64 kHz sample clock, but I think that's ok.  
Quoted text here. Click to load it
esolution to be accurate.  Those are bits of added resolution at the low en
d and other than wanting to make the step  size a simple binary multiple of
 1 Hz, not a factor.  
Quoted text here. Click to load it
d to have a non-binary factor to get the 1 Hz resolution though.  That is w
hat I did on the other NCO with the split radix.  Hmmm... this may require  
an even more complex phase accumulator because the upper part will be binar
y, the middle have 125 in it and the bottom binary again.  lol    
Quoted text here. Click to load it
lly hard at all.  I was just trying to remember some "trick" someone had po
sted about this some 10 years ago.  
Quoted text here. Click to load it

Ease of use and the ability to get exact results.  Use some integer ratio s
tep size to Hz ratio and more bits are needed to get close to the desired r
esults.  

Is that really an issue?  The NCO is not hard to design.  In fact it is don
e.  I was just trying to find out if there are better ways of expressing th
e design.  

Here's a trade off I have no insight to resolve.  I can clock at 32.0 MHz w
ith a 1,000 modulus PWM clocked at 32,000 SPS or I can go with a 32.768 MHz
 clock and have the option of a 512 modulus PWM clocked at 64,000 Hz SPS.  
Not sure which is better for the quality of the reproduced signal.  Probabl
y close to a wash.  

33,554,432 Hz can give a 1024 modulus PWM at 32,768 SPS, but won't give a 1
 ms enable with any divisor.  I suppose I could pick a divisor to get reaso

pm.  That's about twice the error of the off divisor.  I guess I'm trying t
o be a bit too precise with the numbers.  

--  

  Rick C.

  +- Get 1,000 miles of free Supercharging
We've slightly trimmed the long signature. Click to see the full one.

Site Timeline