W
Wojciech M. Zabolotny
Guest
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:
http://stackoverflow.com/questions/3985694/serialize-vhdl-record
http://objectmix.com/vhdl/190447-converting-records-std_logic_vector.html
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:
1. The record type name in the first non-comment line:
record name_of_my_type
2. 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"
3. 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
wzab@ise.pw.edu.pl
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:
http://stackoverflow.com/questions/3985694/serialize-vhdl-record
http://objectmix.com/vhdl/190447-converting-records-std_logic_vector.html
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:
1. The record type name in the first non-comment line:
record name_of_my_type
2. 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"
3. 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
wzab@ise.pw.edu.pl