第五章 VHDL的库、程序包和配置
5.1 VHDL的库
库主要用来存放已经编译过的实体、结构体、程序包和配置,以便在其它设计中可以随时引用这些信息,从而提高设计人员的工作效率。
要引用库中已编译的设计单元时,必须在每个设计的 VHDL程序的开头说明要引用的库;
库说明语句的书写格式:
library <库名列表 >;
如,library ieee;
library ieee,work,std;
对库进行说明以后,还要说明程序所要使用的是库中哪一个设计单元。
书写格式:
use <库名 >,<程序包名 >.all;
use <库名 >,<程序包名 >.<项目名 >;
项目名:指程序包内某个特定的项目;
5.1.1 库的使用如,library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.std_logic;
库说明语句的作用范围:从一个实体说明开始到它所隶属的结构体、配置为止,或从一个程序包的说明开始到该程序包的定义结束为止。
当一个 VHDL程序出现两个或两个以上的实体或程序包时,作为使用库的说明语句应该在每个实体说明语句和包说明语句前重复书写。
library ieee;
use ieee.std_logic_1164.all;
entity and2 is
……
end and2;
architecture rt1 of and2 is
……
end rt1;
library ieee;
use ieee.std_logic_1164.all;
entity or2 is
……
end or2;
architecture rt1 of or2 is
……
end rt1;
5.1.2 库的分类分为两大类:设计库和资源库设计库:对当前设计实体是永远可见的,在使用时无须说明;
包括,std库,work库资源库:存放常规元件和常规模块的库,在使用时要先进行库说明。
包括,ieee库,面向 ASIC的库,用户自定义的库
1,ieee库
包括,ieee标准的程序包;一些支持工业标准的程序包
( 1) ieee标准的程序包
std_logic_1164; numeric_bit; numeric_std; math_complex; math_real
( 2)支持工业标准的程序包如,synopsys公司的 std_logic_arith,std_logic_signed,std_logic_unsigned
引用 ieee库和程序包的四种书写格式:
( 1)第一种书写格式
library ieee;
use ieee.std_logic_1164.all;
entity and2 is
port(a,b:in std_logic;
c,out std_logic);
end and2;
( 2)第二种书写格式
library ieee;
use ieee.std_logic_1164.std_logic;
entity and2 is
port(a,b:in std_logic;
c,out std_logic);
end and2;
( 3)第三种书写格式
library ieee;
entity and2 is
port(a,b:in ieee.std_logic_1164.std_logic;
c,out ieee.std_logic_1164.std_logic);
end and2;
( 3)第四种书写格式
library ieee;
use ieee.all;
entity and2 is
port(a,b:in std_logic_1164.std_logic;
c,out std_logic_1164.std_logic);
end and2;
2,std库是 VHDL标准库,包含两个程序包,standard和 textio;
standard中定义了,bit,bit_vector,character和 time等数据类型;(使用前无须说明)
textio:包含了对文本文件进行读写操作的过程和函数,使用前需说明。如:
library std;
use std.textio.all;
3,work库用来保存共用的例化元件和模块,是标准模块库,使用时无须进行说明;
4,面向 ASIC的库
5,用户自定义的库例:可变模计数器通过模值控制端改变计数器的模值
(1)无置数端的可变模计数器可变模计数器的电路符号
mchange_1
clk q[6…0]
clr
m[6…0]
clk –时钟
clr –清零端
m[6…0] – 模值输入端
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity mchange_1 is
port(clk,clr:in std_logic;
m,in integer range 0 to 99;
q,buffer integer range 0 to 99);
end mchange_1;
architecture one of mchange_1 is
signal md,integer;
begin
process(clr,clk,m)
begin
md<=m-1;
if clr=‘1’ then q<=‘0’;
elsif clk’event and clk=‘1’ then
if q=md then q<=‘0’;
else q<=q+1;
end if;
end if;
end process;
end one;
(2)有置数端的可变模计数器有置数端的可变模计数器的电路符号
mchange100
clk q[6…0]
clr
m[6…0]
clk –时钟
clr –清零端
m[6…0] – 模值输入端
ldld – 置数端
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity mchange_1 is
port(clk,clr,ld:in std_logic;
m,in integer range 0 to 99;
q,buffer integer range 0 to 99);
end mchange_1;
architecture one of mchange_1 is
signal md,integer;
begin
process(clr,clk,m)
begin
md<=m-1;
if clr=‘1’ then q<=0;
elsif clk’event andclk=‘1’ then
ifld=‘1’ then q<=m;
elsif q=md then q<=0;
else q<=q+1;
end if;
end if;
end process;
end one;
5.2 VHDL的程序包作用:使一组信号定义、数据类型、子程序说明、属性说明及元件说明等对多个设计实体及其相应的结构体都成为可见。
5.2.1 程序包的基本结构由程序包说明和程序包包体两部分组成;
程序包说明:为程序包定义接口,主要用来对信号、常量、数据类型、子程序属性等进行说明;
程序包包体:用来规定程序包的实际功能,它主要由程序包说明部分指定的函数和过程的程序体组成。
程序包说明部分的书写格式:
pakage <程序包名 > is
[数据类型说明 ];
[子程序说明 ];
[常量、延迟常量说明 ];
[信号说明 ];
[元件说明 ];
[文件说明 ];
[别名说明 ];
[属性说明 ];
[属性指定 ];
end [package] [程序包名 ];
与实体说明部分的区别:
实体说明部分:用来指定哪些信号对外可见;
程序包说明部分:用来指定哪些信号、常量、数据类型、子程序、属性等对外可见。
程序包包体部分基本书写格式:
package body <程序包名 > is
[外部子程序体 ];
[内部子程序说明 ];
[内部子程序体 ];
[内部常量说明 ];
[内部数据类型说明 ];
end [package body] [程序包名 ];
例:
package logic is
type three_level_logic is(‘0’,’1’,’Z’);
constant value,three_level_logic:=‘0’;
function invert(input,three_level_logic) return three_level_logic;
end package logic;
package body logic is
function invert(input,three_level_logic)
return three_level_logic is
begin
case input is
when‘0’=> return‘1’;
when‘1’=> return ‘0’;
when‘Z’=> return ‘Z’;
end case;
end invert;
end package body logic;
5.2.2 常见的程序包
1,standard程序包预先在 std程序库中编译,在此程序包中主要定义了:布尔类型,bit类型,
character类型,出错级别,实数类型,整数类型,时间类型,延迟长度子类型,自然数子类型,正整数则类型,string类型,bit_vector子类型,文件打开方式类型和文件打开状态类型在 VHDL程序的开始部分隐含了如下说明:
library std;
use std.standard.all;
2,textio程序包预先在 std程序库中进行了编译,主要定义了与文本文件操作有关的数据类型和子程序。使用前要进行如下说明:
library std;
use std.textio.all;
3,std_logic_1164程序包预先在 ieee库中进行了编译,定义了常用的一些数据类型和函数。定义了:
std_logic类型,std_ulogic_vector类型,std_logic子类型,std_logic_vector类型;
对应于不同数据类型的 and,nand,or,nor,xor,xnor,not函数等在 VHDL程序开始部分要进行如下说明:
library ieee;
use ieee.std_logic_1164.all;
4,numeric_std程序包预先编译在 ieee库中,定义了用于综合的数据类型和算数函数。定义的数据类型包括:
unsigned(位矢量形式的无符号数 )和 signed(位矢量形式的有符号数),
在 VHDL程序开始部分要进行如下说明:
library ieee;
use ieee.numeric_std.all;
5,numeric_bit程序包与 numeric_std程序包基本相同,基本元素类型是 bit类型例:寄存器是一种在某一特定信号的控制下用来存储一组二进制数据的时序逻辑电路
8位寄存器的电路符号
reg8_1
clk q[7…0]
d[7…0]
clk –时钟
oe –三态控制端
q[7…0] – 数据输出端
oe
d[7…0] – 数据输入端
8位寄存器的状态表输入 输出
OE CLK D[7…0] Q[7…0]
0 ↑ 0/1 0/1
↓ ↓ X 保持
1 X X 高阻
采用原理图编辑法
O C T A L D - F F
D1
D2
D3
D4
D6
D5
O E N
D8
D7
C L K
Q2
Q3
Q5
Q4
Q6
Q7
Q8
Q1
74374
i n st
V C C
D [ 0] I N P U T
V C C
D [ 1] I N P U T
V C C
D [ 2] I N P U T
V C C
D [ 3] I N P U T
V C C
D [ 4] I N P U T
V C C
D [ 5] I N P U T
V C C
D [ 6] I N P U T
V C C
D [ 7] I N P U T
V C C
OE 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
采用文本编辑法
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity reg8_1 is
port(d:in std_logic_vector(7 downto 0);
oe,clk,in std_logic;
q:out std_logic_vector(7 downto 0));
end reg8_1;
architecture one of reg8_1 is
begin
process (oe,clk)
begin
if oe=‘0’ then
if clk’event and clk=‘1’ then
q<=d;
end if;
else
q<=?ZZZZZZZZ?;
end if;
end process;
end one;
例:锁存器
8位锁存器的电路符号
latch8_1
clk q[7…0]
d[7…0]
clk –时钟
g – 控制信号输入端
q[7…0] – 数据输出端
g
d[7…0] – 数据输入端
8位锁存器的状态表输入 输出
OE G D[7…0] Q[7…0]
0 1 0/1 0/1
0 0 X 保持
1 X X 高阻
采用原理图编辑法
V C C
D [ 0] I N P U T
V C C
D [ 1] I N P U T
V C C
D [ 2 ] I N P U T
V C C
D [ 3 ] I N P U T
V C C
D [ 4] I N P U T
V C C
D [ 5 ] I N P U T
V C C
D [ 6 ] I N P U T
V C C
D [ 7] I N P U T
V C C
OE I N P U T
V C C
G 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
D L A T C H
D1
D3
D6
D7
D2
G
D4
D5
D8
O E N
Q3
Q6
Q7
Q2
Q8
Q4
Q5
Q1
74373
i n st
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity latch8_1 is
port(d:in std_logic_vector(7 downto 0);
oe,g,in std_logic;
q:out std_logic_vector(7 downto 0));
end latch8_1;
architecture one of latch8_1 is
begin
process (oe,g)
begin
if oe=‘0’ then
ifg=‘1’ then
q<=d;
end if;
else
q<=?ZZZZZZZZ?;
end if;
end process;
end one;
采用文本编辑法
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity latch8_1 is
port(d:in std_logic_vector(7 downto 0);
oe,g,in std_logic;
q:out std_logic_vector(7 downto 0));
end latch8_1;
architecture one of latch8_1 is
signal q_temp,std_logic_vector(7 downto 0);
begin
process (en)
begin
case input is
when‘0’ => q_temp<=d;
when ‘1’=> q_temp<=?ZZZZZZZZ?;
end case;
end process;
q<=q_temp;
end one;
例:移位寄存器使寄存器中存储的二进制数据能够在时钟信号控制下依次左移或者右移移位寄存器的分类:
按移位方向分类,左移、右移、双向移位寄存器;
按工作方式分类:串入 /串出移位寄存器;
串入 /并出移位寄存器;
并入 /串出移位寄存器。
双向移位寄存器(串入 /串出)
串入 /串出双向移位寄存器的电路符号
d_reg
clk dout_r
left_right
clk –时钟
din –数据输入端
dout_r – 右移输出端
din
left_right – 方向控制信号输入端 dout_l
dout_l – 左移输出端
library ieee;
use ieee.std_logic_1164.all;
entity d_reg is
port(clk,din,left_right,in std_logic;
dout_r,dout_l:out std_logic);
end d_reg;
architecture one of d_reg is
signal q_temp,std_logic_vector(7 downto 0);
begin
process (clk)
begin
if clk’event andclk=‘1’ then
ifleft_right = ‘0’ then q_temp(0)<=din;
for i in 1 to 7 loop
q_temp(i)<=q_temp(i-1);
end loop;
else
q_temp(7)<=din;
for i in 1 to 7 loop
q_temp(i-1)<=q_temp(i)
end loop;
end if;
end if;
end process;
dout_r<=q_temp(0); dout_l<=q_temp(7);
end one;
串入 /串出移位寄存器当时钟信号边沿到来时,输入端的数据在时钟边沿的作用下逐级向后移动串入 /串出移位寄存器的电路符号
siso4_1
clk doutclk –时钟
din –数据输入端
dout – 数据输出端
din
( 1)图形编辑法
D触发器的电路符号
d
d
cp
r
s qn
q
S –set 置位端
R – reset 复位端
Q,Qn –输出端
d –信号输入端
cp –时钟信号输入 输出
CP R S D Q Qn
X 0 1 X 0 1
X 1 0 X 1 0
↓ 1 1 X 保持 保持
↑ 1 1 0 0 1
↑ 1 1 1 1 0
D触发器的真值表
V C C
d in I N P U T
V C C
c lk I N P U T
CLRN
D
PRN
Q
D F F
in s t
CLRN
D
PRN
Q
D F F
in s t 1
CLRN
D
PRN
Q
D F F
in s t 2
CLRN
D
PRN
Q
D F F
in s t 3
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
library ieee;
use ieee.std_logic_1164.all;
entity siso4_1 is
port(clk,din,in std_logic;
dout,out std_logic);
end siso4_1;
architecture one of siso4_1 is
signal q_temp,std_logic_vector(3 downto 0);
begin
process (clk)
begin
if clk’event andclk=‘1’ then
q_temp(0)<=din;
for i in 0 to 2 loop
q_temp(i+1)<=q_temp(i);
end loop;
end if;
end process;
dout<=q_temp(3);
end one;
( 2)文本编辑法