Posts Issued on April 22, 2020

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

posted by sakurai on April 22, 2020 #245

マクロ命令の使用

過去記事のCalee Savedコールリターンを前稿で作成したマクロ命令を使用して書き直すと、図245.1のようになります。青字がマクロ命令です。Caller Savedでは入らなかった余分なpushRetがルーチン先頭に入っています。あるいは次のcallとまとめてしまい、非リーフからのcallを別に設ければこれは見かけ上無くなります。こうすれば、リーフと非リーフで、コールもリターンも別になるのでかえってすっきりするかもしれません。

図%%.1
図245.1 マクロ命令を使用したサブルーチン呼び出し

検証用FSMソースコード

検証用FSMのBSVの全ソースコードを示します(既紹介部分は除く)。

import RegFile::*;

(* synthesize, always_ready, always_enabled *)
module mkTestFSM();

   Reg#(State_t) state <- mkReg(State_t{func:L1, step:S0}),
                 ret <- mkRegU;

   // L1
   rule rule_L1 (state.func == L1);
      rule rule_S0 (state.step == S0);
         $display("L1 S%d", state.step);
         `next;
      endrule // S0
      rule rule_S1 (state.step == S1);
         $display("L1 S%d", state.step);
         `call(L2);
      endrule // S1
      rule rule_S2 (state.step == S2);
         $display("L1 S%d", state.step);
      endrule // S2
   endrule // L1

   // L2
   rule rule_L2 (state.func == L2);
      rule rule_S0 (state.step == S0);
         $display("  L2 S%d", state.step);
         `pushRet; // L2 is not a leaf routine
         `next;
      endrule // S0
      rule rule_S1 (state.step == S1);
         $display("  L2 S%d", state.step);
         `next;
      endrule // S1
      rule rule_S2 (state.step == S2);
         $display("  L2 S%d", state.step);
         `call(L3);
      endrule // S2
      rule rule_S3 (state.step == S3);
         $display("  L2 S%d", state.step);
         `next;
      endrule // S3
      rule rule_S4 (state.step == S4);
         $display("  L2 S%d", state.step);
         `popRet;
      endrule // S4
   endrule // L2

   // L3
   rule rule_L3 (state.func == L3);
      rule rule_S0 (state.step == S0);
         $display("    L3 S%d", state.step);
         `pushRet; // L3 is not a leaf routine
         `next;
      endrule // S0
      rule rule_S1 (state.step == S1);
         $display("    L3 S%d", state.step);
         `call(L4);
      endrule // S1
      rule rule_S2 (state.step == S2);
         $display("    L3 S%d", state.step);
         `popRet;
      endrule // S2
   endrule // L3

   // L4 (Leaf)
   rule rule_L4 (state.func == L4);
      rule rule_S0 (state.step == S0);
         $display("      L4 S%d", state.step);
         `next;
      endrule // S0
      rule rule_S1 (state.step == S1);
         $display("      L4 S%d", state.step);
         `return;
      endrule // S1
   endrule // L4

endmodule: mkTestFSM

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