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.

Problem calling a function from my vhdl project in Vivado.

Status
Not open for further replies.

Cesar0182

Member level 5
Joined
Feb 18, 2019
Messages
85
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
825
Greetings ... comment that a couple of days ago I am trying to translate an .h file to vhdl, this in order to be able to use the functions in my vhdl project. The truth is that I am new doing translations and I am having problems when I can simulate since I get the following error

[VRFC 10-664] expression has 0 elements; expected 10 ["C: /ProgramData/Teradyne/FPGA/VivadoProjects/App0x3120VHDLMaster/fpgas/g1/src/g1_mmcme2_drp_vhdl.vhd": 917]

and for more laps that I give it, I cannot understand why this error is due.
Someone please can you help me with this problem. Thanks in advance. I leave attached the original code and the other one in vhdl of the function where the error points, in addition to the .h and .vhd files

Original
Code:
function [9:0] mmcm_filter_lookup
  (
     input [6:0] divide, // Max divide is 64
     input [8*9:0] BANDWIDTH
  );

  reg [639:0] lookup_low;
  reg [639:0] lookup_low_ss;
  reg [639:0] lookup_high;
  reg [639:0] lookup_optimized;

  reg [9:0] lookup_entry;

  begin
    lookup_low = {
      // CP_RES_LFHF
      10'b0010_1111_00, // 1
      10'b0010_1111_00, // 2
      10'b0010_1111_00, // 3
      10'b0010_1111_00, // 4
      10'b0010_0111_00, // ....
      10'b0010_1011_00,
      10'b0010_1101_00,
      10'b0010_0011_00,
      10'b0010_0101_00,
      10'b0010_0101_00,
      10'b0010_1001_00,
      10'b0010_1110_00,
      10'b0010_1110_00,
      10'b0010_1110_00,
      10'b0010_1110_00,
      10'b0010_0001_00,
      10'b0010_0001_00,
      10'b0010_0001_00,
      10'b0010_0110_00,
      10'b0010_0110_00,
      10'b0010_0110_00,
      10'b0010_0110_00,
      10'b0010_0110_00,
      10'b0010_0110_00,
      10'b0010_0110_00,
      10'b0010_1010_00,
      10'b0010_1010_00,
      10'b0010_1010_00,
      10'b0010_1010_00,
      10'b0010_1010_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_1100_00,
      10'b0010_0010_00,
      10'b0010_0010_00,
      10'b0010_0010_00,
      10'b0010_0010_00,
      10'b0010_0010_00,
      10'b0010_0010_00,
      10'b0010_0010_00,
      10'b0010_0010_00,
      10'b0010_0010_00,
      10'b0010_0010_00,
      10'b0010_0010_00,
      10'b0010_0010_00,
      10'b0010_0010_00, // ....
      10'b0010_0010_00, // 61
      10'b0010_0010_00, // 62
      10'b0010_0010_00, // 63
      10'b0010_0010_00  // 64
    };

    lookup_low_ss = {
      // CP_RES_LFHF
      10'b0010_1111_11, // 1
      10'b0010_1111_11, // 2
      10'b0010_1111_11, // 3
      10'b0010_1111_11, // 4
      10'b0010_0111_11, // ....
      10'b0010_1011_11,
      10'b0010_1101_11,
      10'b0010_0011_11,
      10'b0010_0101_11,
      10'b0010_0101_11,
      10'b0010_1001_11,
      10'b0010_1110_11,
      10'b0010_1110_11,
      10'b0010_1110_11,
      10'b0010_1110_11,
      10'b0010_0001_11,
      10'b0010_0001_11,
      10'b0010_0001_11,
      10'b0010_0110_11,
      10'b0010_0110_11,
      10'b0010_0110_11,
      10'b0010_0110_11,
      10'b0010_0110_11,
      10'b0010_0110_11,
      10'b0010_0110_11,
      10'b0010_1010_11,
      10'b0010_1010_11,
      10'b0010_1010_11,
      10'b0010_1010_11,
      10'b0010_1010_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_1100_11,
      10'b0010_0010_11,
      10'b0010_0010_11,
      10'b0010_0010_11,
      10'b0010_0010_11,
      10'b0010_0010_11,
      10'b0010_0010_11,
      10'b0010_0010_11,
      10'b0010_0010_11,
      10'b0010_0010_11,
      10'b0010_0010_11,
      10'b0010_0010_11,
      10'b0010_0010_11,
      10'b0010_0010_11, // ....
      10'b0010_0010_11, // 61
      10'b0010_0010_11, // 62
      10'b0010_0010_11, // 63
      10'b0010_0010_11  // 64
    };

    lookup_high = {
      // CP_RES_LFHF
      10'b0010_1111_00, // 1
      10'b0100_1111_00, // 2
      10'b0101_1011_00, // 3
      10'b0111_0111_00, // 4
      10'b1101_0111_00, // ....
      10'b1110_1011_00,
      10'b1110_1101_00,
      10'b1111_0011_00,
      10'b1110_0101_00,
      10'b1111_0101_00,
      10'b1111_1001_00,
      10'b1101_0001_00,
      10'b1111_1001_00,
      10'b1111_1001_00,
      10'b1111_1001_00,
      10'b1111_1001_00,
      10'b1111_0101_00,
      10'b1111_0101_00,
      10'b1100_0001_00,
      10'b1100_0001_00,
      10'b1100_0001_00,
      10'b0101_1100_00,
      10'b0101_1100_00,
      10'b0101_1100_00,
      10'b0101_1100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0010_1000_00,
      10'b0010_1000_00,
      10'b0010_1000_00,
      10'b0010_1000_00,
      10'b0010_1000_00,
      10'b0111_0001_00,
      10'b0111_0001_00,
      10'b0100_1100_00,
      10'b0100_1100_00,
      10'b0100_1100_00,
      10'b0100_1100_00,
      10'b0110_0001_00,
      10'b0110_0001_00,
      10'b0101_0110_00,
      10'b0101_0110_00,
      10'b0101_0110_00,
      10'b0010_0100_00,
      10'b0010_0100_00,
      10'b0010_0100_00, // ....
      10'b0010_0100_00, // 61
      10'b0100_1010_00, // 62
      10'b0011_1100_00, // 63
      10'b0011_1100_00  // 64
    };

    lookup_optimized = {
      // CP_RES_LFHF
      10'b0010_1111_00, // 1
      10'b0100_1111_00, // 2
      10'b0101_1011_00, // 3
      10'b0111_0111_00, // 4
      10'b1101_0111_00, // ....
      10'b1110_1011_00,
      10'b1110_1101_00,
      10'b1111_0011_00,
      10'b1110_0101_00,
      10'b1111_0101_00,
      10'b1111_1001_00,
      10'b1101_0001_00,
      10'b1111_1001_00,
      10'b1111_1001_00,
      10'b1111_1001_00,
      10'b1111_1001_00,
      10'b1111_0101_00,
      10'b1111_0101_00,
      10'b1100_0001_00,
      10'b1100_0001_00,
      10'b1100_0001_00,
      10'b0101_1100_00,
      10'b0101_1100_00,
      10'b0101_1100_00,
      10'b0101_1100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0011_0100_00,
      10'b0010_1000_00,
      10'b0010_1000_00,
      10'b0010_1000_00,
      10'b0010_1000_00,
      10'b0010_1000_00,
      10'b0111_0001_00,
      10'b0111_0001_00,
      10'b0100_1100_00,
      10'b0100_1100_00,
      10'b0100_1100_00,
      10'b0100_1100_00,
      10'b0110_0001_00,
      10'b0110_0001_00,
      10'b0101_0110_00,
      10'b0101_0110_00,
      10'b0101_0110_00,
      10'b0010_0100_00,
      10'b0010_0100_00,
      10'b0010_0100_00, // ....
      10'b0010_0100_00, // 61
      10'b0100_1010_00, // 62
      10'b0011_1100_00, // 63
      10'b0011_1100_00  // 64
    };

    // Set lookup_entry with the explicit bits from lookup with a part select
    if(BANDWIDTH == "LOW") begin
      // Low Bandwidth
      mmcm_filter_lookup = lookup_low[((64-divide)*10) +: 10];
    end
    else if (BANDWIDTH == "LOW_SS") begin
      // low Spread spectrum bandwidth
      mmcm_filter_lookup = lookup_low_ss[((64-divide)*10) +: 10];
    end
    else if (BANDWIDTH == "HIGH") begin
      // High bandwidth
      mmcm_filter_lookup = lookup_high[((64-divide)*10) +: 10];
    end
    else if (BANDWIDTH == "OPTIMIZED") begin
      // Optimized bandwidth
      mmcm_filter_lookup = lookup_optimized[((64-divide)*10) +: 10];
    end

    `ifdef DEBUG
        $display("filter_lookup: %b", mmcm_filter_lookup);
    `endif
  end
