Vengineerの妄想(準備期間)

人生は短いけど、長いです。人生を楽しみましょう!

SimpleBus (その9)

Verification Engineerの戯言

昨日の続きで、SimpleTLTarget1クラスget_direct_mem_ptrメソッドです。SimpleTLTarget1クラスは、DMI(Direct Memory Interface)
サポートしているので、このget_direct_mem_ptrメソッドでその設定をやっています。
  bool get_direct_mem_ptr(const sc_dt::uint64& address,
                          dmi_mode_type& dmi_mode,
                          tlm::tlm_dmi&  dmi_data)
  {
      if (m_invalidate) m_invalidate_dmi_event.notify(m_invalidate_dmi_time);
    if (address < 400) {
      dmi_mode.type = tlm::tlm_dmi_mode::READ_WRITE;
      
      dmi_data.dmi_start_address = 0x0;
      dmi_data.dmi_end_address = 399;
      dmi_data.dmi_ptr = mMem;
      dmi_data.read_latency = sc_core::sc_time(100, sc_core::SC_NS);
      dmi_data.write_latency = sc_core::sc_time(10, sc_core::SC_NS);
      dmi_data.endianness =
        (tlm::hostHasLittleEndianness() ? tlm::TLM_LITTLE_ENDIAN :
                                          tlm::TLM_BIG_ENDIAN);
      return true;

    } else {
      // should not happen
      dmi_data.dmi_start_address = address;
      dmi_data.dmi_end_address = address;
      return false;
    }
  }
SimpleTLTarget1クラスには、400バイトの内部メモリmMemを持っています。
そこで、addressが400未満である場合は、引数dmi_dataの各値に設定し、trueを戻り値として返します。
addressが400以上である場合は、dmi_data.dma_start_addressとdmi_data.dma_end_addressにaddressを
設定し、falseを戻り値として返します。

m_invalidateはコンストラクタへの引数として指定しますが、trueのときはget_direct_mem_ptrメソッド
呼び出されたとき、m_invalidate_dmi_event.notify(m_invalidate_dmi_time)を実行し、m_invalidate_dmi_eventイベントを発生します。
m_invalidate_dmi_eventイベントが発生すると、次のようなinvalidate_dmi_methodメソッドが呼ばれます。
  void invalidate_dmi_method()
  {
      sc_dt::uint64 start_address = 0x0;
      sc_dt::uint64 end_address = 399;
      socket->invalidate_direct_mem_ptr(start_address, end_address);
  }
イニシエータ側へのソケットに対して、invalidate_direct_mem_ptrメソッドを実行し、
DMIでイニシエータに渡したデータポインタを無効化しています。

SimpleLTTarget2クラスは、tlm::tlm_fw_nb_transport_ifクラスを継承していないので、
SimpleLTTraget1クラスでの3つのメソッドに対応するものをマクロで設定します。
ただし、SimpleLTTartget2クラスでは、2つのマクロ(REGISTER_NBTRANSPORTREGISTER_DMI)を使って、
socketに対してメソッドを設定しています。
  SC_HAS_PROCESS(SimpleLTTarget2);
  SimpleLTTarget2(sc_core::sc_module_name name) :
    sc_core::sc_module(name),
    socket("socket")
  {
    // register nb_transport method
    REGISTER_NBTRANSPORT(socket, myNBTransport);
    REGISTER_DMI(socket, myGetDMIPtr);

    // TODO: we don't register the transport_dbg callback here, so we
    // can test if something bad happens
    // REGISTER_DEBUGTRANSPORT(socket, transport_dbg);
  }
myNBTransportメソッドは、nb_transportメソッドに、myGetDMIPtrメソッドは、get_direct_mem_ptrメソッドに対応します。

なお、SimpleTLTarget1クラスにあるinvalidate_dmi_methodメソッドはありません。