首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >vhdl包导出它从另一个包导出的符号

vhdl包导出它从另一个包导出的符号
EN

Stack Overflow用户
提问于 2020-11-25 22:11:05
回答 3查看 110关注 0票数 1

假设我有一个包strkern (我有),它导出函数: strlen

代码语言:javascript
复制
package strkern is
    function strlen(s: string) return natural;
end package strkern;

我写了一个新的包stdstring,它定义了许多令人兴奋的新操作符,但也想重新导出strlen

代码语言:javascript
复制
use work.strkern.all;

package stdstring is
    -- rexport strlen
    -- define exciting new operators
end package stdstring

所以如果一个代码

代码语言:javascript
复制
use work.stdstring.all;

你得到strlen()和令人兴奋的新操作符。如何从子包“重新导出”函数/类型导入?没有使用新名称的虚拟实现,而只是调用“要导入的”实现

代码语言:javascript
复制
function strlen(s: string) return natural is
    return strkern.strlen(s);
end function strlen;
EN

回答 3

Stack Overflow用户

发布于 2020-11-26 00:52:34

通过提供一个最小的、完整的和可验证的示例:

代码语言:javascript
复制
package strkern is
    function strlen(s: string) return natural;
end package strkern;

package body strkern is
    function strlen(s: string) return natural is
    begin
        return s'length;
    end function;
end package body;

use work.strkern.all;  -- NOT USED in this foreshortened example
package stdstring is
    -- rexport strlen
    -- define exciting new operators
    alias strlen is work.strkern.strlen [string return natural];
end package stdstring;

use work.stdstring.all;
entity foo is
end entity;

architecture fum of foo is
begin
    assert false 
        report "strlen of ""abcde"" is " & integer'image(strlen("abcde"))
        severity NOTE;
end architecture;

我们可以演示如何在包中使用别名,以提供在另一个包中找到的函数声明的可见性。

代码语言:javascript
复制
ghdl -r foo
std_flub_up.vhdl:25:5:@0ms:(assertion note): strlen of "abcde" is 5

问题代码片段没有演示任何“令人兴奋的新运算符”,其中运算符特定于VHDL中的预定义运算符。请参阅IEEE标准1076-2008 9.2运算符。

使用别名使名称可见的方法如6.6.3非对象别名所示。请注意,子程序的别名需要签名。

有些读者可能会好奇,为什么在上面的MCVe别名中可以看到所选的名称后缀strlen。请参见12.3可见性:

可见性是通过选择或直接实现的。在定义如下的位置,可通过选择来查看声明:

a)对于库中包含的主单元:在所选名称中的后缀的位置,其前缀表示库。

..。

f)对于在包声明中给出的声明,而不是在定义未实例化的包的包声明中:在其前缀表示包的选定名称中的后缀的位置。

...

基本上,选定的名称(work.strkern.strlen)后缀(strlen)声明出现在由前缀定义的单独名称空间中,该名称空间将指定一个主要单元(这里是库strkern中的package work)。通过规则a使包声明可见。通过规则f使后缀可见。通过隐式库声明使库work可见(请参见13.2设计库)。

票数 3
EN

Stack Overflow用户

发布于 2020-11-25 23:55:13

不能将一个包中的任何内容重新导出到另一个包中。唯一的选择是同时使用strkern包和stdstring包。

代码语言:javascript
复制
use work.strkern.all;
use work.stdstring.all;

我建议不要创建虚拟实现,因为如果用户同时包含两个包,重复的函数签名将导致两者都不可见,因为编译器将不知道使用哪一个。用户必须明确说明要使用哪个函数:

代码语言:javascript
复制
work.strkern.strlen("Hello world");
work.stdstring.strlen("Hello world");

您可以为第一个包中的函数创建别名,但它们不能与原始函数同名:

代码语言:javascript
复制
alias str_len is strlen[string];

也许您想研究一下VHDL2008中的上下文子句。它们允许您在单个上下文中使用多个库和包,并且可以包含在其他地方以包括上下文中的所有子句。这里唯一的问题是你不能使用work,因为work只意味着“当前工作库”。如果要将上下文包含在另一个库中,则工作参考现在是不正确的。

代码语言:javascript
复制
context my_string_packages is
  library my_string_lib;
  use my_string_lib.strkern.all;
  use my_string_lib.stdstring.all;
end context my_string_packages;


library my_string_lib;
context my_string_lib.my_string_packages;
票数 1
EN

Stack Overflow用户

发布于 2020-11-26 17:39:34

包strdemo是strlen,strncpy的别名

代码语言:javascript
复制
package strdemo is
alias strlen  is work.strkern.strlen[string return natural];
alias strncpy is work.strkern.strncpy [string, string, integer, natural, natural, boolean];

