数字逻辑与数字系统设计之电梯控制器设计
数字逻辑与数字系统设计之电梯控制器设计
一、设计目的及要求
设计要求
- 电梯最少可以往返于0—9层楼。
- 乘客要去的楼层数A可手动输入并显示,按取消键可清除本次输入。
- 可自动显示电梯运行的楼层数B
- 当A>B时,电梯上升;
当A<B时,电梯下降;
当A=B时,电梯停止运行并开门; - 可以自动显示电梯每一次启停之间的运行时间
- 任何时候按下复位键,电梯回到1层。
设计目的
目的是对“数字逻辑”课程内容全面、系统的总结、巩固和提高。根据数字逻辑的特点,选择相应的题目,在老师的指导下,由学生独立完成。通过实验使我们掌握数字逻辑电路设计的基本方法和技巧,正确运用vivado软件及实验室多功能学习机硬件平台,完成所选题目的设计任务,并掌握数字逻辑电路测试的基本方法,训练学生的动手能力和思维方法。通过实验,一方面提高运用数字逻辑电路解决实际问题的能力,另一方面使学生更深入的理解所学知识,为以后的计算机硬件课程的学习奠定良好的基础。
二、工作原理和系统框图
工作原理
本实验使用板上的四个开关来模拟电梯的叫梯按键,其中每个按钮有两个状态0和1,4个组成了电梯的叫楼层,将这4位二进制数字看成8421BCD码,转换成十进制数字。
对于电梯按键,当没用用户叫梯时,叫梯的数码管BIT5(G1)显示为0;当有用户叫梯时,控制叫梯的数码管显示为用户所叫的电梯楼层。
电梯运行时,显示电梯运行层数的数码管BIT1(G2)显示电梯运行的层数,假设电梯每运行一层的时间为1s,则该数码管BIT1(G2)数码管在转变为“0”之前显示的数字即为电梯运行的时间。
当SW1-N4 为1时,电梯回到0层。
系统框图
三、各部分模块具体功能及设计思路
各部分选定方案
1.目的:电梯可以往返于0~9层楼,显示当前电梯的楼层B
;实现方法:用计数器来实现0~9之间的变化,并通过译码器接到数码管(BIT8)上显示
2.目的:手动输入要去的楼层A ,按取消键可清除本次输入。实现方法:A 用四个开关来表示,通过译码器接到7段数码管(BIT5)上显示相应的楼层数A。
3.目的:当A>B 时,电梯上升;当A<B 时,电梯下降;当A=B 时,电梯停止运行。实现方法:通过比较器来比较A 与B 的大小,若A>B 电梯上升,否则电梯下降,
4.目的:可以自动显示电梯每一次启停之间的运行时间。实现方法;继承3)的实现方法,若A>B 则计数器正向计数,若A<B 则计数器逆向计数。
5.目的:按下复位键时,电梯回到0层。实现方法:当复位启动时,则不论A 怎么输入,电梯都停在第0层。
相关模块
比较器(Compare)
输入电梯所在楼层B ,乘客要去的楼层 A ,输出O1O2,当A>B 时,输出01;当A<B 时,输出10;当A=B 时,输出00;
代码:
module Compare(A,B,O1,O2);input [3:0]A;//要去的楼层Ainput [3:0]B;//电梯所在楼层Boutput O1;output O2;assign O1 = (A>B);//A>B 输出01assign O2 = (A<B); //A<B 输出10endmodule
复位模块(IfReset)
输入reset 和In ,In 是一个4位的数组。当reset=1时,Out=0,电梯无论在几楼都会回到0楼;当reset==0时,输出Out=In ,接着运行下面的功能。
代码:
module IfReset (In, Out, reset);input [3:0] In;input reset;output reg [3:0]Out;always begin #2if(reset)Out = 0;//如果reset = 1 则清零else Out = In;//如果reset!=1 则输入即为输出endendmodule
节拍发生器(BeatGenerator)
由于数码管只有七个管脚,AB 不能同时显示在同一个数码管上,所以通过节拍发生器来选择显示。因为时钟频率高达100MHz,所以肉眼所见的是A 和B 同时显示。
代码:
module BeatGenerator(in1,in2,clk,sec,Out);input [6:0]in1;//输入Ainput [6:0]in2;//输入Binput clk;//时钟信号output reg [1:0]sec;output reg [6:0]Out;reg [7:0]ControlLED;//七段数码管initial //初始化变量
beginsec = 1;Out = in1;ControlLED = 0;endalways @(posedge clk)beginControlLED = ControlLED + 1;if(sec==1) //分频显示beginOut =in2;endelse beginOut=in1;endendalways @(negedge ControlLED)beginif(sec==1)beginsec=2;endelsebeginsec=1;endendendmodule
分频模块(FrequenceDivide)
将100MHz的时钟信号转换为肉眼可见的信号
代码:
module FrequenceDivide(inClk, outClk);input inClk; //输入时钟信号output outClk;//输出时钟信号reg [31:0]timeClk;//暂存时钟信号(32位)assign outClk = timeClk[19];//每2^20ns 时钟沿变化一次initial begintimeClk = 0;endalways@(posedge inClk)begintimeClk = timeClk + 1;endendmodule
译码器(Decoder)
将4位的A和B转换为七段数码管显示对应的数字
代码:
module Decoder(floor, outLED, on);input [3:0]floor;//楼层input on;//运行状态 运行on=1,未运行on=0output reg[6:0]outLED;//输出的显示always @(*)beginif(!on)outLED=7’b0000001;//未运行状态elsecase(floor)4’b0000:outLED=7’b1111110; //0
4’b0001:outLED=7’b0110000; //1
4’b0010:outLED=7’b1101101; //2
4’b0011:outLED=7’b1111001; //3
4’b0100:outLED=7’b0110011; //4
4’b0101:outLED=7’b1011011; //5
4’b0110:outLED=7’b1011111; //6
4’b0111:outLED=7’b1110000; //7
4’b1000:outLED=7’b1111111; //8
4’b1001:outLED=7’b1111011; //9
default: outLED= 7’b1001111; /E(error) endcaseendendmodule
计时器(clock)
计时器有一个暂停键与计数器的使能端相连,当switch1=switch0=0时,计时器的暂停键有效,计时器不计时;当switch1=1或switch0=1,计时器工作,且每次计时完成后归零,并从下一次电梯开始工作时计时。
代码:
module clock(input show,input clk,input pause,input rst,output reg sm_bit,output reg[6:0]sm_seg
);
reg [3:0]timesec0;
initial beginsm_bit=1;sm_seg=1;timesec0=0;end
always @(posedge clk)
begin
if(pause) beginif(timesec0==9)timesec0=0;elsetimesec0=timesec0+1;endend
always@(posedge show)
begincase(timesec0)0:sm_seg= 7’b1111110; //01:sm_seg= 7’b0110000; //12:sm_seg= 7’b1101101; //23:sm_seg= 7’b1111001; //34:sm_seg= 7’b0110011; //45:sm_seg= 7’b1011011; //56:sm_seg= 7’b1011111; //67:sm_seg= 7’b1110000; //78:sm_seg= 7’b1111111; //89:sm_seg= 7’b1111011; //9default: sm_seg= 7’b0000000; //空白endcase
end
endmodule
可逆计数器
module counter(input clk,input switch0,input switch1,output reg[3:0] sl_reg
);initial beginsl_reg = 0;
end
always @(posedge clk)begincase({switch0,switch1})2’b01:sl_reg=sl_reg-1;2’b10:sl_reg=sl_reg+1;default:;endcaseend
endmodule
四、调试过程
- 检查Verilog 代码是否有语法错误(由vivado 自动检测)
- 检查各个IP 核的功能是否正确,看它的仿真波形图是否正确
- 检查逻辑图中的IP 核连线是否正确,人工代特值进入电路看是否有输出错误。
- 至此调试过程结束
五、设计结论
本次设计在 FPGA 开发板上实现了电梯控制器,通过查阅资料,和同学交流经验,分模块化编程,使得该设计得以实现。做了比较器复位模块、节拍发生器、分频模块、译码器、计时器、可逆计数器等模块。最后综合时,我进行了分模块化的仿真和总体功能的测试,对出现的问题进行反复调试。
本次设计的不足之处是对于乘客想要去的楼层 A 的输入没有很好的控制,比如从0去往9层时无法直接调整为9,需要先去8层再去9层,或者先去1层再去9层。到最后也不知道怎么设计能够解决这个问题。
在后续的学习中,希望我能够多多查阅资料,在网上的资料查询以及Debug 能够更加深刻理解代码的原理,以及各个代码之间的逻辑关系,让自己的能力和耐力有更进一步的提升。
六、设计心得与总结
数电大作业是对于Verilog 语句学习一次非常难得的理论与世纪相结合的机会,通过这次比较完整的电梯控制器的设计,我摆脱了单纯的理论知识学习状态,和实际设计的结合锻炼了我的综合运用所学的专业基础知识,解决实际电路设计问题的能力,同时也提高了我查阅文献资料、EGO 开发板参考手册、以及调试 Verilog代码的能力,而且通过对整体的掌控,对局部的取舍,以及对细节的斟酌处理,都使我的能力得到了锻炼,经验得到了丰富,并且意志品质力,抗压能力以及耐力也都得到了不同程度的提升。这是我希望看到的也正是我进行数电大作业设计的目的所在。
在没有做电梯控制器之前觉得电梯控制器只是简单的逻辑加减以及计数,但是通过真正的实践才发现自己的看法有点太过于片面。这次大作业不仅是对前面所学知识的一种检验,而且也是对自己能力的一种提高。通过这次大作业使我明白了自己原来知识还比较欠缺,自己要学习的东西还是太多了。
刚选择电梯控制器这个设计是感觉会很简单,因为这是我们生活中经常用到的东西,对于其功能的了解和基础原理有简单的了解,但是在真正实践时发现自己的理解还是过于片面。
在设计过程中也遇到了很多问题,比如不能在两个以上的always里面给变量赋值,刚开始编程的时候并没有想到这个问题,觉得符合逻辑,但是语法就是不能通过,还有就是有些变量忘记声明就去使用,或者是打代码打到最后if/end 或者begin/ end 不匹配导致编译不通过,这些简单的小错误积累起来就是一个很大的错误,它反映了我对于 Verilog 代码的生疏。经历这次大作业设计,也提升了我辨析Verilog 语法,以及代码的 debug 能力。
在设计过程中,我通过查阅大量有关资料,和同学交流经验和自学,使自己更加了解了 Verilog 以及 Vivado 的使用。在整个设计中我懂得了很多东西,也培养了我独立工作的能力,树立了对自己工作能力的信心,相信会对今后的学习生活有非常重要的影响。而且大大提高了动手的能力,使我充分体会到了在创造过程中探索的艰难和成功时的喜悦。虽然这次电梯控制器还有一些不足之处,但是在设计过程中所学到的东西是这次毕业设计的最大收获和财富。
附录1:总体设计图
附录2:各模块仿真结果
1比较器
2复位模块
3节拍发生器
4译码器
5计时器
6可逆计数器