【问题标题】:How to reuse an entity to work with different components如何重用实体来处理不同的组件
【发布时间】:2017-07-31 19:50:15
【问题描述】:

我对 vhdl 相当陌生,想知道管理以下情况/模式的最佳方法是什么:

假设我有一个实体 A,其架构实例化了组件 B。然后我想重用 A,但这次实例化组件 C 来代替 B。C 具有与 B 完全不同的功能。B 和 C 可能具有不同大小的端口,但是 A 的功能是它可以处理不同的端口大小,例如使用泛型和生成语句。本质上,A 就像组件 B、C 或 D、E、F 等的容器。它可能以所有这些组件通用的方式对 B、C 等的输入和输出执行一些逻辑/缓冲。

我已经阅读了有关配置的信息,我的理解是我可以在 A 中实例化一个组件(称为 Z),然后使用配置将它的实体链接到不同的架构。使用vhdl这个功能的人好像不多。

配置是否适合这种情况?

理想情况下,我希望设计中的所有参数最终取决于为 Z 选择的架构,以便架构决定其链接到 (Z) 的实体的端口大小,进而决定 Z 的端口大小决定 A 的参数,最后这些参数决定 A 的端口大小。这可能吗?

(我在一般意义上使用“参数化”来表示配置设计的一种方式。泛型、包、“范围属性等都是参数化的示例)

我的意思的伪代码示例如下。大写字母的值应取决于为 Z 选择的架构。

entity A is

    port
    (
        clk             : in std_logic;
        reset           : in std_logic;
        inputs          : in std_logic_vector(SOME_WIDTH_A_IN - 1 downto 0);
        outputs         : out std_logic_vector(SOME_WIDTH_A_OUT - 1 downto 0);
    );

end A;

architecture A_arch of A is

    component Z

        port
        (
            clock       : in std_logic;
            inputs      : std_logic_vector(SOME_WIDTH_Z_IN - 1 downto 0);
            ouputs      : std_logic_vector(SOME_WIDTH_Z_OUT - 1 downto 0)
        );

    end component;

begin

    for i in 1 to SOME_VALUE generate
        -- whatever logic/buffering we want to perform on the inputs    
    end generate;

    for i in 1 to SOME_VALUE generate
        -- whatever logic/buffering we want to perform on the outputs
    end generate;

    instance: Z   
        port map(
            clock => clk,
            inputs => --output of logic/buffering above 
            outputs => -- input of logic/buffering above
        );

end A_arch;

我可能以错误的方式思考这个问题 - 本质上,我希望避免复制/粘贴“容器”实体 A 来处理不同的组件 B、C 等。这样做的最佳方法是什么?

【问题讨论】:

  • “模块”是一个verilog术语。使用“实体”。你应该把它画在示意图中。 “容器”是什么意思?这是一个非常广泛的概念。您还使用了不是 VHDL 概念的“参数”和“过滤器”。总结一下:我发现我很难理解你的问题。也许写一些伪代码左右?
  • 感谢观看,正在编辑中
  • 配置是你正在寻找的,我想。我肯定会使用它们。
  • 是否可以直接从为 Z 选择的架构中导出伪代码中大写字母的值?或者 A 必须事先了解这些值(即我是否必须将这些值作为泛型单独提供给实体 A)
  • 你可以用泛型来做这一切,并在配置中给它们赋值。

标签: vhdl


【解决方案1】:

您似乎希望您的组件 B、C、D 等...除了端口大小不同外,完全相同。最好的方法是使用 GENERIC。假设您的另一个实体(我们称之为 INNER_ENTITY)是可配置的 n 位宽双触发器(可用于解决亚稳态)。 以下是 OUTER_ENTITY 和 INNER_ENTITY 的示例代码:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity OUTER_ENTITY is
    port (
        CLK     : in    std_logic;
        RST     : in    std_logic;
        PORT_A  : in    std_logic_vector(6 downto 0);
        PORT_B  : in    std_logic_vector(13 downto 0);
        SUM_A_B : out   std_logic_vector(13 downto 0)
    );
end entity;

architecture RTL_OUTER_ENTITY of OUTER_ENTITY is
    signal PORT_A_INNER : std_logic_vector(6 downto 0);
    signal PORT_B_INNER : std_logic_vector(13 downto 0);

    component INNER_ENTITY
        generic (PORT_SIZE : integer);
        port (
            CLK      : in   std_logic;
            RST      : in   std_logic;
            PORT_IN  : in   std_logic_vector(PORT_SIZE - 1 downto 0);
            PORT_OUT : out  std_logic_vector(PORT_SIZE - 1 downto 0);
        );
    end component INNER_ENTITY;

begin

    SUM_A_B <= PORT_A_INNER + PORT_B_INNER;

    INNER_7_BIT : INNER_ENTITY
        generic map (PORT_SIZE => 7)
        port map (
            CLK         => CLK,
            RST         => RST,
            PORT_IN     => PORT_A,
            PORT_OUT    => PORT_A_INNER
        );

    INNER_14_BIT : INNER_ENTITY
        generic map (PORT_SIZE => 14)
        port map (
            CLK         => CLK,
            RST         => RST,
            PORT_IN     => PORT_B,
            PORT_OUT    => PORT_B_INNER
        );
end RTL_OUTER_ENTITY;   

entity INNER_ENTITY
    generic (PORT_SIZE : integer);
    port (
        CLK      : in   std_logic;
        RST      : in   std_logic;
        PORT_IN  : in   std_logic_vector(PORT_SIZE - 1 downto 0);
        PORT_OUT : out  std_logic_vector(PORT_SIZE - 1 downto 0);
    );
end entity;

architecture RTL_INNER_ENTITY of INNER_ENTITY is

    signal  PORT_X :  std_logic_vector(PORT_SIZE - 1 downto 0);
begin

    process(CLK, RST)
    begin
        if RST = '1' then
            PORT_OUT <= (OTHERS => '0');
            PORT_X   <= (OTHERS => '0');
        elsif rising_edge(CLK) then
            PORT_OUT <= PORT_X;
            PORT_X <= PORT_IN;
        end if;
    end process;
end RTL_INNER_ENTITY;

请注意,我没有编译此代码,因此它可能有一些小的语法错误,但它应该让您大致了解如何使用 GENERIC 来做您想做的事情。

【讨论】:

  • 我在看到你的示例代码之前添加了这个,但我相信你可以看到我做了什么。泛型也可以用在 FOR LOOP 语句中
  • 感谢您的回答,但实际上 B 和 C 具有不同的功能。就我而言,它们是不同的音频处理算法。我再次编辑以使其更清晰。
  • 啊,好吧,那么我将在实体 A 中使用泛型来指定功能(根据您所说的端口大小不确定是使用 B 还是 C)。然后使用 IF...THEN...GENERATE 根据泛型使用 B 或 C。
  • 问题在于,如果有大量可能的功能,架构 Z 会变得有点笨拙,不是吗?另外,我们在哪里可以得到伪代码中 SOME_VALUE 的值?我们可以在 A 中计算它(如果功能 B 则 SOME_VALUE = WHATEVER),但这意味着每次 B(或 C 或 D 等)发生更改时都必须编辑 A。这就是我要避免的,因为这样很容易引入错误。
  • IF THEN GENERATE 构造将允许您根据通用值进行不同的处理。所以,是的。您还可以在进程中使用常规的 IF THEN。但我相信这会更令人困惑。
猜你喜欢
  • 1970-01-01
  • 2021-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-28
相关资源
最近更新 更多