简易电梯控制系统设计(两层楼)(

 (电子科技大学  数字系统实验二 结课验收项目  fpga板 veriolg语言))

第一次写,实属小白,写的不好请见谅。就对这个设计提供自己的一点思路看法

题目要求:

简易电梯控制系统设计(两层楼)(_第1张图片

简易电梯控制系统设计(两层楼)(_第2张图片

简易电梯控制系统设计(两层楼)(_第3张图片

板子了一般都是学校发的板子,我用的板子就是学校发的。(电子科技大学自主研发的板子)

正文:

对于这个项目,我将之分为顶层文件,时钟分频模块,电梯模块,矩阵键盘模块,动态显示模块。

顶层文件(代码):

module top(
  input clk,
  input set,    //T9启动信号
  input reset,  //f3 复位信号
  input [3:0]col,
  output  [3:0]row,
  output  [3:0]led,
  output [5:0]dig,
  output [7:0]seg
    );
    wire clk_1k;
    wire clk_50;
    wire clk_4s;
 
  fenpin u1(.clk(clk),
         .clk_1k(clk_1k),
         .clk_50(clk_50),
         .clk_4s(clk_4s));
         
         wire k0;
         wire k4;
         wire k3;
         wire k7;
  keyboard u2(
         .clk_1k(clk_1k),//键盘扫描
         .clk_50(clk_50),//按键消抖
         .col(col),
         .row(row),//行初值
         .upButton(k0),//对应一楼按键
         .downButton(k4),//对应二楼按键
         .upstair(k3),
         .downstair(k7));//对应电梯内1 2按键  
         
        wire [1:0]state;
             wire [1:0]floor;      
  dian_ti u3(
                      .clk(clk),
                      .set(set),
                       .reset(reset),
                      .key0(k0),
                      .key4(k4),
                      .key7(k7),
                      .key3(k3),
                      .led(led),//指示灯
                      .state(state),//00待机状态 01上行状态 10下机状态
                      .floor(floor) ); //楼层 01一楼 10二楼 
   dynamic_led2 u4(
                                       .floor(floor),
                                       .state(state),
                                       .clk(clk_1k),
                                       .seg(seg),
                                       .dig(dig)
                                       );              
endmodule

 分频模块:初始时钟源即板上时钟源为50Mhz, 这里有个失误,4s的分频时钟这里没用到,设计的时候多余了

module fenpin(clk,clk_1k,clk_50,clk_4s);
      inout clk;
      output reg clk_1k=0;
      output reg clk_50=0;
      output reg clk_4s=0;
      
      reg[24:0] clk_div_cnt0=0;
      reg[24:0] clk_div_cnt1=0;
      reg[24:0] clk_div_cnt2=0;
      //1khz
      always @ (posedge clk)
              begin
                  if (clk_div_cnt0==25000)//分频
                  begin
                      clk_1k=~clk_1k;
                      clk_div_cnt0=0;
                  end
                  else 
                      clk_div_cnt0=clk_div_cnt0+1;
             end
    //50hz         
       always @ (posedge clk)
             begin
                 if (clk_div_cnt1==499999)//分频
                         begin
                           clk_50=~clk_50;
                           clk_div_cnt1=0;
                          end
                  else 
                       clk_div_cnt1=clk_div_cnt1+1;
                          end 
     //4s                          
         always @ (posedge clk)
                 begin
                 if (clk_div_cnt2==9999999)//分频
                       begin
                        clk_4s=~clk_4s;
                        clk_div_cnt2=0;
                        end
                        else 
                         clk_div_cnt2=clk_div_cnt2+1;
                  end      
endmodule

矩阵键盘:进行按键扫描后进行按键消抖,这里对16个按键都进行了扫描,但由于只用四个按键所以只对四个按键进行消抖

module keyboard(
input clk_1k,//键盘扫描
input clk_50,//按键消抖
input [3:0]col,
output reg [3:0]row=4'b0001,//行初值
output  upButton,//对应一楼按键
output  downButton,//对应二楼按键
output  upstair,
output  downstair);//对应电梯内1 2按键

reg [15:0] btn=0;//初始化为0
always @ (posedge clk_1k)
    begin
    	if (row[3:0]==4'b1000)
             row[3:0]=4'b0001;//到了1000,下一个是0001
    	else
             row[3:0]=row[3:0]<<1; //向左移一位。0001-0010-0100-1000-0001
   end

always @ (negedge clk_1k)
    begin
        case (row[3:0])
    	4'b0001:
    	   begin
    	   	btn[3:0]=col;   //列输入值存至4位寄存器
    	   end
    	4'b0010:
    	   begin
    	   btn[7:4]=col;
    	   end
    	4'b0100:
    	   begin
    	   btn[11:8]=col;
    	   end
    	4'b1000:
    	   begin
    	   btn[15:12]=col;
    	   end 
    	default:btn=0;   		   
        endcase
    end 
   
  ajxd u0(
        .btn_in(btn[0]), 
        .clk(clk_50),
        .btn_out(upButton)
        );   
   ajxd u1(
         .btn_in(btn[4]), 
         .clk(clk_50),
         .btn_out(downButton)
          ); 
  ajxd u2(
         .btn_in(btn[3]), 
         .clk(clk_50),
         .btn_out(upstair)
           );  
  ajxd u3(
         .btn_in(btn[7]), 
         .clk(clk_50),
         .btn_out(downstair)
           );  
                                                        
endmodule

按键消抖:

module ajxd(
    input btn_in, 
    input clk,
    output btn_out
    );  
    reg  btn0=0;//定义了btn0寄存器
    reg  btn1=0;//定义了btn1寄存器
    reg  btn2=0;//定义了btn2寄存器
    reg[24:0] clk_div_cnt=0;
    reg btn_clk=0;

 always@ (posedge clk)
      begin
          btn0<=btn_in;
          btn1<=btn0;
         btn2<=btn1;
      end
      assign btn_out=(btn2&btn1&btn0)|(~btn2&btn1&btn0);
endmodule

电梯模块:就实验要求的效果,算是实现了(gate信号是电梯开关门信号,这里不用管,没用到)

module dian_ti(
input clk,
input set,
input reset,
input key0,
input key4,
input key3,
input key7,
output reg [3:0]led=0,//指示灯
output reg [1:0]state=0,//00待机状态 01上行状态 10下机状态
output reg [1:0]floor=1  //楼层 01一楼 10二楼 
	);

reg gate;//关门状态
reg [2:0] num;
reg [27:0]clk_count=0;


always@(posedge clk)
  begin
    if(!reset)
       begin
        led=4'b0000;
        state=0;
        floor=1;
        gate=0;
       end
   else if(set)
   begin
    if(led)
       begin 
         if(clk_count==199999999) 
          begin            
                clk_count=0;                           
                if((floor==1))  begin floor=floor+1; end
                else          begin floor=floor-1; end                     
                state=0;         
                led=4'b0000;
          end
         else  clk_count=clk_count+1;
       end
 else if((key0)&&state==0)  //一楼按下key0且电梯待机
                 begin                
                         if(floor==2)
                           begin
                           led[0]=1; //一楼电梯外灯亮
                           state=2;  //下行状态
                           end
                          gate=1;     //到达一楼 打开门
                  end 
                  
         else if((key4)&&state==0)
                          begin
                              if(floor==1)
                              begin
                                  led[1]=1;//二楼电梯外灯亮
                                  state=1;//上行
                              end
                              gate=1;//到达二楼,门开
                          end
                       
           else if((key3)&&floor==1)  //在一楼 电梯内按下 且门是开的 
                                 begin
                                     led[2]=1;
                                     gate=0;  //关电梯门
                                    state=1; //电梯上行
                                 end 
          else if((key7)&&floor==2)  //在二楼 电梯内按上 且门是开的 
                                   begin
                                   led[3]=1;
                                   gate=0;  //关电梯门
                                   state=2; //电梯下行
                                   end                                 
            end
         end
       endmodule

动态显示模块:结果显示在最右边的两位数码管上

module dynamic_led2(
input [1:0]floor,//楼层
input [1:0]state,//状态
input gate,//门
input clk,
output reg [7:0] seg,
output reg [5:0] dig
);
reg [1:0] num=0;
	always @ (posedge clk)
	begin
		if (num>=1)
			num=0;
		else
			num=num+1;
	end
	
	//译码器
	always @ (num)
	begin	
		case(num)
		0:dig=6'b111110;
		1:dig=6'b111101;
		//3:dig=6'b111011;
		default: dig=0;
		endcase
	end
	
	//选择器,确定显示数据
	reg [3:0] disp_data;
	always @ (num)
	begin	
		case(num)
		0:disp_data=floor;
		1:disp_data=state+3'b011;
		//2:disp_data=gate+6;
		//3:disp_data=
		default: disp_data=0;
		endcase
	end
	//显示译码器
	always@(disp_data)
	begin
		case(disp_data)
		4'h1: seg=8'h06;
		4'h2: seg=8'h5b;
		4'h3: seg=8'h40;//待机
		4'h4: seg=8'h01;//上行
		4'h5: seg=8'h08;//下行
		//4'h6: seg=8'h06;//关门
		//4'h7: seg=8'h09;
		default: seg=0;
		endcase
	end
   
endmodule

这个演示图片太大了,懒得去弄了,大概就这样了。

你可能感兴趣的:(verilog,fpga)