基于VHDL语言的16阶线性相位滤波器设计Word文档格式.docx
《基于VHDL语言的16阶线性相位滤波器设计Word文档格式.docx》由会员分享,可在线阅读,更多相关《基于VHDL语言的16阶线性相位滤波器设计Word文档格式.docx(26页珍藏版)》请在冰豆网上搜索。
寄存器所有的输入输出数据都是10位带符号类型的数据。
2寄存器的VHDL语言实现
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_arith.all;
entitydff10is
port(x:
insigned(9downto0);
clk,rst:
instd_logic;
q:
outsigned(9downto0));
enddff10;
architecturedffofdff10is
begin
process(clk,rst)
variablezero:
signed(9downto0):
=(others=>
'
0'
);
if(rst='
1'
)thenq<
=zero;
elsif(clk'
eventandclk='
=x;
endif;
endprocess;
enddff;
3寄存器的模块图
4寄存器的仿真波形
完全符合设计要求。
(2)加法器
1加法器原理及功能
本设计当中的所有加法器都具有两个数据输入端、一个时钟输入端和一个数据输出端。
在时钟的上升沿实现两个输入数据的加法,同时将所求的和输出,并且所有加法器输入输出都是带符号类型的数据。
为了保证加法结果的正确性,每个加法器的输出都比输入多一位,且最高位都是符号位。
根据设计原理,滤波器的加法器有三级,所不同的是,每一级加法器的输入输出数据的位数都是不一样的。
2第一级加法器的VHDL语言实现
entityadder_layer1is
port(a,b:
insigned(9downto0);
clk:
c:
outsigned(10downto0));
endadder_layer1;
architectureadder_layer1ofadder_layer1is
begin
process
variabletemp:
signed(9downto0);
variableprod:
signed(10downto0);
begin
waituntil(clk'
eventandclk='
temp:
=a+b;
prod(9downto0):
=temp;
------未扩展的加法结果
if(a(a'
left)=b(b'
left)andtemp(temp'
left)/=b(b'
left))then
prod(10):
=b(b'
left);
-------判断是否溢出
else
=temp(temp'
-------扩展符号位
endif;
c<
=prod;
endprocess;
第一级加法器有10位输入和11位输出,最高位都是符号位。
所求和的符号位的扩展依据是,在有符号数加法器中,当两个符号位相同的操作数相加时,如果计算结果的符号位与两个操作数不同,就说明发生了溢出。
而当两个操作数的符号位不同时,则不会发生溢出。
一旦判断到发生了溢出,则所求和的符号位与两个加数的符号位相同,否则,所求和的符号位与未扩展的加法结果的符号位相同。
3第一级加法器的模块图
4第一级加法器的仿真波形
(3)第二级加法器的设计
本设计中,第二级加法器总共有四个,每个加法器都是进行了带符号类型数据的加法,因为它们的输入都来自对应的上一级乘法器的输出,所以每一个加法器的输入输出数据的位数是不一样的。
为了保证加法结果,所求的和的位数比两个加数的位数多一位。
1)第二级第一个加法器
由于两个加数a和b的位数是不一样的,a为16位,b为18位,因此,在进行加法运算之前,先将a扩展成18位,然后再求和。
和的位数为19位,比输入多一位。
1第二级第一个加法器的VHDL语言设计
entityadder_layer21is
port(a:
insigned(15downto0);
b:
insigned(17downto0);
outsigned(18downto0));
endadder_layer21;
architectureadder_layer2ofadder_layer21is
process
variableexp_a:
signed(17downto0);
variabletemp:
variableprod:
signed(18downto0);
begin
exp_a:
=a(a'
left)&
a(a'
a;
---将a的位数扩展到b的位数
=exp_a+b;
prod(17downto0):
---未扩展位数
if(exp_a(exp_a'
prod(18):
---扩展符号位
else
---扩展符号位
c<
endadder_layer2;
2第二级第一个加法器的模块图
3第二级第一个加法器的仿真波形
2)第二级第二个加法器
两个加数a和b的位数不一样,a为19位,b为18位,因此,在进行加法运算之前,先将b扩展成19位,然后再求和。
和的位数为20位,比输入多一位。
1第二级第二个加法器的VHDL语言实现
代码原理和第二级第一个加法器基本相同,限于篇幅,这里没有给出具体代码,详见adder_layer22.vhd。
2第二级第二个加法器的模块图
3第二级第二个加法器的仿真波形
3)第二级第三个加法器
两个加数a和b的位数不一样,a为18位,b为20位,因此,在进行加法运算之前,先将a扩展成20位,然后再求和。
和的位数为21位,比输入多一位。
1第二级第三个加法器的VHDL语言实现
原理同上,代码见adder_layer23.vhd。
2第二级第三个加法器的模块图
3第二级第三个加法器的仿真波形
4)第二级第四个加法器
两个加数a和b的位数一样,都是21位,所以不需要扩展。
1第二级第四个加法器的VHDL语言实现
原理同上,代码见adder_layer24.vhd。
2第二级第四个加法器的模块图
(4)第三级加法器的设计
1)第三级第一个加法器
两个加数a和b的位数不一样,a为19位,b为20位,因此,在进行加法运算之前,先将a扩展成20位,然后再求和。
1第三级第一个加法器的VHDL语言实现
原理同第二级加法器,代码见adder_layer31.vhd。
2第三级第一个加法器的模块图
3第三级第一个加法器的仿真波形
2)第三级第二个加法器
两个加数a和b的位数不一样,a为21位,b为22位,因此,在进行加法运算之前,先将a扩展成22位,然后再求和。
和的位数为23位,比输入多一位。
1第三级第二个加法器的VHDL语言实现
原理同上,代码见adder_layer32.vhd。
2第三级第二个加法器的模块图
3第三级第二个加法器的仿真波形
(5)第四级加法器的设计
两个加数a和b的位数不一样,a为21位,b为23位,因此,在进行加法运算之前,先将a扩展成23位,然后再求和。
然而根据设计原理,该加法器的输出应该是10位带符号数。
为了证明该加法器能够正常工作,这里先取24为输出。
1第四级加法器的VHDL语言实现
原理同上,代码见adder_layer4.vhd。
2第四级加法器的仿真波形
从仿真波形就可看出,该加法器是正常工作的。
3第四级加法器的模块图
如果要第四级加法器为10位输出,那么只要将输出及其赋值语句分别改为
outsigned(9downto0)和c<
=prod(21downto12)即可。
这里输出取24位当中第22位到第12位这10位的理由是,由于每一个乘法器的系数在处理时乘了2^11,及运算结果比实际左移了11位,所以应该将24位输出的低11位截掉。
而在剩下的13位当中取从原来的第22位到第13位这10位的原因是,若从最高位起取10位,那么最后的输出将会被缩小很多倍,所以这样做的目的是为了既能保证不丢失符号位,又能使输出不至于太小。
下图为第四级加法器的模块图。
4乘法器原理及功能
根据设计原理,所有加法器都是进行有符号数的移位乘法,即先移位,在相加。
这样做具有高效、不会占用过多的系统资源的优点。
如:
,分别先将被乘数左移8位、7位和4位相加,然后再加上它本身。
在作加法前,要分别将这四个加数进行位数扩展,具体的就是,先将被乘数、左移4位后的数和左移7位后的数扩展到19位得a0,a1,a2,即和左移8位后的数a3位数相同,然后a0加a1得b0,a2加a3得b1,最后将b0和b1相加得最终乘法结果。
所有加法的原理和加法器相同。
另外,在系数为负的情况下,先乘系数的绝对值,然后再对结果取反即可。
(6)系数为负31的乘法器
,先将被乘数左移5位,再减去被乘数,再对结果取反。
1系数为负31的乘法器的VHDL语言实现
entitymult31is
port(clk:
a:
insigned(10downto0);
outsigned(15downto0));
endmult31;
architecturemultofmult31is
variableinit:
variableshif1,expond_a,prod:
signed(15downto0);
variables:
signed(15downto0):
="
0000000000000001"
;
init:
=a;
shif1:
=init&
"
00000"
---左移5位
expond_a:
init;
prod:
=shif1-expond_a;
foriin15downto0loop
if(prod(i)='
)thenprod(i):
='
elseprod(i):
endloop;
prod:
=prod+s;
---取补
b<
endmult;
2系数为负31的乘法器的模块图
3系数为负31的乘法器的仿真波形
(7)系数为负88的乘法器
,先分别将被乘数左移3位再扩展两位得a0,左移4位再扩展一位得a1,左移6位得a2。
a0加a1得b0,b0加a2得c0,c0取反即为结果。
1系数为负88的乘法器的VHDL语言实现
entitymult88is
instd_logic;
insigned(10downto0);
outsigned(17downto0));
endmult88;
architecturemultofmult88is
variableshif1:
signed(13downto0);
variableshif2:
signed(14downto0);
variableshif3:
signed(16downto0);
variableexp1,exp2,temp1:
signed(15downto0);
variableaddtion1,temp2:
variableaddtion2:
=a&
000"
shif2:
0000"
shif3:
000000"
if(shif1(shif1'
left)='
)then
exp1:
00"
&
shif1;
11"
if(shif2(shif2'
exp2:
='
shif2;
else
temp1:
=exp1+exp2;
addtion1(15downto0):
=temp1;
if(exp1(exp1'
left)=exp2(exp2'
left)andtemp1(temp1'
left)/=exp1(exp1'
addtion1(16):
=exp2(exp2'
=temp1(temp1'
temp2:
=shif3+addtion1;
addtion2(16downto0):
=temp2;
if(addtion1(addtion1'
left)=shif3(shif3'
left)andtemp2(temp2'
left)/=addtion1(addtion1'
addtion2(17):
=addtion1(addtion1'
=temp2(temp2'
=0-addtion2;
---取反
2系数为负88的乘法器的模块图
3系数为负88的乘法器的仿真波形
(8)系数为负106的乘法器
,先分别将被乘数左移1位再扩展5位得a0,左移3位再扩展3位得a1,左移5位再扩展1位得a2,左移6位得a3,然后a0加a1得b0,a2加a3得b1,b0加b1的c0,c0取反即为结果。
1系数为负106的乘法器的VHDL语言实现
原理同上,代码见mult106.vhd。
2系数为负106的乘法器的模块图
3系数为负106的乘法器的仿真波形
(9)系数为负54的乘法器
,先分别将被乘数左移1位再扩展4位得a0,左移2位再扩展3位得a1,左移4位再扩展1位的a2,左移5位的a3。
a0加a1得b0,a1加a2得b1,b0加b1得c0,c0取反即为结果。
1系数为负54的乘法器的VHDL语言实现
原理同上,代码见mult54.vhd。
2系数为负54的乘法器的模块图
3系数为负54的乘法器的仿真波形
(10)系数为70的乘法器
,先分别将被乘数左移1位再扩展4位得a0,左移2位再扩展3位得a1,左移6位得a2。
a0加a1得b0,b0加a2的c0,c0即为结果。
1系数为70的乘法器的VHDL语言实现
entitymult70is
endmult70;
architecturemultofmult70is
signed(11downto0);
signed(12downto0);
1111"
="
111"
left)and
temp1(temp1'
left)and
temp2(temp2'
=addtion2;
2系数为70的乘法器的模块图
3系数为70的乘法器的仿真波形
(11)系数位239的乘法器
,先分别将被乘数扩展9位得a,左移4位再扩展3位得a0,左移5位再扩展2位得a1,左移6位扩展1位得a2,左移7位得a3。
a0加a1得b0,a2加a3得b1,b0加b1得c0,c0减a即为结果。
1系数位239的乘法器的VHDL语言实现
原理同上,代码见mult239.vhd。
2系数为239的乘法器的模块图
3系数为239的乘法器的仿真波形
(12)系数为401的乘法器
,先分别将被乘数左移8位得a0,左移4位再扩展4位得a1,左移7位再扩展1位得a2,左移8位得a3。
a0加a1得b0,a2加a3得b1,b0加b1即为结果。
1系数为401的乘法器的VHDL语言实现
原理同上,代码见mult401.vhd。
2系数为401的乘法器的模块图
3系数为401的乘法器的仿真波形
(12)系数为499的乘法器
,先分别将被乘数扩展7位得a0,左移1位再扩展6位得a1,左移4位再扩展3位得a2,左移5位再扩展2位得a3,左移6位再扩展1位得a4,左移7位得a5,左移8位得a6。
a0加a1得b0,a2加a3得b1,a4加a5得b2,b0加b1得c0,b2加a6的得c1,c1即为结果。
1系数为499的乘法器的VHDL语言实现
原理同上,代码见mult499.vhd。
2系数为499的乘法器的模块图
3系数为499的乘法器的仿真波形
(13)带有高频噪声的正弦波发生器
为了能够直