Posts Issued on April 20, 2020

BSVの設計トライアル (10)

posted by sakurai on April 20, 2020 #243

スタック操作のBSV記述

共通シーケンスをコールする場合、これまで見てきたように、スタック操作をする必要がありますが、煩雑なのでこれを隠蔽することを考えます。と言ってもソフトウェアでやるように、push, pop, call, return等の概念を使います。また、これまでハードウェアという意識から「共通シーケンス」と称してきた概念を、ソフトウエアに合わせてサブルーチンと呼びます。

対象となる検証用FSMのステート定義を示します。例として4レベルのFSMを考えます。state変数は構造体で定義しています。

typedef enum { L1, L2, L3, L4 } Function_t deriving(Bits,Eq);
typedef enum { S0, S1, S2, S3, S4 } Step_t deriving(Bits,Eq);
    
typedef struct {
     Function_t func;
     Step_t step;
} State_t deriving(Bits,Eq);

rsはリターンスタック配列で、BSVでの実装例として、今回はRegFileで構成します。spはスタックポインタで配列インデックスです。Verilogにおける配列のdata変数への読み出し

    data <= rs[sp]

は、この実装では、

    data <=rs.sub(sp)

となり、逆にVerilogにおける配列へのdataの書き込み

    rs[sp] <= data

は、この実装では

    rs.upd(sp, data)

となります。

マクロ命令定義

これらを用いて作成したマクロ命令の定義文のコードです。

`define pushRet           rs.upd(sp, ret); sp <= sp + 1
`define popRet            state <= rs.sub(sp-1); sp <= sp - 1
`define call(SUB)         `_saveNext; state <= State_t {func:SUB, step:S0}
`define _saveNext         ret <= State_t {func:state.func, step:nextStep()}
`define return            state <= ret
`define next              state.step <= nextStep()

その説明を表243.1に示します。

表243.1 マクロ命令の定義
マクロ命令名 説明
pushRet 非リーフルーチン中で、他のルーチンを呼ぶ際に破壊されるretをスタックにプッシュするマクロ命令で、必ず先頭でpushするものとします。
popRet 非リーフ内で呼び出し元に戻るためのマクロ命令で、retを回復せずに、スタック中の戻りステートに直接戻るマクロ命令です。
call(SUB) サブルーチンコールです。次のステートをretに入れ、コール先にジャンプします。
_saveNext callに使用されており、次のステートをretに入れる内部マクロ命令です。後述のnextStep()関数を使用しています。ユーザが陽に使う必要は無いため、アンダースコアを付けています。
return リーフ内で呼び出し元に戻るためのマクロ命令です。
next 次のステートに進めるためのマクロ命令です。後述のnextStep()関数を使用しています。


左矢前のブログ 次のブログ右矢