The record types in VHDL are very useful when designing more complicated systems. However if you need to store data of record types to memory or FIFO, it is necessary to convert such data to the std_logic_vector type. Similarly, when such data are read from the memory or FIFO, it is necessary to convert to the original record type. This problem was often discussed, eg. here:
Finally I've decided to prepare a Python script which automatically generates the appropriate VHDL package containing both the records type declaration and functions to convert between this type and std_logic_vector.
The input data is a "description file" containing:
- The record type name in the first non-comment line: record name_of_my_type
- A few (at least 1) field declarations, which may have two forms: name_of_the_field,type,number_of_bits or name_of_the_field,type,nr_of_left_bit,nr_of_right_bit
the type may be either "signed" or "unsigned"
- The end line, consisting of a single "end" word.
The description file may contain also multiple comment lines, containing the hash "#" character in the first column.
For example if you run: $ ./rec_to_pkg.py test1.rec
with the following test1.rec:
# This is a test record - packet descriptor record pkt_desc # Below are fields definitions # First two pointers for linked list # prv - previous prv,unsigned,6 # nxt - next nxt,unsigned,6 # Then address to the packet data addr,unsigned,15,0 # Finally flags flags,unsigned,9,2 end
You'll get the following VHDL package:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; package pkt_desc_pkg is
type pkt_desc is record prv : unsigned(5 downto 0); nxt : unsigned(5 downto 0); addr : unsigned(15 downto 0); flags : unsigned(9 downto 2); end record;
constant pkt_desc_width : integer := 36;
function pkt_desc_to_stlv( constant din : pkt_desc) return std_logic_vector;
function stlv_to_pkt_desc( constant din : std_logic_vector) return pkt_desc;
end pkt_desc_pkg;
package body pkt_desc_pkg is
function pkt_desc_to_stlv( constant din : pkt_desc) return std_logic_vector is variable res : std_logic_vector(35 downto 0); begin res(5 downto 0) := std_logic_vector(din.prv); res(11 downto 6) := std_logic_vector(din.nxt); res(27 downto 12) := std_logic_vector(din.addr); res(35 downto 28) := std_logic_vector(din.flags); return res; end pkt_desc_to_stlv;
function stlv_to_pkt_desc( constant din : std_logic_vector) return pkt_desc is variable res : pkt_desc; begin res.prv:=unsigned(din(5 downto 0)); res.nxt:=unsigned(din(11 downto 6)); res.addr:=unsigned(din(27 downto 12)); res.flags:=unsigned(din(35 downto 28)); return res; end stlv_to_pkt_desc;
end pkt_desc_pkg;
Such automatic handling of the record type declaration and of conversion functions should minimize nember of errors due to mistakes in mapping of record's fields into the bits of the std_logic_vector.
Please note, that the information about the total number of bits in our record type is generated as name_of_my_type_width (pkt_desc_width in the above example).
I hope, that you'll find this script useful. As it is published as PUBLIC DOMAIN, you are free to modify and use it in any way you want.
Wojciech M. Zabolotny snipped-for-privacy@ise.pw.edu.pl