名称:基于FPGA的停车场设计Verilog代码Quartus仿真
软件:Quartus
语言:Verilog
代码功能:
假设停车场只有一个入口和一个出口,利用两对光电传感器检测车辆的进出情况,如图5.11所示。
当有车辆处在接收器与发射器中间时,相应的输出位置为有效即置1。
通过检查光电传感器可以确定是否有车辆进出活动或者只是行人穿过。
例如,车辆进入会发生如下事件:
1.最开始两个传心都未被遮挡(ab值为"00")
2.传感器a被遮挡(ab值为"10")
3.两个传感器都被遮挡(ab值为"11”)
4.传感器a未被遮挡(ab值为"01”)
5.两个传感器都未被遮挡(ab值为"00”)
因此,可以按一下步骤设计一个停车场计时器
1.设计一个带有输2输入(a、b)、2输出( enter、exit)的有限状态机。当车辆进入、开出停车场时,分别将enter、exit置一个周期的有效电平。
2.根据有限状态机写出HDL代码。
3.设计一个带有两个控制信号 (inc, dec)的计数器,当信号有效时加1或减1:写出HDL代码。
结合计数器,有限状态机和LED复用显示电路,用俩个带去抖电路的按键代替光电传感器的输入,验证停车场计数器的功能。
FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com
演示视频:
设计文档:
1. 工程文件
2. 程序文件
3. 程序编译
4. Testbench
5. 仿真图
部分代码展示:
`timescale?1ns?/?1ps ////////////////////////////////////////////////////////////////////////////////// // module?park_station( ????input?clk,//输入时钟 ????input?a,//入口 ????input?b,//出口 ???? ????output?reg?[3:0]?weixuan,//数码管位选 ????output?reg?[7:0]?duanxuan//数码管段选 ????); parameter?idle_in?=?3'd0;//空闲状态 parameter?idle_out?=?3'd5;//空闲状态 parameter?car_in?=?3'd1;//有车进入状态 parameter?car_in_wait?=?3'd2;//有车进入维持状态 parameter?car_out?=?3'd3;//有车离开状态 parameter?car_out_wait?=?3'd4;//有车离开维持状态 //parameter?car_inout?=?3'd5;//同时有车进入离开状态 reg?[2:0]?state_a='d0; reg?[2:0]?state_b='d0; //两段式状态机第一段,状态转换 always@(posedge?clk) begin ??case(state_a) ????idle_in:if(a==1) ????????????????state_a<=car_in;//有车进入 ????????????else ????????????????state_a<=idle_in;//无车保持空闲状态 ?????car_in:????state_a<=car_in_wait;//有车进入维持状态 ?????car_in_wait:if(a==1) ?????????????????????state_a<=car_in_wait;//有车进入维持状态 ?????????????????else ?????????????????????state_a<=idle_in;//车完全驶入??? ?????default:state_a<=idle_in;??? ?????endcase ????? ??case(state_b) ???????idle_out:if(b==1) ???????????????????state_b<=car_out;//有车离开 ???????????????else ???????????????????state_b<=idle_out;//无车保持空闲状态 ????????car_out:????state_b<=car_out_wait;//有车离开维持状态 ????????car_out_wait:if(b==1) ????????????????????????state_b<=car_out_wait;//有车离开维持状态 ????????????????????else ????????????????????????state_b<=idle_out;//车完全离开??? ????????default:state_b<=idle_out;??? ????????endcase end reg?enter=0;//进入脉冲 reg?exit=0;//离开脉冲 //两段式状态机第二段,状态对应操作 always@(posedge?clk)?begin ????if(state_a==car_in) ????????enter<=1; ????else ????????enter<=0; ????if(state_b==car_out) ????????exit<=1; ????else ????????exit<=0;???????? end wire?[1:0]?detect;//车辆驶入驶出组合情况 assign?detect={enter,exit}; reg?inc=0;//车辆增加 reg?dec=0;//车辆减少 reg?[7:0]?car_num='d0;//车辆总数 always@(posedge?clk)?begin ????if(detect==2'b00)begin//没有驶入驶出 ????????inc<=0; ????????dec<=0; ????????end ????else?if(detect==2'b01)begin//驶出 ????????inc<=0; ????????dec<=1;???????? ????????end ????else?if(detect==2'b10)begin//驶入 ????????inc<=1; ????????dec<=0;???????? ????????end??? ????else?if(detect==2'b10)begin//同时驶入驶出 ?????????inc<=0; ?????????dec<=0;???????? ?????????end? end always@(posedge?clk)?begin if(inc==1) ????if(car_num=='d255)//停车场满 ????????car_num<=car_num;//不再驶入 ????else ????????car_num<=car_num+1;//驶入 else?if(dec==1) ????if(car_num=='d0) ????????car_num<=car_num;//不再驶出 ????else ????????car_num<=car_num-1;//驶出 else ????car_num<=car_num; end wire????[3:0]?one,ten; wire????[3:0]?hun; wire?count; wire?shift_reg; //将二进制的car_num转换为个位,十位,百位,BCD码便于数码管显示 assign?hun=car_num/100;//除以100 assign?ten=car_num/10%10;//除以10,再除以10取余数 assign?one=car_num%10;//除以10取余数 //以下为数码管显示???? reg?[3:0]?jishu='d0; reg?[3:0]?data='d0; always@(posedge?clk)//为数码管动态扫描的时间间隔作准备 begin if(jishu==4'b1111) ????jishu<=0; else ????jishu<=jishu+1; end always@(posedge?clk) begin case(jishu[3:2])//位值读取;每一个时间间隔读取一个位(个位、十位、百位...) 2'd0:data<=hun; 2'd1:data<=ten; 2'd2:data<=one; ??????default:data<=one; endcase end always@(posedge?clk) begin case(jishu[3:2]) 3'd0:?weixuan<=4'b0001; 3'd1:?weixuan<=4'b0010; 3'd2:?weixuan<=4'b0100; default:weixuan<=4'b0000; endcase case(data)//段选 endmodule
点击链接获取代码文件:http://www.hdlcode.com/index.php?m=home&c=View&a=index&aid=716
265