885191357基于FPGA的数字频率计设计论文

上传人:无*** 文档编号:141937729 上传时间:2022-08-24 格式:DOC 页数:24 大小:775KB
返回 下载 相关 举报
885191357基于FPGA的数字频率计设计论文_第1页
第1页 / 共24页
885191357基于FPGA的数字频率计设计论文_第2页
第2页 / 共24页
885191357基于FPGA的数字频率计设计论文_第3页
第3页 / 共24页
点击查看更多>>
资源描述
数字频率计设计摘要: Verilog HDL 作为一种规范的硬件描述语言, 被广泛应用于电路的设计中。他的设计描述可被不同的工具所支持, 可用不同器件来实现。利用Verilog HDL 语言自顶向下的设计方法设计交通灯控制系统, 使其实现道路交通的正常运转, 突出了其作为硬件描述语言的良好的可读性、可移植性和易理解等优点。关键字: 数字频率计; FPGA; Verilog HDL; 硬件描述语言第一章 系统总体设计 考虑到测量方便,将数字频率计划分为四档:1099Hz、100999Hz、10009999Hz、1000099999Hz。三个输入信号:待测信号、标准时钟脉冲信号和复位脉冲信号。设计细化要求:频率计能根据输入待测信号频率自动选择量程,并在超过最大量程时显示过量程,当复位脉冲到来时,系统复位,重新开始计数显示频率。基于上述要求,可以将系统基本划分为四个模块,分别为分频、计数、锁存和控制,并可以确定基本的连接和反馈,如图1所示。图1 系统模块组成第二章 系统及模块设计说明 如图2已知给定标准时钟脉冲高电平时间,将此高电平信号作为计数器闸门电平,通过计数器得到时间内待测脉冲的个数N,则有。经计算,四档的闸门电平时间分别为10s、1s、0.1s和0.01s。仅对计数器计数值N进行简单的移位即可得到结果。产生闸门电平的工作由分频器完成。图2 测量频率原理分频器采用计数分频的方法,产生计数闸门电平和一系列控制脉冲,并接受计数器和控制器的反馈。控制器主要用来判断计数器计数是否有效,从而控制档位转换,锁存器打开、关闭和设定值。计数器在分频器和控制器的作用下对输入待测信号计数,并把计数值输出,在计数溢出时向控制器和分频器发送溢出脉冲。锁存器用来储存有效计数值,以稳定输出。第三章 系统及模块具体实现与说明在分模块介绍之前先说明两个重要的寄存器状态STAT1:0和LATCH_STAT1:0。STAT1:0用来保存当前档位信息,STAT1:0等于0则为第一档,等于1则为第二档,依此类推,共可标记四档,它位于控制模块中,也是输出,这样其他模块可以通过访问它得到当前档位信息,而控制模块可以修改它从而调整档位LATCH_STAT1:0用来保存锁存器状态信息,LATCH_STAT1:00时,锁存器在CLK作用下打开关闭。LATCH_STAT1:01时,锁存器强制置零,CLK无效。LATCH_STAT1:0 2时,锁存器强制置1FFFF,CLK无效。它也在控制器中,这样可以通过对其改变数值达到控制锁存器锁存、复位和显示过量程的功能。3.1 计数器COUNTER计数器由四个十进制计数器级联。四个输入端口:时钟脉冲CLK、使能端EN、清零端CLRN、档位状态端STAT1:0。五个输出端口:四个四位十进制BCD码输出OUT13:0OUT43:0、过量程溢出OF。功能表见下:表格 1十进制计数器功能表ENCLRNSTAT1:0OUT41OFHL0,1,23位加一计数OF等于第三位进位HL34位加一计数OF等于第四位进位LL计数保持LLLHLL输入输出每个十进制计数器用Verilog HDL语言编程实现。源程序如下:module counter_10(clk, en, clrn, cr, out); /clk:时钟脉冲,上升沿触发 en: 使能端,高电平有效 /clrn:清零端,上升沿,高电平有效input clk, en, clrn; /cr: 进位端output cr;reg cr; /四位十进制BCD码输出output3:0 out;reg3:0 out;always (posedge clk or posedge clrn)begin /clrn 上升沿、高电平清零if(clrn) beginout = 0;cr = 0;endelse begin /en为高,模十加一计数,en为低,计数保持if(en) beginif(out 9) beginout = out + 1;cr = 0;endelse if(out = 9) beginout = 0;cr = 1;endelse beginout = 0;cr = 0;endendelse beginout = out;cr = 0;endendendendmodule3.2 分频器分频器是本系统最重要的功能部件之一,由它产生闸门电平和控制器、计数器的控制脉冲。它有四个输入:标准时钟脉冲输入CLK1024、溢出处理触发TRIGGER、复位触发RESET和档位状态STAT1:0。三个输出:计数闸门电平FGATE、控制器工作脉冲FTRIGGER、计数器控制器清零脉冲FCLR。分频器采用计数分频的办法,即使用一内部寄存器,在时钟脉冲上升沿加一计数,当计到一定值时就改变FGATE的状态,从而达到分频的目的。由于输入标准时钟脉冲为1024Hz,要得到0.1s的FGATE计数值相当小,约为20,误差很大,故在实际设计中把第四档闸门电平时间调整为0.1s,这样第三、四档公用一个闸门电平,同时在计数和锁存时要做相应的移位,因为测量第四档频率时有4位有效数字。要得到10s、1s、0.1s三个FGATE,分别要计数到10240、1024和103。分频器由这三种计数器并联组成,通过3个4选1选择器(一个74LS153和一个4_1MUX),由STAT1:0选择使用的FGATE、FCLR和FTRIGGER。出FGATE送计数器EN作为计数器使能闸门电平。FTRIGGER送控制器TRIGGER作为控制器工作脉冲。FCLR送计数器CLRN作为每次计数开始前的清零信号,送控制器CLR作为控制器内部触发信号。这三个信号的时序图3:图3 信号时序图由图可以看出FGATE由高变低,即计数结束时,FTRIGGER信号才产生,这时控制器开始工作,判断计数是否有效,然后发出一系列指令直到FCLR信号到来,计数器清零,准备进入下一次计数。采用这样的像CPU时钟一样的信号的原因,一方面,处理计数数据只用了很短的时间,两次测量之间时间很短,加快了频率计的响应速度;另一方面,解决了异步时序逻辑的竞争,使系统工作在异步时序状态下,既保持了很高的响应速度,又有很高的稳定性。为了解决在第一档向第二档转换时等待时间过长的问题,分频器由TRIGGER端口接收一个计数器的溢出脉冲,当计数器溢出时,在脉冲上升沿将内部计数器置为FGATE结束高电平的最后一个计数器值。这样,由于控制器此时溢出已被置位,马上就能进入一次换档处理,保证了换档的快速。另外,RESET信号上升沿到来时,计数器被置为零,这样就可以马上重新开始计数,实现了复位的效果。分频器单元FREQCER_10240的源程序如下(其他两个单元仅计数值不相同,其他均一样,故不列在此,见附录):module freqcer_10240(clk, trigger, reset, out_gate, out_clr, out_trigger);input clk, trigger, reset;output out_gate, out_clr, out_trigger;reg out_gate, out_clr, out_trigger;reg13:0 counter;always (posedge clk or posedge trigger or posedge reset)begin /计数器溢出,准备进入换档状态if(trigger) begincounter = 10239;end /复位else if(reset) begin /清零,准备开始计数counter = 10239;out_trigger = 0;out_clr = 0;out_gate = 0; end /非对称式分频else if(counter = 10239) beginout_trigger = 0;out_gate = 1;out_clr = 0;counter = 10240) & (counter = 10247) beginif(counter = 10241) | (counter = 10243) | (counter = 10245)out_trigger = 1;else if(counter = 10247)out_clr = 1;else beginout_clr = 0;out_trigger = 0;endout_gate = 0;counter = counter + 1;endelse if(counter = 10248) begincounter = 0;out_gate = 0;out_trigger = 0;out_clr = 0;endendendmodule3.3 锁存器锁存器有八个输入:时钟脉冲CLK,置位端SET,复位端RESET,4个4bit十进制BCD输入IN13:0IN43:0,档位状态STAT1:0。五个输出:5个5bit十进制BCD输出。由一桥接器BRIDGE和4个LATCH_4_16、1个LATCH_4_1锁存器组成。桥接器BRIDGE主要是为了数据对齐。因为3、4两档使用同一个分频器,故测量第四档时有4位有效数字,通过桥接器转换后就能保证数据有效数字最高位与锁存器第五位对齐。输入输出对应表如下:表格 2 桥接器功能表STAT 0,1,2STAT 3OUT5 IN3 IN4OUT4 IN2 IN3OUT3 IN1 IN2OUT20 IN1表格 3 LATCH_4_16功能表输入输出CLKSETRESETOUT00= IN01010F000F锁存器单元LATCH_4_1和LATCH_4_16均为4bit锁存器,其唯一不同在于置位时,LATCH_4_16锁存器内容置为F,另一个置1。下面将LATCH_4_16的功能表(表3)和源程序列出,同样将另一锁存器源程序收于附录。module latch_4_16(clk, set, reset, in, out);input clk, set, reset;input3:0 in;output3:0 out;reg3:0 out;always (posedge clk or posedge set or posedge reset)beginif(set)out = 4b1111;else if(reset)out = 0;elseout = in;endendmodule3.4 控制器控制器CONTROLER是整个系统最复杂也是最关键的部件。它由一个控制器核心模块CONTROL_CORE和寄存器OFREGISTER组成。OFREGISTER由CLK端接受计数器溢出脉冲在其上升沿置1,当控制器核心开始换档工作时,通过CLR清除OFREGISTER。其功能表4。表4 控制器功能表输入输出CLKCLROF10CONTROL_CORE模块是控制器的核心,有六个输入端口:时序脉冲CLK、清零脉冲CLR、复位脉冲RESET、溢出检测输入OF、计数器输出第3、4位IN33:0和IN43:0。输出端口四个:锁存器工作脉冲LATCH_CLK、OFREGISTER清零脉冲CLROF、锁存器状态LATCH_STAT1:0和当前档位状态STAT1:0。另外还有寄存器stat_reg1:0,用在转换档位时临时保存档位。count寄存器,用来标志当前工作脉冲序号。flag寄存器,用来标志当前计数置溢出或不够。reset_reg寄存器,用来标志复位周期。下面根据时序图简要介绍一下工作过程。图4 控制器仿真时序图由上述介绍我们知道有三种情况能到达状态:计数结束、计数中溢出和复位。这个时候就需要检测。RESET信号在上升沿将reset_reg置为1,并进行复位操作,即状态寄存器分别置值。在时刻第工作脉冲到来时,首先检测是不是复位周期,是则跳过,不作任何动作。不是,则检测OF端口是否为1,为1则有溢出,要进行换档,flag标志置1,并发出OFREGISTER清零信号CLROF,没有溢出,则检测计数器最高两位,两位均为0,则说明档位不够,要调低档位,flag标志置2,如果不均为0,则该计数值有效,flag置为0;当脉冲到来时,检测是否是复位周期,是则跳过,不是则继续。如果flag1,有溢出,向上换档,如果当前档位为3,则保持,并且将锁存器置位(显示1FFFF),否则向上调一挡;如果flag2,档位不够,当当前档位为0时,保持,否则向下调一挡。flag0,计数有效,发出锁存器时钟脉冲LATCH_CLK,将当前计数值打入锁存器。当脉冲到来时,清除中间状态寄存器。当脉冲到来时,在其下降沿将stat_reg的内容打入STAT,在下一次高电平到来之前实现档位转换。具体源程序如下:module control_core(clk, clr, reset, of, IN3, IN4, counter_clrn, latch_clk, clrof, latch_stat, stat);input clk, reset, of, clr;input3:0 IN3, IN4;output counter_clrn, latch_clk, clrof;reg counter_clrn, latch_clk, clrof, reset_reg;output1:0 latch_stat, stat;reg1:0 latch_stat, stat, flag, count, stat_reg;always (posedge clk or posedge reset or posedge clr)beginif(reset) begin /复位脉冲latch_stat = 1;stat_reg = 0;counter_clrn = 1;count = 0;flag = 0;clrof = 1;reset_reg = 1;endelse if(clr) begin /清零信号T4flag = 0;count = 0;endelse if(count = 0) begin /T1脉冲count = count + 1;if(reset_reg = 0) begin /非复位周期counter_clrn = 0;latch_clk = 0;latch_stat = 0;stat_reg = stat;if(of = 1) begin /有溢出clrof = 1;flag = 1;endelse if(of = 0) begin /没有溢出if(IN3 = 0) & (IN4 = 0) begin /档位不够flag = 2;endelse if(IN3) | (IN4) begin /计数有效flag = 0;endendendendelse if(count = 1) begin /T2脉冲count = count + 1;if(reset_reg = 0) begin / 非复位周期clrof = 0;if(flag = 1) begin / 溢出if(stat_reg = 3) begin / 已经在最高档latch_stat = 2; /锁存器置位endelse begin /向上调档stat_reg = stat_reg + 1;latch_stat = latch_stat;endendelse if(flag = 2) begin /档位不够latch_stat = latch_stat;if(stat_reg = 0) begin /当前在最低档stat_reg = 0; /档位保持endelse beginstat_reg = stat_reg - 1; /向下调档endendelse beginlatch_clk = 1; /计数有效,锁存endendendelse if(count = 2) begin /T3脉冲flag = 0;latch_clk = 0;count = 0;reset_reg = 0;endendalways (negedge clr)beginstat = stat_reg; /T4下降沿打入STATendendmodule第四章 误差分析及改进经过下载测试,实际的测量误差在12档时,误差在14数量级,在34档时,误差相对大一些,一般4,这是由于计数分频时计数值为近似值造成的系统误差。另外,在高档位向低档位转换时,会产生第一次测量不准的现象,尤其是在第一档上特别明显。经过分析,我发现这是我的这种分频器结构所特有的。因为三个分频器是并行独立计数分频,因此无法保证换档时各个分频器状态同步,解决方案是改进分频器,采用统一结构。具体程序见附录。实验中采用的CPU式的指令周期结构是不错的,保证了系统的稳定性和快速响应,但是由于刚刚接触,设计的时候逻辑、时序设计不够简洁,很多地方还有待改进。附录分频器 1smodule freqcer_1024(clk, trigger, reset, out_gate, out_clr, out_trigger);input clk, trigger, reset;output out_gate, out_clr, out_trigger;reg out_gate, out_clr, out_trigger;reg10:0 counter;always (posedge clk or posedge trigger)beginif(trigger) begincounter = 1023;endelse if(reset) begincounter = 1032;out_trigger = 0;out_clr = 0;out_gate = 0; endelse if(counter = 1023) beginout_trigger = 0;out_gate = 1;out_clr = 0;counter = 1024) & (counter = 1031) beginif(counter = 1025) | (counter = 1027) | (counter = 1029)out_trigger = 1;else if(counter = 1031)out_clr = 1;else beginout_clr = 0;out_trigger = 0;endout_gate = 0;counter = counter + 1;endelse if(counter = 1032) begincounter = 0;out_gate = 0;out_trigger = 0;out_clr = 0;endendendmodule分频器 0.1smodule freqcer_103(clk, trigger, reset, out_gate, out_clr, out_trigger);input clk, trigger, reset;output out_gate, out_clr, out_trigger;reg out_gate, out_clr, out_trigger;reg6:0 counter;always (posedge clk or posedge trigger)beginif(trigger) begincounter = 100;endelse if(reset) begincounter = 100;out_trigger = 0;out_clr = 0;out_gate = 0; endelse if(counter = 101) beginout_gate = 1;out_trigger = 0;out_clr = 0;counter = 102) & (counter = 109) beginif(counter = 103) | (counter = 105) | (counter = 107) beginout_trigger = 1;endelse if(counter = 109) beginout_clr = 1;endelse beginout_clr = 0;out_trigger = 0;endout_gate = 0;counter = counter + 1;endelse if(counter = 110) begincounter = 0;out_gate = 0;out_clr = 0;endendendmodule锁存器 LATCH_4_1module latch_4_1(clk, set, reset, in, out);input clk, set, reset;input3:0 in;output3:0 out;reg3:0 out;always (posedge clk or posedge set or posedge reset)beginif(set) beginout = 1;endelse if(reset) beginout = 0;endelse beginout = in;endendendmodule改进后的分频器module freq2(CLK1024, STAT, trigger, RESET, FGATE, FCLR, FTRIGGER);input CLK1024, trigger, RESET;input1:0 STAT;output FGATE, FCLR, FTRIGGER;reg FGATE, FCLR, FTRIGGER;reg13:0 counter;always (posedge CLK1024 or posedge trigger or posedge RESET)beginif(RESET) beginif(STAT = 0) begincounter = 10240;endelse if(STAT = 1) begincounter = 1024;endelse if(STAT = 2) | (STAT = 3) begincounter = 103;endFGATE = 0;FCLR = 0;FTRIGGER = 0;endelse if(trigger) beginif(STAT = 0) begincounter = 10240;endelse if(STAT = 1) begincounter = 1024;endelse if(STAT = 2) | (STAT = 3) begincounter = 103;endendelse beginif(STAT = 0) beginif(counter = 10239) beginFGATE = 1;FTRIGGER = 0;FCLR = 0;counter = 10240) & (counter = 10247) beginFGATE = 0;if(counter = 10241) | (counter = 10243) | (counter = 10245) beginFCLR = 0;FTRIGGER = 1;counter = counter + 1;endelse if(counter = 10247) beginFCLR = 1;FTRIGGER = 0;counter = 0;endelse beginFCLR = 0;FTRIGGER = 0;counter = counter + 1;endendelse begincounter = 0;FGATE = 0;FTRIGGER = 0;FCLR = 0;end endelse if(STAT = 1) beginif(counter = 1023) beginFGATE = 1;FTRIGGER = 0;FCLR = 0;counter = 1024) & (counter = 1031) beginFGATE = 0;if(counter = 1025) | (counter = 1027) | (counter = 1029) beginFCLR = 0;FTRIGGER = 1;counter = counter + 1;endelse if(counter = 1031) beginFCLR = 1;FTRIGGER = 0;counter = 0;endelse beginFCLR = 0;counter = counter + 1;FTRIGGER = 0;endendelse begincounter = 0;FGATE = 0;FTRIGGER = 0;FCLR = 0;end endelse if(STAT = 2) | (STAT = 3) beginif(counter = 102) beginFGATE = 1;FTRIGGER = 0;FCLR = 0;counter = 103) & (counter = 110) beginFGATE = 0;if(counter = 104) | (counter = 106) | (counter = 108) beginFCLR = 0;FTRIGGER = 1;counter = counter + 1;endelse if(counter = 110) beginFCLR = 1;FTRIGGER = 0;counter = 0;endelse beginFCLR = 0;FTRIGGER = 0;counter = counter + 1;endendelse begincounter = 0;FGATE = 0;FTRIGGER = 0;FCLR = 0;end endendendendmodule 参考文献1 基于Verilog的数字系统应用设计.王钿 卓兴旺 编著.北京:国防工业出版社,2007.82 数字系统设计与Verilog HDL.王金明 编著.北京:电子工业出版社,2005.93 Verilog数字系统设计教程.夏宇闻 编著.北京航空航天出版社,2003.74 VLSI数字信号处理系统设计与实现.Keshab.K.Parhi(美) 著. 陈弘毅等译.北京:机械工业出版社,2004.6
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 压缩资料 > 基础医学


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!