【问题标题】:Can I access a constant inside a instantiated entity from outside?我可以从外部访问实例化实体中的常量吗?
【发布时间】:2015-06-01 01:18:34
【问题描述】:

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

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

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

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

示例 3:
一个划分实体需要N个循环来计算a div b。 N 取决于 BITS、RADIX、OUTREG、IS_SIGNED、...

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

例如实例化实体需要知道它至少必须等待多长时间。

我可以想到 2 种解决方案,但我认为这两种都不是很好的解决方案。

解决方案 1:
我可以将计算的算法存储在一个包中,以便全局访问。但这违反了封装原则:)。外界只需要知道延迟值,不需要知道算法。

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

可能的解决方案 3:
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)

【问题讨论】:

    标签: vhdl


    【解决方案1】:

    这是对 Morten 的第一个实体声明的修改,其中对于实例化 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 测试
    ghdl -r 测试
    alu_div.vhdl:25:9:@1ns:(报告说明): 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 测试
    alu_div.vhdl:60:9:@0ms:(报告说明): 不断摸索 = 42
    alu_div.vhdl:61:9:@0ms:(报告说明): alu_div'DELAY = 42

    在 Jonathan 的评论之后,该问题试图通过泛型提供的实例化组件循环信息,我尝试将实体属性切换为依赖泛型(用MIN_DELAY 注释掉一个,用TARG_DELAY 取消注释) 并导致与 Morten 提供的错误不同:

    ghdl -a alu_div.vhdl
    alu_div.vhdl:36:13: 实体的属性表达式必须是本地静态
    ghdl:编译错误

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

    7.2 属性说明(第 8 段):

    表达式为继承该属性的每个命名实体指定该属性的值,作为该属性规范的结果。属性规范中表达式的类型应与相应属性声明中的类型标记相同(或隐式转换为)。 如果实体名称列表表示实体声明、架构主体、配置声明或声明为设计单元的未实例化包,则表达式必须是本地静态的(见 9.4.1)。 ...

    此要求是在 '93 LRM(5.1 属性规范)中引入的。经过研究,我们发现在 -1992 年的标准化工作(在 -1993 年获得批准)中提出了out-mode generics

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

    1. 这样的能力会极大地(和负面地)影响至少一些 实施。一种直接的实施方法 规范是用信息来装饰命名实体 包含在规范中。 但是,当实体出现在 一个设计单元和适用的规范出现在另一个, 结果很多问题。没有就无法分析规范 修改包含实体的库单元,这可能导致 潜在的循环依赖链。 此外,多个 对应于给定实体接口的体系结构不能每个 为某些接口驻留的属性提供不同的值 实体。最后,没有 LRM 要求,如果一个架构 属性一些接口常驻实体,那么所有必须,这似乎 可取的。

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

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

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

    【讨论】:

    • 它在modelsim上工作。问题在于 delay 属性是恒定的,而 OP 希望它依赖于泛型。我认为这就是 Morten 尝试过的,因为他报告的错误是关于 label alu_div_0', and not the entity work.alu_div`。
    • @JonathanDrolet、Ya 和我在另一条评论中指出,属性规范中的表达式是本地静态的。 (杜哦!)。 Morten 报告的错误仍然没有达到目标。
    • 分层引用呢?我发现了这个 SE 问题,@JimLewis 指出这些引用也应该与常量一起使用:A <= <<signal .tb_top.u_comp1.my_sig : std_logic_vector >>;Get internal signals of vhdl design in ncvhdl (alternative to modelsim's signal spy)
    • 外部名称不会合成,只适合验证。块之间的通信是通过信号进行的。实体/架构对在细化、提供可见性限制、本地化名称空间方面具有等效的块语句。共享变量用于进程之间的通信。请注意,后期细化设计网络是平面的,名称空间由在设计层次结构中具有局部性的唯一声明表示。实现通过 ID 引用声明的对象。路径/实例名称用于人。
    【解决方案2】:

    好问题。我有时也觉得需要“OUT 模式泛型”,它的实际值是在架构中计算的,再次允许层次结构中的更高级别知道(并调整)处理单元的管道深度。

    可能值得写一个提案以允许在 VHDL-201x 中使用此类内容并将其提交给standards group,但同时我们必须接受我们所拥有的。

    我的正常解决方案是使用与单元关联的包,同时保存初始常量(而不是泛型)和相关量。这将“封装破坏”限制为use 包的那些编译单元,使它们至少易于识别。

    在包中,常量在可能的情况下被延迟,或者无参数(不纯)函数,这相当于同一件事。

    我尚未探索的一种可能方法是,在PORT list 之后的实体声明也允许零个或多个entity_delarative_items。如果这些可能包括函数声明,那么我们可能会以这种方式返回此类信息。

    编辑:David 指出了一个 LRM 规则 (8.3),它阻止了当前 VHDL 版本的这种方法:对该规则的有限放宽可能是“OUT 模式泛型”的替代方案。

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

    【讨论】:

    • “OUT 模式泛型”是描述此功能的好名字:)。写一个提案可能是一个解决方案,但首先我想等待其他答案。
    • 你会将什么形式的项目连接到“out”泛型?延迟常数是否合适?另外,这是否会由于创建循环引用的可能性而产生问题?
    • out 模式泛型与 -2008 不一致,6.5.6.2 泛型子句“泛型提供了一个通道,用于将信息从其环境传递给块、包或子程序。”没有关于“从一个街区”。这是一个新类别 - 详细顺序依赖检查,听起来你需要一些本地静态的东西来打破循环,并且可能很难获得正确的语义描述。 (其他答案中的属性取决于分析顺序)。合成供应商可能需要一段时间才能接受这个想法。
    • 它可能是一个延迟常量或类似的东西,其值可以在架构中设置——例如管道阶段数组的长度。 @David Koontz - 如果这与 -2008 一致,则可能不会问这个问题。
    • 具有实体前缀的扩展名称只能在“构造”本身或其架构中访问(-2008 8.3 选定名称,第 9 段)。您调用声明为实体声明项的函数的可能方法不应该工作。
    【解决方案3】:

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

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

    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 报错:

    没有带有指示符“DELAY”的属性规范修饰标签“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;
      ...
    

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

    【讨论】:

      【解决方案4】:

      我使用的另一种方法是通过将我想要的派生参数的结果指定为另一个泛型来接受所有“泛型”信息流入模块的限制。

      例如,

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

      在架构中,ACTUAL_DELAY 常量从其他泛型(加上端口总线宽度等)派生,并与给定的DELAY 泛型进行比较。

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

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

      否则无法满足请求的延迟,并且架构断言严重性为 FAILURE。

      【讨论】:

        猜你喜欢
        • 2012-08-20
        • 1970-01-01
        • 1970-01-01
        • 2011-05-11
        • 1970-01-01
        • 1970-01-01
        • 2018-09-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多