【问题标题】:How to create a subsignal / subvariable from an entity variable in VHDL?如何从 VHDL 中的实体变量创建子信号/子变量?
【发布时间】:2018-04-07 17:00:56
【问题描述】:

我目前正在用 VHDL 实现 MIPS 处理器。系统组件(将 ALU、寄存器文件、控制单元等粘合在一起)具有以下实体描述:

entity system is
    port (
                 reset : in std_logic;
                 sys_clk : in std_logic;
                 instruction : in std_logic_vector(15 downto 0);
                 sys_mem_dump : in std_logic := '0'
         );
end system;

在这个系统的架构部分,我试图创建指令变量的“子变量”,对应于使用的操作码和寄存器。

architecture Behavioral of system is
        instruction_opcode : std_logic_vector(3 downto 0) := instruction(15 downto 12);
        instruction_rd : std_logic_vector(3 downto 0) := instruction(11 downto 8); -- destination register
        instruction_rs : std_logic_vector(3 downto 0) := instruction(7 downto 4); -- source register
        instruction_rt : std_logic_vector(3 downto 0) := instruction(3 downto 0); -- target register
        -- a bunch of signals
begin 
    -- a bunch of port maps
end Behavioral

我尝试过signalvariableshared_variableconstant,但是当我将这些变量之一映射到它时,这些导致寄存器文件的地址没有被初始化。我也尝试将这些变量放在系统实体端口中,但这也不起作用。我也不想将系统实体端口中的instruction变量拆分成这四个变量。

【问题讨论】:

  • 请阅读您教授的课程资料或书籍或任何其他有关 VHDL 的资源,因为缺少基础知识。
  • @Paebbels 在 VHDL 中根本不可能做到这一点吗?我查看了 synario 手册和其他一些网站,没有一个数据对象类型与这个用例匹配。

标签: vhdl


【解决方案1】:

同意 paebles:您似乎缺乏基本的 VHDL 知识,应该在您的书中查找。

你至少应该知道这个方法:

architecture Behavioral of system is
    signal instruction_opcode : std_logic_vector(3 downto 0);
begin
    instruction_opcode <= instruction(15 downto 12);
end architecture;

但实际上你可以使用别名:

architecture Behavioral of system is
    alias instruction_opcode : std_logic_vector(3 downto 0) is instruction(15 downto 12);
begin
end architecture;

【讨论】:

  • 我的书里几乎没有VHDL,上学期要我们学习VHDL,但根本没有发生。感谢您回答问题。
【解决方案2】:

反映您评论的共同话题

@Paebbels 在 VHDL 中根本不可能做到这一点吗?我查看了 synario 手册和其他一些网站,没有一个数据对象类型与这个用例匹配。

是你使用的参考文献不充分。

除了 JH Bonarius 的回答中描述的中间信号和对象别名之外,还有一种方法使用声明为子类型的索引范围:

library ieee;
use ieee.std_logic_1164.all;

entity field is
    port (
        fourbitfield:   in  std_logic_vector (3 downto 0)
    );
end entity;

architecture foo of field is 
begin
end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity system is
    port (
        reset:          in  std_logic;
        sys_clk:        in  std_logic;
        instruction:    in  std_logic_vector(15 downto 0);
        sys_mem_dump:   in  std_logic := '0'
    );
end entity system;

architecture foo of system is
    subtype opcode is integer range 15 downto 12;
    subtype rd is integer range 11 downto 8;
    subtype rs is integer range 7 downto 4;
    subtype rt is integer range 3 downto 0;
begin
U1: 
    entity work.field port map (instruction(opcode));

U2: 
    entity work.field port map (instruction(rd));

U3: 
    entity work.field port map (instruction(rs));

U4: 
    entity work.field port map (instruction(rt));
end architecture;

这会分析、阐述和模拟(在证明没有边界错误的同时实际上没有做任何事情)。

实体是一个独立的设计单元,自然允许抽象(在详细说明组件实例化期间,端口名称与端口映射中的实际信号相关联)。所有其他形式的名称或使用中间对象都是抽象形式,旨在提高可读性并由样式决定。

在上面的instruction(opcode) 中,切片名称(IEEE Std 1076-2008 8.5 切片名称)以整数子类型的形式提供离散范围。您也可以直接使用具有离散范围(例如 15 到 12)的切片名称作为关联列表中的实际值,而无需声明子类型:

U1:
    entity work.field port map (fourbitfield => instruction(15 downto 12));

在此处显示的正式端口和实际信号之间使用命名关联可以排除进一步抽象的需要。口述抽象会影响 VHDL 标准不要求的样式。

您对子信号或变量的想法与 VHDL 中的切片名称一致,就像使用中间信号一样容易。别名只是命名实体(包括对象切片)的其他名称。

您使用哪种额外的抽象方法可能取决于预期读者的复杂程度。

如果有人在 Stackoverflow 上彻底搜索 标记,您会找到所有这三种方法的示例。聪明的读者可以编辑您的问题以符合 VHDL 语法并将其作为副本提交。

【讨论】:

  • 好建议。这看起来不错。我现在突然考虑另一种方法是使用records 和instruction.opcode。但是你需要一些转换函数 slv->record。当然opcode 应该是枚举类型......等等。
猜你喜欢
  • 2013-03-07
  • 1970-01-01
  • 2020-02-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-07
  • 2017-04-04
  • 2020-04-12
  • 2012-04-20
相关资源
最近更新 更多