I am writing IPbus Transaction Verification Model for UVVM and I have encountered some problem. I know potential solution, but I don't like it and I am not sure if it can be handled better in some different way.
Here is some code snippet that is necessary to introduce the problem.
type t_ipbus_tranaction_header is record protocol_version : natural range 0 to 2**4 - 1; transaction_id : natural range 0 to 2**12 - 1; words : natural range 0 to 2**8 - 1; type_id : t_ipbus_transaction_type_id; info_code : t_ipbus_transaction_info_code; end record; -- Overload t_slv_array in order to enable unconstrained array in record. type t_slv_array is array (natural range <>) of std_logic_vector(31 downto 0); type t_ipbus_transaction is record header : t_ipbus_tranaction_header; bodyy : t_slv_array; end record; function ipbus_transaction ( protocol_version : natural; transaction_id : natural; words : natural; type_id : t_ipbus_transaction_type_id; info_code : t_ipbus_transaction_info_code; bodyy : t_slv_array ) return t_ipbus_transaction is variable trans : t_ipbus_transaction(bodyy(bodyy'length-1 downto 0)); begin assert protocol_version = 2 report "Wrong IPbus protocol version." severity failure; trans.header.protocol_version := protocol_version; trans.header.transaction_id := transaction_id; trans.header.words := words; trans.header.type_id := type_id; trans.header.info_code := info_code; trans.bodyy := bodyy; return trans; end function; function ipbus_read_transaction ( read_size : natural; base_address : std_logic_vector(31 downto 0) ) return t_ipbus_transaction is variable aux : t_slv_array(0 downto 0); begin aux(0) := base_address; return ipbus_transaction(2, 0, read_size, READ, OUTBOUND_REQUEST, aux); end function;
Now, I would like to define signal or variable in the testbench in the following way:
signal transaction : t_ipbus_transaction := ipbus_read_transaction(1, (others => '0'));
However this returns following error in the GHDL:
tb/ipbus_tvm_tb.vhd:40:12:error: declaration of signal "transaction" with unconstrained record type "t_ipbus_transaction" is not allowed tb/ipbus_tvm_tb.vhd:40:12:error: (even with a default value)
I am not sure if it is because of lack of the support in the VHDL standard or in GHDL.
I have also tried the following definition:
signal transaction : t_ipbus_transaction := new ipbus_read_transaction(1, (others => '0'));
This returns error:
tb/ipbus_tvm_tb.vhd:41:53:error: a type mark must denote a type or a subtype tb/ipbus_tvm_tb.vhd:41:53:error: (type mark denotes function "ipbus_read_transaction")
So it is not supported by the VHDL standard.
I am aware that the problem can be easily solved by the following definition:
signal transaction : t_ipbus_transaction(bodyy(0 downto 0)) := ipbus_read_transaction(1, (others => '0'));
However, this approach has few drawbacks for me. Namely:
- User has to type redundant information.
- User has to know transaction body length in advance.
- User has to have greater knowledge about the protocol itself.
So, this is the VHDL language issue I am facing right now.
I realize already in this moment, that there also will be problem with returning response transaction in the procedure via output argument, where length of the transaction body is also unknown.
I would like to ask you for advice, if my object oriented approach to model the IPbus transaction with variable body length is implementable in the VHDL language.