我可以从外部访问实例化实体中的常量吗?

Can I access a constant inside a instantiated entity from outside?

我有一个带有通用参数列表的 VHDL 实体。此实体的体系结构计算几个常量,这些常量是创建预期功能所必需的。

是否可以从外部访问这些常量之一?

示例 1:
假设有一个 FIFO,它根据 DEPTH 和 OUTREG 决定最佳实现是什么(基于寄存器、基于 SRL 或基于 BlockRAM)。取决于此,通过 FIFO 的最小延迟可以在 1 到 2 个周期之间变化。

例二:
将相同的 FIFO 考虑为跨时钟兼容。现在最小延迟还取决于所选择的同步电路和频率差异。

示例 3:
一个division实体需要N个周期来计算adivb。 N 取决于 BITS、RADIX、OUTREG、IS_SIGNED、...

进一步假设每个实体都有一个 NATURAL 类型的 MIN_DELAY 常量,这对其他实例很重要。

例如实例化实体需要知道它必须至少等待多长时间才能得到结果。

我可以想到 2 个解决方案,但我认为都不是一个好方案。

方案一:
我可以将用于计算的算法存储在一个包中,这样它就可以在全球范围内访问。但这违反了封装原则:)。外界只需要知道延迟值而不是算法n。

方案二:
我可以使用有效位。这在动态、自适应或流水线系统中始终是一个很好的解决方案,但该位不能在综合时用于进一步的选择或优化。

可能方案三:
VHDL有定义新属性的能力,但是可以访问吗?

示例实体:alu_div:

constant MIN_DELAY : NATURAL := BITS / log2(RADIX) + 2;
attribute DELAY   : NATURAL;
attribute DELAY of alu_div : entity is MIN_DELAY;

示例顶部:

mydiv : entity work.alu_div
   generic map (....)
   port map (....);

blk : block
  constant my : NATURAL := mydiv'delay;
begin
  ....
end block;

新: 可能的解决方案 4:
我发现了这个 SE 问题,其中 Jim Lewis 指出分层引用也应该与常量一起使用。
alias MY_DELAY is <<constant mydiv.DELAY : NATURAL >>;
Get internal signals of vhdl design in ncvhdl (alternative to modelsim's signal spy)

好问题。我有时也觉得需要 "OUT mode generics",它的实际值是在体系结构中计算的,再次允许层次结构中的更高级别知道(并调整到)处理单元的管道深度。

可能值得写一个提案来允许 VHDL-201x 中的某种东西并将其提交给 standards group,但与此同时我们必须忍受我们所拥有的。

我的正常解决方案是使用与单位关联的包,其中包含初始常数(而不是通用常数)和相关量。这将 "encapsulation breakage" 限制为 use 包的那些编译单元,使它们至少易于识别。

在包中,常量在可能的情况下被延迟,或者无参数(不纯)函数,它们是一样的。

我还没有探索过的一种可能的方法是,在 PORT list 之后的实体声明也允许零个或多个 entity_delarative_item。如果这些可能包含函数声明,那么我们可能会 return 这样的信息。

编辑:David 指出了一个 LRM 规则 (8.3),该规则阻止了当前 VHDL 版本的这种方法:该规则的有限放宽可能是 "OUT mode generics" 的替代方法。

实体声明还可以包括 begin 和一些被动构造 - 例如断言一组泛型和端口宽度是一致的。这样你就必须 input 所有必需的值,但至少构建会失败报告错误,例如widthdepth 不一致。

同意它有时对有关实施的信息非常有用 来自实体的细节,虽然打破了封装原则,但是 对于白盒验证,它可以提供很大的帮助。

尝试使用基于如下实体的实体属性:

entity alu_div is
  generic(
    BITS  : positive;
    RADIX : positive);

  port(
    ...);
  constant MIN_DELAY : NATURAL := BITS / log2(RADIX) + 2;
  attribute DELAY   : NATURAL;
  attribute DELAY of alu_div : entity is MIN_DELAY;
end entity;

但是实例化alu_div的模块无法访问它 使用例如alu_div_0'DELAY,因为 ModelSim 给出错误:

No attribute specification with designator "DELAY" decorates label "alu_div_0".

一种对白盒验证有用的方法,其中验证 取决于实现,是用来自的信息制作一个输出端口 实施,例如:

entity alu_div is
  ...
  port(
    ...
    DELAY_O : out natural);
  ...
end entity;

architecture syn of alu_div is
begin
  DELAY_O <= MIN_DELAY;
  ...

它不会是一个真正的常量,因为对于模拟它需要一个增量循环 在获取值之前,但在许多情况下它可能是一个足够的解决方案。

这是对 Morten 的第一个实体声明的修改,其中对于 'module' 实例化 alu_div 我希望有一个组件声明提供名称 alu_div 的声明。

没有修饰该声明的属性,因此在标签 alu_div_0 处找到的实例化没有属性 DELAY

如果您要使用直接实体实例化,它可能会起作用:

entity alu_div is
  constant MIN_DELAY : NATURAL := 42;
  attribute DELAY   : NATURAL;
  attribute DELAY of alu_div : entity is MIN_DELAY;
end entity;

architecture foo of alu_div is

begin
end architecture;

entity test is
end entity;

architecture foo of test is

begin
alu_div_0: 
    entity work.alu_div ;

MONITOR:
    process 
    begin
        wait for 1 ns;
        report "alu_div'DELAY = " & natural'image(work.alu_div'DELAY);
        wait;
    end process;
