Altera MAX10: 交通灯控制

时间:2023-11-17来源:电子森林

上图为十字路口交通示意图分之路与主路,要求如下:

  • 交通灯主路上绿灯持续15s的时间,黄灯3s的时间,红灯10s的时间;
  • 交通灯支路上绿灯持续7s的时间, 黄灯持续3秒的时间,红灯18秒的时间;

根据上述要求,状态机设计框架分析如下:

  • S1:主路绿灯点亮,支路红灯点亮,持续15s的时间;
  • S2:主路黄灯点亮,支路红灯点亮,持续3s的时间;
  • S3:主路红灯点亮,支路绿灯点亮,持续10s的时间;
  • S4:主路红灯点亮,支路黄灯点亮,持续3s的时间;

首先是时钟分频部分:

//********************************************************
//   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


接下来就是利用三段式状态机实现的交通灯部分:

//********************************************************
//   Copyright(c)2016, STEP FPGA 
//   All rights reserved
//   File name       :   traffic.v
//   Module name     :   traffic
//   Author          :   STEP
//   Email           :   info@stepfpga.com
//   Data            :   2016/08/01
//   Version         :   V1.0
//   Description     :   
////   Modification history
//   ----------------------------------------------------------------------------
// Version       
// Description
//
//******************************************************** 
//*******************
//DEFINE MODULE PORT
//*******************
module traffic(
	//INPUT
	clk			,
	rst_n		,
	//OUTPUT
	out			
);
	//*******************
	//DEFINE INPUT
	//*******************
	input 	clk,rst_n;          //*******************
	//DEFINE OUTPUT
	//*******************
	output	reg[5:0]	out; 	//*******************
	//DEFINE PARAMETER
	//*******************    	parameter      	S1 = 4'b00,    
					S2 = 4'b01,
					S3 = 4'b10,
					S4 = 4'b11; 	parameter		time_s1 = 4'd15,
					time_s2 = 4'd3,
					time_s3 = 4'd10,
					time_s4 = 4'd3; 	parameter		led_s1 = 6'b101011,
					led_s2 = 6'b001011,
					led_s3 = 6'b011101,
					led_s4 = 6'b011001; 	//*********************
	//INNER SIGNAL DECLARATION
	//*********************
	//REGS	
	reg 	[3:0] 	timecont;
	reg 	[1:0] 	cur_state,next_state;  	//WIRES
	wire			clk1h; 
	divide #(.WIDTH(32),.N(12000000)) CLK1H (
								.clk(clk),
								.rst_n(rst_n),
								.clkout(clk1h));
	//Sequential logic style
	always @ (posedge clk1h)
	begin
		if(!rst_n) cur_state <= S1;
        else cur_state <= next_state;
	end 	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 	always @ (posedge clk1h)
	begin
		if(!rst_n) 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路开关,可以用来作为输入信号分别控制数码管的输出。按照下面表格定义输入输出信号

信号引脚信号引脚
clkJ5rstJ9
out[0]E14out[1]E15
out[2]G15out[3]D12
out[4]C14out[5]C15

配置好以后编译下载程序。您也可以试试修改程序,观察修改代码对于FPGA内部电路所造成的影响。

状态机是一类很重要的时序逻辑电路,是许多数字系统的核心部件,掌握状态机的使用是利用FPGA与CPLD进行开发的一项必会技能,本小节的交通灯程序即是利用三段式状态机描述方法实现的,希望读者能够快速掌握这项技能。

关键词: 交通灯 状态机 FPGA Lattice Diamond 小脚丫

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW

或用微信扫描左侧二维码

相关文章

查看电脑版