Record type <-> std_logic_vector conversion - Python script

  • Thread starter Wojciech M. Zabolotny
  • Start date
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
 
In the previous message I'have forgotten to provide link to the announced
script.
It has been published in "alt.sources" Usenet group.
See
http://groups.google.com/group/alt.sources/browse_frm/thread/53ea61208013e9d1
Or look for topic "Script to generate VHDL package for conversion between the
record type and std_logic_vector"
If you want to unpack the archive from the Google archive, remember to
select "show original" option. Otherwise the indendation of the Python
source will be damaged.
--
Regards,
WZab
 
On Monday, March 19, 2012 1:57:36 PM UTC-4, Wojciech M. Zabolotny wrote:
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
Note that the 'objectmix.com' link that you reference also presents a solution that does not require any other language.

Kevin Jennings

Additional links for more information:
https://www.google.com/webhp?sourceid=navclient&amp;ie=UTF-8#hl=en&amp;sclient=psy-ab&amp;q=to_std_logic_vector+from_std_logic_vector+kevin+jennings&amp;oq=to_std_logic_vector+from_std_logic_vector+kevin+jennings&amp;aq=f&amp;aqi=&amp;aql=1&amp;gs_sm=3&amp;gs_upl=3469l3469l1l3984l2l2l0l0l0l0l156l296l0.2l2l0&amp;gs_l=hp.3...3469l3469l1l3984l2l2l0l0l0l0l156l296l0j2l2l0.cqn.1.&amp;pbx=1&amp;bav=on.2,or.r_gc.r_pw.r_qf.,cf.osb&amp;fp=2f01f92557ed5155&amp;biw=1290&amp;bih=887
 
"Wojciech M. Zabolotny" &lt;wzab@ise.pw.edu.pl&gt; wrote in message
news:slrnjmessg.64b.wzab@wzab.nasz.dom...
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.
Altera's Quartus2 (10.x+) seems to be able to instanciate arrays of records
as memory in basic cases. You may have a problem if you index the different
items in the record with different indexes and/or from clock domains, so
better be careful. I assume this will be resolved in a future version.
 
On 20 Mar, 02:37, KJ &lt;kkjenni...@sbcglobal.net&gt; wrote:
On Monday, March 19, 2012 1:57:36 PM UTC-4, Wojciech M. Zabolotny wrote:
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....

Note that the 'objectmix.com' link that you reference also presents a solution that does not require any other language.

Kevin Jennings

Additional links for more information:https://www.google.com/webhp?sourceid=navclient&amp;ie=UTF-8#hl=en&amp;sclien...
Yes, I know, but it seems to me, that it requires manual allocation of
bit ranges in the std_logic_vector so that
record fields do not overlap. If the width of any field is changed,
this allocation must be recalculated, which may lead
to errors. Have I missed something?

Wojtek Zabolotny
 
"wzab" &lt;wzab01@gmail.com&gt; wrote in message
news:c160299b-a585-428a-9b73-938e041854c8@9g2000vbq.googlegroups.com...
On 20 Mar, 09:16, "Morten Leikvoll" &lt;mleik...@yahoo.nospam&gt; wrote:
"Wojciech M. Zabolotny" &lt;w...@ise.pw.edu.pl&gt; wrote in
messagenews:slrnjmessg.64b.wzab@wzab.nasz.dom...

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.

Altera's Quartus2 (10.x+) seems to be able to instanciate arrays of
records
as memory in basic cases. You may have a problem if you index the
different
items in the record with different indexes and/or from clock domains, so
better be careful. I assume this will be resolved in a future version.

Yes, for inferred FIFOs and RAMs it worked both in Quartus and ISE for
quite
a long time (I don't remember in which version I've used it
successfully
for the first time).

However the problem is if you need to use e.g. more complicated FIFO
generated
by the CORE Generator, which has input and output of std_logic_vector
type.
I try to stay away from coregen functions as much as I can to make portable
code. Unfortunately I'm very often forced to :(
But inferring RAM has never bee the problem really. I know some oldtimers
that are afraid to, maybe because of the history of old implementation
tools, but I've become very confident with it.
If I get problems with a long record with multiple domains together with
dual port and different access widths on in/out, I prefer splitting the
record into many subrecords or subvectors to make it easier for the tool.
 
On 20 Mar, 09:16, "Morten Leikvoll" &lt;mleik...@yahoo.nospam&gt; wrote:
"Wojciech M. Zabolotny" &lt;w...@ise.pw.edu.pl&gt; wrote in messagenews:slrnjmessg.64b.wzab@wzab.nasz.dom...

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.

Altera's Quartus2 (10.x+) seems to be able to instanciate arrays of records
as memory in basic cases. You may have a problem if you index the different
items in the record with different indexes and/or from clock domains, so
better be careful. I assume this will be resolved in a future version.
Yes, for inferred FIFOs and RAMs it worked both in Quartus and ISE for
quite
a long time (I don't remember in which version I've used it
successfully
for the first time).

