Lattice MXO2: 交通燈控制
簡易交通燈:本節(jié)將向您介紹Verilog語法之中的精髓內(nèi)容——狀態(tài)機(jī),并且將利用狀態(tài)機(jī)實(shí)現(xiàn)十字路口的交通燈。
硬件說明與實(shí)現(xiàn)項(xiàng)目框圖
本文引用地址:http://www.ex-cimer.com/article/202311/453009.htm
上圖為十字路口交通示意圖分之路與主路,要求如下: * 交通燈主路上綠燈持續(xù)15s的時間,黃燈3s的時間,紅燈10s的時間; * 交通燈支路上綠燈持續(xù)7s的時間, 黃燈持續(xù)3秒的時間,紅燈18秒的時間;
根據(jù)上述要求,狀態(tài)機(jī)設(shè)計框架分析如下: * S1:主路綠燈點(diǎn)亮,支路紅燈點(diǎn)亮,持續(xù)15s的時間; * S2:主路黃燈點(diǎn)亮,支路紅燈點(diǎn)亮,持續(xù)3s的時間; * S3:主路紅燈點(diǎn)亮,支路綠燈點(diǎn)亮,持續(xù)10s的時間; * S4:主路紅燈點(diǎn)亮,支路黃燈點(diǎn)亮,持續(xù)3s的時間;
Verilog代碼
首先是時鐘分頻部分:
//******************************************************** // Copyright(c)2016, STEP FPGA // All rights reserved // File name : divide.v // Module name : divide // Author : STEP // Email : info@stepfpga.com // Data : 2016/08/01 // Version : V1.0 // Description : // // Modification history // ---------------------------------------------------------------------------- // Version // Description // //******************************************************** //******************* //DEFINE MODULE PORT //******************* module divide( //INPUT clk , rst_n , //OUTPUT clkout ); //******************* //DEFINE PARAMETER //******************* parameter WIDTH = 3; parameter N = 5; //******************* //DEFINE INPUT //******************* input clk,rst_n; //******************* //DEFINE OUTPUT //******************* output clkout; //******************** //OUTPUT ATTRIBUTE //******************** //REGS reg [WIDTH-1:0] cnt_p,cnt_n; reg clk_p,clk_n; assign clkout = (N==1)?clk:(N[0])?(clk_p&clk_n):clk_p; //Sequential logic style always @ (posedge clk) begin if(!rst_n) cnt_p<=0; else if (cnt_p==(N-1)) cnt_p<=0; else cnt_p<=cnt_p+1; end always @ (negedge clk) begin if(!rst_n) cnt_n<=0; else if (cnt_n==(N-1)) cnt_n<=0; else cnt_n<=cnt_n+1; end always @ (posedge clk) begin if(!rst_n) clk_p<=0; else if (cnt_p<(N>>1)) clk_p<=0; else clk_p<=1; end always @ (negedge clk) begin if(!rst_n) clk_n<=0; else if (cnt_n<(N>>1)) clk_n<=0; else clk_n<=1; end endmodule
接下來就是利用三段式狀態(tài)機(jī)實(shí)現(xiàn)的交通燈部分:
// ******************************************************************** // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< // ******************************************************************** // File name : traffic.v// Module name : traffic // Author : STE // Description : // // -------------------------------------------------------------------- // Code Revision History : // -------------------------------------------------------------------- // Version: |Mod. Date: |Changes Made: // V1.0 |2017/03/02 |Initial ver // -------------------------------------------------------------------- // Module Function:簡易交通燈 module traffic( clk , //時鐘 rst_n , //復(fù)位 out //三色led代表交通燈); input clk,rst_n; output reg[5:0] out; parameter S1 = 4'b00, //狀態(tài)機(jī)狀態(tài)編碼 S2 = 4'b01, S3 = 4'b10, S4 = 4'b11; parameter time_s1 = 4'd15, //計時參數(shù) time_s2 = 4'd3, time_s3 = 4'd10, time_s4 = 4'd3; //交通燈的控制 parameter led_s1 = 6'b101011, // LED2 綠色 LED1 紅色 led_s2 = 6'b110011, // LED2 藍(lán)色 LED1 紅色 led_s3 = 6'b011101, // LED2 紅色 LED1 綠色 led_s4 = 6'b011110; // LED2 紅色 LED1 藍(lán)色 reg [3:0] timecont; reg [1:0] cur_state,next_state; //現(xiàn)態(tài)、次態(tài) wire clk1h; //1Hz時鐘 //產(chǎn)生1秒的時鐘周期 divide #(.WIDTH(32),.N(12000000)) CLK1H ( .clk(clk), .rst_n(rst_n), .clkout(clk1h)); //第一段 同步邏輯 描述次態(tài)到現(xiàn)態(tài)的轉(zhuǎn)移 always @ (posedge clk1h or negedge rst_n) begin if(!rst_n) cur_state <= S1; else cur_state <= next_state; end //第二段 組合邏輯描述狀態(tài)轉(zhuǎn)移的判斷 always @ (cur_state or rst_n or timecont) begin if(!rst_n) begin next_state = S1; end else begin case(cur_state) S1:begin if(timecont==1) next_state = S2; else next_state = S1; end S2:begin if(timecont==1) next_state = S3; else next_state = S2; end S3:begin if(timecont==1) next_state = S4; else next_state = S3; end S4:begin if(timecont==1) next_state = S1; else next_state = S4; end default: next_state = S1; endcase end end //第三段 同步邏輯 描述次態(tài)的輸出動作 always @ (posedge clk1h or negedge rst_n) begin if(!rst_n==1) begin out <= led_s1; timecont <= time_s1; end else begin case(next_state) S1:begin out <= led_s1; if(timecont == 1) timecont <= time_s1; else timecont <= timecont - 1; end S2:begin out <= led_s2; if(timecont == 1) timecont <= time_s2; else timecont <= timecont - 1; end S3:begin out <= led_s3; if(timecont == 1) timecont <= time_s3; else timecont <= timecont - 1; end S4:begin out <= led_s4; if(timecont == 1) timecont <= time_s4; else timecont <= timecont - 1; end default:begin out <= led_s1; end endcase end end endmodule
引腳分配
小腳丫上正好有4路按鍵和4路開關(guān),可以用來作為輸入信號分別控制數(shù)碼管的輸出。按照下面表格定義輸入輸出信號
信號 | 引腳 | 信號 | 引腳 |
---|---|---|---|
clk | C1 | rst | L14 |
out[0] | P2 | out[1] | N2 |
out[2] | M2 | out[3] | P4 |
out[4] | N3 | out[5] | M3 |
配置好以后編譯下載程序。您也可以試試修改程序,觀察修改代碼對于FPGA內(nèi)部電路所造成的影響。
小結(jié)
狀態(tài)機(jī)是一類很重要的時序邏輯電路,是許多數(shù)字系統(tǒng)的核心部件,掌握狀態(tài)機(jī)的使用是利用FPGA與CPLD進(jìn)行開發(fā)的一項(xiàng)必會技能,本小節(jié)的交通燈程序即是利用三段式狀態(tài)機(jī)描述方法實(shí)現(xiàn)的,希望讀者能夠快速掌握這項(xiàng)技能。
評論