第7章数字系统设计实例.ppt
170页第第7 7章章 数字系统设计实例数字系统设计实例 第第7章章 数字系统设计实例数字系统设计实例 7.1 半整数分频器的设计半整数分频器的设计 7.2 音乐发生器音乐发生器 7.3 2FSK/2PSK信号产生器信号产生器7.4 实用多功能电子表实用多功能电子表 7.5 交通灯控制器交通灯控制器 7.6 数字频率计数字频率计 习题习题 第第7 7章章 数字系统设计实例数字系统设计实例 7.1 半整数分频器的设计半整数分频器的设计 在数字系统设计中,分频器是一种基本电路分频器的实现非常简单,可采用标准的计数器,也可采用可编程逻辑器件来实现一个整数分频器分频器通常用来对某个给定频率进行分频,得到所需的频率在某些场合下,用户所需要的频率与频率时钟源不是整数倍关系,此时可采用小数分频器进行分频第第7 7章章 数字系统设计实例数字系统设计实例 7.1.1 小数分频的基本原理 设有一个5 MHz的时钟源,但电路中需要产生一个2 MHz的时钟信号,由于分频比为2.5,因此整数分频器将不能胜任 采用可编程逻辑器件实现分频系数为2.5的分频器,可采用以下方法:设计一个模3的计数器,再设计一个扣除脉冲电路,加在模3计数器输出之后,每来两个脉冲就扣除一个脉冲(实际上是使被扣除的脉冲变成很窄的脉冲,可由异或门实现),就可以得到分频系数为2.5的小数分频器。
采用类似方法,可以设计分频系数为任意半整数的分频器第第7 7章章 数字系统设计实例数字系统设计实例 小数分频的基本原理为脉冲吞吐计数法:设计两个不同分频比的整数分频器,通过控制单位时间内两种分频比出现的不同次数,从而获得所需的小数分频值例如设计一个分频系数为10.1的分频器,可以将分频器设计成9次10分频,1次11分频,这样总的分频值为 (9×10+1×11)/(9+1) =10.1 第第7 7章章 数字系统设计实例数字系统设计实例 从这种实现方法的特点可以看出,由于分频器的分频值在不断改变,因此分频后得到的信号抖动较大 当分频系数为N-0.5(N为整数)时,可控制扣除脉冲的时间,使输出为一个稳定的脉冲频率,而不是一次N分频,一次N-1分频第第7 7章章 数字系统设计实例数字系统设计实例 7.1.2 电路组成 设需要设计一个分频系数为N-0.5的分频器,其电路可由一个模N计数器、一个二分频器和一个异或门组成,如图7-1所示。
在实现时,模N计数器可设计成带预置的计数器,这样就可以实现任意分频系数为N-0.5的分频器 第第7 7章章 数字系统设计实例数字系统设计实例 图7-1 通用半整数分频器第第7 7章章 数字系统设计实例数字系统设计实例 7.1.3 VHDL程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY deccount IS PORT ( inclk: IN STD_LOGIC;--时钟源 preset: IN STD_LOGIC_VECTOR(3 DOWNTO 0); --预置分频值N第第7 7章章 数字系统设计实例数字系统设计实例 outclk1: OUT STD_LOGIC; outclk2: BUFFER STD_LOGIC--输出时钟 );END deccount; ARCHITECTURE deccount_arch OF deccount ISSIGNAL clk, divide2: STD_LOGIC;SIGNAL count: STD_LOGIC_VECTOR(3 DOWNTO 0);第第7 7章章 数字系统设计实例数字系统设计实例 BEGINclk<=inclk XOR divide2; --inclk与divide2异或后作为模N计数器的时钟outclk1<=inclk;PROCESS(clk)BEGIN IF(clk'event AND clk='1') THEN IF(count="0000") THEN第第7 7章章 数字系统设计实例数字系统设计实例 count<=preset-1;--置整数分频值N outclk2<='1'; ELSE count<=count-1;--模N计数器减法计数 outclk2<='0'; END IF; END IF;END PROCESS; PROCESS(outclk2)第第7 7章章 数字系统设计实例数字系统设计实例 BEGIN IF(outclk2'event AND outclk2='1') THEN divide2<=NOT divide2;--输出时钟二分频 END IF;END PROCESS;END deccount_arch;第第7 7章章 数字系统设计实例数字系统设计实例 图7-2 半整数分频器外部接口第第7 7章章 数字系统设计实例数字系统设计实例 以上程序实现对时钟源inclk进行分频系数为N-0.5的分频,得到输出频率outclk2。
preset输入端口是预置分频值N,本例中preset设为4位宽的位矢量,也即分频系数为16以内的半整数值若分频系数大于16,需同时增大preset和count的位宽,两者的位宽则要求始终一致本设计的外部接口如图7-2所示,程序中设置outclk1是为了方便观察输入信号的波形,以与输出信号outclk2比较第第7 7章章 数字系统设计实例数字系统设计实例 7.1.4 仿真结果 上述半整数分频器的仿真波形如图7-3所示第第7 7章章 数字系统设计实例数字系统设计实例 图7-3 半整数分频器仿真波形图 第第7 7章章 数字系统设计实例数字系统设计实例 7.1.5 下载验证 锁定引脚时将inclk连至CLK1,preset连至K0~K3,outclk1连至TESTOUT1(测试1脚),outclk2连至TESTOUT2(测试2脚),综合适配后将配置数据下载入EDA实验平台(技术资料详见附录)的FPGA中(有关CLK1等引脚在FPGA芯片引脚中的序号, 请参见附录的附图1),通过改变K0~K3状态观察测试1脚和测试2脚上的波形,测试结果与仿真结果一致。
第第7 7章章 数字系统设计实例数字系统设计实例 7.2 音音 乐乐 发发 生生 器器 本设计利用可编程逻辑器件配以一个小扬声器设计了一个音乐发生器,其结构如图7-4所示本例产生的音乐选自“梁祝”片段第第7 7章章 数字系统设计实例数字系统设计实例 图7-4 音乐产生器原理框图第第7 7章章 数字系统设计实例数字系统设计实例 7.2.1 音名与频率的关系 音乐的十二平均率规定:每两个八度音(如简谱中的中音1与高音1)之间的频率相差一倍在两个八度音之间,又可分为十二个半音,每两个半音的频率比为另外,音名A(简谱中的低音6)的频率为440 Hz,音名B到C之间、E到F之间为半音,其余为全音由此可以计算出简谱中从低音1至高音1之间每个音名的频率如表7-1所示第第7 7章章 数字系统设计实例数字系统设计实例 表7-1 简谱中的音名与频率的关系音名频率/Hz音名频率/Hz音名频率/Hz低音1261.63中音1523.25高音11046.50低音2293.67中音2587.33高音21174.66低音3329.63中音3659.25高音31318.51低音4349.23中音4698.46高音41396.92低音5391.99中音5783.99高音51567.98低音6440中音6880高音61760低音7493.88中音7987.76高音71975.52第第7 7章章 数字系统设计实例数字系统设计实例 由于音阶频率多为非整数,而分频系数又不能为小数,故必须将计算得到的分频数四舍五入取整。
若基准频率过低,则由于分频系数过小,四舍五入取整后的误差较大若基准频率过高,虽然误码差变小,但分频结构将变大实际的设计应综合考虑两方面的因素,在尽量减小频率误差的前提下取合适的基准频率本例中选取4 MHz的基准频率若无4 MHz的时钟频率,则可以先分频得到4 MHz或换一个新的基准频率实际上,只要各个音名间的相对频率关系不变,C作1与D作1演奏出的音乐听起来都不会“走调”第第7 7章章 数字系统设计实例数字系统设计实例 本例需要演奏的是“梁祝”片段,此片段内各音阶频率及相应的分频比如表7-2所示为了减小输出的偶次谐波分量,最后输出到扬声器的波形应为对称方波,因此在到达扬声器之前,有一个二分频的分频器表7-2中的分频比就是从4 MHz频率二分频得到的2 MHz频率基础上计算得出的第第7 7章章 数字系统设计实例数字系统设计实例 表7-2 各音阶频率对应的分频值 音名分频系数初始值音名分频系数初始值低音360672124中音234054786低音551023089中音330345157低音645453646中音525515640低音740504141中音622735918中音138224369高音119116280第第7 7章章 数字系统设计实例数字系统设计实例 由于最大的分频系数为6067,故采用13位二进制计数器已能满足分频要求。
在表7-2中,除给出了分频比以外,还给出了对应于各个音阶频率时计数器不同的初始值对于不同的分频系数,只要加载不同的初始值即可采用加载初始值而不是将分频输出译码反馈,可以有效地减少本设计占用可编程逻辑器件的资源,这也是同步计数器的一个常用设计技巧 对于乐曲中的休止符,只要将分频系数设为0,即初始值为213-1=8191即可,此时扬声器将不会发声第第7 7章章 数字系统设计实例数字系统设计实例 7.2.2 音长的控制 本例演奏的“梁祝”片段,最小的节拍为1/4拍将1拍的时长定为1秒,则只需要再提供一个4 Hz的时钟频率即可产生1/4拍的时长演奏的时间控制通过记谱来完成,对于占用时间较长的节拍(一定是1/4拍的整数倍),如2/4拍,只需将该音名连续记录两次即可 本例要求演奏时能循环进行,因此需另外设置一个时长计数器,当乐曲演奏完成时,保证能自动从头开始演奏第第7 7章章 数字系统设计实例数字系统设计实例 7.2.3 演奏时音名的动态显示 如果有必要,可以通过一个数码管或LED来显示乐曲演奏时对应的音符。
如用三个数码管,分别显示本例中的高、中、低音名,就可实现演奏的动态显示,且十分直观本设计通过三个数码管来动态显示演奏时的音名,其中HIGH显示为高音区音阶(仅高音1),MED[2..0]显示的是中音区音阶(中音6, 5, 3, 2, 1),LOW[2..0]显示的是低音区音阶(低音7, 6, 5, 3)数码管显示的七段译码电路在此不作专门讨论需要说明的是,七段译码电路输入为4位,而将HIGH、MED、LOW用作输入时,不足4位的高位均为低电平“0”第第7 7章章 数字系统设计实例数字系统设计实例 图7-5 音乐产生器外部接口第第7 7章章 数字系统设计实例数字系统设计实例 7.2.4 VHDL程序 本设计的外部接口如图7-5所示,程序中定义了一个5位宽的zero[4..0],这是由于实验平台上连向数码管的引脚在不赋值的情况下为高电平,这将导致显示音名错误,设置zero[4..0]就是要将没用到的引脚(高音的高3位、中音的高1位和低音的高1位)赋一个低电平,从而避免显示错误第第7 7章章 数字系统设计实例数字系统设计实例 LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY song IS PORT( clk_4MHz,clk_4Hz: IN STD_LOGIC; --预置计数器和乐谱产生器的时钟第第7 7章章 数字系统设计实例数字系统设计实例 digit: BUFFER STD_LOGIC_VECTOR(6 DOWNTO 0); --高、中、低音数码管指示 zero:OUT STD_LOGIC_VECTOR(4 DOWNTO 0); --用于数码管高位置低 speaker: out STD_LOGIC --扬声器 );END song;ARCHITECTURE song_arch OF song IS第第7 7章章 数字系统设计实例数字系统设计实例 SIGNALdivider,origin:STD_LOGIC_VECTOR(12 DOWNTO 0); --13位计数值和预置值SIGNAL counter:integer range 0 to 140; --7位计数器SIGNAL count:STD_LOGIC_VECTOR(1 DOWNTO 0); --记录1/4拍SIGNAL carrier:STD_LOGIC;BEGINzero<="00000";PROCESS(clk_4MHz)第第7 7章章 数字系统设计实例数字系统设计实例 BEGIN IF(clk_4MHz'event AND clk_4MHz='1') THEN IF(divider="1111111111111") THEN carrier<='1'; divider<=origin; ELSE divider<=divider+'1'; carrier<='0'; END IF; END IF;END PROCESS;第第7 7章章 数字系统设计实例数字系统设计实例 PROCESS(carrier)BEGIN IF(carrier'event AND carrier='1') THEN count<=count+'1';--输出时钟四分频 IF count="00" THEN speaker<='1'; ELSE speaker<='0'; END IF; END IF;END PROCESS;第第7 7章章 数字系统设计实例数字系统设计实例 PROCESS(clk_4Hz)BEGIN IF(clk_4Hz'event AND clk_4Hz='1') THEN IF(counter=140) THEN counter<=0; ELSE counter<=counter+1; END IF; END IF; CASE counter IS第第7 7章章 数字系统设计实例数字系统设计实例 WHEN 0=>digit<="0000011";WHEN 1=>digit<="0000011";WHEN 2=>digit<="0000011";WHEN 3=>digit<="0000011";WHEN 4=>digit<="0000101";WHEN 5=>digit<="0000101";WHEN 6=>digit<="0000101";WHEN 7=>digit<="0000110";WHEN 8=>digit<="0001000";WHEN 9=>digit<="0001000";WHEN 10=>digit<="0001000";WHEN 11=>digit<="0010000";WHEN 12=>digit<="0000110";WHEN 13=>digit<="0001000"; WHEN 14=>digit<="0000101";WHEN 15=>digit<="0000101";WHEN 16=>digit<="0101000";WHEN 17=>digit<="0101000";WHEN 18=>digit<="0101000";WHEN 19=>digit<="1000000";WHEN 20=>digit<="0110000";WHEN 21=>digit<="0101000"; 第第7 7章章 数字系统设计实例数字系统设计实例 WHEN 22=>digit<="0011000";WHEN 23=>digit<="0101000";WHEN 24=>digit<="0010000";WHEN 25=>digit<="0010000";WHEN 26=>digit<="0010000";WHEN 27=>digit<="0010000";WHEN 28=>digit<="0010000";WHEN 29=>digit<="0010000";WHEN 30=>digit<="0010000";WHEN 31=>digit<="0000000";WHEN 32=>digit<="0010000";WHEN 33=>digit<="0010000";WHEN 34=>digit<="0010000";WHEN 35=>digit<="0011000";WHEN 36=>digit<="0000111";WHEN 37=>digit<="0000111";WHEN 38=>digit<="0000110";WHEN 39=>digit<="0000110";WHEN 40=>digit<="0000101";WHEN 41=>digit<="0000101";WHEN 42=>digit<="0000101";WHEN 43=>digit<="0000110";第第7 7章章 数字系统设计实例数字系统设计实例 WHEN 44=>digit<="0001000";WHEN 45=>digit<="0001000";WHEN 46=>digit<="0010000";WHEN 47=>digit<="0010000";WHEN 48=>digit<="0000011";WHEN 49=>digit<="0000011";WHEN 50=>digit<="0001000";WHEN 51=>digit<="0001000";WHEN 52=>digit<="0000110";WHEN 53=>digit<="0000101";WHEN 54=>digit<="0000110";WHEN 55=>digit<="0001000";WHEN 56=>digit<="0000101";WHEN 57=>digit<="0000101";WHEN 58=>digit<="0000101";WHEN 59=>digit<="0000101";WHEN 60=>digit<="0000101";WHEN 61=>digit<="0000101";WHEN 62=>digit<="0000101";WHEN 63=>digit<="0000101"; WHEN 64=>digit<="0011000";WHEN 65=>digit<="0011000";WHEN 66=>digit<="0011000";WHEN 67=>digit<="0101000";WHEN 68=>digit<="0000111";WHEN 69=>digit<="0000111";WHEN 70=>digit<="0010000";WHEN 71=>digit<="0010000"; WHEN 72=>digit<="0000110";WHEN 73=>digit<="0001000";第第7 7章章 数字系统设计实例数字系统设计实例 WHEN 74=>digit<="0000101"; WHEN 75=>digit<="0000101";WHEN 76=>digit<="0000101";WHEN 77=>digit<="0000101";WHEN 78=>digit<="0000101";WHEN 79=>digit<="0000101";WHEN 80=>digit<="0000011";WHEN 81=>digit<="0000101";WHEN 82=>digit<="0000011";WHEN 83=>digit<="0000011";WHEN 84=>digit<="0000101";WHEN 85=>digit<="0000110";WHEN 86=>digit<="0000111";WHEN 87=>digit<="0010000";WHEN 88=>digit<="0000110";WHEN 89=>digit<="0000110";WHEN 90=>digit<="0000110";WHEN 91=>digit<="0000110";WHEN 92=>digit<="0000110";WHEN 93=>digit<="0000110";WHEN 94=>digit<="0000101";WHEN 95=>digit<="0000110";WHEN 96=>digit<="0001000";WHEN 97=>digit<="0001000";WHEN 98=>digit<="0001000";WHEN 99=>digit<="0010000";第第7 7章章 数字系统设计实例数字系统设计实例 WHEN 100=>digit<="0101000";WHEN 101=>digit<="0101000";WHEN 102=>digit<="0101000";WHEN 103=>digit<="0011000";WHEN 104=>digit<="0010000";WHEN 105=>digit<="0010000";WHEN 106=>digit<="0011000";WHEN 107=>digit<="0010000";WHEN 108=>digit<="0001000";WHEN 109=>digit<="0001000";WHEN 110=>digit<="0000110";WHEN 111=>digit<="0000101";WHEN 112=>digit<="0000011";WHEN 113=>digit<="0000011";WHEN 114=>digit<="0000011";WHEN 115=>digit<="0000011";WHEN 116=>digit<="0001000";WHEN 117=>digit<="0001000";WHEN 118=>digit<="0001000";WHEN 119=>digit<="0001000";WHEN 120=>digit<="0000110";WHEN 121=>digit<="0001000";WHEN 122=>digit<="0000110";WHEN 123=>digit<="0000101";WHEN 124=>digit<="0000011";WHEN 125=>digit<="0000101";第第7 7章章 数字系统设计实例数字系统设计实例 WHEN 126=>digit<="0000110";WHEN 127=>digit<="0001000";WHEN 128=>digit<="0000101";WHEN 129=>digit<="0000101";WHEN 130=>digit<="0000101";WHEN 131=>digit<="0000101";WHEN 132=>digit<="0000101";WHEN 133=>digit<="0000101";WHEN 134=>digit<="0000101";WHEN 135=>digit<="0000101";WHEN 136=>digit<="0000000";WHEN 137=>digit<="0000000";WHEN 138=>digit<="0000000";WHEN 139=>digit<="0000000";WHEN others=>digit<="0000000"; END CASE; CASE digit IS第第7 7章章 数字系统设计实例数字系统设计实例 WHEN "0000011"=>origin<="0100001001100";--2124 WHEN "0000101"=>origin<="0110000010001";--3089 WHEN "0000110"=>origin<="0111000111110";--3646 WHEN "0000111"=>origin<="1000000101101";--4141 WHEN "0001000"=>origin<="1000100010001"; --4369 WHEN "0010000"=>origin<="1001010110010"; --4786 WHEN "0011000"=>origin<="1010000100101";--5157 WHEN "0101000"=>origin<="1011000001000";--5640 WHEN "0110000"=>origin<="1011100011110";--5918 WHEN "1000000"=>origin<="1100010001000";--6280 WHEN others=>origin<="1111111111111";--8191第第7 7章章 数字系统设计实例数字系统设计实例 END CASE; END PROCESS;END song_arch;第第7 7章章 数字系统设计实例数字系统设计实例 7.2.5 仿真结果音乐发生器的仿真波形如图7-6所示。
图7-6 音乐发生器仿真波形图 第第7 7章章 数字系统设计实例数字系统设计实例 7.2.6 下载验证 锁定引脚时将clk_4 MHz和clk_4 Hz分别连至CLK1和CLK2,speaker接扬声器,zero[4..2]、digit[6]接一个数码管,zero[1]、digit[5..3]接一个数码管,zero[0]、digit[2..0]接另一个数码管综合适配后将配置数据下载入EDA实验平台(技术资料详见附录)的FPGA中(有关CLK1等引脚在FPGA芯片引脚中的序号,请参见附录的附图1),扬声器短接线短路(接入扬声器),即可听到MIDI音乐第第7 7章章 数字系统设计实例数字系统设计实例 7.3 2FSK/2PSK信号产生器信号产生器 7.3.1 2FSK基本原理 在通信领域中,为了传送信息,一般都将原始的信号进行某种变换变成适合于通信传输的信号形式在数字通信系统中,一般将原始信号(图像、声音等)经过量化编码变成二进制码流,称为基带信号 第第7 7章章 数字系统设计实例数字系统设计实例 但数字基带信号一般不适合于直接传输。
例如,通过公共网络传输数字信号时,由于网络的带宽为4 kHz以下,因此数字信号不能直接在其上传输此时可将数字信号进行调制,FSK即为一种常用的数字调制方式,由FSK调制的波形如图7-7示 第第7 7章章 数字系统设计实例数字系统设计实例 FSK又称移频键控, 它利用载频频率的变化来传递数字信息数字调频信号可以分为相位离散和相位连续两种若两个载频由不同的独立振荡器提供,它们之间相位互不相关,就称相位离散的数字调频信号;若两个频率由同一振荡信号源提供,只是对其中一个载频进行分频,这样产生的两个载频就是相位连续的数字调频信号第第7 7章章 数字系统设计实例数字系统设计实例 图7-7 FSK调制的波形 第第7 7章章 数字系统设计实例数字系统设计实例 7.3.2 2FSK信号产生器 由于FSK为模拟信号,而FPGA只能产生数字信号,因此需对正弦信号采样并经模数变换来得到所需的FSK信号本例由FPGA产生正弦信号的采样值FSK信号发生器框图如图7-8所示,整个系统共分为分频器、m序列产生器、跳变检测、2:1数据选择器、正弦波信号产生器和DAC数模变换器等6部分,其中前5部分由FPGA器件完成。
第第7 7章章 数字系统设计实例数字系统设计实例 图7-8 FSK调制信号发生器框图 第第7 7章章 数字系统设计实例数字系统设计实例 1.分频器 本实例中数据速率为1.2 kHz,要求产生1.2 kHz和2.4 kHz两个正弦信号对正弦信号每周期取100个采样点,因此要求能产生3个时钟信号:1.2 kHz(数据速率)、120 kHz(产生1.2 kHz正弦信号的输入时钟)和240 kHz(产生2.4 kHz正弦信号的输入时钟)基准时钟由一个12 MHz的晶振提供设计中要求一个50分频(产生240 kHz信号),再2分频(产生120 kHz信号)和100分频(产生1.2 kHz信号),共有三个分频值 第第7 7章章 数字系统设计实例数字系统设计实例 2.m序列产生器 m序列是伪随机序列的一种,它的显著特点是:随机特性,预先可确定性,循环特性正因为这些特性,使得m序列产生器在通信领域得到了广泛的应用 本例用一种带有两个反馈抽头的3级反馈移位寄存器,得到一串“1110010”循环序列,并采取措施防止进入全“0”状态。
通过更换时钟频率可以方便地改变输入码元的速率m序列产生器的电路结构如图7-9所示第第7 7章章 数字系统设计实例数字系统设计实例 图7-9 m序列产生器电路结构第第7 7章章 数字系统设计实例数字系统设计实例 3.跳变检测 将跳变检测引入正弦波的产生中,可以使每次基带码元上升沿或下降沿到来时,对应输出波形位于正弦波形的sin0处引入跳变检测主要是为了便于观察,确保示波器上显示为一个连续的波形 基带信号的跳变检测可以有很多方法,图7-10为一种便于在可编程逻辑器件中实现的方案第第7 7章章 数字系统设计实例数字系统设计实例 图7-10 信号跳变检测电路第第7 7章章 数字系统设计实例数字系统设计实例 4.2:1数据选择器 2:1数据选择器用于选择正弦波产生器的两个输入时钟一个时钟的频率为120 kHz,此时正弦波产生器产生一个1.2 kHz的正弦波,代表数字信号“0”;另一个时钟的频率为240 kHz,此时产生一个2.4 kHz的正弦波信号,代表数字信号“1”。
第第7 7章章 数字系统设计实例数字系统设计实例 5.正弦信号的产生 用数字电路和DAC变换器可以产生要求的模拟信号根据抽样定理可知,当用模拟信号最大频率两倍以上的速率对该模拟信号采样时,便可将原模拟信号不失真地恢复出来本例要求得到的是两个不同频率的正弦信号,实验中对正弦波每个周期采样100个点,即采样速率为原正弦信号频率的100倍,因此完全可以在接收端将原正弦信号不失真地恢复出来,从而可以在接收端对FSK信号正确地解调经DAC转换后,可以在示波器上观察到比较理想的波形第第7 7章章 数字系统设计实例数字系统设计实例 本实验中每个采样点采用8位量化编码,即8位分辨率采样点的个数与分辨率的大小主要取决于CPLD/FPGA器件的容量,其中分辨率的高低还与DAC的位数有关实验表明,采用8位分辨率和每周期100个采样点可以达到相当不错的效果第第7 7章章 数字系统设计实例数字系统设计实例 具体的正弦信号产生器可以用状态机来实现按前面的设计思路,本实现方案共需100个状态,分别为s1~s100。
同时设计一个异步复位端,保证当每个“1”或“0”到来时其调制信号正好位于坐标原点,即sin0处状态机共有8位输出(Q7~Q0),经DAC变换为模拟信号输出为得到一个纯正弦波形,应在DAC的输出端加上一个低通滤波器,由于本例仅观察FSK信号,因此省去了低通滤波器 本设计中,数字基带信号与FSK调制信号的对应关系为“0”对应1.2 kHz,“1”对应2.4 kHz,此二载波的频率可以方便地通过软件修改第第7 7章章 数字系统设计实例数字系统设计实例 图7-11 2FSK/2PSK信号产生器外部接口第第7 7章章 数字系统设计实例数字系统设计实例 7.3.3 2FSK/2PSK信号产生器 在2FSK的基础上,可以较容易地设计出2PSK信号产生器,其接口如图7-11所示在检测到基带码元的上升沿或下降沿时,使输出波形位于sinπ处,即可使波形倒相,产生2PSK信号第第7 7章章 数字系统设计实例数字系统设计实例 在设计的最后,应考虑选用DAC器件将波形数据转换为模拟波形输出本实验箱上选用8位并行DAC器件TLC7528,将8位数据输出连至DAC器件的8位数据输入端,即可观察到产生的2FSK/2PSK波形。
为了观察波形的方便,我们将TLC7528连接成电压输出的方式(器件本身是电流输出方式),后面跟一个射随器以增强带载能力第第7 7章章 数字系统设计实例数字系统设计实例 7.3.4 2FSK信号产生器的VHDL程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY fsk ISPORT(clock: IN STD_LOGIC;--正弦波发生器时钟 第第7 7章章 数字系统设计实例数字系统设计实例 dout: OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --并行数据DATA code: BUFFER STD_LOGIC --输出m序列 ); END fsk;第第7 7章章 数字系统设计实例数字系统设计实例 ARCHITECTURE fsk_arch OF fsk ISSIGNAL count100: STD_LOGIC_VECTOR (6 DOWNTO 0);--记录100个状态SIGNAL count50: STD_LOGIC_VECTOR (5 DOWNTO 0);SIGNAL sinclk1: STD_LOGIC;SIGNAL sinclk, coderate: STD_LOGIC;SIGNAL temp, jump_ high: STD_LOGIC;SIGNAL m: STD_LOGIC_VECTOR(2 DOWNTO 0);--m序列第第7 7章章 数字系统设计实例数字系统设计实例 BEGINPROCESS(clock)BEGIN IF(clock'event AND clock='1') THEN --产生FSK所需的另一个频率sinclk1=clock/2 sinclk1<=NOT sinclk1; END IF;END PROCESS;第第7 7章章 数字系统设计实例数字系统设计实例 PROCESS(sinclk1) ---sinclk1 100分频得到coderate码元速率BEGIN IF(sinclk1'event AND sinclk1='1') THEN IF(count50="110001") THEN count50<="000000"; coderate<=NOT coderate; ELSE count50<= count50+'1'; END IF; END IF; END PROCESS;第第7 7章章 数字系统设计实例数字系统设计实例 m_sequence_form: --产生 "1110010" m序列PROCESS(coderate)BEGIN IF(coderate'event AND coderate='1') THEN m(0)<=m(1); m(1)<=m(2); END IF;END PROCESS;第第7 7章章 数字系统设计实例数字系统设计实例 PROCESS(coderate)BEGIN IF(coderate'event AND coderate='1') THEN m(2)<=(m(1) XOR m(0)) OR (NOT (m(0) OR m(1) or m(2))); END IF;END PROCESS; 第第7 7章章 数字系统设计实例数字系统设计实例 code<=m(0); PROCESS(sinclk1,clock,code)BEGIN IF(code='0') THEN sinclk<=sinclk1; ELSE sinclk<=clock; --选择正弦波产生器的时钟频率 END IF;END PROCESS; 第第7 7章章 数字系统设计实例数字系统设计实例 jump_high<=(not temp) AND code; --0到1跳变PROCESS(sinclk)--2FSK跳变的不同处理BEGIN IF(sinclk'event AND sinclk='1') THEN temp<=code; IF((count100="1100011") OR (jump_high='1')) THEN count100<="0000000"; ELSE count100<=count100+'1'; END IF; END IF; END PROCESS;第第7 7章章 数字系统设计实例数字系统设计实例 PROCESS(count100)--产生正弦周期波形的一个周期内的100个样点值BEGIN CASE count100 IS WHEN "0000000" =>dout<= "01111111"; WHEN "0000001" =>dout<= "10000111"; WHEN "0000010" =>dout<= "10001111"; WHEN "0000011" =>dout<= "10010111"; WHEN "0000100" =>dout<= "10011111"; WHEN "0000101" =>dout<= "10100110"; WHEN "0000110" =>dout<= "10101110"; WHEN "0000111" =>dout<= "10110101"; WHEN "0001000" =>dout<= "10111100"; WHEN "0001001" =>dout<= "11000011"; WHEN "0001010" =>dout<= "11001010"; WHEN "0001011" =>dout<= "11010000"; WHEN "0001100" =>dout<= "11010110"; WHEN "0001101" =>dout<= "11011100"; WHEN "0001110" =>dout<= "11100001"; WHEN "0001111" =>dout<= "11100110"; WHEN "0010000" =>dout<= "11101011"; WHEN "0010001" =>dout<= "11101111"; WHEN "0010010" =>dout<= "11110010"; WHEN "0010011" =>dout<= "11110110"; WHEN "0010100" =>dout<= "11111000"; WHEN "0010101" =>dout<= "11111010"; 第第7 7章章 数字系统设计实例数字系统设计实例 WHEN "0010110" =>dout<= "11111100"; WHEN "0010111" =>dout<= "11111101"; WHEN "0011000" =>dout<= "11111110"; WHEN "0011001" =>dout<= "11111111"; WHEN "0011010" =>dout<= "11111110"; WHEN "0011011" =>dout<= "11111101"; WHEN "0011100" =>dout<= "11111100"; WHEN "0011101" =>dout<= "11111010"; WHEN "0011110" =>dout<= "11111000"; WHEN "0011111" =>dout<= "11110110"; WHEN "0100000" =>dout<= "11110010"; WHEN "0100001" =>dout<= "11101111"; WHEN "0100010" =>dout<= "11101011"; WHEN "0100011" =>dout<= "11100110"; WHEN "0100100" =>dout<= "11100001"; WHEN "0100101" =>dout<= "11011100"; WHEN "0100110" =>dout<= "11010110"; WHEN "0100111" =>dout<= "11010000"; WHEN "0101000" =>dout<= "11001010"; WHEN "0101001" =>dout<= "11000011"; WHEN "0101010" =>dout<= "10111100"; WHEN "0101011" =>dout<= "10110101"; WHEN "0101100" =>dout<= "10101110"; WHEN "0101101" =>dout<= "10100110"; WHEN "0101110" =>dout<= "10011111"; WHEN "0101111" =>dout<= "10010111"; WHEN "0110000" =>dout<= "10001111"; WHEN "0110001" =>dout<= "10000111"; WHEN "0110010" =>dout<= "01111111"; WHEN "0110011" =>dout<= "01110111";第第7 7章章 数字系统设计实例数字系统设计实例 WHEN "0110100" =>dout<= "01101111"; WHEN "0110101" =>dout<= "01100111"; WHEN "0110110" =>dout<= "01011111"; WHEN "0110111" =>dout<= "01011000"; WHEN "0111000" =>dout<= "01010000"; WHEN "0111001" =>dout<= "01001001"; WHEN "0111010" =>dout<= "01000010"; WHEN "0111011" =>dout<= "00111011"; WHEN "0111100" =>dout<= "00110100"; WHEN "0111101" =>dout<= "00101110"; WHEN "0111110" =>dout<= "00101000"; WHEN "0111111" =>dout<= "00100010"; WHEN "1000000" =>dout<= "00011101"; WHEN "1000001" =>dout<= "00011000"; WHEN "1000010" =>dout<= "00010011"; WHEN "1000011" =>dout<= "00001111"; WHEN "1000100" =>dout<= "00001100"; WHEN "1000101" =>dout<= "00001000"; WHEN "1000110" =>dout<= "00000110"; WHEN "1000111" =>dout<= "00000100"; WHEN "1001000" =>dout<= "00000010"; WHEN "1001001" =>dout<= "00000001"; WHEN "1001010" =>dout<= "00000000"; WHEN "1001011" =>dout<= "00000000"; WHEN "1001100" =>dout<= "00000000"; WHEN "1001101" =>dout<= "00000001"; WHEN "1001110" =>dout<= "00000010"; WHEN "1001111" =>dout<= "00000100"; WHEN "1010000" =>dout<= "00000110"; WHEN "1010001" =>dout<= "00001000";第第7 7章章 数字系统设计实例数字系统设计实例 WHEN "1010010" =>dout<= "00001100"; WHEN "1010011" =>dout<= "00001111"; WHEN "1010100" =>dout<= "00010011"; WHEN "1010101" =>dout<= "00011000"; WHEN "1010110" =>dout<= "00011101"; WHEN "1010111" =>dout<= "00100010"; WHEN "1011000" =>dout<= "00101000"; WHEN "1011001" =>dout<= "00101110"; WHEN "1011010" =>dout<= "00110100"; WHEN "1011011" =>dout<= "00111011"; WHEN "1011100" =>dout<= "01000010"; WHEN "1011101" =>dout<= "01001001"; WHEN "1011110" =>dout<= "01010000"; WHEN "1011111" =>dout<= "01011000"; WHEN "1100000" =>dout<= "01011111"; WHEN "1100001" =>dout<= "01100111"; WHEN "1100010" =>dout<= "01101111"; WHEN "1100011" =>dout<= "01110111"; WHEN others=>null; END CASE; END PROCESS; END fsk_arch;第第7 7章章 数字系统设计实例数字系统设计实例 7.3.5 2PSK信号产生器的VHDL程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY psk ISPORT (clock: IN STD_LOGIC;--正弦波发生器时钟 第第7 7章章 数字系统设计实例数字系统设计实例 dout: OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --并行数据DATA code: BUFFER STD_LOGIC --输出m序列 );END psk;第第7 7章章 数字系统设计实例数字系统设计实例 ARCHITECTURE psk_arch OF psk ISSIGNAL count100: STD_LOGIC_VECTOR (6 DOWNTO 0); --记录100个状态SIGNAL count50: STD_LOGIC_VECTOR (5 DOWNTO 0);SIGNAL sinclk1: STD_LOGIC;SIGNAL sinclk, coderate: STD_LOGIC;SIGNAL temp,jump_low, jump_high: STD_LOGIC;SIGNAL m: STD_LOGIC_VECTOR(2 DOWNTO 0); --m序列第第7 7章章 数字系统设计实例数字系统设计实例 BEGINPROCESS(clock)BEGIN IF(clock'event AND clock='1') THEN --产生FSK所需的另一个频率sinclk1=clock/2 sinclk1<=NOT sinclk1; END IF;END PROCESS;PROCESS(sinclk1) --sinclk1 100分频得到coderate码元速率第第7 7章章 数字系统设计实例数字系统设计实例 BEGIN IF(sinclk1'event AND sinclk1='1') THEN IF(count50="110001") THEN count50<="000000"; coderate<=NOT coderate; ELSE count50<= count50+'1'; END IF; END IF; END PROCESS;m_sequence_form:---产生 "1110010" m序列PROCESS(coderate)第第7 7章章 数字系统设计实例数字系统设计实例 BEGIN IF(coderate'event AND coderate='1') THEN m(0)<=m(1); m(1)<=m(2); END IF;END PROCESS; PROCESS(coderate)BEGIN IF(coderate'event AND coderate='1') THEN m(2)<=(m(1) XOR m(0)) OR (NOT (m(0) OR m(1) OR m(2))); END IF; END PROCESS; 第第7 7章章 数字系统设计实例数字系统设计实例 code<=m(0);jump_low<=(not code) AND temp;--0到1跳变jump_high<=(not temp) AND code; --1到0跳变PROCESS(clock)--2PSK对跳变的不同处理BEGIN IF(clock'event AND clock='1') THEN第第7 7章章 数字系统设计实例数字系统设计实例 temp<=code; IF(jump_low='1') THEN count100<="0110010"; ELSIF(jump_high='1') THEN count100<="0000000"; ELSIF(count100="1100011") THEN count100<="0000000"; ELSE count100<=count100+'1'; END IF; END IF; END PROCESS;第第7 7章章 数字系统设计实例数字系统设计实例 PROCESS(count100)--产生正弦周期波形的一个周期内的100个样点值BEGIN CASE count100 IS WHEN "0000000" =>dout<= "01111111"; WHEN "0000001" =>dout<= "10000111"; WHEN "0000010" =>dout<= "10001111"; WHEN "0000011" =>dout<= "10010111"; WHEN "0000100" =>dout<= "10011111"; WHEN "0000101" =>dout<= "10100110"; WHEN "0000110" =>dout<= "10101110"; WHEN "0000111" =>dout<= "10110101"; WHEN "0001000" =>dout<= "10111100"; WHEN "0001001" =>dout<= "11000011"; WHEN "0001010" =>dout<= "11001010"; WHEN "0001011" =>dout<= "11010000"; WHEN "0001100" =>dout<= "11010110"; WHEN "0001101" =>dout<= "11011100"; WHEN "0001110" =>dout<= "11100001"; WHEN "0001111" =>dout<= "11100110"; WHEN "0010000" =>dout<= "11101011"; WHEN "0010001" =>dout<= "11101111"; WHEN "0010010" =>dout<= "11110010"; WHEN "0010011" =>dout<= "11110110"; WHEN "0010100" =>dout<= "11111000"; WHEN "0010101" =>dout<= "11111010"; WHEN "0010110" =>dout<= "11111100"; WHEN "0010111" =>dout<= "11111101"; WHEN "0011000" =>dout<= "11111110"; WHEN "0011001" =>dout<= "11111111"; WHEN "0011010" =>dout<= "11111110"; WHEN "0011011" =>dout<= "11111101";第第7 7章章 数字系统设计实例数字系统设计实例 WHEN "0011100" =>dout<= "11111100"; WHEN "0011101" =>dout<= "11111010"; WHEN "0011110" =>dout<= "11111000"; WHEN "0011111" =>dout<= "11110110"; WHEN "0100000" =>dout<= "11110010"; WHEN "0100001" =>dout<= "11101111"; WHEN "0100010" =>dout<= "11101011"; WHEN "0100011" =>dout<= "11100110"; WHEN "0100100" =>dout<= "11100001"; WHEN "0100101" =>dout<= "11011100"; WHEN "0100110" =>dout<= "11010110"; WHEN "0100111" =>dout<= "11010000"; WHEN "0101000" =>dout<= "11001010"; WHEN "0101001" =>dout<= "11000011"; WHEN "0101010" =>dout<= "10111100"; WHEN "0101011" =>dout<= "10110101"; WHEN "0101100" =>dout<= "10101110"; WHEN "0101101" =>dout<= "10100110"; WHEN "0101110" =>dout<= "10011111"; WHEN "0101111" =>dout<= "10010111"; WHEN "0110000" =>dout<= "10001111"; WHEN "0110001" =>dout<= "10000111"; WHEN "0110010" =>dout<= "01111111"; WHEN "0110011" =>dout<= "01110111"; WHEN "0110100" =>dout<= "01101111"; WHEN "0110101" =>dout<= "01100111"; WHEN "0110110" =>dout<= "01011111"; WHEN "0110111" =>dout<= "01011000"; WHEN "0111000" =>dout<= "01010000"; WHEN "0111001" =>dout<= "01001001"; WHEN "0111010" =>dout<= "01000010"; WHEN "0111011" =>dout<= "00111011"; WHEN "0111100" =>dout<= "00110100"; WHEN "0111101" =>dout<= "00101110";第第7 7章章 数字系统设计实例数字系统设计实例 WHEN "0111110" =>dout<= "00101000"; WHEN "0111111" =>dout<= "00100010"; WHEN "1000000" =>dout<= "00011101"; WHEN "1000001" =>dout<= "00011000"; WHEN "1000010" =>dout<= "00010011"; WHEN "1000011" =>dout<= "00001111"; WHEN "1000100" =>dout<= "00001100"; WHEN "1000101" =>dout<= "00001000"; WHEN "1000110" =>dout<= "00000110"; WHEN "1000111" =>dout<= "00000100"; WHEN "1001000" =>dout<= "00000010"; WHEN "1001001" =>dout<= "00000001"; WHEN "1001010" =>dout<= "00000000"; WHEN "1001011" =>dout<= "00000000"; WHEN "1001100" =>dout<= "00000000"; WHEN "1001101" =>dout<= "00000001"; WHEN "1001110" =>dout<= "00000010"; WHEN "1001111" =>dout<= "00000100"; WHEN "1010000" =>dout<= "00000110"; WHEN "1010001" =>dout<= "00001000"; WHEN "1010010" =>dout<= "00001100"; WHEN "1010011" =>dout<= "00001111"; WHEN "1010100" =>dout<= "00010011"; WHEN "1010101" =>dout<= "00011000"; WHEN "1010110" =>dout<= "00011101"; WHEN "1010111" =>dout<= "00100010"; WHEN "1011000" =>dout<= "00101000"; WHEN "1011001" =>dout<= "00101110"; WHEN "1011010" =>dout<= "00110100"; WHEN "1011011" =>dout<= "00111011";第第7 7章章 数字系统设计实例数字系统设计实例 WHEN "1011100" =>dout<= "01000010"; WHEN "1011101" =>dout<= "01001001"; WHEN "1011110" =>dout<= "01010000"; WHEN "1011111" =>dout<= "01011000"; WHEN "1100000" =>dout<= "01011111"; WHEN "1100001" =>dout<= "01100111"; WHEN "1100010" =>dout<= "01101111"; WHEN "1100011" =>dout<= "01110111"; WHEN others=>null; END CASE; END PROCESS; END psk_arch;第第7 7章章 数字系统设计实例数字系统设计实例 7.3.6 仿真结果 2FSK信号产生器的仿真波形如图7-12所示;2PSK信号产生器的仿真波形如图7-13所示。
第第7 7章章 数字系统设计实例数字系统设计实例 图7-12 2FSK信号产生器仿真波形图 第第7 7章章 数字系统设计实例数字系统设计实例 图7-13 2PSK信号产生器仿真波形图 第第7 7章章 数字系统设计实例数字系统设计实例 7.3.7 下载验证 锁定引脚时将clock连至CLK1,dout连至DA输入端,code连至TESTOUT1(测试1脚)综合适配后将配置数据下载入EDA实验平台(技术资料详见附录)的FPGA中(有关CLK1等引脚在FPGA芯片引脚中的序号, 请参见附录的附图1),即可用双踪示波器同时观察m序列及其对应的2FSK或2PSK波形第第7 7章章 数字系统设计实例数字系统设计实例 7.4 实用多功能电子表实用多功能电子表 7.4.1 功能描述 多功能电子表共有5种功能:功能1为数字钟;功能2为数字跑表;功能3为调时;功能4为闹钟设置;功能5为日期设置除调时功能以外,电子表处于其他功能状态下时并不影响数字钟的运行使用数字钟功能时,还可以通过按键快速查看当前的闹钟设置时间和当前日期。
该电子表利用EDA实验平台的扬声器整点报时和定时报时,设置3个按键分别作为功能键和调整键实用多功能电子表外部接口如图7-14所示第第7 7章章 数字系统设计实例数字系统设计实例 图7-14 实用多功能电子表外部接口 第第7 7章章 数字系统设计实例数字系统设计实例 1.输入 (1) func_key:功能键,控制电子表的功能号 (2) key1:调整key1,功能1时按下可显示闹钟设置时间;功能2时用作跑表暂停键;功能3、4时分别用于调数字钟和闹钟的小时数;功能5时用于调日期的月份 (3) key2:调整key2,功能1时按下可显示当前日期;功能2时用作跑表清零键;功能3、4时分别用于调数字钟和闹钟的分钟数;功能5时用于调日期的日期数第第7 7章章 数字系统设计实例数字系统设计实例 (4) clk_1 Hz:数字钟时钟(1 Hz)输入 (5) clk_1 kHz:1 kHz时钟,是整点报时和定点报时所需的频率另外,10分频后还可得到100 Hz频率信号作为数字跑表时钟输入。
第第7 7章章 数字系统设计实例数字系统设计实例 2.输出 (1) mode:显示电子表的功能号1~5 (2) hour:功能1、3和4时显示小时数;功能2时显示跑表的分钟数;功能5时显示月份 (3) minute:功能1、3和4时显示分钟数;功能2时显示跑表的秒数;功能5时显示日期数 (4) second:功能1时显示秒数;功能2时显示1%秒;功能3、4和5时均显示0 (5) alarm:连至扬声器,用于整点报时及闹钟报时第第7 7章章 数字系统设计实例数字系统设计实例 7.4.2 电路组成 在明确电子表的功能后,可对电子表进行模块划分得到电子表设计的结构框图,如图7-15所示第第7 7章章 数字系统设计实例数字系统设计实例 图7-15 实用多功能电子表结构框图 第第7 7章章 数字系统设计实例数字系统设计实例 从结构框图中可以看出,模块划分与功能划分存在不同之处。
下面分别对几个模块加以说明 1.数字钟与调时模块 由于调时功能改变的就是数字钟的时和分,因此应将这两个功能合在同一模块中这是因为在VHDL和Verilog HDL中都不允许两个进程对同一信号进行赋值(即多重驱动)此模块的输入有下面3个第第7 7章章 数字系统设计实例数字系统设计实例 (1) clk_1:时钟输入当处在数字钟功能时,clk_1应为1 Hz的时钟信号;当处在调时功能时,clk_1应为按key1和key2调整键产生的adjust_key1和adjust_key2脉冲信号因此可描述clk_1为clk_1=(clk_1 Hz&&mode!=3)||(mode==3&&(adjust_key1||adjust_key2));即当不处于功能3时为1 Hz时钟信号,处于功能3时为adjust_key1或adjust_key2脉冲信号这样,当将电子表调整到数字钟功能外的其他功能时将不会影响数字钟的运行第第7 7章章 数字系统设计实例数字系统设计实例 (2) adjust_key1和adjust_key2:在EDA实验平台上实现时,key1(KEY2)和key2(KEY3)两个调整键是乒乓开关,即每按动一次,相应引脚上的电平就翻转一次。
这里需将其变为琴键开关,即每按动一次将产生一个上跳脉冲,从而启动进程的运行有关乒乓开关和琴键开关的说明请参见附录 此模块的输出为6位时、7位分和7位秒,采用BCD码表示第第7 7章章 数字系统设计实例数字系统设计实例 2.跑表模块 跑表的设计与数字钟的设计基本相同,不同的是其输入时钟应为100 Hz的信号,同时还应增加暂停键(key1)和清零键(key2)因此其时钟clk_2应描述为 clk_2=clk_100 Hz&&mode==2&&!key1; 即当电子表处于功能2时启动跑表模块运行,时钟为100 Hz,key1(乒乓开关)则作为时钟使能信号,也即作为跑表的暂停键 跑表模块的输出为7位分、7位秒和8位1%秒,采用BCD码显示第第7 7章章 数字系统设计实例数字系统设计实例 3.闹钟设置模块 闹钟设置模块的输入为两个调整键clk_key1和clk_key2,分别描述为 clk_key1=adjust_key1 && mode==4; clk_key2=adjust_key2 && mode==4; 表示在闹钟功能时key1和key2分别作为调时键和调分键。
闹钟的输出为6位时和7位分,采用BCD码显示 第第7 7章章 数字系统设计实例数字系统设计实例 4.日期设置模块 日期设置模块输入为两个调整键clk_key3和clk_key4,分别描述为 clk_key3=adjust_key1 && mode==5; clk_key4=adjust_key2 && mode==5; 表示日期设置功能时key2和key3分别作为调月键和调日键日期设置的输出为5位月(共12月)和6位日(共30日),采用BCD码显示第第7 7章章 数字系统设计实例数字系统设计实例 5.显示模块 由于EDA实验平台上已为数码管显示制作了译码和驱动电路,因此在其上设计数码管显示电路时将无须编写译码电路 本设计显示模块的作用是根据不同的功能号,将相应功能的输出连至数码管上并输出第第7 7章章 数字系统设计实例数字系统设计实例 时、分和秒的显示分别用8位表示,实际上,时、分和秒的最大值分别为23、59和59,对应的BCD码表示分别为6、7和7位。
选用8位表示是因为实验平台上悬空的引脚均为高电平,如果不将高位悬空引脚通过程序置为低电平,将导致显示错误第第7 7章章 数字系统设计实例数字系统设计实例 6.报时模块 报时模块控制在整点或闹钟时间到时将1 kHz或500 Hz的方波信号送至实验平台上的扬声器发声 7.分频模块 分频模块将1 kHz的方波信号分频至500 Hz(整点报时用)和100 Hz(跑表时钟) 8.功能号指示 通过按功能键选择不同的功能号(1~5),将功能号送往其他模块使用并通过数码管显示出来第第7 7章章 数字系统设计实例数字系统设计实例 9.按键切换 在EDA实验平台上,func_key(KEY1)、key1(KEY2)和key2(KEY3)均为乒乓开关,需将其转换为琴键开关func_key、adjust_key1和adjust_key2,这样在用KEY1、KEY2和KEY3键调整功能号或调时、调分时,每按一次便会产生一个上升沿脉冲,启动相应进程的运行。
第第7 7章章 数字系统设计实例数字系统设计实例 7.4.3 Verilog-HDL程序module clock(clk_1 Hz, clk_1 kHz, func_key, key1, key2, mode, hour, minute, second, alarm);input clk_1 Hz ;//1Hz时钟,供数字钟使用input clk_1 kHz ;//1 kHz时钟, 分成500 Hz供闹钟和整点报时使用, 分频100 Hz供跑表使用input func_key ;//功能键, 1表示数字钟, 2表示跑表, 3表示调时, 4表示设置闹钟,5表示日//期设置第第7 7章章 数字系统设计实例数字系统设计实例 input key1 ;//功能1时显示闹钟时间, 功能2时暂停, 功能3、4时调小时, 功能5时调 //月份input key2 ;//功能1时显示日期, 功能2时清零, 功能3、4时调分, 功能5时调日output [3:0] mode;//功能号指示output [7:0] hour ;//功能1、3和4时显示小时, 功能2时显示分钟, 功能5时显示月份output [7:0] minute;//功能1、3和4时显示分钟, 功能2时显示秒, 功能5时显示日期第第7 7章章 数字系统设计实例数字系统设计实例 output [7:0] second;//功能1时显示秒, 功能2时显示1/100秒, 其余时固定显示0output alarm ;//连至扬声器, 整点报时及闹钟reg[3:0] mode;//功能号指示(1~5)reg[7:0] hour,minute,second;reg[2:0] divide;//1 kHz信号10分频得100 Hz, 先5分频,再2分频reg clk_100 Hz;//100 Hz供跑表用reg clk_500 Hz;//500 Hz供准点报时时用第第7 7章章 数字系统设计实例数字系统设计实例 reg temp1,temp2,temp3;wire funckey,adjust_key1,adjust_key2;always@(posedge clk_1 kHz)begin clk_500 Hz=~clk_500 Hz; //由1 kHz分频得500 Hz时钟信号,整点报时使用 temp1=func_key; temp2=key1; temp3=key2;第第7 7章章 数字系统设计实例数字系统设计实例 if(divide==3'b101) //由1 kHz分频得到100 Hz信号,用作跑表的时钟 begin divide=0;clk_100 Hz=~clk_100 Hz; end else divide=divide+1;end第第7 7章章 数字系统设计实例数字系统设计实例 assign funckey=func_key^temp1; //将func_key(乒乓开关)转换为琴键开关assign adjust_key1=key1^temp2;//将key1(乒乓开关)转换为琴键开关assign adjust_key2=key2^temp3;//将key2(乒乓开关)转换为琴键开关always@(posedge funckey)begin if(mode[2]&mode[0]) mode[2]=0; //功能号在1~5之间变化 else mode=mode+1;end第第7 7章章 数字系统设计实例数字系统设计实例 //功能1与功能3:数字钟及时间设置, 功能3以外其他功能将不影响数字钟的运行reg[5:0] h1;//功能1(数字钟)的时、分、秒reg[6:0] m1,s1;wire clk_1;//数字钟时为1 Hz时钟, 时间设置时为按调整键产生的脉冲assignclk_1=(clk_1 Hz&&mode!=3)||(mode==3&&(adjust_key1||adjust_key2));always@(posedge clk_1)第第7 7章章 数字系统设计实例数字系统设计实例 begin if(mode!=3)//数字钟 begin//23:59:59'时变为00:00:00if(h1[5]&h1[1]&h1[0]&m1[6]&m1[4]&m1[3]&m1[0]&s1[6]&s1[4]&s1[3]&s1[0]) {h1,m1,s1}=0; else if(h1[3]&h1[0]&m1[6]&m1[4]&m1[3]&m1[0]&s1[6]&s1[4]&s1[3]&s1[0]) 第第7 7章章 数字系统设计实例数字系统设计实例 begin//*9:59:59'时小时加7,分、秒变为0 h1=h1+7;m1=0;s1=0; end else if(m1[6]&m1[4]&m1[3]&m1[0]&s1[6]&s1[4]&s1[3]&s1[0]) begin//59:59' 时分、秒为0,小时加1 h1=h1+1;m1=0;s1=0; end第第7 7章章 数字系统设计实例数字系统设计实例 else if(m1[3]&m1[0]&s1[6]&s1[4]&s1[3]&s1[0]) begin//*9:59'时秒为0,分加7 m1=m1+7; s1=0; end else if(s1[6]&s1[4]&s1[3]&s1[0]) begin//59秒时秒为0,分加1 m1=m1+1;s1=0; end 第第7 7章章 数字系统设计实例数字系统设计实例 else if(s1[3]&s1[0]) s1=s1+7;//*9秒时秒加7 else s1=s1+1;//秒加1 end else if(adjust_key1)//调时 begin if(h1[5]&h1[1]&h1[0]) h1=0; else if(h1[3]&h1[0]) h1=h1+7; else h1=h1+1; end 第第7 7章章 数字系统设计实例数字系统设计实例 else if(m1[6]&m1[4]&m1[3]&m1[0]) m1=0;//调分 else if(m1[3]&m1[0]) m1=m1+7; else m1=m1+1;end //功能2:跑表,key1作为暂停键,key2作为清零键reg[6:0] h2,m2;//功能2(数字跑表)时的时、分、秒reg[7:0] s2;wire clk_2;第第7 7章章 数字系统设计实例数字系统设计实例 assign clk_2=clk_100 Hz&&mode==2&&!key1; //跑表的100 Hz时钟,key1此时为暂停键always@(posedge clk_2)beginif(key2||(h2[6]&h2[4]&h2[3]&h2[0]&m2[6]&m2[4]&m2[3]&m2[0]&s2[7]&s2[4]&s2[3]&s2[0])) {h2,m2,s2}=0; //跑表时key2清零,59:59'99"时清零第第7 7章章 数字系统设计实例数字系统设计实例 else if(h2[3]&h2[0]&m2[6]&m2[4]&m2[3]&m2[0]&s2[7]&s2[4]&s2[3]&s2[0]) begin h2=h2+7;m2=0;s2=0; endelse if(m2[6]&m2[4]&m2[3]&m2[0]&s2[7]&s2[4]&s2[3]&s2[0]) begin h2=h2+1;m2=0;s2=0; end第第7 7章章 数字系统设计实例数字系统设计实例 else if(m2[3]&m2[0]&s2[7]&s2[4]&s2[3]&s2[0]) begin m2=m2+7; s2=0; endelse if(s2[7]&s2[4]&s2[3]&s2[0]) begin m2=m2+1;s2=0; endelse if(s2[3]&s2[0]) s2=s2+7;else s2=s2+1;end第第7 7章章 数字系统设计实例数字系统设计实例 //功能4:闹钟设置,key1和key2分别用来调时和调分reg[5:0] h4;//功能4(闹钟设置)时的时和分reg[6:0] m4;wire clk_key1,clk_key2;assign clk_key1=adjust_key1 && mode==4; //功能4时key1作为调时键assign clk_key2=adjust_key2 && mode==4; //功能4时key2作为调分键第第7 7章章 数字系统设计实例数字系统设计实例 always@(posedge clk_key1)//最大24小时begin if(h4[5]&h4[1]&h4[0]) h4=0; else if(h4[3]&h4[0]) h4=h4+7; else h4=h4+1;endalways@(posedge clk_key2)//最大60分第第7 7章章 数字系统设计实例数字系统设计实例 begin if(m4[6]&m4[4]&m4[3]&m4[0]) m4=0; else if(m4[3]&m4[0]) m4=m4+7; else m4=m4+1;end第第7 7章章 数字系统设计实例数字系统设计实例 //功能5:调日期,key1和key2分别调月和调日reg[4:0] month;reg[5:0] day;wire clk_key3,clk_key4;assign clk_key3=adjust_key1 && mode==5; //功能5时key1作为调月键assign clk_key4=adjust_key2 && mode==5; //功能5时key2作为调日键第第7 7章章 数字系统设计实例数字系统设计实例 always@(posedge clk_key3)//最大12个月begin if(month[4]&month[1]) month=1; else if(month[3]&month[0]) month=month+7; else month=month+1;end第第7 7章章 数字系统设计实例数字系统设计实例 always@(posedge clk_key4)//每月按30天算begin if(day[5]&day[4]) day=1; else if(day[3]&day[0]) day=day+7; else day=day+1;end第第7 7章章 数字系统设计实例数字系统设计实例 //显示模块:在各功能号下分别显示相应的值always@(h1 or m1 or s1 or h2 or m2 or s2 or h4 or m4 or month or day or mode or key1 or key2)begin if(mode[2]|(mode[1]&mode[0])|(mode==1&(key1|key2))) second=0; else if(mode==1) second=s1; else second=s2; if((mode==1 & !key1 &!key2) | mode==3) begin第第7 7章章 数字系统设计实例数字系统设计实例 hour=h1;minute=m1; end else if(mode==2) begin hour=h2;minute=m2; end else if(mode==4 | ((mode==1) & key1)) begin hour=h4;minute=m4; end第第7 7章章 数字系统设计实例数字系统设计实例 else begin hour=month;minute=day; endend//发声单元:整点报时和定点闹时wire spk,temp4,temp5;第第7 7章章 数字系统设计实例数字系统设计实例 assign temp4=m1[6]&m1[4]&m1[3]&m1[0]&s1[6]&s1[4]&!s1[0];//59:50', 52', 54', 56', 58'时assign temp5=({m1,s1}==0)||((h1==h4)&&(m1==m4)&&!s1[0]);//定时到时每隔1秒及整点时第第7 7章章 数字系统设计实例数字系统设计实例 assign spk=(temp4&&clk_500 Hz)||(temp5&&clk_1 kHz); //整点及闹时送到扬声器的不同频率assign alarm=(temp4||temp5)-spk:0; //扬声器在整点及闹钟时间发出声响endmodule 本例用Verilog HDL语言编写,有关Verilog HDL语言的使用请参见相关参考书籍。
第第7 7章章 数字系统设计实例数字系统设计实例 7.4.4 仿真结果在模式1时, 多功能电子表的仿真波形如图7-16所示第第7 7章章 数字系统设计实例数字系统设计实例 图7-16 多功能电子表模式1的仿真波形 第第7 7章章 数字系统设计实例数字系统设计实例 7.4.5 下载验证 锁定引脚时clk_1 Hz和clk_1 kHz分别接CLK1和CLK2,func_key、key1和key2分别接KEY1、KEY2和KEY3,hour、minute和second分别接时、分、秒数码管,alarm接扬声器,mode可接3个LED综合适配后将配置数据下载入EDA实验平台(技术资料详见附录)的FPGA中(有关CLK1等引脚在FPGA芯片引脚中的序号, 请参见附录的附图1), 即实现了一个实用多功能电子表操作KEY1、KEY2和KEY3,观察时、分、秒数码管的运行,可对该电子表进行功能验证第第7 7章章 数字系统设计实例数字系统设计实例 7.5 交通灯控制器交通灯控制器 7.5.1 功能描述 设东西方向和南北方向的车流量大致相同,因此红、黄、绿灯的时长也相同,定为红灯45秒,黄灯5秒,绿灯40秒,同时用数码管指示当前状态(红、黄、绿灯)剩余时间。
另外,设计一个紧急状态,当紧急状态出现时,两个方向都禁止通行,指示红灯紧急状态解除后,重新计数并指示时间第第7 7章章 数字系统设计实例数字系统设计实例 7.5.2 交通灯控制器的实现 交通灯控制器是状态机的一个典型应用,除了计数器是状态机外,还有东西、南北方向的不同状态组合(红绿、红黄、绿红、黄红4个状态),如表7-3所示但我们可以简单地将其看成两个(东西、南北)减1计数的计数器,通过检测两个方向的计数值,可以检测红、黄、绿灯组合的跳变这样使一个较复杂的状态机设计变成一个较简单的计数器设计 第第7 7章章 数字系统设计实例数字系统设计实例 表7-3 交通灯的4种可能亮灯状态 状 态东 西 方 向南 北 方 向红 黄 绿红 黄 绿11 0 00 0 120 1 00 0 130 0 11 0 040 0 10 1 0第第7 7章章 数字系统设计实例数字系统设计实例 图7-17 交通灯控制器外部接口 第第7 7章章 数字系统设计实例数字系统设计实例 本例假设东西方向和南北方向的黄灯时间均为5秒,在设计交通灯控制器时,可在简单计数器的基础上增加一些状态检测,即通过检测两个方向的计数值判断交通灯应处于4种可能状态中的哪个状态。
本交通灯控制器外部接口如图7-17所示 表7-4列出了需检测的状态跳变点,从表中可以看出,有两种情况出现了东西方向和南北方向计数值均为1的情况,因此在检查跳变点时还应同时判断当前是处于状态2还是状态4,这样就可以决定次状态是状态3还是状态1第第7 7章章 数字系统设计实例数字系统设计实例 表7-4 交通灯设计中的状态跳变点 交通灯现状态计数器计数值交通灯次状态计数器计数值东西方向计数值南北方向计数值东西方向计数值南北方向计数值1612552113404531645541114540第第7 7章章 数字系统设计实例数字系统设计实例 对于紧急情况,只需设计一个异步时序电路即可解决 程序中还应防止出现非法状态,即程序运行后应判断东西方向和南北方向的计数值是否超出范围此电路仅在电路启动运行时有效,因为一旦两个方向的计数值正确后,就不可能再计数到非法状态第第7 7章章 数字系统设计实例数字系统设计实例 7.5.3 VHDL程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY traffic ISPORT(clk,urgency: IN STD_LOGIC; led: BUFFER STD_LOGIC_VECTOR(7 DOWNTO 0); East_West,South_North:BUFFER STD_LOGIC_VECTOR(7 DOWNTO 0));END traffic;第第7 7章章 数字系统设计实例数字系统设计实例 ARCHITECTURE rtl OF traffic ISBEGIN PROCESS(clk) BEGIN IF urgency='0' THEN led<="10000001"; East_West<="00000000"; South_North<="00000000"; ELSIF clk'event AND clk='1' THEN第第7 7章章 数字系统设计实例数字系统设计实例 IF East_West>"01000110" OR South_North>"01000110" THEN East_West<="01000101"; South_North<="01000000"; led<="10000100"; ELSIFEast_West="00000110"AND South_North="00000001" THEN East_West<="00000101"; South_North<="00000101"; led<="10000010";第第7 7章章 数字系统设计实例数字系统设计实例 ELSIFEast_West="00000001"AND South_North="00000001" AND led="10000010" THEN East_West<="01000000"; South_North<="01000101"; led<="00100001"; ELSIFEast_West="00000001"AND South_North="00000110" THEN East_West<="00000101"; South_North<="00000101"; led<="01000001";第第7 7章章 数字系统设计实例数字系统设计实例 ELSIFEast_West="00000001"AND South_North="00000001" AND led="01000001" THEN East_West<="01000101"; South_North<="01000000"; led<="10000100"; ELSIF East_West(3 DOWNTO 0)=0 THEN East_West<=East_West-7; South_North<=South_North-1;第第7 7章章 数字系统设计实例数字系统设计实例 ELSIF South_North(3 DOWNTO 0)=0 THEN East_West<=East_West-1; South_North<=South_North-7; ELSE East_West<=East_West-1; South_North<=South_North-1; END IF; END IF; END PROCESS;END rtl;第第7 7章章 数字系统设计实例数字系统设计实例 7.5.4 仿真结果交通灯控制器仿真波形如图7-18所示。
第第7 7章章 数字系统设计实例数字系统设计实例 图7-18 交通灯控制器仿真波形图 第第7 7章章 数字系统设计实例数字系统设计实例 7.5.5 下载验证 锁定引脚时clk接CLK1,led接8个LED灯,East_West, South_North分别接一组数码管综合适配后将配置数据下载入EDA实验平台(技术资料详见附录)的FPGA中(有关CLK1等引脚在FPGA芯片引脚中的序号, 请参见附录的附图1)开启电源后,交通灯即可正常运行,不需要人工设置初始状态第第7 7章章 数字系统设计实例数字系统设计实例 7.6 数数 字字 频频 率率 计计 7.6.1 测频原理 频率计的基本原理是用一个频率稳定度高的频率源作为基准时钟,对比测量其他信号的频率通常情况下计算每秒内待测信号的脉冲个数,此时我们称闸门时间为1秒闸门时间也可以大于或小于1秒闸门时间越长,得到的频率值就越准确,但闸门时间越长则每测一次频率的间隔就越长闸门时间越短,测得频率值刷新就越快,但测得的频率精度就受影响第第7 7章章 数字系统设计实例数字系统设计实例 7.6.2 频率计实现 频率计的结构包括一个测频控制信号发生器、一个计数器和一个锁存器。
1.测频控制信号发生器 设计频率计的关键是设计一个测频控制信号发生器,产生测量频率的控制时序控制时钟信号clk取为1 Hz,2分频后即可产生一个脉宽为1秒的时钟test_en,以此作为计数闸门信号第第7 7章章 数字系统设计实例数字系统设计实例 当test_en为高电平时,允许计数;当test_en由高电平变为低电平(下降沿到来)时,应产生一个锁存信号,将计数值保存起来;锁存数据后,还要在下次test_en上升沿到来之前产生清零信号clear,将计数器清零,为下次计数作准备第第7 7章章 数字系统设计实例数字系统设计实例 2.计数器 计数器以待测信号作为时钟,清零信号clear到来时,异步清零;test_en为高电平时开始计数计数以十进制数显示,本例设计了一个简单的10 kHz以内信号的频率计,如果需要测试较高频率的信号,则将dout的输出位数增加,当然锁存器的位数也要相应增加第第7 7章章 数字系统设计实例数字系统设计实例 3.锁存器 当test_en下降沿到来时,将计数器的计数值锁存,这样可由外部的七段译码器译码并在数码管上显示。
设置锁存器的好处是显示的数据稳定,不会由于周期性的清零信号而不断闪烁锁存器的位数应跟计数器完全一样 数字频率计外部接口如图7-19所示第第7 7章章 数字系统设计实例数字系统设计实例 图7-19 数字频率计外部接口第第7 7章章 数字系统设计实例数字系统设计实例 7.6.3 VHDL程序LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY freq ISPORT(fsin: in STD_LOGIC;--待测信号 clk: IN STD_LOGIC;--1 Hz基准时钟 dout: OUT STD_LOGIC_VECTOR(15 DOWNTO 0)); --锁存后的数据,显示在数码管上第第7 7章章 数字系统设计实例数字系统设计实例 END freq;ARCHITECTURE one OF freq ISSIGNAL test_en: STD_LOGIC;--测试使能SIGNAL clear: STD_LOGIC;--计数清零SIGNAL data: STD_LOGIC_VECTOR(15 DOWNTO 0);--计数值BEGIN PROCESS(clk)第第7 7章章 数字系统设计实例数字系统设计实例 BEGIN IF clk'event AND clk='1' THEN test_en<=NOT test_en; END IF; END PROCESS; clear<=NOT clk AND NOT test_en; PROCESS(fsin)第第7 7章章 数字系统设计实例数字系统设计实例 BEGIN IF clear='1' THEN data<="0000000000000000"; ELSIF fsin'event AND fsin='1' THEN IF data(11 DOWNO 0)="100110011001" THEN data<=data+"011001100111"; ELSIF data(7 DOWNTO 0)="10011001" THEN data<=data+"01100111"; ELSIF data(3 DOWNTO 0)="1001" THEN data<=data+"0111"; ELSE data<=data+'1'; END IF; 第第7 7章章 数字系统设计实例数字系统设计实例 END IF; END IF; END PROCESS; PROCESS(test_en,data) BEGIN IF test_en'event AND test_en='0' THEN dout<=data; END IF; END PROCESS;END one;第第7 7章章 数字系统设计实例数字系统设计实例 7.6.4 仿真结果频率计仿真波形如图7-20所示。
图7-20 频率计仿真波形图 第第7 7章章 数字系统设计实例数字系统设计实例 7.6.5 下载验证 锁定引脚时clk接CLK1;fsin为待测信号,可接CLK2,也可接TESTOUT1,测试外部引入的TTL波形频率;dout接4个数码管综合适配后将配置数据下载入EDA实验平台(技术资料详见附录)的FPGA中(有关CLK1等引脚在FPGA芯片引脚中的序号,请参见附录的附图1)开启电源后,频率计即可正常运行改变输入信号的频率,观察数码管指示频率的变化情况第第7 7章章 数字系统设计实例数字系统设计实例 习习 题题 1.可以利用FPGA的查询表将乐谱及音长存放在其中,在放音时从RAM区中读取相应的乐谱及音长试用此方法设计出与本章第二节同样功能的音乐发生器 2.试仿7.2节编写出演奏其他乐曲的音乐发生器的VHDL程序 第第7 7章章 数字系统设计实例数字系统设计实例 3.参考7.3节的信号产生器将2FSK和2PSK合并在一起,通过一个按键控制信号产生器输出2FSK或2PSK信号。
4.构造一个RAM区存放波形数据并产生FSK信号 5.将7.4节程序用VHDL语言编写由于本例中大量使用模60和模24计数器,因此建议采用VHDL的生成语句或元件例化语句产生这两种计数器模块 6.将7.4节程序的日期设置模块作改进,如数字钟时间为23:59:59',在下一个脉冲来时将日期数加1;另外为每月设置不同的日期数(原程序每月为固定的30天)第第7 7章章 数字系统设计实例数字系统设计实例 7.7.5节交通灯控制器中未设右拐灯,请添加右拐灯指示及其相应代码另外,如果要求紧急状态过后,交通灯指示器恢复原来状态,应如何修改此VHDL程序? 8.参考7.6节的程序,将计数器和锁存器的位数扩展,以使其可以测试频率高的信号并且在计数器和锁存器位数扩展后,测试当输入信号的频率达到多少时(如10 MHz、50 MHz),频率计将不能正常工作?。





