内存地址应该使用什么VHDL数据类型?

内存地址应该使用什么VHDL数据类型?,vhdl,type-conversion,Vhdl,Type Conversion,我正在开发一个BIST引擎的描述,经理要求我从Verilog转换到VHDL。我对VHDL非常生疏,我无法在代码中找出正确的数据类型来提供给地址寄存器。大多数情况下,地址用于索引到数组中 data : std_logic_vector (2**W-1 downto 0); ... output = data(addr); 但有时,我需要执行位操作(例如,这段代码在地址中找到最低有效值1): 使用std_logic_vector或类似工具时,尝试将地址用作数组索引时会出现错误: ncvhdl_p:

我正在开发一个BIST引擎的描述,经理要求我从Verilog转换到VHDL。我对VHDL非常生疏,我无法在代码中找出正确的数据类型来提供给地址寄存器。大多数情况下,地址用于索引到数组中

data : std_logic_vector (2**W-1 downto 0);
...
output = data(addr);
但有时,我需要执行位操作(例如,这段代码在地址中找到最低有效值1):

使用std_logic_vector或类似工具时,尝试将地址用作数组索引时会出现错误:

ncvhdl_p: *E,INTYMM (filename,52|17): array index type mismatch [6.4]

我在这里似乎处于一个没有胜算的局面。我使用什么数据类型?请注意,解决方案必须是可合成的。谢谢

在这种情况下,我将使用
无符号
类型

这与您在通用位访问方面使用的
std\u logic\u vector
操作非常相似,但您也可以对地址执行算术运算,并在必要时轻松转换为/从
integer
类型。另外,它不会用“可怕的”
std\u logic\u unsigned
包玷污
std\u logic\u vector
的意义

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

...

architecture myarch of myent is
   signal address : unsigned(numbits-1 downto 0);

   ...

begin

-- as an example
addr_counter : process(sysclk, reset)
begin
   if reset = '1' then
      address <= (others => '0');
   elsif rising_edge(sysclk) then
      address <= address + 1;
   end if;
end process addr_counter;
...
ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
...
myent的架构myarch是
信号地址:无符号(numbits-1向下至0);
...
开始
--例如
地址计数器:进程(sysclk,重置)
开始
如果重置='1',则
地址“0”);
elsif上升沿(sysclk)然后

地址您想要按位访问和包装行为:

  • 使
    addr
    基本上成为
    无符号
    向量
然后您需要以整数形式访问它:

  • 如果只需要在一行中使用整数,请在该行中使用
    来调用整数
    
  • 如果您需要在多个位置将其作为一个整数,请创建另一个“阴影”信号,并在体系结构中放置一个连续赋值
像这样:

signal addr_int:natural;
....
addr_int <= to_integer(addr);
信号地址:自然;
....

addr_int不幸的是,这并不能解决数组索引类型不匹配错误。我不能使用无符号来索引向量,而且经常转换为整数实际上不是一个选项,因为地址主要用作索引。我真的希望数据类型能够避免所有转换。我的意思是,我不希望几十个
to_integer(address)
语句散乱在我的代码中,因为在大多数对address的引用中,我都将其用作索引。我可以将其设置为int,并在必要时转换为unsigned,但随后我遇到了信号不会正确溢出的问题。我想我会写我自己的加法函数,但这一切似乎太麻烦了;应该是更简单的方法。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

...

architecture myarch of myent is
   signal address : unsigned(numbits-1 downto 0);

   ...

begin

-- as an example
addr_counter : process(sysclk, reset)
begin
   if reset = '1' then
      address <= (others => '0');
   elsif rising_edge(sysclk) then
      address <= address + 1;
   end if;
end process addr_counter;
...
signal addr_int:natural;
....
addr_int <= to_integer(addr);