vhdl包从另一个包导出它包含的符号
假设我有一个导出函数的strkern包:strlenvhdl包从另一个包导出它包含的符号,vhdl,Vhdl,假设我有一个导出函数的strkern包:strlen package strkern is function strlen(s: string) return natural; end package strkern; 我编写了一个新的包stdstring,它定义了许多令人兴奋的新操作符,但也希望重新导出strlen use work.strkern.all; package stdstring is -- rexport strlen -- define excit
package strkern is
function strlen(s: string) return natural;
end package strkern;
我编写了一个新的包stdstring,它定义了许多令人兴奋的新操作符,但也希望重新导出strlen
use work.strkern.all;
package stdstring is
-- rexport strlen
-- define exciting new operators
end package stdstring
所以如果有一个密码
use work.stdstring.all;
你有斯特伦,还有令人兴奋的新运营商。
如何从子包重新导出函数/类型导入?
缺少一个新名称的虚拟实现,它只调用要导入的实现
function strlen(s: string) return natural is
return strkern.strlen(s);
end function strlen;
您不能从一个包中的另一个包中重新导出任何内容。唯一的选择是同时使用strkern包和stdstring包 使用work.strkern.all; 使用work.stdstring.all; 我建议不要创建虚拟实现,因为如果用户同时包含这两个包,重复的函数签名将导致这两个包都不可见,因为编译器不知道使用哪一个。用户必须明确使用哪个函数: work.strkern.strlenHello世界; work.stdstring.strlenHello世界; 您可以为第一个程序包中的函数创建别名,但它们不能与原始程序包同名:
alias str_len is strlen[string];
也许您想研究VHDL2008中的上下文子句。这些允许您在单个上下文中使用多个库和包,并且可以包含在其他地方以包含上下文中的所有子句。这里唯一的问题是不允许使用work,因为work仅表示当前的工作库。如果要在另一个库中包含上下文,则工作引用现在不正确
上下文我的\u字符串\u包是
库我的字符串库;
使用my_string_lib.strkern.all;
使用my_string_lib.stdstring.all;
结束上下文我的字符串包;
库我的字符串库;
上下文my_string_lib.my_string_包;
您不能从一个包中的另一个包中重新导出任何内容。唯一的选择是同时使用strkern包和stdstring包 使用work.strkern.all; 使用work.stdstring.all; 我建议不要创建虚拟实现,因为如果用户同时包含这两个包,重复的函数签名将导致这两个包都不可见,因为编译器不知道使用哪一个。用户必须明确使用哪个函数: work.strkern.strlenHello世界; work.stdstring.strlenHello世界; 您可以为第一个程序包中的函数创建别名,但它们不能与原始程序包同名:
alias str_len is strlen[string];
也许您想研究VHDL2008中的上下文子句。这些允许您在单个上下文中使用多个库和包,并且可以包含在其他地方以包含上下文中的所有子句。这里唯一的问题是不允许使用work,因为work仅表示当前的工作库。如果要在另一个库中包含上下文,则工作引用现在不正确
上下文我的\u字符串\u包是
库我的字符串库;
使用my_string_lib.strkern.all;
使用my_string_lib.stdstring.all;
结束上下文我的字符串包;
库我的字符串库;
上下文my_string_lib.my_string_包;
通过提供一个最小、完整且可验证的示例: 包裹strkern是 函数strlens:字符串返回自然值; 端包strkern; 包体strkern是 函数strlens:string返回自然值 开始 返回s的长度; 末端功能; 端部封装体; 使用work.strkern.all;-未在本缩短示例中使用 包标准字符串是 -雷克斯波特斯特伦酒店 -定义令人兴奋的新操作符 别名strlen为work.strkern.strlen[string return natural]; 端包标准串; 使用work.stdstring.all; 实体foo是 终端实体; foo is的建筑风格 开始 断言错误 abcde的报告strlen为&integer'imagestrlenabcde 严重性说明; 终端架构; 我们可以演示如何在包中使用别名,以提供在另一个包中找到的函数声明的可见性 ghdl-r foo std_flub_up.vhdl:25:5:@0ms:assertion注:abcde的strlen为5 问题代码片段没有演示任何“令人兴奋的新运算符”,其中运算符特定于VHDL中预定义的运算符。参见IEEE标准1076-2008 9.2运营商 使用别名使名称可见的方法如中所示 6.6.3非对象别名。请注意,子程序的别名需要签名 一些读者可能会好奇,为什么选定的名称后缀strlen在上述MCVe别名中可见。见12.3能见度: 可见性可以通过选择或直接设置。通过选择可在定义如下的位置看到声明: a表示库中包含的主要单元:在选定名称的后缀位置,其前缀表示库。 ... f对于包声明中给出的声明,而不是定义未实例化包的包声明中给出的声明:在前缀表示包的选定名称的后缀位置。 .
基本上,选定名称work.strkern.strlen后缀strlen声明出现在由前缀定义的单独名称空间中,前缀将在库工作中指定主要单元包strkern。程序包声明由规则a显示。后缀由规则f显示。通过隐式库声明使库工作可见,请参见13.2设计库。通过提供一个最小、完整和可验证的示例: 包裹strkern是 函数strlens:字符串返回自然值; 端包strkern; 包体strkern是 函数strlens:string返回自然值 开始 返回s的长度; 末端功能; 端部封装体; 使用work.strkern.all;-未在本缩短示例中使用 包标准字符串是 -雷克斯波特斯特伦酒店 -定义令人兴奋的新操作符 别名strlen为work.strkern.strlen[string return natural]; 端包标准串; 使用work.stdstring.all; 实体foo是 终端实体; foo is的建筑风格 开始 断言错误 abcde的报告strlen为&integer'imagestrlenabcde 严重性说明; 终端架构; 我们可以演示如何在包中使用别名,以提供在另一个包中找到的函数声明的可见性 ghdl-r foo std_flub_up.vhdl:25:5:@0ms:assertion注:abcde的strlen为5 问题代码片段没有演示任何“令人兴奋的新运算符”,其中运算符特定于VHDL中预定义的运算符。参见IEEE标准1076-2008 9.2运营商 使用别名使名称可见的方法如中所示 6.6.3非对象别名。请注意,子程序的别名需要签名 一些读者可能会好奇,为什么选定的名称后缀strlen在上述MCVe别名中可见。见12.3能见度: 可见性可以通过选择或直接设置。通过选择可在定义如下的位置看到声明: a表示库中包含的主要单元:在选定名称的后缀位置,其前缀表示库。 ... f对于包声明中给出的声明,而不是定义未实例化包的包声明中给出的声明:在前缀表示包的选定名称的后缀位置。
基本上,选定名称work.strkern.strlen后缀strlen声明出现在由前缀定义的单独名称空间中,前缀将在库工作中指定主要单元包strkern。程序包声明由规则a显示。后缀由规则f显示。库工作通过隐式库声明可见,请参见13.2设计库。包stremo的别名为strlen、strncpy
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;
这是斯特克恩的完整列表
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;
包strdemo的别名为strlen,strncpy
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;
这是斯特克恩的完整列表
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;
再出口用词不当。来自包的声明通过use子句可见。对于子程序,这些声明在包体中也有一个子程序定义,该定义在过程调用或函数调用期间动态细化和执行。重新导出是一个误称。来自包的声明通过use子句可见。对于子程序,这些声明在包体中也有一个子程序定义,该定义在过程调用或函数调用期间动态细化和执行。下面我的回答表明我的strlen并不像你想象的那么简单,下面可以看到一些令人兴奋的新操作符。它们是由python脚本生成的,所以我只设置了一些脚本,以保持其可读性。谢谢,这对我来说很好。下面我的回答表明我的strlen并不像你想象的那么简单,下面可以看到一些令人兴奋的新操作符。它们是由python脚本生成的,所以我只设置了一些脚本来保持可读性