4

How to index a std_logic vector by enumeration

 2 years ago
source link: https://www.codesd.com/item/how-to-index-a-std-logic-vector-by-enumeration.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

How to index a std_logic vector by enumeration

advertisements

I have a std_logic_vector like this:

cntrl_signals:out std_logic_vector(4 downto 0);

One way to have indexes to this vector would be to explicitly define a constant for each.

constant CLK_SIG:integer := 0;
constant EN_SIG:integer := 1;
constant FOO_SIG:integer := 2;
constant BAR_SIG:integer := 3;
constant BAZ_SIG:integer := 4;

The idea is to use these to index the vector.

cntrl_signals <= (CLK_SIG=>1,EN_SIG=>1,others=>0);

My question is if there a nice shorthand way of declaring the indexes (like an enum in C)?


Well you could use enumerations, the best way would be to declare your own vector of std_logic, indexed by the enumeration instead of by integer.

But probably better would be a record instead of a vector :

type Control_Signals is record
   Clk : std_logic,
   En  : std_logic,
   Foo : std_logic,
   Bar : std_logic,
   Baz : std_logic
end record;

EDIT for more information, following comment:

Unimaginative use of std_logic_vector (and VHDL's type system in general) is holding VHDL back...

If this is a top level entity, then std_logic_vector ports allow you to substitute a post-synthesis netlist for your synthesisable design in the top level testbench. Or you may have to comply with antiquated coding style guidelines that insist on std_logic_vector ports.

But in any other circumstance I would declare the record in a package, use that package throughout the design, and make the ports of the record type. The package should include functions to_slv and to_control_sigs for the (rare, if you get it right) occasions when you actually need std_logic_vectors.

The same applies with enumerations:

type Controls is (Clk, En, Foo, Bar, Baz);
type Control_Signals is array(Controls) of std_logic;
My_Bus_Ctrl : Control_Signals := (Clk => '1', En => '1', others => '0');
My_External_SLV_Port <= std_logic_vector(My_Bus_Ctrl);

And of course, enumerations are a bit more powerful than in C; as well as using them as array index types, you can loop over them. Which keeps your loops in line whenever you update the enumeration!

Records or arrays indexed by enumerations both work; I prefer the record as a bit cleaner and more in line with object oriented practice.

In either case it becomes FAR more useful if you use it for entity ports. Declare one record (or array!) for outgoing bus signals (including address and data) and another for incoming signals, because you can't mix directions in a single port... (There are no bidirectional signals in an FPGA these days, so there is no need for a third port)

Now your design is protected against bus structure changes; changing the address width or adding an interrupt signal only changes the record declaration and any actual users; there is no need to add the new signal throughout the hierarchy...

Tags vhdl

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK