diff --git a/MPSoC/soclib/soclib/lib/mapping_table/include/int_tab.h b/MPSoC/soclib/soclib/lib/mapping_table/include/int_tab.h index 0edf8c8e56b6ad1fe2fabadf02aba02c434b3b50..3dcdc3af62707d5d5395807192b3009a397c4a90 100644 --- a/MPSoC/soclib/soclib/lib/mapping_table/include/int_tab.h +++ b/MPSoC/soclib/soclib/lib/mapping_table/include/int_tab.h @@ -30,6 +30,7 @@ #include <vector> #include "exception.h" +#include <cstdlib> namespace soclib { namespace common { @@ -126,7 +127,8 @@ private: return; } } - throw soclib::exception::ValueError("Too much levels"); + std::cout << "ERROR IntTab.init() function : Too much levels" << std::endl; + exit(0); } public: @@ -134,7 +136,10 @@ public: value_t operator[]( size_t level ) const { if ( level > m_level ) - throw soclib::exception::ValueError("Level out of bounds"); + { + std::cout << "ERROR IntTab.[] operator : level too large" << std::endl; + exit(0); + } return m_values[level]; } @@ -142,7 +147,10 @@ public: value_t operator*( const IntTab &widths ) const { if ( widths.level() != m_level ) - throw soclib::exception::ValueError("Levels not matching"); + { + std::cout << "ERROR IntTab.* operator : levels not matching" << std::endl; + exit(0); + } value_t ret = 0; for ( size_t l=0; l<m_level; ++l ) { diff --git a/MPSoC/soclib/soclib/lib/mapping_table/include/mapping_table.h b/MPSoC/soclib/soclib/lib/mapping_table/include/mapping_table.h index 0b4da1542f83819fc1a6158585ddb2b02da6654d..07dc85ca7e90b7d6094d10cb334a270fcf2cd2e1 100644 --- a/MPSoC/soclib/soclib/lib/mapping_table/include/mapping_table.h +++ b/MPSoC/soclib/soclib/lib/mapping_table/include/mapping_table.h @@ -21,12 +21,22 @@ * SOCLIB_LGPL_HEADER_END * * Copyright (c) UPMC, Lip6, Asim - * Nicolas Pouillon <nipo@ssji.net>, 2007 + * Alain Greiner <alain.greiner@lip6.fr> 2005 + * Nicolas Pouillon <nipo@ssji.net> 2007 + * Alain Greiner <alain.greiner@lip6.fr> 2013 * - * Based on previous works by Francois Pecheux & Alain Greiner - * - * Maintainers: nipo + * Maintainers: alain */ + +///////////////////////////////////////////////////////////////////////// +// Implementation Note (October 2013) +// 1) Regarding the various ADDRESS or SRCID decoding tables: +// - ADDRESSES values are supposed to use uint64_t type +// - SRCID values are supposed to use uint32_t type +// 2) Regarding SRCID decoding, the m_srcid[array] is always used. +// Identity mapping is handled as a default value in this array. +///////////////////////////////////////////////////////////////////////// + #ifndef SOCLIB_MAPPING_TABLE_H #define SOCLIB_MAPPING_TABLE_H @@ -45,66 +55,79 @@ namespace soclib { namespace common { class MappingTable ////////////////////////////////////// { -public: - typedef uint64_t addr64_t; - typedef uint32_t addr32_t; private: std::list<soclib::common::Segment> m_segment_list; // list of all segments - size_t m_addr_width; // address width - addr64_t m_addr_mask; - IntTab m_level_addr_bits; // number of bits per level (addr) - IntTab m_level_id_bits; // number of bits per level (srcid) - addr64_t m_cacheability_mask; - addr64_t m_rt_size; // max segment size for 1 target + size_t m_addr_width; // number of bits + size_t m_srcid_width; // number of bits + uint64_t m_addr_mask; + IntTab m_level_addr_bits; // nb bits per level (addr) + IntTab m_level_id_bits; // nb bits per level (srcid) + uint64_t m_cacheability_mask; + uint64_t m_rt_size; // max segment size for 1 target bool m_used; // no more modif when true size_t* m_srcid_array; // array indexed by srcid, - // and containing local port index + // containing local port index public: MappingTable( const MappingTable& ); + const MappingTable &operator=( const MappingTable & ); MappingTable( size_t addr_width, const IntTab &level_addr_bits, const IntTab &level_id_bits, - const addr64_t cacheability_mask ); + const uint64_t cacheability_mask ); ~MappingTable(); + ////////////////////////////////////////////// void add( const soclib::common::Segment &seg ); - void srcid_map( const IntTab &srcid, size_t portid ); + //////////////////////////////////////////////////// + void srcid_map( const IntTab &srcid, + const IntTab &portid ); + /////////////////////////////////////////////////////////////// std::list<Segment> getSegmentList( const IntTab &index ) const; + //////////////////////////////////////////////////// const std::list<Segment> &getAllSegmentList() const; + //////////////////////////////////////////////////////////////// soclib::common::Segment getSegment( const IntTab &index ) const; - template<typename desired_addr_t> - AddressDecodingTable<desired_addr_t, bool> - getCacheabilityTable() const; - - template<typename desired_addr_t> - AddressDecodingTable<desired_addr_t, bool> - getLocalityTable( const IntTab &index ) const; - - template<typename desired_addr_t> - AddressDecodingTable<desired_addr_t, int> - getRoutingTable( const IntTab &index, int default_index = 0 ) const; - + ////////////////////////////////////// AddressDecodingTable<uint64_t, size_t> - getPortidFromAddress( const size_t cluster_id, const size_t default_id = 0 ) const; + getLocalIndexFromAddress( const size_t cluster_id, + const size_t default_id = 0 ) const; - AddressDecodingTable<uint64_t, size_t> - getPortidFromSrcid( const size_t cluster_id ) const; + /////////////////////////////////////// + AddressDecodingTable<uint32_t, size_t> + getLocalIndexFromSrcid( const size_t cluster_id ) const; + ///////////////////////////////////// + AddressDecodingTable<uint64_t, bool> + getLocalMatchFromAddress( const size_t cluster_id ) const; + + ///////////////////////////////////// AddressDecodingTable<uint32_t, bool> - getIdLocalityTable( const IntTab &index ) const; + getLocalMatchFromSrcid( const size_t cluster_id ) const; + + ////////////////////////////////////// + AddressDecodingTable<uint64_t, size_t> + getGlobalIndexFromAddress( const size_t default_id = 0 ) const; + + ////////////////////////////////////// + AddressDecodingTable<uint32_t, size_t> + getGlobalIndexFromSrcid() const; + + //////////////////////////////////// + AddressDecodingTable<uint64_t, bool> + getCacheabilityTable() const; - AddressMaskingTable<uint32_t> - getIdMaskingTable( const int level ) const; + //////////////////////////////////// + void print( std::ostream &o ) const; ////////////////////////////// size_t getAddressWidth() const @@ -112,7 +135,10 @@ public: return m_addr_width; } - void print( std::ostream &o ) const; + inline const IntTab& getSrcidLevelBits() const + { + return m_level_id_bits; + } ////////////////////////////////////////////////////////////////////////// friend std::ostream &operator << (std::ostream &o, const MappingTable &mt) @@ -121,14 +147,9 @@ public: return o; } - /////////////////////////////////////////////////////////// - inline unsigned int indexForId( const IntTab &index ) const + ///////////////////////////////////////////////////// + inline size_t indexForId( const IntTab &index ) const { - //DG 24.10.2016 - - std::cout << " index : " << index << std::endl; - std::cout << " m_level_id_bits : " << m_level_id_bits << std::endl; - std::cout << " index*m_level_id_bits: " << index*m_level_id_bits << std::endl; return index*m_level_id_bits; } @@ -137,27 +158,6 @@ public: { return m_level_addr_bits.level(); } - - //////////////////// simpler variants /////////////////////////// - - AddressDecodingTable<addr32_t, bool> - getCacheabilityTable() const - { - return getCacheabilityTable<addr32_t>(); - } - - AddressDecodingTable<addr32_t, bool> - getLocalityTable( const IntTab &index ) const - { - return getLocalityTable<addr32_t>( index ); - } - - AddressDecodingTable<addr32_t, int> - getRoutingTable( const IntTab &index, int default_index = 0 ) const - { - return getRoutingTable<addr32_t>( index, default_index ); - } - }; }} diff --git a/MPSoC/soclib/soclib/lib/mapping_table/src/mapping_table.cpp b/MPSoC/soclib/soclib/lib/mapping_table/src/mapping_table.cpp index 0131edb7cc36393fb4d3d766e0b35f9484514f32..2a6e6593c52d1b34c56a6ce84854261464688b6a 100644 --- a/MPSoC/soclib/soclib/lib/mapping_table/src/mapping_table.cpp +++ b/MPSoC/soclib/soclib/lib/mapping_table/src/mapping_table.cpp @@ -20,11 +20,22 @@ * SOCLIB_LGPL_HEADER_END * * Copyright (c) UPMC, Lip6, Asim - * Nicolas Pouillon <nipo@ssji.net>, 2007 + * Alain Greiner <alain.greiner@lip6.fr> 2005 + * Nicolas Pouillon <nipo@ssji.net> 2007 + * Alain Greiner <alain.greiner@lip6.fr> 2013 * - * Based on previous works by Francois Pecheux & Alain Greiner + * Maintainers: alain */ +///////////////////////////////////////////////////////////////////////////// +// Implementation Note (October 2013) +// 1) Regarding the various ADDRESS or SRCID decoding tables: +// - ADDRESSES values are supposed to use uint64_t type +// - SRCID values are supposed to use uint32_t type +// 2) Regarding SRCID decoding, the m_srcid[array] is always used. +// Identity mapping is handled as a default value: m_srcid_array[i] = i +///////////////////////////////////////////////////////////////////////////// + #include <cassert> #include <sstream> #include "mapping_table.h" @@ -32,28 +43,37 @@ namespace soclib { namespace common { /////////////////////////// -MappingTable::MappingTable( - size_t addr_width, - const IntTab &level_addr_bits, - const IntTab &level_id_bits, - const addr64_t cacheability_mask ) +MappingTable::MappingTable( size_t addr_width, + const IntTab &level_addr_bits, + const IntTab &level_id_bits, + const uint64_t cacheability_mask ) : m_segment_list(), - m_addr_width(addr_width), - m_addr_mask((addr_width == 64) ? ((addr64_t)-1) : (((addr64_t)1<<addr_width)-1)), - m_level_addr_bits(level_addr_bits), - m_level_id_bits(level_id_bits), - m_cacheability_mask(cacheability_mask), - m_used(false) + m_addr_width( addr_width ), + m_srcid_width( level_id_bits.sum() ), + m_addr_mask((addr_width == 64) ? ((uint64_t)-1) : (((uint64_t)1<<addr_width)-1)), + m_level_addr_bits( level_addr_bits ), + m_level_id_bits( level_id_bits ), + m_cacheability_mask( cacheability_mask ), + m_used( false ) { + assert( (addr_width <= 64) and + "ERROR in mapping table : address larger than 64 bits not supported\n"); + m_rt_size = 1ULL << (addr_width - m_level_addr_bits.sum()); - addr64_t cm_rt_size = 1 << AddressMaskingTable<addr64_t>(m_cacheability_mask).getDrop(); - m_rt_size = std::min<addr64_t>(cm_rt_size, m_rt_size); + uint64_t cm_rt_size = 1 << AddressMaskingTable<uint64_t>(m_cacheability_mask).getDrop(); + m_rt_size = std::min<uint64_t>(cm_rt_size, m_rt_size); - m_srcid_array = new size_t[1<<m_level_id_bits.sum()]; -} + size_t srcid_size = 1<<m_srcid_width; + m_srcid_array = new size_t[srcid_size]; + + // set identity default values + for( size_t i=0 ; i<srcid_size ; i++ ) m_srcid_array[i] = i; +} -MappingTable::~MappingTable() { +///////////////////////////// +MappingTable::~MappingTable() +{ delete [] m_srcid_array; } @@ -86,11 +106,14 @@ const MappingTable &MappingTable::operator=( const MappingTable &ref ) ///////////////////////////////////////////////////// void MappingTable::srcid_map( const IntTab &srcid, - size_t portid ) + const IntTab &portid ) { - m_srcid_array[indexForId(srcid)] = portid; + const int index = indexForId(srcid); + assert((index < (1 << m_srcid_width)) && + "srcid do not fit the srcid width"); + m_srcid_array[index] = indexForId(portid); } - + ///////////////////////////////////////////// void MappingTable::add( const Segment &_seg ) { @@ -102,9 +125,9 @@ void MappingTable::add( const Segment &_seg ) if ( seg.index().level() != m_level_addr_bits.level() ) { - std::ostringstream o; - o << seg << " is not the same level as the mapping table."; - throw soclib::exception::ValueError(o.str()); + std::cout << "ERROR in mapping table for segment " << seg + << " : inconsistent level" << std::endl; + exit(0); } for ( i = m_segment_list.begin(); @@ -112,18 +135,19 @@ void MappingTable::add( const Segment &_seg ) i++ ) { Segment &s = *i; - if ( s.isOverlapping(seg) ) { - std::ostringstream o; - o << seg << " bumps in " << s; - throw soclib::exception::Collision(o.str()); + if ( s.isOverlapping(seg) ) + { + std::cout << "ERROR in mapping table for segment " << seg + << " : bumps in segment " << s << std::endl; + exit(0); } - for ( addr64_t address = s.baseAddress() & ~(m_rt_size-1); + for ( uint64_t address = s.baseAddress() & ~(m_rt_size-1); (address < s.baseAddress()+s.size()) && (address >= (s.baseAddress() & ~(m_rt_size-1))); address += m_rt_size ) { - for ( addr64_t segaddress = seg.baseAddress() & ~(m_rt_size-1); + for ( uint64_t segaddress = seg.baseAddress() & ~(m_rt_size-1); (segaddress < seg.baseAddress()+seg.size()) && (segaddress >= (seg.baseAddress() & ~(m_rt_size-1))); segaddress += m_rt_size ) @@ -131,11 +155,10 @@ void MappingTable::add( const Segment &_seg ) if ( (m_cacheability_mask & address) == (m_cacheability_mask & segaddress) && s.cacheable() != seg.cacheable() ) { - std::ostringstream oss; - oss << "Segment " << s - << " has a different cacheability attribute with same MSBs than " - << seg << std::endl; - throw soclib::exception::RunTimeError(oss.str()); + std::cout << "ERROR in mapping table for segment " << seg + << " : has different cacheability with same mask " + << " bits than segment " << s << std::endl; + exit(0); } } } @@ -183,7 +206,9 @@ Segment MappingTable::getSegment( const IntTab &index ) const const_cast<MappingTable*>(this)->m_used = true; - assert(list.size() == 1); + assert( (list.size() == 1) and + "ERROR in getSegment() : more than one segment allocated to target\n"); + return list.front(); } @@ -195,33 +220,32 @@ Segment MappingTable::getSegment( const IntTab &index ) const // This ADT can depend on the cluster_id. /////////////////////////////////////////////////////////////////////////// AddressDecodingTable<uint64_t,size_t> -MappingTable::getPortidFromAddress( const size_t cluster_id, - const size_t default_tgt_id ) const +MappingTable::getLocalIndexFromAddress( const size_t cluster_id, + const size_t default_target_id ) const { - // checking mapping table (two levels interconnect) + // checking two levels interconnect if ( m_level_addr_bits.level() != 2 ) { - std::cout << "ERROR in Mapping Table : the getPortidfromAddress() function" + std::cout << "ERROR in Mapping Table : the getLocalIndexFromAddress() function" << " requires a two levels interconnect" << std::endl; - std::cout << *this << std::endl; exit(0); } + const_cast<MappingTable*>(this)->m_used = true; + size_t global_bits = m_level_addr_bits[0]; // number of address global bits size_t local_bits = m_level_addr_bits[1]; // number of address local bits // ADT to be returned AddressDecodingTable<uint64_t,size_t> adt( local_bits, m_addr_width - global_bits - local_bits ); - adt.reset( default_tgt_id ); + adt.reset( default_target_id ); // temporary ADT for checking AddressDecodingTable<uint64_t,bool> done( local_bits, m_addr_width - global_bits - local_bits ); done.reset( false ); - const_cast<MappingTable*>(this)->m_used = true; - // loop on all segments std::list<Segment>::const_iterator seg; for ( seg = m_segment_list.begin(); @@ -231,11 +255,9 @@ MappingTable::getPortidFromAddress( const size_t cluster_id, // skip segment if cluster_id does not match if ( (size_t)seg->index()[0] != cluster_id ) continue; - uint64_t base = seg->baseAddress() & ~(m_rt_size-1); - // loop on all possible values for the address local bits - for ( uint64_t addr = base ; - (addr < base + seg->size()) and (addr >= base); + for ( uint64_t addr = seg->baseAddress() & ~(m_rt_size-1); + addr < (seg->baseAddress() + seg->size()); addr += m_rt_size ) { size_t port_id = seg->index()[1]; @@ -244,233 +266,274 @@ MappingTable::getPortidFromAddress( const size_t cluster_id, { std::cout << "ERROR in Mapping Table : segment " << *seg << " allocated to a different target than another segment" - << " with the same routing bits" << std::endl; - std::cout << *this << std::endl; + << " with the same local routing bits" << std::endl; + exit(0); } adt.set( addr, port_id ); done.set( addr, true ); } } - return adt; -} +} // end getLocalIndexFromAddress() /////////////////////////////////////////////////////////////////////////// // This function returns an ADT that can be used to get -// the local port_id for an initiator identified by the VCI srcid +// the local port_id for an initiator identified by the SRCID // in a clusterized architecture (two levels interconnect). -// Only the local bits in the srcid are decoded. +// Only the local bits in the SRCID are decoded. // This ADT can depend on the cluster_id. /////////////////////////////////////////////////////////////////////////// -AddressDecodingTable<uint64_t, size_t> -MappingTable::getPortidFromSrcid( const size_t cluster_id ) const +AddressDecodingTable<uint32_t, size_t> +MappingTable::getLocalIndexFromSrcid( const size_t cluster_id ) const { - // checking mapping table (two levels interconnect) + // checking two levels interconnect if ( m_level_addr_bits.level() != 2 ) { - std::cout << "ERROR in Mapping Table : the getPortidfromSrcid() function" + std::cout << "ERROR in Mapping Table : the getLocalIndexFromSrcid() function" << " requires a two levels interconnect" << std::endl; - std::cout << *this << std::endl; exit(0); } - size_t local_id_bits = m_level_id_bits[1]; // number of local bits in SRCID - size_t local_id_max = 1<<local_id_bits; // adt size - const_cast<MappingTable*>(this)->m_used = true; + size_t local_width = m_level_id_bits[1]; // number of local bits in SRCID + size_t adt_size = 1<<local_width; // number of entries in adt + size_t local_mask = adt_size - 1; // SRCID mask for local bits + // ADT to be returned - AddressDecodingTable<uint64_t, size_t> adt(local_id_bits, 0); + AddressDecodingTable<uint32_t, size_t> + adt(local_width, 0); - for ( size_t loc = 0 ; loc < local_id_max ; loc++ ) + // loop on all possible local index values + for ( size_t i = 0 ; i < adt_size ; i++ ) { - uint64_t srcid = (cluster_id<<local_id_bits) + loc; - adt.set( srcid , m_srcid_array[srcid] ); + size_t srcid = (cluster_id<<local_width) + i; + adt.set( srcid, m_srcid_array[srcid] & local_mask ); } - return adt; -} +} // end getLocalIndexFromSrcid() //////////////////////////////////////////////////////////// // This function returns an ADT that can be used to get -// the cacheability attribute from a physical address +// the "is_local" condition from a physical address +// in a clusterized architecture (two levels interconnect). +// Only the global bits in the address are decoded. //////////////////////////////////////////////////////////// -template<typename desired_addr_t> -AddressDecodingTable<desired_addr_t, bool> -MappingTable::getCacheabilityTable() const +AddressDecodingTable<uint64_t, bool> +MappingTable::getLocalMatchFromAddress( const size_t cluster_id ) const { + // checking two levels interconnect + if ( m_level_addr_bits.level() != 2 ) + { + std::cout << "ERROR in Mapping Table : the getLocalMatchFromAddress() function" + << " requires a two levels interconnect" << std::endl; + exit(0); + } + + const_cast<MappingTable*>(this)->m_used = true; + + // number of global bits in physical address + size_t global_bits = m_level_addr_bits[0]; + // ADT to be returned - AddressDecodingTable<desired_addr_t, bool> adt(m_cacheability_mask); + AddressDecodingTable<uint64_t, bool> + adt( global_bits, m_addr_width - global_bits ); adt.reset(false); // temporary ADT for checking - AddressDecodingTable<desired_addr_t, bool> done(m_cacheability_mask); + AddressDecodingTable<uint64_t, bool> + done( global_bits, m_addr_width - global_bits ); done.reset(false); - const_cast<MappingTable*>(this)->m_used = true; - - std::list<Segment>::const_iterator i; - for ( i = m_segment_list.begin(); - i != m_segment_list.end(); - i++ ) + // loop on all segments + std::list<Segment>::const_iterator seg; + for ( seg = m_segment_list.begin(); + seg != m_segment_list.end(); + seg++ ) { - for ( desired_addr_t addr = i->baseAddress() & ~(m_rt_size-1); - (addr < i->baseAddress()+i->size()) && - (addr >= (i->baseAddress() & ~(m_rt_size-1))); + bool local = ( (size_t)(seg->index()[0]) == cluster_id ); + + for ( uint64_t addr = seg->baseAddress() & ~(m_rt_size-1); + addr < (seg->baseAddress() + seg->size()); addr += m_rt_size ) { - if ( done[addr] && adt[addr] != i->cacheable() ) + if ( done[addr] && adt[addr] != local ) { - std::ostringstream oss; - oss << "Incoherent Mapping Table:" << std::endl - << "Segment " << *i - << " has different cacheability than other segment with same mask" - << std::endl - << "Mapping table:" << std::endl - << *this; - throw soclib::exception::RunTimeError(oss.str()); + std::cout << "ERROR in Mapping Table : segment " << *seg + << " allocated to a different target than another segment" + << " with the same global routing bits" << std::endl; + exit(0); } - adt.set( addr, i->cacheable() ); + adt.set( addr, local ); done.set( addr, true ); } - } + } return adt; -} +} // end getLocalMatchFromAddress() //////////////////////////////////////////////////////////// -/// This function returns an ADT that can be used to get -// the local condition from a physical address +// This function returns an ADT that can be used to get +// the "is_local" condition from the SRCID value +// in a clusterized architecture (two levels interconnect). +// Only the global bits in the SRCID are decoded. +// We do not asssume identity mapping for m_srcid_array[] //////////////////////////////////////////////////////////// -template<typename desired_addr_t> -AddressDecodingTable<desired_addr_t, bool> -MappingTable::getLocalityTable( const IntTab &index ) const +AddressDecodingTable<uint32_t, bool> +MappingTable::getLocalMatchFromSrcid( const size_t cluster_id ) const { - size_t nbits = m_level_addr_bits.sum(index.level()); + // checking two levels interconnect + if ( m_level_addr_bits.level() != 2 ) + { + std::cout << "ERROR in Mapping Table : the getLocalMatchFromSrcid() function" + << " requires a two levels interconnect" << std::endl; + exit(0); + } + + const_cast<MappingTable*>(this)->m_used = true; + + size_t global_width = m_level_id_bits[0]; // number of global bits in SRCID + size_t local_width = m_level_id_bits[1]; // number of local bits in SRCID + size_t adt_size = 1<<global_width; // number of entries in adt // ADT to be returned - AddressDecodingTable<desired_addr_t, bool> adt(nbits, m_addr_width - nbits); - adt.reset(true); + AddressDecodingTable<uint32_t, bool> + adt( global_width, local_width ); - // temporary ADT for checking - AddressDecodingTable<desired_addr_t, bool> done(nbits, m_addr_width - nbits); - done.reset(false); + // loop on all possible global index values) + for ( size_t i = 0 ; i < adt_size ; i++ ) + { + bool match = ( cluster_id == (m_srcid_array[i<<local_width]>>local_width) ); + adt.set( i<<local_width , match ); + } + return adt; +} // end getLocalMatchFromAddress() +////////////////////////////////////////////////////////////////// +// This function returns an ADT that can be used to get +// the target port index from the MSB bits of a physical address. +// It can be used in a flat (non clusterized) interconnect, +// or in a two level interconnect to perform global routing. +// Only the global bits in the address are decoded. +////////////////////////////////////////////////////////////////// +AddressDecodingTable<uint64_t, size_t> +MappingTable::getGlobalIndexFromAddress( const size_t default_id ) const +{ const_cast<MappingTable*>(this)->m_used = true; - std::list<Segment>::const_iterator i; - for ( i = m_segment_list.begin(); - i != m_segment_list.end(); - i++ ) + size_t global_bits = m_level_addr_bits[0]; + + // ADT to be returned + AddressDecodingTable<uint64_t, size_t> + adt( global_bits, m_addr_width - global_bits ); + adt.reset( default_id ); + + // temporary ADT for checking + AddressDecodingTable<uint64_t, bool> + done( global_bits, m_addr_width - global_bits ); + done.reset(false); + + // loop on all segments + std::list<Segment>::const_iterator seg; + for ( seg = m_segment_list.begin(); + seg != m_segment_list.end(); + seg++ ) { - for ( desired_addr_t addr = i->baseAddress() & ~(m_rt_size-1); - (addr < i->baseAddress()+i->size()) && - (addr >= (i->baseAddress() & ~(m_rt_size-1))); + size_t global_id = (size_t)(seg->index()[0]); + + for ( uint64_t addr = seg->baseAddress() & ~(m_rt_size-1); + addr < (seg->baseAddress() + seg->size()); addr += m_rt_size ) { - bool val = (i->index().idMatches(index) ); - - if ( done[addr] && adt[addr] != val ) + if ( done[addr] && adt[addr] != global_id ) { - std::ostringstream oss; - oss << "Incoherent Mapping Table:" << std::endl - << "Segment " << *i - << " targets different component than other segments with same MSBs" - << std::endl - << "Mapping table:" << std::endl - << *this; - throw soclib::exception::RunTimeError(oss.str()); + std::cout << "ERROR in Mapping Table : segment " << *seg + << " allocated to a different target than another segment" + << " with the same global routing bits" << std::endl; + exit(0); } - adt.set( addr, val ); + adt.set( addr, global_id ); done.set( addr, true ); } } return adt; -} +} // end getGlobaIndexFromAddress() -/////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// // This function returns an ADT that can be used to get -// the target port index from a physical address -/////////////////////////////////////////////////////////// -template<typename desired_addr_t> -AddressDecodingTable<desired_addr_t, int> -MappingTable::getRoutingTable( const IntTab &index, int default_index ) const +// the initiator port index from the MSB bits of a SRCID. +// It can be used in a flat (non clusterized) interconnect, +// or in a two level interconnect to perform global routing. +// Only the global bits in the SRCID are decoded. +////////////////////////////////////////////////////////////////// +AddressDecodingTable<uint32_t, size_t> +MappingTable::getGlobalIndexFromSrcid() const { -#ifdef SOCLIB_MODULE_DEBUG - std::cout << __FUNCTION__ << std::endl; -#endif - size_t before = m_level_addr_bits.sum(index.level()); - size_t at = m_level_addr_bits[index.level()]; + const_cast<MappingTable*>(this)->m_used = true; + + size_t global_width = m_level_id_bits[0]; + size_t local_width = m_srcid_width - global_width; + size_t adt_size = 1<<global_width; // ADT to be returned - AddressDecodingTable<desired_addr_t, int> adt(at, m_addr_width - at - before); - adt.reset(default_index); + AddressDecodingTable<uint32_t, size_t> + adt( global_width, local_width ); + + // loop on all possible global index values) + for ( size_t i = 0 ; i < adt_size ; i++ ) + { + size_t global_id = m_srcid_array[i<<local_width]>>local_width; + adt.set( i<<local_width , global_id ); + } + return adt; +} // end getGlobaIndexFromSrcid() + +//////////////////////////////////////////////////////////////////////// +// This function returns an ADT that can be used to get +// the cacheability attribute from a physical address. +// Only the bits corresponding to the cacheability mask are decoded. +//////////////////////////////////////////////////////////////////////// +AddressDecodingTable<uint64_t, bool> +MappingTable::getCacheabilityTable() const +{ + // ADT to be returned + AddressDecodingTable<uint64_t, bool> + adt(m_cacheability_mask); + adt.reset(false); // temporary ADT for checking - AddressDecodingTable<desired_addr_t, bool> done(at, m_addr_width - at - before); + AddressDecodingTable<uint64_t, bool> + done(m_cacheability_mask); done.reset(false); const_cast<MappingTable*>(this)->m_used = true; - std::list<Segment>::const_iterator i; - for ( i = m_segment_list.begin(); - i != m_segment_list.end(); - i++ ) + // loop on all segments + std::list<Segment>::const_iterator seg; + for ( seg = m_segment_list.begin(); + seg != m_segment_list.end(); + seg++ ) { -#ifdef SOCLIB_MODULE_DEBUG - std::cout << *i - << ", m_rt_size=" << m_rt_size - << ", m_rt_mask=" << ~(m_rt_size-1) - << std::endl; -#endif - if ( ! i->index().idMatches(index) ) - { -#ifdef SOCLIB_MODULE_DEBUG - std::cout << i->index() << " does not match " << index << std::endl; -#endif - continue; - } - - #ifdef SOCLIB_MODULE_DEBUG - std::cout - << ' ' << (i->baseAddress() & ~(m_rt_size-1)) - << ' ' << (i->baseAddress() + i->size()) - << ' ' << (((i->baseAddress() & ~(m_rt_size-1)) < i->baseAddress()+i->size())) - << ' ' << (((i->baseAddress() & ~(m_rt_size-1)) >= (i->baseAddress() & ~(m_rt_size-1)))) - << std::endl; - #endif - - for ( desired_addr_t addr = i->baseAddress() & ~(m_rt_size-1); - (addr < i->baseAddress()+i->size()) && - (addr >= (i->baseAddress() & ~(m_rt_size-1))); + for ( uint64_t addr = seg->baseAddress() & ~(m_rt_size-1); + addr < (seg->baseAddress() + seg->size()); addr += m_rt_size ) { - int val = i->index()[index.level()]; - - #ifdef SOCLIB_MODULE_DEBUG - std::cout << addr << " -> " << val << std::endl; - #endif - - if ( done[addr] && adt[addr] != val ) + if ( done[addr] and adt[addr] != seg->cacheable() ) { - std::ostringstream oss; - oss << "Incoherent Mapping Table: for " << index << std::endl - << "Segment " << *i << " targets different target (or cluster) than other segments with same routing bits" << std::endl - << "Mapping table:" << std::endl - << *this; - throw soclib::exception::RunTimeError(oss.str()); + std::cout << "ERROR in Mapping Table : segment " << *seg + << " has different cacheability than other segment " + << " with the same cacheability mask" << std::endl; + exit(0); } - adt.set( addr, val ); + adt.set( addr, seg->cacheable() ); done.set( addr, true ); } -#ifdef SOCLIB_MODULE_DEBUG - std::cout << std::endl; -#endif - } + } return adt; -} +} // end getCacheabilityFromAddress() ////////////////////////////////////////////////// void MappingTable::print( std::ostream &o ) const +////////////////////////////////////////////////// { std::list<Segment>::const_iterator i; @@ -480,64 +543,12 @@ void MappingTable::print( std::ostream &o ) const << std::endl; for ( i = m_segment_list.begin(); i != m_segment_list.end(); - i++ ) { + i++ ) + { o << " " << (*i) << std::endl; } } -///////////////////////////////////////////////////////// -AddressMaskingTable<uint32_t> -MappingTable::getIdMaskingTable( const int level ) const -{ - int use = m_level_id_bits[level]; - int drop = 0; - const_cast<MappingTable*>(this)->m_used = true; - - for ( size_t i=level+1; i<m_level_id_bits.level(); ++i ) - drop += m_level_id_bits[i]; - return AddressMaskingTable<uint32_t>( use, drop ); -} - -///////////////////////////////////// -AddressDecodingTable<uint32_t, bool> -MappingTable::getIdLocalityTable( const IntTab &index ) const -{ - size_t nbits = m_level_id_bits.sum(index.level()); - size_t id_width = m_level_id_bits.sum(); - IntTab complete_index(index, 0); - uint32_t match = (uint32_t)indexForId(complete_index); - const_cast<MappingTable*>(this)->m_used = true; - - AddressDecodingTable<uint32_t, bool> adt(nbits, id_width-nbits); - adt.reset(false); - adt.set(match, true); - return adt; -} - -template -AddressDecodingTable<uint64_t, bool> -MappingTable::getCacheabilityTable<uint64_t>() const; - -template -AddressDecodingTable<uint64_t, bool> -MappingTable::getLocalityTable<uint64_t>( const IntTab &index ) const; - -template -AddressDecodingTable<uint64_t, int> -MappingTable::getRoutingTable<uint64_t>( const IntTab &index, int default_index ) const; - -template -AddressDecodingTable<uint32_t, bool> -MappingTable::getCacheabilityTable<uint32_t>() const; - -template -AddressDecodingTable<uint32_t, bool> -MappingTable::getLocalityTable<uint32_t>( const IntTab &index ) const; - -template -AddressDecodingTable<uint32_t, int> -MappingTable::getRoutingTable<uint32_t>( const IntTab &index, int default_index ) const; - }} // Local Variables: diff --git a/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/include/vci_xcache_wrapper.h b/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/include/vci_xcache_wrapper.h index b65fd105da6d9fdb64ed7e7c2dbd8d0966d4bd9d..20534945aeda79daef23c98043acec1b334c2c52 100644 --- a/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/include/vci_xcache_wrapper.h +++ b/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/include/vci_xcache_wrapper.h @@ -106,7 +106,7 @@ public: private: // STRUCTURAL PARAMETERS - const soclib::common::AddressDecodingTable<uint32_t, bool> m_cacheability_table; + const soclib::common::AddressDecodingTable<uint64_t, bool> m_cacheability_table; iss_t m_iss; const uint32_t m_srcid; @@ -123,6 +123,10 @@ private: typename iss_t::DataRequest m_dreq; typename iss_t::DataResponse m_drsp; + // Debug variables + bool m_debug_previous_i_hit; + bool m_debug_previous_d_hit; + // REGISTERS sc_signal<int> r_dcache_fsm; sc_signal<addr_t> r_dcache_addr_save; // request address @@ -168,7 +172,6 @@ private: // Activity counters uint32_t m_cpt_icache_read; // ICACHE READ uint32_t m_cpt_icache_write; // ICACHE WRITE - uint32_t m_cpt_dcache_read; // DCACHE READ uint32_t m_cpt_dcache_write; // DCACHE WRITE @@ -180,24 +183,18 @@ private: uint32_t m_cpt_write; // total number of write instructions uint32_t m_cpt_data_miss; // number of read miss uint32_t m_cpt_ins_miss; // number of instruction miss - uint32_t m_cpt_unc_read; // number of read uncached + uint32_t m_cpt_data_unc; // number of data read/write uncached + uint32_t m_cpt_ins_unc; // number of instruction uncached uint32_t m_cpt_write_cached; // number of cached write uint32_t m_cost_write_frz; // frozen cycles related to write buffer uint32_t m_cost_data_miss_frz; // frozen cycles related to data miss - uint32_t m_cost_unc_read_frz; // frozen cycles related to uncached read uint32_t m_cost_ins_miss_frz; // frozen cycles related to ins miss + uint32_t m_cost_data_unc_frz; // frozen cycles related to uncached R/W + uint32_t m_cost_ins_unc_frz; // frozen cycles related to uncached ins - uint32_t m_cpt_imiss_transaction; // VCI instruction miss transactions - uint32_t m_cpt_dmiss_transaction; // VCI data miss transactions - uint32_t m_cpt_unc_transaction; // VCI uncached read transactions uint32_t m_cpt_write_transaction; // VCI write transactions - - uint32_t m_cost_imiss_transaction; // cumulated duration IMISS transactions - uint32_t m_cost_dmiss_transaction; // cumulated duration DMISS transactions - uint32_t m_cost_unc_transaction; // cumulated duration UNC transactions - uint32_t m_cost_write_transaction; // cumulated duration WRITE transactions - uint32_t m_length_write_transaction; // cumulated length WRITE transactions + uint32_t m_length_write_transaction; // cumulated length VCI write transactions protected: @@ -221,10 +218,10 @@ public: void print_cpi(); void print_stats(); - void print_latency();//DG void print_trace(size_t mode = 0); void file_stats(FILE* file); void file_trace(FILE* file); + void cache_monitor( addr_t addr); private: diff --git a/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/src/vci_xcache_wrapper.cpp b/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/src/vci_xcache_wrapper.cpp index 3ffbaa0f66cfa9a46cec812d2efc47dde102b8ac..7bab94440e3ff0a1564860df3744750499109a81 100644 --- a/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/src/vci_xcache_wrapper.cpp +++ b/MPSoC/soclib/soclib/module/internal_component/vci_xcache_wrapper/caba/source/src/vci_xcache_wrapper.cpp @@ -1,4 +1,3 @@ - /* -*- c++ -*- * * SOCLIB_LGPL_HEADER_BEGIN @@ -187,8 +186,9 @@ tmpl(/**/)::VciXcacheWrapper( r_icache("icache", icache_ways, icache_sets, icache_words), r_dcache("dcache", dcache_ways, dcache_sets, dcache_words) { - assert((icache_words*vci_param::B) < (1<<vci_param::K) and "I need more PLEN bits"); + std::cout << " - Building VciXcacheWrapper " << name << std::endl; + assert((icache_words*vci_param::B) < (1<<vci_param::K) and "I need more PLEN bits"); SC_METHOD(transition); dont_initialize(); @@ -213,7 +213,51 @@ tmpl(/**/)::VciXcacheWrapper( tmpl(/**/)::~VciXcacheWrapper() ///////////////////////////////// { - print_stats(); +} + +////////////////////////////////////////// +tmpl(void)::cache_monitor( addr_t addr ) +////////////////////////////////////////// +{ + bool cache_hit; + size_t cache_way = 0; + size_t cache_set = 0; + size_t cache_word = 0; + uint32_t cache_rdata = 0; + + cache_hit = r_dcache.read_neutral( addr, + &cache_rdata, + &cache_way, + &cache_set, + &cache_word ); + + if ( cache_hit != m_debug_previous_d_hit ) + { + std::cout << "Monitor PROC " << name() + << " DCACHE at cycle " << std::dec << m_cpt_total_cycles + << " / HIT = " << cache_hit + << " / PADDR = " << std::hex << addr + << " / DATA = " << cache_rdata + << " / WAY = " << cache_way << std::endl; + m_debug_previous_d_hit = cache_hit; + } + + cache_hit = r_icache.read_neutral( addr, + &cache_rdata, + &cache_way, + &cache_set, + &cache_word ); + + if ( cache_hit != m_debug_previous_i_hit ) + { + std::cout << "Monitor PROC " << name() + << " ICACHE at cycle " << std::dec << m_cpt_total_cycles + << " / HIT = " << cache_hit + << " / PADDR = " << std::hex << addr + << " / DATA = " << cache_rdata + << " / WAY = " << cache_way << std::endl; + m_debug_previous_i_hit = cache_hit; + } } ////////////////////////////////// @@ -236,14 +280,14 @@ tmpl(void)::file_stats(FILE* file) ////////////////////////////////// { float imiss_rate = (float)m_cpt_ins_miss / (float)(m_cpt_exec_ins); - float dmiss_rate = (float)m_cpt_data_miss / (float)(m_cpt_read - m_cpt_unc_read); + float dmiss_rate = (float)m_cpt_data_miss / (float)(m_cpt_read); float cpi = (float)m_cpt_total_cycles / (float)(m_cpt_exec_ins); fprintf(file,"%8d %8d %8d %8d %8d %f %f %f \n", m_cpt_total_cycles, m_cpt_exec_ins, m_cpt_ins_miss, - m_cpt_read-m_cpt_unc_read, + m_cpt_read, m_cpt_data_miss, imiss_rate, dmiss_rate, @@ -257,29 +301,25 @@ tmpl(void)::print_cpi() << (float)m_cpt_total_cycles/(float)(m_cpt_exec_ins) << std::endl; } - //////////////////////// tmpl(void)::print_stats() //////////////////////// { - std::cout << "------------------------------------" << std:: dec << std::endl; - std::cout << name() << " / Time = " << m_cpt_total_cycles << std::endl; - std::cout << "- CPI = " << (float)m_cpt_total_cycles/m_cpt_exec_ins << std::endl ; - std::cout << "- READ RATE = " << (float)m_cpt_read/m_cpt_exec_ins << std::endl ; - std::cout << "- WRITE RATE = " << (float)m_cpt_write/m_cpt_exec_ins << std::endl; - std::cout << "- UNCACHED READ RATE = " << (float)m_cpt_unc_read/m_cpt_read << std::endl ; - std::cout << "- CACHED WRITE RATE = " << (float)m_cpt_write_cached/m_cpt_write << std::endl ; - std::cout << "- IMISS_RATE = " << (float)m_cpt_ins_miss/m_cpt_exec_ins << std::endl; - std::cout << "- DMISS RATE = " << (float)m_cpt_data_miss/(m_cpt_read-m_cpt_unc_read) << std::endl ; - std::cout << "- INS MISS COST = " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl; - std::cout << "- IMISS TRANSACTION = " << (float)m_cost_imiss_transaction/m_cpt_imiss_transaction << std::endl; - std::cout << "- DMISS COST = " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl; - std::cout << "- DMISS TRANSACTION = " << (float)m_cost_dmiss_transaction/m_cpt_dmiss_transaction << std::endl; - std::cout << "- UNC COST = " << (float)m_cost_unc_read_frz/m_cpt_unc_read << std::endl; - std::cout << "- UNC TRANSACTION = " << (float)m_cost_unc_transaction/m_cpt_unc_transaction << std::endl; - std::cout << "- WRITE COST = " << (float)m_cost_write_frz/m_cpt_write << std::endl; - std::cout << "- WRITE TRANSACTION = " << (float)m_cost_write_transaction/m_cpt_write_transaction << std::endl; - std::cout << "- WRITE LENGTH = " << (float)m_length_write_transaction/m_cpt_write_transaction << std::endl; + std::cout << "------------------------------------" << std:: dec << std::endl + << name() << " / Time = " << m_cpt_total_cycles << std::endl + << "- CPI = " << (float)m_cpt_total_cycles/m_cpt_exec_ins << std::endl + << "- READ RATE = " << (float)m_cpt_read/m_cpt_exec_ins << std::endl + << "- WRITE RATE = " << (float)m_cpt_write/m_cpt_exec_ins << std::endl + << "- UNC RATE = " << (float)m_cpt_data_unc/m_cpt_exec_ins << std::endl + << "- CACHED WRITE RATE = " << (float)m_cpt_write_cached/m_cpt_write << std::endl + << "- IMISS_RATE = " << (float)m_cpt_ins_miss/m_cpt_exec_ins << std::endl + << "- DMISS RATE = " << (float)m_cpt_data_miss/m_cpt_read << std::endl + << "- INS MISS COST = " << (float)m_cost_ins_miss_frz/m_cpt_ins_miss << std::endl + << "- DMISS COST = " << (float)m_cost_data_miss_frz/m_cpt_data_miss << std::endl + << "- UNC COST = " << (float)m_cost_data_unc_frz/m_cpt_data_unc << std::endl + << "- WRITE COST = " << (float)m_cost_write_frz/m_cpt_write << std::endl + << "- WRITE LENGTH = " << (float)m_length_write_transaction/m_cpt_write_transaction + << std::endl; } //////////////////////////////////// tmpl(void)::print_trace(size_t mode) @@ -350,6 +390,10 @@ tmpl(void)::transition() r_icache_updated = false; r_dcache_updated = false; + // Debug variables + m_debug_previous_i_hit = false; + m_debug_previous_d_hit = false; + // activity counters m_cpt_dcache_read = 0; m_cpt_dcache_write = 0; @@ -363,23 +407,17 @@ tmpl(void)::transition() m_cpt_write = 0; m_cpt_data_miss = 0; m_cpt_ins_miss = 0; - m_cpt_unc_read = 0; + m_cpt_data_unc = 0; + m_cpt_ins_unc = 0; m_cpt_write_cached = 0; m_cost_write_frz = 0; m_cost_data_miss_frz = 0; - m_cost_unc_read_frz = 0; + m_cost_data_unc_frz = 0; m_cost_ins_miss_frz = 0; + m_cost_ins_unc_frz = 0; - m_cpt_imiss_transaction = 0; - m_cpt_dmiss_transaction = 0; - m_cpt_unc_transaction = 0; m_cpt_write_transaction = 0; - - m_cost_imiss_transaction = 0; - m_cost_dmiss_transaction = 0; - m_cost_unc_transaction = 0; - m_cost_write_transaction = 0; m_length_write_transaction = 0; return; @@ -394,14 +432,14 @@ tmpl(void)::transition() bool vci_rsp_fifo_data_put = false; data_t vci_rsp_fifo_data_data = 0; - #ifdef SOCLIB_MODULE_DEBUG +#ifdef SOCLIB_MODULE_DEBUG std::cout << name() << " dcache fsm: " << dcache_fsm_state_str[r_data_fsm] << " icache fsm: " << icache_fsm_state_str[r_icache_fsm] << " cmd fsm: " << cmd_fsm_state_str[r_vci_cmd_fsm] << " rsp fsm: " << rsp_fsm_state_str[r_vci_rsp_fsm] << std::endl; - #endif +#endif m_cpt_total_cycles++; @@ -439,7 +477,7 @@ tmpl(void)::transition() m_irsp.instruction = 0; switch(r_icache_fsm) - { + { ///////////////// case ICACHE_IDLE: { @@ -450,7 +488,7 @@ tmpl(void)::transition() m_cpt_icache_read++; - bool icache_cacheable = m_cacheability_table[m_ireq.addr]; + bool icache_cacheable = m_cacheability_table[(uint64_t)m_ireq.addr]; if ( icache_cacheable ) // cacheable access { @@ -473,6 +511,9 @@ tmpl(void)::transition() } else // non cacheable access { + m_cpt_ins_unc++; + m_cost_ins_unc_frz++; + r_icache_addr_save = m_ireq.addr; r_icache_fsm = ICACHE_UNC_WAIT; r_icache_unc_req = true; @@ -523,7 +564,8 @@ tmpl(void)::transition() { m_irsp.valid = true; m_irsp.error = true; - r_vci_rsp_ins_error = false; + r_vci_rsp_ins_error = false; + r_icache_fsm = ICACHE_IDLE; } else if ( r_vci_rsp_fifo_ins.rok() ) // available instruction { @@ -561,7 +603,8 @@ tmpl(void)::transition() else if ( r_vci_rsp_fifo_ins.rok() ) // instruction available { vci_rsp_fifo_ins_get = true; - if ( m_ireq.valid and (m_ireq.addr == r_icache_addr_save.read()) ) // unmodified + if ( m_ireq.valid and + (m_ireq.addr == r_icache_addr_save.read()) ) // unmodified { m_irsp.valid = true; m_irsp.instruction = r_vci_rsp_fifo_ins.read(); @@ -646,7 +689,6 @@ tmpl(void)::transition() ///////////////// case DCACHE_IDLE: { - if ( m_dreq.valid ) { bool dcache_cacheable; @@ -682,6 +724,8 @@ tmpl(void)::transition() if ( m_dreq.type == iss_t::DATA_READ ) // cacheable read { + m_cpt_read++; + if ( not dcache_hit ) // read miss { m_cpt_data_miss++; @@ -702,6 +746,8 @@ tmpl(void)::transition() } else if ( m_dreq.type == iss_t::DATA_WRITE ) // cacheable write { + m_cpt_write++; + if ( not dcache_hit ) // write miss { m_drsp.valid = true; @@ -709,6 +755,8 @@ tmpl(void)::transition() } else // write hit { + m_cpt_write_cached++; + m_drsp.valid = true; r_dcache_fsm = DCACHE_WRITE_UPDT; r_dcache_way_save = dcache_way; @@ -726,7 +774,6 @@ tmpl(void)::transition() } else // uncacheable request { - r_dcache_cacheable_save = false; switch( m_dreq.type ) { // we expect a single word rdata for these 3 requests @@ -734,8 +781,8 @@ tmpl(void)::transition() case iss_t::DATA_LL: case iss_t::DATA_SC: { - m_cpt_unc_read++; - m_cost_unc_read_frz++; + m_cpt_data_unc++; + m_cost_data_unc_frz++; r_dcache_unc_req = true; r_dcache_addr_save = m_dreq.addr; @@ -774,7 +821,7 @@ tmpl(void)::transition() } case iss_t::DATA_WRITE: { - m_cpt_write++; + m_cpt_data_unc++; r_dcache_fsm = DCACHE_WRITE_REQ; m_drsp.valid = true; @@ -843,10 +890,10 @@ tmpl(void)::transition() if ( r_vci_rsp_data_error.read() ) // error reported { - assert(m_dreq.valid); m_drsp.valid = true; m_drsp.error = true; r_vci_rsp_data_error = false; + r_dcache_fsm = DCACHE_IDLE; } else if ( r_vci_rsp_fifo_data.rok() ) // available data { @@ -872,22 +919,21 @@ tmpl(void)::transition() ///////////////////// case DCACHE_UNC_WAIT: // wait rdata for LL, SC, or uncacheable read { - m_cost_unc_read_frz++; + m_cost_data_unc_frz++; if ( r_vci_rsp_data_error.read() ) // error reported { - r_vci_rsp_data_error = false; - assert(m_dreq.valid); m_drsp.valid = true; m_drsp.error = true; + r_vci_rsp_data_error = false; r_dcache_fsm = DCACHE_IDLE; } else if ( r_vci_rsp_fifo_data.rok() ) // available data { vci_rsp_fifo_data_get = true; - if ( m_dreq.valid and (m_dreq.addr == r_dcache_addr_save.read()) ) // request unmodified + if ( m_dreq.valid and + (m_dreq.addr == r_dcache_addr_save.read()) ) // request unmodified { - assert(m_dreq.valid); m_drsp.valid = true; m_drsp.rdata = r_vci_rsp_fifo_data.read(); } @@ -916,7 +962,6 @@ tmpl(void)::transition() else // miss : nothing to do { r_dcache_fsm = DCACHE_IDLE; - assert(m_dreq.valid); m_drsp.valid = true; } break; @@ -929,7 +974,6 @@ tmpl(void)::transition() r_dcache_set_save.read(), &nline ); r_dcache_fsm = DCACHE_IDLE; - assert(m_dreq.valid); m_drsp.valid = true; break; } @@ -939,14 +983,7 @@ tmpl(void)::transition() std::cout << name() << " Data Response: " << m_drsp << std::endl; #endif - /////////// execute one iss cycle ///////////////////////////////// - uint32_t it = 0; - for (size_t i=0; i<(size_t)iss_t::n_irq; i++) - { - if(p_irq[i].read()) it |= (1<<i); - } - m_iss.executeNCycles(1, m_irsp, m_drsp, it); - + ////////// Compute number of executed instructions //////////////// if ( (m_ireq.valid and m_irsp.valid) and (!m_dreq.valid or m_drsp.valid) and (m_ireq.addr != m_pc_previous) ) @@ -955,6 +992,14 @@ tmpl(void)::transition() m_pc_previous = m_ireq.addr; } + /////////// execute one iss cycle ///////////////////////////////// + uint32_t it = 0; + for (size_t i=0; i<(size_t)iss_t::n_irq; i++) + { + if(p_irq[i].read()) it |= (1<<i); + } + m_iss.executeNCycles(1, m_irsp, m_drsp, it); + //////////////////////////////////////////////////////////////////////////// // This FSM handles requests from both the DCACHE FSM & the ICACHE FSM. // There is 5 request types, with the following priorities : @@ -985,13 +1030,11 @@ tmpl(void)::transition() r_vci_cmd_cpt = 0; if ( r_icache_miss_req ) { - m_cpt_imiss_transaction++; r_vci_cmd_fsm = CMD_INS_MISS; r_icache_miss_req = false; } else if ( r_icache_unc_req ) { - m_cpt_imiss_transaction++; r_vci_cmd_fsm = CMD_INS_UNC; r_icache_unc_req = false; } @@ -1006,14 +1049,11 @@ tmpl(void)::transition() } else if ( r_dcache_miss_req ) { - m_cpt_dmiss_transaction++; - r_vci_cmd_fsm = CMD_DATA_MISS; r_dcache_miss_req = false; } else if ( r_dcache_unc_req ) { - m_cpt_unc_transaction++; r_vci_cmd_fsm = CMD_DATA_UNC; r_dcache_unc_req = false; } @@ -1089,7 +1129,6 @@ tmpl(void)::transition() ////////////////// case RSP_INS_MISS: { - m_cost_imiss_transaction++; if ( p_vci.rspval.read() ) { if ( (p_vci.rerror.read()&0x1) != 0 ) // error reported @@ -1101,15 +1140,15 @@ tmpl(void)::transition() { if ( r_vci_rsp_fifo_ins.wok() ) { - assert( (r_vci_rsp_cpt.read() < m_dcache_words) and - "The VCI response packet for data miss is too long"); + assert( (r_vci_rsp_cpt.read() < m_icache_words) and + "The VCI response packet for instruction miss is too long"); r_vci_rsp_cpt = r_vci_rsp_cpt.read() + 1; vci_rsp_fifo_ins_put = true, vci_rsp_fifo_ins_data = p_vci.rdata.read(); if ( p_vci.reop.read() ) { - assert( (r_vci_rsp_cpt.read() == m_dcache_words - 1) and - "The VCI response packet for data miss is too short"); + assert( (r_vci_rsp_cpt.read() == (m_icache_words - 1)) and + "The VCI response packet for instruction miss is too short"); r_vci_rsp_fsm = RSP_IDLE; } } @@ -1120,7 +1159,6 @@ tmpl(void)::transition() ///////////////// case RSP_INS_UNC: { - m_cost_imiss_transaction++; if ( p_vci.rspval.read() ) { assert(p_vci.reop.read() and @@ -1145,7 +1183,6 @@ tmpl(void)::transition() /////////////////// case RSP_DATA_MISS: { - m_cost_dmiss_transaction++; if ( p_vci.rspval.read() ) { if ( (p_vci.rerror.read()&0x1) != 0 ) // error reported @@ -1176,7 +1213,6 @@ tmpl(void)::transition() //////////////////// case RSP_DATA_WRITE: { - m_cost_write_transaction++; if ( p_vci.rspval.read() ) { if ( (p_vci.rerror.read() & 0x1) == 0x1 ) m_iss.setWriteBerr(); @@ -1187,7 +1223,6 @@ tmpl(void)::transition() ////////////////// case RSP_DATA_UNC: { - m_cost_dmiss_transaction++; if ( p_vci.rspval.read() ) { assert(p_vci.reop.read() and @@ -1219,7 +1254,7 @@ tmpl(void)::transition() r_vci_rsp_fifo_data.update(vci_rsp_fifo_data_get, vci_rsp_fifo_data_put, vci_rsp_fifo_data_data); - + } // end transition() ////////////////////////////////////////////////////////////////////////////////// diff --git a/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/metadata/vci_local_crossbar.sd b/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/metadata/vci_local_crossbar.sd index 707d579f060027cd4d453b9eb5f3c52db26ace39..393e3370b8af9cc0d7daf195654cf2a82ce3913c 100644 --- a/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/metadata/vci_local_crossbar.sd +++ b/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/metadata/vci_local_crossbar.sd @@ -1,16 +1,20 @@ # -*- python -*- -__id__ = "$Id: vci_local_crossbar.sd 1711 2010-04-20 10:30:27Z nipo $" -__version__ = "$Revision: 1711 $" +__id__ = "$Id: vci_local_crossbar.sd 2582 2015-01-19 09:09:29Z meunier $" +__version__ = "$Revision: 2582 $" Module('caba:vci_local_crossbar', classname = 'soclib::caba::VciLocalCrossbar', - tmpl_parameters = [ - parameter.Module('vci_param', default = 'caba:vci_param'), + tmpl_parameters = [ + parameter.Module('vci_param', default = 'caba:vci_param'), ], - header_files = ['../source/include/vci_local_crossbar.h',], - implementation_files = ['../source/src/vci_local_crossbar.cpp',], + header_files = [ + '../source/include/vci_local_crossbar.h', + ], + implementation_files = [ + '../source/src/vci_local_crossbar.cpp', + ], ports = [ Port('caba:vci_initiator', 'p_to_target', parameter.Reference('nb_attached_target')), Port('caba:vci_target', 'p_to_initiator', parameter.Reference('nb_attached_initiator')), @@ -21,21 +25,25 @@ Module('caba:vci_local_crossbar', ], instance_parameters = [ parameter.Module('mt', typename = 'common:mapping_table'), - parameter.IntTab('tgtid'), - parameter.IntTab('srcid'), - parameter.Int('nb_attached_initiator'), - parameter.Int('nb_attached_target'), + parameter.Int('cluster_id'), + parameter.Int('nb_attached_initiators'), + parameter.Int('nb_attached_targets'), + parameter.Int('default_target_id'), ], uses = [ Uses('caba:base_module'), Uses('common:mapping_table'), Uses('caba:vci_buffers'), - ], - extensions = [ - 'dsx:interconnect', - 'dsx:mapping_type=interconnect', - 'dsx:get_ident=srcid:p_initiator_to_up:mt,tgtid:p_target_to_up:mt', - 'dsx:obtain_ident_method=port', - 'dsx:interconnect_port_assoc=p_to_initiator:p_initiator_to_up,p_to_target:p_target_to_up' + Uses('common:address_decoding_table', input_t = 'uint64_t', output_t = 'size_t'), + Uses('common:address_decoding_table', input_t = 'uint64_t', output_t = 'bool'), + Uses('common:address_decoding_table', input_t = 'uint32_t', output_t = 'size_t'), + Uses('common:address_decoding_table', input_t = 'uint32_t', output_t = 'bool'), + ], + extensions = [ + 'dsx:interconnect', + 'dsx:mapping_type=interconnect', + 'dsx:get_ident=srcid:p_initiator_to_up:mt,tgtid:p_target_to_up:mt', + 'dsx:obtain_ident_method=port', + 'dsx:interconnect_port_assoc=p_to_initiator:p_initiator_to_up,p_to_target:p_target_to_up' ], ) diff --git a/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/include/vci_local_crossbar.h b/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/include/vci_local_crossbar.h index d090f4f7eb790f36920596d11e5d187526d25952..54e450eaff0c0cc12e8d9318f24d2f2dda574267 100644 --- a/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/include/vci_local_crossbar.h +++ b/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/include/vci_local_crossbar.h @@ -21,12 +21,12 @@ * SOCLIB_LGPL_HEADER_END * * Copyright (c) UPMC, Lip6, Asim + * Alain Greiner <alain.greiner@lip6.fr>, 2005 * Nicolas Pouillon <nipo@ssji.net>, 2008 * - * Based on previous works by Alain Greiner, 2005 - * - * Maintainers: nipo + * Maintainers: alain */ + #ifndef SOCLIB_CABA_VCI_LOCAL_CROSSBAR_H_ #define SOCLIB_CABA_VCI_LOCAL_CROSSBAR_H_ @@ -36,54 +36,62 @@ #include "vci_target.h" #include "vci_buffers.h" #include "mapping_table.h" +#include "address_decoding_table.h" namespace soclib { namespace caba { -namespace _local_crossbar { -template<typename pkt_t> class Crossbar; -} +using namespace soclib::common; +template<typename pkt_t> class SimpleCrossbar; + +//////////////////////////////////// template<typename vci_param> class VciLocalCrossbar +//////////////////////////////////// : public BaseModule { public: - sc_in<bool> p_clk; - sc_in<bool> p_resetn; - VciInitiator<vci_param> *p_to_target; - VciTarget<vci_param> *p_to_initiator; - VciTarget<vci_param> p_target_to_up; - VciInitiator<vci_param> p_initiator_to_up; + sc_in<bool> p_clk; + sc_in<bool> p_resetn; + + VciInitiator<vci_param> *p_to_target; + VciTarget<vci_param> *p_to_initiator; + VciTarget<vci_param> p_target_to_up; + VciInitiator<vci_param> p_initiator_to_up; private: - size_t m_nb_attached_initiat; - size_t m_nb_attached_target; - VciInitiator<vci_param> **m_ports_to_target; - VciTarget<vci_param> **m_ports_to_initiator; + size_t m_nb_attached_initiators; + size_t m_nb_attached_targets; - typedef _local_crossbar::Crossbar<VciCmdBuffer<vci_param> > cmd_crossbar_t; - typedef _local_crossbar::Crossbar<VciRspBuffer<vci_param> > rsp_crossbar_t; + AddressDecodingTable<uint64_t, size_t> m_cmd_rt; // command routing table + AddressDecodingTable<uint64_t, bool> m_cmd_lt; // command locality table + + AddressDecodingTable<uint32_t, size_t> m_rsp_rt; // response routing table + AddressDecodingTable<uint32_t, bool> m_rsp_lt; // response locality table + + VciInitiator<vci_param> **m_ports_to_target; + VciTarget<vci_param> **m_ports_to_initiator; + + SimpleCrossbar<VciCmdBuffer<vci_param> > *m_cmd_crossbar; + SimpleCrossbar<VciRspBuffer<vci_param> > *m_rsp_crossbar; void transition(); void genMealy(); - cmd_crossbar_t *m_cmd_crossbar; - rsp_crossbar_t *m_rsp_crossbar; - protected: SC_HAS_PROCESS(VciLocalCrossbar); public: void print_trace(); - VciLocalCrossbar( sc_module_name name, - const soclib::common::MappingTable &mt, - const soclib::common::IntTab &srcid, - const soclib::common::IntTab &tgtid, - size_t nb_attached_initiat, - size_t nb_attached_target ); + VciLocalCrossbar( sc_core::sc_module_name name, + const soclib::common::MappingTable &mt, + const size_t cluster_id, + const size_t nb_attached_initiators, + const size_t nb_attached_targets, + const size_t default_target_id ); ~VciLocalCrossbar(); }; diff --git a/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/src/vci_local_crossbar.cpp b/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/src/vci_local_crossbar.cpp index 22a02537e5341d461983b063b850ca4db2bd31e5..f46f4dfbaade38ed83513aa8095d9188e0d1a861 100644 --- a/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/src/vci_local_crossbar.cpp +++ b/MPSoC/soclib/soclib/module/network_component/vci_local_crossbar/caba/source/src/vci_local_crossbar.cpp @@ -20,47 +20,45 @@ * SOCLIB_LGPL_HEADER_END * * Copyright (c) UPMC, Lip6, Asim - Alain Greiner <alain.greiner@lip6.fr> 2005 & 2011 + Alain Greiner <alain.greiner@lip6.fr> 2005 * Nicolas Pouillon <nipo@ssji.net>, 2008 * - * Maintainers: nipo, alain + * Maintainers: alain */ /////////////////////////////////////////////////////////////////////////// // Implementation Note : -// This component is implemented as two independant crossbars, -// for VCI commands and VCI responses respectively. +// This component is implemented as two independant combinational +// crossbars, for VCI commands and VCI responses respectively. // - The CMD crossbar has NI local plus one global input // ports. It has NT local + one global output ports. -// - The RSP crossbar has NT target local plus one global input +// - The RSP crossbar has NT local plus one global input // ports. It has NI local + one global output ports. // For each generic crossbar, the input and output ports are impemented // as arrays of ports, and the last port (i.e. the largest index value) -// is the ports connected to the global interconnect. +// is the port connected to the global interconnect. // -// This component support single flit VCI broadcast commands : If the +// This component does not contain FIFOs, and behaves as a Mealy FSM. +// +// It supportsi single flit VCI broadcast commands : If the // two lsb bits of the VCI ADDRESS are non zero, the corresponding // command is considered as a broadcast. -// As the broadcast command arriving on input port (i) should not be -// transmitted to the requester, it is not transmitted on output port (i). -// Therefore, in case of broadcast, NI & NT must be equal, and all -// connected components mus have the same index dfor input & output ports. -// -// In case of broadcast, the single VCI flit is SEQUENCIALLY transmitted +// For a broadcast, the single VCI flit is SEQUENCIALLY transmitted // to the (NT+1) output ports, but not to the requesting input port. // For each transmitted flit to a given output port, the standard // round-robin allocation policy is respected. +// As the broadcast command arriving on input port (i) should not be +// transmitted to the requester, it is not transmitted on output port (i). +// Therefore, in case of broadcast, NI & NT must be equal, and all +// connected components mus have the same index for input & output ports. /////////////////////////////////////////////////////////////////////////// #include <systemc> #include <cassert> -//#include "vci_buffers.h" -#include "./vci_buffers.h" +#include "vci_buffers.h" #include "../include/vci_local_crossbar.h" #include "alloc_elems.h" -//#define CROSSBAR_DEBUG - namespace soclib { namespace caba { using soclib::common::alloc_elems; @@ -68,85 +66,132 @@ using soclib::common::dealloc_elems; using namespace sc_core; -namespace _local_crossbar { - -/////////////////////////////////////// -template<typename pkt_t> class Crossbar -{ - typedef typename pkt_t::routing_table_t routing_table_t; - typedef typename pkt_t::locality_table_t locality_table_t; - typedef typename pkt_t::input_port_t input_port_t; - typedef typename pkt_t::output_port_t output_port_t; - - const size_t m_in_size; // total number of inputs (local + global) - const size_t m_out_size; // total number of outputs (local + global) - const routing_table_t m_rt; - const locality_table_t m_lt; - - sc_signal<bool>* r_allocated; // for each output port: allocation state +//////////////////////////////////////////////// +template<typename pkt_t> +class SimpleCrossbar +//////////////////////////////////////////////// +{ + const size_t m_cluster_id; // cluster index + const size_t m_in_size; // total number of inputs (local + global) + const size_t m_out_size; // total number of outputs (local + global) + const void* m_rt; // routing table if cmd / masking table if rsp + const void* m_lt; // locality table if cmd / id_locality table if rsp + const bool m_is_cmd; // cmd crossbar when true + + sc_signal<bool>* r_allocated; // for each output port: allocation state sc_signal<size_t>* r_origin; // for each output port: input port index sc_signal<bool>* r_bc_state; // for each input port: broadcast requested sc_signal<size_t>* r_bc_count; // for each input port: requested output index public: - ///////// - Crossbar( - size_t in_size, size_t out_size, - const routing_table_t &rt, - const locality_table_t <) - : m_in_size(in_size), - m_out_size(out_size), - m_rt(rt), - m_lt(lt) + //////////////////////////////// + SimpleCrossbar( size_t cluster_id, // cluster index + size_t in_size, // number of inputs + size_t out_size, // number of outputs + void* rt, // routing table + void* lt, // locality table + bool is_cmd ) + : m_cluster_id( cluster_id ), + m_in_size( in_size ), + m_out_size( out_size ), + m_rt( rt ), + m_lt( lt ), + m_is_cmd( is_cmd ) { r_allocated = new sc_signal<bool>[out_size]; r_origin = new sc_signal<size_t>[out_size]; - r_bc_state = new sc_signal<bool>[in_size]; + r_bc_state = new sc_signal<bool>[in_size]; r_bc_count = new sc_signal<size_t>[in_size]; - } + } // end constructor + + ~SimpleCrossbar() { + delete [] r_allocated; + delete [] r_origin; + delete [] r_bc_state; + delete [] r_bc_count; + } //////////// void reset() { - for (size_t i=0; i<m_out_size; ++i) + for (size_t i=0; i<m_out_size; ++i) { - r_origin[i] = 0; - r_allocated[i] = false; - } - for (size_t i=0; i<m_in_size; ++i) + r_origin[i] = 0; + r_allocated[i] = false; + } + for (size_t i=0; i<m_in_size; ++i) { - r_bc_state[i] = false; - r_bc_count[i] = 0; - } - } + r_bc_state[i] = false; + r_bc_count[i] = 0; + } + } // end reset() - ////////////////////////////// - void print_trace(bool command) + ////////////////// + void print_trace() { for( size_t out=0 ; out<m_out_size ; out++) { if( r_allocated[out].read() ) { - if(command) std::cout << std::dec << "target " << out - << " allocated to initiator " << r_origin[out].read() << std::endl; - else std::cout << std::dec << "initiator " << out - << " allocated to target " << r_origin[out].read() << std::endl; + if( m_is_cmd ) std::cout << std::dec + << "initiator " << r_origin[out].read() + << " => target " << out; + else std::cout << std::dec + << "target " << r_origin[out].read() + << " => initiator " << out; } } for ( size_t in=0 ; in<m_in_size ; in++) { if( r_bc_state[in].read() ) { - if(command) std::cout << " broadcast request from initiator " << in - << " requesting target " << r_bc_count[in].read() << std::endl; - else std::cout << " broadcast request from target " << in - << " requesting initiator " << r_bc_count[in].read() << std::endl; + if( m_is_cmd ) std::cout << " broadcast request from initiator " << in + << " requesting target " + << r_bc_count[in].read(); + else std::cout << " broadcast request from target " << in + << " requesting initiator " + << r_bc_count[in].read(); } } - } + } // end print_trace() - //////////////////////////////////////////////////////////////////////// - void transition( input_port_t **input_port, output_port_t **output_port ) + ////////////////////////// + size_t route( pkt_t flit ) + { + if( m_is_cmd ) // we use a 64 bits AddressDecodingTable for ADDRESS + { + soclib::common::AddressDecodingTable<uint64_t, size_t>* rt = + (soclib::common::AddressDecodingTable<uint64_t, size_t>*)m_rt; + return rt->get_value( (uint64_t)(flit.dest()) ); + } + else // we use a 32 bits AddressDecodingTable for SRCID + { + soclib::common::AddressDecodingTable<uint32_t, size_t>* rt = + (soclib::common::AddressDecodingTable<uint32_t, size_t>*)m_rt; + return rt->get_value( (uint32_t)(flit.dest()) ); + } + } // end route() + + /////////////////////////// + bool is_local( pkt_t flit ) + { + if( m_is_cmd ) // we use a 64 bits AddressDecoding Table for ADDRESS + { + soclib::common::AddressDecodingTable<uint64_t, bool>* lt = + (soclib::common::AddressDecodingTable<uint64_t, bool>*)m_lt; + return lt->get_value( (uint64_t)(flit.dest()) ); + } + else // we use a 32 bits AddressDecodingTable for SRCID + { + soclib::common::AddressDecodingTable<uint32_t, bool>* lt = + (soclib::common::AddressDecodingTable<uint32_t, bool>*)m_lt; + return lt->get_value( (uint32_t)(flit.dest()) ); + } + } // end is_local() + + ////////////////////////////////////////////////////////////// + void transition( typename pkt_t::input_port_t **input_port, + typename pkt_t::output_port_t **output_port ) { // loop on the input ports to handle r_bc_state[in] and r_bc_count[in] for( size_t in = 0 ; in < m_in_size ; in++ ) @@ -158,12 +203,12 @@ public: size_t out = r_bc_count[in]; if ( ( r_allocated[out].read() ) && ( r_origin[out].read() == in ) && - ( output_port[out]->toPeerEnd() ) ) // flit successfully transmitted + ( output_port[out]->toPeerEnd() ) ) // successfully transmitted { // the broadcast should not be sent to the requester... if ( (out == 0) || ((out == 1) && (in == 0)) ) r_bc_state[in] = false; - else if ( (out-1) != in ) r_bc_count[in] = out-1; - else r_bc_count[in] = out-2; + else if ( (out-1) != in ) r_bc_count[in] = out-1; + else r_bc_count[in] = out-2; } } else // no pending proadcast @@ -173,11 +218,12 @@ public: if ( tmp.is_broadcast() ) // broadcast request { assert( input_port[in]->eop && - "error in vci_local_crossbar : VCI broacast packet must be one flit"); + "error in vci_local_crossbar : VCI broacast packet must be one flit"); + r_bc_state[in] = true; // the broadcast should not be sent to the requester... if ( in == m_in_size-1 ) r_bc_count[in] = m_out_size-2; - else r_bc_count[in] = m_out_size-1; + else r_bc_count[in] = m_out_size-1; } } } @@ -201,10 +247,15 @@ public: { pkt_t tmp; tmp.readFrom(*input_port[in]); - - if ( (tmp.is_broadcast() && r_bc_state[in].read() && (r_bc_count[in].read() == out)) || - (!tmp.is_broadcast() && !tmp.isLocal(m_lt) && (out == m_out_size-1)) || - (!tmp.is_broadcast() && tmp.isLocal(m_lt) && (out == (size_t)tmp.route(m_rt))) ) + if ( (tmp.is_broadcast() and + r_bc_state[in].read() and + (r_bc_count[in].read() == out)) or // broadcast request + (not tmp.is_broadcast() and + not is_local( tmp ) and + (out == m_out_size-1)) or // to global network + (not tmp.is_broadcast() and + is_local( tmp ) and + (out == route( tmp )) ) ) // to local component { r_allocated[out] = true; r_origin[out] = in; @@ -216,8 +267,9 @@ public: } } // end transition - /////////////////////////////////////////////////////////////////////// - void genMealy( input_port_t **input_port, output_port_t **output_port ) + ///////////////////////////////////////////////////////////// + void genMealy( typename pkt_t::input_port_t **input_port, + typename pkt_t::output_port_t **output_port ) { bool ack[m_in_size]; for( size_t in = 0; in < m_in_size; in++) ack[in] = false; @@ -227,7 +279,7 @@ public: { if (r_allocated[out]) { - size_t in = r_origin[out]; + size_t in = r_origin[out]; pkt_t tmp; tmp.readFrom(*input_port[in]); tmp.writeTo(*output_port[out]); @@ -241,17 +293,15 @@ public: } else { - output_port[out]->setVal(false); + output_port[out]->setVal( false ); } } // Send acknowledges on input ports - for( size_t in = 0; in < m_in_size; in++) input_port[in]->setAck(ack[in]); + for( size_t in = 0; in < m_in_size; in++) input_port[in]->setAck( ack[in] ); } // en genmealy -}; // end class Crossbar - -} +}; // end class SimpleCrossbar #define tmpl(x) template<typename vci_param> x VciLocalCrossbar<vci_param> @@ -259,8 +309,8 @@ public: tmpl(void)::print_trace() { std::cout << "LOCAL_CROSSBAR " << name() << " / "; - m_cmd_crossbar->print_trace(true); - m_rsp_crossbar->print_trace(false); + m_cmd_crossbar->print_trace(); + m_rsp_crossbar->print_trace(); std::cout << std::endl; } @@ -285,26 +335,35 @@ tmpl(void)::genMealy() m_rsp_crossbar->genMealy( m_ports_to_target, m_ports_to_initiator ); } -///////////////////////////// -tmpl(/**/)::VciLocalCrossbar( - sc_core::sc_module_name name, - const soclib::common::MappingTable &mt, - const soclib::common::IntTab &srcid, - const soclib::common::IntTab &tgtid, - size_t nb_attached_initiat, - size_t nb_attached_target ) - : BaseModule(name), - p_clk("clk"), - p_resetn("resetn"), +/////////////////////////////////////////////////////////////////////// +tmpl(/**/)::VciLocalCrossbar( sc_core::sc_module_name name, + const soclib::common::MappingTable &mt, + const size_t cluster_id, + const size_t nb_attached_initiators, + const size_t nb_attached_targets, + const size_t default_target_id ) + : BaseModule(name), + p_clk("clk"), + p_resetn("resetn"), p_to_target(soclib::common::alloc_elems<VciInitiator<vci_param> >( - "to_target", nb_attached_target)), + "to_target", nb_attached_targets)), p_to_initiator(soclib::common::alloc_elems<VciTarget<vci_param> >( - "to_initiator", nb_attached_initiat)), - p_target_to_up("target_to_up"), - p_initiator_to_up("initiator_to_up"), - m_nb_attached_initiat(nb_attached_initiat), - m_nb_attached_target(nb_attached_target) + "to_initiator", nb_attached_initiators)), + p_target_to_up("target_to_up"), + p_initiator_to_up("initiator_to_up"), + m_nb_attached_initiators(nb_attached_initiators), + m_nb_attached_targets(nb_attached_targets), + m_cmd_rt ( mt.getLocalIndexFromAddress( cluster_id, default_target_id ) ), + m_cmd_lt ( mt.getLocalMatchFromAddress( cluster_id ) ), + m_rsp_rt ( mt.getLocalIndexFromSrcid( cluster_id ) ), + m_rsp_lt ( mt.getLocalMatchFromSrcid( cluster_id ) ) { + std::cout << " - Building VciLocalCrossbar " << name << std::dec << std::endl + << " => cluster_id = " << cluster_id << std::endl + << " => targets = " << nb_attached_targets << std::endl + << " => initiators = " << nb_attached_initiators << std::endl + << " => default target = " << default_target_id << std::endl; + SC_METHOD(transition); dont_initialize(); sensitive << p_clk.pos(); @@ -313,42 +372,51 @@ tmpl(/**/)::VciLocalCrossbar( dont_initialize(); sensitive << p_clk.neg(); - for ( size_t i=0; i<nb_attached_initiat; ++i ) + for ( size_t i=0; i<nb_attached_initiators; ++i ) sensitive << p_to_initiator[i]; - for ( size_t i=0; i<nb_attached_target; ++i ) + for ( size_t i=0; i<nb_attached_targets; ++i ) sensitive << p_to_target[i]; sensitive << p_target_to_up << p_initiator_to_up; - m_cmd_crossbar = new cmd_crossbar_t( - nb_attached_initiat+1, - nb_attached_target+1, - mt.getRoutingTable(tgtid), - mt.getLocalityTable(tgtid)); - - m_rsp_crossbar = new rsp_crossbar_t( - nb_attached_target+1, - nb_attached_initiat+1, - mt.getIdMaskingTable(srcid.level()), - mt.getIdLocalityTable(srcid)); - - m_ports_to_initiator = new VciTarget<vci_param>*[nb_attached_initiat+1]; - for (size_t i=0; i<nb_attached_initiat; ++i) + // building cmd and rsp crossbars + m_cmd_crossbar = new SimpleCrossbar<VciCmdBuffer<vci_param> >( + cluster_id, + nb_attached_initiators+1, + nb_attached_targets+1, + (void*)(&m_cmd_rt), + (void*)(&m_cmd_lt), + true ); + + m_rsp_crossbar = new SimpleCrossbar<VciRspBuffer<vci_param> >( + cluster_id, + nb_attached_targets+1, + nb_attached_initiators+1, + (void*)(&m_rsp_rt), + (void*)(&m_rsp_lt), + false ); + + m_ports_to_initiator = new VciTarget<vci_param>*[nb_attached_initiators+1]; + for (size_t i=0; i<nb_attached_initiators; ++i) m_ports_to_initiator[i] = &p_to_initiator[i]; - m_ports_to_initiator[nb_attached_initiat] = &p_target_to_up; + m_ports_to_initiator[nb_attached_initiators] = &p_target_to_up; - m_ports_to_target = new VciInitiator<vci_param>*[nb_attached_target+1]; - for (size_t i=0; i<nb_attached_target; ++i) + m_ports_to_target = new VciInitiator<vci_param>*[nb_attached_targets+1]; + for (size_t i=0; i<nb_attached_targets; ++i) m_ports_to_target[i] = &p_to_target[i]; - m_ports_to_target[nb_attached_target] = &p_initiator_to_up; + m_ports_to_target[nb_attached_targets] = &p_initiator_to_up; } /////////////////////////////// tmpl(/**/)::~VciLocalCrossbar() { - soclib::common::dealloc_elems(p_to_initiator, m_nb_attached_initiat); - soclib::common::dealloc_elems(p_to_target, m_nb_attached_target); + soclib::common::dealloc_elems(p_to_initiator, m_nb_attached_initiators); + soclib::common::dealloc_elems(p_to_target, m_nb_attached_targets); + delete m_cmd_crossbar; + delete m_rsp_crossbar; + delete [] m_ports_to_initiator; + delete [] m_ports_to_target; } }} diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/include/vci_vgmn.h b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/include/vci_vgmn.h index 0b686b96ea1a0a42dae9af0d07c1de5f18a0b5f9..d01cb534d3d005f9f1bdd22796d316bbd7da58fe 100644 --- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/include/vci_vgmn.h +++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/include/vci_vgmn.h @@ -21,12 +21,13 @@ * SOCLIB_LGPL_HEADER_END * * Copyright (c) UPMC, Lip6, Asim - * Nicolas Pouillon <nipo@ssji.net>, 2007 + * Alain Greiner <alain.greiner@lip6.fr> 2005 + * Nicolas Pouillon <nipo@ssji.net> 2007 + * Alain Greiner <alain.greiner@lip6.fr> 2013 * - * Based on previous works by Laurent Mortiez & Alain Greiner, 2005 - * - * Maintainers: nipo + * Maintainers: alain */ + #ifndef SOCLIB_CABA_VCI_VGMN_H_ #define SOCLIB_CABA_VCI_VGMN_H_ @@ -34,8 +35,7 @@ #include "caba_base_module.h" #include "vci_initiator.h" #include "vci_target.h" -#include "vci_buffers.h" -//#include "vci_buffers_vgmn.h" //DG 31.08. we require a different kind of buffer than the vci_local_crossbar +#include "vci_buffers.h" #include "address_decoding_table.h" #include "address_masking_table.h" #include "mapping_table.h" @@ -51,6 +51,7 @@ template<typename vci_flit_t, typename vci_input_t, typename vci_output_t> class VgmnMicroNetwork; +/////////////////////////////////// template<typename vci_param> class VciVgmn : public soclib::caba::BaseModule @@ -63,11 +64,11 @@ public: VciTarget<vci_param> *p_to_initiator; private: - const size_t m_nb_initiat; - const size_t m_nb_target; + const size_t m_nb_initiators; + const size_t m_nb_targets; - AddressDecodingTable<uint32_t, int> m_cmd_routing_table; - AddressMaskingTable<uint32_t> m_rsp_routing_table; + AddressDecodingTable<uint64_t, size_t> m_cmd_rt; + AddressDecodingTable<uint32_t, size_t> m_rsp_rt; VgmnMicroNetwork<VciCmdBuffer<vci_param>, VciTarget<vci_param>, @@ -86,13 +87,13 @@ protected: public: void print_trace(); - VciVgmn( sc_module_name name, + VciVgmn( sc_module_name name, const soclib::common::MappingTable &mt, - size_t nb_initiat, - size_t nb_target, - size_t min_latency, - size_t fifo_depth, - const soclib::common::IntTab &default_index = 0); + size_t nb_initiators, + size_t nb_targets, + size_t min_latency, + size_t fifo_depth, + const size_t default_index = 0 ); ~VciVgmn(); }; diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/src/vci_vgmn.cpp b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/src/vci_vgmn.cpp index c96d1e9978d789925d6b8b97dcdc1aacd842923e..6564a4556634ae89624340db52760a8c8296dbd2 100644 --- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/src/vci_vgmn.cpp +++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/caba/source/src/vci_vgmn.cpp @@ -20,12 +20,31 @@ * SOCLIB_LGPL_HEADER_END * * Copyright (c) UPMC, Lip6, Asim - * Nicolas Pouillon <nipo@ssji.net>, 2007-2009 - * Alain Greiner <alain.greiner@lip6.fr> 2005 & 2013 + * Alain Greiner <alain.greiner@lip6.fr> 2005 + * Nicolas Pouillon <nipo@ssji.net> 2007-2009 + * Alain Greiner <alain.greiner@lip6.fr> 2013 * * Maintainers: alain */ +///////////////////////////////////////////////////////////////////////////////// +// Implementation note: +// The VciVgmn component contains two independant micro-network for CMD & RSP. +// Each micro-network is composed of a variable number of "input ports" +// and a variable number of "output ports". +// - Each Input Port contains an input generic fifo, a routing function, +// and a dedicated FSM to handle (sequencial) broadcast. +// - Each Output Port contains several intermediate fifos (one per input port), +// an allocation FSM, and an output fifo acting as a delay line. +// The two micro-networks have three template parameters: +// - CMD network: vci_flit_t == VciCmdBuffer +// vci_input_t == VciTarget +// vci_output_t == VciInitiator +// - RSP network: vci_flit_t == VciRspBuffer +// vci_input_t == VciInitiator +// vci_output_t == VciTarget +///////////////////////////////////////////////////////////////////////////////// + #include <systemc> #include <vector> #include <cassert> @@ -35,6 +54,7 @@ namespace soclib { namespace caba { using namespace sc_core; +using namespace soclib::common; //////////////////////////////////////////// template<typename data_t> class DelayLine @@ -174,7 +194,7 @@ public: // An output module is associated to each output port of a micro-network // Each output module implements a separate allocation mechanism, and // contains as many intermediate FIFOs as the number of input ports, -// and one single output delay line. +// and one single output fifo acting as a delay line. // For a CMD micro-network: vci_flit_t == VciCmdBuffer // vci_output_t == VciInitiator // For a RSP micro-network: vci_flit_t == VciRspBuffer @@ -374,15 +394,15 @@ public: size_t out; if( r_is_cmd ) { - soclib::common::AddressDecodingTable<uint32_t, int>* routing_table = - (soclib::common::AddressDecodingTable<uint32_t, int>*)r_rt; - out = (size_t)(routing_table->get_value( (uint32_t)flit.dest() )); + AddressDecodingTable<uint64_t, size_t>* rt = + (AddressDecodingTable<uint64_t, size_t>*)r_rt; + out = rt->get_value( (uint64_t)flit.dest() ); } else { - soclib::common::AddressMaskingTable<uint32_t>* masking_table = - (soclib::common::AddressMaskingTable<uint32_t>*)r_rt; - out = (size_t)(masking_table->get_value( (uint32_t)flit.dest() )); + AddressDecodingTable<uint32_t, size_t>* rt = + (AddressDecodingTable<uint32_t, size_t>*)r_rt; + out = rt->get_value( (uint32_t)flit.dest() ); } return out; } @@ -488,14 +508,6 @@ public: } }; // end class InputModule -///////////////////////////////////////////////////////////////////////////////// -// The VciVgmn component contains two independant micro-network for CMD & RSP -// - CMD network: vci_flit_t == VciCmdBuffer -// vci_input_t == VciTarget -// vci_output_t == VciInitiator -// - RSP network: vci_flit_t == VciRspBuffer -// vci_input_t == VciInitiator -// vci_output_t == VciTarget ///////////////////////////////////////////////////////////////////////////////// template<typename vci_flit_t, typename vci_input_t, @@ -624,16 +636,21 @@ tmpl(void)::print_trace() ////////////////////////////////////////////////////////////// tmpl(/**/)::VciVgmn( sc_module_name name, const soclib::common::MappingTable &mt, - size_t nb_attached_initiat, - size_t nb_attached_target, + size_t nb_attached_initiators, + size_t nb_attached_targets, size_t min_latency, size_t fifo_depth, - const soclib::common::IntTab &default_index) + const size_t default_index) : soclib::caba::BaseModule(name), - m_nb_initiat(nb_attached_initiat), - m_nb_target(nb_attached_target) + m_nb_initiators( nb_attached_initiators ), + m_nb_targets( nb_attached_targets ), + m_cmd_rt( mt.getGlobalIndexFromAddress( default_index ) ), + m_rsp_rt( mt.getGlobalIndexFromSrcid() ) { - std::cout << " - Building VciVgmn : " << name << std::endl; + std::cout << " - Building VciVgmn : " << name << std::dec << std::endl + << " => targets = " << nb_attached_targets << std::endl + << " => initiators = " << nb_attached_initiators << std::endl + << " => default target = " << default_index << std::endl; assert( (min_latency > 2) and "VCI_VGMN error : min_latency cannot be smaller than 3 cycles"); @@ -642,43 +659,28 @@ tmpl(/**/)::VciVgmn( sc_module_name name, "VCI_VGMN error : fifo_depth cannot be smaller than 2 slots"); p_to_initiator = soclib::common::alloc_elems<soclib::caba::VciTarget<vci_param> >( - "to_initiator", nb_attached_initiat); + "to_initiator", nb_attached_initiators); p_to_target = soclib::common::alloc_elems<soclib::caba::VciInitiator<vci_param> >( - "to_target", nb_attached_target); - - // build cmd routing table and cmd network + "to_target", nb_attached_targets); - - m_cmd_routing_table = mt.getRoutingTable( soclib::common::IntTab(), - mt.indexForId(default_index) ); - - // m_cmd_routing_table = mt.getRoutingTable( soclib::common::IntTab(), - // 0 ); - + // build cmd network and rsp network m_cmd_mn = new VgmnMicroNetwork<VciCmdBuffer<vci_param>, VciTarget<vci_param>, - VciInitiator<vci_param> >( nb_attached_initiat, - nb_attached_target, + VciInitiator<vci_param> >( nb_attached_initiators, + nb_attached_targets, min_latency-2, fifo_depth, - (void*)(&m_cmd_routing_table), + (void*)(&m_cmd_rt), true ); - - - // build rsp routing table and rsp network - m_rsp_routing_table = mt.getIdMaskingTable(0); - m_rsp_mn = new VgmnMicroNetwork<VciRspBuffer<vci_param>, VciInitiator<vci_param>, - VciTarget<vci_param> >( nb_attached_target, - nb_attached_initiat, + VciTarget<vci_param> >( nb_attached_targets, + nb_attached_initiators, min_latency-2, fifo_depth, - (void*)(&m_rsp_routing_table), + (void*)(&m_rsp_rt), false ); - - SC_METHOD(transition); dont_initialize(); sensitive << p_clk.pos(); @@ -693,8 +695,8 @@ tmpl(/**/)::~VciVgmn() { delete m_rsp_mn; delete m_cmd_mn; - soclib::common::dealloc_elems(p_to_initiator, m_nb_initiat); - soclib::common::dealloc_elems(p_to_target, m_nb_target); + soclib::common::dealloc_elems( p_to_initiator, m_nb_initiators ); + soclib::common::dealloc_elems( p_to_target, m_nb_targets ); } }} diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/metadata/vci_vgmn.sd b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/metadata/vci_vgmn.sd index ce9fc020115bc2aa9dafeea81ae33b2d3c72464d..c865d19aba1ea36bbed74c627a0f3297abc21fe1 100644 --- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/metadata/vci_vgmn.sd +++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/metadata/vci_vgmn.sd @@ -20,24 +20,22 @@ # # SOCLIB_LGPL_HEADER_END # -# Maintainers: fpecheux, nipo, alinevieiramello@hotmail.com, hgioja +# Maintainers: fpecheux, nipo, alinevieiramello@hotmail.com, hgioja, alain # # Copyright (c) UPMC / Lip6, 2008 # Francois Pecheux <francois.pecheux@lip6.fr> # Nicolas Pouillon <nipo@ssji.net> # Aline Vieira de Mello <aline.vieira-de-mello@lip6.fr> # Hermann Gioja <hermann.gioja@lip6.fr> +# Alain.Greiner <alain.greiner@lip6.fr> -__id__ = "$Id: vci_vgmn.sd 917 2009-03-12 10:10:06Z nipo $" -__version__ = "$Revision: 917 $" - Module('tlmdt:vci_vgmn', classname = 'soclib::tlmdt::VciVgmn', header_files = [ '../source/include/vci_vgmn.h', ], implementation_files = ['../source/src/vci_vgmn.cpp', ], uses = [ Uses('common:tlmdt'), - Uses('tlmdt:interconnect'), - ], - #debug = True, + Uses('common:mapping_table'), + Uses('tlmdt:centralized_buffer'), + ], ) diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/centralized_buffer.h b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/centralized_buffer.h index f60cab4580d9fae514006cfdd5904cbac4866359..6e388f7db9b4dc08df59f5937184cdb2f488e910 100644 --- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/centralized_buffer.h +++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/centralized_buffer.h @@ -27,55 +27,84 @@ * Aline Vieira de Mello <aline.vieira-de-mello@lip6.fr> */ +///////////////////////////////////////////////////////////////////////////////////// +// Implementation note: +// The centralized_buffer is actually an array of initiator ports descriptors. +// There is one entry per initiator connected to the interconnect in this array. +// Each port descriptor can store one or several transaction (payload, phase, time) +// in a circular buffer (defined in soclib/lib) acting as a software FIFO. +///////////////////////////////////////////////////////////////////////////////////// + #ifndef CENTRALIZED_BUFFER_H #define CENTRALIZED_BUFFER_H -#include <tlmdt> // TLM-DT headers +#include <tlmdt> #include "circular_buffer.h" namespace soclib { namespace tlmdt { -class _command; +//////////////////////////// +class init_port_descriptor +//////////////////////////// +{ + friend class centralized_buffer; + + circular_buffer buffer; // circular buffer of transactions + sc_core::sc_time port_time; // date of last transaction transmited + bool active; // initiator port activated if true + +public: + + // constructor + init_port_descriptor() + : buffer() , port_time(sc_core::SC_ZERO_TIME) + { + active = true; + } +}; +////////////////////////// class centralized_buffer - : public sc_core::sc_module // inherit from SC module base clase +////////////////////////// + : public sc_core::sc_module { - const size_t m_slots; - _command *m_centralized_struct; - - int m_count_push; - int m_count_pop; + // member variables + const size_t m_slots; // number of initiators + init_port_descriptor* m_port_array; // array of initiator port descriptors + int m_count_push; // cumulated push counter + int m_count_pop; // cumulate pop counter + size_t m_previous; // last selected port index (for round-robin) public: - centralized_buffer - ( sc_core::sc_module_name module_name, // SC module name - size_t max); - ~centralized_buffer(); + // constructor destructor + centralized_buffer( sc_core::sc_module_name name, + size_t slots ); + + ~centralized_buffer(); - bool push - ( size_t from, - tlm::tlm_generic_payload &payload, - tlm::tlm_phase &phase, - sc_core::sc_time &time); + // methods + bool push ( size_t from, + tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &time ); - bool pop - ( size_t &from, - tlm::tlm_generic_payload *&payload, - tlm::tlm_phase *&phase, - sc_core::sc_time *&time); + bool pop ( size_t &from, + tlm::tlm_generic_payload* &payload, + tlm::tlm_phase* &phase, + sc_core::sc_time* &time ); - circular_buffer get_buffer(int i); + circular_buffer get_buffer(size_t index); - const size_t get_nslots(); + const size_t get_nslots(); - const size_t get_free_slots(); + const size_t get_free_slots(); - sc_core::sc_time get_delta_time(unsigned int index); + sc_core::sc_time get_port_time(size_t index); - void set_activity(unsigned int index, bool b); + void set_activity(size_t index, bool b); - void set_delta_time(unsigned int index, sc_core::sc_time t); + void set_port_time(size_t index, sc_core::sc_time t); }; }} diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/interconnect.h b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/interconnect.h index 8b055e46bd3d71e7112b27bccbedbd6d413416e8..0e2ee8ada320c3231dc78f9c0636e23ea888e949 100644 --- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/interconnect.h +++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/interconnect.h @@ -31,39 +31,43 @@ #ifndef __INTERCONNECT_H__ #define __INTERCONNECT_H__ -#include <tlmdt> // TLM-DT headers -#include "mapping_table.h" // mapping table -#include "centralized_buffer.h" // centralized buffer +#include <tlmdt> // TLM-DT headers +#include "mapping_table.h" +#include "centralized_buffer.h" namespace soclib { namespace tlmdt { -class Interconnect // Interconnect - : public sc_core::sc_module // inherit from SC module base clase +//////////////////// +class Interconnect +//////////////////// + : public sc_core::sc_module + , virtual public tlm::tlm_fw_transport_if<tlm::tlm_base_protocol_types> + , virtual public tlm::tlm_bw_transport_if<tlm::tlm_base_protocol_types> { private: - typedef soclib::common::AddressDecodingTable<uint32_t, int> routing_table_t; - typedef soclib::common::AddressDecodingTable<uint32_t, bool> locality_table_t; - typedef soclib::common::AddressMaskingTable<uint32_t> resp_routing_table_t; - typedef soclib::common::AddressDecodingTable<uint32_t, bool> resp_locality_table_t; + typedef soclib::common::AddressDecodingTable<uint64_t, size_t> cmd_routing_table_t; + typedef soclib::common::AddressDecodingTable<uint32_t, bool> cmd_locality_table_t; + typedef soclib::common::AddressDecodingTable<uint32_t, size_t> rsp_routing_table_t; + typedef soclib::common::AddressDecodingTable<uint32_t, bool> rsp_locality_table_t; ///////////////////////////////////////////////////////////////////////////////////// // Member Variables ///////////////////////////////////////////////////////////////////////////////////// - int m_id; // identifier - int m_inits; // number of initiiators - int m_targets; // number of targets - size_t m_delay; // interconnect delay - size_t m_local_delta_time; // minimal time between send & response LOCAL - size_t m_no_local_delta_time; // minimal time between send & response NOT LOCAL - bool m_is_local_crossbar; // true if the module is a loca interconnect - - centralized_buffer m_centralized_buffer; // centralized buffer - const routing_table_t m_routing_table; // routing table - const locality_table_t m_locality_table; // locality table - const resp_routing_table_t m_resp_routing_table; // response routing table - const resp_locality_table_t m_resp_locality_table; // response locality table - pdes_local_time* m_pdes_local_time; // local time + size_t m_id; // identifier + size_t m_inits; // number of initiiators + size_t m_targets; // number of targets + size_t m_delay; // interconnect delay + size_t m_local_delta_time; // minimal time between cmd/rsp + size_t m_no_local_delta_time; // minimal time between cmd/rsp + bool m_is_local_crossbar; // true if local interconnect + + centralized_buffer m_centralized_buffer; // centralized buffer + const cmd_routing_table_t m_cmd_routing_table; // command routing table + const cmd_locality_table_t m_cmd_locality_table; // command locality table + const rsp_routing_table_t m_rsp_routing_table; // response routing table + const rsp_locality_table_t m_rsp_locality_table; // response locality table + pdes_local_time* m_pdes_local_time; // local time (pointer) // instrumentation counters size_t m_msg_count; @@ -91,78 +95,84 @@ private: ///////////////////////////////////////////////////////////////////////////////////// void init(); - void behavior(void); + void execLoop(void); - void routing - ( size_t from, // port source - tlm::tlm_generic_payload &payload, // payload - tlm::tlm_phase &phase, // phase - sc_core::sc_time &time); // time + void route ( size_t from, // port source + tlm::tlm_generic_payload &payload, // payload + tlm::tlm_phase &phase, // phase + sc_core::sc_time &time); // time void create_token(); ///////////////////////////////////////////////////////////////////////////////////// - // Fuction tlm::tlm_fw_transport_if (VCI TARGET SOCKET) + // Function executed when receiving command from VCI initiator ///////////////////////////////////////////////////////////////////////////////////// - tlm::tlm_sync_enum nb_transport_fw // receive command from initiator - ( int id, // socket id - tlm::tlm_generic_payload &payload, // payload - tlm::tlm_phase &phase, // phase - sc_core::sc_time &time); // time + tlm::tlm_sync_enum nb_transport_fw ( int id, // socket id + tlm::tlm_generic_payload &payload, // payload + tlm::tlm_phase &phase, // phase + sc_core::sc_time &time); // time ///////////////////////////////////////////////////////////////////////////////////// - // Virtual Fuctions tlm::tlm_bw_transport_if (VCI INITIATOR SOCKET) + // Function executed when receiving response from VCI target ///////////////////////////////////////////////////////////////////////////////////// - tlm::tlm_sync_enum nb_transport_bw // receive answer from target - ( int id, // socket id - tlm::tlm_generic_payload &payload, // payload - tlm::tlm_phase &phase, // phase - sc_core::sc_time &time); // time + tlm::tlm_sync_enum nb_transport_bw ( int id, // socket id + tlm::tlm_generic_payload &payload, // payload + tlm::tlm_phase &phase, // phase + sc_core::sc_time &time); // time protected: + SC_HAS_PROCESS(Interconnect); + public: - std::vector<tlm_utils::simple_target_socket_tagged<Interconnect,32,tlm::tlm_base_protocol_types> *> p_to_initiator; - std::vector<tlm_utils::simple_initiator_socket_tagged<Interconnect,32,tlm::tlm_base_protocol_types> *> p_to_target; - - Interconnect( // constructor - sc_core::sc_module_name module_name // SC module name - , int id // identifier - , const routing_table_t &rt // routing table - , const resp_routing_table_t &rrt // response routing table - , size_t n_inits // number of inits - , size_t n_targets // number of targets - , size_t delay); // interconnect delay - - Interconnect( // constructor - sc_core::sc_module_name module_name // SC module name - , const routing_table_t &rt // routing table - , const resp_routing_table_t &rrt // response routing table - , size_t n_inits // number of inits - , size_t n_targets // number of targets - , size_t delay); // interconnect delay - - Interconnect( // constructor - sc_core::sc_module_name module_name // SC module name - , int id // identifier - , const routing_table_t &rt // routing table - , const locality_table_t < // locality table - , const resp_routing_table_t &rrt // response routing table - , const resp_locality_table_t &rlt // response locality table - , size_t n_inits // number of inits - , size_t n_targets // number of targets - , size_t delay); // interconnect delay - - Interconnect( // constructor - sc_core::sc_module_name module_name // SC module name - , const routing_table_t &rt // routing table - , const locality_table_t < // locality table - , const resp_routing_table_t &rrt // response routing table - , const resp_locality_table_t &rlt // response locality table - , size_t n_inits // number of inits - , size_t n_targets // number of targets - , size_t delay); // interconnect delay + std::vector<tlm_utils::simple_target_socket_tagged + <Interconnect,32,tlm::tlm_base_protocol_types> *> p_to_initiator; + + std::vector<tlm_utils::simple_initiator_socket_tagged + <Interconnect,32,tlm::tlm_base_protocol_types> *> p_to_target; + + //////////////////////////////// + // Constructors + //////////////////////////////// + + // Global interconnect + Interconnect( sc_core::sc_module_name module_name, // module name + const size_t id, // identifier + const cmd_routing_table_t &cmd_rt, // command routing table + const rsp_routing_table_t &rsp_rt, // response routing table + const size_t n_inits, // number of initiators + const size_t n_targets, // number of targets + const size_t delay ); // interconnect latency + + // Global interconnect without identifier + Interconnect( sc_core::sc_module_name module_name, // module name + const cmd_routing_table_t &cmd_rt, // command routing table + const rsp_routing_table_t &rsp_rt, // response routing table + const size_t n_inits, // number of initiators + const size_t n_targets, // number of targets + const size_t delay ); // interconnect latency + + // Local interconnect + Interconnect( sc_core::sc_module_name module_name, // module name + const size_t id, // identifier + const cmd_routing_table_t &cmd_rt, // command routing table + const cmd_locality_table_t &cmd_lt, // command locality table + const rsp_routing_table_t &rsp_rt, // response routing table + const rsp_locality_table_t &rsp_lt, // response locality table + const size_t n_inits, // number of initators + const size_t n_targets, // number of targets + const size_t delay ); // interconnect latency + + // Local interconnect without identifier + Interconnect( sc_core::sc_module_name module_name, // module name + const cmd_routing_table_t &cmd_rt, // command routing table + const cmd_locality_table_t &cmd_lt, // command locality table + const rsp_routing_table_t &rsp_rt, // response routing table + const rsp_locality_table_t &rsp_lt, // response locality table + size_t n_inits, // number of initators + size_t n_targets, // number of targets + size_t delay ); // interconnect latency ~Interconnect(); diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/vci_vgmn.h b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/vci_vgmn.h index cd5242209bbfe9ee5fcc4f7f4614701bad497984..c609caa48519e8408ecae73531388fbb83a9ea83 100644 --- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/vci_vgmn.h +++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/include/vci_vgmn.h @@ -20,41 +20,128 @@ * * SOCLIB_LGPL_HEADER_END * - * Maintainers: fpecheux, alinevieiramello@hotmail.com + * Maintainers: alinevieiramello@hotmail.com, alain * * Copyright (c) UPMC / Lip6, 2008 - * Fran�ois P�cheux <francois.pecheux@lip6.fr> + * Fran�ois P�cheux <francois.pecheux@lip6.fr> * Aline Vieira de Mello <aline.vieira-de-mello@lip6.fr> + * Alain Greiner <alain.greiner@lip6.fr> */ #ifndef __VCI_VGMN_H__ #define __VCI_VGMN_H__ -#include <tlmdt> // TLM-DT headers -#include "interconnect.h" // interconnect +#include <tlmdt> +#include "centralized_buffer.h" +#include "mapping_table.h" namespace soclib { namespace tlmdt { -class VciVgmn // VciVgmn - : public Interconnect // inherit from SC module base clase +//////////////////////// +class VciVgmn +//////////////////////// + : public sc_core::sc_module { + +private: + + typedef soclib::common::AddressDecodingTable<uint64_t, size_t> cmd_routing_table_t; + typedef soclib::common::AddressDecodingTable<uint32_t, bool> cmd_locality_table_t; + typedef soclib::common::AddressDecodingTable<uint32_t, size_t> rsp_routing_table_t; + typedef soclib::common::AddressDecodingTable<uint32_t, bool> rsp_locality_table_t; + + ///////////////////////////////////////////////////////////////////////////////////// + // Member Variables + ///////////////////////////////////////////////////////////////////////////////////// + + size_t m_inits; // number of initiiators + size_t m_targets; // number of targets + size_t m_latency; // interconnect delay + + centralized_buffer m_central_buffer; // input fifos + + const cmd_routing_table_t m_cmd_routing_table; // command routing table + const rsp_routing_table_t m_rsp_routing_table; // response routing table + + pdes_local_time* m_pdes_local_time; // local time (pointer) + + sc_core::sc_event m_cmd_received; // any command received + + // instrumentation counters + size_t m_push_vci_count; + size_t m_pop_vci_count; + size_t m_push_null_count; + size_t m_pop_null_count; + size_t m_push_activity_count; + size_t m_pop_activity_count; + + size_t m_null_sent_count; + + // FIELDS OF NULL TRANSACTION + tlm::tlm_generic_payload m_null_payload; + tlm::tlm_phase m_null_phase; + sc_core::sc_time m_null_time; + soclib_payload_extension m_null_extension; + + ///////////////////////////////////////////////////////////////////////////////////// + // Functions + ///////////////////////////////////////////////////////////////////////////////////// + + void execLoop(void); + + void route ( size_t from, // port source + tlm::tlm_generic_payload &payload, // payload + tlm::tlm_phase &phase, // phase + sc_core::sc_time &time); // time + + ///////////////////////////////////////////////////////////////////////////////////// + // Function executed when receiving command from VCI initiator[id] + ///////////////////////////////////////////////////////////////////////////////////// + tlm::tlm_sync_enum nb_transport_fw ( int id, + tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &time); + + ///////////////////////////////////////////////////////////////////////////////////// + // Function executed when receiving response from VCI target[id] + ///////////////////////////////////////////////////////////////////////////////////// + tlm::tlm_sync_enum nb_transport_bw ( int id, + tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &time ); + +protected: + + SC_HAS_PROCESS( VciVgmn ); + public: - VciVgmn( // constructor - sc_core::sc_module_name module_name // SC module name - , const soclib::common::MappingTable &mt // mapping table - , size_t n_inits // number of inits - , size_t n_targets // number of targets - , size_t min_latency // minimal latency - , size_t fifo_depth); // parameter do not used - - VciVgmn( // constructor - sc_core::sc_module_name module_name // SC module name - , const soclib::common::MappingTable &mt // mapping table - , const soclib::common::IntTab &index // mapping table index - , int n_inits // number of inits - , int n_targets // number of targets - , sc_core::sc_time delay); // interconnect delay + std::vector<tlm_utils::simple_target_socket_tagged + <VciVgmn,32,tlm::tlm_base_protocol_types> *> p_to_initiator; + + std::vector<tlm_utils::simple_initiator_socket_tagged + <VciVgmn,32,tlm::tlm_base_protocol_types> *> p_to_target; + + //////////////////////////////// + // Constructor + //////////////////////////////// + + VciVgmn( sc_core::sc_module_name name, // module name + const soclib::common::MappingTable &mt, // mapping table + const size_t n_inits, // number of initiators + const size_t n_targets, // number of targets + const size_t min_latency, // interconnect latency + const size_t fifo_depth, // unused in tlmdt + const size_t default_tgtid = 0 ); + + ~VciVgmn() {} + + //////////////////////////////////////// + // Instrumentation functions + //////////////////////////////////////// + + void print(); + }; }} diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/centralized_buffer.cpp b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/centralized_buffer.cpp index 5257089ab07b4bdf4324ffe129dfa9a9953d20b0..2519c59657d14f3564716ec2b54f6007319fb992 100644 --- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/centralized_buffer.cpp +++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/centralized_buffer.cpp @@ -32,150 +32,157 @@ namespace soclib { namespace tlmdt { -class _command -{ - friend class centralized_buffer; - - circular_buffer buffer; - sc_core::sc_time delta_time; - bool active; - -public: - _command() - : buffer() - , delta_time(sc_core::SC_ZERO_TIME) - { - active = true; - } - -}; - -centralized_buffer::centralized_buffer -( sc_core::sc_module_name module_name, // module name - size_t nslots ) - : sc_module(module_name) +//////////////////////////////////////////////////////////////////////////// +// constructor / destructor for central buffer +//////////////////////////////////////////////////////////////////////////// +centralized_buffer::centralized_buffer ( sc_core::sc_module_name name, + size_t nslots ) + : sc_module(name) , m_slots(nslots) - , m_centralized_struct(new _command[nslots]) + , m_port_array(new init_port_descriptor[nslots]) + , m_previous( nslots - 1 ) { - for(unsigned int i=0; i<nslots; i++){ - std::ostringstream buf_name; - buf_name << name() << "_buf" << i; - m_centralized_struct[i].buffer.set_name(buf_name.str()); - } + for(unsigned int i=0; i<nslots; i++) + { + std::ostringstream buf_name; + buf_name << "slot_" << i; + m_port_array[i].buffer.set_name(buf_name.str()); + } } centralized_buffer::~centralized_buffer() { - delete [] m_centralized_struct; + delete [] m_port_array; } -bool centralized_buffer::push -( size_t from, - tlm::tlm_generic_payload &payload, - tlm::tlm_phase &phase, - sc_core::sc_time &time) +/////////////////////////////////////////////////////////////// +// This function push a transaction (payload, phase, time) +// in the circular buffer associated to initiator (from) +/////////////////////////////////////////////////////////////// +bool centralized_buffer::push ( size_t from, + tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &time) { + #if SOCLIB_MODULE_DEBUG - std::cout << "[" << name() << "] PUSH [" << from <<"] " << std::endl; +std::cout << "[" << name() << "] PUSH [" << from <<"] " << std::endl; #endif - assert(!(time < m_centralized_struct[from].delta_time) && "PUSH transaction with the time smaller than the precedent"); + assert(!(time < m_port_array[from].port_time) and + "PUSH transaction in a slot with a time smaller than precedent"); - return m_centralized_struct[from].buffer.push(payload, phase, time); + return m_port_array[from].buffer.push(payload, phase, time); } - -bool centralized_buffer::pop -( size_t &from, - tlm::tlm_generic_payload *&payload, - tlm::tlm_phase *&phase, - sc_core::sc_time *&time) +/////////////////////////////////////////////////////////////////////////////// +// This function implements the PDES time filtering algorithm: +// All active initiators are scanned, to select the earliest date. +// - if there is no transaction for this initiator, (false) is returned, +// and no transaction is consumed in the central buffer. +// - if there is a transaction, (true) is returned. The selected +// initiator index is returned in (from). The transaction parameters +// are returned in (payload, phase, time), the transaction is +// removed from the central buffer, and the selected port time is updated. +/////////////////////////////////////////////////////////////////////////////// +bool centralized_buffer::pop ( size_t &from, + tlm::tlm_generic_payload* &payload, + tlm::tlm_phase* &phase, + sc_core::sc_time* &time ) { - bool ok = false; - int min_idx = -1; - uint64_t min_time = MAX_TIME; - uint64_t time_value; + uint64_t min_time = MAX_TIME; + size_t sel_id = 0; // selected port + uint64_t time_value; // date of the port - for(unsigned int i=0; i<m_slots; i++){ - if(m_centralized_struct[i].active){ - if(m_centralized_struct[i].buffer.is_empty()){ - time = &m_centralized_struct[i].delta_time; - time_value = (*time).value(); -#if SOCLIB_MODULE_DEBUG - std::cout << "[" << name() << "] MD FOR POP " << i << " IS EMPTY time = " << time_value << std::endl; -#endif - if(time_value < min_time){ - min_idx = i; - min_time = time_value; - ok = false; - } - } - else{ - bool header = m_centralized_struct[i].buffer.get_front(payload, phase, time); - assert(header); - time_value = (*time).value(); - -#if SOCLIB_MODULE_DEBUG - std::cout << "[" << name() << "] MD FOR POP " << i << " NOT EMPTY time = " << time_value << std::endl; -#endif - - if(time_value < min_time || time_value == min_time){ - min_idx = i; - min_time = time_value; - ok = true; - } - } + // searching the earliest (smaller time) active port + // we implement a round-robin priority because, + // in case of equal times, the first found is selected + for( size_t k=0 ; k<m_slots ; k++ ) + { + size_t i = (m_previous + k + 1) % m_slots; + + if(m_port_array[i].active) // only active ports are competing + { + // get time + if(m_port_array[i].buffer.is_empty()) // no transaction available + { + time_value = m_port_array[i].port_time.value(); + +std::cout << "@@@ port " << i << " / empty / time = " << std::dec << time_value << std::endl; + + } + else // front transaction is earliest + { + m_port_array[i].buffer.get_front(payload, phase, time); + time_value = (*time).value(); + +std::cout << "@@@ port " << i << " / ok / time = " << std::dec << time_value << std::endl; + + } + + // test if it is the earliest + if(time_value < min_time) + { + min_time = time_value; + sel_id = i; + } + } } - } - from = min_idx; - - if(ok){ -#if SOCLIB_MODULE_DEBUG - std::cout << "[" << name() << "] POP from " << min_idx << std::endl; -#endif - bool pop = m_centralized_struct[min_idx].buffer.pop(payload, phase, time); - assert(pop); - } - else{ -#if SOCLIB_MODULE_DEBUG - std::cout << "[" << name() << "] NOT POP from " << min_idx << " IS EMPTY" << std::endl; -#endif - } - - return ok; -} + if( not m_port_array[sel_id].buffer.is_empty() ) // success + { + m_port_array[sel_id].buffer.pop( payload, + phase, + time); + from = sel_id; + m_previous = sel_id; + set_port_time( sel_id, *time ); + return true; + } + else // no eligible command + { + return false; + } +} // end pop() - -circular_buffer centralized_buffer::get_buffer(int i) +//////////////////////////////////////////////////////////// +circular_buffer centralized_buffer::get_buffer(size_t index) { - return m_centralized_struct[i].buffer; + return m_port_array[index].buffer; } +///////////////////////////////////////////// const size_t centralized_buffer::get_nslots() { - return m_slots; + return m_slots; } -sc_core::sc_time centralized_buffer::get_delta_time(unsigned int index) +//////////////////////////////////////////////////////////////// +sc_core::sc_time centralized_buffer::get_port_time(size_t index) { - return m_centralized_struct[index].delta_time; + return m_port_array[index].port_time; } -void centralized_buffer::set_delta_time(unsigned int index, sc_core::sc_time t) +//////////////////////////////////////////////////////////////////////// +void centralized_buffer::set_port_time(size_t index, sc_core::sc_time t) { - m_centralized_struct[index].delta_time = t; + m_port_array[index].port_time = t; + #if SOCLIB_MODULE_DEBUG - std::cout << "[" << name() << "] DELTA_TIME[" << index <<"] = " << t.value() << std::endl; +std::cout << "[" << name() << "] DELTA_TIME[" << index <<"] = " << t.value() << std::endl; #endif + } -void centralized_buffer::set_activity(unsigned int index, bool b) +/////////////////////////////////////////////////////////// +void centralized_buffer::set_activity(size_t index, bool b) { - m_centralized_struct[index].active = b; + m_port_array[index].active = b; + #if SOCLIB_MODULE_DEBUG - std::cout << "[" << name() << "] ACTIVE[" << index <<"] = " << b << std::endl; +std::cout << "[" << name() << "] ACTIVE[" << index <<"] = " << b << std::endl; #endif + } }} diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/interconnect.cpp b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/interconnect.cpp index cfd1343731da60fe454832504ea0bf37c0d317b2..0ef58394842a465a4dc8605b313c1fb4cbb87dc0 100644 --- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/interconnect.cpp +++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/interconnect.cpp @@ -27,28 +27,28 @@ * Aline Vieira de Mello <aline.vieira-de-mello@lip6.fr> */ -#include "interconnect.h" // our header +#include "interconnect.h" -//#define SOCLIB_MODULE_DEBUG 1 +#define SOCLIB_MODULE_DEBUG 1 namespace soclib { namespace tlmdt { #define tmpl(x) x Interconnect ///////////////////////////////////////////////////////////////////////////////////// -// Constructor +// Constructors ///////////////////////////////////////////////////////////////////////////////////// -tmpl(/**/)::Interconnect -( sc_core::sc_module_name module_name // module name - , int id // identifier - , const routing_table_t &rt // routing table - , const locality_table_t < // locality table - , const resp_routing_table_t &rrt // response routing table - , const resp_locality_table_t &rlt // response locality table - , size_t n_inits // number of inits - , size_t n_targets // number of targets - , size_t delay // interconnect delay - ) + +// Local interconnect +tmpl(/**/)::Interconnect( sc_core::sc_module_name module_name, + const size_t id, + const cmd_routing_table_t &cmd_rt, + const cmd_locality_table_t &cmd_lt, + const rsp_routing_table_t &rsp_rt, + const rsp_locality_table_t &rsp_lt, + const size_t n_inits, + const size_t n_targets, + const size_t delay ) : sc_module(module_name) , m_id(id) , m_inits(n_inits) @@ -56,10 +56,10 @@ tmpl(/**/)::Interconnect , m_delay(delay) , m_is_local_crossbar(true) , m_centralized_buffer("centralized_buffer", n_inits) - , m_routing_table(rt) - , m_locality_table(lt) - , m_resp_routing_table(rrt) - , m_resp_locality_table(rlt) + , m_cmd_routing_table(cmd_rt) + , m_cmd_locality_table(cmd_lt) + , m_rsp_routing_table(rsp_rt) + , m_rsp_locality_table(rsp_lt) , m_msg_count(0) , m_local_msg_count(0) , m_non_local_msg_count(0) @@ -68,16 +68,15 @@ tmpl(/**/)::Interconnect init(); } -tmpl(/**/)::Interconnect -( sc_core::sc_module_name module_name // module name - , const routing_table_t &rt // routing table - , const locality_table_t < // locality table - , const resp_routing_table_t &rrt // response routing table - , const resp_locality_table_t &rlt // response locality table - , size_t n_inits // number of inits - , size_t n_targets // number of targets - , size_t delay // interconnect delay - ) +// Local interconnect without identfier +tmpl(/**/)::Interconnect( sc_core::sc_module_name module_name, + const cmd_routing_table_t &cmd_rt, + const cmd_locality_table_t &cmd_lt, + const rsp_routing_table_t &rsp_rt, + const rsp_locality_table_t &rsp_lt, + const size_t n_inits, + const size_t n_targets, + const size_t delay ) : sc_module(module_name) , m_id(0) , m_inits(n_inits) @@ -85,10 +84,10 @@ tmpl(/**/)::Interconnect , m_delay(delay) , m_is_local_crossbar(true) , m_centralized_buffer("centralized_buffer", n_inits) - , m_routing_table(rt) - , m_locality_table(lt) - , m_resp_routing_table(rrt) - , m_resp_locality_table(rlt) + , m_cmd_routing_table(cmd_rt) + , m_cmd_locality_table(cmd_lt) + , m_rsp_routing_table(rsp_rt) + , m_rsp_locality_table(rsp_lt) , m_msg_count(0) , m_local_msg_count(0) , m_non_local_msg_count(0) @@ -97,15 +96,14 @@ tmpl(/**/)::Interconnect init(); } -tmpl(/**/)::Interconnect -( sc_core::sc_module_name module_name // module name - , int id // identifier - , const routing_table_t &rt // routing table - , const resp_routing_table_t &rrt // response routing table - , size_t n_inits // number of inits - , size_t n_targets // number of targets - , size_t delay // interconnect delay - ) +// Global interconnect +tmpl(/**/)::Interconnect( sc_core::sc_module_name module_name, + const size_t id, + const cmd_routing_table_t &cmd_rt, + const rsp_routing_table_t &rsp_rt, + const size_t n_inits, + const size_t n_targets, + const size_t delay ) : sc_module(module_name) , m_id(id) , m_inits(n_inits) @@ -113,8 +111,8 @@ tmpl(/**/)::Interconnect , m_delay(delay) , m_is_local_crossbar(false) , m_centralized_buffer("centralized_buffer", n_inits) - , m_routing_table(rt) - , m_resp_routing_table(rrt) + , m_cmd_routing_table(cmd_rt) + , m_rsp_routing_table(rsp_rt) , m_msg_count(0) , m_local_msg_count(0) , m_non_local_msg_count(0) @@ -123,14 +121,13 @@ tmpl(/**/)::Interconnect init(); } -tmpl(/**/)::Interconnect -( sc_core::sc_module_name module_name // module name - , const routing_table_t &rt // routing table - , const resp_routing_table_t &rrt // response routing table - , size_t n_inits // number of inits - , size_t n_targets // number of targets - , size_t delay // interconnect delay - ) +// Global interconnect without identifier +tmpl(/**/)::Interconnect( sc_core::sc_module_name module_name, + const cmd_routing_table_t &cmd_rt, + const rsp_routing_table_t &rsp_rt, + const size_t n_inits, + const size_t n_targets, + const size_t delay ) : sc_module(module_name) , m_id(0) , m_inits(n_inits) @@ -138,8 +135,8 @@ tmpl(/**/)::Interconnect , m_delay(delay) , m_is_local_crossbar(false) , m_centralized_buffer("centralized_buffer", n_inits) - , m_routing_table(rt) - , m_resp_routing_table(rrt) + , m_cmd_routing_table(cmd_rt) + , m_rsp_routing_table(rsp_rt) , m_msg_count(0) , m_local_msg_count(0) , m_non_local_msg_count(0) @@ -148,30 +145,35 @@ tmpl(/**/)::Interconnect init(); } -tmpl(/**/)::~Interconnect(){ -} +tmpl(/**/)::~Interconnect(){ } /////////////////// tmpl(void)::init() { - // bind VCI TARGET SOCKETS - for(int i=0;i<m_inits;i++) + // allocate & bind p_to_initiator[i] VCI ports + for(size_t i=0;i<m_inits;i++) { - std::ostringstream target_name; - target_name << "target" << i; + std::ostringstream name; + name << "p_to_initiator_" << i; p_to_initiator.push_back(new tlm_utils::simple_target_socket_tagged - <Interconnect,32,tlm::tlm_base_protocol_types>(target_name.str().c_str())); - p_to_initiator[i]->register_nb_transport_fw(this, &Interconnect::nb_transport_fw, i); + <Interconnect,32,tlm::tlm_base_protocol_types>(name.str().c_str())); + + p_to_initiator[i]->register_nb_transport_fw( this, + &Interconnect::nb_transport_fw, + i ); } - // bind VCI INITIATOR SOCKETS - for(int i=0;i<m_targets;i++) + // allocate & bind p_to_target[i] VCI ports + for(size_t i=0;i<m_targets;i++) { - std::ostringstream init_name; - init_name << "init" << i; + std::ostringstream name; + name << "p_to_target_" << i; p_to_target.push_back(new tlm_utils::simple_initiator_socket_tagged - <Interconnect,32,tlm::tlm_base_protocol_types>(init_name.str().c_str())); - p_to_target[i]->register_nb_transport_bw(this, &Interconnect::nb_transport_bw, i); + <Interconnect,32,tlm::tlm_base_protocol_types>(name.str().c_str())); + + p_to_target[i]->register_nb_transport_bw( this, + &Interconnect::nb_transport_bw, + i ); } // minimal local latency @@ -196,25 +198,32 @@ tmpl(void)::init() } // register thread process - SC_THREAD(behavior); + SC_THREAD(execLoop); } ///////////////////////////////////////////////////////////////////////////////////// -// Functions +// Instrumentation Functions ///////////////////////////////////////////////////////////////////////////////////// -tmpl(uint32_t)::getLocalMsgCounter(){ +tmpl(uint32_t)::getLocalMsgCounter() +{ return m_local_msg_count; } -tmpl(uint32_t)::getNonLocalMsgCounter(){ +/////////////////////////////////////// +tmpl(uint32_t)::getNonLocalMsgCounter() +{ return m_non_local_msg_count; } -tmpl(uint32_t)::getTokenMsgCounter(){ +//////////////////////////////////// +tmpl(uint32_t)::getTokenMsgCounter() +{ return m_token_msg_count; } -tmpl(void)::print(){ +/////////////////// +tmpl(void)::print() +{ uint32_t local_msg_count = getLocalMsgCounter(); uint32_t non_local_msg_count = getNonLocalMsgCounter(); uint32_t token_msg_count = getTokenMsgCounter(); @@ -227,36 +236,41 @@ tmpl(void)::print(){ } -/////////////////////////////////////////////////////// -tmpl(void)::routing( size_t from, - tlm::tlm_generic_payload &payload, - tlm::tlm_phase &phase, - sc_core::sc_time &time) +//////////////////////////////////////////////////////////////////////////////// +// This function analyses the transaction poped from the the central buffer, +// and execute the required action. +//////////////////////////////////////////////////////////////////////////////// +tmpl(void)::route( size_t from, + tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &time) { - bool send; - int dest; + bool send_required; + size_t dest; // get payload extension soclib_payload_extension *extension_ptr; payload.get_extension(extension_ptr); - /////////////////////////////////////////////////////////////// - // if transaction command is activation/deactivation - // the source is actived or desactived and no transaction is sent + ///////////////////////////////////////////////////////////////////////// + // if message is activation/deactivation, the corresponding + // initiator port is actived/desactived, but no message is sent. if(extension_ptr->is_active() || extension_ptr->is_inactive()) { #ifdef SOCLIB_MODULE_DEBUG -printf("[%s] time = %d HANDLING ACTIVITY MSG from = %d\n", +printf("[%s] / time = %d / HANDLING ACTIVITY MSG from port %d\n", name(), (int)time.value(), (int)from); #endif - - send = false; + // initiator port activation/deactivation m_centralized_buffer.set_activity(from, extension_ptr->is_active()); + + send_required = false; } - ///////////////////////////////////////////////////////////////////////// - // if transaction command is a token, it must be sent to the target[from] + //////////////////////////////////////////////////////////////////////////// + // if transaction command is a token, it must be sent to the target + // corresponding to the source initiator else if(extension_ptr->is_token_message()) { @@ -268,7 +282,7 @@ printf("[%s] time = %d HANDLING TOKEN MSG from = %d\n", // set the delta_time which this init wont send another message m_centralized_buffer.set_delta_time(from, time); - send = true; + send_required = true; m_msg_count++; m_token_msg_count++; @@ -276,7 +290,7 @@ printf("[%s] time = %d HANDLING TOKEN MSG from = %d\n", if ( m_is_local_crossbar ) { dest = m_targets - 1; - extension_ptr->set_pkt_id(extension_ptr->get_pkt_id()+1); + extension_ptr->set_pkt_id(extension_ptr->get_pkt_id()+1); // ??? AG } else { @@ -285,8 +299,8 @@ printf("[%s] time = %d HANDLING TOKEN MSG from = %d\n", } ////////////////////////////////////////////////////////////////////////////////// - // if transaction command is a null message, the response is sent to the initiator - // to synchronize it, but this null message is not transmited + // if transaction command is a null message, a response is sent to the initiator + // to synchronize it, but this null message is not transmited. else if(extension_ptr->is_null_message()) { @@ -301,59 +315,63 @@ printf("[%s] time = %d HANDLING NULL MSG from = %d\n", // send the response (*p_to_initiator[from])->nb_transport_bw(payload, phase, time); - send = false; + send_required = false; } /////////////////////////////////////////////////////////////////////////////// // if transaction is a VCI command, it must be sent to appropriated target - // no response is sent to the initiator + // no response is sent to the initiator. else { - send = true; + send_required = true; + if(m_is_local_crossbar) // local interconnect { - if (!m_locality_table[payload.get_address()]) // non local target + if ( not m_cmd_locality_table[payload.get_address()] ) // non local target { - if(from == m_centralized_buffer.get_nslots()-1) + if(from == m_centralized_buffer.get_nslots()-1) { - // set the delta_time which this init wont send another message - m_centralized_buffer.set_delta_time(from, time); - } - else + // set the delta_time which this init wont send another message + m_centralized_buffer.set_delta_time(from, time); + } + else { - // set the delta_time which this init wont send another message - m_centralized_buffer.set_delta_time(from, time + (m_no_local_delta_time*UNIT_TIME)); - } + // set the delta_time which this init wont send another message + m_centralized_buffer.set_delta_time(from, + time + (m_no_local_delta_time*UNIT_TIME)); + } - m_msg_count++; - m_non_local_msg_count++; - dest = m_targets - 1; + m_msg_count++; + m_non_local_msg_count++; + dest = m_targets - 1; } else // local target { - if(from == m_centralized_buffer.get_nslots()-1) + if(from == m_centralized_buffer.get_nslots()-1) { - //set the delta_time which this init wont send another message - m_centralized_buffer.set_delta_time(from, time); - } - else + //set the delta_time which this init wont send another message + m_centralized_buffer.set_delta_time(from, time); + } + else { - //set the delta_time which this init wont send another message - m_centralized_buffer.set_delta_time(from, time + (m_local_delta_time*UNIT_TIME)); - } + //set the delta_time which this init wont send another message + m_centralized_buffer.set_delta_time(from, + time + (m_local_delta_time*UNIT_TIME)); + } - m_msg_count++; - m_local_msg_count++; - dest = m_routing_table[payload.get_address()]; - assert( dest >= 0 && dest < m_targets ); + m_msg_count++; + m_local_msg_count++; + dest = m_cmd_routing_table[payload.get_address()]; + assert( dest >= 0 && dest < m_targets ); } } - else // global interconnect + else // global interconnect { // set the delta_time which this init wont send another message m_centralized_buffer.set_delta_time(from, time); - dest = m_routing_table[payload.get_address()]; - assert( dest >= 0 && dest < m_targets ); + + dest = m_cmd_routing_table[payload.get_address()]; + assert( dest < m_targets ); m_msg_count++; m_local_msg_count++; @@ -366,17 +384,17 @@ printf("[%s] time = %d ROUTING VCI MSG from = %d to %d\n", } - if (send) // transmit the command to the selected target + if (send_required) // transmit the command to the selected target { time = time + (m_delay*UNIT_TIME); (*p_to_target[dest])->nb_transport_fw(payload, phase, time); } -} // end routing() +} // end route() ////////////////////////// tmpl(void)::create_token() { - // create token message in beginning of simulation + // create token message at beginning of simulation m_extension_token.set_token_message(); m_extension_token.set_src_id(m_id); m_extension_token.set_pkt_id(0); @@ -390,15 +408,16 @@ printf("[%s] send Token time = %d\n", name(), (int)m_time_token.value()); //push a token in the centralized buffer m_centralized_buffer.push(m_inits-1, m_payload_token, m_phase_token, m_time_token); + #ifdef SOCLIB_MODULE_DEBUG - printf("[%s] send Token time = %d\n", name(), (int)m_time_token.value()); +printf("[%s] send Token time = %d\n", name(), (int)m_time_token.value()); #endif } ///////////////////////////////////////////////////////////////////////////////////// -// consumer thread +// PDES process ///////////////////////////////////////////////////////////////////////////////////// -tmpl(void)::behavior() +tmpl(void)::execLoop() { size_t from; tlm::tlm_generic_payload* payload_ptr; @@ -413,36 +432,39 @@ printf("[%s] WHILE CONSUMER\n", name()); #endif // pop the earliest transaction from centralized buffer - while(m_centralized_buffer.pop(from, payload_ptr, phase_ptr, time_ptr)) + while( m_centralized_buffer.pop( from, payload_ptr, phase_ptr, time_ptr) ) { m_pop_count++; - assert(!(*time_ptr < m_pdes_local_time->get()) - && "Transaction time must not be smaller than the interconnect time"); + assert( not (*time_ptr < m_pdes_local_time->get()) + && "Transaction time must not be smaller than the interconnect time"); // update local time m_pdes_local_time->set(*time_ptr); // process the transaction - routing(from, *payload_ptr, *phase_ptr, *time_ptr); + route( from, *payload_ptr, *phase_ptr, *time_ptr); + } // end while buffer not empty // send periodically NULL messages to all local targets - // if it is a local interconnect + // if this interconnect is a local interconnect if ( m_is_local_crossbar && m_pdes_local_time->need_sync() ) { m_pdes_local_time->reset_sync(); m_null_time = m_pdes_local_time->get(); - for ( int i=0 ; i<(m_targets-1) ; i++ ) + for ( size_t i=0 ; i<(m_targets-1) ; i++ ) + { (*p_to_target[i])->nb_transport_fw(m_null_payload, m_null_phase, m_null_time); + } } #ifdef SOCLIB_MODULE_DEBUG printf("[%s] CONSUMER WAITING id = %d\n", name(), (int)from); #endif - + // deschedule if buffer empty sc_core::wait(sc_core::SC_ZERO_TIME); #ifdef SOCLIB_MODULE_DEBUG @@ -453,8 +475,8 @@ printf("[%s] CONSUMER WAKE-UP\n", name()); } ///////////////////////////////////////////////////////////////////////////////////// -// Interface function executed when receiving a command on an initiator port -// It registers the command in the central buffer +// Interface function executed when receiving a command from a VCI initiator. +// It registers the command in the central buffer, to make time filtering. ///////////////////////////////////////////////////////////////////////////////////// tmpl(tlm::tlm_sync_enum)::nb_transport_fw (int id, tlm::tlm_generic_payload &payload, @@ -467,31 +489,32 @@ tmpl(tlm::tlm_sync_enum)::nb_transport_fw (int id, { #ifdef SOCLIB_MODULE_DEBUG -printf("[%s] time = %d RECEIVE a COMMAND on port %d\n", name(), (int)time.value(), id); +printf( "[%s] RECEIVE COMMAND from INITIATOR %d / time = %d \n", + name(), id, (int)time.value() ); #endif - //push a transaction in the centralized buffer + // push a transaction in the centralized buffer push = m_centralized_buffer.push(id, payload, phase, time); - if(!push) + if( not push ) { try_push++; #ifdef SOCLIB_MODULE_DEBUG -printf("[%s] PRODUCER id = %d <<<<<<<<< NOT PUSH >>>>>>>> try_push = %d \n",name(),id, try_push); +printf("[%s] INITIATOR %d <<<<<<<<< CANNOT PUSH >>>>>>>>\n", name(),id); #endif - sc_core::wait(sc_core::SC_ZERO_TIME); + sc_core::wait( sc_core::SC_ZERO_TIME ); } - } while (!push); + } while ( not push ); return tlm::TLM_COMPLETED; } //end nb_transport_fw ///////////////////////////////////////////////////////////////////////////////////// -// Interface function executed when receiving a response on a target port -// It directly routes the response to the proper initiator +// Interface function executed when receiving a response from target port. +// It directly routes the response to the proper VCI initiator (no time filtering). ///////////////////////////////////////////////////////////////////////////////////// tmpl(tlm::tlm_sync_enum)::nb_transport_bw ( int id, tlm::tlm_generic_payload &payload, @@ -507,25 +530,25 @@ tmpl(tlm::tlm_sync_enum)::nb_transport_bw ( int id, srcid = resp_extension_ptr->get_src_id(); #ifdef SOCLIB_MODULE_DEBUG -printf("[%s] time = %d RECEIVE RESPONSE on port %d / srcid = %d\n", +printf("[%s] / time = %d / RECEIVE RESPONSE from port %d for initiator %d\n", name(), (int)time.value(), id, srcid); #endif if(m_is_local_crossbar) { - if (!m_resp_locality_table[srcid]) dest = m_inits - 1; - else dest = m_resp_routing_table[srcid]; + if (!m_rsp_locality_table[srcid]) dest = m_inits - 1; + else dest = m_rsp_routing_table[srcid]; } else // global interconnect { - dest = m_resp_routing_table[srcid]; + dest = m_rsp_routing_table[srcid]; } // update the transaction time time = time + (m_delay*UNIT_TIME); #ifdef SOCLIB_MODULE_DEBUG -printf("[%s] time = %d SEND RESPONSE on port %d / srcid = %d\n", +printf("[%s] / time = %d / SEND RESPONSE on port %d\n", name(), (int)time.value(), dest, srcid); #endif diff --git a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/vci_vgmn.cpp b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/vci_vgmn.cpp index 546650597e409da3eb23d0f77c01cdb3f01a87d4..830621da2366000c5f5a3d9995c5feb352d2789e 100644 --- a/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/vci_vgmn.cpp +++ b/MPSoC/soclib/soclib/module/network_component/vci_vgmn/tlmdt/source/src/vci_vgmn.cpp @@ -20,33 +20,327 @@ * * SOCLIB_LGPL_HEADER_END * - * Maintainers: fpecheux, alinevieiramello@hotmail.com + * Maintainers: alinevieiramello@hotmail.com, alain * * Copyright (c) UPMC / Lip6, 2008 * Fran�ois P�cheux <francois.pecheux@lip6.fr> * Aline Vieira de Mello <aline.vieira-de-mello@lip6.fr> + * Alain Greiner <alain.greiner@lip6.fr> */ -#include "vci_vgmn.h" // our header +#include "vci_vgmn.h" + +#define SOCLIB_MODULE_DEBUG 1 namespace soclib { namespace tlmdt { #define tmpl(x) x VciVgmn +//////////////////////////////////////////////////////////////////////////////////////////// +tmpl(/**/)::VciVgmn ( sc_core::sc_module_name name, // module name + const soclib::common::MappingTable &mt, // mapping table + const size_t n_inits, // number of initiators + const size_t n_targets, // number of targets + const size_t min_latency, // minimal latency + const size_t fifo_depth, // not used in TLMDT + const size_t default_tgtid ) // default target index + : sc_module( name ) + , m_inits( n_inits ) + , m_targets( n_targets ) + , m_latency( min_latency ) + , m_central_buffer( "central_buffer", n_inits ) + , m_cmd_routing_table( mt.getGlobalIndexFromAddress( default_tgtid ) ) + , m_rsp_routing_table( mt.getGlobalIndexFromSrcid() ) + , m_push_vci_count( 0 ) + , m_pop_vci_count( 0 ) + , m_push_null_count( 0 ) + , m_pop_null_count( 0 ) + , m_push_activity_count( 0 ) + , m_pop_activity_count( 0 ) + , m_null_sent_count( 0 ) +{ + // allocate & bind p_to_initiator VCI ports + for( size_t i=0 ; i<m_inits ; i++ ) + { + std::ostringstream name; + name << "p_to_initiator_" << i; + p_to_initiator.push_back(new tlm_utils::simple_target_socket_tagged + <VciVgmn,32,tlm::tlm_base_protocol_types>(name.str().c_str())); + + p_to_initiator[i]->register_nb_transport_fw( this, + &VciVgmn::nb_transport_fw, + i ); + } + + // allocate & bind p_to_target VCI ports + for( size_t i=0 ; i<m_targets ; i++ ) + { + std::ostringstream name; + name << "p_to_target_" << i; + p_to_target.push_back(new tlm_utils::simple_initiator_socket_tagged + <VciVgmn,32,tlm::tlm_base_protocol_types>(name.str().c_str())); + + p_to_target[i]->register_nb_transport_bw( this, + &VciVgmn::nb_transport_bw, + i ); + } + + // PDES local time + m_pdes_local_time = new pdes_local_time(100*UNIT_TIME); + + // initialises payload, phase and extension for null messages + m_null_payload.set_extension(&m_null_extension); + m_null_extension.set_null_message(); + m_null_phase = tlm::BEGIN_REQ; + + // register thread process + SC_THREAD(execLoop); +} // end init() + + +////////////////////////////////////////////////////////////////////////////////////// +// This function analyses the type of transaction poped from the the central buffer, +// and execute the required action. +////////////////////////////////////////////////////////////////////////////////////// +tmpl(void)::route( size_t from, // initiator index + tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &time) +{ + // get payload extension + soclib_payload_extension *extension_ptr; + payload.get_extension(extension_ptr); + + // if message is activation/deactivation, the initiator port is actived/desactived, + // but no message is transmit, and no response is returned + if( extension_ptr->is_active() || extension_ptr->is_inactive() ) + { + +#ifdef SOCLIB_MODULE_DEBUG +m_pop_activity_count++; +printf(" [%s] handle ACTIVITY from port %d / time = %d \n", + name(), (int)from, (int)time.value() ); +#endif + // initiator port activation/deactivation + m_central_buffer.set_activity(from, extension_ptr->is_active()); + } + + // if transaction command is a NULL message, a response is sent to the initiator + // but this NULL message is not transmit. + else if( extension_ptr->is_null_message() ) + { + +#ifdef SOCLIB_MODULE_DEBUG +m_pop_null_count++; +printf(" [%s] handle NULL from port %d / time = %d \n", + name(), (int)from, (int)time.value() ); +#endif + // send the response + (*p_to_initiator[from])->nb_transport_bw( payload, + phase, + time); + } + + // if transaction is a VCI command, it must be sent to the appropriate target, + // and no response is sent to the initiator. + else + { + size_t dest = m_cmd_routing_table[payload.get_address()]; + + assert( ( dest < m_targets ) and + "ERROR in VGMN: illegal target index" ); + + time = time + (m_latency*UNIT_TIME); + +#ifdef SOCLIB_MODULE_DEBUG +m_pop_vci_count++; +printf(" [%s] transfer VCI command from init %d to target %d / time = %d\n", + name(), (int)from, (int)dest, (int)time.value() ); +#endif + // transfer VCI command + (*p_to_target[dest])->nb_transport_fw( payload, + phase, + time ); + } +} // end route() + +/////////////////////////////////////////////////////////////////////////////////////// +// PDES process +// ALL command from initiators (VCI, NULL, or ACTIVITY) are registered in the central +// buffer and are handled in a strict increasing time (time filtering). +// The local time is updated each time a new transaction is poped from central buffer. +// Non blocking NULL messages are sent to all targets when time quantum elapsed. +// The thread deschedule if there is no more eligible command in central buffer, +// and wake up when a new command is received. +/////////////////////////////////////////////////////////////////////////////////////// +tmpl(void)::execLoop() +{ + size_t from; + tlm::tlm_generic_payload* payload_ptr; + tlm::tlm_phase* phase_ptr; + sc_core::sc_time* time_ptr; + + while (true) + { + +#ifdef SOCLIB_MODULE_DEBUG +printf("###### [%s] wake up / time = %d\n", + name(), (int)m_pdes_local_time->get().value() ); +#endif + + // pop the earliest transaction from central buffer + // while eligible command is found in central buffer + while( m_central_buffer.pop( from, + payload_ptr, + phase_ptr, + time_ptr) ) + { + assert( not (*time_ptr < m_pdes_local_time->get()) + && "ERROR in VGMN: Transaction time smaller than local time"); + + // update local time + m_pdes_local_time->set(*time_ptr); + + // process the transaction + route( from, + *payload_ptr, + *phase_ptr, + *time_ptr ); + + // send NULL messages to all targets if time_quantum elapsed + if ( m_pdes_local_time->need_sync() ) + { + m_pdes_local_time->reset_sync(); + m_null_time = m_pdes_local_time->get(); + m_null_sent_count += m_targets; + + for ( size_t i=0 ; i<(m_targets-1) ; i++ ) + { + (*p_to_target[i])->nb_transport_fw(m_null_payload, + m_null_phase, + m_null_time); + } + } + } // end while buffer not empty + + +#ifdef SOCLIB_MODULE_DEBUG +printf("###### [%s] no eligible transaction => deschedule / time = %d\n", + name(), (int)m_pdes_local_time->get().value() ); +#endif + //////////////////////////////// + sc_core::wait( m_cmd_received ); + //////////////////////////////// + + } // end infinite while +} // end execLoop() + ///////////////////////////////////////////////////////////////////////////////////// -// Constructor +// Interface function executed when receiving a command from VCI initiator[id]. +// It registers the command in the central buffer. +// The initiator thread is desceduled if the buffer is full. ///////////////////////////////////////////////////////////////////////////////////// -tmpl(/**/)::VciVgmn -( sc_core::sc_module_name module_name // module name - , const soclib::common::MappingTable &mt // mapping table - , size_t n_inits // number of inits - , size_t n_targets // number of targets - , size_t min_latency // minimal latency - , size_t fifo_depth // parameter do not used - ) - //: Interconnect(module_name,mt,soclib::common::IntTab(),n_inits,n_targets,min_latency) - : Interconnect(module_name,mt.getRoutingTable(soclib::common::IntTab(),0),mt.getIdMaskingTable(0),n_inits,n_targets,min_latency/2) +tmpl(tlm::tlm_sync_enum)::nb_transport_fw( int id, + tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &time) +{ + +#ifdef SOCLIB_MODULE_DEBUG +printf( " [%s] receive COMMAND from init %d / time = %d \n", + name(), id, (int)time.value() ); +#endif + + bool push = false; + do + { + // try to push a transaction in the central buffer + push = m_central_buffer.push( id, + payload, + phase, + time ); + if( not push ) + { + +#ifdef SOCLIB_MODULE_DEBUG +printf("###### [init %d] cannot push into VGMN buffer => deschedule \n", id); +#endif + /////////////////////////////////////// + sc_core::wait( sc_core::SC_ZERO_TIME ); + /////////////////////////////////////// + +#ifdef SOCLIB_MODULE_DEBUG +printf("###### [init %d] wake up \n", id); +#endif + + } + else + { + +#ifdef SOCLIB_MODULE_DEBUG +soclib_payload_extension *extension_ptr; +payload.get_extension(extension_ptr); +if( extension_ptr->is_active() || extension_ptr->is_inactive() ) { + m_push_activity_count++; + printf( " [%s] push ACTIVITY command into buffer\n", name() ); } +else if( extension_ptr->is_null_message() ) +{ + m_push_null_count++; + printf( " [%s] push NULL command into buffer\n", name() ); +} +else +{ + m_push_vci_count++; + printf( " [%s] push VCI command into buffer\n", name() ); +} +#endif + // notify to wake up the thread + m_cmd_received.notify( sc_core::SC_ZERO_TIME ); + } + } while ( not push ); + + return tlm::TLM_COMPLETED; + +} //end nb_transport_fw + +///////////////////////////////////////////////////////////////////////////////////// +// Interface function executed when receiving a response from VCI target[id]. +// It directly routes the response to the proper VCI initiator (no time filtering). +///////////////////////////////////////////////////////////////////////////////////// +tmpl(tlm::tlm_sync_enum)::nb_transport_bw( int id, + tlm::tlm_generic_payload &payload, + tlm::tlm_phase &phase, + sc_core::sc_time &time) +{ + // get message SRCID + soclib_payload_extension *resp_extension_ptr; + payload.get_extension(resp_extension_ptr); + + unsigned int srcid = resp_extension_ptr->get_src_id(); + +#ifdef SOCLIB_MODULE_DEBUG +printf(" [%s] receive VCI RESPONSE from target %d for init %d / time = %d\n", + name(), id, srcid, (int)time.value() ); +#endif + + // get destination +// unsigned int dest = m_rsp_routing_table[srcid]; + unsigned int dest = srcid; + + // update the transaction time + time = time + (m_latency*UNIT_TIME); + +#ifdef SOCLIB_MODULE_DEBUG +printf(" [%s] send VCI RESPONSE on port %d / time = %d\n", + name(), dest, (int)time.value() ); +#endif + + (*p_to_initiator[dest])->nb_transport_bw( payload, + phase, + time); + return tlm::TLM_COMPLETED; +} // end nb_transport_bw }}