However the problem is if you need to use e.g. more complicated FIFO
generated
by the CORE Generator, which has input and output of std_logic_vector
type.
 
On Tuesday, March 20, 2012 3:34:50 AM UTC-4, wzab wrote:
On 20 Mar, 02:37, KJ &lt;kkjenni...@sbcglobal.net&gt; wrote:
On Monday, March 19, 2012 1:57:36 PM UTC-4, Wojciech M. Zabolotny wrote:
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.....

Note that the 'objectmix.com' link that you reference also presents a solution that does not require any other language.

Kevin Jennings

Additional links for more information:https://www.google.com/webhp?sourceid=navclient&amp;ie=UTF-8#hl=en&amp;sclien...

Yes, I know, but it seems to me, that it requires manual allocation of
bit ranges in the std_logic_vector so that
record fields do not overlap. If the width of any field is changed,
this allocation must be recalculated, which may lead
to errors. Have I missed something?
Yes, the record type must be updated (and that's the only thing) with the correct bit field positions but this is not really much of a problem for the following reasons:
- One of the primary usages is to map bit fields for a software interface. Interfaces have specifications that must be adhered to so the typing in of the bit positions is really just implementation of that part of the specification. Yes, I also know that some like to generate documentation (aka specification) from the code, but I've yet to meet the software person who is happy to have a fluid interface. The software design will have a similar typed in bit position interface definition defined in some header file in the language of their choice. Having the hardware design magically change bit field positions allows the hardware designer to be lazy by not forcing a specification update or even notification to others that are affected...now if you're a one man show doing hardware and software, maybe that's OK, but if that should ever change...well...
- The record type definition has the bit field positions all right there, and can be visually inspected pretty easily...subject to error I agree.
- When you make a change, you do check that it's working in simulation, correct?

Not saying the Python script isn't useful. The tradeoff has to do with adding another tool into the design flow that needs to be managed and understood by everyone who will use and support the tool over the entire lifetime of the design.

Kevin Jennings
 
On 20 Mar, 12:31, KJ &lt;kkjenni...@sbcglobal.net&gt; wrote:
On Tuesday, March 20, 2012 3:34:50 AM UTC-4, wzab wrote:
On 20 Mar, 02:37, KJ &lt;kkjenni...@sbcglobal.net&gt; wrote:
On Monday, March 19, 2012 1:57:36 PM UTC-4, Wojciech M. Zabolotny wrote:
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.....

Note that the 'objectmix.com' link that you reference also presents a solution that does not require any other language.

Kevin Jennings

Additional links for more information:https://www.google.com/webhp?sourceid=navclient&amp;ie=UTF-8#hl=en&amp;sclien...

Yes, I know, but it seems to me, that it requires manual allocation of
bit ranges in the std_logic_vector so that
record fields do not overlap. If the width of any field is changed,
this allocation must be recalculated, which may lead
to errors. Have I missed something?

Yes, the record type must be updated (and that's the only thing) with the correct bit field positions but this is not really much of a problem for the following reasons:
- One of the primary usages is to map bit fields for a software interface..  Interfaces have specifications that must be adhered to so the typing in of the bit positions is really just implementation of that part of the specification.  Yes, I also know that some like to generate documentation (aka specification) from the code, but I've yet to meet the software person who is happy to have a fluid interface.  The software design will have a similar typed in bit position interface definition defined in some header file in the language of their choice.  Having the hardware design magically change bit field positions allows the hardware designer to be lazy by not forcing a specification update or even notification to others that are affected...now if you're a one man show doing hardware and software, maybe that's OK, but if that should ever change...well...
- The record type definition has the bit field positions all right there, and can be visually inspected pretty easily...subject to error I agree.
- When you make a change, you do check that it's working in simulation, correct?

Not saying the Python script isn't useful.  The tradeoff has to do with adding another tool into the design flow that needs to be managed and understood by everyone who will use and support the tool over the entire lifetime of the design.

Kevin Jennings
Yes, you are definitely right. In case of building hardware/software
interface the allocation of bits for record fields should be known for
software.
However often i use such record&lt;-&gt;std_logic_vector conversions
internally, inside of the chip, and then this problem does not exist.
If I have to connect the record type (after conversion) to the output
port, or to the software readable register, I use the similar script
to generate the C headers or C++ headers with this information to
assure both flexibility and maintainability.

My colleague has even built much more complicated tool for automatic
mapping of complex structures in FPGA into software readable objects:
http://tesla.desy.de/new_pages/TESLA_Reports/2005/pdf_files/tesla2005-22.pdf

Wojtek Zabolotny
 

Welcome to EDABoard.com

Sponsor

Back
Top