1 VHDL设计流程
注意, VHDL是不区分大小写的。
2 卡诺图化简
http://gc.nuaa.edu.cn/digital/kejian/ch2/2-4.htm
3
端口的信号模式(signal_mode):IN和OUT是单向引脚,而INOUT是双向引脚,BUFFER模式的引脚首先是一个输出引脚,但该输出信号可以供本电路内部使用(反馈)。注意:OUT类型的端口是不能供电路内部使用的。
4
PROCESS(敏感信号1,敏感信号2,...)
①每当敏感信号列表中的信号发生变化时,PROCESS就执行一次。
②尽管进程(PROCESS)内部的语句是顺序执行的,但是PROCESS作为一个整体和PROCESS外部的其他语句或进程是并发执行的。
5
“<=”操作符用来给信号(SIGNAL)赋值,而“:=”用来给变量(VARIABLE)赋值。默认情况下,ENTITY中所有的端口都是信号。
6
①位(BIT)和位矢量(BIT_VECTOR):位值用‘0’或‘1’表示。
例
SIGNAL x: BIT;
--将x声明为一个位宽为1的BIT类型的信号。
SIGNAL y: BIT_VECTOR(3 DOWNTO 0);
--将y声明为一个位宽为4的位矢量,其中最左边的一位是最高位(MSB:Most Significant Bit)。
②信号赋值(必须用“<=”操作符给信号赋值)。
x <= '1';
--x是位宽为1,值为‘1’的信号。注意,当位宽为1时,位值放在单引号中。
y <= "0111";
--y是位宽为4,值为“0111”(MSB = '0')的信号。注意,当位宽大于1时,位矢量值放在双引号中。
③STD_LOGIC和STD_LOGIC_VECTOR是IEEE 1164标准中引入的8逻辑值系统,但其中只有‘0’、‘1’和‘Z’(高阻态,综合后为三态缓冲器)是可综合的。
SIGNAL z: STD_LOGIC_VECTOR(3 DOWNTO 0) := "0001";
--声明z是一个位宽为4的矢量,其中最左边的一位是MSB。
--对信号z赋初始值“0001”(可选)。注意,使用“:=”对信号赋初始值。
④STD_ULOGIC和STD_ULOGIC_VECTOR是IEEE 1164标准中定义的9逻辑值的数据类型。事实上,上述的STD_LOGIC类型是STD_ULOGIC的一个子集。后者引入了一个新的逻辑值‘U’,表示初始不定值。与前者不同的是,STD_ULOGIC中没有指定两个STD_ULOGIC信号连接到同一个节点上发生冲突后的逻辑值,因此要避免两个STD_ULOGIC输出信号进行直接连接。
⑤SIGNED(有符号数)和UNSIGNED(无符号数)是在ieee库std_logic_arith包集中定义的数据类型。从外在表现上看,他们与STD_LOGIC_VECTOR相同,但能够支持与整型变量类似的算术运算。
- 对于有符号数:
a.正整数的原、反、补码(都用二进制表示,最高位为符号位,0表示正数,1表示负数)都一样。
b.对于负整数:①反码=原码除符号位(始终为1)取反;②补码=反码+1。
7
1. 用户定义的数据类型
①用户定义的整数(integer)类型:
TYPE my_integer IS RANGE -32 TO 32;
--用户定义的整数类型的子集。
②用户定义的枚举(enumerate)类型:
TYPE state IS (idle,forward,backward,stop);
--枚举数据类型,常用于有限状态机定义。
一般来说,枚举类型的数据自动按顺序依次编码(除非在用户自定义属性中进行了特别说明)。例如,上述例子中:“00”表示第一个状态(idle),“01”表示第二个状态(forward),以此类推。
2.子类型
SUBTYPE small_integer IS INTEGER RANGE -32 TO 32;
--整数类型的子类型。
VHDL不允许不同类型的数据之间直接进行操作运算,而某个数据类型的子类型则可以和原有类型数据直接进行操作运算。
3.数组(Array)
①定义数组类型:
TYPE type_name IS ARRAY (specification) OF data_type;
使用定义的数组类型对信号、变量和常数进行声明:
SIGNAL signal_name: type_name [ := initial_value];
--初始值可选。
例
TYPE matrix IS ARRAY(0 TO 3) OF STD_LOGIC_VECTOR(7 DOWMTO 0);
TO 3) OF STD_LOGIC_VECTOR(7 DOWMTO 0);
注意,该矩阵的每个矢量最左边的位为MSB,最上面一行为“第0行”。
②端口数组
由于预定义的数据类型都不超过一维,且在ENTITY中不允许使用TYPE进行类型定义,故当需要把端口定义为矢量矩阵时,必须在包集(PACKAGE)中自定义数据类型,该数据类型可以供包括在ENTITY在内的整个设计使用。
例
-----------------包集-------------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
----------------------------
PACKAGE my_data_types IS
TYPE vector_array IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
END my_data_types;
------------------主代码---------------
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE work.my_data_types.all; --用户定义的包集
---------------------------------------
ENTITY mux IS
port(inp: IN vector_array(0 TO 3);
...);
END mux;
...;
vector_array(0 TO 3);
...);
END mux;
...;
4.有符号数(SIGNED)和无符号数(UNSIGNED)
例
SIGNAL x: SIGNED (7 DOWNTO 0);
SIGNAL y: UNSIGNED(0 TO 0);
注意:
无符号数只能表示大于等于零的数,例如“0101”表示十进制数5;
有符号数则可以表示正数和负数,例如“0101”表示十进制数5,“1101”表示十进制数-5。
SIGNED和UNSIGNED支持算术运算和比较运算,不支持逻辑运算;STD_LOGIC_VECTOR与之相反。但是,当声明了ieee库提供的std_logic_signed和std_logic_unsigned这两个包集后,后者一样可以进行算术运算。
最后一行“AND”操作为a的各位与b的各位分别“与”运算。
8 数据类型转换
两种常见方法:一种是写专门用于数据类型转换的VHDL代码;
y <= long(x); --将x强制转换成long型然后赋给y。
一种是调用std_logic_1164包集中预定义的数据类型转换函数。