Posts Tagged with "Design"

既に発行済みのブログであっても適宜修正・追加することがあります。
We may make changes and additions to blogs already published.

BSVの問題点? (2)

posted by sakurai on May 27, 2024 #805

Uartをテストベンチに組み込み動作しました。次にFIFO付Uartに改造しようとしたところ、FIFOを接続すると最初に0xAAという未定義データが受信FIFOに入ることがわかりました。

そこでverilogコードを出力し波形観測したところ、確かにリセット直後に0xAAという未定義データがUartから出力され受信FIFOに入力されています。図805.1のようにリセット直後にRDY_readがアサートされていることが判明しました。

図%%.1
図805.1 verilogシミュレーション波形

UartとFIFOを接続しているverilogコードを確認すると、uart$RDY_readはreadメソッドを呼ぶとアサートされ、それによりENQされることが判明しました。

assign rfifo$ENQ = uart$RDY_read && rfifo$FULL_N ;

最初のFIFO無しの場合に動作していたのは、ステートマシンの値がデコードされていたのでリセット直後の値は無視されていたからです。一方FIFOを接続するとリセット直後からの未定義データもFIFOに入るため、エラーが顕在化したわけです。その理由は、以下のように常にuartをreadしてenqしているためです。

/* receiver */
rule forever_rfeceiver_inside;
   let rdata <- uart.read;
   rfifo.enq(rdata);
endrule

リセット直後にRDY_readが誤って出ているのではないかと言う推測をしました。ここで、readメソッドは以下のようになっており、getfsmという受信fsmの完了信号であるgetfsm.doneによりreadを開始する論理となっています(下記)。

Uart.bsv(変更前):

   method ActionValue#(Bit#(8)) read if (getfsm.done);
      getfsmDone <= False;
      return idata;
   endmethod

getfsm.doneは直接観測できないものの、これがRDY_readとなっているだろうと推測し、getfsm.doneの代わりに相当するgetfsmDone信号に入れ替えてみます(下記)。getfsmDoneを作成しているgetfsmの部分も含めて示します。

Uart.bsv:(変更後)

   Stmt getseq = seq
      await(isdata == 1'h0);
      repeat (8) action
         idata <= {isdata, (idata >> 1)[6:0]};
      endaction
      getfsmDone <= True;
   endseq;
   FSM getfsm <- mkFSM(getseq);

   method ActionValue#(Bit#(8)) read if (getfsmDone);
      getfsmDone <= False;
      return idata;
   endmethod

この修正によりリセット直後のRDY_readは出力されなくなり、FIFOを接続しても正しく動作しました。

まとめるとRDY_readがおかしいというより、初期状態でgetfsm.doneがTrueになる点がおかしいと思われます。

本件についてフォーラムに問い合わせたところ、「mkFSMのdoneメソッドは、startのRDYと等価である。startはリセット後にレディになるので、doneメソッドも trueになる。startが呼び出された後にのみTrueとなる条件が必要な場合は、自分で実装する必要がある。」、つまり初期状態でgetfsm.doneがTrueなのは仕様とのことでした。


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


ページ: