为什么使用组件时要重新定义端口?

Why are ports redefined when using components?

我正在学习 VHDL 并发现一些令人困惑的东西。假设您有以下实体:

entity alu32 is
    port(a, b       : in STD_LOGIC_VECTOR(31 downto 0);
         alucontrol : in STD_LOGIC_VECTOR(2 downto 0);
         result     : buffer STD_LOGIC_VECTOR(31 downto 0);
         zero       : out STD_LOGIC);
end alu32;

在其他实体的架构中作为组件使用时,定义如下:

component alu32
  port(
        a, b       : in STD_LOGIC_VECTOR(31 downto 0);
        alucontrol : in STD_LOGIC_VECTOR(2 downto 0);
        result     : buffer STD_LOGIC_VECTOR(31 downto 0);
        zero       : out STD_LOGIC
    );
 end component;

我的问题是,为什么我们要重新定义端口?这似乎是一个毫无意义的练习,因为它与实体声明中的完全相同。为什么 VHDL 的设计不允许您简单地使用这样的组件:

component alu32;

你可以,因为 VHDL-93。您可以使用

实例化
Alu_0: entity work.alu32
port map (
    ...
);

在此代码段中,您可以将work替换为您要实例化的组件的VHDL库,work始终当前库VHDL 源码驻留在.

为什么要使用组件声明?首先,如果您要实例化的不是 VHDL,例如 Verilog、IP 核和网表,则它们是必需的。其次,使用配置允许更改 port/entity 绑定,但您需要为此声明组件。

从本质上讲,语言设计者尽可能仔细地期待着一个世界......并没有那样发生。

component 声明的想法是它定义了实例化时所期望的内容,因此使用这些组件的 entity/architecture 是自洽的并且可以编译并且对某些extent 作为独立于它使用的组件的任务进行测试 - 甚至可能在编写这些组件之前。

Bill Lynch 的评论在这里很重要,但今天很容易忘记:当编译时间延长一千倍时,这是生产力的巨大胜利

稍后,当您构建总体设计时,将在组件库中搜索该组件,找到完全匹配的实体(默认配置),或者通过 [=11= 选择特定组件] 陈述。或者详细说明失败,将不匹配报告为错误 - 没有机会创建包含不太合适的零件的设计。该库可以包含范围广泛的 "alu32" 组件,这些组件具有用于不同目的(快速、小型、with/without 浮点等)的不同特性。这发生在 "elaboration",与软件中的 link 阶段大致相同,此时(希望)找到正确的 entity/arch,并根据组件的端口检查其端口。对于伴随着“The TTL Data Book”——TTL IC 形式的物理构建块库——长大的设计师来说,这是一种自然而然的方式来看待设计的演变。

但是,在今天的典型用例中,我们并没有在很大程度上使用组件库,因此您示例中的 "alu32" 可能是同一项目中的另一个文件,编译到您的"work"图书馆。

在那种情况下,Jonathan Drolet 的回答中更短、更简单的 "direct entity instantiation"(1993 年引入)是正确的方法。缺点?这确实意味着您必须先编写并成功编译 "alu32" 实体,然后才能对顶层设计进行语法检查(尽管您可以稍后在详细说明之前编写架构)。

IEEE 标准 1076-2008,6.8 组件声明

A component declaration declares an interface to a virtual design entity that may be used in a component instantiation statement. A component configuration or a configuration specification can be used to associate a component instance with a design entity that resides in a library.

3.4 配置声明

In certain cases, however, it may be appropriate to leave unspecified the binding of component instances in a given block and to defer such specification until later.

组件声明就像Function prototype。通用映射或端口映射方面是绑定指示的一部分。

来自附件一:

binding: The process of associating a design entity and, optionally, an architecture with an instance of a component. A binding can be specified in an explicit or a default binding indication. (3.4, 7.3.2, 7.3.3, 14.4.3.3, 14.5.4)

作为您想要考虑与配置声明一起使用的组件声明的示例,内部块具有相同接口的设计:

component sbox
    port (
        B:  in  std_logic_vector (1 to 6);
        S:  out std_logic_vector (1 to 4)
    );
end component;

它们实际上是不同的,您使用了多个:

S1: sbox
    port map (
        B   => ExK(1 to 6),
        S   => PO(1 to 4)
    );

S2: sbox
    port map (
        B   => ExK(7 to 12),
        S   => PO(5 to 8)
    );

封闭实体在其他方面是相同的 (dslice)。

您可以在阐述过程中指定在何处使用哪个实体:

configuration behave_config of des is
    for behave
    for DSLICE0: dslice
        use entity work.dslice(behave);        
        for behave
            for S1: sbox
                use entity work.sbox1(behave);
            end for;
            for S2: sbox
                use entity work.sbox2(behave);
            end for;
        end for;
    end for;
    ...

本例中的DES加密算法可以描述为四个部分的硬件,分别由替换框内容和外部互连来区分。

此设计模型展示了数字加密标准(FIPS Pub 46,单一 DES)中的数字加密算法的硬件特性。你可以仔细看看这个 link - vhdl_des.tar.gz.

对于不支持配置的综合或仿真工具,替代方法是统一包含实例化实体的块,在这种情况下,设计描述的大小几乎增加了四倍,同时增加了维护和不必要的复制的危害。