hssig said:
Hi,
I am trying to use a generic to select a width of an implemented
signal:
entity xy is
generic ( gIC : integer := 1); -- 1: IC type x ; -- 2 IC type y
port ...
end;
architecture impl of xy is
signal sig : std_logic_vector(8 downto 0); -- when gIC = 1
-- signal sig: std_logic_vector(11 downto 0); -- when gIC = 2
end impl;
First question I always have when I see a generic constant of type integer:
why integer?
I doubt you want to allow negative values. So use type natural instead of
integer. Or even positive. Use the smallest type that is possible.
Continuing on that path: use a range:
generic ( gIC : integer range 1 TO 2 := 1)
The advantage of all this is of course early error reporting. Errors in
supplying impossible values are caught at analysis time, they are not
delayed until simulation time.
Better still: use an enumeration type. The names of the enumeration literals
can be chosen in a way so they become self documenting (meaningful names
instead of the magical values 1 and 2). The only drawback perhaps is that
you need a package. But I hardly would call that a drawback.
Elaborating on Jonathan's function:
package xy_pkg is
type gIC_type is
(
ic_x,
ic_y
);
function gIC_to_sig_width
(
gIC: gIC_type
) return positive;
end package xy_pkg;
package body xy_pkg is
function gIC_to_sig_width
(
gIC: gIC_type
) return positive is
begin
case gIC is
when ic_x => return 9;
when ic_y => return 12;
end case;
end function gIC_to_sig_width;
end package body xy_pkg;
This shows another advantage of using an enumeration type: no "others"
needed in the case statement. This again results in another early (analysis
time) error check. Whenever you add another enumeration literal to gIC_type
and you forget to add it in gIC_to_sig_width: bzzzzzzt, analyze error!
The earlier the error, the better!
And now that I come to think of it: I think that you could skip the function
an use a table instead. That way the package body is not needed, only the
package:
package xy_pkg is
type gIC_type is
(
ic_x,
ic_y
);
type gIC_to_sig_width_type is array(gIC_type) of positive;
constant gIC_to_sig_width: gIC_to_sig_width_type :=
(
ic_x => 9,
ic_y => 12
);
end package body;
In either case, the construction of sig_width is the same:
constant sig_width: positive := gIC_to_sig_width(gIC);
All the above is untested, so syntax errors are left as an exercise to the
reader (not to mention the egg on the writer's face).