endfunction

VHDL

Code:
function mmcm_filter_lookup (
  divide    : in std_logic_vector(6 downto 0);
  BANDWIDTH : string) return std_logic_vector is 
  variable mmcm_filter_lookup        :std_logic_vector(9 downto 0);
  variable lookup_low                : std_logic_vector(639 downto 0) ;
  variable lookup_low_ss             : std_logic_vector(639 downto 0) ;
  variable lookup_high               : std_logic_vector(639 downto 0) ;
  variable lookup_optimized          : std_logic_vector(639 downto 0) ;
  variable lookup_entry              : std_logic_vector(9 downto 0) ;

  begin 
    lookup_low := 
    -- CP_RES_LFHF
    "0010111100" & -- 1
    "0010111100" & -- 2
    "0010111100" & -- 3
    "0010111100" & -- 4
    "0010011100" & -- ....
    "0010101100" &
    "0010110100" &
    "0010001100" &
    "0010010100" & 
    "0010010100" &
    "0010100100" &
    "0010111000" &
    "0010111000" &
    "0010111000" &
    "0010111000" &
    "0010000100" &
    "0010000100" &
    "0010000100" &
    "0010011000" &
    "0010011000" &
    "0010011000" &
    "0010011000" &
    "0010011000" &
    "0010011000" &
    "0010011000" &
    "0010101000" &
    "0010101000" &
    "0010101000" &
    "0010101000" &
    "0010101000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010110000" &
    "0010001000" &
    "0010001000" &
    "0010001000" &
    "0010001000" &
    "0010001000" &
    "0010001000" &
    "0010001000" &
    "0010001000" &
    "0010001000" &
    "0010001000" &
    "0010001000" &
    "0010001000" &
    "0010001000" & -- ....
    "0010001000" & -- 61
    "0010001000" & -- 62
    "0010001000" & -- 63
    "0010001000"  -- 64
  ;

  lookup_low_ss := 
  -- CP_RES_LFHF
  "0010111111" & -- 1
  "0010111111" & -- 2
  "0010111111" & -- 3
  "0010111111" & -- 4
  "0010011111" & -- ....
  "0010101111" &
  "0010110111" &
  "0010001111" &
  "0010010111" &
  "0010010111" &
  "0010100111" &
  "0010111011" &
  "0010111011" &
  "0010111011" &
  "0010111011" &
  "0010000111" &
  "0010000111" &
  "0010000111" &
  "0010011011" &
  "0010011011" &
  "0010011011" &
  "0010011011" &
  "0010011011" &
  "0010011011" &
  "0010011011" &
  "0010101011" &
  "0010101011" &
  "0010101011" &
  "0010101011" &
  "0010101011" &
  "0010110011" &
  "0010110011" &
  "0010110011" &
  "0010110011" &
  "0010110011" &
  "0010110011" &
  "0010110011" &
  "0010110011" &
  "0010110011" &
  "0010110011" &
  "0010110011" &
  "0010110011" &
  "0010100111" &
  "0010110011" &
  "0010110011" &
  "0010110011" &
  "0010110011" &
  "0010001011" &
  "0010001011" &
  "0010001011" &
  "0010001011" &
  "0010001011" &
  "0010001011" &
  "0010001011" &
  "0010001011" &
  "0010001011" &
  "0010001011" &
  "0010001011" &
  "0010001011" &
  "0010001011" & -- ....
  "0010001011" & -- 61
  "0010001011" & -- 62
  "0010001011" & -- 63
  "0010001011"  -- 64
  ;

  lookup_high := 
