3.3.3数据类型的转换转换方法:函数转换法、类型标识符转换法和常量转换法
1、函数转换法即利用一些转换函数进行对象数据类型的转换。
在 std_logic_1164中定义了四个转换函数:
a,to_stdlogicvector(a) 将对象 a由 bit_vector类型转换为 std_logic_vector
b,to_bitvector(a) 将对象 a由 std_logic_vector类型转换为 bit_vector
c,to_stdlogic(a) 将对象 a由 bit类型转换为 std_logic类型
d,to_bit(a) 将对象 a由 std_logic类型转换为 bit类型
★ 在设计 VHDL程序过程中,若要调用程序包中的转换函数,必须在调用前进行程序包使用的说明。
如:要调用 std_logic_unsigned程序包中的转换函数
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
2、类型标识符转换法类型标识符就是类型的名称,适用于标量类型之间的转换,如整数和浮点数,如:
variable a,integer;
variable b,real;
a,=integer(b);
b:=real(a);
§ 3.4 VHDL的运算符四种运算符:逻辑运算符、算数运算符、关系运算符和并置运算符
3.4.1 逻辑运算符运算符 功能
and 与
or 或
nand 与非
nor 或非
xor 异或
xnor 异或非
not 非
VHDL中的逻辑运算符优先级,not的优先级最高,其它 6个逻辑运算符的优先级相同 ;
q <= a and b or not c and d;
应为,q <= (a and b) or (not c and d);
VHDL中左右没有优先级差别。
注意:
使用逻辑运算符时允许在一个表达式中出现两个或两个以上 and运算符而不加括号;
or,xor,nor的规定与 and相同;
不允许一个表达式中出现两个或连个以上 nand和 xnor而不加括号。
例,q<= a and b and c and d;
q<= a or b or c or d;
q<= a xor b xor c xor d;
q<= a nand b and c and d;
3.4.2 算数运算符运算符 功能 运算符 功能
+ 加 + 正号
- 减 - 负号
* 乘 sll 逻辑左移
/ 除 srl 逻辑右移
mod 取模 sla 算数左移
rem 取余 sra 算数右移
** 乘方 rol 逻辑循环左移
abs 取绝对值 ror 逻辑循环右移
VHDL中的算数运算符
sll,srl,sla,sra,rol和 ror为二元运算操作符,只能定义在一维数组上,
其元素必须是 bit和 boolean型。
sll(逻辑左移 )
舍弃 填 0
srl(逻辑右移 )
舍弃填 0
sla(算术左移)
舍弃
srl(算术右移 )
舍弃填 0
rol(逻辑循环左移)
ror(逻辑循环右移)
移位运算符移位规则图
3.4.3 关系运算符运算符 功能
= 相等
/= 不等于
< 小于
> 大于
<= 小于等于
>= 大于等于
VHDL中的关系运算符
3.4.4 并置运算符作用是进行位和位矢量的连接,即将并置运算符右边的内容接在左边的内容之后形成一个新的位矢量。
并置运算符,&
三种情况,(1)将两个位连接起来形成一个位矢量;
(2)将两个位矢量连接起来形成一个新的位矢量;
( 3)将位矢量和位连接起来形成一个新的位矢量。
★ 位连接的不同表示方法:
定义信号:
signal a,b,c,std_logic;
signal q,std_logic_vector(2 downto 0);
(1)直接连接
q <= a & b & c;
(2) 聚合连接
q <=(a,b,c);
也可采用指定位的脚标来进行位的连接,如:
q <= (2=>a,1 =>b,0=>c);
3.4.5 运算符的优先级优先级顺序 运算操作符
** not abs
* / mod rem
+(正号 ) -(负号 )
+(加 ) -(减) &
sll srl sla sra rol ror
= /= < <= > >=
and or nand nor xor xnor
例,BCD-7段显示译码器
BCD码:二进制编码的十进制数。用 4位二进制数来对每个十进制数进行编码。
如,905(十进制) =1001 0000 0101 (BCD)
1、显示器七段字码显示器:七段可以独立控制的发光二极管 (LED)或液晶显示 (LCD)
单元组成的 8字形,可以用于显示十进制数字或其它字符。
分为:共阴极 — 七段二极管的阴极都连接地;
共阳极 — 七段二极管的阳极都连接地。
LED显示的电路条件:
Vcc
a,点亮 LED的条件
a
b,共阴极
b c
a b c
c,共阳极
Vcc
输入 输出数字 A3 A2 A1 A0 Ya Yb Yc Yd Ye Yf Yg 字形
0 0 0 0 0 1 1 1 1 1 1 0 0
1 0 0 0 1 0 1 1 0 0 0 0 1
2 0 0 1 0 1 1 0 1 1 0 1 2
3 0 0 1 1 1 1 1 1 0 0 1 3
4 0 1 0 0 0 1 1 0 0 1 1 4
5 0 1 0 1 1 0 1 1 0 1 1 5
6 0 1 1 0 0 1 0 1 1 1 1 6
7 0 1 1 1 1 1 1 0 0 1 0 7
8 1 0 0 0 1 1 1 1 1 1 1 8
9 1 0 0 1 1 1 1 1 0 1 1 9
10 1 0 1 0 1 1 1 0 1 1 1 A
11 1 0 1 1 0 0 1 1 1 1 1 B
12 1 1 0 0 1 0 0 1 1 1 0 C
13 1 1 0 1 0 1 1 1 1 0 1 D
14 1 1 1 0 1 0 0 1 1 1 1 E
15 1 1 1 1 1 0 0 0 1 1 1 F
BCD-7段显示译码器真值表
library ieee;
use ieee.std_logic_1164.all;
entity bcd_decoder is
port(a:in std_logic_vector(3 downto 0);
y,out std_logic_vector(6 downto 0));
end bcd_decoder;
architecture one of bcd_decoder is
begin
process(a) is
begin
case a is
when?0000? => y<=?1111110?;
when?0001? => y<=?0110000?;
when?0010? => y<=?1101101?;
when?0011? => y<=?1111001?;
when?0100? => y<=?0110011?;
when?0101? => y<=?1011011?;
when?0110? => y<=?1011111?;
when?0111? => y<=?111000?;
when?1000? => y<=?1111111?;
when?1001? => y<=?1111011?;
when?1010? => y<=?1110111?;
when?1011? => y<=?0011111?;
when?1100? => y<=?1001110?;
when?1101? => y<=?0111101?;
when?1110? => y<=?1001111?;
when?1111? => y<=?1000111?;
end case;
end process;
end one;
例:数据选择器功能:实现经过选择,把多个通道的数据传到唯一的公共数据通道上。
数据选择器:实现数据选择功能的逻辑电路
1,4选 1数据选择器输入 输出
A1 A0 Y
0 0 D0
0 1 D1
1 0 D2
1 1 D3
4选 1数据选择器真值表
4选 1数据选择器的电路符号
mux4
d0
d1
d2
d3
g
a[1…0]
y
library ieee;
use ieee.std_logic_1164.all;
entity mux4 is
port(d0,d1,d2,d3:in std_logic;
a,in std_logic_vector(1 downto 0);
g,in std_logic;
y,out std_logic);
end mux4;
architecture one of mux4 is
begin
process(a,g,d0,d1,d2,d3) is
begin
if g=‘0’ then y<=‘0’;
else
case a is
when?00? => y<=d0;
when?01? => y<=d1;
when?10? => y<=d2;
when?11? => y<=d3;
end case;
end process;
end one;
2,8选 1数据选择器输入 输出
g A2 A1 A0 Y
0 X X X 0
1 0 0 0 D0
1 0 0 1 D1
1 0 1 0 D2
1 0 1 1 D3
1 1 0 0 D4
1 1 0 1 D5
1 1 1 0 D6
1 1 1 1 D7
8选 1数据选择器真值表
8选 1数据选择器的电路符号
mux8
d4
d5
d6
d7
g
a[2…0]
yd0
d1
d2
d3
library ieee;
use ieee.std_logic_1164.all;
entity mux8 is
port(a:in std_logic_vector(2 downto 0);
g,in std_logic;
d0,d1,d2,d3,d4,d5,d6,d7,in std_logic;
y,out std_logic);
end mux8;
architecture one of mux8 is
begin
process(a,g,d0,d1,d2,d3,d4,d5,d6,d7) is
begin
if g=‘0’ then y<=0;
else
case a is
when?000? => y<=d0;
when?001? => y<=d1;
when?010? => y<=d2;
when?011? => y<=d3;
when?100? => y<=d4;
when?101? => y<=d5;
when?110? => y<=d6;
when?111? => y<=d7;
end case;
end if;
end process;
end one;
第四章 VHDL的基本描述语句
§ 4.1并行语句
VHDL的基本描述语句分为:并行语句和顺序语句并行语句:语句的执行顺序与语句的书写顺序无关,所有语句都是并发执行的。
顺序语句:语句的执行顺序是按照语句的书写顺序依次执行的。
结构体并行语句 1
并行语句 2
并行语句 3
并行语句在结构体中的关系
VHDL中主要的并行语句:
( 1)进程 (process)语句;
( 2)块( block)语句;
( 3)并行信号赋值语句;
( 4)并行过程调用语句;
( 5)并行断言语句;
( 6)类属 (generic)语句;
( 7)元件例化语句;
( 8)生成( generate)语句,
4.1.1 进程语句
( 1)进程模型进 程 1 进 程 3
进 程 2 进 程 4
结 构 体进程模型
( 2)进程语句的特点
同一结构体中的各进程之间是并发执行的,并且都可使用实体说明和结构体中所定义的信号;而同一进程中的描述语句则是顺序执行的,并且在进程中只能设置顺序语句。
为启动进程,进程的结构中必须包含一个显示的敏感信号表或包含一个 wait
语句,但是在一个进程中不能同时存在敏感信号表和 wait语句。
一个结构体中的各个进程之间可以通过信号或共享变量来进行通信,但任一进程的进程说明部分不允许定义信号和共享变量。
进程语句是 VHDL中重要的建模语句,进程语句不但可以被综合器支持,而且进程的建模方式直接影响仿真和综合的结果。
进程语句综合后对应的硬件结构对进程中所有可读入信号都是敏感的,而在 VHDL
行为仿真中,对应的仿真模型只对敏感的可读入信号敏感。
4.1.2 块 (block)语句
( 1)块语句的嵌套可进行多层嵌套,内层块语句可以使用外层块语句说明的子程序、类型、信号和元件等说明,而外层块语句不可以使用内层块语句中说明的子程序、类型、
信号和元件等说明。
例:描述一个虚拟微处理器的 VHDL程序
library ieee;
use ieee.std_logic_1164.all;
package bit32 is
type tw32 is array (31 downto 0) of std_logic;
end bit32;
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 addr_bus,data_bus,tw32;
begin
ALU,block
signal ad_bus,tw32;
begin
end block ALU;
reg8,block
signal bidir_bus,tw32;
begin
reg1:block
signal ad_bus,tw32;
begin

