FPGA编程,verilog实现简易电梯控制系统,某大学数电实验课设

这篇具有很好参考价值的文章主要介绍了FPGA编程,verilog实现简易电梯控制系统,某大学数电实验课设。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

开发环境:Vivado 2020.1

使用编程语言:Verilog

开发板芯片:xc7a35tftg256-1(具体开发板型号未知,不同版本的开发板可能某些元件的引脚电平会不同,可能需要根据自己手上的开发板版本做一些修改)

项目基本介绍:

1、实现2层楼的简易电梯控制系统。

2、电梯有4个按键。

        1楼外只有向上按键(KEY0)

        2楼外只有向下按键(KEY1)

        电梯内还有2个按键分别为:

        1楼按键(KEY2)

        2楼按键(KEY3)

        所有楼层外和电梯内的按键产生的信号作为给电梯的运行请求信号。

FPGA编程,verilog实现简易电梯控制系统,某大学数电实验课设

   

3、电梯有4个指示灯(LED0、 LED1 、 LED2 、 LED3)。

         LED0: 按下KEY0键,若电梯不在1楼,则LED0亮。

         LED1: 按下KEY1键,若电梯不在2楼,则LED1亮。

         LED2: 电梯在2楼,按KEY2键, 则LED2亮,电梯到1楼后LED2灭。

         LED3: 电梯在1楼,按KEY3键, 则LED3亮,电梯到2楼后LED3灭。

4、有2个数码管,分别显示当前运行状态及楼层。

        (1)1个数码管显示当前运行状态,电梯有三个运行状态:待机、 上行、下行。 待机:电梯停在1楼或2楼且无请求信号时均为待机状态。 上行状态:电梯停在1楼,有KEY1或KEY3被按下,进入上行状态。 下行状态:电梯停在2楼,有KEY0或KEY2被按下,进入下行状态。

        (2)1个数码管显示所在楼层,显示1或2;每一层楼之间的运行时 间间隔为4秒。

5、有2个拨码开关。

        (1)复位开关。向下拨动后,电梯复位回到1楼。

        (2)启动开关。向上拨动后,按键有效,电梯正常工作。

具体要求:

FPGA编程,verilog实现简易电梯控制系统,某大学数电实验课设

 附加功能:

FPGA编程,verilog实现简易电梯控制系统,某大学数电实验课设

       作者只完成了附加功能的第一和第二个,其他的有兴趣可以自己添加。对于复位功能,最开始的时候只以为是整个程序的复位,没有考虑是要像正常地从2楼到1楼,这里只完成了所有状态的复位,即拨下复位拨码开关直接显示为一楼待机状态,而不会经过四秒后再到一楼。后来框架搭好了之后又不便于更改这样的功能了(主要是我懒)。而且期末了还挺忙的,后期如果有时间的话考虑将所有的附加功能都加上去并且把复位也给改了。 

       接下来简单地介绍一下思路:有四个按键,我就给四个按键分别分配了一个四秒的计时器,当某一个按键被按下后,计时器就会开始工作,这时对应的状态位会被置位,比如在一楼按下上行按键后,对应按键的led灯会被点亮,电梯进入上行状态,四秒计时结束后楼层状态翻转(注意这里只有两层楼,其实可以只用一位的状态位来表示楼层,但我选择了用两个位来分别表示,它们分别是lou1和lou2----lou1 = 1,lou2 = 0在一楼;lou1 = 0,lou2 = 1在二楼,楼层状态改变就是这两个状态位翻转)电梯重新进入待机状态。

      当然对于计时器其实还有很多的细节没有说,主要是解决按键之间的冲突和配合。具体代码如下:

module count_4(
    input en,    //使能位
    input clk,
    input wait1,         //两个等待位,检测是否处于冲突状态
    input wait2,
    output reg flag =0,   //led灯使能信号
    output reg key_d,    //按键延迟信号
    output reg status = 0   //计数状态输出:为1计数、为0不计数
    );
    
//等待位,如果该计时器被用于上行计时,那么如果处于下行状态时,计时器就会等待下行状态结束再开始计时 
//这里的两个等待位分别对应了两个下行计数器的状态输出位---status   
reg flag2 = 1;    
always@(posedge clk)
begin
    if(wait1 | wait2)
        flag2 <= 0;
    else 
        flag2 <= 1;              
end        


//使能位上升沿来临,计数器使能信号置位为1
//作用是记住按键被按下的状态
reg flag1 = 1;
always@(posedge clk)
begin
    if(en == 1)
        flag <= 1;
    else if (flag1 == 0)
        flag <= 0;
end

//当使能位为1且不处于冲突状态时计时器开始计时,并将输出状态位置位为1
always@(posedge clk)
begin
    if(flag & flag2)
        status <= 1 ;
    else if (flag1 == 0)
        status <= 0;   
end


//在开始计时的时候获得一个冲激信号
//这个信号被用来模拟按键被按下的动作
reg [31:0] temp1 =0;
reg impluse = 0;
always@(posedge clk)
begin
    if(status == 0)
        begin
            temp1 <= 0;
            impluse <= 0;
        end
    else if(temp1 < 10)
        begin
            temp1 <= temp1 +1;
            impluse <= 1;
        end
    else 
        begin
            temp1 <= temp1+1;
            impluse <= 0;
        end  
end
//key_d = key_delay,是处于冲突状态时有按键被按下的延时信号,即冲突状态结束后模拟一次按键被按下的动作
always@(posedge clk)
begin
    if(impluse)
    key_d = 1;
    else
    key_d = 0;
end



//获得1hz的信号,用来计时
reg [31:0] temp =0;
reg clk_1hz = 0;
always@(posedge clk)
begin
    if(status == 0)
        begin
            temp <= 0;
            clk_1hz <= 0;
        end
    else if(temp == 49999999)
        begin
            temp <= 0;
            clk_1hz <= 1;
        end
    else
        begin
            temp <= temp +1;
            clk_1hz <= 0;
        end
end

//开始计时
//计时完成后,计时器状态位复位,使能信号复位,等待下一次按键被按下
reg [1:0] count = 0;
always@(posedge clk_1hz or negedge status)
begin
    if(status == 0)
        begin
            count <=0;
            
            flag1 <= 1;
          
        end
    else if(count == 3 )
        begin
            count <= 0;
            
            flag1 <= 0;
        end
    else
        begin
        count <= count + 1;
        
        flag1 <= 1;
        end
end   

endmodule

 这里详细说一下key_d这个信号,因为在要求里面有说在下行状态时如果按下上行按键,那么电梯会在到达1楼后继续进入上行状态直到到达2楼后再结束运行。因为在顶层代码中我用到了按键按下的信号、楼层状态以及运行状态这几个信号用来做逻辑判断,以此来改变某些状态。但是在刚刚说的那种情况下,当下行状态结束后如果没有按下上行按键那么电梯也是不会上行的,原因是上行按键是在下行状态被按下的,此时顶层的逻辑判断会判定其无效。为了解决这个问题而又不对顶层模块进行大改,我就在计时器中添加了key_d这个延迟信号,它的作用是当下行状态结束的一瞬间就模拟一次上行按键被按下的动作,以此来获得上行命令,达到所说的要求。而两个wait信号是用来判定是否在冲突状态的,如果在冲突状态就等该冲突状态结束后再开始计时,同时key_d这个信号会模拟一次对于按键被按下的动作。flag这个信号是用来控制按键对应的led灯的,只要按键被按下这个flag就会被置位为1,led灯会再根据其他的一些信号来判断是否要亮(这里的led灯特指按键对应的灯,而非流水灯)。en信号就是使能信号,最开始就是按键被按下的信号,但是会导致led灯的亮灭出现一些问题(比如按下上行key1后再按下上行key3那么led1就会熄灭),所以我又用其他的一些信号将其与按键被按下的信号做了一些逻辑上的与或操作来解决这个问题。计时器大概就是这样了,更加具体的可以看代码,关键部分都有注释。

       剩下的就是一些数码管的动态显示、bcd译码器以及按键消抖的代码,这些东西其实很简单,网上有大把现成的代码可以用,这里就附上我的代码:

按键消抖:

   module ajxd(
    input clk,
    input  [3:0] btn_in,
    output [3:0] btn_out,
    input rst_n
    );

