Unions and/or Variant Records
Summary
This proposal uses discriminants (or alternately generics) to create unions/variant records.
The proposal #81 proposes using discriminants for constraining unconstrained elements of composites.
Gigabit Ethernet Using Discriminants
-- 3 different physical interface from FPGA to a 1GbE PHY chip
type PhyInterfaceType is (RGMII, GMII, SGMII);
type GigabitEthernetType (kind : PhyInterfaceType ) is record
case kind is
when RGMII =>
TX_Data : std_logic_vector(4 downto 0);
RX_Data : std_logic_vector(4 downto 0);
when GMII =>
TX_Data : std_logic_vector(7 downto 0);
TX_Valid : std_logic;
TX_Error : std_logic;
RX_Data : std_logic_vector(7 downto 0);
RX_Valid : std_logic;
RX_Error : std_logic;
when SGMII =>
TX_P : std_logic;
TX_N : std_logic;
RX_P : std_logic;
RX_N : std_logic;
end case;
MDIO_Clock : std_logic;
MDIO_Data : std_logic;
end record GigabitEthernetType ;
Mode views with Discriminants
To complete the picture, Mode Views also need discriminants. There probably needs to be a mechanism where the View gets the discriminant value from the record type.
view GigabitEthernetMasterView (kind : PhyInterfaceType) of GigabitEthernetType is
case kind is
when RGMII =>
TX_Data : out ;
RX_Data : in ;
when GMII =>
TX_Data : out ;
TX_Valid : out ;
TX_Error : in ;
RX_Data : in ;
RX_Valid : in ;
RX_Error : out ;
when SGMII =>
TX_P : out ;
TX_N : out ;
RX_P : in ;
RX_N : in ;
end case;
MDIO_Clock : in ;
MDIO_Data : out ;
end view GigabitEthernetMasterView ;
Usage on Entity Interface
On an entity interface it is probably appropriate that the discriminant be static for each instance, and hence, it is set by the generic.
entity Ethernet is
generic (
PHY_BUS_KIND : PhyInterfaceType
);
port (
Clock : std_logic;
GigabitEthernet: GigabitEthernetMasterView (PHY_BUS_KIND) of GigabitEthernetType (PHY_BUS_KIND)
)
In a similar fashion to an entity interface using composites with unconstrained elements
entity Ethernet is
port (
Clock : std_logic;
GigabitEthernet: GigabitEthernetMasterView of GigabitEthernetType
)
VHDL alternative style using generics
If we implement this with generics, then each generic instance creates a new type and we loose ability to allow an object to dynamically determine what the record contains.
type EthernetInterfaceType is record
generic (
kind : BusInterfaceKind
);
case kind is
when RGMII =>
TX_Data : std_logic_vector(4 downto 0);
RX_Data : std_logic_vector(4 downto 0);
when GMII =>
TX_Data : std_logic_vector(7 downto 0);
TX_Valid : std_logic;
TX_Error : std_logic;
RX_Data : std_logic_vector(7 downto 0);
RX_Valid : std_logic;
RX_Error : std_logic;
when SGMII =>
TX_P : std_logic;
TX_N : std_logic;
RX_P : std_logic;
RX_N : std_logic;
end case;
MDIO_Clock : std_logic;
MDIO_Data : std_logic;
end record;