FPGA有限状态机设计 王安然
主要内容 有限状态机概述 有限状态机分类及异同 序列检测状态机实现 有限状态机编码方式 有限状态机设计一般步骤及实例 交通灯三段式设计案例
有限状态机描述 FSM:finite state machine,一种由寄存器组和组合逻辑构成硬件 时序电路,堪称FPGA硬件设计的灵魂。 在同一时钟跳变沿由当前状态(现态)转移到下一状态(次态) 究竟转向哪一状态不但取决于各个输入值,还取决于当前状态。 在时钟跳变沿时刻进行复杂组合逻辑控制 包含时序、组合逻辑电路 非常有用模型,可以模拟大部分事物。如按键命令、自动门控制、 通信时序等 1.状态总数state是有限的 2.任何一个时刻,只能处于一个状态 3.在条件满足时,由一个状态转变到另一个状态
有限状态机基本类型 moore型:输出逻辑只由当前状态决定 下一个状态 = F(当前状态,输入信号); 输出信号 = G(当前状态);
Mealy和Moore状态机结构图 mealy型:输出逻辑不但与当前状态有关还与当前输入值有关 下一个状态 = F(当前状态,输入信号); 输出信号 = G(当前状态,输入信号);
举例:序列检测器 将指定的二进制序列从数码流中检测出来 如:将“101”序列从码流“111010110”中检测,输出高代表检 测到序列,低电平代表没有发现 1 识别101序列 clk rst out 序列检测结果示意 IN 1 OUT
举例:序列检测器 mealy型 moore型 s0: begin state <= vin? s1:s0; vout <= 1'b0; end s1: begin state <= vin? s1:s2; s2: begin state <= vin? s1:s0; if(vin)vout <= 1'b1; else vout <= 1'b0; s0: begin state <= vin? s1:s0; vout <= 1'b0; end s1: begin state <= vin? s1:s2; s2: begin state <= vin? s3:s0; s3: begin state <= vin? s1:s2; vout <= 1'b1;
有限状态机要素 状态:当前状态、次态 输入:触发状态转移的输入条件 输出:输入所触发的动作 输入 / 输出 现态 次态
有限状态机的样式 一段式 整个状态机在一个always模块中,模块中既包含状态转移也含有 组合逻辑输入输出。 二段式 三段式 状态机使用三个always描述,一个采用同步时序实现状态转移, 一个采用组合逻辑判断转移条件,一个实现状态同步输出 通过例程了解
状态机三段式模板 //第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器 always @ (posedge clk or negedge rst_n) //异步复位 if(!rst_n) current_state <= IDLE; else current_state <= next_state; //注意,使用的是非阻塞赋值 //第二个进程,组合逻辑always模块,描述状态转移条件判断 always @ (current_state) //电平触发 begin next_state = x; //要初始化,使得系统复位后能进入正确的状态 case(current_state) S1: if(...) next_state = S2; //阻塞赋值 ... endcase end //输出逻辑部分 二 out1 = 1‘b1; 段 out2 = 1‘b1; 式
状态机三段式模板 三 段 式 //第三个进程,同步时序always模块,格式化描述次态寄存器输出 always @ (posedge clk or negedge rst_n) ...//初始化 case(next_state) S1: out1 <= 1'b1; //注意是非阻塞逻辑 S2: out2 <= 1'b1; default:... //default的作用是免除综合工具综合出锁存器 endcase end 三 段 式
序列检测器一段式 具体工程及源码在附带资料中,仿真结果如下:
序列检测器二段式 具体工程及源码在附带资料中,仿真结果如下:
序列检测器三段式 具体工程及源码在附带资料中,仿真结果如下:
不同样式的比较 有
状态编码 二进制码 格雷码 独热码 二进制 格雷码 独热码 000 00000001 001 00000010 010 011 00000100 00001000 100 110 00010000 101 111 00100000 01000000 10000000 二进制码 格雷码 独热码 二进制编码、格雷码编码使用最少的触发器,消耗较多的组合逻辑,而独热码编码反之。 在CPLD中,由于器件拥有较多的地提供组合逻辑资源,所以CPLD多使用二进制编码或格雷码,而FPGA更多地提供触发器资源,所以在FPGA中多使用独热码编码,并非绝对,以实际应用而定。
状态机的设计的一般步骤 逻辑抽象,得出状态转移图 状态化简 如果在状态转换图中出现这样两个状态,它们在相同 的输入下转换到同一状态去,并得到一样的输出,则 称它们为等价状态 ,可合并成一个,可以由电脑完成 状态分配:又称状态编码 描述状态机 (选定触发器的类型并求出状态方程、驱动方程和输出方程 按照方程得出逻辑图)
交通灯 交通灯 由红黄绿三种颜色组成用来指挥交通的信号灯; 伴随着红绿灯的指示,有数码管的计时;
交通灯逻辑 交通灯主路上绿灯持续22秒时间,黄灯4秒时间,红灯16秒时间; 交通灯支路上绿灯持续12秒时间,黄灯4秒时间,红灯26秒时间;
程序设计框图 首先将系统时钟进行分配产生1Hz信号 通过1Hz信号倒计时进行状态机状态转换 S1:主路绿灯点亮,支路红灯点亮,持续22S时间; S2:主路黄灯点亮,支路红灯点亮,持续4S时间; S3:主路红灯点亮,支路绿灯点亮,持续12S时间; S4:主路红灯点亮,支路黄灯点亮,持续4S时间;
交通灯实现 reg [1:0] c_state,n_state; //同步状态转移 always @(posedge clk_1Hz or negedge rst_n_in) if(!rst_n_in) c_state <= S1; else c_state <= n_state; //判断转移条件 always @(c_state or timecnt) //组合逻辑 if(!rst_n_in) n_state = S1; else begin case(c_state) S1: if(!timecnt) n_state = S2; else n_state = S1; S2: if(!timecnt) n_state = S3; else n_state = S2; S3: if(!timecnt) n_state = S4; else n_state = S3; S4: if(!timecnt) n_state = S1; else n_state = S4; default:n_state = S1; endcase end
交通灯实现 localparam RED = 3'b011, GREEN = 3'b101, YELLOW = 3'b110; S1: begin led_master <= GREEN; //主路绿灯 led_slave <= RED; //支路红灯 if(timecnt==0) begin timecnt <= 8‘h21; //计数初值 end else begin if(timecnt[3:0]==0) begin //十进制减法 timecnt[7:4] <= timecnt[7:4] - 1'b1; timecnt[3:0] <= 4'd9; end else timecnt[3:0] <= timecnt[3:0] - 1'b1; end
交通灯仿真结果