第六章 VHDL中属性的描述及定义语句属性:指设计实体、结构体、数据类型、信号等对象的特定特征。
VHDL的预定义属性分类:
数值类属性;
函数类属性;
信号类属性;
数据类型类属性;
数据区间类属性。
表示一个对象属性的书写格式:
对象’属性名
6.1 数值类属性用于返回有关常用数据类型、数组类型或块的特定值;还可用于返回数组的长度或者数据类型的上下界等。
数值类属性分为三个子类:
数据类型的数值属性;
数组的数值属性;
块的数值属性。
6.1.1 数值类型的数值属性
用来返回一个数据类型或子类型的边界值,此边界值通常是指上下限和左右限
数据类型的数值属性:
( 1)’ left,返回一个数据类型或子类型最左端的值,即类型的左边界;
( 2)’ right,返回一个数据类型或子类型最右端的值,即类型的右边界;
( 3)’ high,返回一个数据类型或子类型的高端值,即类型的上限值;
( 4)’ low,返回一个数据类型或子类型的低端值,即类型的下限值;
如:定义一个数据类型
type number is integer range 0 to 7;
number’left = 0
number’right = 7
number’high = 7
number’low = 0
如,type word is array (15 downto 0) of std_logic;
word’left = 15
word’right = 0
word’high = 15
word’low = 0
数据类型的数值属性并不限定数值的数据类型,适用于任何一种标量类型例:枚举类型定义:
type week is (sunday,monday,tuesday,wednsday,thursay,friday,saturday);
subtype sub_week1 is week range wednsday to friday;
subtype sub_week2 is week range friday downto wednsday;
可得如下关系式:
week’left = sunday
week’right=saturday
week’high= saturday
week’low = sunday
sub_week1’left=wednsday
sub_week1’right=friday
sub_week1’high=friday
sub_week1’low=wednsday
sub_week2’left=friday
sub_week2’right=wednsday
sub_week2’high=friday
sub_week2’low=wednsday
6.1.2 数组的数值属性作用:返回数组类型的长度值
VHDL中预定义的数组的数值属性:
‘length,返回一个限定性数组的长度值,即数组中元素的个数;
如:定义如下几个数组类型:
type word is array (15 downto 0) of std_logic;
type dword is array (31 downto 0) of std_logic;
type matrix is array ( 0 to 7,0 to 5) of std_logic;
可返回如下数值属性:
word’length = 16
dword’length =32
matrix’length(1) = 8
matrix’length(2) = 6
matrix’length = 8
library ieee;
use ieee.std_logic_1164.all;
entity compare is
port(input1:in std_logic_vector(7 downto 0);
input2,in integer;
q,out std_logic);
end compare;
architecture rt1 of compare is
function vector_to_int (a,in std_logic_vector) return integer is
variable result,tmp,integer:=0;
begin
for i ina’low toa’length -1 loop
tmp:=0;
if(a(i)=‘1’) then
tmp:=2 ** (i-a’low);
else
assert( a(i)=‘0’)
report?no conversion?
severity warning;
end if;
result:=result+tmp;
end loop
return (result);
end vector_to_int;
例:
begin
process (input1)
begin
if (vector_to_int(input1)>input2) then
q<=‘1’;
else
q<=‘0’;
end if;
end process;
end rt1;
例:串入 /并出移位寄存器输入端口的数据在时钟边沿的作用下逐级向后移动,达到一定位数后并行输出。
原理图编辑法
S H IF T R E G,
C L R N
C L K
B
A
QD
QC
QA
QF
QH
QG
QE
QB
74164
i n st
V C C
A I N P U T
V C C
B I N P U T
V C C
C L R N I N P U T
V C C
C LK I N P U T
Q [ 0]O U T P U T
Q [ 1]O U T P U T
Q [ 2 ]O U T P U T
Q [ 3]O U T P U T
Q [ 4]O U T P U T
Q [ 5]O U T P U T
Q [ 6]O U T P U T
Q [ 7 ]O U T P U T
V
C
C
A
I
N
P
U
T
V
C
C
B
I
N
P
U
T
V
C
C
C
L
R
N
I
N
P
U
T
G
N
D
C
L
K
I
N
P
U
T
QA
O
U
T
P
U
T
QB
O
U
T
P
U
T
QC
O
U
T
P
U
T
QD
O
U
T
P
U
T
QE
O
U
T
P
U
T
QF
O
U
T
P
U
T
QG
O
U
T
P
U
T
QH
O
U
T
P
U
T
A
N
D
2
2
CLRN
D
PRN
Q
D
F
F
3
CLRN
D
PRN
Q
D
F
F
4
CLRN
D
PRN
Q
D
F
F
5
CLRN
D
PRN
Q
D
F
F
6
CLRN
D
PRN
Q
D
F
F
7
CLRN
D
PRN
Q
D
F
F
8
CLRN
D
PRN
Q
D
F
F
9
CLRN
D
PRN
Q
D
F
F
10
74164
T
I
T
LE
M
a
cr
o
F
u
n
ct
i
o
n
C
O
M
P
A
N
Y
A
L
T
E
R
A
C
O
R
P
O
R
A
T
I
O
N
D
ESI
GN
ER
A
p
p
l
i
ca
t
i
o
n
s
E
n
g
i
n
e
e
r
i
n
g
N
U
M
B
E
R
1
.
0
0
R
E
V
A
D
AT
E
T
u
e
M
a
y
1
8
1
6
:
2
5
:
4
9
1
9
9
9
S
H
E
E
T
1
OF
1
带有同步清零的 5位串入 /并出移位寄存器的电路符号
sipo
clk dout[4…0]
clr
clk –时钟
clr –清零端
dout[4…0] – 数据输出端
din
din-数据输入端
library ieee;
use ieee.std_logic_1164.all;
Use ieee.std_logic_unsigned.all;
entity sipo is
port(clk,din,clr,in std_logic;
dout,out std_logic_vector(4 downto 0));
end sipo;
文本输入法
architecture one of sipo is
signal q,std_logic_vector(5 downto 0);
Begin
process (clk)
begin
if clk’event andclk=‘1’ then
if clr=‘1’ then q<=?000000?;
elsifq(5)=‘0’ then --设置 q(5)为标志位,当 q(5)=0时移位结束
q<=?11110?&din;
else q<=q(4 downto 0)&din;
end if;
end if;
end process;
process(q)
begin
ifq(5)=‘0’ then
dout<=q(4 downto 0);
elsedout<=?ZZZZZ?; --移位过程中输出设置为高阻
end if;
end process;
end one;
例:并入 /串出移位寄存器输入端口为并行输入,而输出的数据在时钟边沿的作用下由输出端口逐个输出带有异步清零的 4位并入 /串出移位寄存器的电路符号
piso
clk dout
clr
clk –时钟
clr –清零端
dout – 数据输出端
din[3…0]
din[3…0] -数据输入端
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity piso is
port(clk,clr,in std_logic;
din,in std_logic_vector(3 downto 0);
dout,out std_logic);
end piso;
文本输入法
architecture one of piso is
signal q,std_logic_vector(3 downto 0); --4位寄存器
signal cnt,std_logic_vector(1 downto 0); --用于控制数据的输出
begin
process (clk) – 4进制计数器
begin
if clk’event andclk=‘1’ then
cnt<=cnt+1;
end if;
end process;
process(clk,clr)
begin
ifclr=‘0’ then q<=?0000?;
elsif clk’event and clk=‘1’ then
if cnt>?00? then q(3 downto 1) <= q(2 downto 0); --移位
elsif cnt=?00?then --加载数据
q<=din;
end if;
end if;
end process;
dout<=q(3);
end one;
6.2 函数类属性指属性通过函数的形式,返回有关数据类型、数组或者信号的相关信息。
分为三个子类:
( 1)数据类型的属性函数;
( 2)数组的属性函数;
( 3)信号的属性函数。
6.2.1 数据类型的属性函数
用来得到有关数据类型的各种相关信息,包括:位置信息、左右邻值及上下值
预定义的数据类型的属性函数:
( 1)’ pos(x):返回数据类型定义中 x值的位置序号如:
type week is (sunday,monday,tuesday,wednsday,thursay,friday,saturday);
week’pos(wednsday)=3
(2)’val(x),返回数据类型定义中位置序号 x处的值
week’val(0)=sunday
(3)’succ(x),返回数据类型定义中 x值的下一个值;
week’succ(sunday)=monday
(4)’predx,返回数据类型定义中 x值的前一个值;
week’pred(thursday)=wednsday
(5)’leftof(x),返回数据类型定义中 x值左边的一个值;
week’leftof(thursday)=wednsday
(6)’rightof,返回数据类型定义中 x值右边的一个值。
week’leftof(thursday)=friday
例:时间类型 time的定义
type time is range 0 to +1e18
units
fs;
ps=1000fs;
ns=1000ps;
us=1000ns;
ms=1000us;
sec=1000ms;
min=60sec;
hr=60min;
end units;
time’pos(100fs)=100
time’val(80)=80fs
time’succ(100fs)=101fs
time’predx(100fs)=99fs
time’leftof(100fs)=99fs
time’rightof(100fs)=101fs
6.2.2 数组的属性函数可返回数组的区间
VHDL中预定义的数组的属性函数:
( 1)’ left(n):得到索引号为 n的区间的左端位置号;
( 2)’ right(n):得到索引号为 n的区间的右端位置号;
( 3)’ high(n):得到索引号为 n的区间的高端位置号;
( 4)’ low(n):得到索引号为 n的区间的低端位置号。
6.2.3 信号的属性函数用来得到信号的有关行为信息和功能信息
VHDL中预定义的信号的属性函数:
( 1)信号’ event:该属性函数的返回值为? true? 或? false?;
信号变化 true?
信号不变 false?
(2)信号’ active:返回值为? true? 或? false?;
信号活跃 true?
信号不活跃 false?
( 3)信号’ last_event:返回该信号从前一个事件发生到现在时刻所经历的时间值
( 4)信号’ last_value:返回该信号最近一个事件发生以前的值;
( 5)信号’ last_active:返回该信号从前一次信号活跃到现在时刻所经历的时间值。
例:判断时钟信号的上升沿:
clk’event and clk=‘0’
例:顺序脉冲发生器在系统时钟作用下,输出多路节拍控制脉冲分为:计数型和移存型计数型:把计数器的进位端口作为脉冲输出移存型:通过移位寄存器实现移存型顺序脉冲发生器的电路符号
pulse
clk q0
clr
clk –时钟
clr –清零端
q0,q1,q2 – 数据输出端
文本输入法
q1
q2
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity pulse is
port(clk,clr:in std_logic;
q0,q1,q2:out std_logic);
end pulse;
architecture one of pulse is
signal x,y,std_logic_vector(2 downto 0);
begin
process (clk,clr)
begin
if clk’event andclk=‘1’ then
ifclr=‘0’ theny<=?000?; x<=?001?;
else
y<=x;
x<=x(1 downto 0) & x(2); --移位
end if;
end if;
end process;
q0<=y(0);q1<=y(1);q2<=y(2);
end one;
例:序列信号发生器指在系统时钟的作用下能够循环产生一组或多组序列信号的时序电路如设计产生一组? 10110101? 信号序列信号发生器的电路符号
xl_pulse
clk dout
clr
clk –时钟
clr –清零端
dout– 数据输出端
文本输入法
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity xl_pulse is
port(clk,clr:in std_logic;
dout:out std_logic);
end xl_pulse;
architecture one of xl_pulse is
signal x,std_logic_vector(7 downto 0);
begin
process (clk,clr)
begin
if clk’event andclk=‘1’ then
ifclr=‘1’ thendout<=‘0’;x<=?10110101?;
else
dout<=x(7);
x<=x(6 downto 0) & x(7); --移位
end if;
end if;
end process;
end one;
6.3 信号类属性是根据一个信号去建立一些新的信号,新信号中包含了属性函数所增加的信息
VHDL中预定义的信号类属性:
( 1)信号’ delayed[(t)]:建立一个与所加属性的信号同类型的新信号。
t=0时,该信号为所加属性的信号延迟一个模拟周期后的信号。
如,q <=a’delayed(5ns);
(2)信号’ stable[(t)]:建立一个布尔信号,当所加信号在时间 t内没有事件发生时,返回一个值为? true? 的布尔信号;
(3)信号’ quiet[(t)]:建立一个布尔信号,当所加信号在时间 t内不活跃时,则返会一个值为? true? 的布尔信号;
(4)信号’ transaction,建立一个 bit类型的信号,当所加属性的信号活跃时,
信号将对前面的值进行一次翻转。
( 1)’ delayed[(t)]
两个方面的作用:建立一个所加信号的延迟版本;
用于进行信号保持时间的检查。
VHDL中建立信号延迟的两种方法:
采用信号类属性’ delayed[(t)]实现;
使用延迟赋值语句实现。
区别:延迟赋值语句必须在程序中加以说明。
例,4与门电路
library ieee;
use ieee.std_logic_1164.all;
entity and4 is
port(a,b,c,d:in std_logic;
q:out std_logic);
end and4;
architecture one of and4 is
signal q1,q2,std_logic;
begin
q1<= a and b after 5ns;
q2<= c and d after 6ns;
q<= q1 and q2 after 7ns;
end one;
architecture two of and4 is
signal q3,q4,std_logic;
begin
q3<= a and b;
q4<= c and d;
q<= (q3’ delayed(5ns) and q4’ delayed(6ns)) after 7ns;
end two;
( 2)’ stable[(t)]
可用于描述时钟信号的上升沿或下降沿,如:
if ((not(clk’ stable)) andclk=‘1’
and(clk’last_value=‘0’)) then
q<=d;
qb<= not d;
end if;
6.4 数据类型类属性用于返回一个类型标识; VHDL中预定义的数据类型属性:
数据类型’ base:用于得到所加属性的数据类型或子类型的基本类型例:定义如下数据类型的子类型
type week is (sunday,monday,tuesday,wednsday,thursay,friday,saturday);
subtype sub_week1 is week range wednsday to friday;
subtype sub_week2 is week range monday to Friday;
数据类型类返回值:
week’base’left= sunday;
week’base’right=saturday;
week’base’succ(wednsday)=thursday;
sub_week1’base’left= sunday;
sub_week1’base’right=saturday;
sub_week1’base’succ(wednsday)=thursday;
sub_week2’base’left= sunday;
sub_week2’base’right=saturday;
sub_week2’base’succ(wednsday)=thursday;
可以看出:
week’base,sub_week1’base,sub_week2’base 都将返回枚举类型 week
6.5 数据区间类属性用于返回一个数据的区间范围,仅用于限定性数组。
VHDL中预定义的数据区间类属性:
( 1)数组’ range[(n)]:得到索引号为 n的区间范围;
( 2)数组’ reverse_range[(n)]:得到索引号为 n的区间的逆序范围。
n的缺省值为 1,即一维区间
library ieee;
use ieee.std_logic_1164.all;
entity compare is
port(input1:in std_logic_vector(7 downto 0);
input2,in integer;
q,out std_logic);
end compare;
architecture rt1 of compare is
function vector_to_int (a,in std_logic_vector) return integer is
variable result,tmp,integer:=0;
begin
for i in range loop --a’low toa’length -1
tmp:=0;
if(a(i)=‘1’) then
tmp:=2 ** (i-a’low);
else
assert( a(i)=‘0’)
report?no conversion?
severity warning;
end if;
result:=result+tmp;
end loop
return (result);
end vector_to_int;
begin
process (input1)
begin
if (vector_to_int(input1)>input2) then
q<=‘1’;
else
q<=‘0’;
end if;
end process;
end rt1;
6.6 用户自定义的属性基本书写格式:
attribute <属性名 >:<数据子类型名 >;
attribute <属性名 > of <目标名 >:<目标集合 > is <表达式 >;
如,ATTRIBUTE logic_type_encoding,string ;
如,ieee.std_logic_1164中定义的 and函数
FUNCTION "and" ( l,std_ulogic; r,std_ulogic ) RETURN UX01 IS
VARIABLE result,UX01 ;
ATTRIBUTE synthesis_return OF result:VARIABLE IS "AND" ;
BEGIN
result,= (and_table(l,r));
RETURN result ;
END "and";