reg clk_20ms = 0;
reg [31:0] temp = 0;
always@(posedge clk)
begin
    if(rst_n == 0)
    begin
        temp <= 0;
        clk_20ms <= 0;
    end
    else if(temp == 999999)
        begin
            temp <= 0;
            clk_20ms <= 1;
        end
        else if(temp < 999999)
            begin
                clk_20ms <= 0;
                temp <= temp+1;
            end
end    

reg [3:0] btn0;
reg [3:0] btn1;
reg [3:0] btn2;
initial
begin
btn0=0;
btn1=0;
btn2=0;
end

always@(posedge clk_20ms)
begin
btn0<=btn_in;
btn1<=btn0;
btn2<=btn1;
end

assign btn_out=((btn0&btn1)&(~btn2) | (btn0&btn1&btn2) | ((~btn0)&btn1&btn2));

endmodule

数码管动态显示:

module seg_scan(
input  clk,
input [6:0] data_seg0,
input [6:0] data_seg1,
output reg [7:0] data_seg,
output reg [5:0] data_dig
);
parameter clk_freq=50000000;//50Mhz
parameter scan_freq=200;//200hz
parameter scan_cont=clk_freq/scan_freq/2-1;

reg [31:0] time_cont = 0;
reg  temp = 0;
always@(posedge clk)
begin
            if(time_cont<scan_cont)
                time_cont = time_cont+1;
            else  
            begin
                time_cont <= 0;
                temp <= ~temp;
            end        
end            
            
