"header" 文件的 VHDL 标准布局和语法

VHDL standard layout & syntax for "header" file

IDE:Quartus 15

我是 VHDL 编程的新手,所以有一些我不习惯的细微差别(从 C++ 翻译而来)。虽然我已经找到了对 "source" 文件进行编程的资源,但我一直在努力寻找 "header" 文件的资源。

简而言之,VHDL "header" 文件的标准布局/语法是什么?

为简单起见,我感兴趣的用例是声明 subtype 和 "source" 文件之间使用的函数引用。

我找到了以下代码片段 here,它有点帮助,但我仍然不确定 packagepackage body 之间的区别。我也不确定 "work" 来自哪里。

"Header":

    package DEFS is
        CONSTANT MAJOR_VERSION: INTEGER := 0;
        CONSTANT MINOR_VERSION: INTEGER := 22;
        CONSTANT MAXREG: integer := 52;
        TYPE REGS_TYPE is array (0 to MAXREG) of STD_LOGIC_VECTOR(15 downto 0);
        FUNCTION opndrn(inp: std_logic) return std_logic;
    end package DEFS;

    package body DEFS is
        FUNCTION opndrn(inp: std_logic) return std_logic IS
        begin
            CASE INP is
                WHEN '0' => return '0';
                WHEN OTHERS => return 'Z';
            END CASE;    
        end;
    end package body DEFS;

"Source":

    LIBRARY work;
    USE work.defs.all;

感谢任何帮助。

幸运的是,VHDL 中没有头文件。

你所拥有的是一个包裹,从来没有 "include"d 在任何地方。

与头文件不同,包被单独编译为一个库,然后您可以 "use" 正如您所做的那样。

与头文件不同,包创建自己的命名空间。 USE work.defs.all; 导入整个命名空间,就像 C++ 中的 using namespace defs 一样。有时更好的做法是编写 USE work.defs;,这样您就可以有选择地使用该名称空间,并在源代码中引用 defs.Major_Version,从而 (a) 保持全局名称空间整洁,以及 (b) 记录 Major_Version 已定义。

与头文件不同,包鼓励将接口和实现适当分离。您的来源只能访问包导出的内容,即在包中而不是包体中声明的内容。这允许信息隐藏、不透明类型和通常更好的抽象。

例如,您可以在包中声明 Major_Version,但在正文中隐藏其实际值(参见 "deferred constants")

包和包体(接口和实现)在同一个文件中是合法的,但如果你想强制分离接口和实现,包体将是一个单独的文件。

然后您可以修改包体(实现)并重新编译它:使用该包的任何东西都不需要重新编译(除非您还更改了接口。

包的任何客户只需要看包文件,而不是包体。


简而言之,您所做的看起来还不错。

但是你可以在信息隐藏方面走得更远。

要注意的一件事是创建一个通用的 God 包:将总线常量、函数等分离到一个 "bus" 包、寄存器类型(可能还有它们所有名称的枚举)中要好得多在 "registers" 包中,在 "instructions" 包中的说明等