function  "+"(a:string;         b:string)            return string;
function  "-"(a:string;         b:string)            return boolean;
function  "*"(a:integer;        b:character)         return string;
function  "*"(a:boolean;        b:string)            return string;
end package strdemo;

下面是strkern的完整清单

代码语言:javascript
复制
package strkern is
constant STRING_EOF : character := nul; -- \0 string termination from c

-- We can't assign strings but can easily assign string_segments to variables
-- Making a record instead of array because a record has no operators defined for it.
-- An array already has the & operator.

type string_segment is record
    start, stop: natural;
end record string_segment;    

-- We have 3 kinds of string: string, cstring, vstring. All export functions return vstring
-- There is no functionality difference between the 3, just implementation.

-- All functions accept string and return vstring. They can accept any string type but will
-- always return a vstring. 

subtype cstring is string; -- null terminated c    strlen <= 'length   'left =  1
subtype vstring is string; -- vhdl string          strlen =  'length   'left >= 1

function  strlen(s: string) return natural;
function  safeseg(s: string; ss: string_segment := (0, 0); doreport: boolean := false) return vstring;
procedure strncpy(dest: out cstring; src: string; n: integer := -2; at: natural := 1; from: natural := 1; doreport: boolean := false);
end package strkern;


package body strkern is
-- Error messages
constant safeseg_left:  string := "right operand: ";
constant safeseg_right: string := " overflows strlen: ";

-- Borrow integer whenelse() from stdlib
function whenelse(a: boolean; b, c: integer) return integer is begin
    if a then return b; else return c;
    end if;
end function whenelse;

function ii(i: integer) return vstring is begin 
    return integer'image(i); 
end function ii;

-- These 4 are the only functions/procedures that use & = or segment/index strings

-- strlen is fundamental. It gives the correct answer on any type of string  
function strlen(s: string) return natural is
    variable i: natural := s'left;
begin
    while i < s'right and s(i) /= STRING_EOF loop
        i := i+1;
    end loop;
    
    if s'length = 0 then
        return 0;
    elsif s(i) = STRING_EOF then
        return i-s'left;
    else
        return i+1-s'left;
    end if;
end function strlen;


-- safely segment a string. if a=0 convert a cstring to vhdl string
-- otherwise use strlen and 'left to return correct segment string.

function safeseg(s: string; ss: string_segment := (0, 0); doreport: boolean := false) return vstring is
    constant len: natural := strlen(s); -- strlen is an expensive function with long strings

-- This is the reason for stdstring. Debug reports get very verbose.
    impure function dump return vstring is begin
        return " safeseg(s, (" & ii(ss.start) & ", " & ii(ss.stop) & ")) s'left=" & ii(s'left) & " strlen(s)=" & ii(len);
    end function dump;
begin
    if doreport then -- debug. invokers can switch on doreport
        report dump;
    end if;
    
    if ss.start = 0 then -- if ss.start=0 return the entire string as defined by strlen()
        if len=0 then -- cannot use whenelse here 
            return "";
        else
            return s(s'left to s'left + len-1);
        end if;
    else 
        assert ss.stop <= len report safeseg_left & natural'image(ss.stop) & safeseg_right & dump;
        return s(s'left + ss.start-1 to s'left + whenelse(ss.stop=0, s'length, ss.stop) -1);
    end if;
end function safeseg;


-- The only way to assign strings
-- strncpy(dest, src) is effectively strcpy(dest, src) from C
-- It will non fail assert on overflow followed by an array out of bounds error
procedure strncpy(dest: out cstring; src: string; n: integer := -2; at: natural := 1; from: natural := 1; doreport: boolean := false) is
    constant srclen:    natural := strlen(src);
    constant destspace: integer := dest'length + 1 - at;
    variable copylen:   integer := srclen + 1 - from;

    impure function dump return vstring is begin
        return " strncpy(str(" & ii(dest'length) & "), str(" & ii(srclen) & "), " & ii(n) & ", " & ii(at) & ", " & ii(from) & ")"; 
    end function dump;
begin
    if doreport then
        report dump;
    end if;
    
    if n >= 0 and copylen > n then
        copylen := n;
    end if;
    
    if n = -1 and copylen > destspace then
        copylen := destspace;
    end if;
    
    assert copylen <= destspace report "overrun" & dump;
    
    if copylen > 0 then
        dest(at to at + copylen - 1) := src(from to from + copylen - 1);
    end if;
    if copylen < destspace then
        dest(at + copylen) := STRING_EOF;
    end if;
end procedure strncpy;
end package body strkern;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65006385

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档