使用别名的 VHDL 聚合分配

标签 vhdl aggregate alias test-bench

我在我的 VHDL 测试平台(简写如下所示)中使用聚合时遇到了一些问题。

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all    

entity TB is 
end entity;

architecture RTL of TB is
    -- constant(s)
    constant  CLK_PERIOD    : time                         := 10 ns; -- 100 MHz
    -- signal(s)
    signal    CLK           : std_logic                    := '0';
    signal    nRST          : std_logic                    := '1';
    signal    CONFIG_REG    : std_logic_vector(7 downto 0) := (others => '0');
begin
    -- clock driver
    CLK  <= NOT CLK after (CLK_PERIOD / 2.0);

    -- main process
    process
    begin
        -- reset driver...
        nRST  <= 
            '1', 
            '0' after (CLK_PERIOD * 1);

        -- set initial configuration...
        CONFIG_REG <= (
            6           =>  '1',     
            3 downto 2  => "01", 
            7 | 0       =>  '1', 
            others      =>  '0'
        );

        -- do test-bench stuff...

        -- update configuration...
        CONFIG_REG <= (
            6           =>  '0',     
            3 downto 2  => "10", 
            7 | 0       =>  '1', 
            others      =>  '0'
        );

        -- do more test-bench stuff...
    end process;
end architecture;

我真的很想给配置寄存器的各个部分“命名”,这样它实际上读起来很好。

所以我想说:

Bit[6]   = ENABLE
Bit[3:2] = MODE
Bit[7|0] = READY_DONE

我知道我可以为 6 使用常量:

constant  ENABLE : integer := 6;

然后我的代码如下所示:

CONFIG_REG <= (
    ENABLE      =>  '1',     
    3 downto 2  => "01", 
    7 | 0       =>  '1',
    others      =>  '0'
);

但我一直难以尝试将范围 3 缩小到 27|0 命名,以便代码如下所示:

CONFIG_REG <= (
    ENABLE      =>  '1',     
    MODE        => "01", 
    READY_DONE  =>  '1',
    others      =>  '0'
);

我认为我可以使用别名来完成此操作,并且我一直在查看 VHDL Golden Reference Guide (p.15)就理解别名和范围而言,这非常有帮助,但我仍然无法弄清楚如何命名范围本身或值的“或”(|)。

目前我有下面的“hack”,我不太喜欢...

constant ENABLE :  integer := 6;
alias    MODE   is CONFIG_REG(3 downto 2);
-- what to do about the OR though???

CONFIG_REG <= (
    ENABLE      =>  '1',     
    MODE'RANGE  => "01", 
    7 | 0       =>  '1',
    others      =>  '0'
);

我真的想让我的测试台可读,这样当我看它时 6 个月。从现在开始,我将知道它在做什么,而不必去弄清楚“现在位 [6] 又是什么???”或者在我必须将代码交给其他开发人员的情况下,他们可以很容易地了解我试图完成的工作。

如有任何帮助/建议,我们将不胜感激。

感谢阅读。


编辑:修复了 7 | 0 有效:

无效:

7 | 0       =>  "10",

有效:

7 | 0       =>  '1',

最佳答案

当心,您的代码无效:聚合符号 7 | 0 代表索引组,而不是向量。它应该是关联的 std_logic 值,而不是 std_logic_vector。此外,在 2008 年之前的 VHDL 版本中,聚合符号 3 downto 2 也应该关联 std_logic 值:

-- set initial configuration...
CONFIG_REG <= (
    6           => '1',     
    3 downto 2  => '1', 
    7 | 0       => '0', 
    others      => '0'
);

在 VHDL 2008 中,现在支持离散范围的选择与聚合类型的表达式之间的关联。所以,3 downto 2 => "01" 在 VHDL 2008 中是可以的。但是由于 VHDL 2008 仍然没有被许多合成器完全支持,你应该小心,除非这段代码不应该当然是合成。

无论如何,使用记录而不是向量可能是解决您的问题的一种选择。如果您还需要数据的矢量版本,您可以非常轻松地编写矢量和记录类型之间的转换函数。示例:

package foo is
  type config_type is record
    ready:    std_ulogic;
    enable:   std_ulogic;
    foobar:   std_ulogic_vector(1 downto 0);
    mode:     std_ulogic_vector(1 downto 0);
    reserved: std_ulogic;
    done:     std_ulogic;
  end record;

  function rec2vec(v: config_type) return std_ulogic_vector;
  function vec2rec(v: std_ulogic_vector) return config_type;
end package foo;

package body foo is
  function rec2vec(v: config_type) return std_ulogic_vector is
  begin
    return v.ready & v.enable & v.foobar & v.mode & v.reserved & v.done;
  end function rec2vec;

  function vec2rec(v: std_ulogic_vector) return config_type is
    constant vv: std_ulogic_vector(7 downto 0) := v;
  begin
    return (ready => vv(7), enable => vv(6), foobar => vv(5 downto 4),
            mode => vv(3 downto 2), reserved => vv(1), done => vv(0));
  end function vec2rec;
end package body foo;

然后您可以使用聚合符号来分配记录:

signal config_reg: config_type;
...
config_reg <= (
  ready  => '1',
  enable => '1',
  foobar => "--",
  mode   => "01",
  others => '0'
);

并转换为自向量:

signal config_reg_v: std_ulogic_vector(7 downto 0);
...
config_reg_v <= rec2vec(config_reg);
...
config_reg <= vec2rec(config_reg_v);
...
config_reg <= vec2rec(X"ff");

注意:我使用了 std_ulogicstd_ulogic_vector 而不是解析后的 std_logicstd_logic_vector。这有充分的理由,但这是另一个问题。

关于使用别名的 VHDL 聚合分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45470325/

相关文章:

vhdl - 如何在 VHDL-2008 或更高版本中模拟 C++ 类

decimal - 带小数的 VHDL 时钟分频器

json - 从 Postgres 中的 2 个聚合列构建 JSON

python - PySpark Dataframe 将列融为行

entity-framework - 单个查询中的EF多个聚合

linux - 如何将脚本调用添加到 linux 命令?

join - Sequelize 查询 - 是否可以在包含的(内连接)模型中为字段设置别名

vhdl - 如何防止 Xilinx XST 从我的设计中合并网络?

vhdl - 在 VHDL 中,当作为参数传递给函数/过程时,无约束数组的索引范围默认为什么?

sql-server - 无法使用别名连接到 SQL Server