第7章 函数(function)与过程(procedure)
- 格式:pdf
- 大小:159.49 KB
- 文档页数:12
Fun ction与 proced ure 之 间 的 差 异 在 于 :funct ion的 返 回 值 永 远 只 有 一 个 ,而 procedure的 返 回 值 却 可 以 不 只 一 个 。 Function 所 有 的 参 数 都 是 input 信 号 , 而 procedure的参数却可以是input、output,甚至inout。Function的返回值置于 参数声明之外,而procedure的返回值是放在参数声明之内的。图7-1所示即为上 面所述的差异。
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
还 有 一 点 就 是 在 子 程 序 中 所 有 的 语 句 都 是 像 在 process中 的 sequential logic, 所 以 在 第 6章 中 所 使 用 到 的 语 法 都 能 在 子 程 序 中 使 用 。 现 在 让 我 们 看 看子程序的特性。
7-1 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 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的声明及内容的描述,相信要如何写一个function已不是 难事,至于function该怎么调用呢?非常简单,只要看看以下例子就明白了。
O <= max (a, b); 这是延续前面求最大值的例子,只要将输入信号放在参数中,再将 function的返回值指定给输出信号就成了。
7-2 类型转换的 Function
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
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的值当做返回值输出。 我们可以将上面的例子稍做修改,描述方式看起来会更简单。
constant NAS: signed ( 0 downto 1) := (others => ‘0’); 这是一个非常特殊的常数,其数据类型为signed,但注意其范围却是(0
downto 1),这就有些令人搞不清楚了。Downto的用法不是大的数值在前,小的 数值在后吗?为什么会有( 0 downto 1)呢?事实上真的没有,所以在此声明前特 别加了一段批注为null range array constants,这就符合在检查arg的长 度时,若其长度小于1要返回nas了。
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。
在 上 面 的 例 子 中 ,我 们 用 了 两 个 语 句 来 做 func tion的 调 用 ,先 是 声 明 了 一 个 内部信号bitc,并 将 信 号 a与 信 号 b做 逻 辑 上 and的 结 果 指 定 给 信 号 bitc。接 着 再 调 用 function bit2std,将 信 号 bitc转 换 成 std_logic的 数 据 类 型 并 指 定 给 信 号 c。这样的写法并没有错,不过你可以再精简一点,就像下面的写法:
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,其只有一个数据类型为
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是 一 种 数 据 类型检查非常严格的语言”不就有些矛盾了吗?事实上并没有,我们先来看看下 面的64.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)
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 内声明的一个常数,其内容为: