第七章 VHDL中的重载
重载:指同样名称的子程序或运算符可以用不同的数据类型作为它们的输入参数而被定义多次;即当多个子程序或运算符具有同一名称的时候,该子程序或运算符就会被重载。
重载的形式:
( 1)子程序重载允许子程序使用不同数据类型的参数;
( 2)运算符重载允许对不同类型的数据进行相同的运算操作;
重载的好处
( 1)避免了为实际上进行同一操作的子程序或运算符必须生成无数个不同的名字;
( 2)使得 VHDL程序易于维护、易于共享。
7.1 子程序的重载允许设计人员用同一个名字编写两个或多个子程序,但这些子程序的参数类型、
参数数目和返回值可能不同。
7.1.1参数类型的重载指被重载的子程序参数类型不同。
library ieee;
use ieee.std_logic_1164.all;
package example is
function max(i1,i2:std_logic_vector) return std_logic_vector;
function max(i1,i2:bit_vector) return bit_vector;
function max(i1,i2:integer) return integer;
end example;
package body example is
function max(i1,i2:std_logic_vector) return std_logic_vector is
variabletmp:std_logic_vector(i1’range);
begin
if i1>i2 then
tmp:=i1;
else
tmp:=i2;
end if;
return (tmp);
end max;
例,example程序包
function max(i1,i2:bit_vector) return bit_vector is
variabletmp:bit_vector(i1’range);
begin
if i1>i2 then
tmp:=i1;
else
tmp:=i2;
end if;
return (tmp);
end max;
function max(i1,i2:integer) return integer is
variable tmp:integer;
begin
if i1>i2 then
tmp:=i1;
else
tmp:=i2;
end if;
return (tmp);
end max;
end example;
重载函数调用举例 (max_value.vhd):
library ieee;
use ieee.std_logic_1164.all;
use work.example.all;
entity max_value is
port(a1,a2:in std_logic_vector(7 downto 0);
b1,b2:in bit_vector (7 downto 0);
c1,c2,in integer;
a:out std_logic_vector(7 downto 0);
b:out bit_vector( 7 downto 0);
c:out integer;
end max_value;
architecture one of max_value is
begin
a<=max(a1,a2);
b<=max(b1,b2);
c<=max(c1,c2);
end one;
程序包调用的方法:
( 1)将程序包与实体文件合并于一个 VHDL文件中,如:
library ieee;
use ieee.std_logic_1164.all;
package example is

end example;
package body example is

end max;
library ieee;
use ieee.std_logic_1164.all;
use work.example.all;
entity max_value is

end max_value;
architecture one of max_value is

end one;
(2)建立工程 (max_value),在 assignments/setting/Files中在 filename中选择添加
/../example.vhd.
例:分频器常用来对数字电路中的时钟信号分频,用以得到较低频率的时钟信号、选通信号、
中断信号等。
偶数分频器如果输入信号的频率为 f,则分频器的输出信号为 f/2n,n=1,2,…
分频系数为 2的整数次幂的分频器分频系数 N=2n
如 2分频 (n=1),4分频( n=2),8分频 (n=3)
可采用模为 n的计数器实现,如 n=3
clk R S EN Q2 Q1 Q0
↑ 0 0 1 0 0 0
↑ 0 0 1 0 0 1
↑ 0 0 1 0 1 0
↑ 0 0 1 0 1 1
↑ 0 0 1 1 0 0
↑ 0 0 1 1 0 1
↑ 0 0 1 1 1 0
↑ 0 0 1 1 1 1
分频系数是 2的整数次幂分频器的电路符号
counter
clk div2
clk –时钟
div2 – 2分频输出端
div4- 4分频输出端 div4
div8div8- 8分频输出端
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity counter is
port(clk:in std_logic;
div2:out std_logic; --2分频输出
div4:out std_logic; --4分频输出
div8:out std_logic); --8分频输出
end counter;
architecture one of counter is
signal cnt,std_logic_vector(2 downto 0);
Begin
process (clk)
begin
if clk’event andclk=‘1’ then
cnt<=cnt+1;
end if;
end process;
div2<=cnt(0);div4<=cnt(1);div8<=cnt(2);
end one;
分频系数不是 2的整数次幂的分频器例,12分频器分频系数为 12的分频器的电路符号
clk div12
clk –时钟
div12 – 12分频输出端
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity cnt12 is
port(clk:in std_logic;
div12:out std_logic); --12分频输出
end cnt12;
cnt12
architecture one of cnt12 is
signal cnt,std_logic_vector(2 downto 0);
signal clk_tmp,std_logic;
constant m:integer:=5; --控制计数器的常量 m=n/2-1
begin
process (clk)
begin
if clk’event andclk=‘1’ then
if cnt=m then
clk_tmp<= not clk_tmp;
cnt<=?000?;
else
cnt<=cnt+1;
end if;
end if;
end process;
div12<=clk_tmp;
end one;
占空比不是 1,1的偶数分频器如:分频系数为 6、占空比为 1,5的偶数分频器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity cnt6 is
port(clk:in std_logic;
div6:out std_logic); --6分频输出
end cnt6;
分频系数为 6的分频器的电路符号
clk div6
clk –时钟
div6 – 6分频输出端
cnt6
architecture one of cnt6 is
signal cnt,std_logic_vector(2 downto 0);
signal clk_tmp,std_logic;
constant m:integer:=5; --控制计数器的常量 m=n/2-1
begin
process (clk)
begin
if clk’event andclk=‘1’ then
if cnt=m then
clk_tmp<= ‘1’;
cnt<=?000?;
else
clk_tmp<=‘0’;
cnt<=cnt+1;
end if;
end if;
end process;
div6<=clk_tmp;
end one;
7.1.2 参数数目的重载指相同名字的子程序具有不同数目的参数,参数类型却有可能相同。
例:程序包
library ieee;
use ieee.std_logic_1164.all;
package example is
function convert(a0,a1:std_logic) return integer;
function convert(a0,a1,a2:std_logic) return integer;
function convert(a0,a1,a2,a3:std_logic) return integer;
end example;
package body example is
function convert(a0,a1:std_logic) return integer is
variable result:integer=0;
begin
if(a0=‘1’) then
result:=result+1;
end if;
if (a1=‘1’) then
result:=result+2;
end if;
return (result);
end convert;
function convert(a0,a1,a2:std_logic) return integer is
variable result:integer=0;
begin
result:=convert(a0,a1);
if(a2=‘1’) then
result:=result+4;
end if;
return (result);
end convert;
function convert(a0,a1,a2,a3:std_logic) return integer is
variable result:integer=0;
begin
result:=convert(a0,a1,a2);
if(a3=‘1’) then
result:=result+8;
end if;
return (result);
end convert;
参数重载
library ieee;
use ieee.std_logic_1164.all;
use work.example.all;
entity conv is
port (i0,i1,i2,i3:in std_logic);
end conv;
architecture one of conv is
signal int1,int2,int3:integer;
begin
int1<=convert(i0,i1);
int2<=convert(i0,i1,i2);
int3<=convert(i0,i1,i2,i3);
end one;
7.1.3 函数返回类型的重载指被重载的同名函数的返回值类型是不同的。
例,example程序包
library ieee;
use ieee.std_logic_1164.all;
package example is
function max(i1,i2:std_logic_vector) return std_logic_vector;
function max(i1,i2:std_logic_vector) return bit_vector;
end example;
package body example is
function max(i1,i2:std_logic_vector) return std_logic_vector is
variabletmp:std_logic_vector(i1’range);
begin
if i1>i2 then
tmp:=i1;
else
tmp:=i2;
end if;
return (tmp);
end max;
function max(i1,i2:std_logic_vector) return bit_vector is
variabletmp:bit_vector(i1’range);
begin
if i1>i2 then
tmp:=i1;
else
tmp:=i2;
end if;
return (to_bitvector(tmp));
end max;
end example;
调用程序:
library ieee;
use ieee.std_logic_1164.all;
use work.example.all;
entity maxvalue is
port(a1,a2:in std_logic_vector(7 downto 0);
b1,b2:in std_logic_vector (7 downto 0);
a:out std_logic_vector(7 downto 0);
b:out bit_vector( 7 downto 0));
end maxvalue;
architecture one of maxvalue is
begin
a<=max(a1,a2);
b<=max(b1,b2);
end one;
例:奇数分频器分频系数为奇数,N=2n+1(n=1,2,…)
占空比不是 1,1的奇数分频器如:分频系数为 7、占空比为 1,6的分频器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity div7 is
port(clk:in std_logic;
q:out std_logic); --7分频输出
end div7;
architecture one of div7 is
signal cnt,std_logic_vector(2 downto 0);
constant m:integer:=6; --控制计数器的常量
begin
process (clk)
begin
if clk’event andclk=‘1’ then
if cnt=m then
q<= ‘1’;
cnt<=?000?;
else
cnt<=cnt+1;
q<=‘0’;
end if;
end if;
end process;
end one;
占空比为 1,1的奇数分频器如分频系数为 5
方法:设计两个计数器,一个利用上升沿计数,一个利用下降沿计数。两个计数器具有相同的模和分频系数。由这两个计数器的并行信号输出决定两个相应的电平控制信号,通过对这两个电平控制信号运算完成分频信号的输出。
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity div5 is
port(clk:in std_logic;
q:out std_logic); --5分频输出
end div5;
architecture one of div5 is
signal cnt1,std_logic_vector(2 downto 0); --计数器 1
signal cnt2,std_logic_vector(2 downto 0); --计数器 2
signal clk_tmp1,std_logic;
signal clk_tmp2,std_logic;
constant m1:integer:=4; --计数器控制端 1
constant m2:integer:=2; --计数器控制端 2
begin
process (clk) --上升沿触发计数进程
begin
if clk’event andclk=‘1’ then
if cnt1=m1 then
cnt1<=?000?;
else
cnt1<=cnt1+1;
end if;
end if;
end process;
process (clk) --下降沿触发计数进程
begin
if clk’event andclk=‘0’ then
if cnt2=m1 then
cnt2<=?000?;
else
cnt2<=cnt2+1;
end if;
end if;
end process;
process (clk) --上升沿触发计数的计数控制进程
begin
if clk’event andclk=‘1’ then
if cnt1=0 then
clk_tmp1<=‘1’;
elsif cnt1=m2 then
clk_tmp1<=‘0’;
end if;
end if;
end process;
process (clk) --下降沿触发计数的计数控制进程
begin
if clk’event andclk=‘0’ then
if cnt2=0 then
clk_tmp2<=‘1’;
elsif cnt2=m2 then
clk_tmp2<=‘0’;
end if;
end if;
end process;
q<=clk_tmp1 or clk_tmp2;
end one;
7.2 运算符重载重载运算符是指功能由用户定义,并且可对各种类型的数据进行运算的运算符。
例:重载运算符? +?
( 1)定义程序包
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
package example is
function?+?(l:integer; r:integer) return integer;
function?+?(l:bit_vector;r:bit_vector) return integer;
function?+?(l:std_logic_vector;r:std_logic_vector) return integer;
end example;
package body example is
function vector_to_int(a:in bit_vector) return integer is
variable result,tmp:integer:=0;
begin
for i ina’low toa’high loop
tmp:=0;
if(a(i)=‘1’) then
tmp:=2**(i-a’low);
end if;
result:=result+tmp;
end loop;
return (result);
end vector_to_int;
function?+?(l:integer; r:integer) return integer is
begin
return (l+r);
end;
function?+?(l:bit_vector; r:bit_vector) return integer is
begin
return (vector_to_int(l)+vector_to_int(r));
end;
function?+?(l:std_logic_vector; r:std_logic_vector) return integer is
begin
return (conv_integer(l)+conv_integer(r));
end;
end example;
调用程序:
library ieee;
use ieee.std_logic_1164.all;
use work.example.all;
entity add2 is
port(a1,b1:in integer;
a2,b2:in bit_vector (7 downto 0);
a3,b3:in std_logic_vector( 7 downto 0);
c1,out integer;
c2,out integer;
c3,out integer);
end add2;
architecture one of add2 is
begin
c1<=a1+b1;
c2<=a2+b2;
c3<=a3+b3;
end one;