FPGA学习笔记(一):三段式状态机

1.状态机简介

状态机可根据控制信号完成预定的状态转换,由组合逻辑电路和寄存器组成,可由状态转换表或状态转换图描述。

输出只和当前状态有关而与输入无关成为More型状态机,输出和当前状态、输入都有关称为Mealy型状态机。

2.功能需求

本例采用CPLD: MAX V 5M240ZT100C5,目的是通过两个按键key1和key2控制一组引脚的输出状态,该组引脚作为控制信号控制一组继电器,分断一组高压线路。key1按下时系统关闭,引脚输出全为0;key2按下时系统开启,引脚输出全为1。

状态转换图如下:

3.分析

  • 按键按下检测与消抖
  • 三段式状态机:一段 状态转移——仅负责状态的刷新;二段 判断下一状态——仅负责下一状态的判断;三段 状态输出——仅负责根据不同状态输出不同电平。
  • 复位功能

4.代码

module state_ctl(
	input clk,				//时钟信号
	input rst,				//复位信号,低电平有效
	input key1, 			//按键,低电平表示按下
	input key2,
	output reg [3:0] led_output,//LED输出指示
	output reg [3:0] pin_output //引脚输出
);

 
//参数
localparam on_state  = 4'b0010,//状态机状态2
           off_state = 4'b0001,//状态机状态1
           rst_state = 4'b0000,//状态机状态0

           rst_output = 4'b0000,//系统复位 引脚输出
           on_output  = 4'b1111,//系统开启 引脚输出
           off_output = 4'b0000;//系统关闭 引脚输出

 
 //计数寄存器
reg [19:0]  cnt;
       
//状态寄存器
reg [3:0] NS;			//next_state
reg [3:0] CS;			//current_state
reg  [1:0] low_sw;	//low_switch
reg  [1:0] low_sw_r; 


//计数器,用于按键检测---------------------------------------------------------------------------------------------------------------
always @ (posedge clk)

	begin
		cnt <= cnt + 1'b1;
	end
	

always @(posedge clk )

	begin
		if (cnt == 20'hfffff)      
			low_sw <= {key2,key1};
	end
	

	

//检测按键下降沿----------------------------------------------------------------------------------------------------------------------------------------------------------------
     
always @ ( posedge clk )
	begin
		low_sw_r <= low_sw;//将当前按键状态赋给low_sw_r
	end
	

reg [1:0] ctrl;

always @ ( posedge clk )
	begin
		ctrl <= low_sw_r[1:0] & ( ~low_sw[1:0]);//检测到下降沿ctrl为1 ,由于检测延时,故已消抖
	end

 
//状态转移模块------------------------------------------------------------------------------------------------------------------------------------------------------------------
always@(posedge clk or negedge rst)
	begin
		if(!rst)
			CS <= rst_state;
		else
			CS <= NS;		
	end

	
//判断状态转移------------------------------------------------------------------------------------------------------------------------------------------------------------------
always@(ctrl)
	begin
		case(CS)
			rst_state:
				begin
					if(ctrl[1])
						NS <= on_state;
					else if(ctrl[0])
						NS <= off_state;
					else
						NS <= rst_state;
				end
			off_state:
				begin
					if(ctrl[1])
						NS <= on_state;
					else
						NS <= off_state;
				end
			on_state:
				begin
					if(ctrl[0])
						NS <= off_state;
					else
						NS <= on_state;
				end
			default:
				begin
					NS <= off_state;
				end
		endcase
	end

	
	
//描述状态输出------------------------------------------------------------------------------------------------------------------------------------------------------------------
always@(posedge clk or negedge rst)
	begin
		begin
			case(CS)
				on_state: begin
					pin_output <= on_output;
					led_output <= ~on_output;
				end
				off_state: begin
					pin_output <= off_output;
					led_output <= ~off_output;
				end
				rst_state: begin
					pin_output <= rst_output;
					led_output <= ~rst_output;
				end
			endcase
		end
						
	end
endmodule	

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值