设计一个十字路口交通控制系统,其东西、南北两个方向除了有红、黄、绿灯指示是否允许通行外,还设有时间显示,以倒计时方式显示每一路允许通行的时间,绿灯、黄灯、红灯的持续时间分别是45、5和50秒。当东西或南北两路中任一道上出现特殊情况,例如有消防车,警车要去执行任务,此时交通控制系统应可由交警手动控制立即进入特殊运行状态,即两条道上的所有车辆皆停止通行,红灯全亮,时钟停止计时,且其数字在闪烁。当特殊运行状态结束后,管理系统恢复原来的状态,继续正常运行。
实现主干道和支干道的红绿灯,并实现时间显示功能;
实现绿灯,黄灯,红灯的持续时间固定的交通控制功能;
顶层设计模块:
moduletop(ext_clk_25m,ext_rst_n,dtube_cs_n,dtube_data,led ); //顶层控制模块inputext_clk_25m; //时钟信号25MHzinputext_rst_n; //复位信号output [3:0] dtube_cs_n; //段选数据位output [6:0] dtube_data;//位选数据位output [5:0] led; wire [3:0] TimeL; wire [3:0] TimeH; wire [3:0] TimeL1; wire [3:0] TimeH1; wireclk;//中间变量//分频25MHZ变为1HZdivd1( .ext_clk_25m(ext_clk_25m), .ext_rst_n(ext_rst_n), .mclk(clk) ); //倒计时计数模块(东西)counterc1( .ext_clk_25m(ext_clk_25m), .mclk(clk), .ext_rst_n(ext_rst_n), .TimeH(TimeH), .TimeL(TimeL), .led(led[2:0]) ); //数码管显示模块(东西,南北)segs1( .ext_clk_25m(ext_clk_25m), .ext_rst_n(ext_rst_n), .TimeH(TimeH), .TimeL(TimeL), .TimeH1(TimeH1), .TimeL1(TimeL1), .dtube_cs_n(dtube_cs_n), .dtube_data(dtube_data) ); //倒计时计数模块(南北)counter1c2( .ext_clk_25m(ext_clk_25m), .mclk(clk), .ext_rst_n(ext_rst_n), .TimeH1(TimeH1), .TimeL1(TimeL1), .led(led[5:3]) ); endmodule
数码管显示模块:
moduleseg(ext_clk_25m,ext_rst_n,TimeH,TimeL,TimeH1,TimeL1,dtube_cs_n,dtube_data ); inputext_clk_25m; //时钟信号25MHzinputext_rst_n; //复位信号input [3:0]TimeH; //两位输入高位 [0]input [3:0]TimeL; //两位输入低位 [1]input [3:0]TimeH1; //两位输入高位 [2]input [3:0]TimeL1; //两位输入低位 [3]outputreg[3:0] dtube_cs_n; //段选数据位outputreg[6:0] dtube_data;//位选数据位reg[3:0] display_num; //当前显示数据reg[16:0] div_cnt; //延时计数器计数位initialdiv_cnt=0;//赋初值为0//延时计数器模块always (posedgeext_clk_25mornegedgeext_rst_n) beginif(!ext_rst_n) div_cnt<=8'd0;elseif(div_cnt==17'd80000)div_cnt<=8'd0; elsediv_cnt<=div_cnt+1'b1;end//显示当前的数据模块always (posedgeext_clk_25mornegedgeext_rst_n) beginif(!ext_rst_n) display_num<=4'h0;elseif(div_cnt<17'd20000)display_num<=TimeL; elseif((div_cnt>17'd20000)&(div_cnt <17'd40000)) display_num<=TimeH; elseif((div_cnt>17'd40000)&(div_cnt < 17'd60000)) display_num<=TimeL1; elsedisplay_num<=TimeH1; end//段选数据译码模块(共阴数码管)always (*) beginif(!ext_rst_n) dtube_data<=8'h00;elsebegincase(display_num) 4'h0: dtube_data <= 8'h3f; 4'h1: dtube_data <= 8'h06; 4'h2: dtube_data <= 8'h5b; 4'h3: dtube_data <= 8'h4f; 4'h4: dtube_data <= 8'h66; 4'h5: dtube_data <= 8'h6d; 4'h6: dtube_data <= 8'h7d; 4'h7: dtube_data <= 8'h07; 4'h8: dtube_data <= 8'h7f; 4'h9: dtube_data <= 8'h6f; default:dtube_data<=8'h00;endcaseendend//位选选译模块always (posedgeext_clk_25mornegedgeext_rst_n) beginif(!ext_rst_n) dtube_cs_n<=4'b1111;elseif(div_cnt<=17'd20000)dtube_cs_n<=4'b1110;elseif((div_cnt>17'd20000)&(div_cnt <=17'd40000)) dtube_cs_n<=4'b1101;elseif((div_cnt>17'd40000)&(div_cnt <=17'd60000)) dtube_cs_n<=4'b1011;elsedtube_cs_n<=4'b0111;endendmodule
分频模块:
modulediv(ext_clk_25m,ext_rst_n,mclk ); inputext_clk_25m;//输入时钟inputext_rst_n; //复位端口outputregmclk;//输出1Hzreg [23:0] cnt;//存放计数器的值initialcnt=0; parameterTIME=24'd1250_0000;//时钟25MHz//分频模块//使得输入时钟为25MHz输出时钟为1Hzalways (posedgeext_clk_25mornegedgeext_rst_n) beginif(!ext_rst_n) beginmclk<=1'b0;cnt<=25'd0;endelseif(cnt==TIME-1'b1)beginmclk<=~mclk; cnt<=1'b0;endelsecnt<=cnt+1'b1;endendmodule
计数器模块(东西):
modulecounter(ext_clk_25m,mclk,ext_rst_n,TimeH,TimeL,led ); inputext_clk_25m; inputmclk;//时钟信号inputext_rst_n;//复位信号outputreg [3:0]TimeH;//两位数码管显示高位outputreg [3:0]TimeL;//两位数码管显示低位outputreg [2:0] led; //状态机实现三种状态切换reg[2:0] state_c,state_n; reg [7:0] times; parameter [2:0] IDLE=3'b001,S1=3'b010,S2=3'b100;//状态切换模块always (posedgeext_clk_25mornegedgeext_rst_n) beginif(!ext_rst_n) state_c<=IDLE; elsestate_c<=state_n; end//状态切换always (*) begincase(state_c) IDLE: beginif({TimeH,TimeL}==8'h00)state_n=S1; elsestate_n=IDLE; endS1: beginif({TimeH,TimeL}==8'h00)state_n=S2; elsestate_n=S1; endS2: beginif({TimeH,TimeL}==8'h00)state_n=IDLE; elsestate_n=S2; enddefault: state_n=state_c; endcaseendalways (posedgeext_clk_25mornegedgeext_rst_n) beginif(!ext_rst_n) times<=8'd00;elseif(state_c==IDLE) begintimes<=8'h20;endelseif(state_c==S1) begintimes<=8'h15;endelseif(state_c==S2) begintimes<=8'd5;endelse; endalways (posedgemclkornegedgeext_rst_n) beginif(!ext_rst_n) led=3'b111;elseif(state_c==IDLE) beginled[2]=1'b1;led[0]=1'b0;endelseif(state_c==S1) beginled[0]=1'b1;led[1]=1'b0;endelseif(state_c==S2) beginled[1]=1'b1;led[2]=1'b0;endelseled=3'b111;endinitialTimeH=times[7:4]; //计数器赋初值//计数器模块高位always (posedgemclkornegedgeext_rst_n) beginif(!ext_rst_n) TimeH<=times[7:4]; //计数器赋初值elseif({TimeH,TimeL}==8'h00)beginTimeH<=times[7:4]; //计数器赋初值endelseif(TimeL==4'h0)beginTimeH<=TimeH-1'b1;endelsebeginTimeH<=TimeH; endendinitialTimeL=times[3:0]; //计数器模块低位always (posedgemclkornegedgeext_rst_n) beginif(!ext_rst_n) beginTimeL<=times[3:0]; endelseif({TimeH,TimeL}==8'h00) beginTimeL<=times[3:0]; endelseif(TimeL==4'h0)beginTimeL<=4'h9;endelsebeginTimeL<=TimeL-1'b1;endendendmodule
计数器模块(南北)
modulecounter1(ext_clk_25m,mclk,ext_rst_n,TimeH1,TimeL1,led ); inputext_clk_25m; inputmclk;//时钟信号inputext_rst_n;//复位信号outputreg [3:0]TimeH1;//两位数码管显示高位outputreg [3:0]TimeL1;//两位数码管显示低位outputreg [5:3] led; //状态机实现三种状态切换reg[2:0] state_c,state_n; reg [7:0] times1; parameter [2:0] IDLE=3'b001,S1=3'b010,S2=3'b100;//状态切换模块initialstate_c=IDLE; always (posedgeext_clk_25mornegedgeext_rst_n) beginif(!ext_rst_n) state_c<=IDLE; elsestate_c<=state_n; end//状态切换always (*) begincase(state_c) IDLE: beginif({TimeH1,TimeL1}==8'h01)state_n=S1; elsestate_n=IDLE; endS1: beginif({TimeH1,TimeL1}==8'h01)state_n=S2; elsestate_n=S1; endS2: beginif({TimeH1,TimeL1}==8'h01)state_n=IDLE; elsestate_n=S2; enddefault: state_n=state_c; endcaseendalways (posedgeext_clk_25mornegedgeext_rst_n) beginif(!ext_rst_n) times1<=8'd00;elseif(state_c==IDLE) begintimes1<=8'h15;endelseif(state_c==S1) begintimes1<=8'h5;endelseif(state_c==S2) begintimes1<=8'h20;endelse; endalways (posedgemclkornegedgeext_rst_n) beginif(!ext_rst_n) led=3'b111;elseif(state_c==IDLE) beginled[3]=1'b1;led[4]=1'b0;endelseif(state_c==S1) beginled[4]=1'b1;led[5]=1'b0;endelseif(state_c==S2) beginled[5]=1'b1;led[3]=1'b0;endelseled=3'b111;endinitialTimeH1=times1[7:4]; //计数器赋初值//计数器模块高位always (posedgemclkornegedgeext_rst_n) beginif(!ext_rst_n) TimeH1<=times1[7:4]; //计数器赋初值elseif({TimeH1,TimeL1}==8'h00)beginTimeH1<=times1[7:4]; //计数器赋初值endelseif(TimeL1==4'h0)beginTimeH1<=TimeH1-1'b1;endelsebeginTimeH1<=TimeH1; endendinitialTimeL1=times1[3:0]; //计数器模块低位always (posedgemclkornegedgeext_rst_n) beginif(!ext_rst_n) beginTimeL1<=times1[3:0]; endelseif({TimeH1,TimeL1}==8'h00) beginTimeL1<=times1[3:0]; endelseif(TimeL1==4'h0)beginTimeL1<=4'h9;endelsebeginTimeL1<=TimeL1-1'b1;endendendmodule