use ieee.std_logic_1164.all;
———————————————————————- package my_package is
type state is (st1, st2, st3, st4); type color is (red, green, blue);
constant vec: std_logic_vector(7 downto0) := “1111_1111″; end my_package;
Example6.2 内部包含函数的package library ieee;
use ieee.std_logic_1164.all;
———————————————————————- package my_package is
type state is (st1, st2, st3, st4); type color is (red, green, blue);
contant vec: std_logic_vector(7 downto 0) := “1111_1111″; function positive_edge(signal s: std_logic) return boolean; end my_package;
———————————————————————- package body my_package is
function positive_edge(signal s: std_logic) return boolean is begin
return(s’event and s = ‘1′); end positive_edge; end my_package;
为了在QUARTUS II中使用这些package,要在当前project目录下新建一个文件夹,不妨起名为user_lib,把要编译的package放进此文件夹中,然后在AssignmentsàSettingàLibrary中设置相应的目录即可。在VHDL代码中要使用这些package,要在主程序中加入如下代码: use work.package_name.all; 2. 元件component
一个元件是一段结构完整的常用代码,包括声明,实体和结构体,使用component可以使代码具有层次化的结构。 元件声明:
component comp_name is port (
port_name1: signal_mode signal_type; port_name2: signal_mode signal_type;
… ); end component; 元件实例化:
label: comp_name port map (port_list);
元件的声明可以放在主代码中,即调用该元件的代码;或者将元件的声明放到package中,使用时在主代码中增加一条USE语句即可,这样避免了主代码中每实例化一个元件就要声明一次的麻烦。
3. 端口映射
在元件实例化过程中,有两种方法实现元件端口的映射:位置映射和名称映射。 component inverter is port ( a: in std_logic; b: out std_logic ); end component; …
U1: inverter port map(x, y);
此处采用的是位置映射法,x对应a,y对应b。 U1: inverter port map(a => x, b=> y);
此处采用的是名称映射法。对于不需要使用的端口可以断开,只需使用关键字open即可,但是输入端口不能指定为空连接。比如:
U2: my_circuit port map(x => a, y => b, w => open, z => b);
4. GENERIC参数映射
元件实例化时如果要通过GENERIC传递参数,则需进行GENERIC参数的映射。元件实例化的格式如下:
label: comp_name generic map(param_list) port map(port_list);
七、 函数和过程
Function和procedure统称为子程序,内部包含的都是顺序描述的VHDL语言.
八、 有限状态机
状态机的设计包含两个主要过程:状态机建模和状态的编码。 1.有限状态机的建模
有限状态机通常使用CASE语句来建模,一般的模型由两个进程组成,一个进程用来实现时序逻辑电路,另一个进程用来实现组合逻辑电路。 模型的构建:
(1) 分析设计目标,确定有限状态机所需的状态,并绘制状态图; (2) 建立VHDL实体,定义枚举类型的数据类型;
(3) 定义状态变量,其数据类型为前面所定义的枚举数据类型;例: TYPE STATE IS (STATE0, STATE1, STATE2, …); SIGNAL CR_STATE, NEXT_STATE: STATE; (4) 建立时序逻辑电路的实现进程;例: PROCESS (CLK,RESET) BEGIN
IF RESET=’1’ THEN CR_STATE <= STATE0;
ELSIF CLK’EVENT AND CLK=’1’ THEN CR_STATE <= NEXT_STATE; END IF; END PROCESS;
(5) 使用CASE语句建立组合逻辑电路的实现进程。例: PROCESS(CR_STATE,INPUT) BEGIN
CASE CR_STATE IS WHEN STATE0 =>
IF INPUT = … THEN NEXT_STATE <= STATE1; END IF; WHEN STATE1 => …
WHEN OHTERS => NEXT_STATE <= STATE0; END CASE; END PROCESS;
2.状态编码
状态编码包括二进制编码、枚举类型的编码和一位有效编码。利用一位有效编码(One-hot encoding)可以创建更有效地在FPGA结构中实现的有限状态机。每个状态可以使用一个触发器来创建状态机,并且可以降低组合逻辑的宽度。
有限状态机的可能状态由枚举类型所定义,即:
TYPE type_name IS(枚举元素1, 枚举元素2, …., 枚举元素n);
这个定义是通用的格式,时必须的。在该枚举类型定义语句之后,就可以声明信号为所定义的枚举类型:
TYPE STATE_TYPE IS(S1, S2, S3, S4, S5, S6, S7); SIGNAL CS,NS: STATE_TYPE;
为了选择有限状态机的状态编码方式,需要指定状态矢量。也可以通过综合工具指定编码方式。当在程序中指定编码方式时,可以在枚举类型定义语句后指定状态矢量,例如,
定义二进制编码的状态矢量的语句是: ATTRIBUTE ENUM_ENCODING: STRING;
ATTRIBUTE ENUM_ENCODING OF STATE_TYPE:TYPE IS “001 010 011 100 101 110 111”;
定义一位有效编码的状态矢量的语句为: ATTRIBUTE ENUM_ENCODING:STRING;
ATTRIBUTE ENUM_ENCODING OF STATE_TYPE:TYPE IS ”0000001 0000010 0000100 0001000 0010000 0100000 1000000”;