根据通用设置设置VHDL外部属性

3

我正在尝试编写调用外部子程序的VHDL模块,支持VHDL-2008 VHPI接口和Modelsim FLI接口。VHDL-2008标记外部子程序的机制如下:

atrribute foreign of some_subprogram : procedure is "VHPI libname;some_subprogram";

但是Modelsim中的FLI将其定义为:
attribute foreign of some_subprogram : procedure is "some_subprogram libname";

我希望使用相同的实体/结构对,因为所有VHDL都是相同的。唯一不同的是外部子程序属性。我尝试了以下内容:

function get_foreign_attribute_string(func_name : in string; libname : in libname) return string;

attribute foreign of some_subprogram : procedure is get_foreign_attribute_string("some_subprogram", "libname");

然而,Modelsim拒绝了这个操作,说这个外部属性不是一个字符串字面量。

我尝试将函数推入一个包中,并在包体中定义属性,但它要求属性附加到函数声明上。

除了声明两个包并根据工具集进行有选择性的编译,我不确定如何完成此操作。

您有什么想法吗?

编辑:以下是一个样例案例。

library std; -- for foriegn attribute
use std.all;

entity foo is
  generic
  (
    SIMULATOR : integer range 0 to 1 -- 0 = Modelsim FLI, 1 = VHDL-2008 VHPI
  );
end entity foo;

architecture test of foo is
  function get_foreign_attribute_string(func_name : in string; libname : in string) return string is
  begin
    case SIMULATOR is
      when 0 =>
        return func_name & " " & libname;
      when 1 =>
        return "VHPI " & libname & ";" & func_name;
    end case;
  end function;

  procedure some_subprogram is
  begin
      report "some_subprogram";
  end procedure;
  attribute foreign of some_subprogram : procedure is get_foreign_attribute_string("some_subprogram", "libname");
begin
end architecture test;

编辑:以下是我对解决方法的第一次尝试:

library std; -- for foreign attribute
use std.all;

entity foo is
  generic
  (
    SIMULATOR : integer range 0 to 1 -- 0 = Modelsim FLI, 1 = VHDL-2008 VHPI
  );
end entity foo;

architecture test of foo is
  procedure some_subprogram_mti is
  begin
    assert false;
  end procedure some_subprogram_mti;
  attribute foreign of some_subprogram_mti : procedure is "some_subprogram libname";

  procedure some_subprogram_vhpi is
  begin
    assert false;
  end procedure some_subprogram_vhpi;
  attribute foreign of some_subprogram_vhpi : procedure is "VHPI libname;some_subprogram";

  procedure some_subprogram is
  begin
    case SIMULATOR is
      when 0 =>
        some_subprogram_mti;
      when 1 =>
        some_subprogram_vhpi;
    end case;
  end procedure;

begin
end architecture test;

不幸的是,这也失败了,因为模拟器在精化期间尝试绑定外部函数。而_vhpi版本将无法绑定。


你能否将这些代码片段整合成一个可编译的示例,并将其添加到问题中?我模糊地记得在一篇名为“RLOC之死”的论文中看到过计算字符串(而不是字符串字面量)用于属性,但无法记住细节。因此,(1)创建一个测试用例,(2)查看LRM是否仅需要属性字面量,(3)查看Modelsim是否接受其他表达式,例如 funcname&"_"&libname - user1818839
计算字符串属性值的示例(用于属性RLOC_ORIGIN)在此处:http://www.edaboard.com/thread232639.html 或许Modelsim VHPI接口有些奇怪?GHDL支持一个受限子集,称为VHPI_Direct,这可能值得研究。 - user1818839
3
在一个外部属性规范中指定子程序的表达式需要是本地静态的。IEEE Std 1076-2008 7.2 属性规范,第8段。这个信息在分析时需要。在4.3 子程序体的第6段中,外部属性具有可能依赖于不同实现的字符串值,并且您已经证明了这一点。在VHDL语言中,没有一种方式可以操作本地静态表达式而不基于不同的模型结构。 - user1155120
@user1155120 感谢您提供的参考(如果IEEE可以像1666一样免费发布1076就好了)。我有一个可能解决这个问题的想法。稍后我会分享一个例子。 - PlayDough
@BrianDrummond 我尝试了一个简单的hack,只是将整个属性作为通用属性传递,看看是否可以解决问题,即: attribute foreign of some_subprogram : procedure is SOME_SUBPROGRAM_ATTRIBUTE_STRING;。但它报出相同的错误: ** 错误: test.vhd(17): 属性“foreign”不是字符串字面量。 - PlayDough
1
看起来我的唯一解决方法是在两个文件中定义一个包,每个文件都有特定于模拟器的属性。 对于OP中的示例,有一个test_pkg_mti.vhd和一个test_pkg_vhpi.vhd,每个文件都有其独特的外部规范。 然后在编译时动态选择适当的文件。 - PlayDough
1个回答

1
这似乎是foreign属性的一种特殊行为。因此,在Modelsim上,此代码可以正常工作:
entity ATTRIBUTE_TEST is
end entity ATTRIBUTE_TEST;

architecture ATTRIBUTE_TEST of ATTRIBUTE_TEST is
  function get_foreign_attribute_string(func_name : in string; libname : in string) return string is
  begin
    return func_name & " " & libname;
  end function;
  procedure some_subprogram is
  begin
      report "some_subprogram";
    end procedure;
  attribute not_foreign : string;
  attribute not_foreign of some_subprogram : procedure is get_foreign_attribute_string("some_subprogram", "libname");
begin
  process
  begin
    report "process";
    wait;
  end process;    
end architecture ATTRIBUTE_TEST;

1076-2008的第14.4.1节规定:

声明部分的详细说明包括按照声明部分中给出的顺序详细说明声明项(如果有)。对于所有声明部分,此规则均适用,但有以下三个例外:

...

c) 具有在STANDARD包中定义的“FOREIGN”属性的子程序声明部分。

对于这些情况,不会详细说明声明项;相反,设计实体或子程序将受到实现相关的详细说明。

这似乎与此处相关。


这段代码可以编译通过,但是它没有调用外部子程序模型。 - PlayDough
糟糕!我第一次阅读您的帖子时误解了。您的示例展示了“FOREIGN”的特殊性质,通常其他类似属性并不像本地静态那样绑定。 - PlayDough

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接