Posts Issued on March 20, 2025

Pongと強化学習 (89)

posted by sakurai on March 20, 2025 #962

BSVにより、DumpFSMを改造します。従来のDumpDSMの仕様は、

  • SW等の外部指示により、GameFSMにウエイト要求を出す
  • GameFSMはSyncWait時にウエイト信号(停止中信号)を出力する
  • DumpFSMは停止中信号を確認し、SELをTrueとする
  • VRAMの内容をUARTで出力する
  • 完了したらSELとウエイト要求をFalseにする

という動作でした。今回改造するポイントは外部指示ではなく、強化学習ソフトウエアの指示により画面ダンプを実施する点です。そのために従来送信部のみであったUARTを受信部も作成します。

  • SW等の外部指示により、GameモードがFalseになる
  • シリアルデータがSTXを指示したらGameFSMにwait要求を出す
  • GameFSMはSyncWait時にウエイト信号(停止中信号)を出力する
  • DumpFSMは停止中信号を確認し、SELをTrueとする
  • SELがTrueの間は60Hz信号を遮断する。これによりGameFSMが進むことは無い
  • VRAMの内容をUARTで出力する
  • 完了したらSELとウエイト要求をFalseにする。
  • GameモードがTrueになったら60Hz信号を再開する。

図962.1に構造図を示します。DumpFSMモジュールには送信と受信のUARTを配置し、それをテストするテストベンチ内にも同じUARTを対向して配置します。

図%%.1
図962.1 ブロック図

DumpFSM.bsv

    import StmtFSM::*;
    import Uart::*;
    import Connectable::*;
    
    typedef Bit#(16) Addr;
    typedef Bit#(4) Data;
    typedef Bit#(8) Byte;
    
    `define STX 8'h02
    
    interface DumpFSM_ifc;
       (* prefix="" *)
       method Action datam(Data newdata); // input
       (* prefix="" *)
       method Action cwaitm(Bool newcwait); // input
       method Bool sreqm(); // output
       method Addr addrm(); // output
       method Bool selm(); // output
       method Bit#(1) sout(); // serial output
       (* prefix="" *)
       method Action sin(Bit#(1) nidata); // serial input
       (* prefix="" *)
       method Action c60Hz(Bool newtic); // input
       method Bool ticfunction(); // output
       (* prefix="" *)
       method Action mode(Bool newgame); // input
    endinterface
    
    (* synthesize, always_ready="sreqm, addrm, selm, sout, ticfunction",
                   always_enabled="datam, cwaitm, sin, c60Hz, mode" *)
    module mkDumpFSM(DumpFSM_ifc);
    
       Reg#(Addr) addr <- mkReg(0);
       Reg#(Data) data <- mkRegU;
       Reg#(Byte) byteData <- mkRegU;
       Reg#(UInt#(9)) x <- mkRegU;
       Reg#(UInt#(9)) y <- mkRegU;
       Reg#(UInt#(4)) i <- mkRegU;
       Reg#(Bool) cwait <- mkReg(False);
       Reg#(Bool) sreq <- mkReg(False);
       Reg#(Bool) sel <- mkReg(False);
       Reg#(Bool) tic <- mkReg(False);
       Reg#(Bool) game <- mkReg(True);
       
       Uart_ifc uart <- mkUart();
    
       function Stmt nibbleOut(Data nibble);
          return (seq
             byteData <= extend(nibble) + ((nibble >= 10) ? (-10 + 8'h61) : 8'h30);
             uart.write(byteData);
             $write("%c", byteData);
          endseq);
       endfunction: nibbleOut
    
       Stmt test = seq
           while (True) seq
               await(!game); // Gameでない場合、トリガが来たら吸出し
               await(uart.read() == `STX);
               sreq <= True; // 描画マスタ停止要求を出す
               await(cwait); // 描画マスタ停止したら、
               sel <= True; // ダンプ開始
               for (i <= 1; i <= 4; i <= i + 1) seq
                   uart.write(8'h38); // start of header '8888' -> remove
                   $display("8");
               endseq
               addr <= 0;
               for (y <= 0; y <= 2/* 255 */; y <= y + 1) seq
                   for (x <= 0; x <= 255; x <= x + 1) seq
    //                 $display("%3d, %3d", x, y);
    //                 $display(" %04x ", addr);
                       action
                          addr <= addr + 1;
                       endaction
                       nibbleOut(data);
                   endseq // for x
                   uart.write(8'h0a); // LF
               endseq // for y
               await (uart.done()); // 送信終了待ち
               action
                   sreq <= False; // 要求OFF
                   sel <= False; // 選択OFF
               endaction
          endseq // while
       endseq; // Stmt
    
       mkAutoFSM(test);
    
       method Bool sreqm(); // output
          return sreq;
       endmethod
       method Addr addrm(); // output
          return addr;
       endmethod
       method Action datam(Data newdata); // input
          data <= newdata;
       endmethod
       method Action cwaitm(Bool newcwait); // input
          cwait <= newcwait;
       endmethod
       method Bool selm(); // output
          return sel;
       endmethod
       method Bit#(1) sout(); // serial output
          return uart.sout();
       endmethod
       method Action sin(Bit#(1) nidata); // serial input
          action
             uart.sin(nidata);
          endaction
       endmethod
       method Action c60Hz(Bool newtic); // input
          if (game && !sel) action
             tic <= newtic;
          endaction
       endmethod
       method Bool ticfunction; // output
          return tic;
       endmethod
       method Action mode(Bool newgame); // input
          game <= newgame;
       endmethod
    
    endmodule

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