SystemC-Components-Test/tests/configuration/router.h

180 lines
7.8 KiB
C
Raw Normal View History

/*****************************************************************************
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>
2023-12-22 20:42:21 +01:00
#include <iomanip>
#include <sstream>
#include <tlm>
#include <vector>
#include <tlm_utils/multi_passthrough_initiator_socket.h>
2023-12-22 20:42:21 +01:00
#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)
2023-12-22 20:42:21 +01:00
: 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();
2023-12-22 20:42:21 +01:00
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
2023-12-22 20:42:21 +01:00
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)));
}
2023-12-22 20:42:21 +01:00
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);
2023-12-22 20:42:21 +01:00
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
2023-12-22 20:42:21 +01:00
<< 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
2023-12-22 20:42:21 +01:00
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();
2023-12-22 20:42:21 +01:00
if(addr >= static_cast<sc_dt::uint64>(addr_limit.get_value())) {
trans.set_response_status(tlm::TLM_ADDRESS_ERROR_RESPONSE);
return;
}
2023-12-22 20:42:21 +01:00
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;
2023-12-22 20:42:21 +01:00
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
2023-12-22 20:42:21 +01:00
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];
};
2024-12-18 19:23:05 +01:00
// router
2023-12-22 20:42:21 +01:00
#endif // EXAMPLES_EX09_HIERARCHICAL_OVERRIDE_OF_PARAMETER_VALUES_ROUTER_H_