luyaoda0 2019-12-08
下图分别为时钟同步的Moore状态机(左)和时钟同步的Mearly状态机(右),二者都由产生下一状态的组合逻辑、当前状态寄存器和产生输出的组合逻辑三个部分组成。
三段式状态机正如其名字一样,每个部分采用一个always过程块进行描述,可以清晰地显示出状态机的结构。
在调试多输出状态机时,还可以根据输出的数量把产生输出的组合逻辑按输出写成彼此独立的always组合块,以方便调试,在设计复杂的多输出状态机时推荐采用这种风格。
别人的总结:
下图为样例的状态转移图,并使用三段式状态机对其进行描述。由于该状态机包含两个输出G、F,所以代码中包含两个输出组合逻辑。
// 三段式状态机 module fsm_mult_out( output reg K2, K1, input clk, Reset, A ); reg [1:0] state, nextstate;parameter Idle = 2‘b00, Start = 2‘b01, Stop = 2‘b10, Clear = 2‘b11;// -----------------当前状态寄存器------------------------- always @(posedge clk) // 为什么这里要用非阻塞赋值,后面用阻塞赋值? if(!Reset) state <= Idle; else state <= nextstate; // ----------------产生下一状态的组合逻辑-------------------- always @(state, A) case(state) Idle: if(A) nextstate = Start; else nextstate = state; Start: if(!A) nextstate = Stop; else nextstate = state; Stop: if(A) nextstate = Clear; else nextstate = state; Clear: if(!A) nextstate = Idle; else nextstate = Clear; default: nextstate = 2‘bxx; endcase // --------------产生输出的组合逻辑-------------------------- // assignment for K1 always @(state, Reset, A) if(!Reset) K1 = 0; else if(state==Clear && !A) K1 = 1; else K1 = 0; // assginment for K2 always @(state, Reset, A) if(!Reset) K2 = 0; else if(state==Stop && A) K2 = 1; else K2 = 0; endmodule
相应的testbench
// testbench module t_fsm(); reg a; reg clk, rst; wire k1, k2; // reg [1:0] state; fsm_mult_out m(.K2(k2), .K1(k1), .A(a), .clk(clk), .Reset(rst)); initial begin // state = 2‘b00; a = 0; rst = 1; clk = 0; #22 rst = 0; #133 rst = 1; end always #50 clk = ~clk; always @(posedge clk) begin #30 a = {$random}%2; #(3*50 + 12); end initial begin #100000 $stop; end endmodule
整体流程字符流 -> 状态机 -> 词token -> 栈 -> dom构建 DOM 的过程是:从父到子,从先到后,一个一个节点构造,并且挂载到DOM树上。<p class="a">text text