Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / verif / model / vendor / TLM-2006-11-29 / tlm / tlm_ports / tlm_target_port.h
CommitLineData
86530b38
AT
1/*****************************************************************************
2
3 The following code is derived, directly or indirectly, from the SystemC
4 source code Copyright (c) 1996-2004 by all Contributors.
5 All Rights reserved.
6
7 The contents of this file are subject to the restrictions and limitations
8 set forth in the SystemC Open Source License Version 2.4 (the "License");
9 You may not use this file except in compliance with such restrictions and
10 limitations. You may obtain instructions on how to receive a copy of the
11 License at http://www.systemc.org/. Software distributed by Contributors
12 under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF
13 ANY KIND, either express or implied. See the License for the specific
14 language governing rights and limitations under the License.
15
16*****************************************************************************/
17
18#ifndef _TLM_TARGET_PORT_H_
19#define _TLM_TARGET_PORT_H_
20
21/*------------------------------------------------------------------------------
22 * Includes
23 *----------------------------------------------------------------------------*/
24#include <vector>
25
26#include "systemc.h"
27
28#include "tlm_ports/tlm_target_port_base.h"
29
30//----------------------------------------------------------------------------
31/// Class tlm_target_port: port to be instantiated on the target side
32/**
33 * This class could be used as base class for user defined target ports (support of user convenience layer).
34 * \n It provides new binding methods definition: sc_export to sc_export binding must be identified in order
35 * create tlm_target_port_base::target_port_list used target port ID propagation through hierarchical
36 * binding; the only port ID that makes sense is the port ID of the port directly bound to the interface.
37 * An error detection is also provided: multiple interface bind declarations are not detected by
38 * sc_export (the interface is just replaced), the new binding definition issues an error message in this
39 * case.
40 **/
41//----------------------------------------------------------------------------
42template<typename IF>
43class tlm_target_port :
44 public sc_export<IF>,
45 public tlm_target_port_base {
46
47 typedef IF interface_type;
48 typedef tlm_target_port<IF> target_port_type;
49 typedef tlm_target_port_base target_port_base_type;
50
51public:
52
53 //--------------
54 // Constructor
55 //--------------
56 tlm_target_port(const char * name);
57
58 //--------------------------------------------------------------------
59 /// @name sc_export overridden methods
60 /// Need to specialize binding operation to support port propagation in transaction recorders.
61 /// Specialization is done for sc_export/sc_export.
62 /// Other redefinitions of bindings are just calls to regular bind function
63 /// \n Note: This is due to non virtual definition of SystemC bind
64 //--------------------------------------------------------------------
65 /// @{
66 ///
67 //-------------------------------------------------------------------------------
68 // Before end of elaboration
69 /**
70 * Called just before end of elaboration to propagate the significant target port id:
71 * the only valid port id is the one set by the module which implements the tlm core interface.
72 *
73 * Remark: sc_port_base::complete_binding should be the best place to do
74 * that but this method is private !!
75 **/
76 //-------------------------------------------------------------------------------
77 void before_end_of_elaboration();
78
79 //-------------------------------------------------------------------------------
80 // End of elaboration
81 /**
82 * Called at the end of elaboration. Used to print debug message: content opf the target port list
83 **/
84 //-------------------------------------------------------------------------------
85 void end_of_elaboration();
86
87 //---------------------------------------------------------
88 // Special binding between two target ports
89 //---------------------------------------------------------
90
91 /// bind(sc_export) with target ports propagation
92 void bind(target_port_type& target_port_);
93
94 /// Case of the other port uses another interface as template: works only if OTHER_IF derives from IF
95 template<typename OTHER_IF>
96 void bind(tlm_target_port<OTHER_IF>& target_port_);
97
98 /// operator() (sc_export) overridden: just calls bind(sc_export)
99 void operator() (target_port_type& target_port_) {
100 bind(target_port_);
101 }
102
103 /// Case of the other port uses another interface as template: works only if OTHER_IF derives from IF
104 template<typename OTHER_IF>
105 void operator() (tlm_target_port<OTHER_IF>& target_port_) {
106 bind<OTHER_IF>(target_port_);
107 }
108
109
110 //---------------------------------------------------------
111 // Normal binding between port and interface.
112 // To be redefined here (bind(port_) is overridden above
113 //---------------------------------------------------------
114
115 /// bind(interface_type) overridden
116 void bind(interface_type& interface_);
117
118 /// operator() (interface_type) overridden
119 void operator() (interface_type& interface_);
120
121 /// @}
122
123protected:
124
125/** Returns true and issues an error message if the port is already bound to an interface during the
126 binding of other_if (called by bind(sc_export))
127**/
128 bool is_already_bound(sc_interface * other_if);
129
130};
131
132
133//--------------
134// Constructor
135//--------------
136
137template<typename IF>
138tlm_target_port<IF>::tlm_target_port(const char * name) :
139 sc_export<interface_type>(name)
140{}
141
142
143
144/* Return true and issue an error message if the port is already bound to an interface during the
145 binding of other_if (called by bind(sc_export))
146*/
147template<typename IF>
148bool tlm_target_port<IF>::is_already_bound(sc_interface * other_if) {
149 if (dynamic_cast<sc_interface * >(this->get_interface()) == NULL) return(false);
150 else {
151 std::string if_name1,if_name2 ;
152 sc_object * tmp = dynamic_cast<sc_object * >(other_if);
153 if (tmp) if_name1 = tmp->name();
154 else if_name1 = "unnamed interface (non sc_object)";
155 tmp = dynamic_cast<sc_object * >(this->get_interface());
156 if (tmp) if_name2 = tmp->name();
157 else if_name2 = "unnamed interface (non sc_object)";
158
159 std::string msg(sc_object::name());
160 msg += (std::string)(": tlm_target_port warning, Can't bind to \"") + if_name1;
161 msg += (std::string)("\" interface,the target port is already bound to this interface: \"");
162 msg += if_name2 + (std::string)("\"\n");
163 SC_REPORT_WARNING("binding warning",msg.c_str());
164
165 return(true);
166 }
167}
168
169//---------------------------
170// sc_export overridden methods
171//---------------------------
172
173//-------------------------------------------------------------------------------
174// before_end_of_elaboration()
175// Called just before end of elaboration to propagate the significant target port id
176// The only significant target port id is the one set by the module which implements the
177// tlm core interface
178//-------------------------------------------------------------------------------
179template<typename IF>
180void
181tlm_target_port<IF>::before_end_of_elaboration()
182{
183 // if this target port is not directly connected to the core interface
184 if (get_target_port_list().size() > 1) {
185
186 for(typename std::vector<target_port_base_type *>::iterator target_port = get_target_port_list().begin();
187 target_port != get_target_port_list().end();
188 target_port++) {
189 set_tlm_export_id((*target_port)->get_tlm_export_id()); // Propagate the target port id
190 }
191 }
192}
193
194//-------------------------------------------------------------------------------
195// end_of_elaboration(). Debug message concerning target port list centent
196//-------------------------------------------------------------------------------
197template<typename IF>
198void
199tlm_target_port<IF>::end_of_elaboration() {
200
201#ifdef TLM_PORT_DEBUG
202 printf("DEBUG\t\t%s: Registered target port list :\n",sc_object::name());
203 for(typename std::vector<target_port_base_type *>::iterator port = get_target_port_list().begin();
204 port != get_target_port_list().end();
205 port++) {
206 printf("DEBUG\t\t%s: \t- %s\n",sc_object::name(),(static_cast<target_port_type * >(*port))->name());
207 }
208 printf("DEBUG\t\t%s: -------------------------------------------------------\n",sc_object::name());
209#endif
210
211}
212//---------------------------------------------------------
213// Special binding between two target ports
214//---------------------------------------------------------
215
216// bind(sc_export)
217template<typename IF>
218void
219tlm_target_port<IF>::bind(target_port_type& target_port_)
220{
221 // If the target port is still not bound
222 if (!is_already_bound(target_port_.get_interface())) {
223 // Copy the list of registered target ports to the current bound port (port propagation)
224 for(typename std::vector<target_port_base_type *>::iterator target_port = target_port_.get_target_port_list().begin();
225 target_port != target_port_.get_target_port_list().end();
226 target_port++) {
227 this->register_target_port(*target_port);
228 }
229
230 // Calls sc_export standard bind method
231 sc_export<interface_type>::bind(target_port_);
232 }
233}
234
235// Specific case: if the bound export is based on a different interface. Requirement, the interface of
236// the bound export MUST derive from the interface the export is based on.
237template<typename IF>
238template<typename OTHER_IF>
239void
240tlm_target_port<IF>::bind(tlm_target_port<OTHER_IF>& target_port_) {
241 // Test if OTHER_IF derives from IF
242 IF * other_if = dynamic_cast<IF*>(target_port_.get_interface());
243 if (other_if) {
244 // If the target port is still not bound
245 if (!is_already_bound(target_port_.get_interface())) {
246 // Copy the list of registered target ports to the current bound port (port propagation)
247 for(typename std::vector<target_port_base_type *>::iterator target_port = target_port_.get_target_port_list().begin();
248 target_port != target_port_.get_target_port_list().end();
249 target_port++) {
250 this->register_target_port(*target_port);
251 }
252
253 // Calls sc_export standard bind method
254 sc_export<interface_type>::bind(*other_if);
255 }
256 }
257 else {
258 std::string msg(sc_object::name());
259 msg += (std::string)(": tlm_target_port error, incompatible interface detected during the binding tlm_target_port \"") + (std::string)(this->name());
260 msg += (std::string)" to tlm_target_port \"" + (std::string)(target_port_.name()) +(std::string)("\"\n") ;
261 SC_REPORT_ERROR("bind export to export failed",msg.c_str());
262 }
263
264}
265
266
267//---------------------------------------------------------
268// Normal binding between port and interface.
269// To be redefined here (bind(port_) is overridden above
270//---------------------------------------------------------
271
272// bind(interface_type)
273template<typename IF>
274void
275tlm_target_port<IF>::bind(interface_type& interface_) {
276 // Calls sc_export standard bind method
277 sc_export<interface_type>::bind(interface_);
278}
279
280// operator() (interface_type): just calls bind(interface_type)
281template<typename IF>
282void
283tlm_target_port<IF>::operator() (interface_type& interface_) {
284 sc_export<interface_type>::bind(interface_);
285}
286
287#endif /* _TLM_TARGET_PORT_H_ */