Verification Engineerの戯言
SimpleBusに接続するイニシエータとしては、
unit_test/tlm/common/include/modelsディレクトリに次の6つが用意されています。
SimpleATInitiatorXは、Approximately-timed coding styleのモデルです。
_DMIで終わるものは、DMI(Direct Memory Interface)をサポートするモデルです。
unit_test/tlm/common/include/modelsディレクトリに次の6つが用意されています。
SimpleLTInitiator1 SimpleLTInitiator1_DMI SimpleLTInitiator2 SimpleLTInitiator2_DMI SimpleLTInitiator3 SimpleLTInitiator3_DMI SimpleATInitiator1 SimpleATInitiator2SimpleLTInitiatorXは、Loosely-timed coding styleのモデルで、
SimpleATInitiatorXは、Approximately-timed coding styleのモデルです。
_DMIで終わるものは、DMI(Direct Memory Interface)をサポートするモデルです。
_DMIのありなしは、DMIをサポートするかどうかの違いなので、まずSimpleLTInitiator1_DMIを見ていきましょう。
SimpleLTInitiator_DMIクラスは、tlm::tlm_bw_nb_transport_ifクラスを継承しますので、
必要な次の2つのメソッドです。
上記のようなコーディングスタイルになります。引数phaseによってアクションが変わります。
受け取ることができるphaseは、END_REQとBEGIN_RESPです。
BEGIN_REQとEND_RESPの場合はエラーになり(assert(0))、シミュレータ(exit(1))が終了します。
phaseがEND_REQのときは、ただ単にtlm::TLM_ACCEPTEDを返すだけです。
一方、phaseがBEGIN_RESPのときは、ターゲットモデルからレスポンスフェーズが開始されたことを
示すので、引数tを使って、mEndEventイベントにnotifyします。その後、tlm::TLM_COMPLETEDを返します。
mEndEventのイベント待ちは、runメソッドで行われています。
必要な次の2つのメソッドです。
tlm::tlm_sync_enum nb_transport( tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& t); void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range);まずは、nb_transportメソッドです。
sync_enum_type nb_transport(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) { switch (phase) { case tlm::END_REQ: // Request phase ended return tlm::TLM_ACCEPTED; case tlm::BEGIN_RESP: assert(t == sc_core::SC_ZERO_TIME); // FIXME: can t != 0? mEndEvent.notify(t); // Not needed to update the phase if true is returned return tlm::TLM_COMPLETED; case tlm::BEGIN_REQ: // fall-through case tlm::END_RESP: // fall-through default: // A target should never call nb_transport with these phases assert(0); exit(1); return tlm::TLM_REJECTED; }; }Loosely-timed coding styleのイニシエータモデルのnb_transportメソッドは、
上記のようなコーディングスタイルになります。引数phaseによってアクションが変わります。
受け取ることができるphaseは、END_REQとBEGIN_RESPです。
BEGIN_REQとEND_RESPの場合はエラーになり(assert(0))、シミュレータ(exit(1))が終了します。
phaseがEND_REQのときは、ただ単にtlm::TLM_ACCEPTEDを返すだけです。
一方、phaseがBEGIN_RESPのときは、ターゲットモデルからレスポンスフェーズが開始されたことを
示すので、引数tを使って、mEndEventイベントにnotifyします。その後、tlm::TLM_COMPLETEDを返します。
mEndEventのイベント待ちは、runメソッドで行われています。
次は、invalidate_direct_mem_ptrメソッドです。
アドレス内であれば、データポインタを無効化しています。アドレス外のときはメッセージを表示します。
実際に無効化しているのは、invalidateメソッドです。
void invalidate(dmi_type& dmiData) { dmiData.dmi_start_address = 1; dmiData.dmi_end_address = 0; } // Invalidate DMI pointer(s) void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range) { // do the invalidation if there is an address range overlap if (start_range <= mDMIData.dmi_end_address && end_range >= mDMIData.dmi_start_address) { std::cout << name() << ": got DMI pointer invalidation" << " @ " << sc_core::sc_time_stamp() << std::endl; invalidate(mDMIData); } else { std::cout << name() << ": ignored DMI invalidation for addresses " << std::hex << start_range << ", " << end_range << std::dec << " @ " << sc_core::sc_time_stamp() << std::endl; } }引数(start_rangeとend_range)の間のアドレスとmDMIDataのアドレスレンジとを比較し、
アドレス内であれば、データポインタを無効化しています。アドレス外のときはメッセージを表示します。
実際に無効化しているのは、invalidateメソッドです。
次回は、runメソッドについて
P.S
昨日、6000訪問者を達成しました。ありがとうございました。
昨日、6000訪問者を達成しました。ありがとうございました。