Non-binary NCO Modulus...

R

Rick C

Guest
I recall digging deeply into NCO design some years ago. I am trying 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.

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 theory 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 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 adders (subtractors).

Maybe it is the sum of the step size and the modulus which is then 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 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 trying to remember how it all went.

--

Rick C.

- Get 1,000 miles of free Supercharging
- Tesla referral code - https://ts.la/richard11209
 
On Tuesday, September 15, 2020 at 2:12:16 PM UTC-6, gnuarm.del...@gmail.com wrote:
I recall digging deeply into NCO design some years ago. I am trying 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.

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 theory 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 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 adders (subtractors).

Maybe it is the sum of the step size and the modulus which is then 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 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 trying to remember how it all went.

--

Rick C.

- Get 1,000 miles of free Supercharging
- Tesla referral code - https://ts.la/richard11209

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 accumulator 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 radians

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 with a frequency of Fclk*7/22.
 
Am 16.09.20 um 18:17 schrieb Kevin Neilson:

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 accumulator 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 radians

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 with a frequency of Fclk*7/22.

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
 
On Wednesday, September 16, 2020 at 12:17:26 PM UTC-4, Kevin Neilson wrote:
On Tuesday, September 15, 2020 at 2:12:16 PM UTC-6, gnuarm.del...@gmail.com wrote:
I recall digging deeply into NCO design some years ago. I am trying 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.

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 theory 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 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 adders (subtractors).

Maybe it is the sum of the step size and the modulus which is then 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 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 trying to remember how it all went.

--

Rick C.

- Get 1,000 miles of free Supercharging
- Tesla referral code - https://ts.la/richard11209

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 accumulator 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 radians

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 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 outputting 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 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 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 it 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 resolution.

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

--

Rick C.

+ Get 1,000 miles of free Supercharging
+ Tesla referral code - https://ts.la/richard11209
 
On Wednesday, September 16, 2020 at 12:53:58 PM UTC-4, Gerhard Hoffmann wrote:
Am 16.09.20 um 18:17 schrieb Kevin Neilson:

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 accumulator 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 radians

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 with a frequency of Fclk*7/22.


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

I used a partly non-binary NCO in a program I wrote some years ago. On returning to the code I couldn\'t figure out what I was doing. It had to do with getting the sample rate to exactly the right number from a clock or something. 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 allow folding of the sine table.

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

--

Rick C.

-- Get 1,000 miles of free Supercharging
-- Tesla referral code - https://ts.la/richard11209
 
onsdag den 16. september 2020 kl. 19.47.03 UTC+2 skrev Rick C:
On Wednesday, September 16, 2020 at 12:17:26 PM UTC-4, Kevin Neilson wrote:
On Tuesday, September 15, 2020 at 2:12:16 PM UTC-6, gnuarm.del...@gmail..com wrote:
I recall digging deeply into NCO design some years ago. I am trying 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.

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 theory 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 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 adders (subtractors).

Maybe it is the sum of the step size and the modulus which is then 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 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 trying to remember how it all went.

--

Rick C.

- Get 1,000 miles of free Supercharging
- Tesla referral code - https://ts.la/richard11209

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 accumulator 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 radians

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 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 outputting 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 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 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 it 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 resolution.

I was just trying to remember if I am missing something simple for using 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


 
On Thursday, September 17, 2020 at 12:37:34 PM UTC-4, lasselangwad...@gmail..com wrote:
onsdag den 16. september 2020 kl. 19.47.03 UTC+2 skrev Rick C:
On Wednesday, September 16, 2020 at 12:17:26 PM UTC-4, Kevin Neilson wrote:
On Tuesday, September 15, 2020 at 2:12:16 PM UTC-6, gnuarm.del...@gmail.com wrote:
I recall digging deeply into NCO design some years ago. I am trying 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.

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 theory 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 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 adders (subtractors).

Maybe it is the sum of the step size and the modulus which is then 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 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 trying to remember how it all went.

--

Rick C.

- Get 1,000 miles of free Supercharging
- Tesla referral code - https://ts.la/richard11209

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 accumulator 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 radians

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 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 outputting 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 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 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 it 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 resolution.

I was just trying to remember if I am missing something simple for using 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

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 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 accumulator 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 resolution 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.

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 even more complex phase accumulator because the upper part will be binary, the 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
-+ Tesla referral code - https://ts.la/richard11209
 
torsdag den 17. september 2020 kl. 19.58.57 UTC+2 skrev Rick C:
On Thursday, September 17, 2020 at 12:37:34 PM UTC-4, lasselangwad...@gmail.com wrote:
onsdag den 16. september 2020 kl. 19.47.03 UTC+2 skrev Rick C:
On Wednesday, September 16, 2020 at 12:17:26 PM UTC-4, Kevin Neilson wrote:
On Tuesday, September 15, 2020 at 2:12:16 PM UTC-6, gnuarm.del...@gmail.com wrote:
I recall digging deeply into NCO design some years ago. I am trying 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.

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 theory 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 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 adders (subtractors).

Maybe it is the sum of the step size and the modulus which is then 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 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 trying to remember how it all went.

--

Rick C.

- Get 1,000 miles of free Supercharging
- Tesla referral code - https://ts.la/richard11209

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 accumulator 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 radians

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 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 outputting 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 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 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 it 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 resolution.

I was just trying to remember if I am missing something simple for using 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

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 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 accumulator 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 resolution 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.

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 even more complex phase accumulator because the upper part will be binary, the 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.

by why it exactly 1Hz important?
 
On Thursday, September 17, 2020 at 2:44:04 PM UTC-4, lasselangwad...@gmail.com wrote:
torsdag den 17. september 2020 kl. 19.58.57 UTC+2 skrev Rick C:
On Thursday, September 17, 2020 at 12:37:34 PM UTC-4, lasselangwad...@gmail.com wrote:
onsdag den 16. september 2020 kl. 19.47.03 UTC+2 skrev Rick C:
On Wednesday, September 16, 2020 at 12:17:26 PM UTC-4, Kevin Neilson wrote:
On Tuesday, September 15, 2020 at 2:12:16 PM UTC-6, gnuarm.del...@gmail.com wrote:
I recall digging deeply into NCO design some years ago. I am trying 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.

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 theory 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 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 adders (subtractors).

Maybe it is the sum of the step size and the modulus which is then 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 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 trying to remember how it all went.

--

Rick C.

- Get 1,000 miles of free Supercharging
- Tesla referral code - https://ts.la/richard11209

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 accumulator 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 radians

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 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 outputting 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 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 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 it 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 resolution.

I was just trying to remember if I am missing something simple for using 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

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 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 accumulator 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 resolution 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.

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 even more complex phase accumulator because the upper part will be binary, the 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.


by why it exactly 1Hz important?

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

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

Here\'s a trade off I have no insight to resolve. I can clock at 32.0 MHz with 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. Probably 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 reasonably close. Everything has tolerances. The oscillator is only ±25 ppm. That\'s about twice the error of the off divisor. I guess I\'m trying to be a bit too precise with the numbers.

--

Rick C.

+- Get 1,000 miles of free Supercharging
+- Tesla referral code - https://ts.la/richard11209
 

Welcome to EDABoard.com

Sponsor

Back
Top