Posts Issued on April 13, 2020

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

posted by sakurai on April 13, 2020 #238

サウンドFSMの作成(3)

FORMAT機能、DATA機能からコールされるREADCOUNT共通シーケンス及び、そこからコールされるREADMEM共通シーケンスを解説します。

   //  input:  romaddr
   //  output: (romaddr,...,romaddr+3) => dcount;
   //          romaddr + 4 => romaddr;
   //
   rule ruleREADCOUNT (state.func == READCOUNT);

      rule ruleS0 (state.step == S0);
         state.step <= S1;
         ret2 <= ret; // push to stack
         i <= 3;
         workd <= 0;
      endrule

      rule ruleS1 (state.step == S1);
         state <= State_t {cat:state.cat, func:READMEM, step:S0};
         ret <= State_t {cat:state.cat, func:READCOUNT, step:S2};
         worka <= romaddr + i;
      endrule

      rule ruleS2 (state.step == S2);
         if (i == 0) begin
            state <= ret2;
            dcount <= workd<<8 | extend(romdata);
            romaddr <= romaddr + 4;
         end else begin
            state.step <= S1;
            workd <= workd<<8 | extend(romdata);
            i <= i - 1;
         end
      endrule

  endrule // READCOUNT

図示すると、図238.1のようなステート遷移となり、リトルエンディアンで格納されている4バイトの数値を1バイトずつ4回取り出し、dcountにまとめる機能を持ちます。

図%%.1
図238.1 READCOUNT共通シーケンスステート遷移図

次にREADMEMはROMから1バイト読み出す共通シーケンスです。当初はwireを用いても階層の上り下りでレイテンシがかかり、7サイクルとなりましたが、後述のmkConnectionを用いたことにより、RTLと同様の3サイクルの設計とすることができました。

上記のREADCOUNTから呼ばれる際はサイクル数は無関係ですが、サウンド再生中は正しいスループットで読み出す必要があるため、過去記事にもあるように、コール元が1サイクルとコール先(READMEM)が3サイクルの4サイクルで1バイトを読み出す前提で、FSMのクロック周波数=176.4KHzを決めています。

   // READ MEM
   //  input:  worka
   //  output: romdata;
   //
   rule ruleREADMEM (state.func == READMEM);

      rule ruleS0 (state.step == S0);
         addr <= worka;
         state.step <= S1;
      endrule

      rule ruleS1 (state.step == S1); // ROM address phase
         state.step <= S2;
      endrule

      rule ruleS2 (state.step == S2); // ROM data phase
         data <= romdata;
         state <= ret;
      endrule

    endrule // READMEM

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