使用Quartus-II 9.1SP2 + ModelSim 6.5b-Aletra + Altera DE2-115 FPGA開發平台, 用一個FSM設計一個紅綠燈 為例(FPGA開發平台)
用一個有限狀態機FSM(finite state machine)設計一個紅綠燈控制器。
紅綠燈規格如下:
- 主幹道上有較高優先順序
- 會有來車由郊道行駛至交叉口(郊道之號誌應改為綠燈,且需要有足夠的時間讓郊道的車子通過)
- 若郊道無車輛,其號誌應由綠燈轉為黃燈再轉回紅燈
- 郊道上有感應器可以產生信號 singal (C),singal (C) = 0 代表有車通過;反之
- S0~S3為雙道號誌之狀態,狀態轉換時需有延遲,延遲要可以更改
- S0-->HGRE_FRED=2'b00, // Highway green and farm red
- S1-->HYEL_FRED = 2'b01,// Highway yellow and farm red
- S2-->HRED_FGRE = 2'b10,// Highway red and farm green
- S3-->HRED_FYEL = 2'b11;// Highway red and farm yellow
參考來源https://www.fpga4student.com/2016/11/verilog-code-for-traffic-light-system.html
module DE2_115 (SW, LEDR, LEDG , CLOCK_50 ,KEY ,HEX0 ,HEX1 ,HEX2,HEX3,HEX4 ,HEX5 ,HEX6,HEX7, GPIO );
input [17:0] SW; // toggle switches
input [7:0] KEY; // Push bottom
input CLOCK_50; //Clock 27MHz , 50Mhz
output [17:0] LEDR; // red LEDS
output [8:0] LEDG; // green LEDs
output [6:0] HEX0,HEX1,HEX2,HEX3; //7-segment display
output [6:0] HEX4,HEX5,HEX6,HEX7; //7-segment display
inout [35:0] GPIO;
assign HEX0=7'b111_1111;
assign HEX1=7'b111_1111;
assign HEX2=7'b111_1111;
assign HEX3=7'b111_1111;
assign HEX4=7'b111_1111;
assign HEX5=7'b111_1111;
assign HEX6=7'b111_1111;
assign HEX7=7'b111_1111;
//traffic_light(light_highway, light_farm, C, clk, rst_n);
traffic_light (LEDR[2:0],LEDR[7:5],SW[0],CLOCK_50,KEY[0]);
endmodule
input [17:0] SW; // toggle switches
input [7:0] KEY; // Push bottom
input CLOCK_50; //Clock 27MHz , 50Mhz
output [17:0] LEDR; // red LEDS
output [8:0] LEDG; // green LEDs
output [6:0] HEX0,HEX1,HEX2,HEX3; //7-segment display
output [6:0] HEX4,HEX5,HEX6,HEX7; //7-segment display
inout [35:0] GPIO;
assign HEX0=7'b111_1111;
assign HEX1=7'b111_1111;
assign HEX2=7'b111_1111;
assign HEX3=7'b111_1111;
assign HEX4=7'b111_1111;
assign HEX5=7'b111_1111;
assign HEX6=7'b111_1111;
assign HEX7=7'b111_1111;
//traffic_light(light_highway, light_farm, C, clk, rst_n);
traffic_light (LEDR[2:0],LEDR[7:5],SW[0],CLOCK_50,KEY[0]);
endmodule
// Verilog project: Verilog code for traffic light controller
module traffic_light(light_highway, light_farm, C, clk, rst_n);
parameter HGRE_FRED=2'b00, // Highway green and farm red
HYEL_FRED = 2'b01,// Highway yellow and farm red
HRED_FGRE = 2'b10,// Highway red and farm green
HRED_FYEL = 2'b11;// Highway red and farm yellow
input C, // sensor
clk, // clock = 50 MHz
rst_n; // reset active low
output reg[2:0] light_highway, light_farm; // output of lights
reg[27:0] count=0,count_delay=0;
reg delay10s=0, delay3s1=0,delay3s2=0,RED_count_en=0,YELLOW_count_en1=0,YELLOW_count_en2=0;
wire clk_enable; // clock enable signal for 1s
reg[1:0] state, next_state;
// next state
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
state <= 2'b00;
else
state <= next_state;
end
// FSM
always @(*)
begin
case(state)
HGRE_FRED:
begin // Green on highway and red on farm way
RED_count_en=0;
YELLOW_count_en1=0;
YELLOW_count_en2=0;
light_highway = 3'b001;
light_farm = 3'b100;
if(C)
next_state = HYEL_FRED;
// if sensor detects vehicles on farm road,
// turn highway to yellow -> green
else
next_state =HGRE_FRED;
end
HYEL_FRED:
begin// yellow on highway and red on farm way
light_highway = 3'b010;
light_farm = 3'b100;
RED_count_en=0;
YELLOW_count_en1=1;
YELLOW_count_en2=0;
if(delay3s1)
next_state = HRED_FGRE;
// yellow for 3s, then red
else
next_state = HYEL_FRED;
end
HRED_FGRE:
begin// red on highway and green on farm way
light_highway = 3'b100;
light_farm = 3'b001;
RED_count_en=1;
YELLOW_count_en1=0;
YELLOW_count_en2=0;
if(delay10s)
next_state = HRED_FYEL;
// red in 10s then turn to yello -> green again for high way
else
next_state =HRED_FGRE;
end
HRED_FYEL:
begin// red on highway and yellow on farm way
light_highway = 3'b100;
light_farm = 3'b010;
RED_count_en=0;
YELLOW_count_en1=0;
YELLOW_count_en2=1;
if(delay3s2)
next_state = HGRE_FRED;
// turn green for highway, red for farm road
else
next_state =HRED_FYEL;
end
default:
next_state = HGRE_FRED;
endcase
end
//
// create red and yellow delay counts
always @(posedge clk)
begin
if(clk_enable==1) begin
if(RED_count_en||YELLOW_count_en1||YELLOW_count_en2)
count_delay <=count_delay + 1;
if((count_delay == 9)&&RED_count_en)
begin
delay10s=1;
delay3s1=0;
delay3s2=0;
count_delay<=0;
end
else if((count_delay == 2)&&YELLOW_count_en1)
begin
delay10s=0;
delay3s1=1;
delay3s2=0;
count_delay<=0;
end
else if((count_delay == 2)&&YELLOW_count_en2)
begin
delay10s=0;
delay3s1=0;
delay3s2=1;
count_delay<=0;
end
else
begin
delay10s=0;
delay3s1=0;
delay3s2=0;
end
end
end
// create 1s clock enable
always @(posedge clk)
begin
count <=count + 1;
if(count == 50000000) // 50,000,000 for 50 MHz clock running on real FPGA
//if(count == 3) // for testbench
count <= 0;
end
assign clk_enable = count==3 ? 1: 0; // 50,000,000 for 50MHz running on FPGA
endmodule
沒有留言:
張貼留言