always@(posedge clk)
begin
       
           case(temp)
            0:
            begin
                data_seg<={1'b0,data_seg0};
                data_dig<=6'b111110;
            end
            1:
            begin
                 data_seg<={1'b0,data_seg1};
                data_dig<=6'b111101;
            end
            endcase
end        
/*         2:
        begin
             data_seg<={1'b0,data_seg2};
            data_dig<=6'b111011;
        end
         3:
        begin
             data_seg<={1'b0,data_seg3};
            data_dig<=6'b110111;
        end
         4:
        begin
             data_seg<={1'b0,data_seg4};
            data_dig<=6'b101111;
        end
         5:
        begin
             data_seg<={1'b0,data_seg5};
            data_dig<=6'b011111;
        end
*/                
endmodule

 最后的模块结构如下:

FPGA编程,verilog实现简易电梯控制系统,某大学数电实验课设

 再附上顶层模块代码:

module top(
    input clk,
    input rst_n,
    input start,
    input  [3:0] key,
    output reg [4:0] state_led = 0,
    output reg buzzer = 1,
    output reg [3:0] led =0,
    output  [3:0] row,
    output  [7:0] data_seg,
    output  [5:0] data_dig
    ); 
    
      
 //--------------------------------------------------------------------------------------------------   
//按键相关    
assign row = 4'b1110;  //只需要用到最下面一行,不需要按建行扫描
//按键消抖
wire [3:0] key_xd;
ajxd u2 (
.clk  (clk),
.btn_in  ( key),
.rst_n  (rst_n),
.btn_out  (key_xd)
);
//定义四个按键信号,代表按下按键并消抖之后的信号
wire key0,key1,key2,key3;
//按键按下时定义为高电平
assign key0 = ~(key_xd[0]|row[0]);
assign key1 = ~(key_xd[1]|row[0]);
assign key2 = ~(key_xd[2]|row[0]);
assign key3 = ~(key_xd[3]|row[0]);
//--------------------------------------------------------------------------------------------------
/*
每一个按键都对应了一个四秒的计时器,
该计时器检测到按键上升沿信号后开始计时,
计时状态位——status:  1 = 计时中  ;  0 = 计时完成
*/
//四个状态位,分别代表了key0下行,key1上行,key2下行,key3上行状态
wire status_dow0;
wire status_up1;
wire status_dow2;
wire status_up3;
/*
四个按键信号延迟位 key_delay_x    x=0,1,2,3
为了完成“在上行状态时按下KEY0或KEY2下行,电梯到达2楼后立刻下行”这一要求
在计时器中添加了一个按键被按下后的延迟按键信号输出
其功能为:
若处于上行状态中,按下KEY0或KEY2,那么KEY0或KEY2对应的计时器会被触发,但由于
还处于上行状态,无法开启下行状态。于是将等待上行状态完成后模拟一次KEY0或KEY2被
按下的信号。相当于在上行状态结束的一瞬间再按下了KEY0或KEY2一次,以此来达到期望的效果。
在下行状态按下上行按键也同理
*/
wire key_d0;
wire key_d1;
wire key_d2;
wire key_d3;

/*
用来记录四个按键是否被按下的信号,其主要作用是点亮按键对应的led灯
当按键被按下对应的flag就会置位为1,后面会用到该信号来点亮按键对应的
led灯
*/
wire flag0;
wire flag1;
wire flag2;
wire flag3;

//定义两个楼层
reg lou1,lou2;
//定义5个状态---上行(key1)、上行(key3)、下行(key0)、下行(key2)、待机
reg state_up1,state_up3,state_dow0,state_dow2,state_wait;

/*
例化计时器模块
*/
count_4 dow_count0 (
.clk  (clk),
.en  (key0&(lou2|(~state_wait))&(~led[2])),
.flag  (flag0),
.key_d (key_d0),
.wait1  (status_up1),
.wait2  (status_up3),
.status  (status_dow0)
);

count_4 up_count1 (
.clk  (clk),
.en  (key1&(lou1|(~state_wait))&(~led[3])),
.flag  (flag1),
.key_d (key_d1),
.wait1  (status_dow0),
.wait2  (status_dow2),
.status  (status_up1)
);

count_4 dow_count2 (
.clk  (clk),
.en  (key2&(lou2|(~state_wait))&(~led[0])),
.flag  (flag2),
.key_d (key_d2),
.wait1  (status_up1),
.wait2  (status_up3),
.status  (status_dow2)
);

count_4 up_count3 (
.clk  (clk),
.en  (key3&(lou1|(~state_wait))&(~led[1])),
.flag  (flag3),
.key_d (key_d3),
.wait1  (status_dow0),
.wait2  (status_dow2),
.status  (status_up3)
);

//--------------------------------------------------------------------------------------------------
/*
楼层及电梯状态判断
*/
//定义5个状态---上行(key1)、上行(key3)、下行(key0)、下行(key2)、待机
//reg state_up1,state_up3,state_dow0,state_dow2,state_wait;
//定义两个楼层
//reg lou1,lou2;
//ps:本来这几个状态位是定义在这的,但是前面用到了这几个状态位,所以将这几个状态位定义在了前面,这里是做提示用
//初始状态:电梯停在一楼,待机状态
initial
begin
lou1 = 1;
lou2 = 0;
state_up1 = 0;
state_up3 = 0;
state_dow0 = 0;
state_dow2 = 0;
state_wait = 1;
end

/*
使用计时器状态和楼层状态以及按键被按下的信号做逻辑判断
以此来改变楼层状态位和上下行状态位以及待机状态位
*/
always@(posedge clk)
begin
    if(rst_n == 0)    //复位,所有状态皆回到初始值
        begin 
            lou1 = 1;
            lou2 = 0;
            state_up1 = 0;
            state_up3 = 0;
            state_dow0 = 0;
            state_dow2 = 0;
            state_wait = 1;
        end
    else if (start == 1)   //启动
        begin                                   
            if(lou1&(~lou2)&(key_d1|key_d3))                  //电梯不处于上行状态且电梯在一楼、KEY1或KEY3被按下,则电梯进入上行状态,跳出待机状态
                begin
                    if(status_up1 == 1)   
                        begin
                            state_up1 <= 1;
                            state_wait <= 0;                           
                        end
                    else if (status_up3 == 1)
                        begin
                            state_up3 <= 1;
                            state_wait <= 0;                           
                        end
                end                                
            else  
                begin
                    if((status_up1 == 0)&(state_up1 == 1))           //上行状态保持4秒后,status_up1/3置位、上行状态结束、进入待机状态、楼层状态翻转
                    begin    
                        state_up1 <= 0;
                        state_wait <= 1;
                        lou1 <= ~lou1;
                        lou2 <= ~lou2;
                    end
                    else if((status_up3 == 0)&(state_up3 == 1))
                    begin    
                        state_up3 <= 0;
                        state_wait <= 1;
                        lou1 <= ~lou1;
                        lou2 <= ~lou2;
                    end
                end
                
            if(lou2&(~lou1)&(key_d0|key_d2)) //电梯不处于下行状态且电梯在二楼、KEY2或KEY0被按下,则电梯进入下行状态,跳出待机状态
                begin
                    if(status_dow0 == 1)   
                        begin
                            state_dow0 <= 1;
                            state_wait <= 0;                           
                        end
                    else if (status_dow2 == 1)
                        begin
                            state_dow2 <= 1;
                            state_wait <= 0;                           
                        end
                      
                end                                
            else  
                begin
                    if((status_dow0 == 0)&(state_dow0 == 1))           //下行状态保持4秒后,status_dow0/2置位、下行状态结束、进入待机状态、楼层状态翻转
                    begin    
                        state_dow0 <= 0;
                        state_wait <= 1;
                        lou1 <= ~lou1;
                        lou2 <= ~lou2;
                    end
                    else if((status_dow2 == 0)&(state_dow2 == 1))
                    begin    
                        state_dow2 <= 0;
                        state_wait <= 1;
                        lou1 <= ~lou1;
                        lou2 <= ~lou2;
                    end
                    
                end                
   
        end
end


//--------------------------------------------------------------------------------------------------
/*
点亮LED灯
*/
always@(posedge clk )
begin
    if(rst_n == 1'b0)   //reset
        begin
            led <= 0;
        end
    else
       if(start == 1)  //start
        begin
           led[0] <=  (status_dow0&(~status_dow2)&(lou2&(~lou1)))|((state_up1|state_up3)&flag0);
           led[1] <=  (status_up1&(~status_up3)&(lou1&(~lou2)))|((state_dow0|state_dow2)&flag1);
           led[2] <=  (status_dow2&(~status_dow0)&(lou2&(~lou1)))|((state_up1|state_up3)&flag2);
           led[3] <=  (status_up3&(~status_up1)&(lou1&(~lou2)))|((state_dow0|state_dow2)&flag3);
       end
end


//--------------------------------------------------------------------------------------------------
/*
这里使用的是共阴极数码管,若为共阳极数码管则只需要改动数码管相关的一些代码
调用数码管动态显示模块控制数码管的显示
用两个七段(八段)数码管,一个显示楼层数字,一个显示上行、下行、待机状态。
上行用数码管a亮其他灭表示;待机用数码管g亮其他灭表示;下行用数码管d亮其他灭表示。
*/
reg [6:0] data_seg0;  //运行状态显示
reg [6:0] data_seg1;  //当前楼层显示
seg_scan  scan (
.clk  (clk),
.data_seg0  (data_seg1),
.data_seg1  (data_seg0),
.data_seg  (data_seg),
.data_dig  (data_dig)
);
//定义一个数码管状态变量,方便用数码管显示状态
wire [6:0] status_seg ;
assign status_seg = {lou1,lou2,state_up1,state_up3,state_dow0,state_dow2,state_wait};
always@(posedge clk)
begin
    case(status_seg)    
        7'b1000001:     //1楼待机
            begin
               data_seg0 <= 7'b1000000;
               data_seg1 <= 7'b0000110;
           end
         7'b1010000:    //1楼上行——status_up1——KEY1被按下
            begin
               data_seg0 <= 7'b0000001;
               data_seg1 <= 7'b0000110;
           end
         7'b1001000:    //1楼上行——status_up3——KEY3被按下
            begin
               data_seg0 <= 7'b0000001;
               data_seg1 <= 7'b0000110;
           end
         7'b0100001:    //2楼待机
            begin
               data_seg0 <= 7'b1000000;
               data_seg1 <= 7'b1011011;
           end
         7'b0100100:    //2楼下行——status_dow0——KEY0被按下
            begin
               data_seg0 <= 7'b0001000;
               data_seg1 <= 7'b1011011;
           end
         7'b0100010:    //2楼下行——status_dow2——KEY2被按下
            begin
               data_seg0 <= 7'b0001000;
               data_seg1 <= 7'b1011011;
           end
         default:    //其他情况,显示E,待机
            begin
               data_seg0 <= 7'b1000000;
               data_seg1 <= 7'b1111001;
            end
    endcase
end



//--------------------------------------------------------------------------------------------------   
//附加功能:蜂鸣器
//这里采用无源蜂鸣器,需要输入一定频率的方波信号
//输入信号频率决定了蜂鸣器发出的声音频率,这里采用500hz的方波信号

//获得1khz的信号
reg [31:0] temp =0;
reg clk_1khz = 0;
always@(posedge clk)
begin
    if(temp == 49999)
        begin
            temp <= 0;
            clk_1khz <= 1;
        end
    else
        begin
            temp <= temp +1;
            clk_1khz <= 0;
        end
end


reg lou1_dly;
reg turn = 0;
reg [15:0] cnt = 0;
//这是一个检测信号翻转的模块,采用了非阻塞赋值
//检测楼层状态是否翻转,若翻转则turn = 1并开始计时,计时完成后turn = 0
always@(posedge clk)
begin
    lou1_dly <= lou1;
    if(lou1 != lou1_dly)
         turn <= 1;
    else if(cnt == 100)
            turn <= 0;
end  
  
parameter cnt_max = 100;        
always@(posedge clk_1khz)
begin
    if(turn == 1)
        begin
            if(cnt == cnt_max)
                cnt <= 0;
            else
                cnt <= cnt + 1;
        end
    else
        cnt <= 0;
end   
//当turn = 1时向蜂鸣器输入1khz的信号,蜂鸣器响0.1s,这里蜂鸣器响的时间由上面的cnt计数器决定
//t = cnt_max / 1000     单位s
//作为蜂鸣器的输入信号buzzer的频率其实为500hz
//也可以将clk_1hz信号直接赋给buzzer,令其为1khz,这种办法其实更好,
//可以节约一个寄存器资源,也让buzzer和1khz的时钟频率相同,
//但在这里两个都无所谓,只是频率不同而已,看自己的需要更改即可
always@(posedge clk_1khz)
begin
    if(turn == 1)
         buzzer <= ~buzzer;
    else if(turn == 0)
         buzzer <= 0;
end                                                     
   
//--------------------------------------------------------------------------------------------------  
//附加功能:流水灯,上行状态将LED11---LED7从左到右每隔一秒依次点亮;
//                 下行状态将LED11---LED7从右到左每隔一秒依次点亮 
//定义两个状态位控制流水灯的状态
wire state_up;//用来控制上行流水灯
wire state_dow;//用来控制下行流水灯
//为了防止预期以外的情况出现,这里采用了楼层和按键对应的led灯来共同控制流水灯的状态
assign state_up = (led[1]|led[3])&(lou1&(~lou2));
assign state_dow = (led[0]|led[2])&(lou2&(~lou1));

/*
获得1.05hz的信号(总共5个灯,每隔一秒亮一个,
但是最后一个灯在4秒末结束时才亮,这时电梯都已经结束了当前状态了
所以最后效果其实是只能看见4个灯亮,这里将计数器的时钟改为1.05hz左右,
即每隔大概9.5s左右点亮一个灯,这样最后一个灯就可以被点亮0.2s左右)
*/
reg [31:0] temp1 =0;
reg clk_1hz = 0;
always@(posedge clk or negedge state_up or negedge state_dow)
begin
    if(~(state_up|state_dow))
    begin
        temp1 <= 0;
        clk_1hz <= 0;
    end
    else if(state_up | state_dow)
    begin
        if(temp1 == 47619046)
            begin
                temp1 <= 0;
                clk_1hz <= 1;
            end
        else
            begin
                temp1 <= temp1 +1;
                clk_1hz <= 0;
            end
    end
    else
        temp1 <= 0;
end


//计数器
reg [3:0] cnt1 = 0;
always@(posedge clk_1hz or negedge state_up or negedge state_dow)
begin
     if(~(state_up|state_dow))
    begin
        cnt1 <= 0;
    end
    else if(state_up | state_dow)
    begin
        if(cnt1 == 5)
        cnt1 <= 0;
        else
        cnt1 <= cnt1 + 1;
    end
    else
        cnt1 <= 0;
end

always@(posedge clk )
begin
    if(state_up)
    begin
         case(cnt1)
            0 :state_led <= 5'b10000;
            1 :state_led <= 5'b11000;
            2 :state_led <= 5'b11100;
            3 :state_led <= 5'b11110;
            4 :state_led <= 5'b11111;
            default:state_led <= 5'b00000;
         endcase
    end
    else if(state_dow)
    begin
         case(cnt1)
            0 :state_led <= 5'b00001;
            1 :state_led <= 5'b00011;
            2 :state_led <= 5'b00111;
            3 :state_led <= 5'b01111;
            4 :state_led <= 5'b11111;
            default:state_led <= 5'b00000;
         endcase
    end
     else 
            state_led <= 5'b00000;

end
  
    
endmodule

约束文件:

#set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets start_IBUF]
set_property IOSTANDARD LVCMOS33 [get_ports {data_dig[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_dig[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_dig[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_dig[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_dig[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_dig[5]}]
set_property PACKAGE_PIN G12 [get_ports {data_dig[0]}]
set_property PACKAGE_PIN H13 [get_ports {data_dig[1]}]
set_property PACKAGE_PIN M12 [get_ports {data_dig[2]}]
set_property PACKAGE_PIN N13 [get_ports {data_dig[3]}]
set_property PACKAGE_PIN N14 [get_ports {data_dig[4]}]
set_property PACKAGE_PIN N11 [get_ports {data_dig[5]}]

set_property PACKAGE_PIN T10 [get_ports {key[3]}]
set_property PACKAGE_PIN R11 [get_ports {key[2]}]
set_property PACKAGE_PIN T12 [get_ports {key[1]}]
set_property PACKAGE_PIN R12 [get_ports {key[0]}]
set_property PACKAGE_PIN T5 [get_ports {led[3]}]
set_property PACKAGE_PIN R7 [get_ports {led[2]}]
set_property PACKAGE_PIN R8 [get_ports {led[1]}]
set_property PACKAGE_PIN P9 [get_ports {led[0]}]
set_property PACKAGE_PIN R10 [get_ports {row[3]}]
set_property PACKAGE_PIN P10 [get_ports {row[2]}]
set_property PACKAGE_PIN M6 [get_ports {row[1]}]
set_property PACKAGE_PIN K3 [get_ports {row[0]}]
set_property PACKAGE_PIN D4 [get_ports clk]
set_property PACKAGE_PIN F3 [get_ports rst_n]
set_property PACKAGE_PIN T9 [get_ports start]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports start]
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {key[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {row[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {row[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {row[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {row[0]}]
set_property PACKAGE_PIN L13 [get_ports {data_seg[7]}]
set_property PACKAGE_PIN M14 [get_ports {data_seg[6]}]
set_property PACKAGE_PIN P13 [get_ports {data_seg[5]}]
set_property PACKAGE_PIN K12 [get_ports {data_seg[4]}]
set_property PACKAGE_PIN K13 [get_ports {data_seg[3]}]
set_property PACKAGE_PIN L14 [get_ports {data_seg[2]}]
set_property PACKAGE_PIN N12 [get_ports {data_seg[1]}]
set_property PACKAGE_PIN P11 [get_ports {data_seg[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {data_seg[0]}]

set_property PACKAGE_PIN L2 [get_ports buzzer]
set_property IOSTANDARD LVCMOS33 [get_ports buzzer]

set_property IOSTANDARD LVCMOS33 [get_ports {state_led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {state_led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {state_led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {state_led[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {state_led[4]}]
set_property PACKAGE_PIN T2 [get_ports {state_led[0]}]
set_property PACKAGE_PIN R1 [get_ports {state_led[1]}]
set_property PACKAGE_PIN G5 [get_ports {state_led[2]}]
set_property PACKAGE_PIN H3 [get_ports {state_led[3]}]
set_property PACKAGE_PIN E3 [get_ports {state_led[4]}]

最后就到这里了,有什么问题欢迎讨论,如果有更好的想法也可以在评论区分享一下。文章来源地址https://www.toymoban.com/news/detail-484362.html

到了这里,关于FPGA编程,verilog实现简易电梯控制系统,某大学数电实验课设的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 北邮22级信通院数电:Verilog-FPGA(12)第十二周实验(1)设计一个汽车尾灯自动控制系统

    北邮22信通一枚~ 跟随课程进度更新北邮信通院数字系统设计的笔记、代码和文章 持续关注作者 迎接数电实验学习~ 获取更多文章,请访问专栏: 北邮22级信通院数电实验_青山如墨雨如画的博客-CSDN博客   目录 一.题目要求 二.代码部分 2.1  car_system.v  2.2  divide.v 三.管脚分配

    2024年02月05日
    浏览(31)
  • 7. 【可编程并行接口8255】:接口特点、结构、引脚、三种工作方式、控制字、方式0应用、设计简易安全报警系统

    基本输入/输出方式 (方式0) 选通工作方式 (方式1) 双向传送方式 (方式2) 相当于三个独立的8位简单接口,可输入或输出 各端口既可设置为输入口,也可设置为输出口,但不能同时实现输入及输出 C端口可以是一个8位的简单接口,也可以分为两个独立的4位端口 常用于

    2024年02月06日
    浏览(23)
  • 【FPGA教程案例40】通信案例10——基于FPGA的简易OFDM系统verilog实现

    FPGA教程目录 MATLAB教程目录 --------------------------------------------------------------------------------------- 目录 1.软件版本 2.OFDM原理 3.OFDM系统的verilog实现

    2024年02月12日
    浏览(27)
  • 自动售货机控制系统的FPGA设计与实现

            采用VHDL语言设计一个自动售货机控制系统,要求能在MaxPlus Ⅱ软件平台进行仿真模拟,技术指标如下: 1)有2元、3元、8元商品;有1元、5元、10元钱币; 2)当投入的总币值大于顾客购买的商品单价时,机器提供商品并将余币退出,回到初始状态;若投入的总币值小

    2024年02月06日
    浏览(23)
  • 基于FPGA的永磁同步伺服控制系统的设计,在FPGA实现了伺服电机的矢量控制, 坐标变换,电流环,速度环,位置环,电机反馈接口,SVPWM

    一个基于FPGA的永磁同步伺服控制系统,利用Verilog语言在FPGA上实现了伺服电机的矢量控制、坐标变换、电流环、速度环、位置环以及电机反馈接口。这个系统具有很高的研究价值。 涉及到的知识点和领域范围主要包括:FPGA(现场可编程门阵列)、永磁同步伺服控制系统、矢

    2024年02月04日
    浏览(25)
  • 项目三 电梯控制器设计(FPGA综合应用设计)

    (一个很简陋的电梯控制器设计,但是应该可以过关了吧?😶‍🌫️) 通过实验,巩固有限状态机设计方法,并设计实现一个电梯控制器。 利用 BASYS 开发板资源设计一个 5 层楼的电梯控制器系统,并能在开发板上 模拟电梯运行状态,具体要求如下: 利用开发板的 5 个按键作

    2024年02月03日
    浏览(25)
  • 药片瓶装生产线简易控制系统multisim

    由键盘或按键输入每个瓶子将装入的药片数。当每个瓶子的药片正好装满时,以下两个事件同时发生:(1)停止药片装入;(2)已装瓶数+1 2 考虑到系统中电路设计的简单性, 每瓶装入的药片数及瓶数限制在10以内。电路实现的主要功能如下: (1)通过键盘或按键设置每瓶

    2024年02月06日
    浏览(72)
  • Verilog 编程实现 3-8 译码器 FPGA

    Verilog 编程实现 3-8 译码器 FPGA FPGA 是一种可重构的数字电路芯片,可用于实现各种逻辑电路。在 FPGA 中,我们可以使用 Verilog HDL(硬件描述语言)来编写数字电路设计。本篇文章将为您介绍如何使用 Verilog 实现基本的数字电路,即 3-8 译码器。 3-8 译码器是一种常用的数字电路

    2024年02月07日
    浏览(20)
  • FPGA 学习笔记:Verilog 实现LED流水灯控制

    在初步了解 Xilinx Vivado 的使用后,开启了FPGA Hello World 程序:LED 流水灯控制 在嵌入式MCU中,流水灯需要延时来实现,FPGA的延时,使用外部晶振来实现 实现 3个 LED 流水灯控制,也就是循环依次点亮, LED 低电平亮, 高电平灭,FPGA 有一个40MHz的外部晶振,作为系统时钟输入开

    2023年04月08日
    浏览(16)
  • 【FPGA】Verilog编程实现SDRAM读写(一) ----- 初识SDRAM

    SDRAM(Synchronous Dynamic Random Access Memory),同步动态随机存储器。同步、动态、随机是其性能特点的外在说明: 同步(Synchronous )是指内存工作需要同步时钟,内部的命令的发送与数据的传输都以它为基准 动态(Dynamic )是指存储阵列 需要不断的刷新来保证数据不丢失 随机(

    2023年04月08日
    浏览(17)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包