-- CP_RES_LFHF
"0010111100" & -- 1
"0100111100" & -- 2
"0101101100" & -- 3
"0111011100" & -- 4
"1101011100" & -- ....
"1110101100" &
"1110110100" &
"1111001100" &
"1110010100" &
"1111010100" &
"1111100100" &
"1101000100" &
"1111100100" &
"1111100100" &
"1111100100" &
"1111100100" &
"1111010100" &
"1111010100" &
"1100000100" &
"1100000100" &
"1100000100" &
"0101110000" &
"0101110000" &
"0101110000" &
"0101110000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0010100000" &
"0010100000" &
"0010100000" &
"0010100000" &
"0010100000" &
"0111000100" &
"0111000100" &
"0100110000" &
"0100110000" &
"0100110000" &
"0100110000" &
"0110000100" &
"0110000100" &
"0101011000" &
"0101011000" &
"0101011000" &
"0010010000" &
"0010010000" &
"0010010000" & -- ....
"0010010000" & -- 61
"0100101000" & -- 62
"0011110000" & -- 63
"0011110000"  -- 64
;

  lookup_optimized := 
-- CP_RES_LFHF
"0010111100" & -- 1
"0100111100" & -- 2
"0101101100" & -- 3
"0111011100" & -- 4
"1101011100" & -- ....
"1110101100" &
"1110110100" &
"1111001100" &
"1110010100" &
"1111010100" &
"1111100100" &
"1101000100" &
"1111100100" &
"1111100100" &
"1111100100" &
"1111100100" &
"1111010100" &
"1111010100" &
"1100000100" &
"1100000100" &
"1100000100" &
"0101110000" &
"0101110000" &
"0101110000" &
"0101110000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0011010000" &
"0010100000" &
"0010100000" &
"0010100000" &
"0010100000" &
"0010100000" &
"0111000100" &
"0111000100" &
"0100110000" &
"0100110000" &
"0100110000" &
"0100110000" &
"0110000100" &
"0110000100" &
"0101011000" &
"0101011000" &
"0101011000" &
"0010010000" &
"0010010000" &
"0010010000" & -- ....
"0010010000" & -- 61
"0100101000" & -- 62
"0011110000" & -- 63
"0011110000"  -- 64
;

