HDL语言的主要描述语句
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
HDL语言的主要描述语句
5.1 顺序描述语句
5.2 并发描述语句
5.3 GENERARE语句
5.4 属性(attribute)描述
5.1顺序描述语句
●WAIT语句
●断言语句
●信号赋值语句
●变量赋值语句
●IF语句
●CASE语句
●LOOP语句
●NEXT 语句
●过程调用语句
●NULL语句(只占位置的空操作,对信号赋空值,表示关闭)
1.WAIT语句
●WAIT语句用于多种不同的目的,常用于为综合工具指定时钟输入。
另一用途是将进程
的执行延时一段时间或者是为了动态地修改进程的敏感表。
●wait 语句的执行会暂停进程的执行,直到信号敏感表发生变化或某种条件满足为止。
若进程中含信号敏感表,则必须紧跟在procees之后,这等价于该进程最后一个语句为
wait on 语句;此时不能用显式的wait语句。
●4种不同条件:
WAIT ---无限等待
WAIT ON ---敏感信号量变化
WAIT UNTIL ---条件满足
WAIT FOR ---指定的持续时间
●WAIT ON
*格式:
WAIT ON 信号[,信号];
*例1:
WAIT ON a,b;
表示,当a或b变化时,进程便执行后继的语句*例2:
process(a,b)
begin
y<=a and b;
end process;
process
begin
y<=a and b;
wait on a,b;
end process;
以上两进程等价。
●WAIT UNTIL
*表示当检测到某个信号出现之前,进程被终止
*格式:
WAIT UNTIL 条件表达式
*例:
WAIT UNTIL 信号 = 数值;
WAIT UNTIL 信号‘event and 信号 = 数值;
WAIT UNTIL not 信号’stable
and 信号 = 数值;
wait until CLK='1';
wait until CLK'event and CLK='1';
wait until not CLK'stable and CLK='1';
电路综合时,以上3种情况硬件无差别。
*常用语句:
signal CLK: BIT;
……
process
begin
wait until CLK'event and CLK='1';
--等待时钟上沿
end process;
●WAIT FOR
*格式:
WAIT FOR 时间表达式;
表示等待指定时间后再执行后继语句;
*例:
wait for 20 ns;
wait for (a*(b+c));
●多条件WAIT语句
同时使用多个等待条件;
●超时等待
●断言(assert)语句
*在运行过程中报告指定的错误信息,用于仿真和调试;
*基本格式:
assert 条件[report 报告信息][severity 出错级别];
报告信息:字符串;出错级别:note, warning, error, failure。
执行此语句时,如果条件为真,则向下执行,反之,则输出错误信息和出错级别。
*例:
assert( sendB='1')
report"sendB timed out at'1'"
severity ERROR;
3.赋值语句
●将一个值赋给变量或信号。
●格式:目标:= 表达式;--变量赋值
目标 <= 表达式;--信号赋值
目标为接受表达式值的变量或信号(或变量或信号的一部分),表达式必须求值得到与目标相同的数据类型。
●目标的种类:
*简单名:
Δ格式:
标识符 := 表达式 --变量赋值
标识符 <= 表达式 --信号赋值
标识符为信号或变量,对数组类型数组的所有元素都要赋值。
Δ例:
variable A,B: BIT;
signal C: BIT_VECTOR(1 TO 4);
A:='1';
B:='0';
C<="1100";
*有序号名:
Δ格式:
标识符(序号表达式) := 表达式 --变量赋值
标识符(序号表达式)<= 表达式 --信号赋值
标识符为数组类型信号或变量,序号表达式必须计算成该数组序号类型的值且在界内,但无
需是可计算的。
Δ例:
variable A : BIT_VECTOR(1 TO 4);
A(1):='1';
A(2):='1';
A(3):='0';
A(4):='0';
*片(slice):
Δ目标格式:
标识符(序号表达式1 方向序号表达式2)
标识符为数组类型信号或变量,序号表达式必须计算成该数组序号类型的值且在界内,但必须是可计算的;方向必须与数组类型方向一致。
Δ例: variable A ,B: BIT_VECTOR(1 TO 4);
A(1 to 2):="11";
A(3 to 4):="00";
B(1 TO 4):="1100";
* 字段(field):
Δ目标格式:
标识符.字段名
标识符为记录类型信号或变量,字段名是该记录类型中某字段的名称,前面加 "."。
赋值表达式必须必须包含字段类型。
字段可以是任何类型,包括数组、记录或积累类型。
5.信号赋值语句
●信号赋值语句是在VHDL行为建模中的最基本形式,3种类型:
基本型、条件型、选择型(后两种为并发语句)。
●基本型信号赋值语句:
a < =
b ;
为赋值引入非零延时值:
a < =
b after 10 ns ;
●格式:
信号 < = 敏感信号表达式;
例:z<= a not (b nad c);
●注意事项:
信号赋值不立即生效;
若在一个进程中,有若干值赋给一个信号,则最后一个赋值生效;
若干进程赋值给一个信号,电路可能失效;
4.IF语句
●格式:
1)if 条件 then
<顺序处理语句>;
end if;
例1:
-- MAX+plus II VHDL Example
-- Latch Inference
-- Copyright (c) 1994 Altera Corporation
ENTITY latchinf IS
PORT
( enable, data : IN BIT;
q : OUT BIT );
END latchinf;
ARCHITECTURE maxpld OF latchinf IS
BEGIN
latch : PROCESS (enable, data)
BEGIN
IF (enable = '1') THEN
q <= data;
END IF;
END PROCESS latch;
END maxpld;
一信号或变量并不在所有条件下都被驱动,没有"else",当条件不成立时,q保持原来值。
以上为锁存器推断。
例2:
entity ureg is
generic(size:integer :=2);
port(
clk,reset,load: in std_logic;
d : in unsigned(size-1 downto 0);
q: buffer unsigned(size-1 downto 0));
end ureg;
architecture archureg of ureg is
begin
p1:process(reset,clk)
begin
if reset='1' then
q<=(others=>'0');
elsif (clk'event and clk='1')then
if load='1' then
q<=d;
end if;
end if;
end process;
end archureg;
此例描述一个D触发器组。
2)if 条件 then
<顺序处理语句>;
else
<顺序处理语句>;
end if;
例:
if (PHI='1') then
TEMP<=A;
else
TEMP<='0';
end if;
为两输入与门。
为避免锁存器推断,在所有条件下都赋给信号一个值。
3) if 条件 then
<顺序处理语句>;
elsif 条件 then
<顺序处理语句>;
……
elsif 条件 then
<顺序处理语句>;
else
<顺序处理语句>;
end if;
●每个条件必须是布尔表达式,每个"if"分支都包括一个或几个顺序语句;
●每个条件按顺序计算;
●如果没有一个条件满足且"else"语句存在,则执行"else"语句;
●如果没有一个条件满足且"else"语句不存在,则什麽语句也不执行;例:四选一电路
entity mux4 is
port(
input : in std_logic_vector(3 downto 0);
sel : in std_logic_vector(1 downto 0);
y : out in std_logic);
end mux4;
architecture rtl of mux4 is
begin
process(input,sel)
begin
if (sel="00") then
y<=input(0);
elsif (sel="01") then
y<=input(1);
elsif (sel="10") then
y<=input(2);
elsif
y<=input(3);
end if;
end process;
end rtl;
if load='1' then
q<=d;
end if;
end if;
end process;
end archureg;
5.CASE语句
●格式:
CASE 表达式 IS
WHEN 选择=>顺序处理语句;
END CASE;
●选择的计算结果必须是整型、枚举型或枚举型数组;选择为静
态表达式或动态范围,最终的选择是可以是"others",选择不能重叠,若无"others"选择,那末选择必须覆盖表达式的所有可能值。
●4种选择类型:
WHEN 值=>顺序处理语句;
WHEN 值∣值∣……∣值=>顺序处理语句;
WHEN 值 TO值=>顺序处理语句;
WHEN OTHERS=>顺序处理语句;
●例1:
entity MUX4 is
port(A,B,I0,I1,I2,I3: in std_logic;
Q : out std_logic);
end MUX4;
architecture MUX4 of MUX4 is
signal sel:INTEGER range 0 to 3;
begin
process(A,B,I0,I1,I2,I3)
……
CASE sel IS
WHEN 0=> Q<=I0;
WHEN 1=> Q<=I1;
WHEN 2=> Q<=I2;
WHEN 3=> Q<=I3;
END CASE;
end process;
end mux4;
●例2:
signal VALUE : INTEGER range 0 to 15;
signal z1,z2,z3,z4: BIT;
Z1<='0';
Z2<='0';
Z3<='0';
Z4<='0';
case VALUE is
when 0 => z1<='1';
when 1 ∣3 => z2<='1';
when 4 to 7 ∣ 2=> z3<='1';
when others => z4<='1';
end case;
●无效case语句例:
signal VALUE : INTEGER range 0 to 15;
signal OUT_1: BIT;
case VALUE is
end case;
case VALUE is
when 0 => OUT_1<='1';
when 1 => OUT_1<='0';
end case;
case VALUE is
when 0 to 10 => OUT_1<='1';
when 5 to 15 => OUT_1<='0';
end case ;
6. LOOP语句
●重复地执行顺序语句。
2种(for…loop 和while … loop)。
●for…loop
*迭代次数由一个整数范围确定,对该范围内的每一个值,循环执行一次。
当迭代范围中的最后一个值迭代完成后,跳出循环,继续执行循环后的下一个语句。
*格式:
[标号]:for 循环变量 in 范围loop
<顺序处理语句>;
end loop [标号名];
*循环变量不要在别处说明;且只能在循环内读,也不能给循环变量赋值。
*“范围”的表式:
整数表达式 to 整数表达式
整数表达式 downto 整数表达式
其他
*例1:asum: for i in 1 to 9 loop
sum:= i+sum;
end loop asum;
*例2:
signal A,B:BIT_VECTOR(1 to 3);
……
for I in 1 to 3 loop
A(I)<=B(I);
end loop;
……
A(1)<=B(1);
A(2)<=B(2);
A(3)<=B(3);
以上两段等价。
*例3:
variable A,B:BIT_VECTOR(1 to 10);
……
for I in A' range loop
A(I):=not B(I);
end loop;
●while …loop
*只要迭代条件满足,就重复执行封闭的语句。
如果迭代迭代条件求值为“真”,则封闭的语句就执行一次。
然后迭代条件重新求值。
当迭代仍为“真”,循环则重复执行,否则,跳出循环,继续执行循环后的下一个语句。
*格式:
[标号]:while 条件 loop
<顺序处理语句>;
end loop [标号名];
条件为布尔表达式。
*例: i:=1;
sum:=0;
sbcd: while ( i < 10) loop
sum:= i+sum;
i:=i +1;
end loop sbcd;
7.NEXT语句
●停止本次迭代,转入下一次迭代。
●格式:
next [标号] [when 条件];
[标号]表明下一次迭代的起始位置;若既无[标号],也无[when 条件],则执行到该语句就立即跳出本次循环,再从loop的起始位置进行下次迭代。
●例:
signal A,B,COPY_ENABLE: BIT_VECTOR(1 to 8);
……
A<="00000000";
……
for I in 1 to 8 loop
next when COPY_ENABLE(I)='0';
A(I)<=B(I);
end loop;
●嵌套循环中的next语句
signal X,Y: BIT_VECTOR(0 to 7);
A_LOOP: for I in X' range loop
……
B_LOOP: for J in Y' range loop
……
next A_LOOP when I = J ;
……
end loop B_LOOP;
……
end loop A_LOOP;
当条件满足时,从循环B中跳出,到从外循环A开始迭代。
8. EXIT语句
●用于循环体内部,有条件或无条件地结束当前的迭代和循环。
●格式:
exit [loop标号] [when 条件];
当条件满足时,结束循环,继续后继的语句。
●嵌套循环中的3种形式:
*若无[loop标号]:则执行exit时,程序仅从当前所属的loop循环中跳出。
*若exit后接[loop标号]:则执行exit时,程序跳到说明的标号。
*exit 后接 [when 条件]:则执行exit时,只有当条件“真”时才跳出循环。
●例:
signal A,B: BIT_VECTOR(1 downto 8);
signal A_LESS_THAN_B: boolean;
……
A_LESS_THAN_B<=FALSE;
……
for I in 1 downto 0 loop
if(A(I) ='1' and B(I)='0') then
A_LESS_THAN_B<=FALSE;
exit;
elsif(A(I) ='0' and B(I)='1') then
A_LESS_THAN_B<=TRUE;
exit;
else
null;
end if;
end loop;
●exit的 next 比较:
两者格式相同,都是跳出循环的剩余语句;但exit是终止循环,而 next是继续下一次循环。
5
5.2 并发描述语句
●进程(process)语句
●并发信号赋值(concurrent signal assignment)语句
在构造体的进程之外使用。
●条件信号赋值(conditional signal assignment)语句
●选择信号赋值(selective signal assignment)语句
●块(block)语句
1.进程(process)语句
●一个结构体中的所有进程并发运行;
●每个进程中的所有语句都顺序执行;
●进程中包含一个显式信号敏感表或wait语句;
●进程之间的通信靠信号来传递。
2.并发信号赋值(concurrent signal assignment)语句
●在构造体的进程之外使用,等价于包含顺序赋值语句的进程;
●并发信号赋值语句在仿真时同时运行。
●格式:
目标 <= 表达式;
目标为接受表达式值的信号。
●例:
architecture behav of a_var is
begin
output<=a(i);
end behav;
等价于进程中的赋值语句。
3.条件信号赋值(conditional signal assignment)语句
●格式:
目标 <= 表达式1 when 条件1 else
表达式2 when 条件2 else
. .
. .
. .
表达式n;
“目标”为目标为接受表达式值的信号;所使用的表达式是“条件”为真的第一个(按顺序);如果没有条件为真,则将最后一个表达式赋给目标;若多个条件为真,则仅第一个有效,如同IF语句的第一个条件为真的分支一样。
●例1:
z<=A when assign_A ='1' else
B when assign_B ='1' else
C;
与此等价的IF语句:
process(A,ssign_A,B,assign_B,C)
begin
if asign_A ='1' then
Z<=A;
elsif asign_B ='1' then
Z<=B;
else
Z<=C;
end if;
end process;
●例2:四选一电路
entity mux4 is
port(i0,i1,12,13,a,b: in std_logic;
q: out std_logic);
end mux4;
architecture rtl of mux4 is
siganl sel:std_logic_vector(1 downto 0);
begin
sel<=b & a;
q<=i0 when sel="00" else
i1 when sel="01" else
i2 when sel="10" else
i3 when sel="11" else
'X';
end rtl;
●与IF语句的区别:
*IF只能在进程内使用,而条件赋值语句在进程外使用;
*IF语句可以没有else,而条件赋值语句一定要有else;
*IF语句可以嵌套,而条件赋值语句不能进行嵌套;
*IF语句可以生成锁存电路,条件赋值语句不能生成锁存电路。
4.选择信号赋值(selective signal assignment)语句
●格式:
with 选择表达式 select
目标 <= 表达式1 when 条件1
表达式2 when 条件2
. .
. .
. .
表达式n when 条件n;
“目标”为目标为接受表达式值的信号;包括选择表达式值的第一个条件所对应的表达式的值赋给目标;每个选择为静态表达式或静态范围;选择表达式中的每一个值都必须由一个选择所覆盖;最后的选择可以是others。
●约束:各条件不得重叠;若无others,则选择表达式的所有可能值都必须被条件集合
所覆盖。
●例:
siganl A,B,C,D,Z:BIT
signal CONTROL:bit_vector(1 downto 0);
……
with CONTROL select
Z<= A when "00",
B when "01",
C when "10",
D when "11" ,
'X'when others;
等价的case语句:
process(CONTROL,A,B,C,D)
begin
case CONTROL is
when 0=> Z<=A;
when 1=> Z<=B;
when 2=> Z<=C;
when 3=> Z<=D;
end case;
end process;
5.块(block)语句
●块语句是VHDL中具有的一种划分机制,允许设计者合理分组一个模型的区域,即把类
似的部分由块语句保持在一起。
例如设计CPU,ALU一个块、寄存器堆一块,而移位寄存器是另一个块。
每块表示模块中的一个自包容区域,分别描述局部信号、数据类型和常量等,任何能在结构体说明部分说明的对象都能在块说明部分说明
●block为并发语句,其所包含的语句也是并发语句;
●格式:
标号:block
[块说明语句];
begin
……
[并发处理语句];
end block 标号名;
*块说明语句包括:
USE语句,子程序说明与子程序体,类型说明,子类型说明,常数说明,信号说明,元件说明等。
*块中所说明的目标在该block和所有嵌套于内部的block中都是可见的。
●例1:(嵌套block)
B1:block
signal S: BIT;--block B1中S的说明
begin
S<=A and B;--S来自B1
B2:block
signal S: BIT;--block B2中S的说明
begin
S<=C and D;--S来自B2
B3:block
begin
Z<=S;--S来自B2
end block B3;
end block B2;
Y<=S;--S来自B1
end block B1;
例2:
USE WORK.std_logic_1164.ALL;
PACKAGE bit32 IS
TYPE tw32 IS ARRAY(31 DOWNTO 0) OF std_logic; END bit32;
USE WORK.std_logic_1164.ALL
USE WORK.bit32.ALL;
ENTITY cpu IS
PORT (clk,interrupt :IN std_logic;
addr :OUT tw32; data :INOUT tw32);
END cpu;
ARCHITECTURE cpu_blk OF cpu IS
SIGNAL ibus,dbus : tw32;
BEGIN
ALU :BLOCK
SIGNAL qbus :tw32;
BEGIN
-- alu behavior statements
END BLOCK ALU;
REG8:BLOCK
SIGNAL zbus:tw32;
BEGIN
REG1: BLOCK
SIGNAL qbus:
-- reg1 behavior statements
END BLOCK REG1;
-- nore REG8 statements
END BLOCK REG8;
END cpu_blk;
×××××××××××××
BLK1 :BLOCK
SIGNAL qbus :tw32;
BEGIN
BLK2 :BLOCK
SIGNAL qbus :tw32;
BEGIN
-- blk2 statements
END BLOCK BLK2;
-- blk1 statements
END BLOCK BLK1;
●此例信号qbus在两个块均被描述,特点是一个块含在另一个块之中,会看成块BLK2
被两个称为qbus的信号访问,第一个从BLK2的说明中得到qbus的局部说明,第二个从BLK1的说明部分得到说明,BLK1还是BLK2的父模块,BLK2将只从BLK2的说明部分取qbus,来自BLK1的qbus是被BLK2中同名的说明所跨接,来自BLK1的qbus信号能在BLK2内部见到,只要信号qbus的名字由块名所认定,本例中参考来自BLK1的qbus 信号采用BLK1·qbus。
●例3:
USE WORK.std_logic_1164.ALL
PACKGE math IS
TYPE tw32 IS ARRAY(31 DOWNTO 0) OF std_logic;
FUNCTION tw_add(a,b :tw32) RETURN tw32;
FUNCTION tw_sub(a,b :tw32) RETURN tw32;
END math;
USE WORK.math.ALL;
USE WORK.std_logic_1164.ALL;
ENTITY cpu IS
PORT (clk , interrupt :IN std_logic;
addr : OUT tw32;cont :IN INTEGER;
data : INOUT tw32);
END cpu;
ARCHITECTURE cpu_blk OF cpu IS
SIGNAL ibus,dbus : tw32;
BEGIN
ALU : BLOCK
PORT (abus,bbus :IN tw32;
d_out :OUT tw32;
ctbus : IN INTEGER);
PORT MAP (abus => ibus,
bbus => dbus,
d_out =>data,
ctbus =>cont);
SIGNAL qbus :tw32;
BEGIN
d_out <= tw_add(abus,bbus)
WHEN ctbus = 0 ELSE
tw_sub(abus,bbus)
WHEN ctbus = 1 ELSE
abus;
END BLOCK ALU;
END cpu_blk;
5
5.3 GENERARE语句
●对一个封闭的并发语句集合进行多次复制。
●有2种:for… generate和if… ge nerate
●for… generate(复制数目由离散范围确定)
格式:
标号:for 变量 in 范围generate
<并发处理语句>;
end generate [标号];
*变量(用法类似LOOP语句中的循环变量)不要在别处说明;在循环内为局部量,变量只能在循环内读,也不能给循环变量赋值。
*“范围”只有2种表达式:
整数表达式 to 整数表达式
整数表达式 downto 整数表达式
*例1:
signal A,B :bit_vector(3 downto 0);
signal C :bit_vector(7 downto 0);
signal X :bit;
GEN_LABEL:for I in 3 downto 0 generate
C(2*I+1)<=A(I) nor X;
C(2*I) <=B(I) nor X;
end generate GEN_LABEL;
*例2:
component COMP
port( X: in BIT;
Y: OUT BIT);
end component;
signal A,B:BIT_VECTOR(0 to 7);
GEN: for I in A'range generate
U:COMP port map(X=>A(I),Y=>B(I));
end generate GEN;
●if… generate
*格式:
标号:if 条件generate
<并发处理语句>;
end generate [标号];
*当处理不规则的电路时,用if… generate处理。
*例:
library ieee;
use ieee.std_logic_1164.all;
entity shift is
generic(len:integer);
port(
clk : in std_logic;
a : in std_logic;
b : out std_logic);
end shift;
architecture archshift of shift is
component dff
port(
clk : in std_logic;
d : in std_logic;
q : buffer std_logic);
end component;
signal z:std_logic_vector(1 to len-1);
begin
GEN:for i in 0 to (len-1) generate
G1:if i= 0 generate
dffx: port map(d=>a,clk=>clk,q=>z(i+1));
end generate G1;
G2:if i=(len-1) generate
dffx: port map(d=>z(i),clk=>clk,q=>b);
end generate G2;
G3:if (i/= 0 and i/=(len-1)) generate
dffx: port map(d=>z(i),clk=>clk,q=>z(i+1));
end generate G3;
end generate GEN;
end archshift;
5
5.4 属性(attribute)描述
●用于从块、信号和类型中获取信息,以减小编程复杂度。
●属性的类型:
数值类函数类信号类数据类型类数据范围类
1.数值类属性:
●返回一个简单值。
●一般数据的数值属性(返回类型的边界):
*格式:
客体’属性
*种类:
ΔT'LEFT--得到数据类或子类区间的最左端值;
ΔT'RIGHT--得到数据类或子类区间的最右端值;
ΔT'HIGH--得到数据类或子类区间的高端值;
ΔT'LOW--得到数据类或子类区间的低端值;
T表示客体。
*例1:
type NUMBER is 0 to 9;
i:=number'LEFT;--0
i:=number'RIGHT;--9
i:=number'HIGH;--9
i:=number'LOW;--0
注: i 的数据类型应与赋值的数据类型相同。
type NUMBER is array(9 downto 0) of bit;
*例2:
i:=number'LEFT;--9
i:=number'RIGHT;--0
i:=number'HIGH;--31
i:=number'LOW;--0
*例3:(用于枚举型)(略)
●数组的数值属性
*数组长度的值
*格式:’LENGTH
*例1:type bit4 is array( 0 to 3) f bit;
type bit_string is array( 10 to 20) f bit;
len1:= bit4'length --4
len2:= bit_string'length—11
*例2:(用于枚举型)(略)
●块的数值属性
*两种: 'STRUCTURE 和 'BEHAVIOR,用于BLOCK和结构体*用来验证是结构描述还是行为描述
2.函数类属性
以函数的形式获取有关数据类型、数组、信号的信息
●数据类型属性函数:
*种类:
Δ'POS(x)--得到输入x值的位置序号;
Δ'VAL(x)--得到输入的位置序号x值;;
Δ'SUCC(x)--得到输入x值的下一个值;
Δ'PRED(x)--得到输入x值的前一个值;
Δ LEFTOF(x)--得到邻接输入x值左边的值
Δ RIGHTOF(x)—得到输入x值右边的值
●数组属性函数
*种类:
Δ'LEFT(n)--得到索引号为n的区间左端位置号;
Δ'RIGHT(n)--得到索引号为n区间的右端位置号;
Δ'HIGH(n)--得到索引号为n区间的高端位置号;
Δ'LOW(n)--得到索引号为n区间的低端位置号;
●信号属性函数
*种类:
Δ 'EVENT—事件发生(经常用于确定时钟的边沿)
Δ 'ACTIVE—信号发生改变
Δ 'LAST_EVENT—经历的时间
Δ 'LAST_VALUE—信号最后一次改变以前的值
Δ 'LAST_ACTIVE—前一次改变到现在的时间
3.信号类属性:
s'DELAYED—产生一个延时信号
s'STABLE –说明信号是否发生改变
s'QUIET—与s'STABLE功能类似
s'TRANSACTION—建立一个数据类型为BIT的信号,表示信号的
0、1变化
4.数据类型类(略)
5.数据区间类
●用于有约束数组类型,返回所选择参数的区间
●两种:
a'RANGE[(n)]
a'REVERSE_RANGE[(n)]
5.4 过程和函数
●子程序由函数和过程组成,函数只有输入参数和单一的返回值,而过程有任意多个输
入、输出和双向参数,即过程返回多个变量,而函数则只返回一个变元。
●过程被看作一种语句,而函数通常是表达式的一部分。
过程能单独存在,而函数通常
作为语句的一部分。
●过程和函数都有两种形式:即并行过程和并行函数以及顺序过程和顺序函数。
并行的
过程与函数可在进程语句和另一个子程序的外部;而顺序函数和过程仅存在于进程语句和另一个子程序语句。
●过程在结构体或者进程中按分散语句的形式存在,而函数经常在赋值语句或表达式中
用。
●过程中允许使用等待语句和顺序信号赋值语句,而在函数中不允许。
●函数中形参为变量或信号,而过程中形参为变量、信号或常量。
1.过程
●结构:
procedure 过程名(参数1,参数2,…) is
[定义语句];
begin
[顺序处理语句];
end 过程名;
*参数可以是输入也可以是输出
●过程的调用
*用给定参数执行所指明的过程
*并发调用和顺序调用
*格式:
过程名([名称]=>表达式 {,[名称]=>表达式 });
Δ语句前可加标号;语句中应带有in,out 或inout 参数;
有多个返回值。
Δ表达式称做实参,通常为标识符;名称为与实参相联系的形参。
Δ形参通过位置和名称注释与实参匹配,两种方式可以混合使用,但位置参数必须出现在名称参数之前。
*过程调用的3步骤:
Δ实参的值赋给形参;
Δ过程执行;
Δ形参的值赋给实参。
*例:调用将位矢量转成整数的过程
architecture…
begin
vector_to_int(z,x_flag,q);
…
end…;
将位矢量z转成十进整数q。
x flag为标志位。
(参见p21)
2. 函数
●函数可在构造体的说明域和程序包的说明和包体中说明和定义。
在构造体中说明的函数只对该实体可见,而在程序包中说明的函数,可通过use语句对其设计可见。
故函数通常在包集合中定义。
●函数定义的结构:
function 函数名(参数1,参数2,…)
return 数据类型名 is
[定义语句];
begin
[顺序处理语句];
return 返回变量名
end 函数名;
*参数为输入参数
●在结构体中函数的说明与定义:
……
architecture full_add of full_add is
function majority(a,b,c:bit) return bit is
begin
return((a and b) or (a and c) or (b and c));
end majority;
begin
……
●在程序包中函数的说明与定义:
……
package my_package is
function majority(a,b,c:bit) return bit ;
end my_package;
package body my_package is
function majority(a,b,c:bit) return bit is
begin
return((a and b) or (a and c) or (b and c)); end majority;
end my_package;
●函数的调用
*格式:
函数名([参数名]=>表达式 {,[参数名]=>表达式 });
Δ参数名为可选项,为形参表达式;表达式为其参数提供一个值;Δ形参通过位置和名称注释与表达式匹配。
*例1:
function FUNC(A,B,C: INTEGER) return BIT;
……
FUNC(1,2,3)
FUNC(B=>2,A=>1,C=>7 mod 4)
FUNC(1,2,C=>-3+6)
*例2:
use work.my_package.majority
architecture full_add of full_add is
……
begin
……
carry_out<= majority(a,b,carry_in);
……
end full_add;。