描述状态机推荐采用三段式FSM描述方法。这种写法使用3个always模块,一个always模块采用同步时序的方式描述状态转移,一个always采用组合逻辑的方式判断状态转移条件,描述状态转移规律,第三个always模块使用同步时序电路描述每个状态的输出。
这种做法好处在于便于阅读、理解、维护,更重要的是利于综合器优化代码。利于用户添加合适的时序约束条件,利于布局布线器实现设计。
三段式FSM写法参考如下程序:
module fsm(in1, in2, clk, rst_n, out1, out2, err);input in1, in2;input clk, rst_n;output out1, out2;output err;reg out1, out2;reg err;reg[2:0] CS, NS;parameter[2:0] IDLE = 3'b000, S1 = 3'b001, S2 = 3'b010, ERROR = 3'B100; //时序逻辑,状态转移always @(posedge clk or negedge rst_n)begin if (!rst_n) CS <= IDLE; else CS <= NS;end//组合逻辑,状态转移条件判断always @(rst_n, CS, in1, in2)begin NS = 3'bX; case (CS) IDLE: begin if (!in1) NS = IDLE; if (in1 && in2) NS = S1; if (in1 && !in2) NS = ERROR; end S1: begin if (!in2) NS = S1; if (in1 && in2) NS = S2; if (!in1 && in2) NS = ERROR; end S2: begin if (in2) NS = S2; if (in1 && !in2) NS = IDLE; if (!in1 && !in2) NS = ERROR; end ERROR: begin if (in1) NS = ERROR; if (!in1) NS = IDLE; end default: NS = IDLE; endcase;end//时序逻辑,状态机输出always @(posedge clk or negedge rst_n)begin if (!rst_n) {out1, out2, err} <= 3'b000; else begin {out1, out2, err} <= 3'b000; case (NS) IDLE: {out1, out2, err} <= 3'b000; S1: {out1, out2, err} <= 3'b100; S2: {out1, out2, err} <= 3'b010; ERROR: {out1, out2, err} <= 3'b111; default: {out1, out2, err} <= 3'b000; endcase endendendmodule