1919
2020#include < limits>
2121#include < scc/utilities.h>
22+ #include < scc/report.h>
2223#include < sysc/utils/sc_vector.h>
2324#include < tlm.h>
2425#include < tlm/scc/initiator_mixin.h>
@@ -51,8 +52,9 @@ template <unsigned BUSWIDTH = LT, typename TARGET_SOCKET_TYPE = tlm::tlm_target_
5152 * @param nm the component name
5253 * @param slave_cnt number of slaves to be connected
5354 * @param master_cnt number of masters to be connected
55+ * @param check_overlap_on_add_target if true this enables validation of overlaps when adding or setting the target range.
5456 */
55- router (const sc_core::sc_module_name& nm, size_t slave_cnt = 1 , size_t master_cnt = 1 );
57+ router (const sc_core::sc_module_name& nm, size_t slave_cnt = 1 , size_t master_cnt = 1 , bool check_overlap_on_add_target = false );
5658
5759 ~router () = default ;
5860 /* *
@@ -68,7 +70,6 @@ template <unsigned BUSWIDTH = LT, typename TARGET_SOCKET_TYPE = tlm::tlm_target_
6870 */
6971 template <typename TYPE> void bind_target (TYPE& socket, size_t idx, uint64_t base, uint64_t size, bool remap = true ) {
7072 set_target_range (idx, base, size, remap);
71- set_target_name (idx, socket.basename ());
7273 initiator[idx].bind (socket);
7374 }
7475 /* *
@@ -81,7 +82,6 @@ template <unsigned BUSWIDTH = LT, typename TARGET_SOCKET_TYPE = tlm::tlm_target_
8182 * @param name of the binding
8283 */
8384 template <typename TYPE> void bind_target (TYPE& socket, size_t idx, std::string name) {
84- set_target_name (idx, name);
8585 initiator[idx].bind (socket);
8686 }
8787 /* *
@@ -132,6 +132,13 @@ template <unsigned BUSWIDTH = LT, typename TARGET_SOCKET_TYPE = tlm::tlm_target_
132132 * @param remap if true address will be rewritten in accesses to be 0-based at the target
133133 */
134134 void set_target_range (size_t idx, uint64_t base, uint64_t size, bool remap = true );
135+ /* *
136+ * @fn void set_warn_on_address_error(bool)
137+ * @brief enable warning message on address not found error
138+ *
139+ * @param enable if true enable warning message
140+ */
141+ void set_warn_on_address_error (bool enable) { warn_on_address_error = enable; }
135142 /* *
136143 * @fn void b_transport(int, tlm::tlm_generic_payload&, sc_core::sc_time&)
137144 * @brief tagged blocking transport method
@@ -169,6 +176,12 @@ template <unsigned BUSWIDTH = LT, typename TARGET_SOCKET_TYPE = tlm::tlm_target_
169176 */
170177 void invalidate_direct_mem_ptr (int id, ::sc_dt::uint64 start_range, ::sc_dt::uint64 end_range);
171178
179+ /* *
180+ * @fn void end_of_elaboration()
181+ * @brief tagged end of elaboration callback.
182+ */
183+ void end_of_elaboration () override ;
184+
172185protected:
173186 struct range_entry {
174187 uint64_t base, size;
@@ -180,17 +193,20 @@ template <unsigned BUSWIDTH = LT, typename TARGET_SOCKET_TYPE = tlm::tlm_target_
180193 std::vector<sc_core::sc_mutex> mutexes;
181194 util::range_lut<unsigned > addr_decoder;
182195 std::unordered_map<std::string, size_t > target_name_lut;
196+ bool check_overlap_on_add_target;
197+ bool warn_on_address_error{false };
183198};
184199
185200template <unsigned BUSWIDTH, typename TARGET_SOCKET_TYPE>
186- router<BUSWIDTH, TARGET_SOCKET_TYPE>::router(const sc_core::sc_module_name& nm, size_t slave_cnt, size_t master_cnt)
201+ router<BUSWIDTH, TARGET_SOCKET_TYPE>::router(const sc_core::sc_module_name& nm, size_t slave_cnt, size_t master_cnt, bool check_overlap_on_add_target )
187202: sc_module(nm)
188203, target(" target" , master_cnt)
189204, initiator(" intor" , slave_cnt)
190205, ibases(master_cnt)
191206, tranges(slave_cnt)
192207, mutexes(slave_cnt)
193- , addr_decoder(std::numeric_limits<unsigned >::max()) {
208+ , addr_decoder(std::numeric_limits<unsigned >::max())
209+ , check_overlap_on_add_target(check_overlap_on_add_target) {
194210 for (size_t i = 0 ; i < target.size (); ++i) {
195211 target[i].register_b_transport (
196212 [this , i](tlm::tlm_generic_payload& trans, sc_core::sc_time& delay) -> void { this ->b_transport (i, trans, delay); });
@@ -216,6 +232,8 @@ void router<BUSWIDTH, TARGET_SOCKET_TYPE>::set_target_range(size_t idx, uint64_t
216232 tranges[idx].size = size;
217233 tranges[idx].remap = remap;
218234 addr_decoder.addEntry (idx, base, size);
235+ if (check_overlap_on_add_target)
236+ addr_decoder.validate ();
219237}
220238
221239template <unsigned BUSWIDTH, typename TARGET_SOCKET_TYPE>
@@ -237,6 +255,8 @@ void router<BUSWIDTH, TARGET_SOCKET_TYPE>::add_target_range(std::string name, ui
237255 tranges[idx].size = size;
238256 tranges[idx].remap = remap;
239257 addr_decoder.addEntry (idx, base, size);
258+ if (check_overlap_on_add_target)
259+ addr_decoder.validate ();
240260}
241261
242262template <unsigned BUSWIDTH, typename TARGET_SOCKET_TYPE>
@@ -249,6 +269,9 @@ void router<BUSWIDTH, TARGET_SOCKET_TYPE>::b_transport(int i, tlm::tlm_generic_p
249269 size_t idx = addr_decoder.getEntry (address);
250270 if (idx == addr_decoder.null_entry ) {
251271 if (default_idx == std::numeric_limits<size_t >::max ()) {
272+ if (warn_on_address_error) {
273+ SCCWARN (SCMOD) << " target address=0x" << std::hex << address << " not found for " << (trans.get_command () == tlm::TLM_READ_COMMAND ? " read" : " write" ) << " transaction." ;
274+ }
252275 trans.set_response_status (tlm::TLM_ADDRESS_ERROR_RESPONSE);
253276 return ;
254277 }
@@ -272,6 +295,9 @@ bool router<BUSWIDTH, TARGET_SOCKET_TYPE>::get_direct_mem_ptr(int i, tlm::tlm_ge
272295 size_t idx = addr_decoder.getEntry (address);
273296 if (idx == addr_decoder.null_entry ) {
274297 if (default_idx == std::numeric_limits<size_t >::max ()) {
298+ if (warn_on_address_error) {
299+ SCCWARN (SCMOD) << " target address=0x" << std::hex << address << " not found for " << (trans.get_command () == tlm::TLM_READ_COMMAND ? " read" : " write" ) << " transaction." ;
300+ }
275301 trans.set_response_status (tlm::TLM_ADDRESS_ERROR_RESPONSE);
276302 return false ;
277303 }
@@ -300,6 +326,9 @@ unsigned router<BUSWIDTH, TARGET_SOCKET_TYPE>::transport_dbg(int i, tlm::tlm_gen
300326 size_t idx = addr_decoder.getEntry (address);
301327 if (idx == addr_decoder.null_entry ) {
302328 if (default_idx == std::numeric_limits<size_t >::max ()) {
329+ if (warn_on_address_error) {
330+ SCCWARN (SCMOD) << " target address=0x" << std::hex << address << " not found for " << (trans.get_command () == tlm::TLM_READ_COMMAND ? " read" : " write" ) << " transaction." ;
331+ }
303332 trans.set_response_status (tlm::TLM_ADDRESS_ERROR_RESPONSE);
304333 return 0 ;
305334 }
@@ -324,6 +353,10 @@ void router<BUSWIDTH, TARGET_SOCKET_TYPE>::invalidate_direct_mem_ptr(int id, ::s
324353 target[i]->invalidate_direct_mem_ptr (bw_start_range - ibases[i], bw_end_range - ibases[i]);
325354 }
326355}
356+ template <unsigned BUSWIDTH, typename TARGET_SOCKET_TYPE>
357+ void router<BUSWIDTH, TARGET_SOCKET_TYPE>::end_of_elaboration() {
358+ addr_decoder.validate ();
359+ }
327360
328361} // namespace scc
329362
0 commit comments