Electronic – VHDL types control

vhdl

I have (i've hope not silly) question about types control in vhdl.

type data_t is record -- 16 bytes + 1 bit
    order       : std_ulogic_vector(7 downto 0);
    data        : std_ulogic_vector(111 downto 0); --14 bytes data
    data_en     : std_ulogic;
    card_addr   : std_ulogic_vector(7 downto 0);
end record data_t;

type order_respond_t is record -- 16 bytes + 1 bit
    order       : std_ulogic_vector(7 downto 0);
    timestamp   : std_ulogic_vector(15 downto 0);
    data        : std_ulogic_vector(95 downto 0);
    data_en     : std_ulogic;
    card_addr   : std_ulogic_vector(7 downto 0);
end record order_respond_t;

Previously I was working as embedded programer so I am curious how it is working with vhdl. The records have exactly the same size but different structure inside. Can I do something like this ?:

signal_order_respond_t <= signal_data_t;

In C I can assign two different structures to each other using pointer (so I can map data from one structure to different one (let's skip if it is useful or not at this moment).

Is it possible to do it in VHDL, is it right according to good practices of vhdl coding ?

Best Answer

VHDL is strongly typed so what you request is not possible with some conversion functions. I would typically make some conversion functions that encode the record to a slv, and one that decodes from a slv to a record. With these functions something like the following is possible:

signal data : data_t;
signal order_respond : order_respond_t;
-- 
order_respond <= decode(encode(data));

Here's what the conversion code looks like. Realize with some helpers this can be simplified a bit as well.

subtype common_t is std_logic_vector(128 downto 0);
function encode(d : data_t) return common_t is
  variable comm : common_t;
begin
  comm(7 downto 0)               := d.order;
  comm(111+8 downto 8);          := d.data;
  comm(112+8);                   := d.data_en;
  comm(112+8+1+7 downto 112+8+1) := d.card_addr;
  return comm;
end encode;

function decode(comm : common_t) return order_respond_t is
  variable order_resp : order_respond_t;
begin
  order_resp.order     := comm(7 downto 0);             
  order_resp.timestamp := comm(8+15 downto 8);         
  order_resp.data      := comm(8+16+95 downto 8+16);                  
  order_resp.data_en   := comm(8+16+96);
  order_resp.card_addr := comm(8+16+96+7 downto 8+16+96+1)
  return d;
end decode;