zoukankan      html  css  js  c++  java
  • 同步状态机——三段式状态机

    三段式状态机

    下图分别为时钟同步的Moore状态机(左)和时钟同步的Mearly状态机(右),二者都由产生下一状态的组合逻辑、当前状态寄存器和产生输出的组合逻辑三个部分组成。

    三段式状态机正如其名字一样,每个部分采用一个always过程块进行描述,可以清晰地显示出状态机的结构。

    在调试多输出状态机时,还可以根据输出的数量把产生输出的组合逻辑按输出写成彼此独立的always组合块,以方便调试,在设计复杂的多输出状态机时推荐采用这种风格。

     

     

    别人的总结:

    1. 使用三段式状态机需要声明内部信号,一般需要定义state和nextstate;
    2. 三个always语句块分别代表:
      1. 当前状态转换到下一状态的时序逻辑;
      2. 在当前状态在当前输出下转换为下一状态的组合逻辑;
      3. 当前状态(和当前输入)产生当前输出的组合逻辑;

     样例:

      下图为样例的状态转移图,并使用三段式状态机对其进行描述。由于该状态机包含两个输出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
  • 相关阅读:
    转:C++中Static作用和使用方法
    转:C/C++中,空数组、空类、类中空数组的解析及其作用
    转:c++类实例在内存中的分配
    转:union 联合体(共用体)
    转:内存对齐与补齐 字节对齐与结构体大小
    转:c++内存分配
    转:代码重构
    转:设计模式六大原则(3):依赖倒置原则
    读书
    转:Teach Yourself Programming in Ten Years——用十年教会自己编程
  • 原文地址:https://www.cnblogs.com/lizhiqing/p/12008285.html
Copyright © 2011-2022 走看看