tlm2_base_protocol_checker.h revision 12027
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