Non-binary NCO Modulus

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 
 Click to see the full signature
Reply to
Rick C
Loading thread data ...

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.

theory can use the same hardware as the subtractor borrow out.

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).

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.

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

Reply to
Kevin Neilson

Am 16.09.20 um 18:17 schrieb Kevin Neilson:

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

Reply to
Gerhard Hoffmann

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.

n theory can use the same hardware as the subtractor borrow out.

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).

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.

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:

ans

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 
 Click to see the full signature
Reply to
Rick C

On Wednesday, September 16, 2020 at 12:53:58 PM UTC-4, Gerhard Hoffmann wro te:

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:

dians

e with a frequency of Fclk*7/22.

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 
 Click to see the full signature
Reply to
Rick C

onsdag den 16. september 2020 kl. 19.47.03 UTC+2 skrev Rick C:

e:

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.

in theory can use the same hardware as the subtractor borrow out.

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).

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.

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:

dians

e with a frequency of Fclk*7/22.

ry value. But more importantly, the output value range is defined. So out putting 2^n-1 is not a valid value.

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.

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.

non-binarly moduli. Is that a word, moduli?

what the point of the non binary numbers? upper ten bits out of the

+10bit bit phase accumulator, into 10bit pwm, done
Reply to
lasselangwadtchristensen

ote:

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.

it in theory can use the same hardware as the subtractor borrow out.

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).

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.

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:

radians

ble with a frequency of Fclk*7/22.

rary value. But more importantly, the output value range is defined. So o utputting 2^n-1 is not a valid value.

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.

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.

g non-binarly moduli. Is that a word, moduli?

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 
 Click to see the full signature
Reply to
Rick C

torsdag den 17. september 2020 kl. 19.58.57 UTC+2 skrev Rick C:

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.

e it in theory can use the same hardware as the subtractor borrow out.

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).

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.

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:

t radians

nable with a frequency of Fclk*7/22.

itrary value. But more importantly, the output value range is defined. So outputting 2^n-1 is not a valid value.

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.

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.

ing non-binarly moduli. Is that a word, moduli?

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.

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.

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

y hard at all. I was just trying to remember some "trick" someone had post ed about this some 10 years ago.

by why it exactly 1Hz important?

Reply to
lasselangwadtchristensen

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.

use it in theory can use the same hardware as the subtractor borrow out.

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).

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.

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:

get radians

enable with a frequency of Fclk*7/22.

rbitrary value. But more importantly, the output value range is defined. So outputting 2^n-1 is not a valid value.

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.

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

  1. It also approximates the required step values well using an eighth of a Hz resolution.

using non-binarly moduli. Is that a word, moduli?

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.

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.

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

lly hard at all. I was just trying to remember some "trick" someone had po sted about this some 10 years ago.

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 
 Click to see the full signature
Reply to
Rick C

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.