Verilog FSM设计的学习心得(三)

时间:2022-06-30 14:00:12

设计FSM时,有多种编码方式,是为了达到以下目的:

  • 改变状态编码和FSM风格时,FSM的编码方式应便于修改
  • 编码方式应紧凑
  • 编码方式应容易理解和实现
  • 编码方式应便于调试
  • 编码方式应实现有效的综合

本文主要讨论onehot(独热码)的索引(index)和非索引(no-index)编码方式。

onehot编码方式的优势(摘录自Steve Golson 《State machine design techniques for Verilog and VHDL》)

  • One-hot state machines are typically faster. Speed is independent of the number of states, and instead depends only on the number of transitions into a particular state. A highly-encoded machine may slow dramatically as more states are added.
  • Don’t have to worry about finding an “optimal”state encoding. This is particularly beneficial as the machine design is modified, for what is “optimal”for one design may no longer be best if you add a few states and change some others. One-hot is equally “optimal” for all machines.
  • One-hot machines are easy to design. HDL code can be written directly from the state diagram without coding a state table.
  • Modifications are straightforward. Adding and deleting states, or changing excitation equations,can be implemented easily without affecting the rest of the machine.
  • Easily synthesized from VHDL or Verilog.
  • There is typically not much area penalty over highly-encoded machines.
  • Critical paths are easy to find using static timing analysis.
  • Easy to debug. Bogus state transitions are obvious, and current state display is trivial.

(本来想翻译来的,后面发现自己的英语水平仅够自己看懂,翻译出来后实在达不到原文的效果,为避免误导大家,就直接从原文摘录了^@^)

下面以实例来说明索引和非索引编码方式的区别。

Verilog FSM设计的学习心得(三)

图1 10状态的FSM

非索引(no-index)编码方式:

module fsm_no_index
    (output reg y1,
    input jmp, go, clk, rst_n);

    parameter S0 = 10'b0000000001,
                        S1 = 10'b0000000010,
                        S2 = 10'b0000000100,
                        S3 = 10'b0000001000,
                        S4 = 10'b0000010000,
                        S5 = 10'b0000100000,
                        S6 = 10'b0001000000,
                        S7 = 10'b0010000000,
                        S8 = 10'b0100000000,
                        S9 = 10'b1000000000;

     reg [3:0] state, next;

    always @(posedge clk or negedge rst_n)
            if (!rst_n) state <= S0;
            else state <= next;

    always @(state or go or jmp) begin
           next = 4'bx;
           y1 = 1'b0;
           case (state)
               S0 : if (!go) next = S0;
                       else if (jmp) next = S3;
                       else next = S1;
               S1 : if (jmp) next = S3;
                     else next = S2;
              S2 : next = S3;
              S3 : begin y1 = 1'b1;
                         if (jmp) next = S3;
                         else next = S4;
                       end
              S4 : if (jmp) next = S3;
                    else next = S5;
             S5 : if (jmp) next = S3;
                     else next = S6;
              S6 : if (jmp) next = S3;
                     else next = S7;
              S7 : if (jmp) next = S3;
                       else next = S8;
              S8 : if (jmp) next = S3;
                     else next = S9;
              S9 : if (jmp) next = S3;
                    else next = S0;
            endcase
        end
endmodule

 

索引(index)编码方式:

module fsm_index
    (output reg y1,
      input jmp, go, clk, rst_n);

    parameter S0 = 0,
                        S1 = 1,
                        S2 = 2,
                        S3 = 3,
                        S4 = 4,
                        S5 = 5,
                        S6 = 6,
                        S7 = 7,
                        S8 = 8,
                        S9 = 9;

    reg [9:0] state, next;

    always @(posedge clk or negedge rst_n)
          if (!rst_n) begin
                 state <= 0;
                 state[S0] <= 1'b1;
               end
         else state <= next;

always @(state or go or jmp) begin
       next = 10'b0;
        y1 = 1'b0;
        case (1'b1) // ambit full_case parallel_case
             state[S0] : if (!go) next[S0]=1'b1;
                               else if (jmp) next[S3]=1'b1;
                               else next[S1]=1'b1;
             state[S1] : if (jmp) next[S3]=1'b1;
                               else next[S2]=1'b1;
             state[S2] : next[S3]=1'b1;
             state[S3] : begin y1 = 1'b1;
                               if (jmp) next[S3]=1'b1;
                                else next[S4]=1'b1;
                               end
              state[S4] : if (jmp) next[S3]=1'b1;
                                else next[S5]=1'b1;
              state[S5] : if (jmp) next[S3]=1'b1;
                                 else next[S6]=1'b1;
              state[S6] : if (jmp) next[S3]=1'b1;
                                 else next[S7]=1'b1;
              state[S7] : if (jmp) next[S3]=1'b1;
                                 else next[S8]=1'b1;
              state[S8] : if (jmp) next[S3]=1'b1;
                                else next[S9]=1'b1;
              state[S9] : if (jmp) next[S3]=1'b1;
                                else next[S0]=1'b1;
          endcase
    end
endmodule

 

个人对索引和非索引写法的理解:

  • 非索引:第一个always使用时序逻辑控制状态变化;第二个always使用组合逻辑由当前状态值来控制状态转移的条件,即在什么情况下状态发生转移。
  • 索引:整体结构与索引写法相同,不同之处在第二模块中使用case(1'b1)语句用状态变量的有效位的值来控制状态变化。(onehot每个状态仅有一位为1)

以上代码均采用两段式写法(two-always-blocks)。当需要寄存输出时,可将第二个always模块中的输出提出,单独使用一个always模块来操作,此时为三段式写法。

  1. FPGA是触发器密集型的,一个 LE由一个 LUT+一个DFF(典型的)组成,用了一个 LUT这个 LE也就算用完了;而在大状态机条件下,binary编码会导致大的译码逻辑,进而使译码逻辑增大(因为一个状态需要多位表示),因此还不如用 one-hot划算。对于 ASIC则不同,它的基本单元是由与门、非门、或门、DFF等电路,一个 DFF占的面积比与非门等大,因此,用 binary编码在面积上会更划算。
  2. index和非 index的 one-hot编码无非是希望让综合工具更好地识别并进行优化,对于一个较好的综合工具来说,这两者是等价的,综合出来的效果也是一样的,因此,这两者的区别主要是哪一种能让综合工具更好地识别,就我个人认识而言,index编码反应了 one-hot的本质(非 index编码在表面上看有多位参与了译码,这不是 one-hot的本质),可以降低对综合器的依靠。
  3. 针对one-hot可能会出现跑飞的情况,可以在状态机后面添加xnor门来控制,确保每个状态仅有一位为1时为有效状态。

 

参考资料:

foreveryoung 《状态机设计 by foreveryoung》http://wenku.baidu.com/view/d80353fbaef8941ea76e0502.html

《Safe and Efficient One-Hot State Machine》 http://www.klabs.org/mapld05/presento/179_zheng_p.ppt

Steve Golson《State machine design techniques for Verilog and VHDL》

Clifford E. Cummings 《The Fundamentals of Efficient Synthesizable Finite State Machine Design using NC-Verilog and BuildGates》 http://www.sunburst-design.com/papers/