end architecture;

给出:

ghdl -a alu_div.vhdl
ghdl -e test
ghdl -r test
alu_div.vhdl:25:9:@1ns:(report note): alu_div'DELAY = 42
>

这个想法是,如果您使用具有选定名称(扩展名称)的直接实体实例化,您将使用前缀标注的库中的声明(在本例中为 WORK)。

下面演示了访问 alu_div'DELAY 的值可以在详细说明中完成:

entity alu_div is
 generic (pickone: natural := 1);
  constant MIN_DELAY : NATURAL := 42;
  constant TARG_DELAY:  natural := MIN_DELAY + pickone;
  attribute DELAY   : NATURAL;
  attribute DELAY of alu_div:  entity is MIN_DELAY;
  -- attribute DELAY of alu_div : entity is TARG_DELAY;
end entity;

architecture foo of alu_div is

begin
end architecture;

entity test is
end entity;

architecture fie of test is
    constant fumble: natural := work.alu_div'DELAY;
    component alu_div is
        generic (pickone: natural := 1);
    end component;
begin
alu_div_0: 
    alu_div
    generic map(1);

MONITOR:
    process 
    begin
        report "constant fumble = " & natural'image(fumble);
        report "alu_div'DELAY = " & natural'image(work.alu_div'DELAY);
        wait;
    end process;
end architecture;

这有效:

ghdl -a alu_div.vhdl
david_koontz@Macbook: ghdl -e test
david_koontz@Macbook: ghdl -r test
alu_div.vhdl:60:9:@0ms:(report note): constant fumble = 42
alu_div.vhdl:61:9:@0ms:(report note): alu_div'DELAY = 42

另外,根据 Jonathan 的评论,问题是试图通过泛型提供的实例化组件循环信息,我尝试将实体属性切换为依赖于泛型(用 [=17= 注释掉那个,取消注释那个)使用 TARG_DELAY),这会导致与 Morten 提供的错误不同的错误:

ghdl -a alu_div.vhdl
alu_div.vhdl:36:13: attribute expression for entity must be locally static
ghdl: compilation error

这个错误在 2008 LRM 中非常有用并且很容易找到,而且非常具体:

7.2 Attribute specification (paragraph 8):

The expression specifies the value of this attribute for each of the named entities inheriting the attribute as a result of this attribute specification. The type of the expression in the attribute specification shall be the same as (or implicitly convertible to) the type mark in the corresponding attribute declaration. If the entity name list denotes an entity declaration, architecture body, configuration declaration, or an uninstantiated package that is declared as a design unit, then the expression is required to be locally static (see 9.4.1)....

此要求是在 '93 LRM(5.1 属性规范)中引入的。通过研究,我们发现在 -1992 年的标准化工作(-1993 年批准)中有一项针对 out-mode generics 的提案。

同样在 87 年问题报告 40 (IR00040.txt) 之后的第一个 ISAC 基本原理报告中讨论了与从架构中设置属性相关的问题:

  1. Such a capability would greatly (and negatively) affect at least some implementations. A straightforward approach to the implementation of specifications is to decorate the named entity with the information contained in the specification. However, when the entity appears in one design unit and the applicable specification appears in another, many problems result. One cannot analyze the specification without modifying the library unit containing the entity, which can lead to potential circular chains of dependence. Moreover, multiple architectures corresponding to a given entity interface cannot each supply a different value to the attribute of some interface-resident entity. Finally, there is no LRM requirement that, if one architecture attributes some interface-resident entity, then all must, which seems desirable.

您可能会注意到,依赖于泛型的属性也可能出现不需要的循环依赖。或者与过时泛型类似,问题从分析顺序的循环依赖(属性声明中的局部静态表达式)转移到详细说明顺序(评估全局静态表达式),这可能要困难得多。 out-mode 泛型在可用记录中显示零星提及,最后一次出现在 vhdl-200x-mp(建模和生产力)电子邮件反射器上。

如果没有人定义如何处理后期绑定(链接加载器时间)顺序依赖性,那么这两个状态都不太可能发生变化。

同时,正如 Brian 所说,公认的方法是使用一个共享的包,它使用本地静态常量声明(并且依赖于声明顺序)。您还可以通过配置来解决问题。

我使用的另一种方法是通过将所有 "generic" 信息指定为另一个泛型来忍受所有 "generic" 信息流入模块的限制,即我希望从派生参数获得的结果。

例如,

entity alu_div is
  generic(
    BITS  : positive;
    RADIX : positive;
    DELAY : positive);
  port(
    ...);

在该体系结构中,ACTUAL_DELAY 常量是从其他泛型(加上端口总线宽度等)导出的,并与给定的 DELAY 泛型进行比较。

如果请求的 DELAYACTUAL_DELAY 相同,则一切正常。

如果请求的 DELAY 超过 ACTUAL_DELAY,架构可以插入流水线阶段来满足请求。总体设计将按预期运行,但它可能会消耗比绝对必要更多的寄存器。

否则无法满足请求的延迟,架构断言严重性失败。