赞
踩
当设计文件加载到目标器件后,拨动开关的K1,使其置为高电平,从输入输出观测模块的输入端输入一个频率大于1Hz的时钟信号,这时在数码管上显示这个时钟信号的频率值。如果使拨动开关置为低电平,数码管上显示的值为系统上的数字信号源的时钟频率。改变数字信号源的时钟,看显示的值是否与标值一致(数码管显示2s刷新一次)。
测频实现框图如下图所示
所以我们可以通过设计六个模块,最终在一个原理图文件中连接,实现测频
文件名称 | 完成功能 |
---|---|
CLKOUT.VHD | 产生1Hz的闸门信号和1KHz的显示扫描信号 |
MUX.VHD | 被测信号源选择模块 |
TELTCL.VHD | 在时钟的作用下生成测频的控制信号 |
CNT10.VHD | 十进制计数器,在设计中使用8个来进行计数 |
SEG32B.VHD | 32位的锁存器,在锁存器控制信号的作用下,将计数的值锁存 |
DISPLAY.VHD | 显示译码,将锁存的数据显示出来 |
控制信号时序关系如下图所示
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY CLKOUT IS PORT(CLK:IN STD_LOGIC; CLKOUT1:OUT STD_LOGIC; CLKOUT1K:OUT STD_LOGIC); END CLKOUT; ARCHITECTURE BHV OF CLKOUT IS BEGIN PROCESS(CLK) VARIABLE COUNT1:STD_LOGIC_VECTOR(25 DOWNTO 0); VARIABLE COUNT2:STD_LOGIC_VECTOR(15 DOWNTO 0); VARIABLE Q1:STD_LOGIC; VARIABLE Q2:STD_LOGIC; BEGIN IF CLK'EVENT AND CLK = '1' THEN COUNT1:=COUNT1+1; --分频计数器1 COUNT2:=COUNT2+1; --分频计数器2 --这部分将50MHz频率分频得到1Hz方波 IF COUNT1="01011111010111100001000000" THEN --0.5s --仿真时可以改成这条,因为电脑屏幕显示有限"00000000000000000000000010" Q1:='1'; ELSIF COUNT1="10111110101111000010000000" THEN --1s --仿真时可以改成这条,因为电脑屏幕显示有限"00000000000000000000000100" Q1:='0'; COUNT1:="00000000000000000000000000"; END IF; --这部分将50MHz频率分频得到1kHz方波 IF COUNT2="0110000110101000" THEN --0.5ms --同上"0000000000000001" Q2:='1'; ELSIF COUNT2="110000110101000" THEN --1.0ms --同上"0000000000000010" Q2:='0'; COUNT2:="0000000000000000"; END IF; CLKOUT1 <=Q1; --输出1Hz方波 CLKOUT1K<=Q2; --输出1kHz方波 END IF; END PROCESS; END BHV;
仿真结果如下图所示
通过修改分频计数器的值可以得到不同频率的方波
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY MUX IS PORT( SEL:IN STD_LOGIC; CLKIN1:IN STD_LOGIC; CLKIN2:IN STD_LOGIC; CLKOUT:OUT STD_LOGIC); END MUX; ARCHITECTURE BHV OF MUX IS BEGIN PROCESS(SEL,CLKIN1,CLKIN2) VARIABLE FLAG:STD_LOGIC; BEGIN IF SEL = '1'THEN FLAG := '1'; ELSIF SEL = '0'THEN FLAG := '0'; END IF; IF FLAG = '1' THEN --当开关拨动置1时 CLKOUT<=CLKIN1; --输出波形1 ELSIF FLAG = '0' THEN --当开关拨动置1时 CLKOUT<=CLKIN2; --输出波形2 END IF; END PROCESS; END BHV;
仿真结果仿真结果如下图所示
开关置1时,输出CLKIN1的波形,开关置0时,输出CLKIN2的波形
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY TELTCL IS PORT(CLK:IN STD_LOGIC; EN:OUT STD_LOGIC; CLR:OUT STD_LOGIC; Q:OUT STD_LOGIC_VECTOR(3 DOWNTO 0); LOAD:OUT STD_LOGIC); END TELTCL; ARCHITECTURE BHV OF TELTCL IS BEGIN PROCESS(CLK) VARIABLE T1:STD_LOGIC_VECTOR(1 DOWNTO 0); VARIABLE T2:STD_LOGIC_VECTOR(1 DOWNTO 0); VARIABLE TT:STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE CEN:STD_LOGIC; VARIABLE CCLR:STD_LOGIC; VARIABLE CLOAD:STD_LOGIC; BEGIN IF CLK'EVENT AND CLK = '0' THEN T1 := T1+1; ELSIF CLK'EVENT AND CLK = '1' THEN T2 := T2+1; END IF; --允许计数控制信号 IF (T1 = "01") OR (T1 = "11") THEN CEN:='1'; ELSIF (T1 = "00") OR (T1 = "10") THEN CEN:='0'; END IF; --清零控制信号 TT := T1&T2; IF TT = ("0001" OR "1011") THEN --"0000" "1010" CCLR := '1'; ELSE CCLR := '0'; END IF; --锁存控制信号 IF CEN = '1' THEN CLOAD := '0'; ELSIF CEN = '0' THEN CLOAD := '1'; END IF; --最终赋值输出 EN<=CEN; CLR<=CCLR; LOAD<=CLOAD; Q<=TT; END PROCESS; END BHV;
仿真结果仿真结果如下图所示
完美波形
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY CNT10 IS PORT(CLK:IN STD_LOGIC; EN:IN STD_LOGIC; CLR:IN STD_LOGIC; LOAD:OUT STD_LOGIC; Q:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END CNT10; ARCHITECTURE BHV OF CNT10 IS BEGIN PROCESS(CLK,EN,CLK) VARIABLE COUNT:STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE CLOAD:STD_LOGIC; BEGIN IF EN = '1' THEN IF CLK'EVENT AND CLK = '1'THEN COUNT := COUNT + 1; --每个时钟上升沿计数器+1 IF COUNT = "1010" THEN --当计数器值为10时清零 COUNT := "0000"; CLOAD := '1'; --LOAD输出一个高电平 ELSE CLOAD := '0'; END IF; IF CLR = '1' THEN --当清零控制信号为高电平时清零 COUNT := "0000"; END IF; END IF; LOAD <= CLOAD; Q <= COUNT; END IF; END PROCESS; END BHV;
仿真结果如图所示
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY SEG32B IS PORT(CLK:IN STD_LOGIC; H1:IN STD_LOGIC_VECTOR(3 DOWNTO 0); H2:IN STD_LOGIC_VECTOR(3 DOWNTO 0); H3:IN STD_LOGIC_VECTOR(3 DOWNTO 0); H4:IN STD_LOGIC_VECTOR(3 DOWNTO 0); H5:IN STD_LOGIC_VECTOR(3 DOWNTO 0); H6:IN STD_LOGIC_VECTOR(3 DOWNTO 0); H7:IN STD_LOGIC_VECTOR(3 DOWNTO 0); H8:IN STD_LOGIC_VECTOR(3 DOWNTO 0); X:OUT STD_LOGIC_VECTOR(31 DOWNTO 0)); END SEG32B; ARCHITECTURE BHV OF SEG32B IS BEGIN PROCESS(CLK) VARIABLE T1:STD_LOGIC_VECTOR(1 DOWNTO 0); VARIABLE T2:STD_LOGIC_VECTOR(1 DOWNTO 0); VARIABLE TT:STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE CX:STD_LOGIC_VECTOR(31 DOWNTO 0); BEGIN --因为我们需要高电平这一段,所以需要判断上升沿和下降沿 IF CLK'EVENT AND CLK = '0' THEN T1 := T1+1; ELSIF CLK'EVENT AND CLK = '1' THEN T2 := T2+1; END IF; TT := T1&T2; --判断是否是高电平期间 IF TT = ("0001" OR "1011" OR "0000" OR "1010") THEN CX:=CX; --高电平锁存 ELSE CX:=H8&H7&H6&H5&H4&H3&H2&H1; --低电平获取输入值 END IF; X <= CX; END PROCESS; END BHV;
仿真结果如图所示
高电平期间锁存,低电平期间获取值
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY DISPLAY IS PORT(CLK:IN STD_LOGIC; P:IN STD_LOGIC_VECTOR(31 DOWNTO 0); SEGS7:OUT STD_LOGIC_VECTOR(7 DOWNTO 0); SEL:OUT STD_LOGIC_VECTOR(2 DOWNTO 0)); END DISPLAY; ARCHITECTURE BHV OF DISPLAY IS BEGIN PROCESS(CLK) VARIABLE QT:STD_LOGIC_VECTOR(31 DOWNTO 0); VARIABLE Q1:STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE Q2:STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE Q3:STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE Q4:STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE Q5:STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE Q6:STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE Q7:STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE Q8:STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE K:STD_LOGIC_VECTOR(3 DOWNTO 0); VARIABLE COUNT:STD_LOGIC_VECTOR(2 DOWNTO 0); BEGIN IF CLK'EVENT AND CLK = '1' THEN COUNT := COUNT + 1; QT:=P; Q8:=QT(31 DOWNTO 28);Q7:=QT(27 DOWNTO 24); Q6:=QT(23 DOWNTO 20);Q5:=QT(19 DOWNTO 16); Q4:=QT(15 DOWNTO 12);Q3:=QT(11 DOWNTO 8); Q2:=QT(7 DOWNTO 4);Q1:=QT(3 DOWNTO 0); SEL <= COUNT; CASE COUNT IS WHEN "000" => K := Q8; WHEN "001" => K := Q7; WHEN "010" => K := Q6; WHEN "011" => K := Q5; WHEN "100" => K := Q4; WHEN "101" => K := Q3; WHEN "110" => K := Q2; WHEN "111" => K := Q1; WHEN OTHERS =>NULL; END CASE; CASE K IS WHEN "0000" =>SEGS7 <= "00111111"; --0 WHEN "0001" =>SEGS7 <= "00000110"; --1 WHEN "0010" =>SEGS7 <= "01011011"; --2 WHEN "0011" =>SEGS7 <= "01001111"; --3 WHEN "0100" =>SEGS7 <= "01100110"; --4 WHEN "0101" =>SEGS7 <= "01101101"; --5 WHEN "0110" =>SEGS7 <= "01111101"; --6 WHEN "0111" =>SEGS7 <= "00000111"; --7 WHEN "1000" =>SEGS7 <= "01111111"; --8 WHEN "1001" =>SEGS7 <= "01101111"; --9 WHEN "1010" =>SEGS7 <= "01110111"; --A WHEN "1011" =>SEGS7 <= "01111100"; --B WHEN "1100" =>SEGS7 <= "00111001"; --C WHEN "1101" =>SEGS7 <= "01011110"; --D WHEN "1110" =>SEGS7 <= "01111001"; --E WHEN "1111" =>SEGS7 <= "01110001"; --F WHEN OTHERS => SEGS7 <= "00000000"; END CASE; END IF; END PROCESS; END BHV;
仿真结果如图所示
数码管位选循环点亮八个数码管,达到视觉暂留,相当于八个数码管同时显示;
参照教程完成六个VHD文件的转换成模块符号文件再将各个模块按下图所示方式连接
编译后没有错误即可,新建仿真页,参数仿照下图设置
开始仿真
由于条件有限,没有设备进行调试,所以仿真设置的分频计数器较小。这里只要数码管能正常显示和移位即表明程序实验成功,若烧录与FPAG芯片中些许问题可以对某些数据调参,以达到最优效果。如果还有其他问题欢迎私聊我。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。