无论如何都要将类型或子类型传入和传出函数

时间:2014-02-28 14:16:09

标签: vhdl

深思熟虑。

我正在处理大量数据信息,这些信息传入和传出记录,向量和ram。 为此,我喜欢使我的代码非常简单,因为它可以快速复杂化。

我前几天正在处理一些我正在读取内存块的信息。

此数据的上半部分包含在包文件中定义的信息。 我试着在下面做一个例子。

我有8位信息+ 64位数据IE a vector 71 downto 0;
信息字节又被分成半字节,我创建了两个具有定义范围的常量向量。

constant nibble_one : std_logic_vector(7 downto 4) := X"F";
constant nibble_two : std_logic_vector(3 downto 0) := X"2"; 

和内存输出的向量

signal data_out : std_logic_vector(71 downto 0);

现在我需要在

时停止从内存中读取
data_out(71 downto 68) = nibble_one; 

它当然可以通过多种方式完成,如上所述,这很好。但现在是有趣的部分。我认为必须通过重载“+”运算符来执行以下操作。

data_out(nibble_one'range + 64) = nibble_one; 

哪个看起来不错。但是我遇到了障碍。如何将“范围值”传递给函数并再次传递给该函数?

4 个答案:

答案 0 :(得分:1)

我不认为您可以将类型提升为第一类值,可以在运行时进行操作,而无需将VHDL转换为动态类型语言。哪个不会发生。

这意味着没有办法写一个函数,比如'+'返回一个类型;只有一个值(例如整数,数组或记录)。返回数组或记录中的值对可行,但使用起来很难看。

所以你必须预先创建类型。这与静态类型理念一致:显式声明允许编译器尽可能多地清理。

如果这是nibble_one的唯一用途,那么

没有任何问题
constant nibble_one : std_logic_vector(71 downto 68) := X"F";

然后你的表达简化为

    data_out(nibble_one'range) = nibble_one; 

否则你需要一些更丑陋的东西,比如明确的解决方案:

    data_out((nibble_one'left + 64) downto (nibble_one'right + 64))

然而,你至少可以将丑陋限制在一个地方:

constant MS_Nibble : std_logic_vector(nibble_one'left + 64) 
                              downto (nibble_one'right + 64) := nibble_one;

    data_out(MS_Nibble'range) = nibble_one; 

或比较功能:

function equal (word : std_logic_vector; nibble : std_logic_vector; 
         offset : natural) return boolean is
begin
   assert nibble'left + offset <= word'left and
          nibble'right + offset >= word'right
   report "Compare_range error" severity failure;
   return word(nibble'left + offset downto word(nibble'right + offset) = nibble;
end equal;

然后在你的循环中,

    exit when equal(data_out, nibble_one, offset => 64);

答案 1 :(得分:1)

其他方法更好,但我能想到的最接近你尝试的方法是:

function offset_range(s : std_logic_vector; offset : natural) return std_logic_vector is
  variable so : std_logic_vector(s'high + offset downto s'low + offset);
begin
  return so;
end function offset_range

...

data_out(offset_range(nibble_one, 64)'range) = nibble_one

它有效,但它并不完美。编写函数会更常规,因此它将data_out作为参数并返回所需的切片,当然。

(编辑):我应该澄清一下,这个解决方案更像是一个实验,而不是我实际建议使用的解决方案。

答案 2 :(得分:1)

返回data_out部分的不纯函数提供了一种格式,但需要为每个信号提取特定函数:

  constant nibble_one : std_logic_vector(7 downto 4) := X"F";
  constant nibble_two : std_logic_vector(3 downto 0) := X"2";

  signal data_out : std_logic_vector(71 downto 0);

  impure function data_out_part(nibble : std_logic_vector; offset : integer) return std_logic_vector is
  begin
    return data_out(nibble'left + offset downto nibble'right + offset);
  end function;

  signal data_out_part_sig : std_logic_vector(3 downto 0);  -- For example below

begin

  data_out_part_sig <= data_out_part(nibble_one, 64);  -- Example of use

答案 3 :(得分:0)

我认为不可能以你想要的方式使用(或超载)plus运算符。但是,一个简单的解决方案是:

data_out((nibble_one'left + 64) downto (nibble_one'right + 64)) = nibble_one;

(假设您仅使用downto范围。)