FPGA-08-任務五、十字路口交通控制燈器系統設計(一)
阿新 • • 發佈:2018-11-17
設計一個十字路口交通控制系統,其東西、南北兩個方向除了有紅、黃、綠燈指示是否允許通行外,還設有時間顯示,以倒計時方式顯示每一路允許通行的時間,綠燈、黃燈、紅燈的持續時間分別是45、5和50秒。當東西或南北兩路中任一道上出現特殊情況,例如有消防車,警車要去執行任務,此時交通控制系統應可由交警手動控制立即進入特殊執行狀態,即兩條道上的所有車輛皆停止通行,紅燈全亮,時鐘停止計時,且其數字在閃爍。當特殊執行狀態結束後,管理系統恢復原來的狀態,繼續正常執行。
實現主幹道和支幹道的紅綠燈,並實現時間顯示功能;
實現綠燈,黃燈,紅燈的持續時間固定的交通控制功能;
頂層設計模組:
module top(ext_clk_25m,ext_rst_n,dtube_cs_n,dtube_data,led ); //頂層控制模組 input ext_clk_25m; //時鐘訊號25MHz input ext_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; wire clk;//中間變數 //分頻25MHZ變為1HZ div d1( .ext_clk_25m(ext_clk_25m), .ext_rst_n(ext_rst_n), .mclk(clk) ); //倒計時計數模組(東西) counter c1( .ext_clk_25m(ext_clk_25m), .mclk(clk), .ext_rst_n(ext_rst_n), .TimeH(TimeH), .TimeL(TimeL), .led(led[2:0]) ); //數碼管顯示模組(東西,南北) seg s1( .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) ); //倒計時計數模組(南北) counter1 c2( .ext_clk_25m(ext_clk_25m), .mclk(clk), .ext_rst_n(ext_rst_n), .TimeH1(TimeH1), .TimeL1(TimeL1), .led(led[5:3]) ); endmodule
數碼管顯示模組:
module seg(ext_clk_25m,ext_rst_n,TimeH,TimeL,TimeH1,TimeL1,dtube_cs_n,dtube_data
);
input ext_clk_25m; //時鐘訊號25MHz
input ext_rst_n; //復位訊號
input [3:0]TimeH; //兩位輸入高位 [0]
input [3:0]TimeL; //兩位輸入低位 [1]
input [3:0]TimeH1; //兩位輸入高位 [2]
input [3:0]TimeL1; //兩位輸入低位 [3]
output reg[3:0] dtube_cs_n; //段選資料位
output reg[6:0] dtube_data;//位選資料位
reg[3:0] display_num; //當前顯示資料
reg[16:0] div_cnt; //延時計數器計數位
initial div_cnt = 0;//賦初值為0
//延時計數器模組
[email protected] (posedge ext_clk_25m or negedge ext_rst_n)
begin
if(!ext_rst_n)
div_cnt <= 8'd0;
else if(div_cnt==17'd80000)
div_cnt <= 8'd0;
else
div_cnt <= div_cnt+1'b1;
end
//顯示當前的資料模組
always @(posedge ext_clk_25m or negedge ext_rst_n)
begin
if(!ext_rst_n)
display_num <= 4'h0;
else if(div_cnt < 17'd20000)
display_num <= TimeL;
else if((div_cnt>17'd20000)&(div_cnt <17'd40000))
display_num <= TimeH;
else if((div_cnt>17'd40000)&(div_cnt < 17'd60000))
display_num <=TimeL1;
else
display_num <=TimeH1;
end
//段選資料譯碼模組(共陰數碼管)
always @(*)
begin
if(!ext_rst_n)
dtube_data <= 8'h00;
else begin
case(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;
endcase
end
end
//位選選譯模組
always @(posedge ext_clk_25m or negedge ext_rst_n)
begin
if(!ext_rst_n)
dtube_cs_n <= 4'b1111;
else if(div_cnt <= 17'd20000)
dtube_cs_n <= 4'b1110;
else if((div_cnt>17'd20000)&(div_cnt <=17'd40000))
dtube_cs_n <= 4'b1101;
else if((div_cnt>17'd40000)&(div_cnt <=17'd60000))
dtube_cs_n <= 4'b1011;
else
dtube_cs_n <=4'b0111;
end
endmodule
分頻模組:
module div(ext_clk_25m,ext_rst_n,mclk
);
input ext_clk_25m;//輸入時鐘
input ext_rst_n; //復位埠
output reg mclk;//輸出1Hz
reg [23:0] cnt;//存放計數器的值
initial cnt = 0;
parameter TIME=24'd1250_0000;//時鐘25MHz
//分頻模組
//使得輸入時鐘為25MHz輸出時鐘為1Hz
[email protected](posedge ext_clk_25m or negedge ext_rst_n)
begin
if(!ext_rst_n)
begin
mclk <=1'b0;
cnt <=25'd0;
end
else if(cnt ==TIME-1'b1)
begin
mclk <=~mclk;
cnt <=1'b0;
end
else
cnt <=cnt + 1'b1;
end
endmodule
計數器模組(東西):
module counter(ext_clk_25m,mclk,ext_rst_n,TimeH,TimeL,led
);
input ext_clk_25m;
input mclk;//時鐘訊號
input ext_rst_n;//復位訊號
output reg [3:0]TimeH;//兩位數碼管顯示高位
output reg [3:0]TimeL;//兩位數碼管顯示低位
output reg [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;
//狀態切換模組
[email protected](posedge ext_clk_25m or negedge ext_rst_n)
begin
if(!ext_rst_n)
state_c <=IDLE;
else
state_c <= state_n;
end
//狀態切換
[email protected](*)
begin
case(state_c)
IDLE:
begin
if({TimeH,TimeL}==8'h00)
state_n=S1;
else
state_n=IDLE;
end
S1:
begin
if({TimeH,TimeL}==8'h00)
state_n=S2;
else
state_n=S1;
end
S2:
begin
if({TimeH,TimeL}==8'h00)
state_n=IDLE;
else
state_n=S2;
end
default:
state_n=state_c;
endcase
end
[email protected](posedge ext_clk_25m or negedge ext_rst_n)
begin
if(!ext_rst_n)
times <=8'd00;
else if(state_c==IDLE)
begin
times <=8'h20;
end
else if(state_c==S1)
begin
times <=8'h15;
end
else if(state_c==S2)
begin
times <=8'd5;
end
else;
end
[email protected](posedge mclk or negedge ext_rst_n)
begin
if(!ext_rst_n)
led = 3'b111;
else if(state_c==IDLE)
begin
led[2]=1'b1;
led[0]=1'b0;
end
else if(state_c==S1)
begin
led[0]=1'b1;
led[1]=1'b0;
end
else if(state_c==S2)
begin
led[1]=1'b1;
led[2]=1'b0;
end
else
led = 3'b111;
end
initial TimeH = times[7:4]; //計數器賦初值
//計數器模組高位
[email protected](posedge mclk or negedge ext_rst_n)
begin
if(!ext_rst_n)
TimeH <=times[7:4]; //計數器賦初值
else if({TimeH,TimeL}==8'h00)
begin
TimeH <=times[7:4]; //計數器賦初值
end
else if(TimeL==4'h0)
begin
TimeH <=TimeH-1'b1;
end
else
begin
TimeH <=TimeH;
end
end
initial TimeL = times[3:0];
//計數器模組低位
[email protected](posedge mclk or negedge ext_rst_n)
begin
if(!ext_rst_n)
begin
TimeL <=times[3:0];
end
else if({TimeH,TimeL}==8'h00)
begin
TimeL <=times[3:0];
end
else if(TimeL==4'h0)
begin
TimeL <=4'h9;
end
else
begin
TimeL <=TimeL-1'b1;
end
end
endmodule
計數器模組(南北)
module counter1(ext_clk_25m,mclk,ext_rst_n,TimeH1,TimeL1,led
);
input ext_clk_25m;
input mclk;//時鐘訊號
input ext_rst_n;//復位訊號
output reg [3:0]TimeH1;//兩位數碼管顯示高位
output reg [3:0]TimeL1;//兩位數碼管顯示低位
output reg [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;
//狀態切換模組
initial state_c = IDLE;
[email protected](posedge ext_clk_25m or negedge ext_rst_n)
begin
if(!ext_rst_n)
state_c <=IDLE;
else
state_c <= state_n;
end
//狀態切換
[email protected](*)
begin
case(state_c)
IDLE:
begin
if({TimeH1,TimeL1}==8'h01)
state_n=S1;
else
state_n=IDLE;
end
S1:
begin
if({TimeH1,TimeL1}==8'h01)
state_n=S2;
else
state_n=S1;
end
S2:
begin
if({TimeH1,TimeL1}==8'h01)
state_n=IDLE;
else
state_n=S2;
end
default:
state_n=state_c;
endcase
end
[email protected](posedge ext_clk_25m or negedge ext_rst_n)
begin
if(!ext_rst_n)
times1 <=8'd00;
else if(state_c==IDLE)
begin
times1 <=8'h15;
end
else if(state_c==S1)
begin
times1 <=8'h5;
end
else if(state_c==S2)
begin
times1 <=8'h20;
end
else;
end
[email protected](posedge mclk or negedge ext_rst_n)
begin
if(!ext_rst_n)
led = 3'b111;
else if(state_c==IDLE)
begin
led[3]=1'b1;
led[4]=1'b0;
end
else if(state_c==S1)
begin
led[4]=1'b1;
led[5]=1'b0;
end
else if(state_c==S2)
begin
led[5]=1'b1;
led[3]=1'b0;
end
else
led = 3'b111;
end
initial TimeH1 = times1[7:4]; //計數器賦初值
//計數器模組高位
[email protected](posedge mclk or negedge ext_rst_n)
begin
if(!ext_rst_n)
TimeH1 <=times1[7:4]; //計數器賦初值
else if({TimeH1,TimeL1}==8'h00)
begin
TimeH1 <=times1[7:4]; //計數器賦初值
end
else if(TimeL1==4'h0)
begin
TimeH1 <=TimeH1-1'b1;
end
else
begin
TimeH1 <=TimeH1;
end
end
initial TimeL1 = times1[3:0];
//計數器模組低位
[email protected](posedge mclk or negedge ext_rst_n)
begin
if(!ext_rst_n)
begin
TimeL1 <=times1[3:0];
end
else if({TimeH1,TimeL1}==8'h00)
begin
TimeL1 <=times1[3:0];
end
else if(TimeL1==4'h0)
begin
TimeL1 <=4'h9;
end
else
begin
TimeL1 <=TimeL1-1'b1;
end
end
endmodule