在硬件逻辑电路中,实际面对的数据对象总是逻辑量,能够直接形成的运算是逻辑运算。
算术运算可以看作是一种抽象的行为描述。
组合运算电路主要包括加法器( adder)和乘法器( multipliers)。
组合运算模块的 VHDL设计组合运算模块的设计特点
VHDL的算术运算可以采用不同方式进行:
利用算术量和算术运算进行行为描述。
利用 signed和 unsigned类型直接进行二进制加减运算(对应于加法器);
直接设计加法的基本逻辑单元,再通过结构设计方式形成加法器和乘法器等功能单元。
组合运算模块的行为设计直接利用 VHDL中的加法运算和乘法运算可以对 integer类型的数据进行运算。
例:一个 4抽头的 FIR滤波器的直接实现。
组合运算模块的行为设计
entity fir4 is
port (x0,x1,x2,x3,in integer;
h0,h1,h2,h3,in integer;
y,out integer);
end fir4;
architecture beh of fir4 is
begin
y<=x3*h0+x2*h1+x1*h2+x0*h3;
end beh;
综合结果:需要使用 15800个 LUT!
组合运算模块的行为设计在数字逻辑电路中,通常进行的运算采用二进制形式,通过符号数或无符号数的运算规则进行;
为了体现这一特点,在算术运算包集合
IEEE.std_logic_arith中,定义了 signed和
unsinged 两种数据类型。
组合运算模块的行为设计
library ieee;
use ieee.std_logic_arith.all;
entity fir4 is
port (x0,x1,x2,x3,in unsigned ( 15 downto 0 );
h0,h1,h2,h3,in unsigned ( 15 downto 0 );
y,out unsigned ( 31 downto 0 ) );
end fir4;
architecture beh of fir4 is
begin
y<=x3*h0+x2*h1+x1*h2+x0*h3;
end beh;
综合结果:需要使用 8194个 LUT!
组合运算模块的行为设计
y,out unsigned ( 15 downto 0 ) );
----
architecture beh of fir4 is
signal y0,y1,y2,y3,unsigned (31 downto 0);
begin
y0<=x3*h0;y1<=x2*h1;y2<=x1*h2;y3<=x0*h3;
y<=y0(31 downto 16)+y1(31 downto
16)+y2(31 downto 16)+y3(31 downto 16);
end beh;
综合结果:需要使用 7959个 LUT!
采用二进制符号数或无符号数,可以对运算过程进行更准确的描述。
signed和 unsigned类型的特点
1 当两个二进制量进行相加时,若运算量中存在 signed类型,结果就为 signed类型;否则为 unsinged 类型;
2 若结果被指定为 std_logic_vector、
std_logic等类型,则 signed或 unsigned 类型的运算结果可以自动转为指定类型;
signed和 unsigned类型的特点
3 两个运算量长度不同时,运算结果的长度自动取为最长运算量的长度;
4 但若 unsigned 类型与 signed类型运算,会自动变为后一类型,则其长度会增加 1(在最高位增加符号位 ‘ 0’ );
signed和 unsigned类型的特点
5 对于通常所用的 sdt_logic_vector类型的数据 d,进行算术运算时,可以采用函数
signed(d)将其转换为 signed类型,或采用函数 unsigned(d)将其转换为 unsigned类型,
运算完毕后,通过赋值语句将结果直接赋值给 sdt_logic_vector类型的信号,即可恢复通用的类型;
各种运算结果的类型
entity vadd is
port (a,b,in unsigned( 7 downto 0 );
c,in signed ( 7 downto 0 );
d,in std_logic_vector( 7 downto 0 );
s,out unsigned (8 downto 0);
t,out signed (8 downto 0);
u,out signed (7 downto 0);
v,out std_logic_vector(8 downto 0));
end vadd;
各种运算结果的类型
architecture rtl of vadd is
begin
s <= (‘0’ & a)+(‘0’ & b);--保证位长一致
t <= a+c; --a转为 signed时自动添加 1位
u <= c+signed(d); --逻辑量通过函数转换
v <= c-unsigned(d);
--通过赋值自动转回逻辑量
end rtl;
采用 std_logic类型端口的 8位加法器
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity vadd is
port (a,b,in std_logic_vector( 7 downto 0 );
c,in std_logic;
s,out std_logic_vector(8 downto 0));
end vadd;
采用 std_logic类型端口的 8位加法器
architecture rtl of vadd is
signal d,std_logic_vector(0 to 0);
begin
d(0)<= c;
s <= ('0' & unsigned(a))+unsigned(b)+unsigned(d);
end rtl;
说明:由于 unsigned()函数只针对数组,
因此不能将 c直接变化,必须先将其写为数组信号;此外,为了使 s的数据宽度能够与右端运算匹配,应先将 a的宽度扩展到 8位。
组合运算电路的结构设计:基本单元从基本逻辑运算考虑,运算电路的基本逻辑单元为半加器和全加器;这些逻辑单元可以用简单赋值语句实现。
半加器,s <= a xor b; c0 <= a and b;
全加器,s <= a xor b xor ci;
c0 <= (a and b) or (a and ci) or (b and ci);
组合运算电路的结构设计:基本单元半加器( HA) 全加器( FA)
组合运算电路的结构设计:串行进位加法器
architecture str of add4 is
signal c,bit_vector(2 downto 0);
component fa is
port (a,b,ci,in bit;
s,co,out bit);
end component;
begin
u1:fa port map (a(0),b(0),ci,s(0),c(0));
u2:fa port map (a(1),b(1),c(0),s(1),c(1));
u3:fa port map (a(2),b(2),c(1),s(2),c(2));
u4:fa port map (a(3),b(3),c(2),s(3),s(4));
end str;
组合运算电路的结构设计:串行进位加法器采用流水设计,则每级的运算时间约为 2个 XOR延迟;
采用整体组合,n级的时间为 n个( NAND2+NAND3 )的延迟;
组合运算电路的结构设计:进位选择加法器为了提高运算速度,可以将全加器中与进位有关的运算加以分离,利用 P和 G选择由本位产生进位还是让低位进位通过:
组合运算电路的结构设计:进位选择加法器由于 HA的运算可以同时并行进行,进位选择加法器的平均速度可以大为加快,器件资源也减少了。
组合运算电路的结构设计:进位保存加法器利用半加器进行设计可以改善加法器的性能,
由此可以设计出下列的加法器基本单元:
组合运算电路的结构设计:进位保存加法器利用半加器进行设计可以改善加法器的性能,
由此可以设计出下列的加法器基本单元:
组合运算电路的结构设计:进位保存加法器
n位加法器:资源 =n2/2个 HA;时间 =n个 HA;
采用流水结构时,周期时间仅为 1个 HA的延迟。
组合运算电路的结构设计:组合乘法器结构单位乘积项采用 AND2实现,设计重点在于如何进行这些乘积项的相加。
组合运算电路的结构设计:组合乘法器结构方式 1:直接横向进位;
最长运算途径,7个 FA+1个 HA
组合运算电路的结构设计:组合乘法器结构方式 2:优化横向进位;
最长运算途径,5个 FA+1个 HA
组合运算电路的结构设计:组合乘法器结构方式 3:斜向进位(进位到下一行);
最长运算途径,4个 FA+2个 HA
组合运算电路的结构设计:组合乘法器结构固定系数乘法器比通用乘法器简单:
首先可以去掉所有产生乘积项的与门;
其次,当 bi=0时,可以去掉对应的行,系统得到简化。
在设计电路时,乘法器系数能够采用常数时,就不要采用信号或变量描述。
组合运算电路的结构设计:组合乘法器结构例,P=A*B,A=a3 a2 a1 a0,B=1001;
组合运算电路的结构设计:组合乘法器结构固定系数乘法器中乘数 B中含有的 0的数量越多,结构越简单;可以采用数学变换方式使 B中 0的数量最大化:
例如:
B=00010111( 16+4+2+1=23)
可以变换为:
D=00101001( 32-8-1=23)
变换后,0的数量增加了。