VHDL彩灯控制电路的设计与实现一、实验目的1.进一步了解时序电路设计方法2.熟悉状态机的设计方法二、实验所用仪器及元器件1、计算机2、直流稳压电源3、数字系统与逻辑设计实验开发板三、实验内容用VHDL语言设计并实现一个彩灯控制(8个发光二极管)电路,仿真并下载验证其功能。彩灯有两种工作模式,可以通过拨码开关或者按键进行切换。(1)单点移动模式:一个点在8个发光二极管上来回的亮(2)幕布模式:从中间两个点,同时向两边一次点亮直至全亮,然后再向中间点灭,依次往复四、设计思路与过程根据实验要求,需要实现在拨码开关或者按键的控制下实现两种状态机的转换。首先,确定输入输出变量:输入:拨码开关a:实现两种模式的转换;时钟clk::提供有效时钟沿;输出:8维向量b:连接8个发光二极管。其次,确定电路工作状态因为在单点移动模式和幕布模式都要满足灯来回亮,共计工作状态23种:a=0时,实现单点移动模式,工作状态有s0~s13共14种状态;a=1时,实现幕布模式,工作状态有s14~s22共9种状态。再次,大致确定VHDL编写思路确定好输入输出变量和电路状态后,考虑结构体中需要的进程需要完成以下两个功能——分频和实现状态机,故我使用了4个进程。其功能分别如下:P0:分频,将实验板上提供的50MHz的时钟信号,即输入clk分为频率为1Hz的低频信号clk_out,以便观察现象;P1:为当前状态储存的下一状态;P2:当时钟有效沿到来时,当前状态转入下一状态;(P1、P2共同实现状态机的转换)P3:控制LED灯的输出,达到实验要求效果具体程序如下。五、VHDL程序libraryieee;useieee.std_logic_1164.all;-1-entitylightisport(clk:instd_logic;a:instd_logic;b:outstd_logic_vector(7downto0));endlight;architecturelight_1oflightistypestate_typeis(s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s20,s21,s22);signalcurrent_state,next_state:state_type;signalclk_out:std_logic;signaltmp:integerrange0to49999999;beginp0:process(clk)--分频器,把50MHz的时钟clk分为1Hz的时钟clk_outbeginifclk'eventandclk='1'theniftmp=49999999thentmp=0;elsetmp=tmp+1;endif;iftmp=49999999thenclk_out='1';elseclk_out='0';endif;endif;endprocess;p1:process(current_state,a)--当前状态在开关函数a作用下所储存的下一状态begincasecurrent_stateiswhens0=if(a='0')thennext_state=s1;elsenext_state=s14;endif;whens1=if(a='0')thennext_state=s2;elsenext_state=s14;endif;whens2=if(a='0')thennext_state=s3;elsenext_state=s14;endif;whens3=if(a='0')thennext_state=s4;elsenext_state=s14;endif;whens4=if(a='0')thennext_state=s5;elsenext_state=s14;endif;whens5=if(a='0')thennext_state=s6;elsenext_state=s14;endif;-2-whens6=if(a='0')thennext_state=s7;elsenext_state=s14;endif;whens7=if(a='0')thennext_state=s8;elsenext_state=s14;endif;whens8=if(a='0')thennext_state=s9;elsenext_state=s14;endif;whens9=if(a='0')thennext_state=s10;elsenext_state=s14;endif;whens10=if(a='0')thennext_state=s11;elsenext_state=s14;endif;whens11=if(a='0')thennext_state=s12;elsenext_state=s14;endif;whens12=if(a='0')thennext_state=s13;elsenext_state=s14;endif;whens13=if(a='0')thennext_state=s0;elsenext_state=s14;endif;whens14=if(a='1')thennext_state=s15;elsenext_state=s0;endif;whens15=if(a='1')thennext_state=s16;elsenext_state=s0;endif;whens16=if(a='1')thennext_state=s17;elsenext_state=s0;endif;whens17=if(a='1')thennext_state=s18;elsenext_state=s0;endif;whens18=if(a='1')thennext_state=s19;elsenext_state=s0;endif;whens19=if(a='1')thennext_state=s20;elsenext_state=s0;endif;whens20=if(a='1')thennext_state=s21;elsenext_state=s0;endif;whens21=if(a='1')thennext_state=s22;elsenext_state=s0;endif;whens22=if(a='1')thennext_state=s14;elsenext_state=s0;endif;endcase;endprocess;p2:process(clk_out)--时钟clk_out作用下的状态转换函数beginif(clk_out'eventandclk_out='1')thencurrent_state=next_state;endif;endprocess;p3:process(current_state)--当前状态所对应的输出函数begin-3-casecurrent_stateiswhens0=b=10000000;whens1=b=01000000;whens2=b=00100000;whens3=b=00010000;whens4=b=00001000;whens5=b=00000100;whens6=b=00000010;whens7=b=00000001;whens8=b=00000010;whens9=b=00000100;whens10=b=00001000;whens11=b=00010000;whens12=b=00100000;whens13=b=01000000;whens14=b=00000000;whens15=b=00011000;whens16=b=00111100;whens17=b=01111110;whens18=b=11111111;whens19=b=01111110;whens20=b=00111100;whens21=b=00011000;whens22=b=00000000;endcase;endprocess;endlight_1;六、仿真波形说明:为了仿真需要,在进行仿真事,将分频部分p0去掉,直接用clk作用进程p2-4-其中:Endtime=2msaperiodtime=60usclkperiodtime=2us七、故障及问题分析本次实验整体比较顺利,但仍旧出现了几个问题:开始并未设置分频器,clk的频率为50MHz,这个频率过高,若是直接用于提供时钟,不但不能看清现象,还会因为周期过短(可能会短于电路的延迟时间),导致输出错误。故加了一个50M的分频器,使作用的有效时钟信号为1Hz。其他未出现什么问题,顺利地完成了实验。八、总结和结论本学期数电实验共完成了4次实验,分别完成了以下四项任务:对实验板的熟悉;对Quarter的初步认识,并熟悉掌握其图形编译功能;对Quarter的进一步了解,初步结识VHDL语言,并用其实现了简单的计数器和译码器的功能,为最后一次实验打下基础;进一步熟悉VHDL语言,并用其实现实际电路设计;纵观四次实验,让我感触颇深的就是,预习对实验的重要性。QuarterII对我们来说是一个全新的东西,一切操作都得从头来学,好在它的界面友善,操作简单易懂,只是在编写VHDL程序的时候,需要事先学习其语言习惯。如果预习充分,就能很顺利地完成实验任务,还留有时间思考其它问题,完成额外的题目。实验要想仿真并下载成功,需要注意的细节很多,如,引脚设置、输入变量的周期设置等。在第三次实验时,我犯了个很愚蠢的错误——锁定引脚后没有让程序再运行compilation一遍,导致的结果就是,仿真完全正确,但下载到实验板上怎么就不能正确工作,白白耽误了很长时间。所以按部就班的操作是很必要的。实验中还有一些细节,在预习时并未注意,只有去实验室实际操作时才发现。如第三次实验实现7段数码译码器并用数码显示管显示时,预习时,并不知道,通过用一个八维向量c来控制8个数码显示管亮的管子的数量;再如第四次实验,预习的时候并不知道,板子上提供的时钟是50MHz,必须通过分频才能看清实验现象,就临场模仿书上例子做了分频器。四次实验,对我最有启发的是第四次实验。完成这次实验,需要思考实验需要完成的具体部分,将功能分成块,通过几个process分别完成。这种设计方法对我很有启发。相信在完成更大型的电路时,这种思想将起到很关键的作用。本学期的数电实验,完成了理论与实验的结合,将一些很抽象的理论概念具体地体现出来,如,门的延迟对输出波形的影响,冒险现象的产生原因等等。与此同时,我们学会了仿真工具QuarterII,初步掌握了VHDL语言,为理论学习提供了便利。这些都使数字电路的学习更具趣味性,同时更可以增强我们的动手动脑能力,从而达到学以致用的目的。-5-附录:第二、三次实验编程部分及仿真波形1.用QuarterII原理图输入法实现一个全加器,仿真验证其功能,并下载到实验板上测试,要求用拨码开关(SW1~SW3)作为输入,发光二极管(LD1~LD2)作为输出。2.用VHDL语言设计实现一个7段数码管译码器。实验内容及要求:在QuartusII平台上设计程序和仿真题目要求,并下载到实验板上验证实验结果。a)用拨码开关输入二进制数0000~1001;b)用数码显示管显示译码结果3.用VHDL语言设计并实现一个8421码十进制计数器。实验内容及要求:在QuartusII平台上设计程序和仿真题目要求,并下载到实验板上验证实验结果,用发光二极管显示计数值。实验1QuarterII原理图:实验1仿真波形-6-实验2VHDL语言LIBRARYIEEE;USEIEEE.STD_LOGIC_1164.ALL;ENTITYseg1ISPORT(a:INSTD_