cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Advisor
Advisor
690 Views
Registered: ‎10-10-2014

creating a vhdl lookup-table containing strings in a testbench

Jump to solution

I tried a few ways to create a simple lookup table with strings in a testbench. 

But I always run into this error :

The "Vhdl 2008 Unconstrained Array Type as Subtype in Array Type Definition" is not supported yet for simulation

Here's my code, the error is thrown on the line with 'type lut_string_type is array (positive range <>) of string;'

architecture behavioral of tb_my_testbench is
     ....
    constant kREG0_ADDR  : std_logic_vector(31 downto 0) := X"40000000";
    constant kREG1_ADDR  : std_logic_vector(31 downto 0) := X"40000004";
    constant kREG2_ADDR  : std_logic_vector(31 downto 0) := X"40000008";
    ...
constant kREG31_ADDR : std_logic_vector(31 downto 0) := X"4000007C"; function calc_reg_index(reg_addr : std_logic_vector) return integer is constant BASE_ADDR : integer := to_integer(unsigned(kREG0_ADDR)); variable index : integer; begin -- calculate the register index in the lut by subtracting the base address from the reg_addr index := to_integer(unsigned(reg_addr)) - BASE_ADDR; return index; end; function lookup_reg_name(reg_addr : std_logic_vector) return string is variable index : integer; variable reg_name : string; type lut_string_type is array (positive range <>) of string; variable lut_reg_names : lut_string_type(0 to 31) := ( "REG0", "REG1", "REG2", ...
"REG31" ); begin index := calc_reg_index(reg_addr); reg_name:= lut_reg_names(index); return reg_name; end;

I also tried this variation:

        type lut_string_type is array (0 to 31) of string;
        variable lut_reg_names : lut_string_type := (
            "REG0",
            "REG1",
            "REG2",
            ...
        );

is there any way to create a simple LUT that returns a string based on an integer index ...? 

 

** kudo if the answer was helpful. Accept as solution if your question is answered **
0 Kudos
1 Solution

Accepted Solutions
Scholar
Scholar
668 Views
Registered: ‎08-01-2012

Re: creating a vhdl lookup-table containg strings in a testbench

Jump to solution

Yes there is, but probably not as easily as you may think.

First of all, your code is actually illegal VHDL 2008. In an unconstrained array type, all elements must have the same subtype - so you cant have an array where every element has a different length. But you can easily make your code VHDL 93 compatible, by making all the strings the same length:

type lut_string_type is array (positive range <>) of string(1 to 5);
        variable lut_reg_names : lut_string_type(0 to 31) := (
            "REG0 ",
            "REG1 ",
            "REG2 ",
            ...
            "REG31"
        );

Basically, just add spaces.

But, there is a fancy way of doing this, even using VHDL 87 (I think).

Remember the line type? that is an access type that points to a string. Ie., a pointer to a string, and a pointer to an array doesnt need a length until you declare it. so you could be all fancy and do something like this:

type lut_string_type is array (natural range <>) of line;

function init_names(n : natural) return lut_string_type is variable r : lut_string_type(0 to n-1); begin for i in 0 to n-1 loop r(i) := new string'( "REG" & integer'image(i)); end loop; return r; end function; variable names : lut_string_type(0 to 31) := init_names; ..... report "The name 24 is " & names(24).all;

Now, you have to note that VHDL has no garbage collection, so its very easy to create memory leaks. One nicer way of doing this might be to generate the name based on a number, rahter than using a LUT. But learning the above might be overkill, but its the start of showing the power of VHDL testbench stuff.

View solution in original post

3 Replies
Scholar
Scholar
669 Views
Registered: ‎08-01-2012

Re: creating a vhdl lookup-table containg strings in a testbench

Jump to solution

Yes there is, but probably not as easily as you may think.

First of all, your code is actually illegal VHDL 2008. In an unconstrained array type, all elements must have the same subtype - so you cant have an array where every element has a different length. But you can easily make your code VHDL 93 compatible, by making all the strings the same length:

type lut_string_type is array (positive range <>) of string(1 to 5);
        variable lut_reg_names : lut_string_type(0 to 31) := (
            "REG0 ",
            "REG1 ",
            "REG2 ",
            ...
            "REG31"
        );

Basically, just add spaces.

But, there is a fancy way of doing this, even using VHDL 87 (I think).

Remember the line type? that is an access type that points to a string. Ie., a pointer to a string, and a pointer to an array doesnt need a length until you declare it. so you could be all fancy and do something like this:

type lut_string_type is array (natural range <>) of line;

function init_names(n : natural) return lut_string_type is variable r : lut_string_type(0 to n-1); begin for i in 0 to n-1 loop r(i) := new string'( "REG" & integer'image(i)); end loop; return r; end function; variable names : lut_string_type(0 to 31) := init_names; ..... report "The name 24 is " & names(24).all;

Now, you have to note that VHDL has no garbage collection, so its very easy to create memory leaks. One nicer way of doing this might be to generate the name based on a number, rahter than using a LUT. But learning the above might be overkill, but its the start of showing the power of VHDL testbench stuff.

View solution in original post

