基于FPGA的等精度频率计论文版.docx
《基于FPGA的等精度频率计论文版.docx》由会员分享,可在线阅读,更多相关《基于FPGA的等精度频率计论文版.docx(37页珍藏版)》请在冰豆网上搜索。
![基于FPGA的等精度频率计论文版.docx](https://file1.bdocx.com/fileroot1/2023-2/2/27e6f243-f324-4aba-8284-d29778c4a50c/27e6f243-f324-4aba-8284-d29778c4a50c1.gif)
基于FPGA的等精度频率计论文版
基于FPGA的等精度数字频率计
摘要:
利用超高速硬件描述语言(VHDL)在现场可编程逻辑门阵列(FPGA)上编程实现的纯数字式等精度频率计,不但具有较高的测量精度,而且其测量精度不会随着被测信号频率的降低而下降。
为了实现对任意信号进行频率测量,在前端输入加整形电路即可。
关键字:
VHDLFPGA等精度波形整形 串行BCD码除法
DesignoftheCymometerBasedonFPGA
Abstract:
ThecymoneterthatbeimplementedwithusingtheVHDL(VeryHighSpeedIntegratedHardwareDescriptionLanguage)toprogramintotheFPGA(FieldProgrammableGateArray)chip,itnotonlyhashighprecision,butalsoitsprecisiondonotdecreasewithmeasured-frequency’sbecominglower.Inordertomeasureanysignal,itputareshapingcircuitatthefront-end.
Keyword:
VHDLFPGAIso-precisionWavereshaping
SerialBCDdivision
目录
第一章总体设计……………………………………….…….3
第二章单元电路设计…………………………….………….5
第三章软件设计……………………………………………..5
第四章系统测试……………………………………………..6
第五章结论及参考文献………………………………….….6
第六章附录………………………………………………….6
一.总体设计
基于传统测频原理的频率计的测量精度将随被测信号频率的下降而降低,在实用中有较大的局限性,而等精度频率计不但具有较高的测量精度,而且在整个频率区域能保持恒定的测试精度。
1.1.方案选择
1.1.1.总体方案比较:
方案一:
采用数字逻辑电路制作,用IC拼凑焊接实现。
其特点是直接用现成的IC组合而成,简单方便,但由于使用的器件较多,连线复杂,体积大,功耗大,焊点和线路较多将使成品稳定度与精确度大打折扣。
方案二:
采用可编程逻辑器件(CPLD)制作,利用EDA软件编程,下载烧制实现。
将所有器件集成在一块芯片上,体积大大减小的同时还提高了稳定性,并且可应用EDA软件仿真,调试,每个设计人员可以充分利用软件代码,提高开发效率,缩短研发周期,降低研发成本。
易于进行功能扩展,可以利用频率计的核心技术,改造成其它产品。
实现方法灵活,调试方便,修改容易。
比较以上两种方案,易见采用后者更优。
1.1.2.测频方案比较:
方案一:
完全按定义式F=N/T进行测量。
被测信号Fx经放大整形形成时标ГX,晶振经分频形成时基TR。
用时基TR开闸门,累计时标ГX的个数,则有公式可得Fx=1/ГX=N/TR。
此方案为传统的测频方案,其测量精度将随被测信号频率的下降而降低。
方案二:
对被信号的周期进行测量,再利用F=1/T(频率=1/周期)可得频率。
测周期时,晶振FR经分频形成时标ГX,被测信号经放在整形形成时基TX控制闸门。
闸门输出的计数脉冲N=ГX/TR,则TX=NГX。
但当被测信号的周期较短时,会使精度大大下降。
方案三:
等精度测频,按定义式F=N/T进行测量,但闸门时间随被测信号的频率变化而变化。
如图1所示,被测信号Fx经放大整形形成时标ГX,将时标ГX经编程处理后形成时基TR。
用时基TR开闸门,累计时标ГX的个数,则有公式可得Fx=1/ГX=N/TR。
此方案闸门时间随被测信号的频率变化而变化,其测量精度将不会随着被测信号频率的下降而降低。
综上所述,选用第三种等精度测频方案。
FX
图1测频方案方框图
1.2.串行BCD码除法介绍
测频方案中用到了定义式:
F=N/T,即要用到除法运算。
利用FPGA实现二进制除法运算,一种方法是采用逼近法,这种方法速度低、准确性不高。
另一种方法是采取被除数与除数的倒数相乘的方法,即将除数作为寄存器的地址,其倒数的小数部分作为寄存器的内容,通过一次寄存器寻址来计算除数的倒数。
这种方法在一个时钟周期内即可完成一个完整的除法运算,虽然速度较高,但对于多字节除法运算,不仅程序复杂,而且占用资源较多。
根据频率计的实际情况,本设计采用串行除法运算,利用多个时钟周期完成一个完整的除法运算,从而兼顾了频率计对速度和资源两方面的要求。
1.2.1.多位串行BCD码减法原理:
在数字串行除法运算中,减法运算是必不可少的部分。
数字串行BCD码的减法运算是将P位的BCD码分为P个宽为4的二进制数,然后从低位开始相减,在P个时钟周期内完成减法操作。
如果输入的操作数位数为8,那么串行BCD码减法器可以在8个时钟周期内完成8位BCD码减法运算。
数字串行减法的控制也比较简单,1位BCD码减法运算完成,进行移位操作,并且移位次数加1,然后通过采用start信号指示新计算周期。
当移位次数为n时,输出移位寄存器完成串/并转换,输出结果。
设计者可以根据实际情况,通过选择不同的n,提高设计的灵活性。
本设计选择n=8。
该设计在提高速度的同时,节省了资源。
实验证明,采用1OOMHz的工作频率,实现一个8位BCD码串行减法运算,耗用的资源却小于实现2位BCD码并行减法运算所耗用的资源。
1.2.2.多位串行BCD码除法原理:
本设计采用循环式除法运算,循环原理可以用下面的公式表示:
ω[j+1]=rω[j]-dqj+1
式中,ω[j]为第j步的余数,ω[0]为被除数;d为除数;qj+1为第j+1步所得的商;r为与移位步长有关的常数,在此取为16。
除法运算循环图表如图2所示。
图2串行BCD码除法运算算循环图
循环步骤如下:
1.将ω[j]左移四位,构成rω[j]。
2.通过多次BCD码减法运算,求得部分商qJ+1,得到部分余数。
3.部分余数、部分商移位,准备下次循环。
高速串行BCD码除法是建立在BCD码减法运算基础上的循环运算。
用被除数减除数得到部分余数的BCD码,如果够减,则使商加1;否则,余数和商同时左移四位,并记录移位的次数m,根据对有效位数的不同要求,可以对m进行赋值,如果要求保留8位有效数字,则m=8。
在这种循环除法运算中,减少循环的次数是提高运算速度比较有效的方法。
在一般循环式除法运算中,是从低位开始进行循环相减,循环次数等于商。
如果是8位除法运行,则得到一个8位的商,要进行8位次的BCD码减法循环,例如:
56895230/8=7111903.8,要进行7111903.8次循环,计算的速度可想而知。
在本设计中借鉴了一般十进制除法的运算方法,从高位开始相减,大大减少了循环次数。
下面以一个例子说明它的原理:
1.将被除数和除数移位,使其第一位BCD码不为0000,并记录移位的次数P(例如:
56895230/80000000,p=8)。
2.比较最高位的大小,如果除数的最高位大于被除数的最高位,则将除数右移4位,同时将P减1(即:
56895230/08000000,且p=7)。
3.得到的数卢为小数点的位置(F:
7说明小数点的位置在第七位数后)。
4.循环相减。
当部分余数小于08000000,再将部分余数左移四位,继续进行相减。
循环m次后即可得到m个有效数字的结果,然后根据p可以确定小数点的位置。
使用这种方法计算一个8位数的除法运算,循环减法次数最大为80次,每次循环使用时间为8个时钟周期。
如果工作频率为100MHz,则最长的运算时间为6.4μs,运算速度大大提高。
二.单元电路设计
2.1.整形电路:
图3输入信号整形电路图
三.软件设计
3.1.程序流程图:
频率测量程序流程图如图所示。
图4频率测量程序流程图
四.系统测试
4.1.使用仪器:
直流稳压电源:
DCPOWERSUPPLYDF1731SL2A,ZhongCeElectronicsCO.,LTD;
数字万用表:
UT101MULTIMETER金创电子仪器厂;
FPGA实验仪:
DP-FPGA,广州致远电子有限公司;
4.2.测试数据:
被测次数
1
2
3
4
5
6
7
8
被测频率(Hz)
测得频率(Hz)
测量误差(%)
五.结论及参考文献
5.1.参考文献:
1.潘松,黄计业.EDA技术实用教程[m].北京:
科学出版社.2002。
2.黄智伟主编,王彦,陈文光,朱卫华编著.全国大学生电子设计竞赛训练教程[M].北京:
电
子工业出版社2005.
3.南华大学第六届全国电子设计竞赛全体参赛成员.第六届电子大赛资料[C](多谢老师提供).
4.王松武,蒋志坚.通用仪器【M】.哈尔滨:
哈尔滨工程大学出版社.2002。
5.高吉祥.电子技术基础实验与课程设计【M】.北京:
电子工业出版社.2002。
六.附件
6.1.元件清单:
Designator
PartType
Quantity
Footprint
电阻
3.3k
1
axial0.4
电阻
10k
2
axial0.4
电阻
100k
4
axial0.4
电容
瓷片电容
2
rad0.1
插针
2针
2
sip2
插针
3针
1
sip3
插针
20针
1
idc20
芯片
DAC0832
1
DIP20
电容
电解电容
1
rb.2/.4
液晶
2x16字符型
1
led-a
集成运放
LM324
1
DIP14
电阻
RES2
2
axial0.4
6.2.程序清单:
--/*DJDPLJ_TOP.VHD*/--顶层模块
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
--Uncommentthefollowinglinestousethedeclarationsthatare
--providedforinstantiatingXilinxprimitivecomponents.
--libraryUNISIM;
--useUNISIM.VComponents.all;
entitydjdplj_topis
Port(rst,clk:
instd_logic;
dc,das:
instd_logic;
rs,wr,e:
outstd_logic;
lcd_data:
inoutstd_logic_vector(7downto0));
enddjdplj_top;
architectureBehavioralofdjdplj_topis
componentcepinis
Port(bz:
instd_logic;
dc:
instd_logic;
rst,cl:
instd_logic;
bzclk,dcclk:
outstd_logic_vector(31downto0));
endcomponentcepin;
componentdivis
Port(clk,rst:
instd_logic;
bei,chu:
instd_logic_vector(31downto0);
shang:
outstd_logic_vector(31downto0);
dian:
outintegerrange-10to10);
endcomponentdiv;
componentlcdis
Port(clk,rst:
instd_logic;
rs,wr,e:
outstd_logic;
data:
inoutstd_logic_vector(7downto0);
pl:
instd_logic_vector(31downto0);
d:
inintegerrange-10to10);
endcomponentlcd;
componentresetis
Port(clk,rst:
instd_logic;
cl,clr:
outstd_logic);
endcomponentreset;
signalrst1,cl1,clr1,clkk:
std_logic;
signalbzclk1,dcclk1,shang1:
std_logic_vector(31downto0);
signaldian1:
integerrange-10to10;
signaldc1:
std_logic;
begin
u1:
cepinportmap(bz=>clkk,dc=>dc1,rst=>clr1,cl=>cl1,bzclk=>bzclk1,dcclk=>dcclk1);
u2:
divportmap(clk=>clk,rst=>rst1,bei=>dcclk1,chu=>bzclk1,shang=>shang1,dian=>dian1);
u3:
lcdportmap(clk=>clk,rst=>rst1,rs=>rs,wr=>wr,e=>e,data=>lcd_data,pl=>shang1,d=>dian1);
u4:
resetportmap(clk=>clk,rst=>rst1,cl=>cl1,clr=>clr1);
process(clk,rst)
variablecnt:
integerrange0to15;
begin
ifrst='0'then
cnt:
=0;clkk<='0';
elsifrising_edge(clk)then
ifcnt=15then
cnt:
=0;clkk<=notclkk;
else
cnt:
=cnt+1;
endif;
endif;
endprocess;
process(clk,rst)
variablecnt:
integerrange0to3200000;
begin
ifrst='0'then
cnt:
=0;
elsifrising_edge(clk)then
ifcnt<=10000then
cnt:
=cnt+1;
rst1<='1';
elsifcnt<=20000then
cnt:
=cnt+1;
rst1<='0';
else
cnt:
=30000;
rst1<=rst;
endif;
endif;
endprocess;
process(das,dc)
begin
ifdas='0'then
dc1<=dc;
endif;
endprocess;
endBehavioral;
--/*RESET.VHD*/--复位模块
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
--Uncommentthefollowinglinestousethedeclarationsthatare
--providedforinstantiatingXilinxprimitivecomponents.
--libraryUNISIM;
--useUNISIM.VComponents.all;
entityresetis
Port(clk,rst:
instd_logic;
cl,clr:
outstd_logic);
endreset;
architectureBehavioralofresetis
begin
process(clk,rst)
variablecnt:
integerrange0to32000000;
begin
ifrst='0'then
cnt:
=0;clr<='1';cl<='0';
elsifrising_edge(clk)then
cnt:
=cnt+1;
ifcnt=1000000then--cnt=1000000
clr<='1';
elsifcnt=2000000then--cnt=2000000
clr<='0';
elsifcnt=3000000then--cnt=3000000
cl<='1';
elsifcnt=19000000then--cnt=19000000
cl<='0';
elsifcnt=20000000then--cnt=20000000
cnt:
=0;
endif;
endif;
endprocess;
endBehavioral;
--/*DIV.VHD*/--串行BCD码除法模块
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
entitydivis
Port(clk,rst:
instd_logic;
bei,chu:
instd_logic_vector(31downto0);
shang:
outstd_logic_vector(31downto0);
dian:
outintegerrange-10to10);
enddiv;
architectureBehavioralofdivis
typessisarray(1to8)ofstd_logic_vector(3downto0);
signals:
ss;
signala,b:
std_logic_vector(31downto0);
signaln:
integerrange-10to10;
signalc:
integerrange0to8;
signalk:
integerrange1to7;
signald:
integerrange0to1;
begin
process(clk,k,n,c,s,bei,chu,a,b,rst)
variablecnt:
integerrange0to31;
variablem:
std_logic_vector(3downto0);
begin
ifrst='0'then
k<=5;n<=7;c<=8;cnt:
=0;m:
="0000";s<=(("0000"),("0000"),("0000"),("0000"),("0000"),("0000"),("0000"),("0000"));
shang<=(others=>'0');
elsifrising_edge(clk)then
casekis
when1=>ifb(31downto28)=0then
b<=b(27downto0)&"0000";
ifn<10then
n<=n+1;
else
k<=5;
n<=7;
endif;
else
k<=2;
endif;
when2=>ifab<="0000"&b(31downto4);
n<=n-1;
else
ifn=0then
k<=5;
n<=7;
else
k<=3;
endif;
endif;
when3=>ifa(cnt+3downtocnt)>=b(cnt+3downtocnt)+dthen
a(cnt+3downtocnt)<=a(cnt+3downtocnt)-b(cnt+3downtocnt)-d;
d<=0;
else
a(cnt+3downtocnt)<=a(cnt+3downtocnt)+10-b(cnt+03downtocnt)-d;
d<=1;
endif;
ifcnt<28then
cnt:
=cnt+4;
k<=3;
else
k<=4;
endif;
when4=>m:
=m+1;
cnt:
=0;
d<=0;
ifa<=bthen
s(c)<=m;
m:
="0000";
ifc=1then
k<=5;
else
k<=7;
c<=c-1;
ifa(31downto28)=0then
a<=a(27downto0)&"0000";
else
b<="0000"&b(31downto4);
endif;
endif;
else
k<=3;
endif;
when7=>ifa>=bthen
k<=3;
else
a<=a(27downto0)&"0000";
s(c)<=m;
ifc>=2then
c<=c-1;
else
k<=5;
endif;
endif;
when5=>a<=bei;
b<=chu;
shang<=s(8)&s(7)&s(6)&s(5)&s(4)&s(3)&s
(2)&s
(1);
k<=6;
dian<=n;
n<=7;
m:
="0000";
c<=8;
cnt:
=0;
when6=>ifa(31downto28)=0then