-- Set lookup_entry with the explicit bits from lookup with a part select
  if BANDWIDTH = "LOW" then
--       Low Bandwidth
    return lookup_low(9 downto ((64-conv_integer(divide))*10));
  elsif BANDWIDTH = "LOW_SS" then
--       low Spread spectrum bandwidth
    return lookup_low_ss(9 downto ((64-conv_integer(divide))*10));
  elsif BANDWIDTH = "HIGH" then
--       High bandwidth
    return lookup_high(9 downto ((64-conv_integer(divide))*10));
    
  elsif BANDWIDTH = "OPTIMIZED" then
--       Optimized bandwidth
    return lookup_optimized(9 downto ((64-conv_integer(divide))*10));
  end if;  
end function;
 

Attachments

  • g1_mmcme2_drp_func.h.rar
    5.7 KB · Views: 79
  • g1_mmcme2_drp_func_vhdl.rar
    519 bytes · Views: 85

Good grief, why are you copying Verilog directly to VHDL...
If you use VHDL arrays for the tables then you don't need to do all that ugly indexing and bit slicing to return the data.


your problem though is this
(9 downto ((64-conv_integer(divide))*10)
FYI you are using the wrong package (you should be using numeric_std and not the synopsys packages, which aren't an IEEE standard nor are they even truly a defacto standard)

calculate out what 64-conv_integer(divide)*10 comes out to
e.g. if divide is "0000100"
then 64-4*10 = 24
now you have (9 downto 24) which is wrong.

The Verilog has [((64-divide)*10) +: 10], which is a totally different statement
namely it says (with divide=4) 64-4*10 = 24, which results in [33:24] because +: 10 means starting with the value on the left side that value plus the next 9 up is the entire range of 10.

e.g
[0 +: 8] = [7:0]
[10 +:10] = [19:10]
 

You need to think what this means:
(9 downto ((64-conv_integer(divide))*10)

Let start to see what happens if Divide = 64
you get the range (9 downto 0).

If divide > 64 on the RHS you get 10 or more.
(9 downto 10)
Is a range with 0 length (a null range). This is prefectly legal in VHDL, and illegal in Verilog. It returns an array with length 0.

If its < 64, on the RHS you get -10 or less
Then you get (9 downto -10), which illegal because std_logic_vector is declared with a natural range, which means both indeces must be >= 0 (unless you're making a null array, like above)

I think you intended the left index to be the calculation+9, with the right index being the calculation.

in verilog [a +: b] means an array slice, with a being low, and (a+b-1) being the high index (b bits total)

There is also an error in the original, because divide is 7 bits, giving 128 lookup locations, but there are only 64.

Commenting on your code, the translation basically a direct translation of some not great code in the first place. I would recommend the following:

1. Make the lookups constants, not variables
2. Make the lookups arrays of std_logic_vector (make it 2008 for more generic array types)
3. Make divide an integer input to the function.
4. When you've done 2, then the return can be an integer lookup into an array.
5. With the above, you then wont need to use the conv_integer from the non-standard std_logic_arith library. You can use the standard numeric_std or numeric_std_unsigned instead, but you wont need them in the function

eg.

Code VHDL - [expand]
1
2
3
4
5
6
type slv_array_t is array(natural range <>) of std_logic_vector;
constant lookup : slv_array_t(0 to 63)(9 downto 0);
 
...
 
return lookup(divide);

 

Thanks for the help. Is there a rule for this type of verilog syntax for vhdl? because the examples are not clear to me. Tell you that I did the translation based on the following link http://electronics.stackexchange.com/questions/154438/what-does-mean-in-verilog

- - - Updated - - -

I just solved that problem, with the following line:

Code:
((64-conv_integer(divide))*10)-1 downto ((64-conv_integer(divide))*10)-10

But now I am having the following error.
BUG: [XSIM 43-4187] File "C: /ProgramData/Teradyne/FPGA/VivadoProjects/App0x3120VHDLMaster/fpgas/g1/src/g1_mmcme2_drp_vhdl.vhd" Line 989: The "Vhdl is still sequential conditional sequential. simulation.
I found a similar problem in the Xilinx forums, where they apparently don't have a solution.
http://forums.xilinx.com/t5/Simulation-and-Verification/Vivado-2018-3-VHDL2008-Support-Conditional-and-selected/td-p/1009575
 

The best rule for converting to VHDL is to understand the code and re-write in VHDL. Direct port is always going to be a mess

That error is because you're using VHDL 2008 syntax. The Vivado simualor is very bad and has little to no VHDL 2008 support. You can get a proper simulator in the form of GHDL (open source) or Modelsim (for free from intel). Vivado simulator is just poor.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top