交通灯控制器eda课程设计报告书大学论文.doc
EDA应用实训课程设计说明书目录1 绪论02 方案论证12.1程序设计的任务要求12.2方案选择13 单元模块53.1程序中使用的信号介绍:53.2子模块功能介绍:54 整体电路115 仿真及实物图125.2 实物图136心得16参考文献16附录17源程序171.绪论EDA课程教会了我们如何运用电脑辅助我们进行数字电路的设计。还教会了我们用于对FPGA进行编程的VHDL语言。我十分喜欢FPGA的编程,也觉得这次课程设计是一次实践的好机会。由于在之前我已经写过一些FPGA的程序,所以在拿到这个题目时我的思路还是比较清晰的。2.方案论证2.1程序设计的任务要求2.1.1初始条件:设计一个交通灯控制器,有一条主干道和一条支干道汇合成十字路口,在每个入口处设置红、黄、绿三色箭头信号灯,红灯亮禁止通行,绿灯亮允许通行,黄灯亮则给行驶中的车辆有时间停在禁行线外。2.1.2要求完成的主要任务: 2.1.2.1主干道和支干道构成的十字路口上有车辆交替运行,主干道每次直行通行时间为30s,左转通行时间为25s,支干道每次直行通行时间为20s,左转通行时间为15s。2.1.2.2每次绿灯变红灯时,黄灯先亮5s,才能变换运行车道。上述时间设置可修改。2.1.2.3十字路口有数码管显示灯亮时间,要求灯亮时间以秒为单位进行减计数。2.2方案选择2.2.1方案一 只使用一个计时器完成所有计时工作,通过计数到不同的数值时发出不同的脉冲信号告诉系统相应的计时值已到。该方案的优势在于占用资源少,只用使用一个计时器就可完成5种不同的计时。但不管是在哪一个状态都会调用该计时器,一旦该计时器出错,整个系统都会受影响,不利于系统的维护和模块化编程的思想。2.2.2方案二 使用5个计时器进行计时。在某个状态时,系统会调用相应的计时器开始计时,并且只检测相应计时器的计时完成脉冲信号。该方案的缺点在于占用FPGA资源多,但由于FPGA上资源足够,这个缺陷不影响系统工作。但它的优势是很明显的,它采用模块化编程设计,单个计时器的复杂度远远小于方案一中的计时器,并且5个计时器完全类似,只要完成一个计时器的设计就能轻易完成整个计时模块的设计。因此,我选择方案二进行设计。2.2.3设计思路整个程序设计可以分为4个部分,灯的显示部分、数码管的显示部分、计时部分和按键对倒计数时间的调整部分。灯的显示部分可用状态机实现。由于交通灯的显示状况是有限的几个状态,于是可以用状态机让灯在固定的几个状态中顺次切换。对于这个题目,我将灯的显示分了8个状态: 首先,所有交通灯有12个:主干道直行的红黄绿灯,主干道左转的红黄绿灯,次干道直行的红黄绿灯,次干道左转的红黄绿灯。主干道直行绿灯亮、主干道左转红灯亮、次干道直行和左转红灯亮;主干道直行黄灯亮、主干道左转红灯亮、次干道直行和左转红灯亮;主干道直行红灯亮、主干道左转绿灯亮、次干道直行和左转红灯亮;主干道直行红灯亮、主干道左转黄灯亮、次干道直行和左转红灯亮;主干道直行红灯亮、主干道左转红灯亮、次干道直行绿灯亮,次干道左转红灯亮;主干道直行红灯亮、主干道左转红灯亮、次干道直行黄灯亮,次干道左转红灯亮;主干道直行红灯亮、主干道左转红灯亮、次干道直行红灯亮,次干道左转绿灯亮;主干道直行红灯亮、主干道左转红灯亮、次干道直行绿灯亮,次干道左转黄灯亮;于是我定义了一个信号STATE用于存储状态机的状态:TYPE STATE_TYPE IS(A,B,C,D,E,F,G,H);SIGNAL STATE:STATE_TYPE:=A;-状态初始化为A数码管的显示部分。设置了5个计时器,分别是30s计时器、25s计时器、20s计时器、15s计时器和5s计时器。每个计时器都有一个使能EN信号,每个状态下只允许一个EN有效,当检测的计时器的EN信号有效时,就会将它的计数数值送到数码管显示。定义了一个常量数组:LED。代码如下:constant LED:data:=("11000000","11111001","10100100","10110000","10011001","10010010","10000010","11111000","10000000","10010000");-储存09的数码管显示字符将2位十进制数转化为2个8位二进制数显示的代码为:hh:=current_30s/10;ll:=current_30s rem 10;LED2<=LED(hh);LED1<=LED(ll); 计时部分使用5个计时器,每个计时器由使能信号EN控制启动。由计时完成信号SIN告知系统计时完成。 5个计时器结构类似,下面是计时器30S的程序代码:SANs:process(time_1s,stop,pause,en_30s)beginif stop='1' then current_30s<=set_30s;elsif pause='1' thenelsif en_30s='0' thencurrent_30s<=set_30s;sin_30s<='0'elsif time_1s'event and time_1s='1' then current_30s<=current_30s-1;if sin_30s='1' then sin_30s<='0'end if;if current_30s=0 then sin_30s<='1' current_30s<=set_30s;end if;end if;end process SANs; 按键对倒计数时间的调整部分。设置了四个键用于计数时间的调整:stop键用于从正常运行模式跳转到调整模式,change键用于选择调整5个计数器中哪一个的值,plus和minus键用于加或减相应计数器的值。由于要用一个change键控制5个状态的转化,于是在这儿又用了一个状态机。 状态信号set_LED定义如下:TYPE set_typeIS(A,B,C,D,E);SIGNAL set_LED:set_type; 状态变换部分代码:IF change='0' THENcase SET_LED is when A=>set_LED<=B;when B=>set_LED<=C;when C=>set_LED<=D;when D=>set_LED<=E;when E=>set_LED<=A;end case;END IF;3.单元模块3.1程序中使用的信号介绍: signal time_1s,time_ms:std_logic;signal sin_30s,sin_25s,sin_20s,sin_5s,sin_15s :std_logic;-定义30s,25s,15s,5s计时模块的信号线,计满相应秒数后输出,高有效signal en_30s,en_25s,en_20s,en_5s,en_15s :std_logic;-定义30s,25s,15s,5s计时模块的使能端,高有效signal set_30s,set_25s,set_20s,set_5s,set_15s :integer range 0 to 100;-设定计时初始值signal current_30s,current_25s,current_20s,current_5s,current_15s:integer range 0 to 99;3.2子模块功能介绍:3.2.1分频器 将学习板上50MHZ的晶振信号分频为1HZ和0.2HZ,tex为测试信号,频率为1HZ用于观测分频器是否工作正常。如下图所示:图3-2-1分频器3.2.2交通信号灯控制模块 根据STATE的状态来点亮各个交通灯。当pause或stop信号为高时,灯的显示状态保持。如下图所示:图3-2-2交通信号灯控制模块3.2.3 STATE信号以及计时器使能信号控制器 根据STATE的现态和sin_30s、sin_25s、sin_20s、sin_15s、sin_5s信号的状态可以决定STATE信号的状态切换和5个计时器的使能。当stop信号为1的时候,sin_30s被置1,sin_25s、sin_20s、sin_15s和sin_5s被置0。STATE信号被置A。如下图所示:图3-2-3 STATE信号以及计时器使能信号控制器3.2.4计时值设置模块 当stop置1时启用计时值设置模块,当change按下时会在5个计时器之间转换,按plus或minus时会将相应的计时器设置值加一或减一。如下图所示:图3-2-4计时值设置模块3.2.5 数码管倒计时显示模块 当stop为0时为正常显示模式,实时显示当前被使能的计时器的值。当stop值为1时为指示模式,显示当前调整计时值设置模块调整的计时器编号。如30S计时器的编号为30,当调整计时器30S的计时值时,数码管将显示30。如下图所示:图3-2-5 数码管倒计时显示模块3.2.6 25号计时器 计时初值为25s。当set_25s变化时,它会实时从set_25s中读取新的计时值。当25s倒计时计到0时,sin_25s端会送出一个高电平脉冲,表示计时完成。如下图所示:图3.2.6 25号计时器3.2.7 20号计时器 计时初值为20s。当set_20s变化时,它会实时从set_20s中读取新的计时值。当20s倒计时计到0时,sin_20s端会送出一个高电平脉冲,表示计时完成。如下图所示:图3.2.7 20号计时器3.2.8 30号计时器 计时初值为30s。当set_30s变化时,它会实时从set_30s中读取新的计时值。当30s倒计时计到0时,sin_30s端会送出一个高电平脉冲,表示计时完成。如下图所示:图3.2.8 30号计时器3.2.9 15号计时器。 计时初值为15s。当set_15s变化时,它会实时从set_15s中读取新的计时值。当15s倒计时计到0时,sin_15s端会送出一个高电平脉冲,表示计时完成。如下图所示:图3-2-9 15号计时器3.2.1 05号计时器计时初值为5s。当set_5s变化时,它会实时从set_5s中读取新的计时值。当5s倒计时计到0时,sin_5s端会送出一个高电平脉冲,表示计时完成。如下图所示:图3-2-1 05号计时器4.整体电路总体的模块图共有十个模块:一个分频器模块,5个计时器模块,一个交通信号灯控制模块,一个STATE信号以及计时器使能信号控制模块,一个数码管倒计时显示模块以及一个计时值设置模块。如下图所示:图4 系统整体模块图5.仿真及实物图5.1 ModelSim仿真图该图显示了控制交通灯的状态机的工作状况。Stop置0,pause置0,系统工作在正常模式下。STATE状态信号以A->B->C->D->E->F->G->H->A变化。如下图所示:图5-1-1交通灯状态变换ModelSim仿真图该图显示了按键设置部分的状态机运行状况,此时stop置1,change置0,系统工作在停止以及设置模式下。SET_LED会以A=>B=>C=>D=>E=>A变化。如下图所示:图5-1-2 按键设置部分状态机ModelSim仿真图5.2 实物图图5-2-1是初始化界面,系统从30开始倒计时,此时灯亮的状态为:主干道直行绿灯亮、主干道左转红灯亮、次干道直行红灯亮、次干道左转红灯亮。车道的状态为只允许主干道车辆直行。如下图所示:图5.2.1 初始化界面 初始化界面之后,系统开始30S倒计时。如下图所示:图5-2-2 正常运行界面30S倒计时阶段30S倒计时完成后,亮5s黄灯后,进入25S倒计时界面,此时灯亮的状态为: 主干道直行红灯亮、主干道左转绿灯亮、次干道直行红灯亮、次干道左转红灯亮。车道的状态为只允许主干道车辆左转。如下图所示:图5-2-3正常运行界面25S倒计时阶段对30S计时器的初值进行设置,其初始化值为30,现在已经被调整为26。前两个数码管显示当前设定后的初值,后两个数码管显示当前调整的计时器的编号。如下图所示:图5.2.4设置30S计时器的计时初值界面系统可对所有计时器进行初值设定,图5-2-5为对20S计时器做初值设定。前两个数码管显示当前设定后的初值,后两个数码管显示当前调整的计时器的编号。如下图所示:图5-2-5设置20S计时器的计时初值界面图5-2-6为对05S计时器做初值设定。前两个数码管显示当前设定后的初值,后两个数码管显示当前调整的计时器的编号。如下图所示:图5-2-6设置05S计时器的计时初值界面6心得 作为工科生,在大学里进行这样的实习的时候还是不多的。我也非常珍惜,希望能学到一些课堂上学不到的东西。运用课堂学习的东西做课设一般是是不够的,于是这就考验了我们在略有思路的情况下如何迅速的通过自学或试验来获取课程设计中需要的知识和经验,并理清思路做出设计并仿真调试最终做出实物来。 我在课设期间的收获很大。除了在FPGA编程上又得到了一次难得的历练外,我还学会使用了ModelSim这一功能强大的仿真软件。参考文献1 徐志军,王金明等.EDA技术与VHDL设计 .北京:电子工业出版社,2009年2 贝耶尔,刘凌. 数字信号处理的FPGA实现.北京:清华大学出版社,2011年3 高亚军. 基于FPGA的数字信号处理.北京:电子工业出版社,2012年4 张凯虹. 一种FPGA验证与测试的方法介绍.计算机与数字工程,2010年第9期5 童鹏,胡以华. FPGA器件选型研究.现代电子技术,2007年第20期附录源程序libraryieee;useieee.std_logic_unsigned.all;use ieee.std_logic_1164.all;useieee.std_logic_arith.all;entity traffic isport(stop,pause,plus,minus,change,clk :in std_logic;MR,MY,MG,BR,BY,BG,MLR,MLY,MLG,BLY,BLR,BLG,tex:outstd_logic;LED1 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);LED2 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);LED3 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);LED4 : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);end traffic;architecture one of traffic is TYPE STATE_TYPE IS(A,B,C,D,E,F,G,H);SIGNAL STATE:STATE_TYPE:=A;signal time_1s,time_ms:std_logic;signal sin_30s,sin_25s,sin_20s,sin_5s,sin_15s:std_logic;signal en_30s,en_25s,en_20s,en_5s,en_15s :std_logic;signal set_30s,set_25s,set_20s,set_5s,set_15s:integer range 0 to 100;signal current_30s,current_25s,current_20s,current_15s,current_5s:range 0 to 99; type data is array(0 to 9) of std_logic_vector(7 downto 0); constant LED:data:=("11000000","11111001","10100100","10110000","10011001","10010010","10000010","11111000","10000000","10010000"); TYPE set_typeIS(A,B,C,D,E); SIGNAL set_LED:set_type; BEGINno1:process(clk)variable i:INTEGER RANGE 0 TO 25_000_000;variable j:INTEGER RANGE 0 TO 25_000_000;beginifclk'event and clk='1' then i:=i+1;j:=j+1;if j=50_00000 then time_ms<=not time_ms;j:=0;end if;ifi=25_000_000 then tex<=time_1s; time_1s<=not time_1s;i:=0;end if;end if;end process no1;no2:process(STATE)beginif stop='1' thenelsif pause='1' thenelse case STATE is WHEN A=>MR<='0'MY<='0'MG<='1'BR<='1'BY<='0'BG<='0'MLR<='1'MLY<='0'MLG<='0'BLY<='0'BLR<='1'BLG<='0' WHEN B=>MR<='0'MY<='1'MG<='0'BR<='1'BY<='0'BG<='0'MLR<='1'MLY<='0'MLG<='0'BLY<='1'BLR<='1'BLG<='0' WHEN C=>MR<='1'MY<='0'MG<='0'BR<='1'BY<='0'BG<='0'MLR<='0'MLY<='0'MLG<='1'BLY<='0'BLR<='1'BLG<='0' WHEN D=>MR<='1'MY<='0'MG<='0'BR<='1'BY<='0'BG<='0'MLR<='0'MLY<='1'MLG<='0'BLY<='1'BLR<='1'BLG<='0' WHEN E=>MR<='1'MY<='0'MG<='0'BR<='0'BY<='0'BG<='1'MLR<='1'MLY<='0'MLG<='0'BLY<='0'BLR<='1'BLG<='0' WHEN F=>MR<='1'MY<='0'MG<='0'BR<='0'BY<='1'BG<='0'MLR<='1'MLY<='0'MLG<='0'BLY<='1'BLR<='1'BLG<='0' WHEN G=>MR<='1'MY<='0'MG<='0'BR<='1'BY<='0'BG<='0'MLR<='1'MLY<='0'MLG<='0'BLY<='0'BLR<='0'BLG<='1' WHEN H=>MR<='1'MY<='0'MG<='0'BR<='1'BY<='0'BG<='0'MLR<='1'MLY<='0'MLG<='0'BLY<='1'BLR<='0'BLG<='0' END CASE;end if;end process no2; no3:process(sin_30s,sin_25s,sin_20s,sin_5s,sin_15s,stop,pause,clk,state)variableint:std_logic:='0'beginif stop='1' thenstate<=A; en_30s<='0' en_25s<='0' en_20s<='0' en_5s<='0' en_15s<='0'int:='0'elsif pause='1' thenelseifclk'event and clk='1' then ifint='0' thenstate<=A; en_30s<='1' en_25s<='0' en_20s<='0' en_5s<='0' en_15s<='0'int:='1'end if;case STATE is WHEN A=>if sin_30s='1' then STATE<=B; EN_30S<='0' EN_5S<='1'end if; WHEN B=>if sin_5s='1' then STATE<=C; EN_5S<='0' EN_25S<='1'end if; WHEN C=>if sin_25s='1' then STATE<=D; EN_25S<='0' EN_5S<='1'end if; WHEN D=>if sin_5s='1' then STATE<=E; EN_5S<='0' EN_20S<='1'end if; WHEN E=>if sin_20s='1' then STATE<=F; EN_20S<='0' EN_5S<='1'end if; WHEN F=>if sin_5s='1' then STATE<=G; EN_5S<='0' EN_15S<='1'end if; WHEN G=>if sin_15s='1' then STATE<=H; EN_15S<='0' EN_5S<='1'end if; WHEN H=>if sin_5s='1' then STATE<=A; EN_5S<='0' EN_30S<='1'end if; END CASE; END IF;end if; END process no3;set:process(time_ms,stop,pause,plus,minus,change) -TYPE set_typeIS(A,B,C,D,E);- variableset:set_type;variableint:std_logic:='0' VARIABLE HH,LL:INTEGER RANGE 0 TO 9;beginiftime_ms'event and time_ms='1' thenifint='0' then set_30s<=30; set_25s<=25; set_20s<=20; set_5s<=5; set_15s<=15;set_LED<=A;int:='1'end if;if stop='1' then if change='0' then fori IN 0 to 25 loopend loop;if change='0' then case SET_LED is when A=>set_LED<=B;when B=>set_LED<=C;when C=>set_LED<=D;when D=>set_LED<=E;when E=>set_LED<=A;end case;END IF;END IF;case SET_LED is when A=>hh:=SET_30s/10;ll:=SET_30s rem 10; LED4<=LED(hh); LED3<=LED(ll);if plus='0' then fori IN 0 to 25 loopend loop;if plus='0' thenset_30s<=set_30s+1;hh:=SET_30s/10;ll:=SET_30s rem 10; LED4<=LED(hh); LED3<=LED(ll);end if;end if;if minus='0' then fori IN 0 to 25 loopend loop;if minus='0' thenset_30s<=set_30s-1;hh:=SET_30s/10;ll:=SET_30s rem 10; LED4<=LED(hh); LED3<=LED(ll);end if;end if;when B=>hh:=SET_25s/10;ll:=SET_25s rem 10; LED4<=LED(hh); LED3<=LED(ll);if plus='0' then fori IN 0 to 25 loopend loop;if plus='0' thenset_25s<=set_25s+1;hh:=SET_25s/10;ll:=SET_25s rem 10; LED4<=LED(hh); LED3<=LED(ll);end if;end if;if minus='0' then fori IN 0 to 25 loopend loop;if minus='0' thenset_25s<=set_25s-1;hh:=SET_25s/10;ll:=SET_25s rem 10; LED4<=LED(hh); LED3<=LED(ll);end if;end if;when C=>hh:=SET_20s/10;ll:=SET_20s rem 10; LED4<=LED(hh); LED3<=LED(ll);if plus='0' then fori IN 0 to 25 loopend loop;if plus='0' thenset_20s<=set_20s+1;hh:=SET_20s/10;ll:=SET_20s rem 10; LED4<=LED(hh); LED3<=LED(ll);end if;end if;if minus='0' then fori IN 0 to 25 loopend loop;if minus='0' thenset_20s<=set_20s-1;hh:=SET_20s/10;ll:=SET_20s rem 10; LED4<=LED(hh); LED3<=LED(ll);end if;end if;when D=>hh:=SET_15s/10;ll:=SET_15s rem 10; LED4<=LED(hh); LED3<=LED(ll);if plus='0' then fori IN 0 to 25 loopend loop;if plus='0' thenset_15s<=set_15s+1;hh:=SET_15s/10;ll:=SET_15s rem 10; LED4<=LED(hh); LED3<=LED(ll);end if;end if;if minus='0' then fori IN 0 to 25 loopend loop;if minus='0' thenset_15s<=set_15s-1;hh:=SET_15s/10;ll:=SET_15s rem 10; LED4<=LED(hh); LED3<=LED(ll);end if;end if;when E=>hh:=SET_5s/10;ll:=SET_5s rem 10; LED4<=LED(hh); LED3<=LED(ll);if plus='0' then fori IN 0 to 25 loopend loop;if plus='0' thenset_5s<=set_5s+1;hh:=SET_5s/10;ll:=SET_5s rem 10; LED4<=LED(hh); LED3<=LED(ll);end if;end if;if minus='0' then fori IN 0 to 25 loopend loop;if minus='0' thenset_5s<=set_5s-1;hh:=SET_5s/10;ll:=SET_5s rem 10; LED4<=LED(hh); LED3<=LED(ll);end if;end if;end case;elseLED4<="11111111"LED3<="11111111"END IF;end if;end process set;SANs:process(time_1s,stop,pause,en_30s)beginif stop='1' then current_30s<=set_30s;elsif pause='1' thenelsif en_30s='0' thencurrent_30s<=set_30s;sin_30s<='0'elsif time_1s'event and time_1s='1' then current_30s<=current_30s-1;if sin_30s='1' then sin_30s<='0'end if;if current_30s=0 then sin_30s<='1' current_30s<=set_30s;end if;end if;end process SANs;ERs:process(time_1s,stop,pause,en_25s)beginif stop='1' then current_25s<=set_25s;elsif pause='1' thenelsif en_25s='0' then current_25s<=set_25s; sin_25s<='0'elsif time_1s'event and time_1s='1' then current_25s<=current_25s-1;if sin_25s='1' then sin_25s<='0'end if;if current_25s=0 then sin_25s<='1' current_25s<=set_25s;end if;end if;end process ERs;ERSHIs:process(time_1s,stop,pause,en_20s)beginif stop='1' then current_20s<=set_20s;elsif pause='1' thenelsif en_20s='0' then current_20s<=set_20s; sin_20s<='0'elsif time_1s'event and time_1s='1' then current_20s<=current_20s-1;if sin_20s='1' then sin_20s<='0'end if;if current_20s=0 then sin_20s<='1' current_20s<=set_20s;end if;end if;end process ERSHIs;Ws:process(time_1s,stop,pause,en_5s)beginif stop='1' then current_5s<=set_5s;elsif pause='1' thenelsif en_5s='0' then current_5s<=set_5s; sin_5s<=