Highlighted
Advisor
Advisor
593 Views
Registered: ‎10-10-2014

Re: creating a vhdl lookup-table containg strings in a testbench

Jump to solution

thanks @richardhead , indeed fixing the string size helped me solve the problem. Thank you also for the example using 'line', that's some more advanced stuff that is hard to find in any book :-) In my case, I actually want to add a short description after REGxx, so the strings will al become different, but thanks for the idea!

I rewrote my methods like this (using a subtype for the string with fixed length) :

    constant kREG0_ADDR : std_logic_vector(31 downto 0) := X"40000000";
constant kREG1_ADDR : std_logic_vector(31 downto 0) := X"40000004";
...
constant kREG31_ADDR : std_logic_vector(31 downto 0) := X"4000007C";

subtype T_STRING_REG_NAME is string(1 to 5); type T_LUT_STRING_REG_DESCR is array (positive range <>) of T_STRING_REG_NAME; constant lut_reg_names : T_LUT_STRING_REG_DESCR(1 to 32) := ( "REG00", "REG01", ... "REG31" ); function lookup_reg_name(reg_addr : std_logic_vector) return T_STRING_REG_NAME is constant BASE_ADDR : std_logic_vector := kREG0_ADDR; variable index : integer; variable reg_name : T_STRING_REG_NAME; begin -- make sure address is in acceptable range and aligned, otherwise simulation will hang assert ( unsigned(reg_addr) <= unsigned(kREG31_ADDR) ) and ( unsigned(reg_addr) >= unsigned(kREG0_ADDR) ) report "lookup_reg_name() : reg_addr out of range" severity failure; assert ((unsigned(reg_addr) mod 4) = 0) report "lookup_reg_name(): reg_addr should be 32-bit aligned" severity failure; -- calculate the register index in the lut by subtracting the base address from the reg_addr -- then we divide by 4 because regs are 32-bit index := ( to_integer(unsigned(reg_addr)) - to_integer(unsigned(BASE_ADDR)) ) / 4; reg_name:= lut_reg_names(index); return reg_name; end;

now I can call the function like this :

        report "LUT " & lookup_reg_name(X"4000_007C");
or
        report "LUT " & lookup_reg_name(kREG31_ADDR);

This works fine.

I also experimented with asserts to check the incoming address in the function, to avoid an 'out of bounds' access to the array, because that seems to crash the simulator, and check that it's within the address range, and if it's 32-bit aligned. However, when I try an illegal address, my simulation hangs in an endless loop, and I get a strange error dialog saying 'unable to open file " because file does not have read permission. would you like to open the directory instead'? 

-- test if assert works correctly       
report "LUT " & lookup_reg_name(X"4000_1234");

Hitting escape a few times stops the simulator at the first assert :

       assert ( unsigned(reg_addr) <= unsigned(kREG31_ADDR) ) and ( unsigned(reg_addr) >= unsigned(kREG0_ADDR) ) 
            report "lookup_reg_name() : reg_addr out of range" severity failure;

maybe asserts are not supported inside functions? (I'm still in a testbench though).

Also during my further experiments I sometimes ran into a weird 'SIGSEGV' error, without any further explanation.... most of them were related to using the unconstrained string I guess.

These more advanced things are rarely found in books, the only one that touches these things seems to be 'The designers guide to VHDL by Ashenden'. Do you happen to know another book/resource that dives deeper into self-checking tesbenches and more advanced VHDL? 

** kudo if the answer was helpful. Accept as solution if your question is answered **
0 Kudos
Highlighted
Scholar
Scholar
582 Views
Registered: ‎08-01-2012

Re: creating a vhdl lookup-table containg strings in a testbench

Jump to solution

@ronnywebers 

My Initial learning came from a Doulos Advanced VHDL Verification course (about 13 years ago - I still have the excelent reference book) with the rest collected from various online forums (initially comp.lang.vhdl newsgroup, then others) and collegues. Writing alot of testbenches helped. I also read "Writing Testbenches, Functional Verification of HDL models". While it is probably a little outdated now (a lot of the languages examples are in E and Vera, the forerunner to systemVerilog) the techniques are all still valid and can all be done in the VHDL.

https://www.amazon.co.uk/Writing-Testbenches-Functional-Verification-Models/dp/1402074018

(this book is now about 4x the price I got a copy for 10 years ago!)

There is also "VHDL 2008, Just the new stuff", another Ashenden book (along with Jim Lewis, custodian of the VHDL LRM) which has some cool examples in it (although most simulators are only just now supporting packages as generics!)

https://www.amazon.co.uk/VHDL-2008-Just-Stuff-Systems-Silicon/dp/0123742498/ref=sr_1_1?keywords=vhdl+2008+just+the+new+stuff&qid=1579079163&s=books&sr=1-1

 

Recently Ive been using a lot of OSVVM ( you'll need to use a better simulator) but it doesnt carry a lot of examples. UVVM is another framework that is catching on but I havent done much with it.

OSVVM can be taken like a tool box of individual verification elements that you build into your testbenches, whereas UVVM is more an entire framework and style for you to work to.

You may also want to have a look into VUnit for an open source CI (continuous integration) environment.