/***************************************************************************** Licensed to Accellera Systems Initiative Inc. (Accellera) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. Accellera licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ****************************************************************************/ /** * @file router.h * @brief Definition of the router module. * This file declares and implements the functionality of the router. * Few of the parameters of the target and initiator sc_module(s) are * configured by the router sc_module * @authors P V S Phaneendra, CircuitSutra Technologies <pvs@circuitsutra.com> * @date 29th April, 2011 (Friday) */ #ifndef EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_ROUTER_H_ #define EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_ROUTER_H_ #ifdef _MSC_VER #define snprintf _snprintf #endif #include <cci_configuration> #include <iomanip> #include <sstream> #include <tlm> #include <vector> #include <tlm_utils/multi_passthrough_initiator_socket.h> #include <tlm_utils/multi_passthrough_target_socket.h> /** * @class router * @brief Thes module implements a router functionality */ SC_MODULE(router) { public: // Declare tlm multi-passthrough sockets for target and initiator modules tlm_utils::multi_passthrough_target_socket<router, 32> Router_target; tlm_utils::multi_passthrough_initiator_socket<router, 32> Router_initiator; /** * @fn router * @brief The class constructor * @return void */ SC_CTOR(router) : Router_target("Router_target") , Router_initiator("Router_initiator") , r_initiators("r_initiators", 0) , r_targets("r_targets", 0) , addr_limit("addr_max", 64) , m_broker(cci::cci_get_broker()) , addrSize(0) { SCCINFO(SCMOD) << "[ROUTER C_TOR] ----- [ROUTER CONSTRUCTOR BEGINS HERE] ------"; // Register b_transport Router_target.register_b_transport(this, &router::b_transport); } /** * @fn void before_end_of_elaboration(void) * @brief The router table information is filled in during this function * @return void */ void before_end_of_elaboration(void) { SCCINFO(SCMOD) << "[ROUTER in beoe] : Number of initiator(s) : " << r_initiators.get_cci_value().to_json(); SCCINFO(SCMOD) << "[ROUTER in beoe] : Number of target(s) : " << r_targets.get_value(); SCCINFO(SCMOD) << "[ROUTER in beoe] : Maximum Addressable Limit of the router : " << addr_limit.get_value(); char targetName[10]; ///< Holds router table's fields' names addrSize = (unsigned int)(addr_limit.get_value() / r_targets); // Printing the Router Table contents SCCINFO(SCMOD) << "============= ROUTER TABLE INFORMATION =============="; SCCINFO(SCMOD) << "-----------------------------------------------------"; SCCINFO(SCMOD) << "| Target ID | Start Addr | End Addr | Base Addr |"; SCCINFO(SCMOD) << "-----------------------------------------------------"; // Sets the contents of the routing table with (default) values // calculated within 'beoe' phase for(int i = 0; i < r_targets; i++) { snprintf(targetName, sizeof(targetName), "r_index_%d", i); r_target_index.push_back(new cci::cci_param<unsigned int, cci::CCI_IMMUTABLE_PARAM>(targetName, i)); snprintf(targetName, sizeof(targetName), "r_sa_%d", i); r_addr_start.push_back(new cci::cci_param<unsigned int, cci::CCI_IMMUTABLE_PARAM>(targetName, (i * addrSize))); snprintf(targetName, sizeof(targetName), "r_ea_%d", i); r_addr_end.push_back(new cci::cci_param<unsigned int, cci::CCI_IMMUTABLE_PARAM>(targetName, ((i + 1) * addrSize - 1))); } for(int i = 0; i < r_targets; i++) { snprintf(stringName, sizeof(stringName), "top_module_inst.target_%d.s_base_addr", i); base_handle = m_broker.get_param_handle(stringName); if(!base_handle.is_valid()) { sc_assert(!"target Base Address Handle returned is NULL"); } std::stringstream row_ss; row_ss << "| " << std::setw(10) << r_target_index[i]->get_value() << " | " << std::setw(10) << std::hex << std::showbase << r_addr_start[i]->get_value() << " | " << std::setw(10) << r_addr_end[i]->get_value() << " | " << std::setw(10) << base_handle.get_cci_value().to_json() << " |"; SCCINFO(SCMOD) << row_ss.str().c_str(); SCCINFO(SCMOD) << "-----------------------------------------------------"; } } // Blocking transport implementation of the router void b_transport(int i_, tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) { wait(delay); delay = sc_core::SC_ZERO_TIME; sc_dt::uint64 addr = trans.get_address(); if(addr >= static_cast<sc_dt::uint64>(addr_limit.get_value())) { trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE); return; } for(unsigned int i = 0; i < r_target_index.size(); i++) { if((addr >= (r_addr_start[i]->get_value())) && (addr <= (r_addr_end[i]->get_value()))) { SCCINFO(SCMOD) << "[Router in 'b_transport' layer]"; SCCINFO(SCMOD) << "Address = " << std::hex << addr; SCCINFO(SCMOD) << "Index = " << (r_target_index[i])->get_value(); SCCINFO(SCMOD) << "Start addres = " << std::hex << (r_addr_start[i]->get_value()); SCCINFO(SCMOD) << "End Address = " << std::hex << (r_addr_end[i]->get_value()); Router_initiator[(r_target_index[i])->get_value()]->b_transport(trans, delay); break; } } } private: /// Demonstrates Model-to-Model Configuration (UC12) /// Elaboration Time Parameters for setting up the model hierarcy; cci::cci_param<int, cci::CCI_MUTABLE_PARAM> r_initiators; ///< initiator ID assigned by the top_module upon instantiation cci::cci_param<int, cci::CCI_MUTABLE_PARAM> r_targets; ///< target ID assigned by the top_module upon instantiation cci::cci_param<unsigned int, cci::CCI_MUTABLE_PARAM> addr_limit; ///< Router Addressing Range cci::cci_broker_handle m_broker; ///< CCI configuration broker handle /// Router Table contents holding targets related information std::vector<cci::cci_param<unsigned int, cci::CCI_IMMUTABLE_PARAM>*> r_target_index; ///< Router table target index std::vector<cci::cci_param<unsigned int, cci::CCI_IMMUTABLE_PARAM>*> r_addr_start; ///< Router table start address std::vector<cci::cci_param<unsigned int, cci::CCI_IMMUTABLE_PARAM>*> r_addr_end; ///< Router table end address cci::cci_param_handle base_handle; ///< CCI base parameter handle for target base address /** * @fn void end_of_elaboration() * @brief end of elaboration function to lock structural param * @return void */ void end_of_elaboration() { r_initiators.lock(); r_targets.lock(); } int addrSize; char stringName[50]; }; // router #endif // EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_ROUTER_H_