FSMのエンコーディング

[] [] []


ステートマシンFinite State Machine(FSM)は、特に禁止しないかぎり論理合成でステートレジスタ値の割り当て(エンコーディング)が変更されてしまう

制約

QuartusII

XST

Vivado

FSMのエンコーディング

syn_encoding="value"

value={default|sequential|one-hot

|gray|user}

fsm_encoding="value"

value={auto|sequential|one-hot

|gray|user}

fsm_encoding="value"

value={auto|sequential|one-hot

|gray|johnson}

ユーザ定義どおりにするには

dont_touch="true"にする

ここで

(1) sequential 'd0→'d1→'d2→'d3→'d0→... (カウントアップ)

(2) one-hot 'b0001→''b0010→'b0100→'b1000→'b0001→... (常に1ビットだけが1

(3) gray     'b000→''b001→'b011→'b010→'b110→'b111→'b101→'b100→'b000→... (常に1ビットづつ変化)

ユーザ定義(user)の場合はRTLに書いたとおりの割り当てを保持する。おまかせ(auto,default)の場合は状態数によって選択され、数個以下ならばsequential、数10個以下ならばone-hot、それ以上はgrayとなるのが一般的のようである。

このようにエンコーディングが変更されると不都合なのは、非同期リセット解除後すぐ遷移するような設計でone-hotになった場合である

例えば図のようなone-hotの回路は、'b100→'b010→・・・と遷移するが、rstのスキューにより過渡値の'b000または'b110に遷移する可能性がある。特に'b000になった場合はFSMがフリーズしてしまう。

本来の設計としては、非同期リセット後に何か入力を待って遷移するようにするか、非同期リセットを同期リセットに変えるのがよいが、どうしてもこのようにするならば、非同期リセットとクロックが同時になってもよいようなエンコーディングにしてreg変数に合成制約 (user)を指定する。

// FSM

(* syn_encoding="user" *) reg[2:0] state_reg;

localparam IDLE=3'b000;

localparam SA1 =3'b100;

localparam SA2 =3'b101;

localparam SA2 =3'b010;

always @(posedge clk or posedge rst)

    begin

    if(rst)

        state_reg <= IDLE;

    else

        case(state_reg)

        IDLE: state_reg <= SA1;         // 非同期リセット解除後すぐ遷移する

        SA1: if(start_a) state_reg <= SA2;

        SA2: state_reg <= SA3;

        SA3: if(done_a) state_reg <= IDLE;

        default: state_reg <= 3'bx;

        endcase

    end

◇◇

もうひとつンコーディングが変更されると不都合なのは、state_regのビットをそのままFF出力の制御信号として使っている場合である

上記のstate_regの割り当てのとき、

if((state_reg==SA1)|(state_reg==SA2))

というロジックを、非同期転送やハザードフリーの出力として使うためFF出力であることを意図して

if(state_reg[2])  // state_regのビットをそのままFF出力の制御信号として使っている

と記述することもできるが、もしエンコーディングがone-hotにされてしまうと、信号state_reg[2]ハザードの出る組合せ回路になってしまい不都合である。したがってこの場合もreg変数に合成制約 (user)を指定する必要がある。


[] [] []