3
\$\begingroup\$

I am performing direct digital synthesis on my FPGA using lookup tables, and jumping through them to increase output frequency.

As the value of the phase accumulator increases, the sine wave becomes increasingly distorted, which isn't a problem since I have a low pass filter (not my domain.) The issue is that the output deviation increases heavily.

I have a couple of questions:

  1. I understand why the distortion in the sine wave occurs, but why is there a deviation in output frequency? I developed a formula for my DAC. The deviation is quite a lot. Why does this variation occur?
  2. How do I accurately generate 100kHz? My phase accumulator is 32 bits, and my LUT is 10-bit. I can't increase it too much due to memory considerations.

Edit:

Code for LUT:

module LUT_1024(
    input clk, rst,
    input [9:0] address,
    output reg [15:0] new
    );
   
    always @(*) begin
    if(rst) begin new<=0; end
    else begin

    case (address)
10'd0: new<=16'h80C;
10'd1: new<=16'h818;
10'd2: new<=16'h825;
10'd3: new<=16'h831;
.
.
.
10'd1023: new<=16'h80C;
default: new<=16'h0;
 endcase
 end end
 endmodule
\$\endgroup\$
5
  • \$\begingroup\$ How did you implement the "time" base ? \$\endgroup\$
    – Antonio51
    Commented Mar 18 at 7:01
  • 2
    \$\begingroup\$ How did you generated the LUT? Pl share your code for reading the LUT as well. \$\endgroup\$
    – Im Groot
    Commented Mar 18 at 7:32
  • \$\begingroup\$ Which FPGA you are using? If you are using Xilinx, then you can use the DDS IP in Vivado and that will generate the desired frequency. \$\endgroup\$
    – Im Groot
    Commented Mar 18 at 7:44
  • \$\begingroup\$ @ImGroot I wish to generate the sine wave manually. I don't want to rely on the IP. \$\endgroup\$
    – DaveFenner
    Commented Mar 18 at 8:47
  • 2
    \$\begingroup\$ Frequency issues are associated with the DDS logic, not the LUT logic. Show us that code. In fact, you should provide an MCVE, as well as explain exactly what the difference is between what you expect to happen and what actually happens. \$\endgroup\$
    – Dave Tweed
    Commented Mar 18 at 11:58

1 Answer 1

3
\$\begingroup\$

First, you have to isolate the issue and find out if either the issue is with your Verilog module or with the DAC.

I see a couple of issues in your Verilog module.

  1. You have not used clk in the module and you are using the combinational logic to send data to output.
  2. You have used Non-blocking statement (<=) in the always block.

To correct it, you have to use the clk in the sensitivity list.

module LUT_1024(
    input clk, rst,
    input [9:0] address,
    output reg [15:0] new
    );
   
    always @(posedge clk) begin
    if(rst) begin 
        new<=0; 
    end
    else begin

        case (address)
            10'd0: new<=16'h80C;
            10'd1: new<=16'h818;
            10'd2: new<=16'h825;
            10'd3: new<=16'h831;
            .
            .
            .
            10'd1023: new<=16'h80C;
            default: new<=16'h0;
        endcase
        end 
    end
endmodule

But this is not a recommended way to work with LUT in Verilog. To create a LUT table we define a memory and provided values in the initial block. And then rest of the time we just read from the memory, as below.

module LUT_1024(
    input clk, rst,
    input [9:0] address,
    output reg [15:0] new
    );
    
    reg [15:0] LUT_Mem [0:1023];
    
    initial begin
        LUT_Mem[0]=16'h80C;
        LUT_Mem[1]=16'h818;
        LUT_Mem[2]=16'h825;
        LUT_Mem[3]=16'h831;
        .
        .
        .
        LUT_Mem[1023]=16'h80C;
    end
   
    always @(posedge clk) begin
    if(rst) begin 
        new<=0; 
    end
    else begin
        new <= LUT_Mem[address];
    end
endmodule

Further issue that you have to look for is your DAC is 12 bit but the LUT values that you are generating are going to exceed the 12 bit. For example, the maximum value that should be given to DAC has to be less 4096 but the LUT that you have generated seems to exceed that value based on the starting value that you have provided i.e. 16'h80C.

enter image description here

Generate the LUT with the following settings from the link:

Number of Points: 1024
Maximum Amplitude Value: 4000
Numbers Per Line: 1
Output Values Type: Hex

Now there is one more thing that you have to check for is, how you are generating the address to read values from the LUT table in the above Verilog module. If you are not generating address properly then it may de-shape the sin wave.

Lastly, simulation is your ally here. If the error is on FPGA side (i.e. Verilog) then you can easily capture it in the simulation.

\$\endgroup\$
4
  • \$\begingroup\$ For the LUT format, I will attempt it. Secondly, the values are less than 4096, since anything beyond that given to the DAC will lead to a shut-down mode. That doesn't occur in the output waveform, at least from what I can observe. Lastly, the address is calculated by a control parameter, which when increased will step through the LUT. It doesn't go beyond the domain of the LUT using limits that I have applied. So I don't really see where I am going wrong. \$\endgroup\$
    – DaveFenner
    Commented Mar 18 at 10:20
  • \$\begingroup\$ The issue for the address is not going beyond the limits, it how you are incrementing the values of the address and if the interval is correct or not. \$\endgroup\$
    – Im Groot
    Commented Mar 18 at 12:11
  • \$\begingroup\$ Generating a frequency is a function of multiple parameter i.e. Correct LUT, Correct increments and Accurate interval after which next value is sent to output. Slight change in the interval and the result will be different \$\endgroup\$
    – Im Groot
    Commented Mar 18 at 12:12
  • 1
    \$\begingroup\$ As per your issue, I would start by simulating the LUT with read module and verify if correct tone is being generated or not. Next, I will place an ILA (debug) core and check if correct tone is being sent to output at runtime or not. If tone is correct then I would look into how I am giving data to the DAQ? \$\endgroup\$
    – Im Groot
    Commented Mar 18 at 12:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.