第一篇:基于FPGA的数字频率计设计报告
电子技术综合试验实验报告
班级:测控一班
学号:2907101002
姓名:李大帅 指导老师:李颖
基于FPGA的数字频率计设计报告
一、系统整体设计
设计要求:
1、被测输入信号:方波
2、测试频率范围为:10Hz~100MHz
3、量程分为三档:第一档:闸门时间为1S时,最大读数为999.999KHz
第二档:闸门时间为0.1S时,最大读数为9999.99KHz
第三档:闸门时间为0.01S时,最大读数为99999.9KHz。
4、显示工作方式:a、用六位BCD七段数码管显示读数。
b、采用记忆显示方法
c、实现对高位无意义零的消隐。
系统设计原理:
所谓“频率”,就是周期性信号在单位时间(1秒)内变化的次数。若在一定的时间间隔T内计数,计得某周期性信号的重复变化次数为N,则该信号的频率可表达为:f = N / T.基于这一原理我们可以使用单位时间内对被测信号进行计数的方法求得对该信号的频率测量,具体实现过程简述如下: 首先,将被测信号①(方波)加到闸门的输入端。由一个高稳定的石英振荡器和一系列数字分频器组成了时基信号发生器,它输出时间基准(或频率基准)信号③去控制门控电路形成门控信号④,门控信号的作用时间T是非常准确的(由石英振荡器决定)。门控信号控制闸门的开与闭,只有在闸门开通的时间内,方波脉冲②才能通过闸门成为被计数的脉冲⑤由计数器计数。
闸门开通的时间称为闸门时间,其长度等于门控信号作用时间T。比如,时间基准信号的重复周期为1S,加到闸门的门控信号作用时间T亦准确地等于1S,即闸门的开通时间——“闸门时间”为1S。在这一段时间内,若计数器计得N=100000个数,根据公式f = N / T,那么被测频率就是100000Hz。如果计数式频率计的显示器单位为“KHz”,则显示100.000KHz,即小数点定位在第三位。不难设想,若将闸门时间设为T=0.1S,则计数值为10000,这时,显示器的小数点只要根据闸门时间T的改变也随之自动往右移动一位(自动定位),那么,显示的结果为100.00Khz。在计数式数字频率计中,通过选择不同的闸门时间,可以改变频率计的测量范围和测量精度。
系统单元模块划分: 1)分频器,将产生用于计数控制的时钟分别为1HZ,10HZ,100HZ脉冲和1KHZ的用于七段显示数码管扫描显示的扫描信号。
2)闸门选择器,用于选择不同的闸门时间以及产生后续的小数点的显示位置。3)门控电路,产生用于计数的使能控制信号,清零信号以及锁存器锁存信号。4)计数器,用于对输入的待测信号进行脉冲计数,计数输出。
5)锁存器,用于对计数器输出数据的锁存,便于后续译码显示电路的对数据进行记忆显示,同时避免计数器清零信号对数据产生影响。
6)译码显示,用于产生使七段显示数码管的扫描数字显示,小数点显示的输出信号,同时对高位的无意义零进行消隐。
二、单元电路设计
1、分频器:
该电路将产生四个不同频率的信号输出,因为电路板上给出了一个48MHZ的晶振,所以我们只需要对48MHZ的信号进行适当分频即可得到我们所需的四个不同频率的信号输出,我们设计一个输入为48MHZ,有四个输出端分别为1HZ,10HZ和100HZ,1KHZ的分频器,原程序如下:
library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;entity fenpinqi is Port(clk : in STD_LOGIC;clkout1 : out STD_LOGIC;clkout10 : out STD_LOGIC;clkout100 : out STD_LOGIC;clkout1K : out STD_LOGIC);end fenpinqi;
architecture Behavioral of fenpinqi is signal cnt1:integer range 1 to 24000000;signal cnt10:integer range 1 to 2400000;signal cnt100:integer range 1 to 240000;signal cnt1K:integer range 1 to 24000;signal c1:std_logic;signal c2:std_logic;signal c3:std_logic;signal c4:std_logic;begin process(clk)is begin if clk'event and clk='1' then if cnt1<24000000 then
--对cnt1进行计数,当cnt1未计满后对其进行加1 cnt1<=cnt1+1;elsif cnt1=24000000 then
--cnt1计满后对其进行赋一,并且令c1进行翻转,然后将c1的值赋给clkout1
c1<=not c1;--由于48MHZ的的信号,前一半的时候c1为0,则后一半是为1,就完成了对信号进行分频,产生了1HZ的信号 cnt1<=1;end if;end if;end process;process(clk)is begin if clk'event and clk='1' then--方法同上
if cnt10<2400000 then cnt10<=cnt10+1;elsif cnt10=2400000 then c2<=not c2;
cnt10<=1;
end if;end if;end process;
process(clk)is begin
if clk'event and clk='1' then
--方法同上
if cnt100<240000 then
cnt100<=cnt100+1;
elsif cnt100=240000 then
c3<=not c3;
cnt100<=1;
end if;end if;end process;
process(clk)is begin
if clk'event and clk='1' then
--方法同上
if cnt1K<24000000 then
cnt1K<=cnt1K+1;
elsif cnt1=24000 then
c4<=not c4;
cnt1K<=1;
end if;end if;end process;clkout1<=c1;clkout10<=c2;clkout100<=c3;clkout1K<=c4;end Behavioral;源文件编写成功后编译并生成图形文件符号如图:仿真文件编写如下:
LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.all;USE ieee.numeric_std.ALL;
ENTITY tbb_vhd IS END tbb_vhd;ARCHITECTURE behavior OF tbb_vhd IS COMPONENT fenpinqi 4
BEGIN
END;uut: fenpinqi PORT MAP(clk => clk,clkout1 => clkout1, clkout10 => clkout10, clkout100 => clkout100, clkout1K => clkout1K);PORT(clk : IN std_logic;
clkout1 : OUT std_logic;clkout10 : OUT std_logic;clkout100 : OUT std_logic;clkout1K : OUT std_logic);END COMPONENT;SIGNAL clk : std_logic := '0';SIGNAL clkout1 : std_logic;SIGNAL clkout10 : std_logic;SIGNAL clkout100 : std_logic;SIGNAL clkout1K : std_logic;tb : PROCESS BEGIN
clk<='0';wait for 10 ps;clk<='1';wait for 10 ps;END PROCESS;对该模块进行仿真结果如下:
有上图可知分频器工作正常,产生的个信号也没有毛刺,结果十分理想。
2、闸门选择器:
在这个模块中我们有四个输出端和六个输入端,其中四个输出端中有一个是频率输出端,是通过三个闸门选择开关输入和三个输入频率决定的,另外三个输出端则是用来后面的小数点控制的,而六个输入端中的三个是上面分频器的三个输出1HZ,10HZ和100HZ,另外三个是电路板上的拨动开关,用来选择闸门,控制输出。其原程序和分析如下:
library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity SELE is Port(SE1 : in STD_LOGIC;
SE10 : in STD_LOGIC;SE100 : in STD_LOGIC;F1HZ : IN STD_LOGIC;F10HZ : IN STD_LOGIC;F100HZ :IN STD_LOGIC;FREF : out STD_LOGIC;DP1 : out STD_LOGIC;DP2 : out STD_LOGIC;DP3 : out STD_LOGIC);end SELE;architecture Behavioral of SELE is begin PROCESS(SE1,SE10,SE100)IS BEGIN IF SE1='1' AND SE10='0' AND SE100='0' THEN
FREF<=F1HZ;--当闸门控制在第一档的时候,令输出端输出1HZ输入端的输入,小数点控制dp1有效,dp2,dp3无效
DP1<='0';
DP2<='1';DP3<='1';END IF;IF SE1='0' AND SE10='1' AND SE100='0' THEN
FREF<=F10HZ;
--第二档,输出为10HZ,dp2有效
DP1<='1';
DP2<='0';DP3<='1';END IF;IF SE1='0' AND SE10='0' AND SE100='1' THEN
FREF<=F100HZ;
--第三档,输出为100HZ,dp3有效
DP1<='1';
DP2<='1';DP3<='0';END IF;END PROCESS;end Behavioral;源代码编写完成后保存并生成图形文件符号如图:
仿真文件编写如下:
LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.all;USE ieee.numeric_std.ALL;
ENTITY TTB_vhd IS END TTB_vhd;ARCHITECTURE behavior OF TTB_vhd IS COMPONENT SELE
PORT(SE1 : IN std_logic;
SE10 : IN std_logic;
SE100 : IN std_logic;
F1HZ : IN std_logic;
F10HZ : IN std_logic;
F100HZ : IN std_logic;
FREF : OUT std_logic;
DP1 : OUT std_logic;
DP2 : OUT std_logic;DP3 : OUT std_logic);END COMPONENT;SIGNAL SE1 : std_logic := '1';SIGNAL SE10 : std_logic := '0';SIGNAL SE100 : std_logic := '0';SIGNAL F1HZ : std_logic := '0';SIGNAL F10HZ : std_logic := '0';SIGNAL F100HZ : std_logic := '0';SIGNAL FREF : std_logic;SIGNAL DP1 : std_logic;SIGNAL DP2 : std_logic;SIGNAL DP3 : std_logic;BEGIN uut: SELE PORT MAP(SE1 => SE1,SE10 => SE10,SE100 => SE100,F1HZ => F1HZ,F10HZ => F10HZ,F100HZ => F100HZ,FREF => FREF,DP1 => DP1,DP2 => DP2, DP3 => DP3);
tb : PROCESS BEGIN
F1HZ<='0';FREF<='0';
wait for 100 ns;
F1HZ<='1';FREF<='1';WAIT FOR 100 NS;END PROCESS;END;仿真结果如图:
有仿真结果可知闸门选择器工作正常,能够准确输出我们所需的信号。
3、门控信号:
在此模块中有一个输入端和两个输出端,输入端为上面的闸门选择器输出的频率,两个输出端分别为计数器是能控制信号(锁存器控制信号),和计数器清零信号。具体源程序即分析如下:
library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity CONTROLS is Port(FREF : in STD_LOGIC;GAT : out STD_LOGIC;CLR : out STD_LOGIC);end CONTROLS;
architecture Behavioral of CONTROLS is SIGNAL G1: STD_LOGIC:='0';begin
PROCESS(FREF)IS
BEGIN IF FREF'EVENT AND FREF='1' THEN G1<=NOT G1;--该过程对时钟信号又一次进行分频,产生出半个周期时间为1的控制信号,作为计数使能,保证了时间的准确性
END IF;END PROCESS;PROCESS(FREF,G1)IS
BEGIN IF FREF='0' AND G1='0' THEN CLR<='1';--该过程产生清零信号,即当使能信号为无效0同时时钟为0时,即在技术始终无效半个时钟时间后,对计数器清零
--清零信号高电平有效 ELSE CLR<='0';END IF;END PROCESS;GAT<=G1;--将G1赋给gat输出端,它是计数器的使能信号同时也是锁存器的锁存信号
end Behavioral;源文件编写完成后保存编译并生成图形文件符号如图:
仿真文件代码如下:
LIBRARY ieee;8
USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.all;USE ieee.numeric_std.ALL;
ENTITY TBCON_vhd IS END TBCON_vhd;ARCHITECTURE behavior OF TBCON_vhd IS
BEGIN
END;tb : PROCESS BEGIN
FREF<='0';WAIT FOR 100 NS;FREF<='1';WAIT FOR 100 NS;uut: CONTROLS PORT MAP(FREF => FREF, GAT => GAT, CLR => CLR);COMPONENT CONTROLS PORT(FREF : IN std_logic;
GAT : OUT std_logic;CLR : OUT std_logic);END COMPONENT;SIGNAL FREF : std_logic := '0';SIGNAL GAT : std_logic;SIGNAL CLR : std_logic;END PROCESS;对上面的文件进行仿真,结果如下:
由上图的仿真结果可知,控制电路工作正常,输出信号稳定,很理想。同时我们也可以看出来该模块对分频器的时钟输出的稳定性依赖十分严重,一旦分频器输出时钟有毛刺,该控制信号将会完全的无效,这也是为什么我知道上面的分频器设计不是最优的方案,却还是采用了上述方法的原因。
4、计数器:
该模块实现的功能是对输入信号脉冲的计数,并正确的输出结果和溢出。使用上面的门控信号产生的gat信号控制计数器的使能端,以实现计数器的定时计数。该模块是使用六个十进制计数器同步并联而成的,首先我们设计用于并联的十进制计数器,原程序如下:
library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;9
entity CNT10 is Port(CLK : in STD_LOGIC;CLR : in STD_LOGIC;
ENA : in STD_LOGIC;CQ : out STD_LOGIC_VECTOR(3 downto 0);CO : out STD_LOGIC);end CNT10;
architecture Behavioral of CNT10 is SIGNAL CQI: STD_LOGIC_VECTOR(3 DOWNTO 0):=“0000”;
--定义中间信号CQI,用于数据输出的循环计数
begin
PROCESS(CLK,CLR)IS
end Behavioral;
BEGIN IF CLR='1' THEN CQI<=“0000”;
--当CLR清零信号有效时使输出为0000,无效时进行下述操作--对时钟进行计数 ELSIF CLK'EVENT AND CLK='1' THEN
IF ENA='1' THEN
--判断使能信号,有效则进行计数,否则不作处理
--数据0~9循环,计满后重新回到0 IF CQI=“1001” THEN CQI<=“0000”;ELSE CQI<=CQI+'1';END IF;END IF;END IF;END PROCESS;CO <= '1' when ena = '1' and cqi = 9 else '0';CQ<=CQI;
--进位信号,最高位的仅为信号作为计数的溢出信号
--当且仅当使能有效且计数为9时产生进位信号,进位信号1有效,同步并联时连高位的使能端
文件编写完成后保存编译生成图形文件符号,如上图:
创建图形文件cnt6并按照下图进行连接,保存后编译生成图形文件符号如图:
仿真文件代码如下:
LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.all;USE ieee.numeric_std.ALL;
ENTITY TBCNT10_vhd IS END TBCNT10_vhd;ARCHITECTURE behavior OF TBCNT10_vhd IS
COMPONENT CNT10 PORT(CLK : IN std_logic;
CLR : IN std_logic;ENA : IN std_logic;CQ : OUT std_logic_vector(3 downto 0);CO : OUT std_logic);END COMPONENT;SIGNAL CLK : std_logic := '0';SIGNAL CLR : std_logic := '0';SIGNAL ENA : std_logic := '1';SIGNAL CQ : std_logic_vector(3 downto 0);SIGNAL CO : std_logic;BEGIN
END;tb : PROCESS BEGIN
CLK<='0';wait for 100 ns;CLK<='1';WAIT FOR 100 NS;uut: CNT10 PORT MAP(CLK => CLK, CLR => CLR, ENA => ENA, CQ => CQ, CO => CO);END PROCESS;仿真结果如图:
如仿真结果我们可以看出,该模块运行正常,计数稳定,结果十分理想。
5、锁存器:
由于前面的计数器的输出为六组四位二进制数和一个溢出信号,所以我们使用的锁存器也使用六个四位锁存器和一个一位锁存器。锁存器使用下降沿锁存,即当计数器的使能信号变为无效的一瞬间我们令锁存器将数据锁存。四位锁存器的原代码如下:
library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;entity LATCH4 is Port(CLK : in STD_LOGIC;DIN : in STD_LOGIC_VECTOR(3 downto 0);QOU : out STD_LOGIC_VECTOR(3 downto 0));end LATCH4;architecture Behavioral of LATCH4 is begin
PROCESS(CLK,DIN)IS
BEGIN
IF CLK'EVENT AND CLK='0' THEN--当时钟信号下降沿时,实现锁存
QOU<=DIN;
END IF;END PROCESS;end Behavioral;上述文件编写完成后保存编译生成图形文件符号如图: 再编写一位锁存器,源程序代码如下:
library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;entity LATCH1 is Port(CLK : in STD_LOGIC;DIN : in STD_LOGIC_VECTOR;QOU : out STD_LOGIC_VECTOR);end LATCH1;architecture Behavioral of LATCH1 is begin
PROCESS(CLK,DIN)IS
BEGIN
IF CLK'EVENT AND CLK='0' THEN--当时钟信号下降沿时,实现锁存
QOU<=DIN;
END IF;END PROCESS;end Behavioral;
文件编写完成后保存编译生成图形文件符号,如图:
锁存完成后有六组四位二进制数和一个一位二进制数,所以我们队总线进行了合并,即将六组四位数合并成一个二十四位数,合并程序如下:
library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ADVOCATES is Port(S0 : in STD_LOGIC_VECTOR(3 downto 0);S1 : in STD_LOGIC_VECTOR(3 downto 0);S2 : in STD_LOGIC_VECTOR(3 downto 0);S3 : in STD_LOGIC_VECTOR(3 downto 0);S4 : in STD_LOGIC_VECTOR(3 downto 0);S5 : in STD_LOGIC_VECTOR(3 downto 0);S6 : out STD_LOGIC_VECTOR(23 downto 0));
end ADVOCATES;
architecture Behavioral of ADVOCATES is
begin S6(23 DOWNTO 20)<=S0;S6(19 DOWNTO 16)<=S1;S6(15 DOWNTO 12)<=S2;S6(11 DOWNTO 8)<=S3;S6(7 DOWNTO 4)<=S4;S6(3 DOWNTO 0)<=S5;end Behavioral;--将总线的对应位进行连接
文件编写完成后保存编译生成图形文件符号,如图:
创建该模块的顶层图形文件LAT.sch将上述个文件按照如图所示连接,保存编译生成图形文件符号如图:
该模块的输入输出简单,无需仿真。
6、译码显示:
该模块实现的是对锁存器锁存的数据进行处理并显示输出,以及小数点的不同闸门的输出显示,以及电路板上七段显示译码管的扫描信号输出。其中对锁存数据的处理包括溢出有效时的数据消除,和对高位无意义零的自动消隐。首先我们编写小数点控制的源文件代码:
library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity POINTCON is Port(SE1 : in STD_LOGIC;SE10 : in STD_LOGIC;SE100 : in STD_LOGIC;SEL : in STD_LOGIC_VECTOR(2 downto 0);DP : out STD_LOGIC);end POINTCON;
architecture Behavioral of POINTCON is begin
PROCESS(SE1,SE10,SE100,SEL)IS
BEGIN
IF SE1='1' AND SE10='0' AND SE100='0' AND SEL=“011” THEN DP<='0';
--当为第一档时,令第四位的数码管的小数点点亮,其他的不亮
ELSIF SE1='0' AND SE10='1' AND SE100='0' AND SEL=“010” THEN DP<='0';
--第二档时,第三位的数码管小数点点亮
ELSIF SE1='0' AND SE10='0' AND SE100='1' AND SEL=“001” THEN DP<='0';
--第三档时,第二位的小数点点亮--不符合上述三档时,小数点全部消隐 ELSE DP<='1';END IF;END PROCESS;end Behavioral;编写完成后保存编译生成图形文件符号如图:
再编写用于数码管扫描显示的的位选信号生成文件,其代码如下:
library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity CTRLS is Port(CLK : in STD_LOGIC;SEL : out STD_LOGIC_VECTOR(2 downto 0));end CTRLS;
architecture Behavioral of CTRLS is SIGNAL CNT: STD_LOGIC_VECTOR(2 DOWNTO 0):=“000”;begin PROCESS(CLK)IS 14
BEGIN IF CLK'EVENT AND CLK='1' THEN
--接入1KHZ的时钟信号,使CNT进行循环计数,从000到101
IF CNT=”101” THEN CNT<=”000”;--计满则清零,不满则加一
ELSE CNT<=CNT+’1’;END IF;END IF;END PROCESS;SEL<=CNT;--将CNT信号赋给SEL输出
end Behavioral;文件编写完成后保存编译生成图形文件符号如图:
再编写使高位无意义零自动消隐功能的的文件,源程序代码如下:
library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity DSELE is Port(DP1: IN STD_LOGIC;DP2: IN STD_LOGIC;DIN : in STD_LOGIC_VECTOR(23 downto 0);QOU : out STD_LOGIC_VECTOR(23 downto 0));end DSELE;architecture Behavioral of DSELE is begin PROCESS(DP1,DP2,DIN)IS
BEGIN
IF DP1='0' AND DP2='1' THEN
IF DIN(23 DOWNTO 20)=“0000” THEN
QOU(23 DOWNTO 20)<=“1111”;
QOU(19 DOWNTO 0)<=DIN(19 DOWNTO 0);
END IF;
IF DIN(23 DOWNTO 20)=“0000” AND DIN(19 DOWNTO 16)=“0000” THEN
QOU(23 DOWNTO 20)<=“1111”;
QOU(19 DOWNTO 16)<=“1111”;
QOU(15 DOWNTO 0)<=DIN(15 DOWNTO 0);
END IF;
END IF;
IF DP1='1' AND DP2='0' THEN
IF DIN(23 DOWNTO 20)=“0000” THEN
QOU(23 DOWNTO 20)<=“1111”;
QOU(19 DOWNTO 0)<=DIN(19 DOWNTO 0);
END IF;
IF DIN(23 DOWNTO 20)=“0000” AND DIN(19 DOWNTO 16)=“0000” THEN
QOU(23 DOWNTO 20)<=“1111”;QOU(19 DOWNTO 16)<=“1111”;
THEN
QOU(23 DOWNTO 20)<=“1111”;QOU(19 DOWNTO 16)<=“1111”;QOU(15 DOWNTO 12)<=“1111”;QOU(11 DOWNTO 8)<=“1111”;QOU(7 DOWNTO 0)<=DIN(7 DOWNTO 0);
QOU(15 DOWNTO 0)<=DIN(15 DOWNTO 0);END IF;IF DIN(23 DOWNTO 20)=“0000” AND DIN(19 DOWNTO 16)=“0000” AND DIN(15 DOWNTO 12)=“0000” THEN
QOU(23 DOWNTO 20)<=“1111”;QOU(19 DOWNTO 16)<=“1111”;QOU(15 DOWNTO 12)<=“1111”;QOU(11 DOWNTO 0)<=DIN(11 DOWNTO 0);END IF;END IF;IF DP1='1' AND DP2='1' THEN
IF DIN(23 DOWNTO 20)=“0000” THEN QOU(23 DOWNTO 20)<=“1111”;QOU(19 DOWNTO 0)<=DIN(19 DOWNTO 0);END IF;IF DIN(23 DOWNTO 20)=“0000” AND DIN(19 DOWNTO 16)=“0000” THEN
QOU(23 DOWNTO 20)<=“1111”;QOU(19 DOWNTO 16)<=“1111”;QOU(15 DOWNTO 0)<=DIN(15 DOWNTO 0);END IF;IF DIN(23 DOWNTO 20)=“0000” AND DIN(19 DOWNTO 16)=“0000” AND DIN(15 DOWNTO 12)=“0000” THEN
QOU(23 DOWNTO 20)<=“1111”;QOU(19 DOWNTO 16)<=“1111”;QOU(15 DOWNTO 12)<=“1111”;QOU(11 DOWNTO 0)<=DIN(11 DOWNTO 0);END IF;IF DIN(23 DOWNTO 20)=“0000” AND DIN(19 DOWNTO 16)=“0000” AND DIN(15 DOWNTO 12)=“0000” AND DIN(11 DOWNTO 8)=“0000” END IF;END IF;END PROCESS;end Behavioral;该段代码的编写的主要原理是首先判断小数点的位置,然后对小数点前的高位数从高到低依次进行判断,如果高位为零则将数据取反,在后续译码中将不再显示,从而实现高位无意义零的自动消隐。代码编写完成后保存编译生成图形文件符号如上图: 然后我们编写数据显示输出文件,代码如下:
library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_ARITH.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity DISPLAY1 is 16
Port(SEL : in STD_LOGIC_VECTOR(2 downto 0);
OVERIN : IN STD_LOGIC;
DATAIN : in STD_LOGIC_VECTOR(23 downto 0);SEG : OUT STD_LOGIC_VECTOR(6 DOWNTO 0));END DISPLAY1;
architecture Behavioral of DISPLAY1 is SIGNAL DATA: STD_LOGIC_VECTOR(3 DOWNTO 0):=“0000”;BEGIN PROCESS(SEL,OVERIN)IS
BEGIN
CASE SEL IS
--对位选信号进行判断,对应每一位分别提取数据中的不同位置的数据赋给中间信号DATA
WHEN “000”=>DATA<=DATAIN(3 DOWNTO 0);
WHEN “001”=>DATA<=DATAIN(7 DOWNTO 4);
WHEN “010”=>DATA<=DATAIN(11 DOWNTO 8);
WHEN “011”=>DATA<=DATAIN(15 DOWNTO 12);
WHEN “100”=>DATA<=DATAIN(19 DOWNTO 16);
WHEN “101”=>DATA<=DATAIN(23 DOWNTO 20);
WHEN OTHERS=>DATA<=“0000”;
END CASE;
CASE DATA IS
--对中间信号DATA进行译码,SEG为数码管的数据显示输出,从而使不同位置上有不同的数字显示
WHEN “0000”=>SEG<=“1000000”;
WHEN “0001”=>SEG<=“1111001”;
WHEN “0010”=>SEG<=“0100100”;
WHEN “0011”=>SEG<=“0110000”;
WHEN “0100”=>SEG<=“0011001”;
WHEN “0101”=>SEG<=“0010010”;
WHEN “0110”=>SEG<=“0000010”;
WHEN “0111”=>SEG<=“1111000”;
WHEN “1000”=>SEG<=“0000000”;
WHEN “1001”=>SEG<=“0010000”;
WHEN OTHERS=>SEG<=“1111111”;
END CASE;
if OVERIN='1' THEN
--判断溢出,若溢出则令输出全部不显示
SEG<=“1111111”;END IF;END PROCESS;end Behavioral;代码编写完成后保存编译生成图形文件符号如图:
建立该模块的顶层图形文件DISPLAY.sch,按照下图连接各元件,保存编译生成图形文件符号如下图:17
该模块的输入数据量太大难以仿真,故这里只对其中的扫描信号生成文件进行仿真,仿真文件代码如下:
LIBRARY ieee;USE ieee.std_logic_1164.ALL;USE ieee.std_logic_unsigned.all;USE ieee.numeric_std.ALL;
ENTITY TBCTRLS_vhd IS END TBCTRLS_vhd;ARCHITECTURE behavior OF TBCTRLS_vhd IS
BEGIN
END;uut: CTRLS PORT MAP(CLK => CLK, SEL => SEL);COMPONENT CTRLS PORT(CLK : IN std_logic;
SEL : OUT std_logic_vector(2 downto 0));END COMPONENT;SIGNAL CLK : std_logic := '0';SIGNAL SEL : std_logic_vector(2 downto 0);tb : PROCESS BEGIN
CLK<='0';WAIT FOR 100 NS;CLK<='1';WAIT FOR 100 NS;END PROCESS;结果如下:
有仿真结果我们可以看出程序运行正常,逻辑上没有任何问题。至此所有的单元电路全部完成。
三、设计实现
1、顶层文件:
创建图形文件FRYALL.sch,按照下图连接各模块生成的图形文件符号,完成后保存编译。
2、管脚分配:
由系统的顶层文件可以看到该系统的输入端共有5个,输出端有11个,管脚分配文件FRYALL.ucf如下:
NET “CLKIN” LOC = T8;NET “DCLK” LOC = C16;NET “DP” LOC = C11;NET “NECT” LOC = D7;NET “SE1” LOC = L6;NET “SE10” LOC = N5;NET “SE100” LOC = L7;NET “SEG<0>” LOC = B14;NET “SEG<1>” LOC = A13;NET “SEG<2>” LOC = C13;NET “SEG<3>” LOC = C12;NET “SEG<4>” LOC = A12;NET “SEG<5>” LOC = B12;NET “SEG<6>” LOC = A11;NET “SEL<0>” LOC = F8;NET “SEL<1>” LOC = D8;NET “SEL<2>” LOC = E7;19
3、下载过程:
光标移至【Generate Programing File】后单击鼠标右键,然后单击【Properties】在打开的对话框的左侧栏选中【Configuration Options】将右侧的Unused IOB Pins这一项改为Pull Up,单击OK。在界面的左下角双击【 Generate Programing File】,软件将自动对整个系统进行编译并生成可执行文件FRYALL.bit。将弹出的对话框关掉,双击【 Generate Prom, ACE,or JTAG File】在弹出的对话框中点击Finish,在随后出现的对话框中选择FRYALL.bit,然后点击打开,在随后的对话框中点击Bypass。右键单击左边图标选择Program,在随后的对话框中单击OK,文件将自动下载到开发板上,成功后,接入函数发生器进行测试。
四、测试结果及结论
经过了前三步,最后我们将所完成的工程下载到了板子上,连接好函数发生器,并设定好了函数发生器的输出信号电平(5Vpp),就可以进行使用了。
最后结果显示程序工作正常,读数清晰稳定,完全符合开始时的要求。
误差分析:
我将函数发生器的频率调节到999,999HZ时,频率计不显示,即产生了计数溢出,然后我进行了进一步的调节,将函数发生器的频率调节到999,997时读书显示为999.999,单位为KHZ。由此可知相对误差为±0.0002%,误差很小。所以本次实验圆满成功。
通过对数字频率计的设计实现,我深入的学习了ise软件的使用,VHDL语言的编写规范,语法结构等。在本次试验中我回顾了在《数字电路》课程中学过的关于数字电路的设计的部分,了解了VHDL和Verilog语言的区别与联系,以及它们的优缺点,以及它们主要针对的设计对象。我觉得我通过本次试验学会了很多。
第二篇:基于FPGA的简易数字频率计
EDA 简易数字频计 设计性实验 2008112020327 ** 电子信息科学与技术
物电
电工电子中心2009年5月绘制
2008.6.10 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
简易数字频率计设计
一.任务解析
通过对选择题的分析,认为该简易数字频率计应该能达到以下要求: 1. 准确测出所给的方波信号的频率(1HZ以上的信号)。2. 在显示环节上,应能实现高位清零功能。3. 另外还有一个总的清零按键。
二.方案论证
本实验中所做的频率计的原理图如上图所示。即在一个1HZ时钟信号的控制下,在每个时钟的上升沿将计数器的数据送到缓冲器中保存起来,再送数码管中显示出来。
第2页,共11页 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
在本实验中,用到过几中不同的方案,主要是在1HZ时钟信号的选择和计数器清零环节上:
1. 在实验设计过程中,考滤到两种1HZ时钟信号其波形如下图所
对于上术的两种波形,可以调整各项参数来产生两种1HZ时钟信号。最后通过实验的验证发现第二种波形对于控制缓冲器获得数据和控制计数器清零更易实现。并且,用第二种波形做为时钟信号,可以在很短的高电平时间内对计数器清零,在低电平时间内让计数器计数,从面提高测量的精度。而用第一种波形则不易实现这个过程。
2.在计数器的清零过程中,也有两个方案,分别是能通过缓冲器反回一个清零信号,另一个是在时钟的控制下进行清零。最终通过实验发现,用时钟进行清零更易实现。因为如果用缓冲器反回一个清零信号,有一个清零信号归位问题,即当缓冲器反回一个低电平清零信号时,计数器实现清零,但不好控制让缓器冲的清零信号又回到高电平,否则计数器就一直处于清零状态面不能正常计数了。
三.实验步骤
通过上分析后,实验分为以下几步:
1.1HZ时钟信号的产生(产生该信号的模块如下):
module ones(clk,clkout);input clk;output clkout;parameter parameter N=24000000;n=24;
第3页,共11页 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
reg [n:0]cnt;reg clkout;
always @(posedge clk)begin if(cnt==N)else end endmodule begin cnt=0;
clkout=1;clkout=0;end
end begin cnt=cnt+1;最终产生的信号的波形:
2. 计数模块。其主要公能是在每个被测信号的上升沿自动加一,并且有一个清零信号的输入端,在1HZ时钟信号的高电平时间里进行清零。模块如下:
module count_99999999(sign,clr,b0,b1,b2,b3,b4,b5,b6,b7);input sign,clr;output [3:0]b0,b1,b2,b3,b4,b5,b6,b7;reg [3:0]b0,b1,b2,b3,b4,b5,b6,b7;always @(posedge sign or posedge clr)
if(clr)begin b0=0;b1=0;b2=0;b3=0;b4=0;b5=0;b6=0;b7=0;end else begin if(b0<9)b0=b0+1;else begin b0=0;if(b1<9)
第4页,共11页 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
b1=b1+1;else begin b1=0;if(b2<9)b2=b2+1;else begin
b2=0;
if(b3<9)
b3=b3+1;
else begin
b3=0;
if(b4<9)
b4=b4+1;
else begin
b4=0;
if(b5<9)
b5=b5+1;
else begin
b5=0;
if(b6<9)
b6=b6+1;
else begin
b6=0;
if(b7<9)
b7=b7+1;
else b7=0;
第5页,共11页
湖北师范学院电工电子实验教学省级示范中心电子版实验报告
end
end
end
end
end
end end
end endmodule 如果要访真该模块,要设定较长的访真时间,故在此不进行软件访真,只在实验箱上进行实验。
3. 数据缓冲模块。在每个秒级门控信号的上升沿接收计数器的数据,并送到驱动八个数码管的显示模块里。
module fre_count(clk,clr,b0,b1,b2,b3,b4,b5,b6,b7,a0,a1,a2,a3,a4,a5,a6,a7);input clk,clr;input [3:0]b0,b1,b2,b3,b4,b5,b6,b7;output [3:0]a0,a1,a2,a3,a4,a5,a6,a7;reg clro;reg [3:0]a0,a1,a2,a3,a4,a5,a6,a7;always @(posedge clk or negedge clr)//clk应该为1HZ的信号// begin if(!clr)
begin
a0<=0;a1<=0;a2<=0;a3<=0;a4<=0;a5<=0;a6<=0;a7<=0;end else
第6页,共11页 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
end begin a0<=b0;a1<=b1;a2<=b2;a3<=b3;a4<=b4;a5<=b5;a6<=b6;a7<=b7;end endmodule 在此模块中用了到了<=阻塞赋值的方式。
4.编写控制高位清零的模块,利用在扫描模块中控制SEL的值来实现高位清零。即先从高位开始判断,当只有个位有数据时,SEL只能等于0,当只有个位和十位有数据时,SEL要小于1,依此类推,实现高位清零功能。module scan(clk,a1,a2,a3,a4,a5,a6,a7,sel);input clk;input [3:0]a1,a2,a3,a4,a5,a6,a7;output [2:0]sel;reg [2:0]sel;always @(posedge clk)if({a1,a2,a3,a4,a5,a6,a7}==0000000)sel=0;else if({a2,a3,a4,a5,a6,a7}==000000)if(sel<1)sel=sel+1;else sel=0;else if({a3,a4,a5,a6,a7}==00000)if(sel<2)sel=sel+1;else sel=0;else if({a4,a5,a6,a7}==0000)if(sel<3)sel=sel+1;
第7页,共11页 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
else sel=0;else if({a5,a6,a7}==000)if(sel<4)sel=sel+1;else sel=0;else if({a6,a7}==00)if(sel<5)sel=sel+1;else sel=0;else if({a7}==0)if(sel<6)sel=sel+1;else sel=0;else sel=sel+1;endmodule 5.上述三个模块为本次实验的主要模块。除此,还用到了,译码,数据选择器模块。相应的模块代码省略。
6.所有模块都写完后,就是写顶层文件。
module top(clk,clr,sig_in,a,b,c,d,e,f,g,dp,sel);input clk,clr,sig_in;output [2:0]sel;output a,b,c,d,e,f,g,dp;
wire clk1,clk2,clk3;wire [2:0]sel_sign;wire [3:0] QA,QB,QC,QD,QE,QF,QG,QH;wire [3:0] b0_o,b1_o,b2_o,b3_o,b4_o,b5_o,b6_o,b7_o;wire [3:0] org_data;
第8页,共11页 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
assign sel=sel_sign;assign clk3=clk;
fre_count frequence(.clk(clk2),.clr(clr),.b0(b0_o),.b1(b1_o),.b2(b2_o),.b3(b3_o),.b4(b4_o),.b5(b5_o),.b6(b6_o),.b7(b7_o),.a0(QA),.a1(QB),count_99999999 mycounter(.sign(sig_in),.clr(clk2),.b0(b0_o),.b1(b1_o),.a2(QC),.a3(QD),.a4(QE),.a5(QF),.a6(QG),.a7(QH));.b2(b2_o),.b3(b3_o),.b4(b4_o),.b5(b5_o),.b6(b6_o),.b7(b7_o));
clk_div clksource(.clk(clk3),.clko1(clk1));
ones ones_con(.clk(clk3),.clkout(clk2));scan myscan(.clk(clk1),.a1(QB),.a2(QC),.a3(QD),.a4(QE),.a5(QF),.a6(QG),.a7(QF),.sel(sel_sign));mux81 mymux81(.sel(sel_sign),.a(QA),.b(QB),.c(QC),.d(QD),.e(QE),.f(QF),.g(QG),.h(QH),.out(org_data));
第9页,共11页 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
decode3_8 decode(.org(org_data),.a(a),.b(b),.c(c),.d(d),.e(e),.f(f),.g(g),.dp(dp));
endmodule
7. 写完了全部代码后,就是器件选择,分配引脚,下载程序,最后在实验箱上进行实验。
在实验的验证过程中,用到了DDS函数信号发生器,从其TTL输出端输出各种不同频率的方波信号,接入接简易频率计的被测信号输入端,在八个数码管上显示出相应的测量结果。
四.结果分析
在上述实验过程中,我们选取了若干组不同的TTL输出进行测量,发现当被测信号的频率不小于1HZ时,简易频率计可以精确的测出被测信号的频率。但是,当被测信号小于1HZ时,显示的测量结果在0和1之间跳动,不稳定。分析简易频率计的结构可知,在如下图所示波形关系中,当被测信号的频率小于1HZ时,在秒级门控信号的一个周期内,计数器要么能计数一次,要么计数零次,因而不能准确的测出被测信号的频率。
五.经验总结
1.本实验中的频率计由于其在结构上存在缺限,因而在测量小于1HZ的信号时,会有较大的误码差,在测量频率大于1HZ信号时,也可能存1HZ误差,其原因在于如果在一个秒级门控信号的周期内,被测信号的上升沿的个数正好
第10页,共11页 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
和其周数相同,则测量结果是准确的,如果上升沿的个数比周期数多一,则测量结果比实际值大一。
2.提高测量精度的另一个关键地方在所产生的秒级门控信号的精度。只有所产生的秒级门控信号的低电平时间长度为严格的一秒时,测量结果才会更精确。由于实验箱上所使用的晶振不是严格等于24MHZ,因而可用示波器测出晶振的准确频率后,再在parameter
N=24000000;语句中改变N的值。也可以在实验中逐渐调整N的值,直到测量结果最精确为止。最终我们的实验中,N的值取的是24000351。
3.对于高位清零功能的加入,正是仪器设计人性化的一个体现。如果没有这个功能,再未显示数据的数码管也一直处于工作状态,一则是对资源的乱费,二则是会减少器件的使用寿命。
第11页,共11页
第三篇:数字频率计设计
数字频率计设计 1.设计任务
设计一简易数字频率计,其基本要求是:
1)测量频率范围1Hz~10Hz,量程分为4档,即×1,×10,×100,×1000。2)频率测量准确度fx2103.fx3)被测信号可以是下弦波、三角波和方波。4)显示方式为4位十进制数显示。5)使用EWB进行仿真。2.设计原理及方案
频率的定义是单位时间(1s)内周期信号的变化次数。若在一定时间间隔T内测得周期信号的重复变化次数为N,则其频率为
f=N/T 据此,设计方案框图如图1所示。
图1 数字频率计组成框图
其基本原理是,被测信号ux首先经整形电路变成计数器所要求的脉冲信号,频率与被测信号的频率fx相同。时钟电路产生时间基准信号,分频后控制计数与保持状态。当其高电平时,计数器计数;低电平时,计数器处于保持状态,数据送入锁存器进行锁存显示。然后对计数器清零,准备下一次计数。其波形逻辑关系图如图2所示。3.基本电路设计 1)整形电路
整形电路是将待测信号整形变成计数器所要求的脉冲信号。电路形式采用由555定时器所构成的施密特触发器,电路如图XXX所示。若待测信号为三角波,输入整形电路,设置分析为瞬态分析,启动电路,其输入、输出波形如图XXX所示。可见输出为方波,二者频率相同。
2)时钟产生电路
时钟信号是控制计数器计数的标准时间信号,其精度很大程度上决定了频率计的频率测量精度。当要求频率测量精度较高时,应使用晶体振荡器通过分频获得。在此频率计中,时钟信号采用555定时器构成的多谐振荡器电路,产生频率为1Kz的信号,然后再进行分频。多谐振荡器电路如图XXX所示。由555定时器构成多谐振荡器的周期计算公式为
XXXXXXXXXX 取XXXXXXXXXXXXXX,则得到振荡频率为1Kz的负脉冲,其振荡波形如图XXX所示。3)分频器电路
采用计数器构成分频电路,对1Kz的时钟脉冲进行分频,取得不同量程所需要的时间基准信号,实现量程控制。1Kz的时钟脉冲,对其进行3次10分频,每个10分频器的输出信号频率分别为100Hz,10Hz,1Hz三种时间基准信号。对应于以1Kz,100Hz,10Hz,1Hz的信号作为时间基准信号时,相应的量程为×1000,×100,×10,×1。
构成10分频带电路是采用十进制计数器74LS160实现的。具体电路及其输入、输出波形如图XXX所示。
(1)T触发器
T触发器电路是用来将分频带器输出阻抗的窄脉冲整形为方波,因为计数器需要用方波来控制其计数/保持状态的切换。整形后方波的频率为频器输出信号频率的一半,则对应于1Kz,100Kz,10Kz,1Hz的信号,T触发器输出信号的高电平持续时间分别为0.001s,0.01s,0.1s,1s。T触发器采用JK触发器7473为实现,其电路连接图及其输入、输出波形如图XXX所示。
(2)单稳触发器
单稳触发器用于产生一窄脉冲,以触发锁存器,使计数器在计数完毕后更新锁存器数值。单稳触发器电路采用555定时器实现,为了保证系统正常工作,单稳电路产生的脉冲宽度不能大于该量程分频带器输出信号的周期。例如,计数器的最大量程是×1000,对应分频带器输出的时间基准信号频率为1000Hz,周期是1ms。取单稳电路输出脉冲宽度TW=0.1ms。根据TW=1.1RC,取C=0.01Uf,则R=9.8KΩ,取标称什为10KΩ。单稳触发器输入信号是T触发器输出信号经Rd、Cd组成的微分器将方波变成尖脉冲后加到555定时器的触发器。电路图及输入、输出波形如图XXX所示。
(3)延迟反相器
延时反相器的功能是为了得到一个对计数器清零的信号。由于计数器清零是低电平有效,而且计数器清零必须在单稳触发信号之后,故延迟反相器是在上述单稳电路之后,再加一级单稳触发电路,且在其输出端加反相器输出。其输入、输出波形如图XXX所示。(4)计数器
计数器在T触发器输出信号的控制下,对经过整形的待测信号进行脉冲计数,所得结果乘以量程即为待测信号频率。
根据精度要求,采用4个十进制计数器级联,构成N=1000计数器。十进制计数器仍采用74LS160实现。其电路图如图XXX所示。其中计数器的清零信号由延迟反相器提供,控制信号由T触发器提供,计数器输出结果送入锁存器。
(5)锁存器和显示
计数器的结果进入锁存器锁存,4个七段数码管显示测试信号的频率。锁存器使用了两片8D集成触发器实现,其控制信号来自于延迟反相器,具体电路如图XXX所示。
(6)数字频率计的总体电路
图XXX是数字频率计的总体电路图。
4.测试
搭建好以上电路以后,进行调试,首先分模块进行调试,待每一个模块调试正确后,不规则进行联调。因为整个电路的分析是瞬态分析,故总体电路的分析需要较长时间。以上仅仅是学生所做综合电路分析与设计的例子,由于EWB5.12教学版本库元件的限制,有些电路与系统无法进行全部电路的仿真(例如收发信通信系统等),但有些局部电路也可以进行仿真,从而节省对这部分电路设计化费的时间。
第四篇:简易数字频率计设计报告
EDA技术基础 简易数字频率计 必做实验
电子信息科学与技术
物电学院
2011-06-24 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
简易数字频率计
一.实验要求
用Verilog硬件描述语言设计一个时序逻辑电路,能够对输入的TTL信号进行1s时长计数,将计数结果在数码管上显示,让该电路循环运行,则数码管显示的就是输入信号的频率。
用标准DDS信号发生器输入TTL信号,测试信号的频率与DDS输出设定的频率比较,分析误差以及误差产生的原因。
显示效果好,无闪烁,高位零不显示。
二.方案原理图
总体框图:
三、主要部分原理说明及实验步骤
根据原理图,先把计数器模块、显示模块、扫描模块分别做出。对于计数器模块因为要实现00000000~99999999的计数器,所以要用32bit,即要用
32第2页,共8页 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
个D触发器。从而要用8个数码管进行循环扫描显示。对于1HZ的精密脉冲在低电平时,一方面和被测脉冲通过或门,当被测脉冲为高电平时门电路开启,另一方面通过一个非门把计数器的清零端置1,计数器正常工作开始计数。高电平时对计数器清零的同时,把测得的数据送入BUFFER中进行显示锁存。数码管的扫描时钟由外部提供。在此基础上把前面的0清除。
1、我在该设计中使用了一个或门作为门控电路,当输入时钟clka为低电平时,被测信号clk通过,当输入时钟clka为高电平时,被测信号被阻止。从clka端输入的是一个24M的脉冲,经过1HZ模块处理后生成一秒赫兹信号(如下图)
由这个信号来控制99999999计数器的清零和buffer中数据的更新以及被测信号的通过与阻止
其verilog语言代码如下 module clk_1hz(clk,clked);input clk;output clked;reg clked;reg[31:0]jishu;always @(posedge clk)begin if(jishu==24000000)begin jishu=0;clked=1;end else begin jishu=jishu+1;clked=0;end end endmodule
2、门控电路部分
其verilog语言代码如下
第3页,共8页 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
module mynot(clk_1hz,nclk_1hz);input clk_1hz;output nclk_1hz;assign nclk_1hz=!clk_1hz;endmodule
99999999计数器计数在到达1S的瞬间,1HZ时钟出现上升沿,控制缓存器将此时的计数值锁存起来,然后送出显示。很短一段时间后,1HZ时钟恢复低电平,在这很短的时间内1HZ时钟经非门也完成了计数器的清零,之后计数器又恢复计数状态,进入下一秒的计数。
其verilog语言代码如下 module mynot(clk_1hz,nclk_1hz);input clk_1hz;output nclk_1hz;assign nclk_1hz=!clk_1hz;endmodule
3、计数模块
第4页,共8页 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
99999999计数器是本次实验的关键所在,它的主要功能是:在1hz精密时钟和门控电路的控制下,在1s的时间内,对输入信号进行计数,1s后,由于门控电路的存在,计数器停止计数 其verilog语言代码如下 module cnt99999999(clr,clk,q);input clr,clk;output [31:0]q;reg [31:0]q;always @(posedge clk or negedge clr)begin if(!clr)q[31:0]=0;else if(q[31:0]==31'H99999999)q[31:0]=q[31:0]+32'H66666667;else if(q[27:0]==27'H9999999)q[31:0]=q[31:0]+28'H6666667;else if(q[23:0]==24'H999999)
q[31:0]=q[31:0]+24'H666667;else if(q[19:0]==20'H99999)
q[31:0]=q[31:0]+20'H66667;else if(q[15:0]==16'H9999)
q[31:0]=q[31:0]+16'H6667;else if(q[11:0]==12'H999)
q[31:0]=q[31:0]+12'H667;else if(q[ 7:0]== 8'H99)
q[31:0]=q[31:0]+8'H67;else if(q[ 3:0]== 4'H9)
q[31:0]=q[31:0]+4'H7;else q[31:0]=q[31:0]+1;end endmodule
4、显示数据缓冲buffer的设计
数据缓冲buffer的功能是当用计数器对输入信号计数,这些数据都暂时存在这个里面,每当时钟的上升沿到来的时候,它就向后面的模块输送数据,这样就可以得到相对稳定的显示。
第5页,共8页 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
其verilog语言代码如下
module buff(in,clk,n1,n2,n3,n4,n5,n6,n7,n8);input clk;input [31:0]in;output [3:0]n1,n2,n3,n4,n5,n6,n7,n8;reg [3:0]n1,n2,n3,n4,n5,n6,n7,n8;
always @(posedge clk)begin begin n1=in[3:0];n2=in[7:4];n3=in[11:8];n4=in[15:12];n5=in[19:16];n6=in[23:20];n7=in[27:24];n8=in[31:28];end end endmodule
5、显示部分
由于要用到8个数码管对实验结果进行显示,我们可以设计一个译码模块:
其verilog语言代码如下 module yima(in,a,b,c,d,e,f,g,dp);input
[3:0]in;output a,b,c,d,e,f,g,dp;reg
a,b,c,d,e,f,g,dp;always @(in)begin case(in)
第6页,共8页 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
4'b0000:{dp,g,f,e,d,c,b,a}=8'b00111111;4'b0001:{dp,g,f,e,d,c,b,a}=8'b00000110;4'b0010:{dp,g,f,e,d,c,b,a}=8'b01011011;4'b0011:{dp,g,f,e,d,c,b,a}=8'b01001111;4'b0100:{dp,g,f,e,d,c,b,a}=8'b01100110;4'b0101:{dp,g,f,e,d,c,b,a}=8'b01101101;4'b0110:{dp,g,f,e,d,c,b,a}=8'b01111101;4'b0111:{dp,g,f,e,d,c,b,a}=8'b00000111;4'b1000:{dp,g,f,e,d,c,b,a}=8'b01111111;4'b1001:{dp,g,f,e,d,c,b,a}=8'b01101111;default:{dp,g,f,e,d,c,b,a}=8'b01000000;endcase end endmodule 部分引脚功能的排列如下图所示
数码管的引脚排列 以上5部分就是顶层原理图的主要部分
四、实验总结
1、要用1HZ的精确时钟不能直接接一个外接的信号源,这样的误差太大,只能将一个标准的24M的时钟进行24分频,才能的到相对稳定的时钟信号。
2、数据缓冲部分不能少,如果没有这部分,将得不到想要的结果,数码管上会出现一排乱跳的数字。
3、在整个实验设计过程中,我发现只要弄清楚所需要的几个模块,然后将模块分开来进行生成,设计也并不是想象中的那么难。
第7页,共8页 湖北师范学院电工电子实验教学省级示范中心电子版实验报告
4、在此程序设计中,对各个模块的功能有针对性的设计思路有了一定的提高,对于一个程序的需要哪些功能模块,需要什么样的输入输出,都比以前有了一定的提高。
5、学EDA已经有一学期了,现在对那些原理框图并不陌生了,现在也可以写一些简单的代码。我发现只要我们认真的去学习,虚心的的去请教他人,我们谁都可以把这门课学好。虽然在学习这门课以及做实验的过程中,我们往往会遇到种种困难,但是当实验结果与现象出来的那一刹那,我们就会感受那成功的快乐。
第8页,共8页
第五篇:FPGA抢答器设计报告
Vb开办上海电力学院
课程设计报告
信息工程系
抢答器设计报告
一、设计目的:
本课程的授课对象是电子科学与技术专业本科生,是电子类专业的一门重要的实践课程,是理论与实践相结合的重要环节。
本课程有助于培养学生的数字电路设计方法、掌握模块划分、工程设计思想与电路调试能力,为以后从事各种电路设计、制作与调试工作打下坚实的基础
二、实验器材和工具软件:
PC机一台、QuartusII软件、DE2板。
三、设计内容:
(1)抢答器可容纳四组12位选手,每组设置三个抢答按钮供选手使
用。
(2)电路具有第一抢答信号的鉴别和锁存功能。在主持人将系统复位并发出抢答指令后,蜂鸣器提示抢答开始,时显示器显示初始时间并开始倒计时,若参赛选手按抢答按钮,则该组指示灯亮并用组别显示器显示选手的组别,同时蜂鸣器发出“嘀嘟”的双音频声。此时,电路具备自锁功能,使其它抢答按钮不起作用。
(3)如果无人抢答,计时器倒计时到零,蜂鸣器有抢答失败提示,主持人可以按复位键,开始新一轮的抢答。
(4)设置犯规功能。选手在主持人按开始键之前抢答,则认为犯规,犯规指示灯亮和显示出犯规组号,且蜂鸣器报警,主持人可以终止抢答执行相应惩罚。
(5)抢答器设置抢答时间选择功能。为适应多种抢答需要,系统设有10秒、15秒、20秒和3O秒四种抢答时间选择功能。
四、设计具体步骤:
首先把系统划分为组别判断电路模块groupslct,犯规判别与抢答信号判别电路模块fgqd,分频电路模块fpq1,倒计时控制电路模块djs,显示时间译码电路模块num_7seg模块,组别显示模块showgroup模块这六个模块,各模块设计完成后,用电路原理图方法将各模块连接构成系统。
各模块功能及代码:
1、组别判别模块
(1)功能:可容纳四组12位选手,每组设置三个抢答按钮供选手使用。若参赛选手按抢答按钮,则输出选手的组别。此时,电路具
signal rst : std_logic;begin
h<=“0000” when(a=“000” and b=“000” and c=“000” and d=“000”)else
“0001” when(a/=“000” and b=“000” and c=“000” and d=“000”)else
“0010” when(a=“000” and b/=“000” and c=“000” and d=“000”)else
“0100” when(a=“000” and b=“000” and c/=“000” and d=“000”)else
“1000” when(a=“000” and b=“000” and c=“000” and d/=“000”)else
“0000”;process
begin
wait on clock until rising_edge(clock);
if clr='1' then
rst<='1';
g<=“0000”;
end if;
if h/=“0000” then
if rst='1' then
g<=h;
rst<='0';
end if;
end if;
end process;
end behave_groupslct;
2、犯规判别与抢答信号判别模块
(1)功能:若参赛选手在主持人按开始键之后按抢答按钮,则使该组指示灯亮并输出选手的组别,同时蜂鸣器发出响声。
选手在主持人按开始键之前抢答,则认为犯规,犯规指示灯亮并输出犯规组号,且蜂鸣器报警。
(2)原理:c[3..0]接组别判别模块的g[3..0],即此时c为按键组别的信息。go接主持人的“开始”按键。由于无论是在正常情况还是犯规情况下按下按键,都必须显示按键的组别且蜂鸣器响,所以将c的值给hex以输出按键组别,且在有按键按下(c/=“0000”)时输出fm为‘1’,否则为‘0’。若在开始之前有按键按下时,即go='0'且c/=“0000”,输出ledfg为‘1’,否则为‘0’。若在开始之后有按键按下,将c的值给led,使该组指示灯亮,开始之前led输出“0000”。
(3)程序代码:
library ieee;
use ieee.std_logic_1164.all;
entity fgqd is port(c:in std_logic_vector(3 downto 0);
go:in std_logic;
hex:out std_logic_vector(3 downto 0);
led:out std_logic_vector(3 downto 0);
ledfg,fm:out std_logic);
end fgqd;
architecture behave_fgqd of fgqd is begin);end djs;
architecture behave_djs of djs is begin
process(clock,aclr,s)
begin
if(aclr='1')then
if(s=“00”)then
q<=“01010”;
elsif(s=“01”)then
q<=“01111”;
elsif(s=“10”)then
q<=“10100”;
else
q<=“11110”;
end if;
else
if rising_edge(clock)then
if en='1' then
q<=q-1;
if(q=“00000” and grpsl=“0000”)then
time0<='1';
else
time0<='0';
end if;
end if;
end if;
end if;
end process;end behave_djs;
4、分频器模块
(1)功能:实现50MHz—1Hz的分频,为倒计时模块提供时钟。
(2)程序代码
library ieee;
use ieee.std_logic_1164.all;
entity fpq1 is port(clkin :in std_logic;
clkout:out std_logic);end fpq1;
architecture behave_fpq1 of fpq1 is constant N: Integer:=24999999;signal Counter:Integer RANGE 0 TO N;signal Clk: Std_Logic;begin
process(clkin)
begin
if rising_edge(clkin)then--每计到N个(0~n-1)上升沿,输出信号翻转一次
if Counter=N then
Counter<=0;
Clk<=NOT Clk;
else
Counter<= Counter+1;
end if;
end if;
end process;clkout<= Clk;end behave_fpq1;
5、时间显示译码器
(1)功能:将时间信息在7段数码管上显示。
(2)程序代码
library ieee;
use ieee.std_logic_1164.all;
entity num_7seg is port(c:in std_logic_vector(4 downto 0);
hex:out std_logic_vector(13 downto 0));
end num_7seg;
architecture behave_num_7seg of num_7seg is begin
with c(4 downto 0)select
hex<= “10000001000000” when “00000” ,--“0”
“10000001111001” when “00001” ,--“1”
“10000000100100” when “00010” ,--“2”
“10000000110000” when “00011” ,--“3”
“10000000011001” when “00100” ,--“4”
“10000000010010” when “00101” ,--“5”
“10000000000010” when “00110” ,--“6”
“10000001111000” when “00111” ,--“7”
“10000000000000” when “01000” ,--“8”
“10000000010000” when “01001” ,--“9”
“11110011000000” when “01010” ,--“10”
“11110011111001” when “01011” ,--“11”
“11110010100100” when “01100” ,--“12”
“11110010110000” when “01101” ,--“13”
“11110010011001” when “01110” ,--“14”
“11110010010010” when “01111” ,--“15”
“11110010000010” when “10000” ,--“16”
“11110011111000” when “10001” ,--“17”
“11110010000000” when “10010” ,--“18”
“11110010010000” when “10011” ,--“19”
“01001001000000” when “10100” ,--“20”
“01001001111001” when “10101” ,--“21”
“01001000100100” when “10110” ,--“22”
“01001000110000” when “10111” ,--“23”
“01001000011001” when “11000” ,--“24”
“01001000010010” when “11001” ,--“25”
“01001000000010” when “11010” ,--“26”
“01001001111000” when “11011” ,--“27”
来。然后就是将选出的组别锁存。将按下按键的组别赋给一内部信号“h”(没有按键按下时h=“0000”),当复位键按下时(clr=‘1’)输出g=“0000”并且将另一内部信号rst置1。当复位后(rst=‘1’)有按键按下时将h的值给输出信号g,并且将标志信号rst清零。这样就实现最快按键组别锁存功能。
六、心得体会
通过此次设计,我掌握了数字电路的设计方法,尤其是模块划分、工程设计思想与电路调试能力,都有了一定的提高。为以后从事各种电路设计、制作与调试工作打下坚实的基础。