第7章 函数(function)与过程(procedure)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在 上 面 的 例 子 中 ,我 们 用 了 两 个 语 句 来 做 func tion的 调 用 ,先 是 声 明 了 一 个 内部信号bitc,并 将 信 号 a与 信 号 b做 逻 辑 上 and的 结 果 指 定 给 信 号 bitc。接 着 再 调 用 function bit2std,将 信 号 bitc转 换 成 std_logic的 数 据 类 型 并 指 定 给 信 号 c。这样的写法并没有错,不过你可以再精简一点,就像下面的写法:
library ieee; use ieee.std_logic_1164.all;
entity V7_1 is port(a,b : in bit; c : out std_logic);
end V7_1;
architecture a of V7_1 is
function bit2std(Inb : bit ) return std_logic is
constant NAS: signed ( 0 downto 1) := (others => ‘0’); 这是一个非常特殊的常数,其数据类型为signed,但注意其范围却是(0
downto 1),这就有些令人搞不清楚了。Downto的用法不是大的数值在前,小的 数值在后吗?为什么会有( 0 downto 1)呢?事实上真的没有,所以在此声明前特 别加了一段批注为null range array constants,这就符合在检查arg的长 度时,若其长度小于1要返回nas了。
variable MaxValue : integer begin
if Ina > Inb then MaxValue := Ina;
else MaxValue := Inb;
End if; return MaxValue; end max; 上 面 的 例 子 是 一 个 比 较 两 个 输 入 值 , 并 返 回 其 中 较 大 值 的 function。在 function中 声 明 了 一 个 内 部 参 数 MaxValue,比 较 时 若 Ina大 于 Inb,会 将 信 号 Ina 的 值 指 定 给 MaxValue , 否 则 会 将 信 号 Inb 的 值 指 定 给 MaxValue 。 最 后 再 将 MaxValue的值当做返回值输出。 我们可以将上面的例子稍做修改,描述方式看起来会更简单。
Fun ction与 proced ure 之 间 的 差 异 在 于 :funct ion的 返 回 值 永 远 只 有 一 个 ,而 procedure的 返 回 值 却 可 以 不 只 一 个 。 Function 所 有 的 参 数 都 是 input 信 号 , 而 procedure的参数却可以是input、output,甚至inout。Function的返回值置于 参数声明之外,而procedure的返回值是放在参数声明之内的。图7-1所示即为上 面所述的差异。
c <= bit2std (a and b ); 因为a and b之后仍是一个数据类型为bit的信号,只不过少了一道手续罢了。 然而在看完7-1节中的function SHIFT_LEFT后,不知你是否会有个疑问,那 就是“是不是有一个function其名称为std_logic_vector或signed呢?”不然为 什 么 用 std_logic_vector(a)就 能 将 原 先 不 是 std_logic_vector的 信 号 a转 变 成 数 据 类 型 为 std_logic_vector呢 ? 答 案 是 否 定 呢 。那 之 前 所 说 的 ”VHD L是 一 种 数 据 类型检查非常严格的语言”不就有些矛盾了吗?事实上并没有,我们先来看看下 面的程序: library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all;
在看完判断arg长度的if语句之后,后面接着就是一个返回值的语句: return signed (XSLL (std_logic_vector(arg) , count )); 由 于 在 之 前 就 已 经 声 明 了 这 个 Function返 回 值 的 数 据 类 型 是 signed,因 此 我们要看看XSLL这个Function的返回值是什么,先看看它的声明。 function XSLL (arg: std_logic_vector; count: natural)
return std_logic_vector
不 管 这 个 function 的 内 容 是 什 么 , 其 返 回 值 就 已 经 不 是 signed , 而 是 std_logic_vector了。为了让其返回值由std_logic_vector变成signed,需要将 此function以括号括起来,再在其前面加上signed,这么一来就能将原先数据类 型为std_logic_vector的输出编程signed了。另外function XSLL的第一个参数 其 数 据 类 型 为 std_logic_vector, 而 SHIFT_LEFT 的 第 一 个 参 数 其 数 据 类 型 为 signed , 可 使 用 相 同 的 方 法 , 在 function XSLL 的 第 一 个 参 数 前 加 上 std_logic_vector,将其数据类型由signed转成std_logic_vector。
第7章 函数(Function)与过程(Procedure)
Function与procedure就是一般所说的子程序(subprogram),它们可以取代 程序现的相同部分,使用子程序能使设计看起来能更结构化。当然你也可以在设 计中完全不使用任何的子程序,不过如果使用起来可以使程序更易懂,更容易维 护,这样子程序的使用就有其必要性了。
还 有 一 点 就 是 在 子 程 序 中 所 有 的 语 句 都 是 像 在 process中 的 sequential logic, 所 以 在 第 6章 中 所 使 用 到 的 语 法 都 能 在 子 程 序 中 使 用 。 现 在 让 我 们 看 看子程序的特性。
7-1 Function 的声明及使用
bit的参数。当参数送入function之后,首先会判断参数的值是逻辑’0’还是’1’, 若 其 值 为 逻 辑 ’ 0’ ,则 将 数 据 类 型 为 std_logic的 逻 辑 ’ 0’ 指 定 给 返 回 值 ,否 则 将 数 据类型为std_logic的逻辑’1’指定给返回值。这样的解释似乎很可笑,难道数据 类 型 为 std_logic的 逻 辑 ’1’与 数 据 类 型 为 bit的 逻 辑 ’1’有 什 么 不 同 吗 ?外 表 上 Leabharlann Baidu 然是没有,不过在严格的数据类型检查之下就得如此。
声明: function SHIFT_LEFT( arg : signed; count :natural )
return signed; 内容: function SHIFT_LEFT ( arg : signed; count : natural )
return signed is begin
if (arg’length < 1) then return nas;
Function所 有 的 参 数 都 是 input信 号 ,惟 一 的 输 出 值 就 是 此 function的 处 理 结果。Function的语法如下:
语法: function Function_Name(parameters:parameters ‘type;…)return
return_type is function 声明区; begin Function 结构区; end Function_Name; 实例: function max( Ina: integer; Inb: integer) return integer is
在看完function的声明及内容的描述,相信要如何写一个function已不是 难事,至于function该怎么调用呢?非常简单,只要看看以下例子就明白了。
O <= max (a, b); 这是延续前面求最大值的例子,只要将输入信号放在参数中,再将 function的返回值指定给输出信号就成了。
7-2 类型转换的 Function
VHDL是一种数据类型检查非常严格的语言,比如说bit的数据类型包含’0’ 与’1’两种逻辑状态,而std_logic的数据类型包含了’0’与’1’及其他七种逻辑状 态,若是一个设计中有bit的数据类型及std_logic的数据类型如下:
signal a, b :bit; signal c, d :std_logic; 那你能做以下方式的指定吗? a <= c and d; 答案是否定的。也许你会认为是因为信号c和信号d的范围比较宽,信号a 的范围比较窄,那么反过来表示: C <= a and b; 总该可以了吧!结果答案仍是否定的。为什么呢?信号c的数据类型是 std_logic,总共有九种不同的逻辑状态。信号a和信号b的数据类型是bit,再怎 么样都不会超过std_logic的九种不同的逻辑状态啊!为什么答案还是否定的呢? 问题就在于这一节开始就提到的,VHDL是一种数据类型检查非常严格的语言,只 要是数据类型不同,即使是范围再宽也不能做指定,惟一的办法是将数据类型转 换成一样的,这便是function的功能之一。我们可以看看下面的例子:
function max ( Ina : integer ; Inb : integer ) return integer is begin
if Ina > Inb then return Ina;
else return Inb;
end if; end max;
Function可 以 在 你 的 设 计 中 声 明 , 或 是 在 package中 声 明 。 当 设 计 者 将 function声 明 在 设 计 中 时 ,要 讲 function放 置 在 architecture与 begin之 间 ,声 明完function后直接将其内容的陈述写在后面,如上面所示的例子。另外一种 是 将 function声 明 在 package中 ,包 含 function的 输 入 参 数 及 返 回 值 的 类 型 ,而 其function的内 容 则放 在package body中。这 一点 在 介绍 package时已经 提 过了 。 以下的例子是在IEEE Std.1076.3中,numeric_std package里function的声明 及package body中function的内容。
end if; return signed ( XSLL(std_logic_vector(arg),count)); end SHIFT_LEFT;
这 是 一 个 将 输 入 参 数 移 位 几 个 bit的 function,它 有 两 个 参 数 ,一 个 是 要 被 shift的 数 值 arg, 其 数 据 类 型 为 signed。 一 个 是 要 shift几 个 bit的 count, 其 数 据 类 型 为 natural。 Function一 开 始 会 检 查 arg的 长 度 , 若 是 长 度 小 于 1, 表 示其根本不存在,所以返回值是nas。Nas是在numeric_std的package body 内声明的一个常数,其内容为:
begin if Inb = '0' then return '0'; else return '1'; end if;
end function;
signal bitc : bit;
begin
bitc <= a and b; c <= bit2std(bitc);
end a; 在architecture之后声明了一个function bit2std,其只有一个数据类型为
library ieee; use ieee.std_logic_1164.all;
entity V7_1 is port(a,b : in bit; c : out std_logic);
end V7_1;
architecture a of V7_1 is
function bit2std(Inb : bit ) return std_logic is
constant NAS: signed ( 0 downto 1) := (others => ‘0’); 这是一个非常特殊的常数,其数据类型为signed,但注意其范围却是(0
downto 1),这就有些令人搞不清楚了。Downto的用法不是大的数值在前,小的 数值在后吗?为什么会有( 0 downto 1)呢?事实上真的没有,所以在此声明前特 别加了一段批注为null range array constants,这就符合在检查arg的长 度时,若其长度小于1要返回nas了。
variable MaxValue : integer begin
if Ina > Inb then MaxValue := Ina;
else MaxValue := Inb;
End if; return MaxValue; end max; 上 面 的 例 子 是 一 个 比 较 两 个 输 入 值 , 并 返 回 其 中 较 大 值 的 function。在 function中 声 明 了 一 个 内 部 参 数 MaxValue,比 较 时 若 Ina大 于 Inb,会 将 信 号 Ina 的 值 指 定 给 MaxValue , 否 则 会 将 信 号 Inb 的 值 指 定 给 MaxValue 。 最 后 再 将 MaxValue的值当做返回值输出。 我们可以将上面的例子稍做修改,描述方式看起来会更简单。
Fun ction与 proced ure 之 间 的 差 异 在 于 :funct ion的 返 回 值 永 远 只 有 一 个 ,而 procedure的 返 回 值 却 可 以 不 只 一 个 。 Function 所 有 的 参 数 都 是 input 信 号 , 而 procedure的参数却可以是input、output,甚至inout。Function的返回值置于 参数声明之外,而procedure的返回值是放在参数声明之内的。图7-1所示即为上 面所述的差异。
c <= bit2std (a and b ); 因为a and b之后仍是一个数据类型为bit的信号,只不过少了一道手续罢了。 然而在看完7-1节中的function SHIFT_LEFT后,不知你是否会有个疑问,那 就是“是不是有一个function其名称为std_logic_vector或signed呢?”不然为 什 么 用 std_logic_vector(a)就 能 将 原 先 不 是 std_logic_vector的 信 号 a转 变 成 数 据 类 型 为 std_logic_vector呢 ? 答 案 是 否 定 呢 。那 之 前 所 说 的 ”VHD L是 一 种 数 据 类型检查非常严格的语言”不就有些矛盾了吗?事实上并没有,我们先来看看下 面的程序: library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.numeric_std.all;
在看完判断arg长度的if语句之后,后面接着就是一个返回值的语句: return signed (XSLL (std_logic_vector(arg) , count )); 由 于 在 之 前 就 已 经 声 明 了 这 个 Function返 回 值 的 数 据 类 型 是 signed,因 此 我们要看看XSLL这个Function的返回值是什么,先看看它的声明。 function XSLL (arg: std_logic_vector; count: natural)
return std_logic_vector
不 管 这 个 function 的 内 容 是 什 么 , 其 返 回 值 就 已 经 不 是 signed , 而 是 std_logic_vector了。为了让其返回值由std_logic_vector变成signed,需要将 此function以括号括起来,再在其前面加上signed,这么一来就能将原先数据类 型为std_logic_vector的输出编程signed了。另外function XSLL的第一个参数 其 数 据 类 型 为 std_logic_vector, 而 SHIFT_LEFT 的 第 一 个 参 数 其 数 据 类 型 为 signed , 可 使 用 相 同 的 方 法 , 在 function XSLL 的 第 一 个 参 数 前 加 上 std_logic_vector,将其数据类型由signed转成std_logic_vector。
第7章 函数(Function)与过程(Procedure)
Function与procedure就是一般所说的子程序(subprogram),它们可以取代 程序现的相同部分,使用子程序能使设计看起来能更结构化。当然你也可以在设 计中完全不使用任何的子程序,不过如果使用起来可以使程序更易懂,更容易维 护,这样子程序的使用就有其必要性了。
还 有 一 点 就 是 在 子 程 序 中 所 有 的 语 句 都 是 像 在 process中 的 sequential logic, 所 以 在 第 6章 中 所 使 用 到 的 语 法 都 能 在 子 程 序 中 使 用 。 现 在 让 我 们 看 看子程序的特性。
7-1 Function 的声明及使用
bit的参数。当参数送入function之后,首先会判断参数的值是逻辑’0’还是’1’, 若 其 值 为 逻 辑 ’ 0’ ,则 将 数 据 类 型 为 std_logic的 逻 辑 ’ 0’ 指 定 给 返 回 值 ,否 则 将 数 据类型为std_logic的逻辑’1’指定给返回值。这样的解释似乎很可笑,难道数据 类 型 为 std_logic的 逻 辑 ’1’与 数 据 类 型 为 bit的 逻 辑 ’1’有 什 么 不 同 吗 ?外 表 上 Leabharlann Baidu 然是没有,不过在严格的数据类型检查之下就得如此。
声明: function SHIFT_LEFT( arg : signed; count :natural )
return signed; 内容: function SHIFT_LEFT ( arg : signed; count : natural )
return signed is begin
if (arg’length < 1) then return nas;
Function所 有 的 参 数 都 是 input信 号 ,惟 一 的 输 出 值 就 是 此 function的 处 理 结果。Function的语法如下:
语法: function Function_Name(parameters:parameters ‘type;…)return
return_type is function 声明区; begin Function 结构区; end Function_Name; 实例: function max( Ina: integer; Inb: integer) return integer is
在看完function的声明及内容的描述,相信要如何写一个function已不是 难事,至于function该怎么调用呢?非常简单,只要看看以下例子就明白了。
O <= max (a, b); 这是延续前面求最大值的例子,只要将输入信号放在参数中,再将 function的返回值指定给输出信号就成了。
7-2 类型转换的 Function
VHDL是一种数据类型检查非常严格的语言,比如说bit的数据类型包含’0’ 与’1’两种逻辑状态,而std_logic的数据类型包含了’0’与’1’及其他七种逻辑状 态,若是一个设计中有bit的数据类型及std_logic的数据类型如下:
signal a, b :bit; signal c, d :std_logic; 那你能做以下方式的指定吗? a <= c and d; 答案是否定的。也许你会认为是因为信号c和信号d的范围比较宽,信号a 的范围比较窄,那么反过来表示: C <= a and b; 总该可以了吧!结果答案仍是否定的。为什么呢?信号c的数据类型是 std_logic,总共有九种不同的逻辑状态。信号a和信号b的数据类型是bit,再怎 么样都不会超过std_logic的九种不同的逻辑状态啊!为什么答案还是否定的呢? 问题就在于这一节开始就提到的,VHDL是一种数据类型检查非常严格的语言,只 要是数据类型不同,即使是范围再宽也不能做指定,惟一的办法是将数据类型转 换成一样的,这便是function的功能之一。我们可以看看下面的例子:
function max ( Ina : integer ; Inb : integer ) return integer is begin
if Ina > Inb then return Ina;
else return Inb;
end if; end max;
Function可 以 在 你 的 设 计 中 声 明 , 或 是 在 package中 声 明 。 当 设 计 者 将 function声 明 在 设 计 中 时 ,要 讲 function放 置 在 architecture与 begin之 间 ,声 明完function后直接将其内容的陈述写在后面,如上面所示的例子。另外一种 是 将 function声 明 在 package中 ,包 含 function的 输 入 参 数 及 返 回 值 的 类 型 ,而 其function的内 容 则放 在package body中。这 一点 在 介绍 package时已经 提 过了 。 以下的例子是在IEEE Std.1076.3中,numeric_std package里function的声明 及package body中function的内容。
end if; return signed ( XSLL(std_logic_vector(arg),count)); end SHIFT_LEFT;
这 是 一 个 将 输 入 参 数 移 位 几 个 bit的 function,它 有 两 个 参 数 ,一 个 是 要 被 shift的 数 值 arg, 其 数 据 类 型 为 signed。 一 个 是 要 shift几 个 bit的 count, 其 数 据 类 型 为 natural。 Function一 开 始 会 检 查 arg的 长 度 , 若 是 长 度 小 于 1, 表 示其根本不存在,所以返回值是nas。Nas是在numeric_std的package body 内声明的一个常数,其内容为:
begin if Inb = '0' then return '0'; else return '1'; end if;
end function;
signal bitc : bit;
begin
bitc <= a and b; c <= bit2std(bitc);
end a; 在architecture之后声明了一个function bit2std,其只有一个数据类型为