基于VHDL函数重载方法程序设计
函数(function)
一个函数就是一段顺序描述的代码。对于一些经常遇到的具有共性的设计问题,如数据类型转换、算术运算等,希望将其功能实现的代码被共享和重用,使主代码简洁并易于理解—函数。
注意:由于在于每次调用函数时,都要首先对其进行初始化,即一次执行结束后再调用需再次初始化,即函数内部的值是不能保持的,因此在函数中禁止进行信号声明和元件实例化。
函数的使用过程:先创建函数,再调用函数。
函数的存放形式
功能描述: “+”函数:
功能描述:扩展预定义的“+”操作符,进行std_logic_vector类型数据的加法运算。
实现方式:在包集中定义函数,在主代码中调用。
实验内容
(1) 用VHDL通过在包集中定义函数,实现“+”函数重载和调用。
(2) 将源程序进行综合、优化及功能仿真。
(3)软件说明:ModelSimSetup-13.1.0.162,QuartusSetup-13.1.0.162。
建立工程:
第一步:打开Quartus软件。
第二步:点击New Project Wizard -> next.
第三步:选择工程文件的存放位置,输入工程名 -> next -> next。
第四步:在family栏选择芯片型号-Cyclone IV E,在Name栏选择EP4CE115F29C7,选择完之后点击next。(如果不进行硬件调试时,此处默认即可)
第五步:检查工程有没有建错,点击完成。如下图:
程序设计:
方法一:(在包集中定义函数)
在包集中定义函数,可以方便地被其它设计所重用和共享。注意:函数在package中声明,在package body中定义。
全加器顶层文件设计:
--文件名:add_bit.vhd 应与工程名保持一致:
-------在主代码中调用包集中定义的函数--------------
library ieee;
use ieee.std_logic_1164.all;
use work.my_package.all;
entity add_bit is
GENERIC (n: integer :=4); --default is 4 ;
port(a: in std_logic_vector(n-1 downto 0);
b: in std_logic_vector(n-1 downto 0);
y: out std_logic_vector(n-1 downto 0) );
end add_bit;
architecture my_arch of add_bit is
--CONSTANT b: std_logic_vector(n-1 downto 0):="0011";
CONSTANT c: std_logic_vector(n-1 downto 0):="0110";
begin
y<= a + b + c; --重载“+”操作符
end my_arch;
–在包集中定义函数程序实现:
--文件名:my_package.vhl
-------在包集中定义函数----
library ieee;
use ieee.std_logic_1164.all;
package my_package is
function "+" (a, b: std_logic_vector) return std_logic_vector;
end my_package;
package body my_package is
function "+" (a, b: std_logic_vector) return std_logic_vector is
variable result: std_logic_vector (a'length-1 downto 0);
variable carry: std_logic;
begin
carry:='0';
for i in a'reverse_range loop
result (i):= a(i) XOR b(i) XOR carry;
carry:= (a(i) AND b(i)) OR (a(i) AND carry) OR (b(i) AND carry);
end loop;
return result;
end "+";
end my_package;
注意:
- 函数传递数据参数,可以通过(传递参数)'length获取,即上面程序中的a’length-1
- 另外,由于FUNCTION的输入值由调用者拷贝到输入参数中,因此输入参数不能指定取值范围。
- 函数内部不能声明信号
- 在输入参数列表中仍然不能指定信号的范围
- 虽然不知道输入信号的范围,但可以函数被调用时使用s’length来获取输入参数的具体范围
方法二:(在主代码中定义函数)
在主代码中定义函数, 可以出现在entity中,也可以出现在architecture中。如存放于architecture中的声明:
--文件名:add_bit.vhd 应与工程名保持一致:
-------在主代码中调用包集中定义的函数--------------
library ieee;
use ieee.std_logic_1164.all;
entity add_bit is
GENERIC (n: positive :=4);
port(a: in std_logic_vector(n-1 downto 0);
b: in std_logic_vector(n-1 downto 0);
y: out std_logic_vector(n-1 downto 0) );
end add_bit;
architecture my_arch of add_bit is
function "+" (a, b: std_logic_vector) return std_logic_vector is
variable result: std_logic_vector (n-1 downto 0);
variable carry: std_logic;
begin
carry:='0';
for i in a'reverse_range loop
result (i):= a(i) XOR b(i) XOR carry;
carry:= (a(i) AND b(i)) OR (a(i) AND carry) OR (b(i) AND carry);
end loop;
return result;
end "+";
--CONSTANT b: std_logic_vector(n-1 downto 0):="0011";
CONSTANT c: std_logic_vector(n-1 downto 0):="0110";
begin
y<= a + b + c; --重载“+”操作符
end my_arch;
文件仿真(这里采用modelsim仿真波形):
- 选择File-> New -> Verification/Debugging Files ->University Program VWF。
2.打开测试文件。(右键点击添加端口,对输入信号初始化,赋值。)
3.仿真结果:
逻辑电路图:
显示编译成功后,选择菜单栏 Tools –>Netlist Viewers –>RTL Viewer 显示逻辑电路图