Author Topic: Quarter wave symmetry of sine wave using Verilog (SOLVED)  (Read 2082 times)

0 Members and 1 Guest are viewing this topic.

Offline knightTopic starter

  • Regular Contributor
  • *
  • Posts: 50
  • Country: sg
Quarter wave symmetry of sine wave using Verilog (SOLVED)
« on: October 12, 2022, 06:19:37 am »
Hi all, I'm trying to create a sine wave using the quarter wave symmetry property. I have followed the attached block diagram and not getting output for 1MHz frequency, which appears to have small peaks during change from one quadrant to another. I have attached the Vivado project and the output waveform. Can someone please help me to debug the code?

Edit: The issue is solved, and all files are in the zip file if anyone is interested in the project.

« Last Edit: October 24, 2022, 09:31:25 am by knight »
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2812
  • Country: nz
Re: Quarter wave symmetry of sine wave using Verilog
« Reply #1 on: October 12, 2022, 08:39:04 am »
Their is a difference in latency between the  'pa_out' signal and the 's_lut_out', because the lookup table's output is registered.

Code: [Select]
lut_complementer # (
                .N(17)
                )
                C2 (
                .clk(clk), .rst(rst), .msb_in(pa_out[11]),
                .comp_in(s_lut_out), .comp_out(s_out)
                );
You want to delay pa_out[11] by one cycle.
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: knight

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2812
  • Country: nz
Re: Quarter wave symmetry of sine wave using Verilog
« Reply #2 on: October 12, 2022, 09:11:11 am »
Oh and your LUT table is slightly wrong....

Table entry x should be

Code: [Select]
   table[x] = sin((2*x+1)/(2*table_size)*PI/2)

not the current

Code: [Select]
   table[x] = sin(x/table_size)*PI/2) 

With the current LUT values, if you walks slowly around the circle you will get what looks to be 'crossover distortion':

Code: [Select]
11111111101101001    -table[3]
11111111110011011    -table[2]
11111111111001110    -table[1]
00000000000000000    -table[0]
00000000000000000     table[0]
00000000000110010     table[1]
00000000001100101     table[2]
00000000010010111     table[3]
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: knight

Offline knightTopic starter

  • Regular Contributor
  • *
  • Posts: 50
  • Country: sg
Re: Quarter wave symmetry of sine wave using Verilog
« Reply #3 on: October 12, 2022, 10:22:41 am »
Oh and your LUT table is slightly wrong....

Table entry x should be

Code: [Select]
   table[x] = sin((2*x+1)/(2*table_size)*PI/2)

I'm using this code for the sine/cosine look-up table values. It works fine without using symmetry properties, not sure why it's not working in this case.

How do I modify this code to your equation?
table
  • = sin((2*x+1)/(2*table_size)*PI/2)
Code: [Select]
#include <stdio.h>
#include <math.h>
#define POINTS 512
#define BITS   8
void dec2bin(int);

int main(void)
{
  int n;

  for (n=0; n<POINTS; n++)
  {
printf("assign sine_rom[");
printf("%d",n);
printf("] = 8'b");
    dec2bin((int)floor(0.5 + ((1 << (BITS-1)) - 0.50001) * sin(2 * 3.1415926535897932 / POINTS * n)));
  }
  return 0;
}

void dec2bin(int c)
{
   int i = 0;
   for(i = (BITS-1); i >= 0; i--)
   {
     if((c & (1 << i)) != 0)
     {
       printf("1");
     }
     else
     {
       printf("0");
     }
   }
   printf(";");
   printf("\n");
}
« Last Edit: October 12, 2022, 05:12:54 pm by knight »
 

Offline knightTopic starter

  • Regular Contributor
  • *
  • Posts: 50
  • Country: sg
Re: Quarter wave symmetry of sine wave using Verilog
« Reply #4 on: October 12, 2022, 05:18:48 pm »
Their is a difference in latency between the  'pa_out' signal and the 's_lut_out', because the lookup table's output is registered.

Code: [Select]
lut_complementer # (
                .N(17)
                )
                C2 (
                .clk(clk), .rst(rst), .msb_in(pa_out[11]),
                .comp_in(s_lut_out), .comp_out(s_out)
                );
You want to delay pa_out[11] by one cycle.

The pa_out is also registerised if you check the phase_accum module. In top level ddfs, wire is just used to connect the internal signals.
 

Offline knightTopic starter

  • Regular Contributor
  • *
  • Posts: 50
  • Country: sg
Re: Quarter wave symmetry of sine wave using Verilog
« Reply #5 on: October 13, 2022, 04:08:51 am »
Their is a difference in latency between the  'pa_out' signal and the 's_lut_out', because the lookup table's output is registered.

Code: [Select]
lut_complementer # (
                .N(17)
                )
                C2 (
                .clk(clk), .rst(rst), .msb_in(pa_out[11]),
                .comp_in(s_lut_out), .comp_out(s_out)
                );
You want to delay pa_out[11] by one cycle.

