112922Sgabeblack@google.com/***************************************************************************** 212922Sgabeblack@google.com 312922Sgabeblack@google.com Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 412922Sgabeblack@google.com more contributor license agreements. See the NOTICE file distributed 512922Sgabeblack@google.com with this work for additional information regarding copyright ownership. 612922Sgabeblack@google.com Accellera licenses this file to you under the Apache License, Version 2.0 712922Sgabeblack@google.com (the "License"); you may not use this file except in compliance with the 812922Sgabeblack@google.com License. You may obtain a copy of the License at 912922Sgabeblack@google.com 1012922Sgabeblack@google.com http://www.apache.org/licenses/LICENSE-2.0 1112922Sgabeblack@google.com 1212922Sgabeblack@google.com Unless required by applicable law or agreed to in writing, software 1312922Sgabeblack@google.com distributed under the License is distributed on an "AS IS" BASIS, 1412922Sgabeblack@google.com WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1512922Sgabeblack@google.com implied. See the License for the specific language governing 1612922Sgabeblack@google.com permissions and limitations under the License. 1712922Sgabeblack@google.com 1812922Sgabeblack@google.com *****************************************************************************/ 1912922Sgabeblack@google.com 2012922Sgabeblack@google.com#ifndef __SIMPLEBUSLT_H__ 2112922Sgabeblack@google.com#define __SIMPLEBUSLT_H__ 2212922Sgabeblack@google.com 2312922Sgabeblack@google.com//#include <systemc> 2412922Sgabeblack@google.com#include "tlm.h" 2512922Sgabeblack@google.com 2612922Sgabeblack@google.com#include "tlm_utils/simple_target_socket.h" 2712922Sgabeblack@google.com#include "tlm_utils/simple_initiator_socket.h" 2812922Sgabeblack@google.com 2912922Sgabeblack@google.comtemplate <int NR_OF_INITIATORS, int NR_OF_TARGETS> 3012922Sgabeblack@google.comclass SimpleBusLT : public sc_core::sc_module 3112922Sgabeblack@google.com{ 3212922Sgabeblack@google.compublic: 3312922Sgabeblack@google.com typedef tlm::tlm_generic_payload transaction_type; 3412922Sgabeblack@google.com typedef tlm::tlm_phase phase_type; 3512922Sgabeblack@google.com typedef tlm::tlm_sync_enum sync_enum_type; 3612922Sgabeblack@google.com typedef tlm_utils::simple_target_socket_tagged<SimpleBusLT> target_socket_type; 3712922Sgabeblack@google.com typedef tlm_utils::simple_initiator_socket_tagged<SimpleBusLT> initiator_socket_type; 3812922Sgabeblack@google.com 3912922Sgabeblack@google.compublic: 4012922Sgabeblack@google.com target_socket_type target_socket[NR_OF_INITIATORS]; 4112922Sgabeblack@google.com initiator_socket_type initiator_socket[NR_OF_TARGETS]; 4212922Sgabeblack@google.com 4312922Sgabeblack@google.compublic: 4412922Sgabeblack@google.com SC_HAS_PROCESS(SimpleBusLT); 4512922Sgabeblack@google.com SimpleBusLT(sc_core::sc_module_name name) : 4612922Sgabeblack@google.com sc_core::sc_module(name) 4712922Sgabeblack@google.com { 4812922Sgabeblack@google.com for (unsigned int i = 0; i < NR_OF_INITIATORS; ++i) { 4912922Sgabeblack@google.com target_socket[i].register_b_transport(this, &SimpleBusLT::initiatorBTransport, i); 5012922Sgabeblack@google.com target_socket[i].register_transport_dbg(this, &SimpleBusLT::transportDebug, i); 5112922Sgabeblack@google.com target_socket[i].register_get_direct_mem_ptr(this, &SimpleBusLT::getDMIPointer, i); 5212922Sgabeblack@google.com } 5312922Sgabeblack@google.com for (unsigned int i = 0; i < NR_OF_TARGETS; ++i) { 5412922Sgabeblack@google.com initiator_socket[i].register_invalidate_direct_mem_ptr(this, &SimpleBusLT::invalidateDMIPointers, i); 5512922Sgabeblack@google.com } 5612922Sgabeblack@google.com } 5712922Sgabeblack@google.com 5812922Sgabeblack@google.com // 5912922Sgabeblack@google.com // Dummy decoder: 6012922Sgabeblack@google.com // - address[31-28]: portId 6112922Sgabeblack@google.com // - address[27-0]: masked address 6212922Sgabeblack@google.com // 6312922Sgabeblack@google.com 6412922Sgabeblack@google.com unsigned int getPortId(const sc_dt::uint64& address) 6512922Sgabeblack@google.com { 6612922Sgabeblack@google.com return (unsigned int)address >> 28; 6712922Sgabeblack@google.com } 6812922Sgabeblack@google.com 6912922Sgabeblack@google.com sc_dt::uint64 getAddressOffset(unsigned int portId) 7012922Sgabeblack@google.com { 7112922Sgabeblack@google.com return portId << 28; 7212922Sgabeblack@google.com } 7312922Sgabeblack@google.com 7412922Sgabeblack@google.com sc_dt::uint64 getAddressMask(unsigned int portId) 7512922Sgabeblack@google.com { 7612922Sgabeblack@google.com return 0xfffffff; 7712922Sgabeblack@google.com } 7812922Sgabeblack@google.com 7912922Sgabeblack@google.com unsigned int decode(const sc_dt::uint64& address) 8012922Sgabeblack@google.com { 8112922Sgabeblack@google.com // decode address: 8212922Sgabeblack@google.com // - return initiator socket id 8312922Sgabeblack@google.com 8412922Sgabeblack@google.com return getPortId(address); 8512922Sgabeblack@google.com } 8612922Sgabeblack@google.com 8712922Sgabeblack@google.com // 8812922Sgabeblack@google.com // interface methods 8912922Sgabeblack@google.com // 9012922Sgabeblack@google.com 9112922Sgabeblack@google.com // 9212922Sgabeblack@google.com // LT protocol 9312922Sgabeblack@google.com // - forward each call to the target/initiator 9412922Sgabeblack@google.com // 9512922Sgabeblack@google.com void initiatorBTransport(int SocketId, 9612922Sgabeblack@google.com transaction_type& trans, 9712922Sgabeblack@google.com sc_core::sc_time& t) 9812922Sgabeblack@google.com { 9912922Sgabeblack@google.com initiator_socket_type* decodeSocket; 10012922Sgabeblack@google.com unsigned int portId = decode(trans.get_address()); 10112922Sgabeblack@google.com assert(portId < NR_OF_TARGETS); 10212922Sgabeblack@google.com decodeSocket = &initiator_socket[portId]; 10312922Sgabeblack@google.com trans.set_address(trans.get_address() & getAddressMask(portId)); 10412922Sgabeblack@google.com 10512922Sgabeblack@google.com (*decodeSocket)->b_transport(trans, t); 10612922Sgabeblack@google.com } 10712922Sgabeblack@google.com 10812922Sgabeblack@google.com unsigned int transportDebug(int SocketId, 10912922Sgabeblack@google.com transaction_type& trans) 11012922Sgabeblack@google.com { 11112922Sgabeblack@google.com unsigned int portId = decode(trans.get_address()); 11212922Sgabeblack@google.com assert(portId < NR_OF_TARGETS); 11312922Sgabeblack@google.com initiator_socket_type* decodeSocket = &initiator_socket[portId]; 11412922Sgabeblack@google.com trans.set_address( trans.get_address() & getAddressMask(portId) ); 11512922Sgabeblack@google.com 11612922Sgabeblack@google.com return (*decodeSocket)->transport_dbg(trans); 11712922Sgabeblack@google.com } 11812922Sgabeblack@google.com 11912922Sgabeblack@google.com bool limitRange(unsigned int portId, sc_dt::uint64& low, sc_dt::uint64& high) 12012922Sgabeblack@google.com { 12112922Sgabeblack@google.com sc_dt::uint64 addressOffset = getAddressOffset(portId); 12212922Sgabeblack@google.com sc_dt::uint64 addressMask = getAddressMask(portId); 12312922Sgabeblack@google.com 12412922Sgabeblack@google.com if (low > addressMask) { 12512922Sgabeblack@google.com // Range does not overlap with addressrange for this target 12612922Sgabeblack@google.com return false; 12712922Sgabeblack@google.com } 12812922Sgabeblack@google.com 12912922Sgabeblack@google.com low += addressOffset; 13012922Sgabeblack@google.com if (high > addressMask) { 13112922Sgabeblack@google.com high = addressOffset + addressMask; 13212922Sgabeblack@google.com 13312922Sgabeblack@google.com } else { 13412922Sgabeblack@google.com high += addressOffset; 13512922Sgabeblack@google.com } 13612922Sgabeblack@google.com return true; 13712922Sgabeblack@google.com } 13812922Sgabeblack@google.com 13912922Sgabeblack@google.com bool getDMIPointer(int SocketId, 14012922Sgabeblack@google.com transaction_type& trans, 14112922Sgabeblack@google.com tlm::tlm_dmi& dmi_data) 14212922Sgabeblack@google.com { 14312922Sgabeblack@google.com sc_dt::uint64 address = trans.get_address(); 14412922Sgabeblack@google.com 14512922Sgabeblack@google.com unsigned int portId = decode(address); 14612922Sgabeblack@google.com assert(portId < NR_OF_TARGETS); 14712922Sgabeblack@google.com initiator_socket_type* decodeSocket = &initiator_socket[portId]; 14812922Sgabeblack@google.com sc_dt::uint64 maskedAddress = address & getAddressMask(portId); 14912922Sgabeblack@google.com 15012922Sgabeblack@google.com trans.set_address(maskedAddress); 15112922Sgabeblack@google.com 15212922Sgabeblack@google.com bool result = 15312922Sgabeblack@google.com (*decodeSocket)->get_direct_mem_ptr(trans, dmi_data); 15412922Sgabeblack@google.com 15512922Sgabeblack@google.com if (result) 15612922Sgabeblack@google.com { 15712922Sgabeblack@google.com // Range must contain address 15812922Sgabeblack@google.com assert(dmi_data.get_start_address() <= maskedAddress); 15912922Sgabeblack@google.com assert(dmi_data.get_end_address() >= maskedAddress); 16012922Sgabeblack@google.com } 16112922Sgabeblack@google.com 16212922Sgabeblack@google.com // Should always succeed 16312922Sgabeblack@google.com sc_dt::uint64 start, end; 16412922Sgabeblack@google.com start = dmi_data.get_start_address(); 16512922Sgabeblack@google.com end = dmi_data.get_end_address(); 16612922Sgabeblack@google.com 16712922Sgabeblack@google.com limitRange(portId, start, end); 16812922Sgabeblack@google.com 16912922Sgabeblack@google.com dmi_data.set_start_address(start); 17012922Sgabeblack@google.com dmi_data.set_end_address(end); 17112922Sgabeblack@google.com 17212922Sgabeblack@google.com return result; 17312922Sgabeblack@google.com } 17412922Sgabeblack@google.com 17512922Sgabeblack@google.com void invalidateDMIPointers(int port_id, 17612922Sgabeblack@google.com sc_dt::uint64 start_range, 17712922Sgabeblack@google.com sc_dt::uint64 end_range) 17812922Sgabeblack@google.com { 17912922Sgabeblack@google.com // FIXME: probably faster to always invalidate everything? 18012922Sgabeblack@google.com 18112922Sgabeblack@google.com if (!limitRange(port_id, start_range, end_range)) { 18212922Sgabeblack@google.com // Range does not fall into address range of target 18312922Sgabeblack@google.com return; 18412922Sgabeblack@google.com } 18512922Sgabeblack@google.com 18612922Sgabeblack@google.com for (unsigned int i = 0; i < NR_OF_INITIATORS; ++i) { 18712922Sgabeblack@google.com (target_socket[i])->invalidate_direct_mem_ptr(start_range, end_range); 18812922Sgabeblack@google.com } 18912922Sgabeblack@google.com } 19012922Sgabeblack@google.com 19112922Sgabeblack@google.com}; 19212922Sgabeblack@google.com 19312922Sgabeblack@google.com#endif 194