如何通过枚举索引std_logic_vector

时间:2012-12-10 21:07:13

标签: vhdl

我有一个像这样的std_logic_vector:

cntrl_signals:out std_logic_vector(4 downto 0);

为此向量提供索引的一种方法是为每个向量显式定义一个常量。

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;

这个想法是使用它们来索引矢量。

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

我的问题是,是否有一种很好的速记方式来声明索引(比如C中的枚举)?

2 个答案:

答案 0 :(得分:11)

您可以使用枚举,最好的方法是声明自己的std_logic向量,由枚举而不是整数索引。

但可能更好的是记录而不是矢量:

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

编辑以获取更多信息,发表评论:

缺乏想象力地使用std_logic_vector(以及一般的VHDL类型系统)正在召回VHDL ......

如果这是顶级实体,那么std_logic_vector端口允许您在顶级测试平台中替换综合后网表以进行可合成设计。或者您可能必须遵守坚持std_logic_vector端口的过时编码样式指南。

但在任何其他情况下,我会在包中声明记录,在整个设计中使用该包,并创建记录类型的端口。当你真正需要std_logic_vectors时,包应该包含函数to_slvto_control_sigs(罕见,如果你做对了)。

同样适用于枚举:

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);

当然,枚举比C更强大;以及将它们用作数组索引类型,您可以循环它们。无论何时更新枚举,都会使循环保持一致!

由枚举索引的记录或数组都有效;我更喜欢记录更清洁,更符合面向对象的习惯。

在任何一种情况下,如果将它用于实体端口,它将变得更加有用。为输出信号(包括地址和数据)声明一个记录(或数组!),为输入信号声明另一个记录(或数组!),因为你不能在一个端口中混合方向...(这些天FPGA中没有双向信号,所以不需要第三个端口)

现在您的设计可以防止总线结构变化;更改地址宽度或添加中断信号只会更改记录声明和任何实际用户;没有必要在整个层次结构中添加新信号......

答案 1 :(得分:1)

Brian有最好的答案,但另一点信息:

您可以创建这样的枚举:

type some_type is (clk, en, foo, bar, baz);

如果您拥有该类型的signalvariable,则可以使用'pos属性将其转换回数字:

variable v : some_type := foo;

v'pos将返回整数2