end block reg1;

end block reg8;

end cpu_blk;
(2)块间信号和参数的传递采用 port 和 port_map
library ieee;
use ieee.std_logic_1164.all;
package 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;
entity cpu is
port(clk,interrupt:in std_logic;
add,out tw32;
comt,in integer;
data,inout tw32 );
end cpu;
architecture cpu_blk of cpu is
signal addr_bus,data_bus,tw32;
begin
ALU,block
port( a_bus,b_bus,in tw32;
c_bus,in integer;
d_out,out tw32);
port map( a_bus => addr_bus; --将 a_bus映射到快外结构体的局部信号 addr_bus
b_bus => data_bus; --将 b_bus映射到快外结构体的局部信号 data_bus
c_bus => comt; --将 c_bus映射到实体端口 comt
d_out => data) --将 d_out映射到实体端口 data
begin
d_out <=tw_add(a_bus,b_bus) when c_bus=0 else
tw_sub(a_bus,b_bus) when c_bus =1 else
a_bus;
end block ALU;
end cpu_blk;
例:数据分配器功能:将一个数据源的数据根据需要送到多个不同的通道上去数据分配器:实现数据分配功能的逻辑电路,相当于多个输出的单刀多掷开关
1对 4数据分配器的电路符号
demux4
din
y1a[1…0]
y0
y2
y3
输入 输出地址选择
A1 A0 Y3 Y2 Y1 Y0
0 0 0 0 0 Din
0 1 0 0 Din 0
1 0 0 Din 0 0
1 1 Din 0 0 0
1对 4数据分配器的真值表
library ieee;
use ieee.std_logic_1164.all;
entity demux4 is
port(a:in std_logic_vector(1 downto 0);
din,in std_logic;
y0,y1,y2,y3,out std_logic);
end demux4;
architecture one of demux4 is
begin
process(din,a) is
begin
y0<=‘0’;y1<=‘0’; y2<=‘0’; y3<=‘0’;
case a is
when?00? => y0<=din;
when?01? => y1<=din;
when?10? => y2<=din;
when?11? => y3<=din;
when others <= null;
end case;
end process;
end;