Limitation using MemoryPkg

Why OSVVM™? Forums OSVVM Limitation using MemoryPkg

This topic contains 5 replies, has 3 voices, and was last updated by Avatar of Jim Lewis Jim Lewis 1 year, 7 months ago.

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #1385
    Avatar of Jorge Tonfat
    Jorge Tonfat
    Member

    Hi!

    I am using OSVVM 2017.05 and I have the following limitation using MemoryPkg:

    I defined an SRAM vhdl model using the MemoryPType. And my SRAM data width is 32 bits.

    My problem is that when I am reading a memory position with a value that is outside the integer positive range (> 2147483647) , I get only ‘U’ as data because of the following code in MemoryPkg:

    if ArrayPtrVar(BlockAddr)(WordAddr) >= 0 then 

            -- Get the Word from the Array

            Data := to_slv(ArrayPtrVar(BlockAddr)(WordAddr), Data'length) ;

          elsif ArrayPtrVar(BlockAddr)(WordAddr) = -1 then 

           -- X in Word, return all X

            Data := (Data'range => 'X') ;

          else 

           -- Location Uninitialized, return all X

            Data := (Data'range => 'U') ;

          end if ;

    To solve this issue, can we just change the MemBlockType definition?

    From:

    type MemBlockType    is array (integer range <>) of integer ;

    To:

    type MemBlockType    is array (integer range <>) of real;

    Thank you!

    • This topic was modified 1 year, 9 months ago by Avatar of Jorge Tonfat Jorge Tonfat. Reason: formatting
    #1388

    Hi Jorge,

    replacing the integer with a real won’t solve the problem.

    Instead, it makes it even worse.

    The integer data type uses 32 bits (signed) so you have a numerical range of -2^31 to (2^31)-1.

    The mantissa of the (32 bit) real data type is just 23 bits wide, which means it has a smaller numerical range (for integer use).

    Once you increase the exponent, you are loosing LSBs of the mantissa.

    So, while the memory range may grow, you are not able to adress each word in the higher adress regions.

    My guess would be to use some unsigned type for the desired purpose.

    With unsigned the number of usable adresses can be increased to ranges not yet imaginable for existing memories.

    (e.g. can your simulator host computer adress some array of unsigned (2048 downto 0) memory?)

    Also, the unsigned data type behaves almost like integer and is compatible (castable) to slv, so it might require less code changes.

    But it needs to be checked, wether the conversion functions (e.g. to_integer/to_unsigned) are used, I doubt that they handle larger_than_integer unsigned types properly.

    Have a nice simulation

       Eilert

    #1391
    Avatar of Jorge Tonfat
    Jorge Tonfat
    Member

    Thank you Eilert!

    Yes, you are right, changing to REAL will not solve the problem. To avoid troubles in this case, I just limited my pseudo-random generation to be bounded by the positive integer range. As you mention, maybe it is possible to change the data type to an unsigned type, but I have not tried.

    Best regards,

    Jorge

    #1392
    Avatar of Jim Lewis
    Jim Lewis
    Member

    Hi Jorge,

    For the time being, you can use more than one memory model.

    A past version used integer_vector instead of integer.   This is something I intend to re-consider in the future.   The problem is it adds complication and overhead to all models.   This is something that needs to be considered.   I am looking into using generics with the package to handle this and some other features I am considering.   I am particularly interested in the VHDL-2017 generics on protected types.

    The VHDL type REAL is a double (64 bits) – so it could handle the value but integer_vector would be a better solution.

    Best Regards,

    Jim

    #1395

    Hi Jim,

    Thanks for clarifying the real-type issue.

    I really tried to look up some reference before and just stumbled over this:

    https://www.ece.uic.edu/~dutt/courses/ece368/lect-notes/vhdl-attrs-data-types.pdf

    But it seems to be either somehow wrong or just outdated.

    (I had my doubts when I saw the numerical range, but some other source mentioned a max. Exponent of +/- 38 insted of +/-308)

    But even some VHDL LRM says:

    Std 1076, 2000 Edition IEEE STANDARD VHDL

    Copyright © 2000 IEEE. All rights reserved.
    3.1.4.1 Predefined floating point types
    The only predefined floating point type is the type REAL. The range of REAL is host-dependent, but it is guaranteed to include the range –1.0E38 to +1.0E38 inclusive. It is defined with an ascending range.

    Another LRM (probably a proposal: 2000/D3) changed this like this:

    3.1.4.1 Predefined floating point types
    The only predefined floating point type is the type REAL. The range of REAL is host-dependent, but it is guaranteed to include the range –1.0E38 to +1.0E38 inclusive be the largest allowed by the chosen representation

    How did this change with VHDL 2008?

    Is it really host-dependent now, or specifically defined as double?

    I know, one should always check the latest LRM, but how if it is not available. 

    Kind regards

      Eilert

    #1400
    Avatar of Jim Lewis
    Jim Lewis
    Member

    Hi Eilert,
    In the 2008 standard it says:
    An implementation shall choose a representation for all floating-point types except for universal_real that conforms either to IEEE Std 754-1985 or to IEEE Std 854-1987; in either case, a minimum representation size of 64 bits is required for this chosen representation.

    I think this changed before 2008, perhaps in 2002.

    Best Regards,
    Jim

Viewing 6 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic.