如何重用实体以使用不同的组件

时间:2017-07-31 09:43:08

标签: vhdl

我是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等。这样做的最佳方法是什么? / p>

1 个答案:

答案 0 :(得分:0)

除了不同的端口大小外,您似乎希望组件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;

请注意,我没有编译此代码,因此它可能会有一些轻微的语法错误,但它应该让您概述G​​ENERIC如何用于执行您想要的操作。