112027Sjungma@eit.uni-kl.de
212027Sjungma@eit.uni-kl.de// Filename: tlm2_base_protocol_checker.h
312027Sjungma@eit.uni-kl.de
412027Sjungma@eit.uni-kl.de//----------------------------------------------------------------------
512027Sjungma@eit.uni-kl.de//  Copyright (c) 2008-2013 by Doulos Ltd.
612027Sjungma@eit.uni-kl.de//
712027Sjungma@eit.uni-kl.de//  Licensed under the Apache License, Version 2.0 (the "License");
812027Sjungma@eit.uni-kl.de//  you may not use this file except in compliance with the License.
912027Sjungma@eit.uni-kl.de//  You may obtain a copy of the License at
1012027Sjungma@eit.uni-kl.de//
1112027Sjungma@eit.uni-kl.de//  http://www.apache.org/licenses/LICENSE-2.0
1212027Sjungma@eit.uni-kl.de//
1312027Sjungma@eit.uni-kl.de//  Unless required by applicable law or agreed to in writing, software
1412027Sjungma@eit.uni-kl.de//  distributed under the License is distributed on an "AS IS" BASIS,
1512027Sjungma@eit.uni-kl.de//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1612027Sjungma@eit.uni-kl.de//  See the License for the specific language governing permissions and
1712027Sjungma@eit.uni-kl.de//  limitations under the License.
1812027Sjungma@eit.uni-kl.de//----------------------------------------------------------------------
1912027Sjungma@eit.uni-kl.de
2012027Sjungma@eit.uni-kl.de// Author: John Aynsley, Doulos
2112027Sjungma@eit.uni-kl.de
2212027Sjungma@eit.uni-kl.de// Version  1, 11 July 2008
2312027Sjungma@eit.uni-kl.de// Version  2, 16 July 2008  Only generate ref_count > 1 warning from 1st checker of path
2412027Sjungma@eit.uni-kl.de// Version  3, 17 July 2008  Support compilation under SystemC 2.1.v1
2512027Sjungma@eit.uni-kl.de// Version  4, 12 Aug  2008  Add header #include <map>
2612027Sjungma@eit.uni-kl.de// Version  5, 08 Sep  2008  Fix bugs in message text
2712027Sjungma@eit.uni-kl.de// Version  6, 01 Aug  2010  Update messages to refer to OSCI TLM-2.0 LRM of July 2009
2812027Sjungma@eit.uni-kl.de// Version  7, 25 Oct  2011  Minor bug fix for certain compilers: replace u_char with uchar_t
2912027Sjungma@eit.uni-kl.de// Version  8, 02 Nov  2011  Support the endianness conversion functions by excluding the
3012027Sjungma@eit.uni-kl.de//                           tlm_endian_context extension from the protocol checks
3112027Sjungma@eit.uni-kl.de// Version  9, 17 Aug  2012  Fix LRM reference on line 805 (should be 8.2.11 a) [NOT YET RELEASED]
3212027Sjungma@eit.uni-kl.de// Version 10,  3 Jan  2013  Updated messages to refer to IEEE Std 1666-2011, the combined SystemC + TLM-2.0 LRM
3312027Sjungma@eit.uni-kl.de//                           Added checks related to the generic payload option attribute
3412027Sjungma@eit.uni-kl.de// Version 11, 14 Mar  2016  Fix minor bug - start_phase should be a copy, not a reference
3512027Sjungma@eit.uni-kl.de
3612027Sjungma@eit.uni-kl.de// TLM-2.0 Base Protocol Compliance Checker
3712027Sjungma@eit.uni-kl.de
3812027Sjungma@eit.uni-kl.de/*
3912027Sjungma@eit.uni-kl.deInstantiate this checker module in-line between initiator and target, initiator and interconnect,
4012027Sjungma@eit.uni-kl.deor interconnect and target by binding the target_socket and initiator_socket
4112027Sjungma@eit.uni-kl.deBinding two checkers either side of an interconnect component, or interleaving a series of
4212027Sjungma@eit.uni-kl.decheckers with interconnect components, will enable some deeper checks as against having just
4312027Sjungma@eit.uni-kl.dea single checker
4412027Sjungma@eit.uni-kl.de
4512027Sjungma@eit.uni-kl.deFor example
4612027Sjungma@eit.uni-kl.de
4712027Sjungma@eit.uni-kl.de  Initiator *initiator;
4812027Sjungma@eit.uni-kl.de  Bus       *bus;
4912027Sjungma@eit.uni-kl.de  Memory    *memory;
5012027Sjungma@eit.uni-kl.de  ...
5112027Sjungma@eit.uni-kl.de  initiator->socket.bind(bus->target_socket);
5212027Sjungma@eit.uni-kl.de  bus->initiator_socket.bind(memory->socket);
5312027Sjungma@eit.uni-kl.de
5412027Sjungma@eit.uni-kl.demight become
5512027Sjungma@eit.uni-kl.de
5612027Sjungma@eit.uni-kl.de  tlm_utils::tlm2_base_protocol_checker<32> *checker1;
5712027Sjungma@eit.uni-kl.de  tlm_utils::tlm2_base_protocol_checker<32> *checker2;
5812027Sjungma@eit.uni-kl.de  ...
5912027Sjungma@eit.uni-kl.de  initiator->socket.bind(checker1->target_socket);
6012027Sjungma@eit.uni-kl.de  checker1->initiator_socket.bind(bus->target_socket);
6112027Sjungma@eit.uni-kl.de  bus->initiator_socket.bind(checker2->target_socket);
6212027Sjungma@eit.uni-kl.de  checker2->initiator_socket.bind(memory->socket);
6312027Sjungma@eit.uni-kl.de
6412027Sjungma@eit.uni-kl.de
6512027Sjungma@eit.uni-kl.deGENERAL FEATURES OF THE BASE PROTOCOL CHECKER
6612027Sjungma@eit.uni-kl.de
6712027Sjungma@eit.uni-kl.deThe checks are relatively expensive, hence by default the number of checks is limited.
6812027Sjungma@eit.uni-kl.deA maximum number can be set explicitly by calling set_num_checks(max)
6912027Sjungma@eit.uni-kl.deChecking can be deactivated at any time by calling set_num_checks(0)
7012027Sjungma@eit.uni-kl.deAll checkers decrement a single global count, because having some checkers running and
7112027Sjungma@eit.uni-kl.deothers not can cause bogus violation reports
7212027Sjungma@eit.uni-kl.deIt is not permitted to turn checks on by calling set_num_checks() once checking has been
7312027Sjungma@eit.uni-kl.dedeactivated, because this could cause bogus violation reports
7412027Sjungma@eit.uni-kl.de
7512027Sjungma@eit.uni-kl.deThe DMI and debug checks are unaffected by the num_checks count (because they are cheap)
7612027Sjungma@eit.uni-kl.de
7712027Sjungma@eit.uni-kl.deThe error messages contain User Manual references
7812027Sjungma@eit.uni-kl.de
7912027Sjungma@eit.uni-kl.deThe checker is designed to be used with a transaction pool: otherwise it could consume
8012027Sjungma@eit.uni-kl.dea lot of memory. The checker keeps a local copy of each transaction object
8112027Sjungma@eit.uni-kl.deFailures are reported with a severity of SC_ERROR. The actions may be overridden by calling:
8212027Sjungma@eit.uni-kl.de   sc_report_handler::set_actions("tlm2_protocol_checker", ...);
8312027Sjungma@eit.uni-kl.de
8412027Sjungma@eit.uni-kl.deSPECIFIC CHECKS
8512027Sjungma@eit.uni-kl.de
8612027Sjungma@eit.uni-kl.denb_transport: phase sequence BEGIN_REQ -> END_REQ -> BEGIN_RESP -> END_RESP
8712027Sjungma@eit.uni-kl.deMust not have two outstanding requests or responses (exclusion rules)
8812027Sjungma@eit.uni-kl.deMust not have decreasing timing annotations on calls to or returns from nb_transport_fw/bw
8912027Sjungma@eit.uni-kl.dePhase extensions permitted and ignored
9012027Sjungma@eit.uni-kl.deMust not call b_transport during nb_transport phase sequence and vice-versa
9112027Sjungma@eit.uni-kl.de
9212027Sjungma@eit.uni-kl.denb_transport: memory manager must be set
9312027Sjungma@eit.uni-kl.denb_transport: reference count must be non-zero
9412027Sjungma@eit.uni-kl.deFirst checker in BEGIN_REQ path should see ref_count == 1 (warning only)
9512027Sjungma@eit.uni-kl.deAn interconnect component that sets a memory manager should also clear it
9612027Sjungma@eit.uni-kl.deAn interconnect component that sets extensions with no memory manager should also clear them
9712027Sjungma@eit.uni-kl.de(Does not bother with these memory manager checks for DMI and debug)
9812027Sjungma@eit.uni-kl.de
9912027Sjungma@eit.uni-kl.deTransaction object must be properly initialized
10012027Sjungma@eit.uni-kl.deMany generic payload attributes must not be modified during the transaction lifetime
10112027Sjungma@eit.uni-kl.deTransaction object must not be re-allocated for a new transaction while still in use
10212027Sjungma@eit.uni-kl.deDMI descriptor must be properly initialized
10312027Sjungma@eit.uni-kl.deDebug transaction must be properly initialized
10412027Sjungma@eit.uni-kl.deDebug byte count must be less than data_length
10512027Sjungma@eit.uni-kl.de
10612027Sjungma@eit.uni-kl.deChecks that require multiple checkers to be instantiated along a transaction path:
10712027Sjungma@eit.uni-kl.deThe BEGIN_RESP path must be the reverse of the BEGIN_REQ path
10812027Sjungma@eit.uni-kl.deTransaction object must not be sent with BEGIN_REQ while participating in a previous response
10912027Sjungma@eit.uni-kl.deInterconnect component must not set response status attribute to TLM_OK_RESPONSE
11012027Sjungma@eit.uni-kl.deInterconnect component must not modify data array on the response path
11112027Sjungma@eit.uni-kl.de
11212027Sjungma@eit.uni-kl.deGeneric payload option attribute (IEEE Std 1666-2011, SystemC 2.3.x)
11312027Sjungma@eit.uni-kl.degp_option must be properly initialized and only used for DMI and debug transport
11412027Sjungma@eit.uni-kl.deWhen gp_option is used, other gp attributes must be initalized and used as per the transport interfaces
11512027Sjungma@eit.uni-kl.de*/
11612027Sjungma@eit.uni-kl.de
11712027Sjungma@eit.uni-kl.de
11812027Sjungma@eit.uni-kl.de// ******************** PREAMBLE ********************
11912027Sjungma@eit.uni-kl.de
12012027Sjungma@eit.uni-kl.de
12112027Sjungma@eit.uni-kl.de#ifndef __tlm2_base_protocol_checker__
12212027Sjungma@eit.uni-kl.de#define __tlm2_base_protocol_checker__
12312027Sjungma@eit.uni-kl.de
12412027Sjungma@eit.uni-kl.de#include "systemc"
12512027Sjungma@eit.uni-kl.deusing std::cout;
12612027Sjungma@eit.uni-kl.deusing std::endl;
12712027Sjungma@eit.uni-kl.deusing std::dec;
12812027Sjungma@eit.uni-kl.deusing std::hex;
12912027Sjungma@eit.uni-kl.de
13012027Sjungma@eit.uni-kl.de#include "tlm.h"
13112027Sjungma@eit.uni-kl.de#include <sstream>
13212027Sjungma@eit.uni-kl.de#include <map>
13312027Sjungma@eit.uni-kl.de
13412027Sjungma@eit.uni-kl.de
13512027Sjungma@eit.uni-kl.denamespace tlm_utils {
13612027Sjungma@eit.uni-kl.de
13712027Sjungma@eit.uni-kl.de
13812027Sjungma@eit.uni-kl.de// Number of checks remaining
13912027Sjungma@eit.uni-kl.deconst  sc_dt::uint64 default_num_checks = 100000;
14012027Sjungma@eit.uni-kl.destatic sc_dt::uint64 num_checks = default_num_checks;
14112027Sjungma@eit.uni-kl.de
14212027Sjungma@eit.uni-kl.de
14312027Sjungma@eit.uni-kl.de// Types used when building a trace of the transaction path
14412027Sjungma@eit.uni-kl.detypedef unsigned char uchar_t;
14512027Sjungma@eit.uni-kl.detypedef std::deque<sc_core::sc_module*> deque_t;
14612027Sjungma@eit.uni-kl.de
14712027Sjungma@eit.uni-kl.destruct path_t {
14812027Sjungma@eit.uni-kl.de  path_t () { response_in_progress = false; ok_response = false; resp_data_ptr = 0; }
14912027Sjungma@eit.uni-kl.de
15012027Sjungma@eit.uni-kl.de  bool      response_in_progress;
15112027Sjungma@eit.uni-kl.de  bool      ok_response;
15212027Sjungma@eit.uni-kl.de  deque_t   path;
15312027Sjungma@eit.uni-kl.de  uchar_t*  resp_data_ptr;  // Copy of data on response path
15412027Sjungma@eit.uni-kl.de};
15512027Sjungma@eit.uni-kl.de
15612027Sjungma@eit.uni-kl.de// Global variable used for checks involving multiple checkers along a transaction path
15712027Sjungma@eit.uni-kl.destatic std::map<tlm::tlm_generic_payload*, path_t> shared_map;
15812027Sjungma@eit.uni-kl.de
15912027Sjungma@eit.uni-kl.de
16012027Sjungma@eit.uni-kl.de// ******************** CLASS DEFINITION ********************
16112027Sjungma@eit.uni-kl.de
16212027Sjungma@eit.uni-kl.de
16312027Sjungma@eit.uni-kl.detemplate <unsigned int  BUSWIDTH = 32>
16412027Sjungma@eit.uni-kl.declass tlm2_base_protocol_checker
16512027Sjungma@eit.uni-kl.de
16612027Sjungma@eit.uni-kl.de: public sc_core::sc_module
16712027Sjungma@eit.uni-kl.de, public tlm::tlm_fw_transport_if<tlm::tlm_base_protocol_types>
16812027Sjungma@eit.uni-kl.de, public tlm::tlm_bw_transport_if<tlm::tlm_base_protocol_types>
16912027Sjungma@eit.uni-kl.de{
17012027Sjungma@eit.uni-kl.depublic:
17112027Sjungma@eit.uni-kl.de
17212027Sjungma@eit.uni-kl.de  // Instantiate and bind checker inline between an existing pair of initiator and target sockets
17312027Sjungma@eit.uni-kl.de
17412027Sjungma@eit.uni-kl.de  tlm::tlm_target_socket   <BUSWIDTH, tlm::tlm_base_protocol_types, 1> target_socket;
17512027Sjungma@eit.uni-kl.de  tlm::tlm_initiator_socket<BUSWIDTH, tlm::tlm_base_protocol_types, 1> initiator_socket;
17612027Sjungma@eit.uni-kl.de
17712027Sjungma@eit.uni-kl.de  SC_CTOR(tlm2_base_protocol_checker)
17812027Sjungma@eit.uni-kl.de  : m_request_in_progress(0), m_response_in_progress(0)
17912027Sjungma@eit.uni-kl.de  {
18012027Sjungma@eit.uni-kl.de    target_socket   .bind( *this );
18112027Sjungma@eit.uni-kl.de    initiator_socket.bind( *this );
18212027Sjungma@eit.uni-kl.de  }
18312027Sjungma@eit.uni-kl.de
18412027Sjungma@eit.uni-kl.de
18512027Sjungma@eit.uni-kl.de  // Access methods for num_checks count
18612027Sjungma@eit.uni-kl.de
18712027Sjungma@eit.uni-kl.de  static void set_num_checks(sc_dt::uint64 n) {
18812027Sjungma@eit.uni-kl.de    if (num_checks == 0)
18912027Sjungma@eit.uni-kl.de      SC_REPORT_FATAL("tlm2_protocol_checker", "Method set_num_checks called after checking has stopped due to maximum number of checks being reached");
19012027Sjungma@eit.uni-kl.de    num_checks = n;
19112027Sjungma@eit.uni-kl.de  }
19212027Sjungma@eit.uni-kl.de
19312027Sjungma@eit.uni-kl.de  static sc_dt::uint64 get_num_checks() { return num_checks; }
19412027Sjungma@eit.uni-kl.de
19512027Sjungma@eit.uni-kl.de
19612027Sjungma@eit.uni-kl.de  // TLM-2.0 interface methods for initiator and target sockets, instrumented with checks
19712027Sjungma@eit.uni-kl.de
19812027Sjungma@eit.uni-kl.de  virtual tlm::tlm_sync_enum nb_transport_fw(
19912027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay)
20012027Sjungma@eit.uni-kl.de  {
20112027Sjungma@eit.uni-kl.de    tlm::tlm_phase start_phase = phase;
20212027Sjungma@eit.uni-kl.de
20312027Sjungma@eit.uni-kl.de    if (num_checks)
20412027Sjungma@eit.uni-kl.de      nb_transport_fw_pre_checks( trans, phase, delay );
20512027Sjungma@eit.uni-kl.de
20612027Sjungma@eit.uni-kl.de    tlm::tlm_sync_enum status;
20712027Sjungma@eit.uni-kl.de    status = initiator_socket->nb_transport_fw( trans, phase, delay );
20812027Sjungma@eit.uni-kl.de
20912027Sjungma@eit.uni-kl.de    if (num_checks)
21012027Sjungma@eit.uni-kl.de      nb_transport_fw_post_checks( trans, start_phase, phase, delay, status );
21112027Sjungma@eit.uni-kl.de
21212027Sjungma@eit.uni-kl.de    return status;
21312027Sjungma@eit.uni-kl.de  }
21412027Sjungma@eit.uni-kl.de
21512027Sjungma@eit.uni-kl.de  virtual tlm::tlm_sync_enum nb_transport_bw(
21612027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay)
21712027Sjungma@eit.uni-kl.de  {
21812027Sjungma@eit.uni-kl.de    if (num_checks)
21912027Sjungma@eit.uni-kl.de      nb_transport_bw_pre_checks( trans, phase, delay );
22012027Sjungma@eit.uni-kl.de
22112027Sjungma@eit.uni-kl.de    tlm::tlm_sync_enum status;
22212027Sjungma@eit.uni-kl.de    status = target_socket->nb_transport_bw( trans, phase, delay );
22312027Sjungma@eit.uni-kl.de
22412027Sjungma@eit.uni-kl.de    if (num_checks)
22512027Sjungma@eit.uni-kl.de      nb_transport_bw_post_checks( trans, phase, delay, status );
22612027Sjungma@eit.uni-kl.de
22712027Sjungma@eit.uni-kl.de    return status;
22812027Sjungma@eit.uni-kl.de  }
22912027Sjungma@eit.uni-kl.de
23012027Sjungma@eit.uni-kl.de  virtual void b_transport( tlm::tlm_generic_payload& trans, sc_core::sc_time& delay )
23112027Sjungma@eit.uni-kl.de  {
23212027Sjungma@eit.uni-kl.de    if (num_checks)
23312027Sjungma@eit.uni-kl.de      b_transport_pre_checks( trans, delay );
23412027Sjungma@eit.uni-kl.de
23512027Sjungma@eit.uni-kl.de    initiator_socket->b_transport( trans, delay );
23612027Sjungma@eit.uni-kl.de
23712027Sjungma@eit.uni-kl.de    if (num_checks)
23812027Sjungma@eit.uni-kl.de      b_transport_post_checks( trans, delay );
23912027Sjungma@eit.uni-kl.de  }
24012027Sjungma@eit.uni-kl.de
24112027Sjungma@eit.uni-kl.de  virtual bool get_direct_mem_ptr(tlm::tlm_generic_payload& trans,
24212027Sjungma@eit.uni-kl.de                                  tlm::tlm_dmi&  dmi_data)
24312027Sjungma@eit.uni-kl.de  {
24412027Sjungma@eit.uni-kl.de    get_direct_mem_ptr_pre_checks( trans, dmi_data );
24512027Sjungma@eit.uni-kl.de
24612027Sjungma@eit.uni-kl.de    bool status;
24712027Sjungma@eit.uni-kl.de    status = initiator_socket->get_direct_mem_ptr( trans, dmi_data );
24812027Sjungma@eit.uni-kl.de
24912027Sjungma@eit.uni-kl.de    get_direct_mem_ptr_post_checks( trans, dmi_data );
25012027Sjungma@eit.uni-kl.de    return status;
25112027Sjungma@eit.uni-kl.de  }
25212027Sjungma@eit.uni-kl.de
25312027Sjungma@eit.uni-kl.de  virtual void invalidate_direct_mem_ptr(sc_dt::uint64 start_range,
25412027Sjungma@eit.uni-kl.de                                         sc_dt::uint64 end_range)
25512027Sjungma@eit.uni-kl.de  {
25612027Sjungma@eit.uni-kl.de    target_socket->invalidate_direct_mem_ptr(start_range, end_range);
25712027Sjungma@eit.uni-kl.de  }
25812027Sjungma@eit.uni-kl.de
25912027Sjungma@eit.uni-kl.de  virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans)
26012027Sjungma@eit.uni-kl.de  {
26112027Sjungma@eit.uni-kl.de    transport_dbg_pre_checks( trans );
26212027Sjungma@eit.uni-kl.de
26312027Sjungma@eit.uni-kl.de    unsigned int count;
26412027Sjungma@eit.uni-kl.de    count = initiator_socket->transport_dbg( trans );
26512027Sjungma@eit.uni-kl.de
26612027Sjungma@eit.uni-kl.de    transport_dbg_post_checks( trans, count );
26712027Sjungma@eit.uni-kl.de    return count;
26812027Sjungma@eit.uni-kl.de  }
26912027Sjungma@eit.uni-kl.de
27012027Sjungma@eit.uni-kl.de
27112027Sjungma@eit.uni-kl.deprivate:
27212027Sjungma@eit.uni-kl.de  void b_transport_pre_checks( tlm::tlm_generic_payload& trans, sc_core::sc_time& delay);
27312027Sjungma@eit.uni-kl.de
27412027Sjungma@eit.uni-kl.de  void b_transport_post_checks( tlm::tlm_generic_payload& trans, sc_core::sc_time& delay);
27512027Sjungma@eit.uni-kl.de
27612027Sjungma@eit.uni-kl.de  void nb_transport_fw_pre_checks(
27712027Sjungma@eit.uni-kl.de      tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay);
27812027Sjungma@eit.uni-kl.de
27912027Sjungma@eit.uni-kl.de  void nb_transport_fw_post_checks(
28012027Sjungma@eit.uni-kl.de      tlm::tlm_generic_payload& trans, tlm::tlm_phase& start_phase, tlm::tlm_phase& phase,
28112027Sjungma@eit.uni-kl.de      sc_core::sc_time& delay, tlm::tlm_sync_enum status);
28212027Sjungma@eit.uni-kl.de
28312027Sjungma@eit.uni-kl.de  void nb_transport_bw_pre_checks(
28412027Sjungma@eit.uni-kl.de      tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay);
28512027Sjungma@eit.uni-kl.de
28612027Sjungma@eit.uni-kl.de  void nb_transport_bw_post_checks(
28712027Sjungma@eit.uni-kl.de      tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay,
28812027Sjungma@eit.uni-kl.de      tlm::tlm_sync_enum status);
28912027Sjungma@eit.uni-kl.de
29012027Sjungma@eit.uni-kl.de  void nb_transport_response_checks(
29112027Sjungma@eit.uni-kl.de      tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay,
29212027Sjungma@eit.uni-kl.de      const char* txt2, const char* txt3, const char* txt4);
29312027Sjungma@eit.uni-kl.de
29412027Sjungma@eit.uni-kl.de  void check_initial_state(       tlm::tlm_generic_payload& trans, const char* txt2 );
29512027Sjungma@eit.uni-kl.de  void check_trans_not_modified(  tlm::tlm_generic_payload& trans, const char* txt2 );
29612027Sjungma@eit.uni-kl.de  void check_response_path(       tlm::tlm_generic_payload& trans, const char* txt2 );
29712027Sjungma@eit.uni-kl.de  void remember_gp_option(        tlm::tlm_generic_payload& trans );
29812027Sjungma@eit.uni-kl.de
29912027Sjungma@eit.uni-kl.de  void get_direct_mem_ptr_pre_checks( tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data );
30012027Sjungma@eit.uni-kl.de
30112027Sjungma@eit.uni-kl.de  void get_direct_mem_ptr_post_checks( tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data );
30212027Sjungma@eit.uni-kl.de
30312027Sjungma@eit.uni-kl.de  void transport_dbg_pre_checks( tlm::tlm_generic_payload& trans );
30412027Sjungma@eit.uni-kl.de
30512027Sjungma@eit.uni-kl.de  void transport_dbg_post_checks( tlm::tlm_generic_payload& trans, unsigned int count );
30612027Sjungma@eit.uni-kl.de
30712027Sjungma@eit.uni-kl.de  void tlm2error( tlm::tlm_generic_payload& trans, const char* ref, bool warning = false  );
30812027Sjungma@eit.uni-kl.de
30912027Sjungma@eit.uni-kl.deprivate:
31012027Sjungma@eit.uni-kl.de
31112027Sjungma@eit.uni-kl.de  struct state_t {
31212027Sjungma@eit.uni-kl.de    state_t() { b_call = 0; ph = tlm::UNINITIALIZED_PHASE; gp = 0; }
31312027Sjungma@eit.uni-kl.de
31412027Sjungma@eit.uni-kl.de    bool                      has_mm;
31512027Sjungma@eit.uni-kl.de    unsigned int              b_call;    // Number of b_transport calls in progress
31612027Sjungma@eit.uni-kl.de    tlm::tlm_phase            ph;
31712027Sjungma@eit.uni-kl.de    sc_core::sc_time          time;      // Current time + annotated delay
31812027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload* gp;        // Points to new data and byte enable buffers
31912027Sjungma@eit.uni-kl.de    uchar_t*                  data_ptr;  // Stores original pointers
32012027Sjungma@eit.uni-kl.de    uchar_t*                  byte_enable_ptr;
32112027Sjungma@eit.uni-kl.de  };
32212027Sjungma@eit.uni-kl.de
32312027Sjungma@eit.uni-kl.de  // Transaction state for the specific hop where this checker is inlined
32412027Sjungma@eit.uni-kl.de  std::map<tlm::tlm_generic_payload*, state_t> m_map;
32512027Sjungma@eit.uni-kl.de
32612027Sjungma@eit.uni-kl.de  // Flags for exclusion rules
32712027Sjungma@eit.uni-kl.de  tlm::tlm_generic_payload* m_request_in_progress;
32812027Sjungma@eit.uni-kl.de  tlm::tlm_generic_payload* m_response_in_progress;
32912027Sjungma@eit.uni-kl.de
33012027Sjungma@eit.uni-kl.de  std::ostringstream txt;
33112027Sjungma@eit.uni-kl.de
33212027Sjungma@eit.uni-kl.de};
33312027Sjungma@eit.uni-kl.de
33412027Sjungma@eit.uni-kl.de
33512027Sjungma@eit.uni-kl.de
33612027Sjungma@eit.uni-kl.de// ******************** MEMBER FUNCTION DEFINITIONS ********************
33712027Sjungma@eit.uni-kl.de
33812027Sjungma@eit.uni-kl.de
33912027Sjungma@eit.uni-kl.de#define BOILERPLATE \
34012027Sjungma@eit.uni-kl.detemplate <unsigned int BUSWIDTH> \
34112027Sjungma@eit.uni-kl.devoid tlm2_base_protocol_checker<BUSWIDTH>::
34212027Sjungma@eit.uni-kl.de
34312027Sjungma@eit.uni-kl.de
34412027Sjungma@eit.uni-kl.deBOILERPLATE
34512027Sjungma@eit.uni-kl.deb_transport_pre_checks(
34612027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload& trans, sc_core::sc_time& delay)
34712027Sjungma@eit.uni-kl.de{
34812027Sjungma@eit.uni-kl.de  ++ m_map[&trans].b_call;
34912027Sjungma@eit.uni-kl.de
35012027Sjungma@eit.uni-kl.de  if ( trans.has_mm() && trans.get_ref_count() == 0)
35112027Sjungma@eit.uni-kl.de  {
35212027Sjungma@eit.uni-kl.de    txt << "Transaction passed to b_transport with memory manager and reference count of 0";
35312027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.5 t)");
35412027Sjungma@eit.uni-kl.de  }
35512027Sjungma@eit.uni-kl.de  check_initial_state(trans, "b_transport");
35612027Sjungma@eit.uni-kl.de
35712027Sjungma@eit.uni-kl.de#if !(defined SYSTEMC_VERSION & SYSTEMC_VERSION <= 20050714)
35812027Sjungma@eit.uni-kl.de  if (sc_core::sc_get_current_process_handle().proc_kind() == sc_core::SC_METHOD_PROC_)
35912027Sjungma@eit.uni-kl.de  {
36012027Sjungma@eit.uni-kl.de    txt << "b_transport called from method process";
36112027Sjungma@eit.uni-kl.de    tlm2error(trans, "11.1.1.4 b)");
36212027Sjungma@eit.uni-kl.de  }
36312027Sjungma@eit.uni-kl.de#endif
36412027Sjungma@eit.uni-kl.de
36512027Sjungma@eit.uni-kl.de  if (m_map[&trans].ph > 0 && m_map[&trans].ph < 4)
36612027Sjungma@eit.uni-kl.de  {
36712027Sjungma@eit.uni-kl.de    txt << "b_transport called during a sequence of nb_transport calls";
36812027Sjungma@eit.uni-kl.de    tlm2error(trans, "15.2.10 c)");
36912027Sjungma@eit.uni-kl.de  }
37012027Sjungma@eit.uni-kl.de}
37112027Sjungma@eit.uni-kl.de
37212027Sjungma@eit.uni-kl.de
37312027Sjungma@eit.uni-kl.deBOILERPLATE
37412027Sjungma@eit.uni-kl.deb_transport_post_checks(
37512027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload& trans, sc_core::sc_time& delay)
37612027Sjungma@eit.uni-kl.de{
37712027Sjungma@eit.uni-kl.de  check_response_path(trans, "b_transport");
37812027Sjungma@eit.uni-kl.de  check_trans_not_modified(trans, "b_transport");
37912027Sjungma@eit.uni-kl.de  -- m_map[&trans].b_call;
38012027Sjungma@eit.uni-kl.de}
38112027Sjungma@eit.uni-kl.de
38212027Sjungma@eit.uni-kl.de
38312027Sjungma@eit.uni-kl.deBOILERPLATE
38412027Sjungma@eit.uni-kl.denb_transport_fw_pre_checks(
38512027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay)
38612027Sjungma@eit.uni-kl.de{
38712027Sjungma@eit.uni-kl.de  if ( !trans.has_mm() )
38812027Sjungma@eit.uni-kl.de  {
38912027Sjungma@eit.uni-kl.de    txt << "Transaction passed to nb_transport_fw with no memory manager set";
39012027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.5 i)");
39112027Sjungma@eit.uni-kl.de  }
39212027Sjungma@eit.uni-kl.de  if ( trans.get_ref_count() == 0)
39312027Sjungma@eit.uni-kl.de  {
39412027Sjungma@eit.uni-kl.de    txt << "Transaction passed to nb_transport_fw with reference count of 0";
39512027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.5 t)");
39612027Sjungma@eit.uni-kl.de  }
39712027Sjungma@eit.uni-kl.de
39812027Sjungma@eit.uni-kl.de  switch (phase)
39912027Sjungma@eit.uni-kl.de  {
40012027Sjungma@eit.uni-kl.de    case tlm::BEGIN_REQ:
40112027Sjungma@eit.uni-kl.de      check_initial_state(trans, "nb_transport_fw");
40212027Sjungma@eit.uni-kl.de
40312027Sjungma@eit.uni-kl.de      if (m_map[&trans].ph > 0 &&  m_map[&trans].ph < 4) // END_RESP -> BEGIN_REQ is legal
40412027Sjungma@eit.uni-kl.de      {
40512027Sjungma@eit.uni-kl.de        txt << "Phase " << phase << " sent out-of-sequence on forward path, detected in nb_transport_fw";
40612027Sjungma@eit.uni-kl.de        tlm2error(trans, "15.2.4");
40712027Sjungma@eit.uni-kl.de      }
40812027Sjungma@eit.uni-kl.de
40912027Sjungma@eit.uni-kl.de      if (m_request_in_progress)
41012027Sjungma@eit.uni-kl.de      {
41112027Sjungma@eit.uni-kl.de        txt << "Transaction violates BEGIN_REQ exclusion rule, detected in nb_transport_fw";
41212027Sjungma@eit.uni-kl.de        tlm2error(trans, "15.2.6 e)");
41312027Sjungma@eit.uni-kl.de      }
41412027Sjungma@eit.uni-kl.de      m_request_in_progress = &trans;
41512027Sjungma@eit.uni-kl.de
41612027Sjungma@eit.uni-kl.de      if (m_map[&trans].b_call)
41712027Sjungma@eit.uni-kl.de      {
41812027Sjungma@eit.uni-kl.de        txt << "nb_transport_fw called during a b_transport call";
41912027Sjungma@eit.uni-kl.de        tlm2error(trans, "15.2.10 c)");
42012027Sjungma@eit.uni-kl.de      }
42112027Sjungma@eit.uni-kl.de      break;
42212027Sjungma@eit.uni-kl.de
42312027Sjungma@eit.uni-kl.de    case tlm::END_REQ:
42412027Sjungma@eit.uni-kl.de    case tlm::BEGIN_RESP:
42512027Sjungma@eit.uni-kl.de    case tlm::UNINITIALIZED_PHASE:
42612027Sjungma@eit.uni-kl.de      txt << "Phase " << phase << " sent on forward path, detected in nb_transport_fw";
42712027Sjungma@eit.uni-kl.de      tlm2error(trans, " 15.2.3 c)");
42812027Sjungma@eit.uni-kl.de      break;
42912027Sjungma@eit.uni-kl.de
43012027Sjungma@eit.uni-kl.de    case tlm::END_RESP:
43112027Sjungma@eit.uni-kl.de      if (m_map[&trans].ph != tlm::BEGIN_RESP)
43212027Sjungma@eit.uni-kl.de      {
43312027Sjungma@eit.uni-kl.de        txt << "Phase " << phase << " sent out-of-sequence on forward path, detected in nb_transport_fw";
43412027Sjungma@eit.uni-kl.de        tlm2error(trans, "15.2.4");
43512027Sjungma@eit.uni-kl.de      }
43612027Sjungma@eit.uni-kl.de      m_response_in_progress = 0;
43712027Sjungma@eit.uni-kl.de      break;
43812027Sjungma@eit.uni-kl.de  }
43912027Sjungma@eit.uni-kl.de
44012027Sjungma@eit.uni-kl.de  if (phase < 5)  // Ignore extended phases
44112027Sjungma@eit.uni-kl.de    m_map[&trans].ph = phase;
44212027Sjungma@eit.uni-kl.de
44312027Sjungma@eit.uni-kl.de  if (sc_core::sc_time_stamp() + delay < m_map[&trans].time)
44412027Sjungma@eit.uni-kl.de  {
44512027Sjungma@eit.uni-kl.de    txt << "nb_transport_fw called with decreasing timing annotation:"
44612027Sjungma@eit.uni-kl.de        << " delay = " << delay
44712027Sjungma@eit.uni-kl.de        << ", sc_time_stamp() + delay from previous call = " << m_map[&trans].time;
44812027Sjungma@eit.uni-kl.de    tlm2error(trans, "15.2.7 c)");
44912027Sjungma@eit.uni-kl.de  }
45012027Sjungma@eit.uni-kl.de  m_map[&trans].time = sc_core::sc_time_stamp() + delay;
45112027Sjungma@eit.uni-kl.de}
45212027Sjungma@eit.uni-kl.de
45312027Sjungma@eit.uni-kl.de
45412027Sjungma@eit.uni-kl.deBOILERPLATE
45512027Sjungma@eit.uni-kl.denb_transport_fw_post_checks(
45612027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload& trans, tlm::tlm_phase& start_phase, tlm::tlm_phase& phase,
45712027Sjungma@eit.uni-kl.de    sc_core::sc_time& delay, tlm::tlm_sync_enum status)
45812027Sjungma@eit.uni-kl.de{
45912027Sjungma@eit.uni-kl.de  if (status == tlm::TLM_UPDATED)
46012027Sjungma@eit.uni-kl.de  {
46112027Sjungma@eit.uni-kl.de    nb_transport_response_checks(
46212027Sjungma@eit.uni-kl.de        trans, phase, delay, "(forward) return", "Return from nb_transport_fw", "nb_transport_fw");
46312027Sjungma@eit.uni-kl.de  }
46412027Sjungma@eit.uni-kl.de  else if (status == tlm::TLM_COMPLETED)
46512027Sjungma@eit.uni-kl.de  {
46612027Sjungma@eit.uni-kl.de    if (start_phase == tlm::BEGIN_REQ)
46712027Sjungma@eit.uni-kl.de      check_response_path(trans, "nb_transport_fw");
46812027Sjungma@eit.uni-kl.de    m_request_in_progress = 0;
46912027Sjungma@eit.uni-kl.de    m_map[&trans].ph = tlm::UNINITIALIZED_PHASE;
47012027Sjungma@eit.uni-kl.de  }
47112027Sjungma@eit.uni-kl.de
47212027Sjungma@eit.uni-kl.de  // Transaction object should not be re-allocated, even during the END_RESP phase
47312027Sjungma@eit.uni-kl.de  //if (phase != tlm::END_RESP)
47412027Sjungma@eit.uni-kl.de  {
47512027Sjungma@eit.uni-kl.de    std::ostringstream txt;
47612027Sjungma@eit.uni-kl.de    txt << "nb_transport_fw, phase = " << phase;
47712027Sjungma@eit.uni-kl.de    check_trans_not_modified(trans, txt.str().c_str());
47812027Sjungma@eit.uni-kl.de  }
47912027Sjungma@eit.uni-kl.de}
48012027Sjungma@eit.uni-kl.de
48112027Sjungma@eit.uni-kl.de
48212027Sjungma@eit.uni-kl.deBOILERPLATE
48312027Sjungma@eit.uni-kl.denb_transport_bw_pre_checks(
48412027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay)
48512027Sjungma@eit.uni-kl.de{
48612027Sjungma@eit.uni-kl.de  if ( !trans.has_mm() )
48712027Sjungma@eit.uni-kl.de  {
48812027Sjungma@eit.uni-kl.de    txt << "Transaction passed to nb_transport_bw with no memory manager set";
48912027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.5 i)");
49012027Sjungma@eit.uni-kl.de  }
49112027Sjungma@eit.uni-kl.de  if ( trans.get_ref_count() == 0)
49212027Sjungma@eit.uni-kl.de  {
49312027Sjungma@eit.uni-kl.de    txt << "Transaction passed to nb_transport_bw with reference count of 0";
49412027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.5 t)");
49512027Sjungma@eit.uni-kl.de  }
49612027Sjungma@eit.uni-kl.de  nb_transport_response_checks(
49712027Sjungma@eit.uni-kl.de      trans, phase, delay, "backward", "nb_transport_bw called", "nb_transport_bw");
49812027Sjungma@eit.uni-kl.de}
49912027Sjungma@eit.uni-kl.de
50012027Sjungma@eit.uni-kl.de
50112027Sjungma@eit.uni-kl.deBOILERPLATE
50212027Sjungma@eit.uni-kl.denb_transport_bw_post_checks(
50312027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay,
50412027Sjungma@eit.uni-kl.de    tlm::tlm_sync_enum status)
50512027Sjungma@eit.uni-kl.de{
50612027Sjungma@eit.uni-kl.de  if (status == tlm::TLM_UPDATED)
50712027Sjungma@eit.uni-kl.de  {
50812027Sjungma@eit.uni-kl.de    switch (phase)
50912027Sjungma@eit.uni-kl.de    {
51012027Sjungma@eit.uni-kl.de      case tlm::BEGIN_REQ:
51112027Sjungma@eit.uni-kl.de        txt << "Phase " << phase << " sent out-of-sequence on (backward) return path, detected in nb_transport_bw";
51212027Sjungma@eit.uni-kl.de        tlm2error(trans, "15.2.4");
51312027Sjungma@eit.uni-kl.de        break;
51412027Sjungma@eit.uni-kl.de
51512027Sjungma@eit.uni-kl.de      case tlm::END_REQ:
51612027Sjungma@eit.uni-kl.de      case tlm::BEGIN_RESP:
51712027Sjungma@eit.uni-kl.de      case tlm::UNINITIALIZED_PHASE:
51812027Sjungma@eit.uni-kl.de        txt << "Phase " << phase << " sent on (backward) return path, detected in nb_transport_bw";
51912027Sjungma@eit.uni-kl.de        tlm2error(trans, "15.2.3 c)");
52012027Sjungma@eit.uni-kl.de        break;
52112027Sjungma@eit.uni-kl.de
52212027Sjungma@eit.uni-kl.de      case tlm::END_RESP:
52312027Sjungma@eit.uni-kl.de        if (m_map[&trans].ph != tlm::BEGIN_RESP)
52412027Sjungma@eit.uni-kl.de        {
52512027Sjungma@eit.uni-kl.de          txt << "Phase " << phase << " sent out-of-sequence on (backward) return path, detected in nb_transport_bw";
52612027Sjungma@eit.uni-kl.de          tlm2error(trans, "15.2.4");
52712027Sjungma@eit.uni-kl.de        }
52812027Sjungma@eit.uni-kl.de
52912027Sjungma@eit.uni-kl.de        m_response_in_progress = 0;
53012027Sjungma@eit.uni-kl.de        break;
53112027Sjungma@eit.uni-kl.de    }
53212027Sjungma@eit.uni-kl.de
53312027Sjungma@eit.uni-kl.de    if (phase < 5)  // Ignore extended phases
53412027Sjungma@eit.uni-kl.de      m_map[&trans].ph = phase;
53512027Sjungma@eit.uni-kl.de
53612027Sjungma@eit.uni-kl.de    if (sc_core::sc_time_stamp() + delay < m_map[&trans].time)
53712027Sjungma@eit.uni-kl.de    {
53812027Sjungma@eit.uni-kl.de      txt << "Return from nb_transport_bw with decreasing timing annotation:"
53912027Sjungma@eit.uni-kl.de          << " delay = " << delay
54012027Sjungma@eit.uni-kl.de          << ", sc_time_stamp() + delay from previous call = " << m_map[&trans].time;
54112027Sjungma@eit.uni-kl.de      tlm2error(trans, "15.2.7 c)");
54212027Sjungma@eit.uni-kl.de    }
54312027Sjungma@eit.uni-kl.de    m_map[&trans].time = sc_core::sc_time_stamp() + delay;
54412027Sjungma@eit.uni-kl.de  }
54512027Sjungma@eit.uni-kl.de  else if (status == tlm::TLM_COMPLETED)
54612027Sjungma@eit.uni-kl.de  {
54712027Sjungma@eit.uni-kl.de    m_response_in_progress = 0;
54812027Sjungma@eit.uni-kl.de    m_map[&trans].ph = tlm::UNINITIALIZED_PHASE;
54912027Sjungma@eit.uni-kl.de  }
55012027Sjungma@eit.uni-kl.de
55112027Sjungma@eit.uni-kl.de  // Transaction object should not be re-allocated, even during the END_RESP phase
55212027Sjungma@eit.uni-kl.de  //if (phase != tlm::END_RESP)
55312027Sjungma@eit.uni-kl.de  {
55412027Sjungma@eit.uni-kl.de    std::ostringstream txt;
55512027Sjungma@eit.uni-kl.de    txt << "nb_transport_bw, phase = " << phase;
55612027Sjungma@eit.uni-kl.de    check_trans_not_modified(trans, txt.str().c_str());
55712027Sjungma@eit.uni-kl.de  }
55812027Sjungma@eit.uni-kl.de}
55912027Sjungma@eit.uni-kl.de
56012027Sjungma@eit.uni-kl.de
56112027Sjungma@eit.uni-kl.deBOILERPLATE
56212027Sjungma@eit.uni-kl.denb_transport_response_checks(
56312027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload& trans, tlm::tlm_phase& phase, sc_core::sc_time& delay,
56412027Sjungma@eit.uni-kl.de    const char* txt2, const char* txt3, const char* txt4)
56512027Sjungma@eit.uni-kl.de{
56612027Sjungma@eit.uni-kl.de  if (trans.is_response_ok())
56712027Sjungma@eit.uni-kl.de    if (shared_map[&trans].response_in_progress && !shared_map[&trans].ok_response)
56812027Sjungma@eit.uni-kl.de    {
56912027Sjungma@eit.uni-kl.de      txt << "Interconnect component sets response status attribute to TLM_OK_RESPONSE"
57012027Sjungma@eit.uni-kl.de          << ", detected in " << txt4;
57112027Sjungma@eit.uni-kl.de      tlm2error(trans, "14.7");
57212027Sjungma@eit.uni-kl.de
57312027Sjungma@eit.uni-kl.de    }
57412027Sjungma@eit.uni-kl.de
57512027Sjungma@eit.uni-kl.de  switch (phase)
57612027Sjungma@eit.uni-kl.de  {
57712027Sjungma@eit.uni-kl.de    case tlm::BEGIN_REQ:
57812027Sjungma@eit.uni-kl.de    case tlm::END_RESP:
57912027Sjungma@eit.uni-kl.de    case tlm::UNINITIALIZED_PHASE:
58012027Sjungma@eit.uni-kl.de      txt << "Phase " << phase << " sent on " << txt2 << " path"
58112027Sjungma@eit.uni-kl.de          << ", detected in " << txt4;
58212027Sjungma@eit.uni-kl.de      tlm2error(trans, "15.2.3 c)");
58312027Sjungma@eit.uni-kl.de      break;
58412027Sjungma@eit.uni-kl.de
58512027Sjungma@eit.uni-kl.de    case tlm::END_REQ:
58612027Sjungma@eit.uni-kl.de      if (m_map[&trans].ph != tlm::BEGIN_REQ)
58712027Sjungma@eit.uni-kl.de      {
58812027Sjungma@eit.uni-kl.de        txt << "Phase " << phase << " sent out-of-sequence on " << txt2 << " path"
58912027Sjungma@eit.uni-kl.de            << ", detected in " << txt4;
59012027Sjungma@eit.uni-kl.de        tlm2error(trans, "15.2.4");
59112027Sjungma@eit.uni-kl.de      }
59212027Sjungma@eit.uni-kl.de
59312027Sjungma@eit.uni-kl.de      m_request_in_progress = 0;
59412027Sjungma@eit.uni-kl.de      break;
59512027Sjungma@eit.uni-kl.de
59612027Sjungma@eit.uni-kl.de    case tlm::BEGIN_RESP:
59712027Sjungma@eit.uni-kl.de      if (m_map[&trans].ph != tlm::BEGIN_REQ && m_map[&trans].ph != tlm::END_REQ)
59812027Sjungma@eit.uni-kl.de      {
59912027Sjungma@eit.uni-kl.de        txt << "Phase " << phase << " sent out-of-sequence on " << txt2 << " path"
60012027Sjungma@eit.uni-kl.de            << ", detected in " << txt4;
60112027Sjungma@eit.uni-kl.de        tlm2error(trans, "15.2.4");
60212027Sjungma@eit.uni-kl.de      }
60312027Sjungma@eit.uni-kl.de
60412027Sjungma@eit.uni-kl.de      if (&trans == m_request_in_progress)
60512027Sjungma@eit.uni-kl.de        m_request_in_progress = 0;
60612027Sjungma@eit.uni-kl.de
60712027Sjungma@eit.uni-kl.de      if (m_response_in_progress)
60812027Sjungma@eit.uni-kl.de      {
60912027Sjungma@eit.uni-kl.de        txt << "Transaction violates BEGIN_RESP exclusion rule"
61012027Sjungma@eit.uni-kl.de            << ", detected in " << txt4;
61112027Sjungma@eit.uni-kl.de        tlm2error(trans, "15.2.6 f)");
61212027Sjungma@eit.uni-kl.de      }
61312027Sjungma@eit.uni-kl.de      m_response_in_progress = &trans;
61412027Sjungma@eit.uni-kl.de
61512027Sjungma@eit.uni-kl.de      check_response_path(trans, txt4);
61612027Sjungma@eit.uni-kl.de      break;
61712027Sjungma@eit.uni-kl.de  }
61812027Sjungma@eit.uni-kl.de
61912027Sjungma@eit.uni-kl.de  if (phase < 5)  // Ignore extended phases
62012027Sjungma@eit.uni-kl.de    m_map[&trans].ph = phase;
62112027Sjungma@eit.uni-kl.de
62212027Sjungma@eit.uni-kl.de  if (sc_core::sc_time_stamp() + delay < m_map[&trans].time)
62312027Sjungma@eit.uni-kl.de  {
62412027Sjungma@eit.uni-kl.de    txt << txt3 << " with decreasing timing annotation:"
62512027Sjungma@eit.uni-kl.de        << " delay = " << delay
62612027Sjungma@eit.uni-kl.de        << ", sc_time_stamp() + delay from previous call = " << m_map[&trans].time;
62712027Sjungma@eit.uni-kl.de    tlm2error(trans, "15.2.7 c)");
62812027Sjungma@eit.uni-kl.de  }
62912027Sjungma@eit.uni-kl.de  m_map[&trans].time = sc_core::sc_time_stamp() + delay;
63012027Sjungma@eit.uni-kl.de}
63112027Sjungma@eit.uni-kl.de
63212027Sjungma@eit.uni-kl.de
63312027Sjungma@eit.uni-kl.deBOILERPLATE
63412027Sjungma@eit.uni-kl.decheck_initial_state(
63512027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload& trans, const char* txt2 )
63612027Sjungma@eit.uni-kl.de{
63712027Sjungma@eit.uni-kl.de  if (num_checks > 0)
63812027Sjungma@eit.uni-kl.de  {
63912027Sjungma@eit.uni-kl.de    --num_checks;
64012027Sjungma@eit.uni-kl.de    if (num_checks == 0)
64112027Sjungma@eit.uni-kl.de      SC_REPORT_INFO("tlm2_protocol_checker", "Checkers deactivated after executing the set number of checks");
64212027Sjungma@eit.uni-kl.de  }
64312027Sjungma@eit.uni-kl.de
64412027Sjungma@eit.uni-kl.de  if ( trans.has_mm() && trans.get_ref_count() > 1 && shared_map[&trans].path.empty() )
64512027Sjungma@eit.uni-kl.de  {
64612027Sjungma@eit.uni-kl.de    txt << "New transaction passed to " << txt2 << " with reference count = "
64712027Sjungma@eit.uni-kl.de        << trans.get_ref_count();
64812027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.5 t)", true);
64912027Sjungma@eit.uni-kl.de  }
65012027Sjungma@eit.uni-kl.de  if (trans.get_data_ptr() == 0 && trans.get_command() != tlm::TLM_IGNORE_COMMAND)
65112027Sjungma@eit.uni-kl.de  {
65212027Sjungma@eit.uni-kl.de    txt << "Transaction not properly initialized: data_ptr == 0, detected in " << txt2;
65312027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.11 e)");
65412027Sjungma@eit.uni-kl.de  }
65512027Sjungma@eit.uni-kl.de  if (trans.get_data_length() == 0 && trans.get_command() != tlm::TLM_IGNORE_COMMAND)
65612027Sjungma@eit.uni-kl.de  {
65712027Sjungma@eit.uni-kl.de    txt << "Transaction not properly initialized: data_langth == 0, detected in " << txt2;
65812027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.12 d)");
65912027Sjungma@eit.uni-kl.de  }
66012027Sjungma@eit.uni-kl.de  if (trans.get_byte_enable_ptr() != 0 && trans.get_byte_enable_length() == 0)
66112027Sjungma@eit.uni-kl.de  {
66212027Sjungma@eit.uni-kl.de    txt << "Transaction not properly initialized: "
66312027Sjungma@eit.uni-kl.de        << "byte_enable_ptr != 0 and byte_enable_length == 0, detected in " << txt2;
66412027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.14 f)");
66512027Sjungma@eit.uni-kl.de  }
66612027Sjungma@eit.uni-kl.de  if (trans.get_streaming_width() == 0)
66712027Sjungma@eit.uni-kl.de  {
66812027Sjungma@eit.uni-kl.de    txt << "Transaction not properly initialized: streaming_width == 0, detected in " << txt2;
66912027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.15 f)");
67012027Sjungma@eit.uni-kl.de  }
67112027Sjungma@eit.uni-kl.de  if (trans.is_dmi_allowed())
67212027Sjungma@eit.uni-kl.de  {
67312027Sjungma@eit.uni-kl.de    txt << "Transaction not properly initialized: dmi_allowed == true, detected in " << txt2;
67412027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.16");
67512027Sjungma@eit.uni-kl.de  }
67612027Sjungma@eit.uni-kl.de  if (trans.get_response_status() != tlm::TLM_INCOMPLETE_RESPONSE)
67712027Sjungma@eit.uni-kl.de  {
67812027Sjungma@eit.uni-kl.de    txt << "Transaction not properly initialized: response_status != TLM_INCOMPLETE_RESPONSE, detected in " << txt2;
67912027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.17 e)");
68012027Sjungma@eit.uni-kl.de  }
68112027Sjungma@eit.uni-kl.de  if (trans.get_gp_option() != tlm::TLM_MIN_PAYLOAD)
68212027Sjungma@eit.uni-kl.de  {
68312027Sjungma@eit.uni-kl.de    txt << "Transaction not properly initialized: gp_option != TLM_MIN_PAYLOAD, detected in " << txt2;
68412027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.8 g)");
68512027Sjungma@eit.uni-kl.de  }
68612027Sjungma@eit.uni-kl.de
68712027Sjungma@eit.uni-kl.de  // Setup clones of transaction and buffers in map
68812027Sjungma@eit.uni-kl.de  tlm::tlm_generic_payload* gp = m_map[&trans].gp;
68912027Sjungma@eit.uni-kl.de  if (gp == 0)
69012027Sjungma@eit.uni-kl.de    gp = new tlm::tlm_generic_payload;  // Memory leak: transactions are never cleared from map
69112027Sjungma@eit.uni-kl.de  else
69212027Sjungma@eit.uni-kl.de  {
69312027Sjungma@eit.uni-kl.de    delete [] gp->get_data_ptr();
69412027Sjungma@eit.uni-kl.de    gp->free_all_extensions();
69512027Sjungma@eit.uni-kl.de  }
69612027Sjungma@eit.uni-kl.de  gp->set_data_ptr( new uchar_t[trans.get_data_length()] );
69712027Sjungma@eit.uni-kl.de  m_map[&trans].data_ptr = trans.get_data_ptr();
69812027Sjungma@eit.uni-kl.de
69912027Sjungma@eit.uni-kl.de  if (gp->get_byte_enable_ptr())
70012027Sjungma@eit.uni-kl.de    delete [] gp->get_byte_enable_ptr();
70112027Sjungma@eit.uni-kl.de  if (trans.get_byte_enable_ptr())
70212027Sjungma@eit.uni-kl.de    gp->set_byte_enable_ptr( new uchar_t[trans.get_byte_enable_length()] );
70312027Sjungma@eit.uni-kl.de  else
70412027Sjungma@eit.uni-kl.de    gp->set_byte_enable_ptr(0);
70512027Sjungma@eit.uni-kl.de  m_map[&trans].byte_enable_ptr = trans.get_byte_enable_ptr();
70612027Sjungma@eit.uni-kl.de
70712027Sjungma@eit.uni-kl.de  gp->deep_copy_from(trans);
70812027Sjungma@eit.uni-kl.de  m_map[&trans].gp = gp;
70912027Sjungma@eit.uni-kl.de  m_map[&trans].time = sc_core::SC_ZERO_TIME;
71012027Sjungma@eit.uni-kl.de  m_map[&trans].has_mm = trans.has_mm();
71112027Sjungma@eit.uni-kl.de
71212027Sjungma@eit.uni-kl.de  // Store request path checker sequence
71312027Sjungma@eit.uni-kl.de  if (shared_map[&trans].resp_data_ptr)
71412027Sjungma@eit.uni-kl.de  {
71512027Sjungma@eit.uni-kl.de    delete [] shared_map[&trans].resp_data_ptr;
71612027Sjungma@eit.uni-kl.de    shared_map[&trans].resp_data_ptr = 0;
71712027Sjungma@eit.uni-kl.de  }
71812027Sjungma@eit.uni-kl.de  if (shared_map[&trans].response_in_progress)
71912027Sjungma@eit.uni-kl.de  {
72012027Sjungma@eit.uni-kl.de    txt << "Transaction object sent with BEGIN_REQ while still being used on a previous response path, detected in " << txt2;
72112027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.5 x)");
72212027Sjungma@eit.uni-kl.de  }
72312027Sjungma@eit.uni-kl.de  shared_map[&trans].ok_response = false;
72412027Sjungma@eit.uni-kl.de  shared_map[&trans].path.push_back(this);
72512027Sjungma@eit.uni-kl.de}
72612027Sjungma@eit.uni-kl.de
72712027Sjungma@eit.uni-kl.de
72812027Sjungma@eit.uni-kl.deBOILERPLATE
72912027Sjungma@eit.uni-kl.deremember_gp_option(
73012027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload& trans)
73112027Sjungma@eit.uni-kl.de{
73212027Sjungma@eit.uni-kl.de  // Setup clone of transaction in map in order to check gp_option only
73312027Sjungma@eit.uni-kl.de  tlm::tlm_generic_payload* gp = m_map[&trans].gp;
73412027Sjungma@eit.uni-kl.de  if (gp == 0)
73512027Sjungma@eit.uni-kl.de    gp = new tlm::tlm_generic_payload;  // Memory leak: transactions are never cleared from map
73612027Sjungma@eit.uni-kl.de  gp->set_gp_option( trans.get_gp_option() );
73712027Sjungma@eit.uni-kl.de  m_map[&trans].gp = gp;
73812027Sjungma@eit.uni-kl.de}
73912027Sjungma@eit.uni-kl.de
74012027Sjungma@eit.uni-kl.de
74112027Sjungma@eit.uni-kl.deBOILERPLATE
74212027Sjungma@eit.uni-kl.decheck_trans_not_modified(
74312027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload& trans, const char* txt2 )
74412027Sjungma@eit.uni-kl.de{
74512027Sjungma@eit.uni-kl.de  tlm::tlm_generic_payload* init = m_map[&trans].gp;
74612027Sjungma@eit.uni-kl.de
74712027Sjungma@eit.uni-kl.de  if (trans.get_command() != init->get_command())
74812027Sjungma@eit.uni-kl.de  {
74912027Sjungma@eit.uni-kl.de    txt << "Command attribute modified during transaction lifetime, detected in " << txt2;
75012027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.7");
75112027Sjungma@eit.uni-kl.de  }
75212027Sjungma@eit.uni-kl.de  if (trans.get_data_ptr() != m_map[&trans].data_ptr)
75312027Sjungma@eit.uni-kl.de  {
75412027Sjungma@eit.uni-kl.de    txt << "Data pointer attribute modified during transaction lifetime, detected in " << txt2;
75512027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.7");
75612027Sjungma@eit.uni-kl.de  }
75712027Sjungma@eit.uni-kl.de  if (trans.get_data_length() != init->get_data_length())
75812027Sjungma@eit.uni-kl.de  {
75912027Sjungma@eit.uni-kl.de    txt << "Data length attribute modified during transaction lifetime, detected in " << txt2;
76012027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.7");
76112027Sjungma@eit.uni-kl.de  }
76212027Sjungma@eit.uni-kl.de  if (trans.get_command() == tlm::TLM_WRITE_COMMAND)
76312027Sjungma@eit.uni-kl.de    for (unsigned int i = 0; i < init->get_data_length(); i++)
76412027Sjungma@eit.uni-kl.de      if (trans.get_data_ptr()[i] != init->get_data_ptr()[i])
76512027Sjungma@eit.uni-kl.de      {
76612027Sjungma@eit.uni-kl.de        txt << "Data array modified during transaction lifetime, detected in " << txt2;
76712027Sjungma@eit.uni-kl.de        tlm2error(trans, "14.7");
76812027Sjungma@eit.uni-kl.de      }
76912027Sjungma@eit.uni-kl.de  if (trans.get_byte_enable_ptr() != m_map[&trans].byte_enable_ptr)
77012027Sjungma@eit.uni-kl.de  {
77112027Sjungma@eit.uni-kl.de    txt << "Byte enable pointer attribute modified during transaction lifetime, detected in " << txt2;
77212027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.7");
77312027Sjungma@eit.uni-kl.de  }
77412027Sjungma@eit.uni-kl.de  if (trans.get_byte_enable_length() != init->get_byte_enable_length())
77512027Sjungma@eit.uni-kl.de  {
77612027Sjungma@eit.uni-kl.de    txt << "Byte enable length attribute modified during transaction lifetime, detected in " << txt2;
77712027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.7");
77812027Sjungma@eit.uni-kl.de  }
77912027Sjungma@eit.uni-kl.de  if (trans.get_byte_enable_ptr())
78012027Sjungma@eit.uni-kl.de    for (unsigned int i = 0; i < init->get_byte_enable_length(); i++)
78112027Sjungma@eit.uni-kl.de      if (trans.get_byte_enable_ptr()[i] != init->get_byte_enable_ptr()[i])
78212027Sjungma@eit.uni-kl.de      {
78312027Sjungma@eit.uni-kl.de        txt << "Byte enable array modified during transaction lifetime, detected in " << txt2;
78412027Sjungma@eit.uni-kl.de        tlm2error(trans, "14.7");
78512027Sjungma@eit.uni-kl.de      }
78612027Sjungma@eit.uni-kl.de  if (trans.get_streaming_width() != init->get_streaming_width())
78712027Sjungma@eit.uni-kl.de  {
78812027Sjungma@eit.uni-kl.de    txt << "Streaming width attribute modified during transaction lifetime, detected in " << txt2;
78912027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.7");
79012027Sjungma@eit.uni-kl.de  }
79112027Sjungma@eit.uni-kl.de  if (init->get_gp_option() == tlm::TLM_MIN_PAYLOAD && trans.get_gp_option() != tlm::TLM_MIN_PAYLOAD)
79212027Sjungma@eit.uni-kl.de  {
79312027Sjungma@eit.uni-kl.de    txt << "Generic payload option attribute modified during transaction lifetime, detected in " << txt2;
79412027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.8 g)");
79512027Sjungma@eit.uni-kl.de  }
79612027Sjungma@eit.uni-kl.de  if ( !m_map[&trans].has_mm )
79712027Sjungma@eit.uni-kl.de  {
79812027Sjungma@eit.uni-kl.de    if (trans.has_mm())
79912027Sjungma@eit.uni-kl.de    {
80012027Sjungma@eit.uni-kl.de      txt << "Interconnect component sets a memory manager, but does not clear it on return, detected in " << txt2;
80112027Sjungma@eit.uni-kl.de      tlm2error(trans, "14.5 aa)");
80212027Sjungma@eit.uni-kl.de    }
80312027Sjungma@eit.uni-kl.de
80412027Sjungma@eit.uni-kl.de    for (unsigned int i = 0; i < tlm::max_num_extensions(); i++)
80512027Sjungma@eit.uni-kl.de      // Exclude tlm_endian_context extension from the check because it is not cloned in m_map
80612027Sjungma@eit.uni-kl.de      if (i != tlm::tlm_endian_context::ID)
80712027Sjungma@eit.uni-kl.de        if (trans.get_extension(i))
80812027Sjungma@eit.uni-kl.de          if ( !m_map[&trans].gp->get_extension(i) )
80912027Sjungma@eit.uni-kl.de          {
81012027Sjungma@eit.uni-kl.de            txt << "Extension set (index = " << i << ") without also being deleted in the absence of a memory manager, detected in " << txt2;
81112027Sjungma@eit.uni-kl.de            tlm2error(trans, "14.5 aa)");
81212027Sjungma@eit.uni-kl.de          }
81312027Sjungma@eit.uni-kl.de  }
81412027Sjungma@eit.uni-kl.de
81512027Sjungma@eit.uni-kl.de  uchar_t* resp_data_ptr = shared_map[&trans].resp_data_ptr;
81612027Sjungma@eit.uni-kl.de  if (resp_data_ptr)
81712027Sjungma@eit.uni-kl.de    for (unsigned int i = 0; i < trans.get_data_length(); i++)
81812027Sjungma@eit.uni-kl.de      if (trans.get_data_ptr()[i] != resp_data_ptr[i])
81912027Sjungma@eit.uni-kl.de      {
82012027Sjungma@eit.uni-kl.de        txt << "Transaction data array modified in interconnect component on response path, detected in " << txt2;
82112027Sjungma@eit.uni-kl.de        tlm2error(trans, "14.7");
82212027Sjungma@eit.uni-kl.de      }
82312027Sjungma@eit.uni-kl.de}
82412027Sjungma@eit.uni-kl.de
82512027Sjungma@eit.uni-kl.de
82612027Sjungma@eit.uni-kl.deBOILERPLATE
82712027Sjungma@eit.uni-kl.decheck_response_path(
82812027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload& trans, const char* txt2 )
82912027Sjungma@eit.uni-kl.de{
83012027Sjungma@eit.uni-kl.de  if ( !shared_map[&trans].path.empty() )
83112027Sjungma@eit.uni-kl.de  {
83212027Sjungma@eit.uni-kl.de    if ( this != shared_map[&trans].path.back() )
83312027Sjungma@eit.uni-kl.de    {
83412027Sjungma@eit.uni-kl.de      txt << "BEGIN_RESP path is not the reverse of the BEGIN_REQ path.";
83512027Sjungma@eit.uni-kl.de      txt << "\nBEGIN_REQ path includes these checkers: -> ";
83612027Sjungma@eit.uni-kl.de      deque_t path = shared_map[&trans].path;
83712027Sjungma@eit.uni-kl.de      for (deque_t::iterator i = path.begin(); i < path.end(); i++)
83812027Sjungma@eit.uni-kl.de        txt << (*i)->name() << " -> ";
83912027Sjungma@eit.uni-kl.de      txt << "\nDetected in " << txt2;
84012027Sjungma@eit.uni-kl.de      tlm2error(trans, "15.2.11 a)");
84112027Sjungma@eit.uni-kl.de    }
84212027Sjungma@eit.uni-kl.de    shared_map[&trans].path.pop_back();
84312027Sjungma@eit.uni-kl.de    shared_map[&trans].response_in_progress = !shared_map[&trans].path.empty();
84412027Sjungma@eit.uni-kl.de    shared_map[&trans].ok_response = trans.is_response_ok();
84512027Sjungma@eit.uni-kl.de
84612027Sjungma@eit.uni-kl.de    // Create a copy of the data array for comparison on the response path
84712027Sjungma@eit.uni-kl.de    if ( !shared_map[&trans].resp_data_ptr )
84812027Sjungma@eit.uni-kl.de    {
84912027Sjungma@eit.uni-kl.de      shared_map[&trans].resp_data_ptr = new uchar_t[trans.get_data_length()];
85012027Sjungma@eit.uni-kl.de      memcpy(shared_map[&trans].resp_data_ptr, trans.get_data_ptr(), trans.get_data_length());
85112027Sjungma@eit.uni-kl.de    }
85212027Sjungma@eit.uni-kl.de  }
85312027Sjungma@eit.uni-kl.de}
85412027Sjungma@eit.uni-kl.de
85512027Sjungma@eit.uni-kl.de
85612027Sjungma@eit.uni-kl.deBOILERPLATE
85712027Sjungma@eit.uni-kl.deget_direct_mem_ptr_pre_checks(
85812027Sjungma@eit.uni-kl.de    tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data )
85912027Sjungma@eit.uni-kl.de{
86012027Sjungma@eit.uni-kl.de  remember_gp_option(trans);
86112027Sjungma@eit.uni-kl.de
86212027Sjungma@eit.uni-kl.de  if (dmi_data.get_dmi_ptr() != 0)
86312027Sjungma@eit.uni-kl.de  {
86412027Sjungma@eit.uni-kl.de    txt << "DMI descriptor not properly initialized: dmi_ptr != 0";
86512027Sjungma@eit.uni-kl.de    tlm2error(trans, "11.2.5 f)");
86612027Sjungma@eit.uni-kl.de  }
86712027Sjungma@eit.uni-kl.de  if (!dmi_data.is_none_allowed())
86812027Sjungma@eit.uni-kl.de  {
86912027Sjungma@eit.uni-kl.de    txt << "DMI descriptor not properly initialized: granted_access != DMI_ACCESS_NONE";
87012027Sjungma@eit.uni-kl.de    tlm2error(trans, "11.2.5 a)");
87112027Sjungma@eit.uni-kl.de  }
87212027Sjungma@eit.uni-kl.de  if (dmi_data.get_start_address() != 0)
87312027Sjungma@eit.uni-kl.de  {
87412027Sjungma@eit.uni-kl.de    txt << "DMI descriptor not properly initialized: start_address != 0";
87512027Sjungma@eit.uni-kl.de    tlm2error(trans, "11.2.5 u)");
87612027Sjungma@eit.uni-kl.de  }
87712027Sjungma@eit.uni-kl.de  if (dmi_data.get_end_address() != (sc_dt::uint64)(-1))
87812027Sjungma@eit.uni-kl.de  {
87912027Sjungma@eit.uni-kl.de    txt << "DMI descriptor not properly initialized: end_address != 0";
88012027Sjungma@eit.uni-kl.de    tlm2error(trans, "11.2.5 u)");
88112027Sjungma@eit.uni-kl.de  }
88212027Sjungma@eit.uni-kl.de  if (dmi_data.get_read_latency() != sc_core::SC_ZERO_TIME)
88312027Sjungma@eit.uni-kl.de  {
88412027Sjungma@eit.uni-kl.de    txt << "DMI descriptor not properly initialized: read_latency != SC_ZERO_TIME";
88512027Sjungma@eit.uni-kl.de    tlm2error(trans, "11.2.5 ac)");
88612027Sjungma@eit.uni-kl.de  }
88712027Sjungma@eit.uni-kl.de  if (dmi_data.get_write_latency() != sc_core::SC_ZERO_TIME)
88812027Sjungma@eit.uni-kl.de  {
88912027Sjungma@eit.uni-kl.de    txt << "DMI descriptor not properly initialized: write_latency != SC_ZERO_TIME";
89012027Sjungma@eit.uni-kl.de    tlm2error(trans, "11.2.5 ac)");
89112027Sjungma@eit.uni-kl.de  }
89212027Sjungma@eit.uni-kl.de
89312027Sjungma@eit.uni-kl.de  if (trans.get_gp_option() == tlm::TLM_FULL_PAYLOAD)
89412027Sjungma@eit.uni-kl.de  {
89512027Sjungma@eit.uni-kl.de    /*
89612027Sjungma@eit.uni-kl.de    if (trans.is_dmi_allowed())  // Would be rather brutal to flag dmi_allowed as an arror for a DMI transaction!
89712027Sjungma@eit.uni-kl.de    {
89812027Sjungma@eit.uni-kl.de      txt << "DMI transaction not properly initialized: dmi_allowed == true";
89912027Sjungma@eit.uni-kl.de      tlm2error(trans, "14.8 e) & 14.16");
90012027Sjungma@eit.uni-kl.de    }
90112027Sjungma@eit.uni-kl.de	*/
90212027Sjungma@eit.uni-kl.de    if (trans.get_response_status() != tlm::TLM_INCOMPLETE_RESPONSE)
90312027Sjungma@eit.uni-kl.de    {
90412027Sjungma@eit.uni-kl.de      txt << "DMI transaction not properly initialized: response_status != TLM_INCOMPLETE_RESPONSE";
90512027Sjungma@eit.uni-kl.de      tlm2error(trans, "14.8 e) & 14.17 e)");
90612027Sjungma@eit.uni-kl.de    }
90712027Sjungma@eit.uni-kl.de  }
90812027Sjungma@eit.uni-kl.de  else if (trans.get_gp_option() == tlm::TLM_FULL_PAYLOAD_ACCEPTED)
90912027Sjungma@eit.uni-kl.de  {
91012027Sjungma@eit.uni-kl.de    txt << "DMI transaction not properly initialized: gp_option == TLM_FULL_PAYLOAD_ACCEPTED";
91112027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.8 c) & e) & j)");
91212027Sjungma@eit.uni-kl.de  }
91312027Sjungma@eit.uni-kl.de}
91412027Sjungma@eit.uni-kl.de
91512027Sjungma@eit.uni-kl.de
91612027Sjungma@eit.uni-kl.deBOILERPLATE
91712027Sjungma@eit.uni-kl.deget_direct_mem_ptr_post_checks( tlm::tlm_generic_payload& trans, tlm::tlm_dmi& dmi_data )
91812027Sjungma@eit.uni-kl.de{
91912027Sjungma@eit.uni-kl.de  tlm::tlm_generic_payload* init = m_map[&trans].gp;
92012027Sjungma@eit.uni-kl.de
92112027Sjungma@eit.uni-kl.de  if (init->get_gp_option() == tlm::TLM_MIN_PAYLOAD && trans.get_gp_option() != tlm::TLM_MIN_PAYLOAD)
92212027Sjungma@eit.uni-kl.de  {
92312027Sjungma@eit.uni-kl.de    txt << "DMI transaction gp_option attribute value TLM_MIN_PAYLOAD modified during transaction lifetime";
92412027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.8 h)");
92512027Sjungma@eit.uni-kl.de  }
92612027Sjungma@eit.uni-kl.de  else if (init->get_gp_option() == tlm::TLM_FULL_PAYLOAD && trans.get_gp_option() == tlm::TLM_MIN_PAYLOAD)
92712027Sjungma@eit.uni-kl.de  {
92812027Sjungma@eit.uni-kl.de    txt << "DMI transaction gp_option attribute value changed from TLM_FULL_PAYLOAD to TLM_MIN_PAYLOAD";
92912027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.8 j)");
93012027Sjungma@eit.uni-kl.de  }
93112027Sjungma@eit.uni-kl.de}
93212027Sjungma@eit.uni-kl.de
93312027Sjungma@eit.uni-kl.de
93412027Sjungma@eit.uni-kl.deBOILERPLATE
93512027Sjungma@eit.uni-kl.detransport_dbg_pre_checks( tlm::tlm_generic_payload& trans )
93612027Sjungma@eit.uni-kl.de{
93712027Sjungma@eit.uni-kl.de  remember_gp_option(trans);
93812027Sjungma@eit.uni-kl.de
93912027Sjungma@eit.uni-kl.de  if (trans.get_data_length() > 0 && trans.get_data_ptr() == 0)
94012027Sjungma@eit.uni-kl.de  {
94112027Sjungma@eit.uni-kl.de    txt << "Debug transaction has data_ptr == 0";
94212027Sjungma@eit.uni-kl.de    tlm2error(trans, "11.3.4 l)");
94312027Sjungma@eit.uni-kl.de  }
94412027Sjungma@eit.uni-kl.de
94512027Sjungma@eit.uni-kl.de  if (trans.get_gp_option() == tlm::TLM_FULL_PAYLOAD)
94612027Sjungma@eit.uni-kl.de  {
94712027Sjungma@eit.uni-kl.de    if (trans.get_byte_enable_ptr() != 0 && trans.get_byte_enable_length() == 0)
94812027Sjungma@eit.uni-kl.de    {
94912027Sjungma@eit.uni-kl.de      txt << "Debug transaction not properly initialized: "
95012027Sjungma@eit.uni-kl.de          << "byte_enable_ptr != 0 and byte_enable_length == 0";
95112027Sjungma@eit.uni-kl.de      tlm2error(trans, "14.8 f) & 14.14 f)");
95212027Sjungma@eit.uni-kl.de    }
95312027Sjungma@eit.uni-kl.de    if (trans.get_streaming_width() == 0)
95412027Sjungma@eit.uni-kl.de    {
95512027Sjungma@eit.uni-kl.de      txt << "Debug transaction not properly initialized: streaming_width == 0";
95612027Sjungma@eit.uni-kl.de      tlm2error(trans, "14.8 f) & 14.15 f)");
95712027Sjungma@eit.uni-kl.de    }
95812027Sjungma@eit.uni-kl.de    if (trans.is_dmi_allowed())
95912027Sjungma@eit.uni-kl.de    {
96012027Sjungma@eit.uni-kl.de      txt << "Debug transaction not properly initialized: dmi_allowed == true";
96112027Sjungma@eit.uni-kl.de      tlm2error(trans, "14.8 f) & 14.16");
96212027Sjungma@eit.uni-kl.de    }
96312027Sjungma@eit.uni-kl.de    if (trans.get_response_status() != tlm::TLM_INCOMPLETE_RESPONSE)
96412027Sjungma@eit.uni-kl.de    {
96512027Sjungma@eit.uni-kl.de      txt << "Debug transaction not properly initialized: response_status != TLM_INCOMPLETE_RESPONSE";
96612027Sjungma@eit.uni-kl.de      tlm2error(trans, "14.8 f) & 14.17 e)");
96712027Sjungma@eit.uni-kl.de    }
96812027Sjungma@eit.uni-kl.de  }
96912027Sjungma@eit.uni-kl.de  else if (trans.get_gp_option() == tlm::TLM_FULL_PAYLOAD_ACCEPTED)
97012027Sjungma@eit.uni-kl.de  {
97112027Sjungma@eit.uni-kl.de    txt << "Debug transaction not properly initialized: gp_option == TLM_FULL_PAYLOAD_ACCEPTED";
97212027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.8 c) & f) & l)");
97312027Sjungma@eit.uni-kl.de  }}
97412027Sjungma@eit.uni-kl.de
97512027Sjungma@eit.uni-kl.de
97612027Sjungma@eit.uni-kl.deBOILERPLATE
97712027Sjungma@eit.uni-kl.detransport_dbg_post_checks( tlm::tlm_generic_payload& trans, unsigned int count )
97812027Sjungma@eit.uni-kl.de{
97912027Sjungma@eit.uni-kl.de  tlm::tlm_generic_payload* init = m_map[&trans].gp;
98012027Sjungma@eit.uni-kl.de
98112027Sjungma@eit.uni-kl.de  if (trans.get_data_length() > 0 && trans.get_data_ptr() == 0)
98212027Sjungma@eit.uni-kl.de  {
98312027Sjungma@eit.uni-kl.de    txt << "Debug transaction has data_ptr == 0";
98412027Sjungma@eit.uni-kl.de    tlm2error(trans, "11.3.4 l)");
98512027Sjungma@eit.uni-kl.de  }
98612027Sjungma@eit.uni-kl.de  if (count > trans.get_data_length())
98712027Sjungma@eit.uni-kl.de  {
98812027Sjungma@eit.uni-kl.de    txt << "Count returned from transport_dbg is greater than data_length";
98912027Sjungma@eit.uni-kl.de    tlm2error(trans, "11.3.4 s)");
99012027Sjungma@eit.uni-kl.de  }
99112027Sjungma@eit.uni-kl.de
99212027Sjungma@eit.uni-kl.de  if (init->get_gp_option() == tlm::TLM_MIN_PAYLOAD && trans.get_gp_option() != tlm::TLM_MIN_PAYLOAD)
99312027Sjungma@eit.uni-kl.de  {
99412027Sjungma@eit.uni-kl.de    txt << "Debug transaction gp_option attribute value TLM_MIN_PAYLOAD modified during transaction lifetime";
99512027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.8 h)");
99612027Sjungma@eit.uni-kl.de  }
99712027Sjungma@eit.uni-kl.de  else if (init->get_gp_option() == tlm::TLM_FULL_PAYLOAD && trans.get_gp_option() == tlm::TLM_MIN_PAYLOAD)
99812027Sjungma@eit.uni-kl.de  {
99912027Sjungma@eit.uni-kl.de    txt << "Debug transaction gp_option attribute value changed from TLM_FULL_PAYLOAD to TLM_MIN_PAYLOAD";
100012027Sjungma@eit.uni-kl.de    tlm2error(trans, "14.8 l)");
100112027Sjungma@eit.uni-kl.de  }}
100212027Sjungma@eit.uni-kl.de
100312027Sjungma@eit.uni-kl.de
100412027Sjungma@eit.uni-kl.deBOILERPLATE
100512027Sjungma@eit.uni-kl.detlm2error( tlm::tlm_generic_payload& trans, const char* ref, bool warning )
100612027Sjungma@eit.uni-kl.de{
100712027Sjungma@eit.uni-kl.de  txt << "\n\nRefer to IEEE Std 1666-2011, clause " << ref;
100812027Sjungma@eit.uni-kl.de  txt << "\n\nChecker instance: " << this->name();
100912027Sjungma@eit.uni-kl.de  txt << "\n\nTransaction details:";
101012027Sjungma@eit.uni-kl.de  txt << "\n  has_mm             = " << dec << trans.has_mm() << " (bool)";
101112027Sjungma@eit.uni-kl.de  txt << "\n  ref_count          = " << dec << trans.get_ref_count() << " (int)";
101212027Sjungma@eit.uni-kl.de  txt << "\n\n  gp_option          = " <<
101312027Sjungma@eit.uni-kl.de      (trans.get_gp_option() == tlm::TLM_MIN_PAYLOAD  ? "TLM_MIN_PAYLOAD"
101412027Sjungma@eit.uni-kl.de	  :trans.get_gp_option() == tlm::TLM_FULL_PAYLOAD ? "TLM_FULL_PAYLOAD"
101512027Sjungma@eit.uni-kl.de	                                                  : "TLM_FULL_PAYLOAD_ACCEPTED");
101612027Sjungma@eit.uni-kl.de  txt << "\n  command            = " <<
101712027Sjungma@eit.uni-kl.de     (trans.get_command() == tlm::TLM_READ_COMMAND  ? "TLM_READ_COMMAND"
101812027Sjungma@eit.uni-kl.de     :trans.get_command() == tlm::TLM_WRITE_COMMAND ? "TLM_WRITE_COMMAND"
101912027Sjungma@eit.uni-kl.de                                                    : "TLM_IGNORE_COMMAND");
102012027Sjungma@eit.uni-kl.de  txt << "\n  address            = " << hex << trans.get_address() << " (hex)";
102112027Sjungma@eit.uni-kl.de  txt << "\n  data_ptr           = " << hex
102212027Sjungma@eit.uni-kl.de      << reinterpret_cast<int*>(trans.get_data_ptr()) << " (hex)";
102312027Sjungma@eit.uni-kl.de  txt << "\n  data_length        = " << hex << trans.get_data_length() << " (hex)";
102412027Sjungma@eit.uni-kl.de  txt << "\n  streaming_width    = " << hex << trans.get_streaming_width() << " (hex)";
102512027Sjungma@eit.uni-kl.de  txt << "\n  byte_enable_ptr    = " << hex
102612027Sjungma@eit.uni-kl.de      << reinterpret_cast<int*>(trans.get_byte_enable_ptr()) << " (hex)";
102712027Sjungma@eit.uni-kl.de  txt << "\n  byte_enable_length = " << hex << trans.get_byte_enable_length() << " (hex)";
102812027Sjungma@eit.uni-kl.de  txt << "\n  dmi_allowed        = " << dec << trans.is_dmi_allowed() << " (bool)";
102912027Sjungma@eit.uni-kl.de  txt << "\n  response_status    = " << trans.get_response_string();
103012027Sjungma@eit.uni-kl.de
103112027Sjungma@eit.uni-kl.de  bool extensions_present = false;
103212027Sjungma@eit.uni-kl.de  for (unsigned int i = 0; i < tlm::max_num_extensions(); i++)
103312027Sjungma@eit.uni-kl.de  {
103412027Sjungma@eit.uni-kl.de    tlm::tlm_extension_base* ext = trans.get_extension(i);
103512027Sjungma@eit.uni-kl.de    if (ext)
103612027Sjungma@eit.uni-kl.de    {
103712027Sjungma@eit.uni-kl.de      if (!extensions_present)
103812027Sjungma@eit.uni-kl.de        txt << "\n\n  extensions:";
103912027Sjungma@eit.uni-kl.de      txt << "\n    index = " << i << "   type = " << typeid(*ext).name();
104012027Sjungma@eit.uni-kl.de      extensions_present = true;
104112027Sjungma@eit.uni-kl.de    }
104212027Sjungma@eit.uni-kl.de  }
104312027Sjungma@eit.uni-kl.de
104412027Sjungma@eit.uni-kl.de  txt << "\n\n";
104512027Sjungma@eit.uni-kl.de  if (warning)
104612027Sjungma@eit.uni-kl.de    SC_REPORT_WARNING("tlm2_protocol_checker", txt.str().c_str());
104712027Sjungma@eit.uni-kl.de  else
104812027Sjungma@eit.uni-kl.de    SC_REPORT_ERROR("tlm2_protocol_checker", txt.str().c_str());
104912027Sjungma@eit.uni-kl.de}
105012027Sjungma@eit.uni-kl.de
105112027Sjungma@eit.uni-kl.de
105212027Sjungma@eit.uni-kl.de
105312027Sjungma@eit.uni-kl.de} // namespace tlm_utils
105412027Sjungma@eit.uni-kl.de
105512027Sjungma@eit.uni-kl.de#endif // __tlm2_base_protocol_checker__
1056