Hi Peter,
If I have well understood the compiler don't know that the actual will
be an unconstrained array, so I can not apply any index constraint.
This means that the example below is not correct. How would you then
write a general shift right function which work for array of integer or
array of real or array of unconstrained signed, ....
package ShiftPkg is
generic( type array_type) ;
function RightShift( A : array_type ; SHIFT : natural ) return
array_type ;
end ShiftPkg ;
package body ShiftPkg is
function RightShift( ARG : array_type ; SHIFT : natural , ZERO_VAL :
array_elt ;) return array_type is
constant ARG_L: INTEGER := ARG'LENGTH-1;
alias XARG: array_type(ARG_L downto 0) is ARG;
variable RESULT: array_type(ARG_L downto 0) := (others =>
ZERO_VAL);
RESULT: array_type;
begin
if COUNT <= ARG_L then
RESULT(ARG_L-COUNT downto 0) := XARG(ARG_L downto COUNT);
end if;
return RESULT;
end function RightShift;
end ShiftPkg ;
Kind Regards,
Yannick
---------------------------------------------------------------------------------------------------------
Yannick Grugni Design Competence Center
Leuven
VLSI Engineer Interleuvenlaan 74-82
Tel: +(32)16.390.742 3001 Leuven
yannick.grugni@philips.com Belgium
----------------------------------------------------------------------------------------------------------
"Peter Ashenden" <peter@ashenden.com.au>
2005-01-20 04:38 AM
To: Yannick Grugni/LEU/SC/PHILIPS@PHILIPS
cc: <vhdl-200x-ft@eda.org>
Subject: RE: [vhdl-200x-ft] Question On Type Genericity
Classification:
Yannick,
Re 1): In my modified example, I passed T'succ in as the actual function:
c : entity work.counter(behavioral)
generic map ( T, T'low, T'high, T'succ )
port map ( ... );
My reasoning was that 'succ is defined to be of a function kind, so why
not
treat it so in a general way?
Whether we would want to allow this or not is an open question. Currently,
the only places I can think of where a suprogram name can appear, denoting
the subprogram without calling it, are attribute specifications and group
declarations. In the case of attribute specifications, the name must be a
simple name, operator symbol or character literal, so an attribute name is
not allowed. In the case of a group declaration, the LRM explicitly
prohibits attribute names.
My inclination would be not to allow attribute names as actuals for
subprogram formals, since I think the expectation is that they be built
into
the innards of a compiler, rather than being implemented as subprograms.
If
that is the case, then you would need to define a helper function to
increment a value and pass that function as the actual.
Re 2): If I understand the intent of your example correctly, I don't think
you would specify enum_operation_type as a generic. Presumably there
would
not be different types for specifying the collection of operations to be
performed. If that is so, then only the type for the input and output
data
ports needs to be a generic. Also, since different arithmetic operators
are
required depending on the data type, those operators would need to be
specified as formal subprograms. You could use a default specifier to
allow
selection of the visible operator at point of instatiation. The example
would be written as:
entity add_substract is
generic ( type signal_type;
function "+"(a, b : signal_type) return signal_type is <>;
function "-"(a, b : signal_type) return signal_type is <>;
function "<"(a, b : signal_type) return boolean is <> );
port ( clk : in bit; operation : in enum_operation_type;
data1_in : in signal_type; data2_in : in signal_type;
data_out : out signal_type );
end entity add_substract;
-- signal_type can be integer,signed, unsigned ....
-- enum_operation_type is a enum (add,sub,maxval,minval)
architecture behavioral of add_substract is
begin
add_substract_behavior : process is
begin
wait until clk = '1';
if operation = add then
data_out <= data1_in + data2_in;
elsif operation = sub then
data_out <= data1_in - data2_in;
elsif operation = maxval then
if data1_in < data2_in then
data_out <= data2_in;
else
data_out <= data1_in;
end if;
else -- operation = minval
if data1_in < data2_in then
data_out <= data1_in;
else
data_out <= data2_in;
end if;
end if;
end process add_substract_behavior;
end architecture behavioral;
The idea here is that when you instantiate the entity with an actual type,
you can also provide the specific "+", "-" and "<" operators for that
type.
The "is <>" notation specifies that the default operator is the operator
of
the given name that is visible at the point of instantiation. So in the
following instantiation:
a : entity work.add_substract(behavioral)
generic map ( signal_type => unsigned )
port map ( ... );
the "+", "-" and "<" operators defined for unsigned that are visible are
used by default.
Re 3): In principle, entities and architectures that use generic types
should be synthesizable, provided the architecture bodies conform to other
synthesis guidelines. The information about actual types and actual
subprograms is globally static, and so is available for use by a synthesis
tool. Of course, whether synthesis tool vendors choose to support such
constructs is another questions. Also, the 1076.6 working group might
consider whether to include the features in a future revision of the
synthesis interoperability standard.
I hope this answers you questions.
Cheers,
PA
--
Dr. Peter J. Ashenden peter@ashenden.com.au
Ashenden Designs Pty. Ltd. www.ashenden.com.au
PO Box 640 Ph: +61 8 8339 7532
Stirling, SA 5152 Fax: +61 8 8339 2616
Australia Mobile: +61 414 70 9106
-----Original Message-----
From: yannick.grugni@philips.com [mailto:yannick.grugni@philips.com]
Sent: Wednesday, 19 January 2005 21:02
To: Peter Ashenden
Cc: vhdl-200x-ft@eda.org
Subject: RE: [vhdl-200x-ft] Question On Type Genericity
Thanks for your explanation.
I still have some questions:
1) In the revised version of my example, you enter as generic a function
succ, do I need to write this function or can I pass the attribute 'succ
at
instantition time :
entity counter is
generic ( type count_type; low, high : count_type;
function succ ( V : count_type ) return count_type );
2 ) How would you rewrite the following code :
entity add_substract is
generic ( type signal_type, type enum_operation_type);
port ( clk : in bit; operation : in enum_operation_type; data1_in : in
signal_type ; data2_in : in signal_type ; data_out : out signal_type );
end entity add_substract;
-- signal_type can be integer,signed, unsigned ....
-- enum_operation_type is a enum (add,sub,maxval,minval)
architecture behavioral of add_substract is
begin
add_substract_behavior : process is
variable count : count_type := low;
begin
wait until clk = '1';
if operation=add then
data_out <= data1_in +data2_in;
elsif operation=sub then
data_out <= data1_in - data2_in;
elsif operation = maxval then
if data1_in > data2_in then
data_out <= data1_in;
else
data_out <= data2_in;
end if;
else -- operation = minval
if data1_in < data2_in then
data_out <= data1_in;
else
data_out <= data2_in;
end if;
end if;
end process add_substract_behavior;
end architecture behavioral;
3) Will those 2 examples be only accepted by simulators or the intention
is
also to have them supported by synthesis tools?
Kind Regards,
Yannick
----------------------------------------------------------------------------
-----------------------------
Yannick Grugni Design Competence Center
Leuven
VLSI Engineer Interleuvenlaan 74-82
Tel: +(32)16.390.742 3001 Leuven
yannick.grugni@philips.com Belgium
----------------------------------------------------------------------------
------------------------------
Received on Mon Feb 7 06:36:14 2005
This archive was generated by hypermail 2.1.8 : Mon Feb 07 2005 - 06:36:59 PST