📄 tlm2_base_protocol_checker.h
字号:
tlm::tlm_generic_payload* m_request_in_progress;
tlm::tlm_generic_payload* m_response_in_progress;
std::ostringstream txt;
};
// ******************** MEMBER FUNCTION DEFINITIONS ********************
#define BOILERPLATE \
template <unsigned int BUSWIDTH> \
void tlm2_base_protocol_checker<BUSWIDTH>::
BOILERPLATE
b_transport_pre_checks(
tlm::tlm_generic_payload& trans, sc_core::sc_time& delay)
{
++ m_map[&trans].b_call;
if ( trans.has_mm() && trans.get_ref_count() == 0)
{
txt << "Transaction passed to b_transport with memory manager and reference count of 0";
tlm2error(trans, "6.5 s)");
}
check_initial_state(trans, "b_transport");
#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
if (sc_core::sc_get_current_process_handle().proc_kind() == sc_core::SC_METHOD_PROC_)
{
txt << "b_transport called from method process";
tlm2error(trans, "4.1.1.4 b)");
}
#endif
if (m_map[&trans].ph > 0 && m_map[&trans].ph < 4)
{
txt << "b_transport called during a sequence of nb_transport calls";
tlm2error(trans, "7.2.5 k)");
}
}
BOILERPLATE
b_transport_post_checks(
tlm::tlm_generic_payload& trans, sc_core::sc_time& delay)
{
check_response_path(trans, "b_transport");
check_trans_not_modified(trans, "b_transport");
-- m_map[&trans].b_call;
}
BOILERPLATE
nb_transport_fw_pre_checks(
tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay)
{
if ( !trans.has_mm() )
{
txt << "Transaction passed to nb_transport_fw with no memory manager set";
tlm2error(trans, "6.5 h)");
}
if ( trans.get_ref_count() == 0)
{
txt << "Transaction passed to nb_transport_fw with reference count of 0";
tlm2error(trans, "6.5 s)");
}
switch (phase)
{
case tlm::BEGIN_REQ:
check_initial_state(trans, "nb_transport_fw");
if (m_map[&trans].ph > 0 && m_map[&trans].ph < 4) // END_RESP -> BEGIN_REQ is legal
{
txt << "Phase " << phase << " sent out-of-sequence on forward path, detected in nb_transport_fw";
tlm2error(trans, "7.2.3 i)");
}
if (m_request_in_progress)
{
txt << "Transaction violates BEGIN_REQ exclusion rule, detected in nb_transport_fw";
tlm2error(trans, "7.2.4 b)");
}
m_request_in_progress = &trans;
if (m_map[&trans].b_call)
{
txt << "nb_transport_fw called during a b_transport call";
tlm2error(trans, "7.2.5 k)");
}
break;
case tlm::END_REQ:
case tlm::BEGIN_RESP:
case tlm::UNINITIALIZED_PHASE:
txt << "Phase " << phase << " sent on forward path, detected in nb_transport_fw";
tlm2error(trans, "7.2.3 d)");
break;
case tlm::END_RESP:
if (m_map[&trans].ph != tlm::BEGIN_RESP)
{
txt << "Phase " << phase << " sent out-of-sequence on forward path, detected in nb_transport_fw";
tlm2error(trans, "7.2.3 i)");
}
m_response_in_progress = 0;
break;
}
if (phase < 5) // Ignore extended phases
m_map[&trans].ph = phase;
if (sc_core::sc_time_stamp() + delay < m_map[&trans].time)
{
txt << "nb_transport_fw called with decreasing timing annotation:"
<< " delay = " << delay
<< ", sc_time_stamp() + delay from previous call = " << m_map[&trans].time;
tlm2error(trans, "7.2.5 e)");
}
m_map[&trans].time = sc_core::sc_time_stamp() + delay;
}
BOILERPLATE
nb_transport_fw_post_checks(
tlm::tlm_generic_payload& trans, tlm::tlm_phase& start_phase, tlm::tlm_phase& phase,
sc_core::sc_time& delay, tlm::tlm_sync_enum status)
{
if (status == tlm::TLM_UPDATED)
{
nb_transport_response_checks(
trans, phase, delay, "(forward) return", "Return from nb_transport_fw", "nb_transport_fw");
}
else if (status == tlm::TLM_COMPLETED)
{
if (start_phase == tlm::BEGIN_REQ)
check_response_path(trans, "nb_transport_fw");
m_request_in_progress = 0;
m_map[&trans].ph = tlm::UNINITIALIZED_PHASE;
}
// Transaction object should not be re-allocated, even during the END_RESP phase
//if (phase != tlm::END_RESP)
{
std::ostringstream txt;
txt << "nb_transport_fw, phase = " << phase;
check_trans_not_modified(trans, txt.str().c_str());
}
}
BOILERPLATE
nb_transport_bw_pre_checks(
tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay)
{
if ( !trans.has_mm() )
{
txt << "Transaction passed to nb_transport_bw with no memory manager set";
tlm2error(trans, "6.5 h)");
}
if ( trans.get_ref_count() == 0)
{
txt << "Transaction passed to nb_transport_bw with reference count of 0";
tlm2error(trans, "6.5 s)");
}
nb_transport_response_checks(
trans, phase, delay, "backward", "nb_transport_bw called", "nb_transport_bw");
}
BOILERPLATE
nb_transport_bw_post_checks(
tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay,
tlm::tlm_sync_enum status)
{
if (status == tlm::TLM_UPDATED)
{
switch (phase)
{
case tlm::BEGIN_REQ:
txt << "Phase " << phase << " sent out-of-sequence on (backward) return path, detected in nb_transport_bw";
tlm2error(trans, "7.2.3 i)");
break;
case tlm::END_REQ:
case tlm::BEGIN_RESP:
case tlm::UNINITIALIZED_PHASE:
txt << "Phase " << phase << " sent on (backward) return path, detected in nb_transport_bw";
tlm2error(trans, "7.2.3 d)");
break;
case tlm::END_RESP:
if (m_map[&trans].ph != tlm::BEGIN_RESP)
{
txt << "Phase " << phase << " sent out-of-sequence on (backward) return path, detected in nb_transport_bw";
tlm2error(trans, "7.2.3 i)");
}
m_response_in_progress = 0;
break;
}
if (phase < 5) // Ignore extended phases
m_map[&trans].ph = phase;
if (sc_core::sc_time_stamp() + delay < m_map[&trans].time)
{
txt << "Return from nb_transport_bw with decreasing timing annotation:"
<< " delay = " << delay
<< ", sc_time_stamp() + delay from previous call = " << m_map[&trans].time;
tlm2error(trans, "7.2.5 e)");
}
m_map[&trans].time = sc_core::sc_time_stamp() + delay;
}
else if (status == tlm::TLM_COMPLETED)
{
m_response_in_progress = 0;
m_map[&trans].ph = tlm::UNINITIALIZED_PHASE;
}
// Transaction object should not be re-allocated, even during the END_RESP phase
//if (phase != tlm::END_RESP)
{
std::ostringstream txt;
txt << "nb_transport_bw, phase = " << phase;
check_trans_not_modified(trans, txt.str().c_str());
}
}
BOILERPLATE
nb_transport_response_checks(
tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay,
const char* txt2, const char* txt3, const char* txt4)
{
if (trans.is_response_ok())
if (shared_map[&trans].response_in_progress && !shared_map[&trans].ok_response)
{
txt << "Interconnect component sets response status attribute to TLM_OK_RESPONSE"
<< ", detected in " << txt4;
tlm2error(trans, "6.7)");
}
switch (phase)
{
case tlm::BEGIN_REQ:
case tlm::END_RESP:
case tlm::UNINITIALIZED_PHASE:
txt << "Phase " << phase << " sent on " << txt2 << " path"
<< ", detected in " << txt4;
tlm2error(trans, "7.2.3 d)");
break;
case tlm::END_REQ:
if (m_map[&trans].ph != tlm::BEGIN_REQ)
{
txt << "Phase " << phase << " sent out-of-sequence on " << txt2 << " path"
<< ", detected in " << txt4;
tlm2error(trans, "7.2.3 i)");
}
m_request_in_progress = 0;
break;
case tlm::BEGIN_RESP:
if (m_map[&trans].ph != tlm::BEGIN_REQ && m_map[&trans].ph != tlm::END_REQ)
{
txt << "Phase " << phase << " sent out-of-sequence on " << txt2 << " path"
<< ", detected in " << txt4;
tlm2error(trans, "7.2.3 i)");
}
if (&trans == m_request_in_progress)
m_request_in_progress = 0;
if (m_response_in_progress)
{
txt << "Transaction violates BEGIN_RESP exclusion rule"
<< ", detected in " << txt4;
tlm2error(trans, "7.2.4 c)");
}
m_response_in_progress = &trans;
check_response_path(trans, txt4);
break;
}
if (phase < 5) // Ignore extended phases
m_map[&trans].ph = phase;
if (sc_core::sc_time_stamp() + delay < m_map[&trans].time)
{
txt << txt3 << " with decreasing timing annotation:"
<< " delay = " << delay
<< ", sc_time_stamp() + delay from previous call = " << m_map[&trans].time;
tlm2error(trans, "7.2.5 e)");
}
m_map[&trans].time = sc_core::sc_time_stamp() + delay;
}
BOILERPLATE
check_initial_state(
tlm::tlm_generic_payload& trans, const char* txt2 )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -