Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can custom types be used in port declaration?

Tags:

vhdl

I am preparing for an exam by going through some old ones. One of the questions is:

Write the synthesizable behavioral VHDL code that implements the synchronous FSM in fig... The FSM has one input, called request, that is of enumeration type with values (r1, r2, r3)...

That makes me want to write this code:

entity fsm is
  port ( clk     : in  std_logic;
         request : in  my_enum_type
  );
end fsm;

And somewhere have a:

type my_enum_type is (r1, r2, r3);

somewhere (I have tried right befor the port declaration and right after the architecture declaration).

But I can't seem to get that to work. Can I have custom types as inputs or outputs like that?

like image 584
evading Avatar asked Jun 01 '13 12:06

evading


1 Answers

Yes you can, and I regard it as best practice - it means least work, best understanding, easiest maintenance, and cleanest design.

The trick is to declare the types common to your whole design in a package (I usually call it "Common" :-) and add use work.Common.all before the entity declaration AND in every customer of that entity. More specialised components can have appropriate names, of course!

For example:

package Common is    -- untested...

   type my_enum_type is (r1, r2, r3);

   -- (optional) useful tools
   function to_slv (e : my_enum_type) return std_logic_vector;
   function to_enum (s : std_logic_vector(my_enum'length downto 0)) 
                    return my_enum_type;

end Common;

package body Common is
   -- subprogram bodies here
end Common;

Now when you add a value to the enumeration, you ONLY modify "Common" and rebuild the design, while those who follow conventional guidelines are still trying to identify every port and signal where they have to increase the range of their "std_logic_vector" by 1.

Works really well for bus interfaces too, where a record in each direction hides all the individual bus and handshaking signals.

You WILL have to fight brain-dead tools like Xilinx "automatic testbench generator" which will helpfully translate ALL your port types - integer or boolean as well as custom - into std_logic(_vector) and then fail to compile. Just translate them back again.

You can still make a case that at the very top level, all the external FPGA pins should still be std_logic based. And if you ever need to simulate a post-synthesis version of your design, then you will either need to live with std_logic_vector ports, or add a simple wrapper to convert from one form to the other.

like image 99
user_1818839 Avatar answered Oct 21 '22 03:10

user_1818839