【状态机FSM】
基础知识:
- 为啥要用状态机嘛:由于FPGA是并行执行,但当我想要处理有先后顺序的问题,这个时候就需要用状态机来解决
- 有几种状态机让我选:Moore状态机、Mealy状态机(记得B站数电老师讲到过这两个词语,先挖个坑)
- 这两个让我怎么选嘛:
- Moore状态机:输出只和当前状态有关,与输入无关。
- Mealy状态机:输出和输入、当前状态有关(常用)
- 相同点:状态的跳转只和输入有关
三段式状态机的结构:(重点)
- 状态编码:描述状态机各个状态名称
-
第一段:时序逻辑: 描述状态转换,格式固定
always@(posedge Clk or negedge Rst_n)begin if(Rst_n == 1'b0) state <= IDLE; else state <= next_state; end
- 第二段:状态转移条件:只考虑状态之间的跳转
always @(*)
- 第三段:输出状态
实践:
目标:可乐贩卖机
3元1瓶、投币1次1元、投币3元出1瓶可乐
我是这样想的:
- 首先需要确定选什么作为状态,这里无非就只有可乐和钱,我一定是选钱
- 明确输入、输出、状态跳变,画出状态转移图
状态机功能模块:
// ------------------------------ // 新型二段式状态机:状态、输出信号都是时序逻辑 // ------------------------------ module fsm ( input Clk, input Rst_n, input pi_input, output reg po_out ); parameter IDLE = 3'b001; parameter ONE = 3'b010; parameter TWO = 3'b100; reg [2:0] state; // 状态转移 always@(posedge Clk or negedge Rst_n) if(Rst_n == 1'b0) state <= IDLE; else case (state) IDLE : if(pi_input == 1'b1) state <= ONE; else state <= IDLE; ONE : if(pi_input == 1'b1) state <= TWO; else state <= ONE; TWO : if(pi_input == 1'b1) state <= IDLE; else state <= TWO; default : state <= IDLE; endcase // 输出由状态和输入同时决定 always@(posedge Clk or negedge Rst_n) if(Rst_n == 1'b0) po_out <= 1'b0; else if(state == TWO && pi_input == 1'b1) po_out <= 1'b1; else po_out <= 1'b0; endmodule