The pa_out is also registerised if you check the phase_accum module. In top level ddfs, wire is just used to connect the internal signals.
Sorry, you were right. Delaying by two clock cycles fixed the "crossover" problem. I didn't change the LUT though.
Code: [Select]
reg dly1, dly2;
always @(posedge clk or negedge rst)
begin
if (~rst)
begin
    dly1 <= 0;
    dly2 <= 0;
end
else
begin
    dly1 <= pa_out[11];
    dly2 <= dly1;
end
end
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2812
  • Country: nz
Re: Quarter wave symmetry of sine wave using Verilog
« Reply #6 on: October 13, 2022, 07:15:02 am »
How do I modify this code to your equation?

Code: [Select]
#include <stdio.h>
#include <math.h>
#define POINTS 512
#define BITS   8
void dec2bin(int);

int main(void)
{
  int n;

  for (n=0; n<POINTS; n++)
  {
printf("assign sine_rom[");
printf("%d",n);
printf("] = 8'b");
    dec2bin((int)floor(0.5 + ((1 << (BITS-1)) - 0.50001) * sin(2 * 3.1415926535897932 / POINTS * n)));
  }
  return 0;
}

void dec2bin(int c)
{
   int i = 0;
   for(i = (BITS-1); i >= 0; i--)
   {
     if((c & (1 << i)) != 0)
     {
       printf("1");
     }
     else
     {
       printf("0");
     }
   }
   printf(";");
   printf("\n");
}

Replace
Code: [Select]
    dec2bin((int)floor(0.5 + ((1 << (BITS-1)) - 0.50001) * sin(2 * 3.1415926535897932 / POINTS * n)));

with

Code: [Select]
    double scale = 0.5 + ((1 << (BITS-1)) - 0.50001);
    double angle = 2 * M_PI / (2*POINTS) * (2*n+1);
    dec2bin((int)(scale * sin(angle)));
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 
The following users thanked this post: knight

Offline knightTopic starter

  • Regular Contributor
  • *
  • Posts: 50
  • Country: sg
Re: Quarter wave symmetry of sine wave using Verilog
« Reply #7 on: October 22, 2022, 03:55:17 pm »
Hi all, I'm trying to create a sine wave using the quarter wave symmetry property. I have followed the attached block diagram and got all the proper outputs except the sine wave output, which appears to have small peaks during change from one quadrant to another. I have attached the Vivado project and the output waveform. Can someone please help me to debug the code?

I completed the code for both sine and cosine wave and I'm getting output for all frequencies but not 1 MHz, as you can see, there is peaks when sine goes from one quadrant to another. The output is clean for other frequencies. The frequency tuning word or fcw is calculated as:

FCW = (Fout * 2^(n))/Fclk

So, for Fout = 1 MHz, n = 20-bits and Fclk = 100 MHz, FCW = 10486. In the testbench you can put any value for FCW (Fout less than 1/10 Fclk), and you would get a proper output, just not for 1MHz, that's my issue.


Thanks.
« Last Edit: October 22, 2022, 03:59:22 pm by knight »
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2812
  • Country: nz
Re: Quarter wave symmetry of sine wave using Verilog
« Reply #8 on: October 23, 2022, 02:07:05 am »
I am pretty sure that 1,000,000 x 2^20 will cause an integer overflow.

Could that be your problem?
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline knightTopic starter

  • Regular Contributor
  • *
  • Posts: 50
  • Country: sg
Re: Quarter wave symmetry of sine wave using Verilog
« Reply #9 on: October 23, 2022, 06:52:06 am »
I am pretty sure that 1,000,000 x 2^20 will cause an integer overflow.

Could that be your problem?
Phase word is hard coded in the program and not calculated using the expression.
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2812
  • Country: nz
Re: Quarter wave symmetry of sine wave using Verilog
« Reply #10 on: October 24, 2022, 04:24:42 am »
I am pretty sure that 1,000,000 x 2^20 will cause an integer overflow.

Could that be your problem?
Phase word is hard coded in the program and not calculated using the expression.
If you are able to post a zip of the .v files, including the testbench that demonstrates the problem, I'll have a look at it..
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline knightTopic starter

  • Regular Contributor
  • *
  • Posts: 50
  • Country: sg
Re: Quarter wave symmetry of sine wave using Verilog
« Reply #11 on: October 24, 2022, 09:29:08 am »
I am pretty sure that 1,000,000 x 2^20 will cause an integer overflow.

Could that be your problem?
Phase word is hard coded in the program and not calculated using the expression.
If you are able to post a zip of the .v files, including the testbench that demonstrates the problem, I'll have a look at it..

Everything is in the Vivado project folder bro, you just need to open the .xpr file in Xilinx vivado and everything is there.

You can find the .v files in srcs folder.

By the way, I fixed the issue. I followed the block diagram, and you can see that PA complementor outputs (k-2) bits but I coded it to output (k-2+1) bits, so that was causing the problem. Now it works for all FCW values. I updated the .zip files if you want to try it out and maybe you can do a more thorough testing?
« Last Edit: October 24, 2022, 09:32:45 am by knight »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf