当前位置:文档之家› 基于fpga的计数器的程序设计

基于fpga的计数器的程序设计

基于fpga的计数器的程序设计
基于fpga的计数器的程序设计

基于FPGA的计数器的程序设计

摘要

本文介绍了一种基于FPGA的,由顶层到底层设计的数字计数器。本文主要包括该计数器的设计基础和实现方法以及译码与显示等内容,描述了它的设计平台、工作原理和软硬件实现。本设计主要有分频器、四位计数器、16位锁存器以及数码管显示电路四个模块组成。计数器各模块设计采用VHDL硬件描述语言编程,极大地减少了硬件资源的占用,仿真与分析结果表明,该数字计数器性能优异,软件设计语言灵活,硬件简单,速度快。

关键词FPGA计数器VHDL分频器

目录

基于FPGA的计数器的程序设计 (1)

摘要 (1)

1 绪论 (3)

1.1 FPGA简介 (3)

1.2硬件描述语言VHDL简介 (3)

1.3开发工具Quartus II简介 (4)

2整体设计方案 (4)

3各功能模块设计及仿真 (5)

3.1分频器的设计 (5)

3.1.1分频器设计原理 (5)

3.1.2源程序及波形仿真 (6)

3.1.3分频器RTL 电路图 (7)

3.2计数器的设计 (7)

3.2.1分频器设计原理 (7)

3.2.2源程序及波形仿真 (8)

3.2.3 RTL 电路图 (11)

3.3锁存器的设计 (11)

3.3.1锁存器设计原理 (11)

3.3.2锁存器源程序及波形仿真 (12)

3.3.3锁存器RTL电路图 (13)

3.4显示部分的设计 (13)

3.4.1七段数码管显示原理 (13)

3.4.2七段数码管显示源程序及波形仿真 (15)

3.4.3七段数码管显示RTL 电路图 (16)

4系统顶层设计 (17)

4.1.1自顶向下的设计方法 (17)

4.1.2 顶层设计源程序及其仿真波形 (17)

4.1.3系统顶层RTL 电路图 (20)

5总结 (21)

参考文献 (22)

1 绪论

1.1 FPGA简介

FPGA 是现场可编程门阵列(Field Programmable Gate Array)的简称。FPGA 器件及其开发系统是开发大规模数字集成电路的新技术。它利用计算机辅助设计,绘制出实现用户逻辑的原理图、编辑布尔方程或用硬件描述语言等方式作为设计输入;然后经一系列转换程序、自动布局布线、模拟仿真的过程;最后生成配置FPGA器件的数据文件,对FPGA器件初始化。这样就实现了满足用户要求的专用集成电路,真正达到了用户自行设计、自行研制和自行生产集成电路的目的。

FPGA是一种半定制的集成电路,其特点是直接面向用户,具有极大的灵活性和通用性,开发效率高,硬件测试和实现快捷,工作可靠性好而且技术维护简单。

1.2硬件描述语言VHDL简介

随着电子技术的发展,集成电路的规模越来越大,复杂程度也越来越高。对于如此大规模的和复杂程度的电路设计问题,传统的门级描述方法显得过于琐碎和难以管理。而VHDL语言具有强大的功能,覆盖面广,描述能力强,可用于从门级、电路级直至系统级的描述、仿真和综合。下面简要介绍了VHDL语言。

VHDL的英文全名是Very-High-Speed Intergrated Circuit Hardware Description Language诞生于1982年。1987年底,VHDL被IEEE和美国国防部确认为标准硬件描述语言。自IEEE公布了VHDL的标准版本,IEEE-1076(简称87版)之后,各EDA公司相继推出了自己的VHDL设计环境,或宣布自己的设计工具可以和VHDL接口。此后VHDL在电子设计领域得到了广泛的接受,并逐步取代了原有的非标准的硬件描述语言。1993年,IEEE对VHDL进行了修订,从更高的抽象层次和系统描述能力上扩展VHDL的内容,公布了新版本的VHDL,即IEEE标准的1076-1993版本(简称93版)。现在,VHDL和Verilog 作为IEEE的工业标准硬件描述语言,又得到众多EDA公司的支持。在电子工程

领域,已成为事实上的通用硬件描述语言。有专家认为:在新的世纪中,VHDL 与Verilog语言将承担起大部分的数字系统设计任务。VHDL主要用于描述数字系统的结构、行为、功能和接口。除了含有许多具有硬件特征的语句外,VHDL 的语言形式和描述风格与句法是十分类似于一般的计算机高级语言。VHDL的程序结构特点是将一项工程设计——或称设计实体(可以是一个元件,一个电路模块或一个系统)分成外部(或称可视部分,及端口)和内部(或称不可视部分),即设计实体的内部功能和算法完成部分。在对一个设计实体定义了外部界面后,一旦其内部开发完成后,其它的设计就可以直接调用这个实体。这种将设计实体分成内外部分的概念是VHDL系统设计的基本点。

1.3开发工具Quartus II简介

Quartus II是Altera公司推出的CPLD/FPGA集成化开发软件,可以完成设计输入、逻辑综合、布局与布线、仿真、时序分析、硬件配置完整的PLD设计流程。QuartusⅡ提供了多种设计输入方式、快速的编译和直接易懂的器件编程。具有友好的用户界面,快速的综合速度和更优化的综合和适配功能。Quartus I I 自带宏功能模块库,大大减轻了用户的工作量,加快设计速度。Quartus II内置仿真器可以在工程中仿真任何设计。可进行功能仿真、时序仿真来检验设计的逻辑功能和计算设计的内部定时是否符合设计。仿真器可以仿真整个设计,或仿真设计的任何部分。支持可编程系统(SOPC)和大规模FPGA设计开发,集系统级设计、嵌入式软件开发、可编程逻辑设计于一体,是一种综合性的开发平台。

该软件支持Altera公司的Stratix Ⅱ、Stratix GX、Stratix、MAX3000A、MAX 7000B、MAX 7000AE、MAX Ⅱ、FLEX6000、FLEX10K系列、Cyclone、Cyclone Ⅱ、APEX Ⅱ、APEX20K和ACEX1K系列。

2整体设计方案

设计基于FPGA的计数器,要求显示1个0-9999的四位计数器,可以由4个模块为10的十进制计数器级联而成,所以可以显示的频率范围是1-9999HZ。因此频率计的功能分割成四个模块:分频计、计数器、输出锁存器和译码显示电

路。各个模块均用VHDL语言描述并用QuartusⅡ进行仿真。本设计采用数控分频计可以对信号实现不同分频比输出信号作为计数器输入。锁存器由一个外部脉冲控制可以控制显示部分显示周期。当系统正常工作时,输入信号标提供频率,经过分频器分频,产生计数信号送入计数器模块,计数模块对输入的脉冲个数进行计数数结束后将计数结果送入锁存器中,保证系统可以稳定显示数据,计数结果能够显示在七段数码显示管上。

图2-1整体设计方案

3各功能模块设计及仿真

3.1分频器的设计

3.1.1分频器设计原理

在数字逻辑电路设计中,分频器是一种基本电路,通过分频可以得到需要的时钟频率。常见的分频器有二进制分频器、偶数次分频器、奇数次分频器、占空比可调的分频器和小数分频器。分频的方法很多最常见的就是利用加法器对时钟信号进行分频,当然也可以利用一些专用的电路结构来实现。

数控分频器的功能是在输入端给定不同数据时,将对输入的时钟信号有不同的分频比,对于一个N分频器,分频出的时钟周期是原时钟周期的N倍,频率变为原来的1/N。对于一个8位计数器,如果输入数D,然后启动计数器工作,则经过D倍的时钟周期计数器溢出时,输出full变为高电平,再以full为敏感信号,对fout进行取反操作,如此N=2D。计数一次后,再重新计数,反复进行直至输入被赋予新值。对于数控分频数器,装载不同的计数初始值时,会有不同频

率的溢出信号,从而得到不同的输出。数控分频器是利用计数值可并行预置的加法计数器设计完成的

3.1.2源程序及波形仿真

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY DVF IS

PORT ( CLK : IN STD_LOGIC;

D : IN STD_LOGIC_VECTOR(7 DOWNTO 0);

FOUT : OUT STD_LOGIC );

END;

ARCHITECTURE one OF DVF IS

SIGNAL FULL : STD_LOGIC;

BEGIN

P_REG: PROCESS(CLK,D)

V ARIABLE CNT8 : STD_LOGIC_VECTOR(7 DOWNTO 0);

BEGIN

IF CLK'EVENT AND CLK = '1' THEN

IF CNT8 = "11111111" THEN

CNT8 := D; --当CNT计数计满时输入数据D被同步预置给计数器CNT8

FULL <= '1'; --同时使溢出标志信号FULL输出为高电平

ELSE CNT8 := CNT8 + 1; --否则继续作加1计数

FULL <= '0'; --且输出溢出标志信号FULL为低电平

END IF;

END IF;

END PROCESS P_REG ;

P_DIV: PROCESS(FULL)

V ARIABLE CNT2 : STD_LOGIC;

BEGIN

IF FULL'EVENT AND FULL = '1'

THEN CNT2 := NOT CNT2;

IF CNT2 = '1' THEN FOUT <= '1';

ELSE FOUT <= '0';

END IF;

END IF;

END PROCESS P_DIV ;

END;

图3-1 分频器时序仿真

3.1.3分频器RTL 电路图

图3-2 分频器RTL电路图

3.2计数器的设计

3.2.1分频器设计原理

计数是一种最简单基本的运算,计数器就是实现这种运算的逻辑电路,计数器在数字系统中主要是对脉冲的个数进行计数,以实现测量、计数和控制的功能,同时兼有分频功能,计数器是由基本的计数单元和一些控制门所组成,计数单元则由一系列具有存储信息功能的各类触发器构成,这些触发器有RS触发器、T

触发器、D触发器及JK触发器等。计数器在数字系统中应用广泛,如在电子计算机的控制器中对指令地址进行计数,以便顺序取出下一条指令,在运算器中作乘法、除法运算时记下加法、减法次数,又如在数字仪器中对脉冲的计数等等。计数器可以用来显示产品的工作状态,一般来说主要是用来表示产品已经完成了多少份的折页配页工作。它主要的指标在于计数器的位数,常见的有3位和4位的。很显然,3位数的计数器最大可以显示到999,4位数的最大可以显示到9999。在数字电子技术中应用的最多的时序逻辑电路。计数器不仅能用于对时钟脉冲计数,还可以用于分频、定时、产生节拍脉冲和脉冲序列以及进行数字运算等。但是并无法显示计算结果,一般都是要通过外接LCD或LED屏才能显示。

3.2.2源程序及波形仿真

3.2.2.1十进制计数器

加数的合法设计范围为0到9,故当输入的加数大于9的时候要将其统一变换成0。本实验采用一个带有异步复位和同步时钟使能的十进制加法计数器这种计数器有许多实际的用处。如果rst为“1”,将对时钟清零,如果为1,且有clk信号,则允许计数器就数,若计数器小于9,计数器加1,否则清零。第二个if语句功能是当计数器cqi的只达到9时产生进位溢出信号cout,常使用进位信号作为下个计数器的时钟。如下图3-3所示为十进制计数器时序仿真图。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY CNT10 IS

PORT(CLK,RST,EN: IN STD_LOGIC;

CQ: OUT STD_LOGIC_VECTOR(3 DOWNTO 0);

COUT: OUT STD_LOGIC);

END CNT10;

ARCHITECTURE behav OF CNT10 IS

BEGIN

PROCESS(CLK,RST,EN)

V ARIABLE CQI: STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

IF RST='1' THEN CQI:=(OTHERS=>'0');

ELSIF CLK'EVENT AND CLK='1' THEN

IF EN='1' THEN

IF CQI<9 THEN CQI:=CQI+1;

ELSE CQI:=(OTHERS=>'0');

END IF;

END IF;

END IF;

IF CQI =9 THEN COUT<='1';

ELSE COUT<='0';

END IF;

CQ <= CQI ;

END PROCESS;

END behav;

图3-3 十进制计数器时序仿真图

3.2.2.2四位十进制计数器

下面是一含计数使能、异步复位功能的4位计数器, rst是异步清信号,高电平有效。如下图3-4所示为四位十进制时序仿真图。

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

ENTITY CNT10_4 IS

PORT(CLK,RST,EN:in std_logic;

D:OUT STD_LOGIC_VECTOR(15 DOWNTO 0));

END ENTITY;

ARCHITECTURE behav OF CNT10_4 IS

COMPONENT CNT10

PORT(CLK,RST,EN: IN STD_LOGIC;

CQ: OUT STD_LOGIC_VECTOR(3 DOWNTO 0);

COUT: OUT STD_LOGIC);

END COMPONENT;

SIGNAL E:STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

U1: CNT10 PORT MAP( CLK=>CLK, RST=>RST,EN=>EN, COUT=>E(0), CQ=>D(3 downto 0) );

U2:CNT10 PORT MAP ( clk=>E(0), RST=>RST, EN=>EN, COUT=>E(1), CQ=>D(7 downto 4) ) ;

U3:CNT10 PORT MAP( clk=>E(1), RST=>RST, EN=>EN,COUT=>E(2), CQ=>D(11 downto 8) );

U4:CNT10 PORT MAP( clk=>E(2), RST=>RST,EN=>EN, COUT=>E(3), CQ=>D(15 downto 12) );

END ;

图3-4 四位十进制计数器时序仿真图

3.2.3 RTL 电路图

图3-5十进制计数器RTL电路图

图3-6 四位十进制计数器RTL电路图

3.3锁存器的设计

3.3.1锁存器设计原理

所谓锁存器,就是输出端的状态不会随输入端的状态变化而变化,仅在有锁存信号时输入的状态被保存到输出,直到下一个锁存信号到来时才改变。典型的锁存器逻辑电路是D触发器电路。在LED和数码管显示方面,要维持一个数据的显示,往往要持续的快速的刷新。尤其是在四段八位数码管等这些要选通的显示设备上。在人类能够接受的刷新频率之内,大概每三十毫秒就要刷新一次。这就大大占用了处理器的处理时间,消耗了处理器的处理能力,还浪费了处理器的功耗。锁存器的使用可以大大的缓解处理器在这方面的压力。当处理器把数据传输到锁存器并将其锁存后,锁存器的输出引脚便会一直保持数据状态直到下一次

锁存新的数据为止。这样在数码管的显示内容不变之前,处理器的处理时间和IO 引脚便可以释放。可以看出,处理器处理的时间仅限于显示内容发生变化的时候,这在整个显示时间上只是非常少的一个部分。而处理器在处理完后可以有更多的时间来执行其他的任务。这就是锁存器在LED和数码管显示方面的作用:节省了宝贵的MCU时间。

3.3.2锁存器源程序及波形仿真

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY REG16B IS

PORT (LOAD: IN std_logic;

DIN: IN STD_LOGIC_VECTOR(15 DOWNTO 0);

DOUT: OUT STD_LOGIC_VECTOR(15 DOWNTO 0));

END REG16B;

ARCHITECTURE art OF REG16B IS

BEGIN

PROCESS(LOAD,DIN)

BEGIN

IF LOAD'EVENT AND LOAD='1'THEN

DOUT<=DIN;

END IF;

END PROCESS;

END;

图3-7 锁存器时序仿真图

3.3.3锁存器RTL电路图

图3-8 锁存器RTL电路图

3.4显示部分的设计

3.4.1七段数码管显示原理

对于人机交互式单片机系统来说,不仅需要响应用户输入,同时也需要将一些测控信息输出显示。这些显示信息可以提供实时的数据或图形结果,以便于掌握系统的状态并进行分析处理。目前,最常用的是LED数码管显示。其成本低廉、使用简便,可以显示数字或几个特定的字符。数码管数码管的一种是半导体发光器件,数码管可分为七段数码管和八段数码管,区别在于八段数码管比七段数码管多一个发光二极管单元,其基本单元是发光二极管。数码管通过对其不同的管脚输入相对的电流,使其发亮,从而显示出数字能够显示时间、日期、温度等所有可用数字表示的参数的器件。在电器特别是家电领域应用极为广泛,如显示屏、空调、热水器、冰箱等等。绝大多数热水器用的都是数码管,其他家电也用液晶屏与荧光屏。

按发光二极管单元连接方式可分为共阳极数码管和共阴极数码管。共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管,共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低

电平时,相应字段就点亮,当某一字段的阴极为高电平时,相应字段就不亮。共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管,共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮,当某一字段的阳极为低电平时,相应字段就不亮。

7段共阳极LED数码管是由7个条形发光二极管和一个小数点位构成,其引脚配置,如下图3-9所示,其内部结构,如下图3-10所示。从图中可以看出,其中7个发光二极管构成字形“8”,可以用来显示数字,另一个发光二极管构成小数点。因此,这种数码管有时也被称为8段LED数码管显示器。

图3-9图3-10

LED数码管及引脚图资料LED数码管实际上是由七个发光管组成8字形构成的,加上一个小数点单元。这些段分别由字母a,b,c,d,e,f,g来表示。当数码管特定的段加上电压后,这些特定的段就会发亮,以形成我们眼睛看到的2个8数码管字样了。如:显示一个“2”字,那么应当是a亮b亮g亮e亮d亮f不亮c 不亮。

表3-1七段LED段码表

3.4.2七段数码管显示源程序及波形仿真

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY led_controller IS

PORT(D:IN STD_LOGIC_VECTOR(3 DOWNTO 0);

A:OUT STD_LOGIC_VECTOR(6 DOWNTO 0));

END led_controller;

ARCHITECTURE behav OF led_controller IS

BEGIN

PROCESS(D)

BEGIN

CASE D IS

WHEN "0000"=> A<= "0111111";WHEN "0001"=> A<= "0000110";

WHEN "0010"=> A<= "1011011";WHEN "0011"=> A<= "1001111";

WHEN "0100"=> A<= "1100110";WHEN "0101"=> A<= "1101101";

WHEN "0110"=> A<= "1111101";WHEN "0111"=> A<= "0000111";

WHEN "1000"=> A<= "1111111";WHEN "1001"=> A<= "1101111";

WHEN "1010"=> A<= "1110111";WHEN "1011"=> A<= "1111100";

WHEN "1100"=> A<= "0111001";WHEN "1101"=> A<= "1011110";

WHEN "1110"=> A<= "1111001";WHEN "1111"=> A<= "1110001";

WHEN OTHERS => NULL;

END CASE;

END PROCESS;

END;

图3-11 七段数码管显示时序仿真

3.4.3七段数码管显示RTL 电路图

图3-12七段数码管显示RTL

4系统顶层设计

4.1.1自顶向下的设计方法

所谓自顶向下设计方法,就是采用可完全独立于芯片厂商及其产品结构的描述语,在功能级对设计产品进行定义,并结合功能仿真技术,以确保设计的正确性,能定义完成后,利用逻辑综合技术,把功能描述转换成某一具体结构芯片的网表

文件,输出给厂商的布局布线器进行布局布线。布局布线结果还可反标回同一仿真器,进行包括功能和时序的后验证,以保证布局布线所带来的门延时和线延时

不会影响设计的性能。

自顶向下设计方法的优越性是显而易见的。首先,由于功能描述可完全独立于芯片结构,在设计的最初阶段,设计师可不受芯片结构的约束,集中精力进行产品设计,避免了传统设计方法所带来的重新再设计风险,大大缩短了设计周期。其次,设计的再利用得到保证。目前的电子产品正向模块化发展所谓模块化就是对以往设计成果进行修改,组合和再利用,产生全新的或派生设计,而自顶向下设计方法的功能描述可与芯片结构无关。因此可以以一种IP的方式进行存档,以便将来的重新利用。第三,设计规模大大提高。简单的语言描述即可完成复杂的功能,而不需要手工绘图。第四,芯片选择更加灵活。设计师可在较短的时间内采用各种结构芯片来完成同一功能描述,从而在设计规模、速度、芯片价格及系统性能要求等方面进行平衡,选择最佳结果。

4.1.2 顶层设计源程序及其仿真波形

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

USE IEEE.STD_LOGIC_ARITH;

USE IEEE.STD_LOGIC_SIGNED;

ENTITY ccnntt IS

port( ena0,rst0:IN STD_LOGIC;

clk1,clk2:IN STD_LOGIC;

ledout:OUT STD_LOGIC_VECTOR(27 DOWNTO 0);

din:IN STD_LOGIC_VECTOR(7 DOWNTO 0)); END ENTITY;

ARCHITECTURE one OF ccnntt IS

COMPONENT DVF

PORT ( CLK : IN STD_LOGIC;

D : IN STD_LOGIC_VECTOR(7 DOWNTO 0);

FOUT : OUT STD_LOGIC );

END COMPONENT;

COMPONENT CNT10_4

PORT(CLK,RST,EN:in std_logic;

D:OUT STD_LOGIC_VECTOR(15 DOWNTO 0));

END COMPONENT;

COMPONENT REG16B

PORT ( LOAD: IN std_logic;

DIN: IN STD_LOGIC_VECTOR(15 DOWNTO 0);

DOUT: OUT STD_LOGIC_VECTOR(15 DOWNTO 0)); END COMPONENT;

COMPONENT led_controller

PORT(D:IN STD_LOGIC_VECTOR(3 DOWNTO 0);

A:OUT STD_LOGIC_VECTOR(6 DOWNTO 0));

END COMPONENT;

SIGNAL Y: STD_LOGIC;

SIGNAL B,H: STD_LOGIC_VECTOR(15 DOWNTO 0);

SIGNAL LEDS: STD_LOGIC_VECTOR(27 DOWNTO 0);

BEGIN

U1: DVF PORT MAP(clk=>clk1,D=>din,FOUT=>Y);

U2: CNT10_4 PORT MAP(CLK=>Y,RST=>rst0, EN=>ena0, D=>B);

U3: REG16B PORT MAP(LOAD=>clk2,DIN=>B(15 DOWNTO

0),DOUT=>H(15 DOWNTO 0));

U4: led_controller PORT MAP(D=>H(3 DOWNTO 0),A=>LEDS(6 DOWNTO 0));

U5: led_controller PORT MAP(D=>H(7 DOWNTO 4),A=>LEDS(13 DOWNTO 7));

U6: led_controller PORT MAP(D=>H(11 DOWNTO 8),A=>LEDS(20 DOWNTO 14));

U7: led_controller PORT MAP(D=>H(15 DOWNTO 12),A=>LEDS(27 DOWNTO 21));

ledout<=LEDS;

END;

4-1顶层时序仿真图4.1.3系统顶层RTL 电路图

图4-2系统顶层RTL电路图

相关主题
文本预览
相关文档 最新文档