Abstract Packages
Is your capability/feature request related to a problem?
Abstract packages to establish a set of subprograms that a package must implement in order to be passed as a generic - in a similar fashion to generic packages.
Issue
A limitation to type generics is that we cannot make any assumptions about what operators and/or subprograms are supported for a given type. As a result, the type and subprograms must be passed as generics.
This is shown below on the interface to RandomGenericPkg.
package RandomGenericPkg is
generic (
type RandomSeedType ; -- base type for randomization
procedure Uniform (Result : out real ; Seed : inout RandomSeedType) ;
function GenRandSeed(IV : integer_vector) return RandomSeedType ;
function GenRandSeed(I : integer) return RandomSeedType ;
function GenRandSeed(S : string) return RandomSeedType
) ;
. . .
end package RandomGenericPkg ;
Use Model 1:
The goal is to minimize the amount of information that needs to be sent.
package RandomGenericPkg is
generic (
package RandomBasePkg is abstract work.RandomBaseAbsPkg
) ;
use RandomBasePkg.all ;
. . .
end package RandomGenericPkg ;
...
package RandomBaseAbsPkg is abstract
type RandomSeedType ; -- base type for randomization
procedure Uniform (Result : out real ; Seed : inout RandomSeedType) ;
function GenRandSeed(IV : integer_vector) return RandomSeedType ;
function GenRandSeed(I : integer) return RandomSeedType ;
function GenRandSeed(S : string) return RandomSeedType ;
end package RandomBaseAbsPkg ;
...
package RandomPkg is new RandomGenericPkg
generic map (RandomBaseAbsPkg => RandomBasePkg) ;
Use Model 2:
-- There are issues in this that still need to be resolved.
When we work with math types, there may be more than one type defined in the package, such as ieee.numeric_std.unsigned and ieee.numeric_std.signed.
package NumericAbsPkg is abstract
type NumericType ;
function from_integer(I : integer) return NumericType ;
function to_integer(N : NumericType) return integer ;
function from_real(R : real) return NumericType ;
function to_real(N : NumericType) return NumericType ;
function "+"(l, r : NumericType) return NumericType ;
function "+"(l : NumericType ; r : integer) return NumericType ;
function "+"(l : integer ; r : NumericType ) return NumericType ;
function "+"(l : NumericType ; r : real) return NumericType ;
function "+"(l : real; r : NumericType ) return NumericType ;
function "-"(l, r : NumericType) return NumericType ;
function "-"(l : NumericType ; r : integer) return NumericType ;
function "-"(l : integer ; r : NumericType ) return NumericType ;
function "-"(l : NumericType ; r : real) return NumericType ;
function "-"(l : real; r : NumericType ) return NumericType ;
end package NumericAbsPkg ;
package ComplexMathGenericPkg is
generic (
package NumericPkg is abstract work.NumericAbsPkg
) ;
use NumericPkg.all ;
. . .
end package ComplexMathGenericPkg ;
. . .
package ComplexMathUnsignedPkg is new ComplexMathGenericPkg
generic map (NumericPkg => ieee.numeric_std with (NumericType => Unsigned ) ;
-- Issues - NumericType not identified as a type that may need to be mapped.
-- issues - from_real and from_integer need to be sized for array based types and
-- perhaps does not work. So mixed overloading may need to be omitted.
General Comments
An essential companion to generics on packages.
Rust has a nice solution for this problem: https://doc.rust-lang.org/book/traits.html or on wikipedia the general description: https://en.wikipedia.org/wiki/Type_class
Original TWIKI Proposal (all copied over)
See http://www.eda-twiki.org/cgi-bin/view.cgi/P1076/AbstractPackages.