112855Sgabeblack@google.com/***************************************************************************** 212855Sgabeblack@google.com 312855Sgabeblack@google.com Licensed to Accellera Systems Initiative Inc. (Accellera) under one or 412855Sgabeblack@google.com more contributor license agreements. See the NOTICE file distributed 512855Sgabeblack@google.com with this work for additional information regarding copyright ownership. 612855Sgabeblack@google.com Accellera licenses this file to you under the Apache License, Version 2.0 712855Sgabeblack@google.com (the "License"); you may not use this file except in compliance with the 812855Sgabeblack@google.com License. You may obtain a copy of the License at 912855Sgabeblack@google.com 1012855Sgabeblack@google.com http://www.apache.org/licenses/LICENSE-2.0 1112855Sgabeblack@google.com 1212855Sgabeblack@google.com Unless required by applicable law or agreed to in writing, software 1312855Sgabeblack@google.com distributed under the License is distributed on an "AS IS" BASIS, 1412855Sgabeblack@google.com WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 1512855Sgabeblack@google.com implied. See the License for the specific language governing 1612855Sgabeblack@google.com permissions and limitations under the License. 1712855Sgabeblack@google.com 1812855Sgabeblack@google.com *****************************************************************************/ 1912855Sgabeblack@google.com 2012855Sgabeblack@google.com// sc_vector.cpp -- test for 2112855Sgabeblack@google.com// 2212855Sgabeblack@google.com// Original Author: John Aynsley, Doulos, Inc. 2312855Sgabeblack@google.com// 2412855Sgabeblack@google.com// MODIFICATION LOG - modifiers, enter your name, affiliation, date and 2512855Sgabeblack@google.com// 2612855Sgabeblack@google.com// $Log: sc_vector.cpp,v $ 2712855Sgabeblack@google.com// Revision 1.3 2011/07/24 16:04:12 acg 2812855Sgabeblack@google.com// Philipp A. Hartmann: remove assert() that does not test the correct thing. 2912855Sgabeblack@google.com// 3012855Sgabeblack@google.com// Revision 1.2 2011/05/08 19:18:46 acg 3112855Sgabeblack@google.com// Andy Goodrich: remove extraneous + prefixes from git diff. 3212855Sgabeblack@google.com// 3312855Sgabeblack@google.com 3412855Sgabeblack@google.com// sc_vector 3512855Sgabeblack@google.com 3612855Sgabeblack@google.com#define SC_INCLUDE_DYNAMIC_PROCESSES 3712855Sgabeblack@google.com#include <systemc> 3812855Sgabeblack@google.com#include <cstring> 3912855Sgabeblack@google.com 4012855Sgabeblack@google.comusing namespace sc_core; 4112855Sgabeblack@google.comusing std::cout; 4212855Sgabeblack@google.comusing std::endl; 4312855Sgabeblack@google.comusing std::string; 4412855Sgabeblack@google.com 4512855Sgabeblack@google.comstruct Sub: sc_module 4612855Sgabeblack@google.com{ 4712855Sgabeblack@google.com sc_inout<int> p; 4812855Sgabeblack@google.com 4912855Sgabeblack@google.com Sub(sc_module_name) 5012855Sgabeblack@google.com { 5112855Sgabeblack@google.com SC_THREAD(T); 5212855Sgabeblack@google.com } 5312855Sgabeblack@google.com 5412855Sgabeblack@google.com void T() 5512855Sgabeblack@google.com { 5612855Sgabeblack@google.com for (;;) 5712855Sgabeblack@google.com { 5812855Sgabeblack@google.com wait(p.default_event()); 5912855Sgabeblack@google.com } 6012855Sgabeblack@google.com } 6112855Sgabeblack@google.com 6212855Sgabeblack@google.com SC_HAS_PROCESS(Sub); 6312855Sgabeblack@google.com}; 6412855Sgabeblack@google.com 6512855Sgabeblack@google.com 6612855Sgabeblack@google.comstruct my_module: sc_module 6712855Sgabeblack@google.com{ 6812855Sgabeblack@google.com my_module(sc_module_name n, string weird_arg ) 6912855Sgabeblack@google.com { 7012855Sgabeblack@google.com sc_assert( weird_arg == "The Creator" || weird_arg == "WeIrD_aRg" ); 7112855Sgabeblack@google.com } 7212855Sgabeblack@google.com}; 7312855Sgabeblack@google.com 7412855Sgabeblack@google.com 7512855Sgabeblack@google.comstruct my_object: sc_object 7612855Sgabeblack@google.com{ 7712855Sgabeblack@google.com my_object() : sc_object() {} 7812855Sgabeblack@google.com my_object(const char* c) : sc_object(c) {} 7912855Sgabeblack@google.com}; 8012855Sgabeblack@google.com 8112855Sgabeblack@google.com 8212855Sgabeblack@google.comstruct i_f: virtual sc_interface 8312855Sgabeblack@google.com{ 8412855Sgabeblack@google.com virtual void method() = 0; 8512855Sgabeblack@google.com}; 8612855Sgabeblack@google.com 8712855Sgabeblack@google.com 8812855Sgabeblack@google.comstruct Initiator: sc_module 8912855Sgabeblack@google.com{ 9012855Sgabeblack@google.com sc_vector<sc_port<i_f> > ports; 9112855Sgabeblack@google.com 9212855Sgabeblack@google.com Initiator(sc_module_name) 9312855Sgabeblack@google.com : ports("ports", 4) 9412855Sgabeblack@google.com { 9512855Sgabeblack@google.com SC_THREAD(T); 9612855Sgabeblack@google.com } 9712855Sgabeblack@google.com 9812855Sgabeblack@google.com void T() 9912855Sgabeblack@google.com { 10012855Sgabeblack@google.com for (unsigned int i = 0; i < ports.size(); i++) // Use method size() with vector 10112855Sgabeblack@google.com { 10212855Sgabeblack@google.com wait(10, SC_NS); 10312855Sgabeblack@google.com ports[i]->method(); // Use operator[] with vector 10412855Sgabeblack@google.com } 10512855Sgabeblack@google.com } 10612855Sgabeblack@google.com SC_HAS_PROCESS(Initiator); 10712855Sgabeblack@google.com}; 10812855Sgabeblack@google.com 10912855Sgabeblack@google.com 11012855Sgabeblack@google.comstruct Initiator1: sc_module 11112855Sgabeblack@google.com{ 11212855Sgabeblack@google.com sc_port<i_f> port; 11312855Sgabeblack@google.com 11412855Sgabeblack@google.com Initiator1(sc_module_name) 11512855Sgabeblack@google.com : port("port") 11612855Sgabeblack@google.com { 11712855Sgabeblack@google.com SC_THREAD(T); 11812855Sgabeblack@google.com } 11912855Sgabeblack@google.com 12012855Sgabeblack@google.com void T() 12112855Sgabeblack@google.com { 12212855Sgabeblack@google.com wait(10, SC_NS); 12312855Sgabeblack@google.com port->method(); 12412855Sgabeblack@google.com } 12512855Sgabeblack@google.com SC_HAS_PROCESS(Initiator1); 12612855Sgabeblack@google.com}; 12712855Sgabeblack@google.com 12812855Sgabeblack@google.com 12912855Sgabeblack@google.comstruct Target: public sc_module, private i_f 13012855Sgabeblack@google.com{ 13112855Sgabeblack@google.com sc_export<i_f> xp; 13212855Sgabeblack@google.com 13312855Sgabeblack@google.com Target(sc_module_name) 13412855Sgabeblack@google.com : xp("xp") 13512855Sgabeblack@google.com { 13612855Sgabeblack@google.com xp.bind( *this ); 13712855Sgabeblack@google.com } 13812855Sgabeblack@google.com 13912855Sgabeblack@google.com virtual void method() { 14012855Sgabeblack@google.com cout << "Called method() in " << name() << " at " << sc_time_stamp() << endl; 14112855Sgabeblack@google.com } 14212855Sgabeblack@google.com}; 14312855Sgabeblack@google.com 14412855Sgabeblack@google.com 14512855Sgabeblack@google.comtypedef sc_vector<sc_inout<int> > port_type; 14612855Sgabeblack@google.com 14712855Sgabeblack@google.comstruct M: sc_module 14812855Sgabeblack@google.com{ 14912855Sgabeblack@google.com port_type ports; // Vector-of-ports 15012855Sgabeblack@google.com 15112855Sgabeblack@google.com sc_vector<Sub> kids; // Vector-of-modules, each with a port p 15212855Sgabeblack@google.com sc_vector<Sub> kids2; 15312855Sgabeblack@google.com sc_vector<sc_signal<int> > sigs2; 15412855Sgabeblack@google.com sc_vector<sc_signal<int> > sigs3; 15512855Sgabeblack@google.com 15612855Sgabeblack@google.com int dim; 15712855Sgabeblack@google.com 15812855Sgabeblack@google.com Initiator* initiator; 15912855Sgabeblack@google.com sc_vector<Target> targets; 16012855Sgabeblack@google.com 16112855Sgabeblack@google.com sc_vector<Initiator1> initiator_vec; 16212855Sgabeblack@google.com sc_vector<Target> target_vec; 16312855Sgabeblack@google.com 16412855Sgabeblack@google.com 16512855Sgabeblack@google.com sc_vector<my_module> my_vec_of_modules; 16612855Sgabeblack@google.com 16712855Sgabeblack@google.com struct my_module_creator 16812855Sgabeblack@google.com { 16912855Sgabeblack@google.com my_module_creator( string arg ) : weird_arg(arg) {} 17012855Sgabeblack@google.com 17112855Sgabeblack@google.com my_module* operator() (const char* name, size_t) 17212855Sgabeblack@google.com { 17312855Sgabeblack@google.com return new my_module(name, weird_arg ); 17412855Sgabeblack@google.com } 17512855Sgabeblack@google.com string weird_arg; 17612855Sgabeblack@google.com }; 17712855Sgabeblack@google.com 17812855Sgabeblack@google.com sc_vector<my_module> my_vec_of_modules2; 17912855Sgabeblack@google.com 18012855Sgabeblack@google.com // If creator is not a function object, it could be a function 18112855Sgabeblack@google.com my_module* my_module_creator_func( const char* name, size_t i ) 18212855Sgabeblack@google.com { 18312855Sgabeblack@google.com creator_func_called = true; 18412855Sgabeblack@google.com return new my_module( name, "WeIrD_aRg" ); 18512855Sgabeblack@google.com } 18612855Sgabeblack@google.com 18712855Sgabeblack@google.com bool creator_func_called; 18812855Sgabeblack@google.com 18912855Sgabeblack@google.com 19012855Sgabeblack@google.com M(sc_module_name _name, int N) 19112855Sgabeblack@google.com : ports("ports", N) 19212855Sgabeblack@google.com , kids("kids") // Construct the vector with name seed "kids" 19312855Sgabeblack@google.com , kids2("kids2", 8) 19412855Sgabeblack@google.com , sigs2("sigs2", 4) 19512855Sgabeblack@google.com , sigs3("sigs3", 4) 19612855Sgabeblack@google.com , dim(N) 19712855Sgabeblack@google.com , targets("targets", N) 19812855Sgabeblack@google.com , initiator_vec("initiator_vec", N) 19912855Sgabeblack@google.com , target_vec("target_vec", N) 20012855Sgabeblack@google.com , my_vec_of_modules("my_vec_of_modules") 20112855Sgabeblack@google.com , creator_func_called(false) 20212855Sgabeblack@google.com { 20312855Sgabeblack@google.com //vec.init(N); // Alternative initialization (instead of passing N to ctor) 20412855Sgabeblack@google.com kids.init(N); 20512855Sgabeblack@google.com 20612855Sgabeblack@google.com sc_assert( ports.size() == static_cast<unsigned int>(N) ); 20712855Sgabeblack@google.com sc_assert( kids.size() == static_cast<unsigned int>(N) ); 20812855Sgabeblack@google.com 20912855Sgabeblack@google.com // Using vector view to create vector-of-ports 21012855Sgabeblack@google.com sc_assemble_vector(kids, &Sub::p).bind( ports ); 21112855Sgabeblack@google.com 21212855Sgabeblack@google.com for (unsigned int i = 0; i < kids.size(); i++) 21312855Sgabeblack@google.com { 21412855Sgabeblack@google.com sc_assert( kids[i].p.get_interface() == ports[i].get_interface() ); 21512855Sgabeblack@google.com } 21612855Sgabeblack@google.com 21712855Sgabeblack@google.com initiator = new Initiator("initiator"); 21812855Sgabeblack@google.com 21912855Sgabeblack@google.com // Using vector view to create vector-of-exports 22012855Sgabeblack@google.com initiator->ports.bind( sc_assemble_vector(targets, &Target::xp) ); 22112855Sgabeblack@google.com 22212855Sgabeblack@google.com // Double whammy 22312855Sgabeblack@google.com sc_assemble_vector(initiator_vec, &Initiator1::port).bind( sc_assemble_vector(target_vec, &Target::xp) ); 22412855Sgabeblack@google.com 22512855Sgabeblack@google.com // sc_vector_view has no public constructors, though it is copyable 22612855Sgabeblack@google.com sc_vector_assembly< Initiator1, sc_port<i_f> > assembly = sc_assemble_vector(initiator_vec, &Initiator1::port); 22712855Sgabeblack@google.com 22812855Sgabeblack@google.com sc_assert( &*(assembly.begin()) == &(*initiator_vec.begin()).port ); 22912855Sgabeblack@google.com // sc_assert( &*(assembly.end()) == &(*initiator_vec.end()).port ); 23012855Sgabeblack@google.com sc_assert( assembly.size() == initiator_vec.size() ); 23112855Sgabeblack@google.com for (unsigned int i = 0; i < assembly.size(); i++) 23212855Sgabeblack@google.com { 23312855Sgabeblack@google.com sc_assert( &assembly[i] == &initiator_vec[i].port ); 23412855Sgabeblack@google.com sc_assert( &assembly.at(i) == &initiator_vec[i].port ); 23512855Sgabeblack@google.com } 23612855Sgabeblack@google.com 23712855Sgabeblack@google.com std::vector<sc_object*> elements; 23812855Sgabeblack@google.com 23912855Sgabeblack@google.com // sc_vector_view (aka sc_vector_assembly) acts as a proxy for sc_vector 24012855Sgabeblack@google.com // It has begin() end() size() operator[] bind() etc 24112855Sgabeblack@google.com 24212855Sgabeblack@google.com elements = assembly.get_elements(); 24312855Sgabeblack@google.com for ( unsigned i = 0; i < elements.size(); i++ ) 24412855Sgabeblack@google.com if ( elements[i] ) 24512855Sgabeblack@google.com sc_assert( elements[i] == &initiator_vec[i].port ); 24612855Sgabeblack@google.com 24712855Sgabeblack@google.com elements = ports.get_elements(); 24812855Sgabeblack@google.com for ( unsigned i = 0; i < elements.size(); i++ ) 24912855Sgabeblack@google.com if ( elements[i] ) 25012855Sgabeblack@google.com sc_assert( elements[i] == &ports[i] ); 25112855Sgabeblack@google.com 25212855Sgabeblack@google.com elements = sc_assemble_vector(initiator_vec, &Initiator1::port).get_elements(); 25312855Sgabeblack@google.com for ( unsigned i = 0; i < elements.size(); i++ ) 25412855Sgabeblack@google.com if ( elements[i] ) 25512855Sgabeblack@google.com sc_assert( elements[i] == &initiator_vec[i].port ); 25612855Sgabeblack@google.com 25712855Sgabeblack@google.com // Additional method to support a vector iterator as an offset 25812855Sgabeblack@google.com sc_assemble_vector(kids2, &Sub::p).bind( sigs2.begin(), sigs2.end(), kids2.begin()); 25912855Sgabeblack@google.com sc_assemble_vector(kids2, &Sub::p).bind( sigs3.begin(), sigs3.end(), kids2.begin() + 4 ); 26012855Sgabeblack@google.com 26112855Sgabeblack@google.com // Construct elements of sc_vector, passing through ctor arguments to user-defined sc_module 26212855Sgabeblack@google.com my_vec_of_modules.init(N, my_module_creator("The Creator")); 26312855Sgabeblack@google.com 26412855Sgabeblack@google.com // Alternatively, instead of a function object pass in a function 26512855Sgabeblack@google.com my_vec_of_modules2.init(N, sc_bind( &M::my_module_creator_func, this, sc_unnamed::_1, sc_unnamed::_2 ) ); 26612855Sgabeblack@google.com 26712855Sgabeblack@google.com // Well-formedness check on creator function call 26812855Sgabeblack@google.com my_module_creator foo("The Creator"); 26912855Sgabeblack@google.com const char* nm = "foo"; 27012855Sgabeblack@google.com unsigned int idx = 0; 27112855Sgabeblack@google.com my_module* next = foo( (const char*)nm, (sc_vector<my_module>::size_type)idx ); 27212855Sgabeblack@google.com char buf[80]; 27312855Sgabeblack@google.com strcpy(buf, this->name()); 27412855Sgabeblack@google.com strcat(buf, ".foo"); 27512855Sgabeblack@google.com sc_assert( strcmp(next->name(), buf) == 0 ); 27612855Sgabeblack@google.com delete next; 27712855Sgabeblack@google.com 27812855Sgabeblack@google.com SC_THREAD(T); 27912855Sgabeblack@google.com } 28012855Sgabeblack@google.com 28112855Sgabeblack@google.com void T() 28212855Sgabeblack@google.com { 28312855Sgabeblack@google.com int j = 0; 28412855Sgabeblack@google.com for (int i = 0; i < 10; i++) 28512855Sgabeblack@google.com { 28612855Sgabeblack@google.com wait(10, SC_NS); 28712855Sgabeblack@google.com ports[i % dim].write((j++) % 10); // Use operator[] with vector 28812855Sgabeblack@google.com } 28912855Sgabeblack@google.com } 29012855Sgabeblack@google.com 29112855Sgabeblack@google.com SC_HAS_PROCESS(M); 29212855Sgabeblack@google.com}; 29312855Sgabeblack@google.com 29412855Sgabeblack@google.comstruct Top: sc_module 29512855Sgabeblack@google.com{ 29612855Sgabeblack@google.com sc_vector<sc_signal<int> > sigs; // Vector-of-signals 29712855Sgabeblack@google.com sc_vector<sc_signal<int> > more_sigs; // Vector-of-signals 29812855Sgabeblack@google.com sc_vector<sc_signal<int> > hi_sigs; // Vector-of-signals 29912855Sgabeblack@google.com sc_vector<sc_signal<int> > lo_sigs; // Vector-of-signals 30012855Sgabeblack@google.com 30112855Sgabeblack@google.com M *m1, *m2, *m3; 30212855Sgabeblack@google.com 30312855Sgabeblack@google.com Top(sc_module_name _name) 30412855Sgabeblack@google.com : sigs("sigs", 4) 30512855Sgabeblack@google.com , more_sigs("more_sigs", 4) 30612855Sgabeblack@google.com , hi_sigs("hi_sigs", 2) 30712855Sgabeblack@google.com , lo_sigs("lo_sigs", 2) 30812855Sgabeblack@google.com { 30912855Sgabeblack@google.com m1 = new M("m1", 4); 31012855Sgabeblack@google.com m2 = new M("m2", 4); 31112855Sgabeblack@google.com m3 = new M("m3", 4); 31212855Sgabeblack@google.com 31312855Sgabeblack@google.com for (int i = 0; i < 4; i++) 31412855Sgabeblack@google.com m1->ports[i].bind( sigs[i] ); // Using operator[] with a vector 31512855Sgabeblack@google.com 31612855Sgabeblack@google.com port_type::iterator it = m2->ports.bind( more_sigs ); // Vector-to-vector bind 31712855Sgabeblack@google.com sc_assert( (it - m2->ports.begin()) == 4 ); 31812855Sgabeblack@google.com 31912855Sgabeblack@google.com // Bind upper half of ports vector to hi_sigs 32012855Sgabeblack@google.com it = m3->ports.bind( hi_sigs.begin(), hi_sigs.end() ); 32112855Sgabeblack@google.com sc_assert( (it - m3->ports.begin()) == 2 ); 32212855Sgabeblack@google.com 32312855Sgabeblack@google.com // Bind lower half of ports vector to lo_sigs 32412855Sgabeblack@google.com it = m3->ports.bind( lo_sigs.begin(), lo_sigs.end(), it); 32512855Sgabeblack@google.com sc_assert( (it - m3->ports.begin()) == 4 ); 32612855Sgabeblack@google.com 32712855Sgabeblack@google.com SC_THREAD(T); 32812855Sgabeblack@google.com SC_THREAD(T2); 32912855Sgabeblack@google.com } 33012855Sgabeblack@google.com 33112855Sgabeblack@google.com void T() 33212855Sgabeblack@google.com { 33312855Sgabeblack@google.com sc_event_or_list list; 33412855Sgabeblack@google.com for (int i = 0; i < 4; i++) 33512855Sgabeblack@google.com list |= sigs[i].default_event(); 33612855Sgabeblack@google.com for (;;) 33712855Sgabeblack@google.com { 33812855Sgabeblack@google.com wait(list); 33912855Sgabeblack@google.com cout << "Top:" << sigs[0] << sigs[1] << sigs[2] << sigs[3] << endl; 34012855Sgabeblack@google.com } 34112855Sgabeblack@google.com } 34212855Sgabeblack@google.com 34312855Sgabeblack@google.com 34412855Sgabeblack@google.com void T2() 34512855Sgabeblack@google.com { 34612855Sgabeblack@google.com wait(10, SC_US); 34712855Sgabeblack@google.com 34812855Sgabeblack@google.com // Create sc_vector during simulation 34912855Sgabeblack@google.com sc_vector<my_object> vec_obj("vec_obj", 4); 35012855Sgabeblack@google.com sc_assert( vec_obj.size() == 4 ); 35112855Sgabeblack@google.com for (unsigned int i = 0; i < vec_obj.size(); i++) 35212855Sgabeblack@google.com cout << "vec_obj[" << i << "].name() = " << vec_obj[i].name() << endl; 35312855Sgabeblack@google.com 35412855Sgabeblack@google.com sc_object* proc = sc_get_current_process_handle().get_process_object(); 35512855Sgabeblack@google.com std::vector<sc_object*> children = proc->get_child_objects(); 35612855Sgabeblack@google.com 35712855Sgabeblack@google.com sc_assert( children.size() == 5 ); // sc_vector itself + 4 X my_object 35812855Sgabeblack@google.com } 35912855Sgabeblack@google.com 36012855Sgabeblack@google.com SC_HAS_PROCESS(Top); 36112855Sgabeblack@google.com}; 36212855Sgabeblack@google.com 36312855Sgabeblack@google.com 36412855Sgabeblack@google.comint sc_main(int argc, char* argv[]) 36512855Sgabeblack@google.com{ 36612855Sgabeblack@google.com Top top("top"); 36712855Sgabeblack@google.com 36812855Sgabeblack@google.com std::vector<sc_object*> children = top.get_child_objects(); 36912855Sgabeblack@google.com sc_assert( children.size() == 21 ); // sc_vectors themselves are sc_objects 37012855Sgabeblack@google.com 37112855Sgabeblack@google.com sc_start(); 37212855Sgabeblack@google.com 37312855Sgabeblack@google.com sc_assert( top.m1->creator_func_called ); 37412855Sgabeblack@google.com sc_assert( top.m2->creator_func_called ); 37512855Sgabeblack@google.com sc_assert( top.m3->creator_func_called ); 37612855Sgabeblack@google.com 37712855Sgabeblack@google.com cout << endl << "Success" << endl; 37812855Sgabeblack@google.com return 0; 37912855Sgabeblack@google.com} 38012855Sgabeblack@google.com 381