Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Verilog/Vivado/FPGA Error for sinewave LUT: Single value range is not allowed in packed dimension

Status
Not open for further replies.

hobbskw

Junior Member level 3
Joined
Oct 19, 2021
Messages
25
Helped
1
Reputation
2
Reaction score
1
Trophy points
3
Activity points
197
Hello,
I am trying to make a sinewave lookup table. I would like it to be a series of 50 stored value, which I plan to use for SPWM.
However, when I try to create the lookup table, it is giving me a few errors, one of which says "single value range is not allowed in packed dimension"
This is the only error that gives and real details as to what is wrong with the code, though I cannot find any clear-cut explanation what this error means, nor can I find any solution online. Can anyone possible help see what the problem with my code is?
I appreciate any help!
I will try attaching an image of the error, which appears on each of the "sine[x] = y;" lines.
1649100846193.png



Code:
`timescale 1ns / 1ps
module duty_cycle_gen(
    input clk,
    input rst_n,
    output AP,
    output AN,
    output BP,
    output BN,
    output CP,
    output CN
);
    // Input clock is 100MHz
    //localparam CLOCK_FREQUENCY = 100000000;
    localparam CLOCK_FREQUENCY = 1000000;
    localparam STEP = CLOCK_FREQUENCY / 6;
    // Counter for toggling of clock
    integer counterA = 0;
    integer counterB = 4 * STEP;
    integer counterC = 2 * STEP;

    reg [7:0] sine[0:49];
    sine[0] = 0;
    sine[1] = 157;
    sine[2] = 311;
    sine[3] = 460;
    sine[4] = 602;
    sine[5] = 735;
    sine[6] = 856;
    sine[7] = 963;
    sine[8] = 1055;
    sine[9] = 1131;
    sine[10] = 1189;
    sine[11] = 1228;
    sine[12] = 1248;
    sine[13] = 1248;
    sine[14] = 1228;
    sine[15] = 1189;
    sine[16] = 1131;
    sine[17] = 1055;
    sine[18] = 963;
    sine[19] = 856;
    sine[20] = 735;
    sine[21] = 602;
    sine[22] = 460;
    sine[23] = 311;
    sine[24] = 157;
    sine[25] = 0;
    sine[26] = -157;
    sine[27] = -311;
    sine[28] = -460;
    sine[29] = -602;
    sine[30] = -735;
    sine[31] = -856;
    sine[32] = -963;
    sine[33] = -1055;
    sine[34] = -1131;
    sine[35] = -1189;
    sine[36] = -1228;
    sine[37] = -1248;
    sine[38] = -1248;
    sine[39] = -1228;
    sine[40] = -1189;
    sine[41] = -1131;
    sine[42] = -1055;
    sine[43] = -963;
    sine[44] = -856;
    sine[45] = -735;
    sine[46] = -602;
    sine[47] = -460;
    sine[48] = -311;
    sine[49] = -157;

 always @(posedge clk) begin
        if (!rst_n) begin
            counterA <= 8'h00;
            counterB <= 4 * STEP;
            counterC <= 2 * STEP;
        end
        else begin
        
        
            // If counter is 100M, reset counter, ELSE count up
            if (counterA == CLOCK_FREQUENCY - 1) begin
                counterA <= 8'h00; 
            end
            else begin
                counterA <= counterA + 1;
            end
            
            if (counterB == CLOCK_FREQUENCY - 1) begin
                counterB <= 8'h00; 
            end
            else begin
                counterB <= counterB + 1;
            end
            
            if (counterC == CLOCK_FREQUENCY - 1) begin
                counterC <= 8'h00;
            end
            else begin
                counterC <= counterC + 1;
            end
        end
        
        end
assign AP = (counterA < 3*STEP) ? 1 : 0;
assign AN = ~AP;
assign BP = (counterB < 3*STEP) ? 1 : 0;
assign BN = ~BP;
assign CP = (counterC < 3*STEP) ? 1 : 0;
assign CN = ~CP;
endmodule
 

You can't use assignments like
sine[0] = 0;
in Verilog, it might look like C but Verilog isn't C and it doesn't behave like C.

You can use a case statement to build the LUT

Code Verilog - [expand]
1
2
3
4
5
6
7
always @* begin
  case (addr)
    0: sine[0] = 0;
    1: sine[1] = 157;
    //...
  endcase;
end


You also need to increase the width of the sine as the values assigned are a maximum of 11-bit values as there are some that are over 1023.
 
You can't use assignments like
sine[0] = 0;
in Verilog, it might look like C but Verilog isn't C and it doesn't behave like C.

You can use a case statement to build the LUT

Code Verilog - [expand]
1
2
3
4
5
6
7
always @* begin
  case (addr)
    0: sine[0] = 0;
    1: sine[1] = 157;
    //...
  endcase;
end


You also need to increase the width of the sine as the values assigned are a maximum of 11-bit values as there are some that are over 1023.
Thank you for your helpful response! Would addr simply be initialized like this?
Code:
reg addr;
How would I use this? Do I just set addr to every value from 0 to 49 and then I can call sine[x], with x being some number from 0 to 49?
 

Since the error is resolved, thanks to ads-ee's help, I'll mark as solved and ask my last question separately. Thank you very much for helping!
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top