diff options
author | Gabe Black <gabeblack@google.com> | 2018-05-24 01:37:55 -0700 |
---|---|---|
committer | Gabe Black <gabeblack@google.com> | 2018-08-08 10:09:54 +0000 |
commit | 16fa8d7cc8c92f5ab879e4cf9c6c0bbb3567860f (patch) | |
tree | 7b6faaacb4574a555e561534aa4a8508c0624c32 /src/systemc/tests/tlm | |
parent | 7235d3b5211d0ba8f528d930a4c1e7ad62eec51a (diff) | |
download | gem5-16fa8d7cc8c92f5ab879e4cf9c6c0bbb3567860f.tar.xz |
systemc: Import tests from the Accellera systemc distribution.
Change-Id: Iad76b398949a55d768a34d027a2d8e3739953da6
Reviewed-on: https://gem5-review.googlesource.com/10845
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Maintainer: Gabe Black <gabeblack@google.com>
Diffstat (limited to 'src/systemc/tests/tlm')
56 files changed, 8206 insertions, 0 deletions
diff --git a/src/systemc/tests/tlm/README.txt b/src/systemc/tests/tlm/README.txt new file mode 100644 index 000000000..33def095a --- /dev/null +++ b/src/systemc/tests/tlm/README.txt @@ -0,0 +1,89 @@ + +TLM-2.0 unit tests +================== + +Dir: tests/tlm/ +SubDirs: + bus/ + bus_dmi/ + cancel_all/ + common/ + endian_conv/ + multi_sockets/ + nb2b_adapter/ + p2p/ + static_extensions/ + update_original/ + +Files: README.txt + + +Comments +======== + +Running the tests: +------------------ + +See the main README and README_windows.txt files. + + +The tests: +---------- + +All tests are build using a set of models that can be found in the subdirectory +common/include/models. For a description of the models see the README.txt in +that subdirectory. + +The test themselves can be found in the following subdirectories: +bus/ : + test system using a TLM2 compliant AT bus model and a combination of + LT and AT targets and initiators, with and without temporal decoupling. + +bus_dmi/ : + test system using a similar system as in the bus/ test but now with DMI + support added for the LT initiators and targets. + +cancel_all/ : + Tests the cancel_all() methods of the two PEQs, peq_with_cb_and_phase and peq_with_get. + Along the way, it also tests the basic operation of each PEQ. + +endian_conv/ : + unit test for the endianness conversion ftions, there is only a build for + linux provided, the C++ test performs a single conversion, there is a + python script using the program to do a more extensive test + +multi_sockets/ : + test system using a TLM2 compliant AT busmodel using a single socket to + bind all targets and initiators to, in combination with LT and AT + initiators and targets. This test also uses instance specific extentions + in the generic payload + +nb2b_adapter/ : + Primarily a regression test for a bug in the nb2b adapter of the simple_target_socket. + Tests the operation of the nb2b adapter, and also exercises the peq_with_cb_and_phase + and the instance_specific_extension. + +p2p/ : + BaseSocketLT/ : + simple point to point test for LT initiator and target + CoreDecoupling/ + simple test for using the LT initiator with temporal decoupling + EndEventLT/ + ?? + HierarchicalSocket/ + tests sockets on hierachical modules + RegisterSocketProcessLT/ + simple test for initiator and target using callback registry in sockets + SimpleAT/ + simple point to point test for AT initiator and target using GP + AT phases and TLM_ACCEPTED + SimpleAT_TA/ + simple point to point test for AT initiator and target using GP + AT phases and TLM_UPDATED + +static_extentions/ : + contains 3 unit tests to verify the GP extention mechanism + +update_original/ : + Tests the deep_copy_from() and update_original_from() methods of tlm_generic_payload. + Along the way, it also tests the use of byte enables for read and write commands. diff --git a/src/systemc/tests/tlm/bugs/multi_passthrough_sockets_bug/golden/multi_passthrough_sockets_bug.log b/src/systemc/tests/tlm/bugs/multi_passthrough_sockets_bug/golden/multi_passthrough_sockets_bug.log new file mode 100644 index 000000000..1511493c4 --- /dev/null +++ b/src/systemc/tests/tlm/bugs/multi_passthrough_sockets_bug/golden/multi_passthrough_sockets_bug.log @@ -0,0 +1,2 @@ +SystemC Simulation +Received successfully introspection extension! diff --git a/src/systemc/tests/tlm/bugs/multi_passthrough_sockets_bug/multi_passthrough_sockets_bug.cpp b/src/systemc/tests/tlm/bugs/multi_passthrough_sockets_bug/multi_passthrough_sockets_bug.cpp new file mode 100644 index 000000000..209093aa7 --- /dev/null +++ b/src/systemc/tests/tlm/bugs/multi_passthrough_sockets_bug/multi_passthrough_sockets_bug.cpp @@ -0,0 +1,196 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ +#define SC_INCLUDE_DYNAMIC_PROCESSES +#include "systemc" +#include "tlm" +#include "tlm_utils/simple_initiator_socket.h" +#include "tlm_utils/multi_passthrough_target_socket.h" + +class introspection_extension; + +class initiator_module : public sc_core::sc_module +{ +public: + + tlm_utils::simple_initiator_socket<initiator_module> initiator_socket; + SC_HAS_PROCESS(initiator_module); + explicit initiator_module(sc_core::sc_module_name module_name) + : sc_core::sc_module(module_name) + , initiator_socket("initiator_socket") + { + SC_THREAD(process); + } + + void process() + { + // To verify regular TLM-2 access from initiators are OK + tlm::tlm_generic_payload transaction; + + unsigned char byte = 0x42; + + transaction.set_command(tlm::TLM_WRITE_COMMAND); + transaction.set_address(sc_dt::uint64(0)); + transaction.set_data_length(1); + transaction.set_streaming_width(1); + transaction.set_data_ptr(&byte); + transaction.set_byte_enable_ptr(0); + transaction.set_byte_enable_length(0); + transaction.set_dmi_allowed(false); + transaction.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + + sc_core::sc_time t = sc_core::SC_ZERO_TIME; + + initiator_socket->b_transport(transaction, t); + } + +}; + +class target_module : public sc_core::sc_module +{ +public: + + tlm_utils::multi_passthrough_target_socket<target_module> target_socket; + tlm_utils::multi_passthrough_target_socket<target_module, 32, tlm::tlm_base_protocol_types,0,::sc_core::SC_ZERO_OR_MORE_BOUND> target_optional; + + explicit target_module(sc_core::sc_module_name module_name) + : sc_core::sc_module(module_name) + , target_socket("target_socket") + , target_optional("target_optional") + { + target_socket.register_b_transport(this, &target_module::transport); + target_socket.register_transport_dbg(this, &target_module::transport_dbg); + target_socket.register_get_direct_mem_ptr(this, &target_module::get_direct_mem_ptr); + + // bind callbacks to optional socket (unbound) + target_optional.register_b_transport(this, &target_module::transport); + target_optional.register_transport_dbg(this, &target_module::transport_dbg); + target_optional.register_get_direct_mem_ptr(this, &target_module::get_direct_mem_ptr); + } + + virtual void transport(int port, tlm::tlm_generic_payload & transaction, sc_core::sc_time & t) {} + + virtual unsigned int transport_dbg(int port, tlm::tlm_generic_payload & transaction) + { + if ((transaction.get_command() == tlm::TLM_IGNORE_COMMAND) && + transaction.get_extension<introspection_extension>()) + { + std::cout << "Received successfully introspection extension!" << std::endl; + } + + return 0; + } + + virtual bool get_direct_mem_ptr(int port, tlm::tlm_generic_payload & transaction, tlm::tlm_dmi & dmi_data) { return false; } + +}; + +// Simple empty extension to verify the target module is receiving it +class introspection_extension : public tlm::tlm_extension<introspection_extension> +{ +public: + + virtual tlm_extension_base * clone() const + { + return new introspection_extension; + } + + virtual void copy_from(tlm_extension_base const & ext) + { + } + +}; + +class introspector_module : public sc_core::sc_module +{ +public: + + SC_HAS_PROCESS(introspector_module); + introspector_module(sc_core::sc_module_name module_name) : + sc_core::sc_module(module_name) + { + SC_THREAD(process); + } + + void send_introspection_request(sc_core::sc_export<tlm::tlm_fw_transport_if<> > & target_socket) + { + tlm::tlm_generic_payload transaction; + + transaction.set_command(tlm::TLM_IGNORE_COMMAND); + transaction.set_address(sc_dt::uint64(0)); + transaction.set_data_length(0); + transaction.set_streaming_width(0); + transaction.set_data_ptr(0); + transaction.set_byte_enable_ptr(0); + transaction.set_byte_enable_length(0); + transaction.set_dmi_allowed(false); + transaction.set_response_status(tlm::TLM_INCOMPLETE_RESPONSE); + + introspection_extension *ext = new introspection_extension; + + transaction.set_extension(ext); + + target_socket->transport_dbg(transaction); + } + + void find_target_sockets(sc_core::sc_module *module) + { + std::vector<sc_core::sc_object*> children = module->get_child_objects(); + + for (std::vector<sc_core::sc_object*>::iterator i = children.begin(); i != children.end(); ++i) + { + if (dynamic_cast<sc_core::sc_module *>(*i)) + { + find_target_sockets(dynamic_cast<sc_core::sc_module *>(*i)); + } + else if (dynamic_cast<sc_core::sc_export<tlm::tlm_fw_transport_if<> > *>((*i))) + { + sc_core::sc_export<tlm::tlm_fw_transport_if<> > * target_socket = dynamic_cast<sc_core::sc_export<tlm::tlm_fw_transport_if<> > *>(*i); + + send_introspection_request(*target_socket); + } + } + } + + void process() + { + const std::vector<sc_core::sc_object*> & top_objs = sc_core::sc_get_top_level_objects(); + + for (std::vector<sc_core::sc_object*>::const_iterator i = top_objs.begin(); i != top_objs.end(); ++i) + { + if (dynamic_cast<sc_core::sc_module *>(*i)) + { + find_target_sockets(dynamic_cast<sc_core::sc_module *>(*i)); + } + } + } + +}; + +int sc_main(int argc, char* argv[]) +{ + initiator_module initiator("initiator"); + target_module target("target"); + introspector_module introspector("introspector"); + + initiator.initiator_socket(target.target_socket); + + sc_core::sc_start(); + + return 0; +} diff --git a/src/systemc/tests/tlm/bus/bus.cpp b/src/systemc/tests/tlm/bus/bus.cpp new file mode 100644 index 000000000..0f3f5ae65 --- /dev/null +++ b/src/systemc/tests/tlm/bus/bus.cpp @@ -0,0 +1,81 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ +#define SC_INCLUDE_DYNAMIC_PROCESSES +#include <systemc> +#include "tlm.h" + +#include "SimpleLTInitiator1.h" +#include "SimpleLTTarget1.h" +#include "SimpleLTInitiator2.h" +#include "SimpleLTTarget2.h" +#include "SimpleATInitiator1.h" +#include "SimpleATInitiator2.h" +#include "SimpleATTarget1.h" +#include "SimpleATInitiator2.h" +#include "SimpleATTarget2.h" +#include "CoreDecouplingLTInitiator.h" +#include "ExplicitLTTarget.h" +#include "ExplicitATTarget.h" +#include "SimpleBusAT.h" + +int sc_main(int argc, char* argv[]) +{ + SimpleLTInitiator1 initiator1("initiator1", 10, 0x00000000); + SimpleLTTarget1 target1("target1"); + + SimpleLTInitiator2 initiator2("initiator2", 10, 0x10000000); + SimpleLTTarget2 target2("target2"); + + SimpleATInitiator1 initiator3("initiator3", 10, 0x20000000); + SimpleATTarget1 target3("target3"); + + SimpleATInitiator2 initiator4("initiator4", 10, 0x30000000); + SimpleATTarget2 target4("target4"); + + SimpleATInitiator2 initiator5("initiator5", 10, 0x40000000); + SimpleATTarget2 target5("target5"); + + CoreDecouplingLTInitiator initiator6("initiator6", 10, 0x50000000); + ExplicitLTTarget target6("target6"); + + CoreDecouplingLTInitiator initiator7("initiator7", 10, 0x60000000); + ExplicitATTarget target7("target7"); + + SimpleBusAT<7, 7> bus("bus"); + + initiator1.socket(bus.target_socket[0]); + initiator2.socket(bus.target_socket[1]); + initiator3.socket(bus.target_socket[2]); + initiator4.socket(bus.target_socket[3]); + initiator5.socket(bus.target_socket[4]); + initiator6.socket(bus.target_socket[5]); + initiator7.socket(bus.target_socket[6]); + bus.initiator_socket[0](target1.socket); + bus.initiator_socket[1](target2.socket); + bus.initiator_socket[2](target3.socket); + bus.initiator_socket[3](target4.socket); + bus.initiator_socket[4](target5.socket); + bus.initiator_socket[5](target6.socket); + bus.initiator_socket[6](target7.socket); + + sc_core::sc_start(); + sc_core::sc_stop(); + + return 0; +} diff --git a/src/systemc/tests/tlm/bus/golden/bus.log b/src/systemc/tests/tlm/bus/golden/bus.log new file mode 100644 index 000000000..05fbfe374 --- /dev/null +++ b/src/systemc/tests/tlm/bus/golden/bus.log @@ -0,0 +1,445 @@ +SystemC Simulation +initiator1: Send write request: A = 0x0, D = 0x0 @ 0 s +initiator2: Send write request: A = 0x10000000, D = 0x0 @ 0 s +initiator3: Send write request: A = 0x20000000, D = 0x0 @ 0 s +initiator4: Send write request: A = 0x30000000, D = 0x0 @ 0 s +initiator5: Send write request: A = 0x40000000, D = 0x0 @ 0 s +initiator6: Send write request: A = 0x50000000, D = 0x0 @ 0 s (0 s + 0 s) +initiator7: Send write request: A = 0x60000000, D = 0x0 @ 0 s (0 s + 0 s) +target3: Received write request: A = 0x0, D = 0x0 @ 0 s +target4: Received write request: A = 0x0, D = 0x0 @ 25 ns +initiator3: Send write request: A = 0x20000004, D = 0x1 @ 25 ns +target5: Received write request: A = 0x0, D = 0x0 @ 50 ns +initiator4: Send write request: A = 0x30000004, D = 0x1 @ 50 ns +target7: Received write request: A = 0x0, D = 0x0 @ 75 ns +initiator5: Send write request: A = 0x40000004, D = 0x1 @ 75 ns +target6: Received write request: A = 0x0, D = 0x0 @ 75 ns +target2: Received write request: A = 0x0, D = 0x0 @ 125 ns +initiator3: Received ok response @ 135 ns +target1: Received write request: A = 0x0, D = 0x0 @ 135 ns +initiator7: Received ok response @ 135 ns (135 ns + 0 s) +initiator7: Send write request: A = 0x60000004, D = 0x1 @ 135 ns (135 ns + 0 s) +initiator6: Received ok response @ 135 ns (135 ns + 0 s) +initiator6: Send write request: A = 0x50000004, D = 0x1 @ 135 ns (135 ns + 0 s) +initiator2: Received ok response @ 135 ns +initiator2: Send write request: A = 0x10000004, D = 0x1 @ 135 ns +target3: Received write request: A = 0x4, D = 0x1 @ 145 ns +initiator1: Received ok response @ 145 ns +initiator1: Send write request: A = 0x4, D = 0x1 @ 145 ns +initiator4: Received ok response @ 150 ns +target4: Received write request: A = 0x4, D = 0x1 @ 150 ns +initiator3: Send write request: A = 0x20000008, D = 0x2 @ 150 ns +target5: Received write request: A = 0x4, D = 0x1 @ 175 ns +initiator4: Send write request: A = 0x30000008, D = 0x2 @ 175 ns +initiator5: Received ok response @ 175 ns +target7: Received write request: A = 0x4, D = 0x1 @ 200 ns +initiator5: Send write request: A = 0x40000008, D = 0x2 @ 200 ns +target6: Received write request: A = 0x4, D = 0x1 @ 200 ns +target2: Received write request: A = 0x4, D = 0x1 @ 250 ns +initiator7: Received ok response @ 250 ns (250 ns + 0 s) +initiator7: Send write request: A = 0x60000008, D = 0x2 @ 250 ns (250 ns + 0 s) +initiator6: Received ok response @ 250 ns (250 ns + 0 s) +initiator6: Send write request: A = 0x50000008, D = 0x2 @ 250 ns (250 ns + 0 s) +target1: Received write request: A = 0x4, D = 0x1 @ 260 ns +initiator4: Received ok response @ 260 ns +initiator2: Received ok response @ 260 ns +initiator2: Send write request: A = 0x10000008, D = 0x2 @ 260 ns +target3: Received write request: A = 0x8, D = 0x2 @ 270 ns +target4: Received write request: A = 0x8, D = 0x2 @ 270 ns +initiator3: Send write request: A = 0x2000000c, D = 0x3 @ 270 ns +initiator1: Received ok response @ 270 ns +initiator1: Send write request: A = 0x8, D = 0x2 @ 270 ns +initiator3: Received ok response @ 280 ns +initiator5: Received ok response @ 285 ns +target5: Received write request: A = 0x8, D = 0x2 @ 295 ns +initiator4: Send write request: A = 0x3000000c, D = 0x3 @ 295 ns +target7: Received write request: A = 0x8, D = 0x2 @ 320 ns +initiator5: Send write request: A = 0x4000000c, D = 0x3 @ 320 ns +target6: Received write request: A = 0x8, D = 0x2 @ 320 ns +target2: Received write request: A = 0x8, D = 0x2 @ 370 ns +initiator7: Received ok response @ 370 ns (370 ns + 0 s) +initiator7: Send write request: A = 0x6000000c, D = 0x3 @ 370 ns (370 ns + 0 s) +initiator6: Received ok response @ 370 ns (370 ns + 0 s) +initiator6: Send write request: A = 0x5000000c, D = 0x3 @ 370 ns (370 ns + 0 s) +target3: Received write request: A = 0xc, D = 0x3 @ 380 ns +initiator2: Received ok response @ 380 ns +initiator2: Send write request: A = 0x1000000c, D = 0x3 @ 380 ns +initiator5: Received ok response @ 395 ns +target1: Received write request: A = 0x8, D = 0x2 @ 395 ns +initiator3: Send write request: A = 0x20000010, D = 0x4 @ 395 ns +target4: Received write request: A = 0xc, D = 0x3 @ 405 ns +initiator3: Received ok response @ 415 ns +initiator4: Received ok response @ 415 ns +initiator1: Received ok response @ 425 ns +initiator1: Send write request: A = 0xc, D = 0x3 @ 425 ns +target5: Received write request: A = 0xc, D = 0x3 @ 430 ns +initiator4: Send write request: A = 0x30000010, D = 0x4 @ 430 ns +target7: Received write request: A = 0xc, D = 0x3 @ 455 ns +initiator5: Send write request: A = 0x40000010, D = 0x4 @ 455 ns +target6: Received write request: A = 0xc, D = 0x3 @ 455 ns +target2: Received write request: A = 0xc, D = 0x3 @ 505 ns +Sync'ing... +initiator7: Received ok response @ 505 ns (505 ns + 0 s) +initiator7: Send write request: A = 0x60000010, D = 0x4 @ 505 ns (505 ns + 0 s) +Sync'ing... +initiator6: Received ok response @ 505 ns (505 ns + 0 s) +initiator6: Send write request: A = 0x50000010, D = 0x4 @ 505 ns (505 ns + 0 s) +target3: Received write request: A = 0x10, D = 0x4 @ 515 ns +target1: Received write request: A = 0xc, D = 0x3 @ 515 ns +initiator3: Send write request: A = 0x20000014, D = 0x5 @ 515 ns +initiator2: Received ok response @ 515 ns +initiator2: Send write request: A = 0x10000010, D = 0x4 @ 515 ns +initiator3: Received ok response @ 525 ns +target4: Received write request: A = 0x10, D = 0x4 @ 525 ns +initiator4: Received ok response @ 525 ns +initiator1: Received ok response @ 525 ns +initiator1: Send write request: A = 0x10, D = 0x4 @ 525 ns +target5: Received write request: A = 0x10, D = 0x4 @ 550 ns +initiator4: Send write request: A = 0x30000014, D = 0x5 @ 550 ns +initiator5: Received ok response @ 555 ns +target7: Received write request: A = 0x10, D = 0x4 @ 575 ns +initiator5: Send write request: A = 0x40000014, D = 0x5 @ 575 ns +target6: Received write request: A = 0x10, D = 0x4 @ 575 ns +target3: Received write request: A = 0x14, D = 0x5 @ 625 ns +initiator7: Received ok response @ 625 ns (625 ns + 0 s) +initiator7: Send write request: A = 0x60000014, D = 0x5 @ 625 ns (625 ns + 0 s) +target2: Received write request: A = 0x10, D = 0x4 @ 625 ns +initiator3: Send write request: A = 0x20000018, D = 0x6 @ 625 ns +initiator6: Received ok response @ 625 ns (625 ns + 0 s) +initiator6: Send write request: A = 0x50000014, D = 0x5 @ 625 ns (625 ns + 0 s) +target1: Received write request: A = 0x10, D = 0x4 @ 635 ns +initiator4: Received ok response @ 635 ns +initiator2: Received ok response @ 635 ns +initiator2: Send write request: A = 0x10000014, D = 0x5 @ 635 ns +target4: Received write request: A = 0x14, D = 0x5 @ 645 ns +initiator3: Received ok response @ 655 ns +initiator1: Received ok response @ 655 ns +initiator1: Send write request: A = 0x14, D = 0x5 @ 655 ns +initiator5: Received ok response @ 665 ns +target5: Received write request: A = 0x14, D = 0x5 @ 670 ns +initiator4: Send write request: A = 0x30000018, D = 0x6 @ 670 ns +target3: Received write request: A = 0x18, D = 0x6 @ 695 ns +initiator5: Send write request: A = 0x40000018, D = 0x6 @ 695 ns +target7: Received write request: A = 0x14, D = 0x5 @ 720 ns +initiator3: Send write request: A = 0x2000001c, D = 0x7 @ 720 ns +target6: Received write request: A = 0x14, D = 0x5 @ 720 ns +initiator4: Received ok response @ 745 ns +target2: Received write request: A = 0x14, D = 0x5 @ 745 ns +target1: Received write request: A = 0x14, D = 0x5 @ 755 ns +initiator2: Received ok response @ 755 ns +initiator2: Send write request: A = 0x10000018, D = 0x6 @ 755 ns +initiator3: Received ok response @ 765 ns +target4: Received write request: A = 0x18, D = 0x6 @ 765 ns +initiator1: Received ok response @ 765 ns +initiator1: Send write request: A = 0x18, D = 0x6 @ 765 ns +initiator7: Received ok response @ 770 ns (770 ns + 0 s) +initiator7: Send write request: A = 0x60000018, D = 0x6 @ 770 ns (770 ns + 0 s) +initiator6: Received ok response @ 770 ns (770 ns + 0 s) +initiator6: Send write request: A = 0x50000018, D = 0x6 @ 770 ns (770 ns + 0 s) +initiator5: Received ok response @ 775 ns +target5: Received write request: A = 0x18, D = 0x6 @ 790 ns +initiator4: Send write request: A = 0x3000001c, D = 0x7 @ 790 ns +target3: Received write request: A = 0x1c, D = 0x7 @ 815 ns +initiator5: Send write request: A = 0x4000001c, D = 0x7 @ 815 ns +target2: Received write request: A = 0x18, D = 0x6 @ 840 ns +initiator3: Send write request: A = 0x20000020, D = 0x8 @ 840 ns +target1: Received write request: A = 0x18, D = 0x6 @ 850 ns +initiator2: Received ok response @ 850 ns +initiator2: Send write request: A = 0x1000001c, D = 0x7 @ 850 ns +target7: Received write request: A = 0x18, D = 0x6 @ 860 ns +initiator1: Received ok response @ 860 ns +initiator1: Send write request: A = 0x1c, D = 0x7 @ 860 ns +target6: Received write request: A = 0x18, D = 0x6 @ 860 ns +target4: Received write request: A = 0x1c, D = 0x7 @ 865 ns +initiator3: Received ok response @ 875 ns +target5: Received write request: A = 0x1c, D = 0x7 @ 890 ns +initiator4: Send write request: A = 0x30000020, D = 0x8 @ 890 ns +initiator4: Received ok response @ 890 ns +initiator7: Received ok response @ 910 ns (910 ns + 0 s) +initiator7: Send write request: A = 0x6000001c, D = 0x7 @ 910 ns (910 ns + 0 s) +initiator6: Received ok response @ 910 ns (910 ns + 0 s) +initiator6: Send write request: A = 0x5000001c, D = 0x7 @ 910 ns (910 ns + 0 s) +target3: Received write request: A = 0x20, D = 0x8 @ 915 ns +initiator5: Send write request: A = 0x40000020, D = 0x8 @ 915 ns +initiator5: Received ok response @ 915 ns +target2: Received write request: A = 0x1c, D = 0x7 @ 915 ns +initiator3: Send write request: A = 0x20000024, D = 0x9 @ 915 ns +target1: Received write request: A = 0x1c, D = 0x7 @ 925 ns +initiator2: Received ok response @ 925 ns +initiator2: Send write request: A = 0x10000020, D = 0x8 @ 925 ns +target4: Received write request: A = 0x20, D = 0x8 @ 935 ns +initiator1: Received ok response @ 935 ns +initiator1: Send write request: A = 0x20, D = 0x8 @ 935 ns +target7: Received write request: A = 0x1c, D = 0x7 @ 960 ns +initiator4: Send write request: A = 0x30000024, D = 0x9 @ 960 ns +target6: Received write request: A = 0x1c, D = 0x7 @ 960 ns +target5: Received write request: A = 0x20, D = 0x8 @ 975 ns +initiator3: Received ok response @ 985 ns +target3: Received write request: A = 0x24, D = 0x9 @ 1 us +initiator5: Send write request: A = 0x40000024, D = 0x9 @ 1 us +initiator4: Received ok response @ 1 us +target2: Received write request: A = 0x20, D = 0x8 @ 1 us +initiator3: Send read request: A = 0x20000000 @ 1 us +target1: Received write request: A = 0x20, D = 0x8 @ 1010 ns +initiator2: Received ok response @ 1010 ns +initiator2: Send write request: A = 0x10000024, D = 0x9 @ 1010 ns +Sync'ing... +initiator7: Received ok response @ 1010 ns (1010 ns + 0 s) +initiator7: Send write request: A = 0x60000020, D = 0x8 @ 1010 ns (1010 ns + 0 s) +Sync'ing... +initiator6: Received ok response @ 1010 ns (1010 ns + 0 s) +initiator6: Send write request: A = 0x50000020, D = 0x8 @ 1010 ns (1010 ns + 0 s) +target4: Received write request: A = 0x24, D = 0x9 @ 1020 ns +initiator1: Received ok response @ 1020 ns +initiator1: Send write request: A = 0x24, D = 0x9 @ 1020 ns +initiator5: Received ok response @ 1025 ns +target5: Received write request: A = 0x24, D = 0x9 @ 1045 ns +initiator4: Send read request: A = 0x30000000 @ 1045 ns +target3: Received read request: A = 0x0 @ 1070 ns +initiator5: Send read request: A = 0x40000000 @ 1070 ns +target2: Received write request: A = 0x24, D = 0x9 @ 1085 ns +initiator3: Send read request: A = 0x20000004 @ 1085 ns +initiator3: Received ok response @ 1095 ns +target7: Received write request: A = 0x20, D = 0x8 @ 1095 ns +target6: Received write request: A = 0x20, D = 0x8 @ 1095 ns +initiator2: Received ok response @ 1095 ns +initiator2: Send read request: A = 0x10000000 @ 1095 ns +initiator4: Received ok response @ 1110 ns +target1: Received write request: A = 0x24, D = 0x9 @ 1110 ns +target4: Received read request: A = 0x0 @ 1120 ns +initiator1: Received ok response @ 1120 ns +initiator1: Send read request: A = 0x0 @ 1120 ns +initiator5: Received ok response @ 1135 ns +target5: Received read request: A = 0x0 @ 1145 ns +initiator4: Send read request: A = 0x30000004 @ 1145 ns +initiator7: Received ok response @ 1145 ns (1145 ns + 0 s) +initiator7: Send write request: A = 0x60000024, D = 0x9 @ 1145 ns (1145 ns + 0 s) +initiator6: Received ok response @ 1145 ns (1145 ns + 0 s) +initiator6: Send write request: A = 0x50000024, D = 0x9 @ 1145 ns (1145 ns + 0 s) +target3: Received read request: A = 0x4 @ 1170 ns +initiator5: Send read request: A = 0x40000004 @ 1170 ns +target2: Received read request: A = 0x0 @ 1195 ns +initiator3: Send read request: A = 0x20000008 @ 1195 ns +initiator3: Received ok response @ 1205 ns +initiator4: Received ok response @ 1220 ns +initiator5: Received ok response @ 1245 ns +target1: Received read request: A = 0x0 @ 1295 ns +initiator2: Received ok response: D = 0x0 @ 1295 ns +initiator2: Send read request: A = 0x10000004 @ 1295 ns +initiator3: Received ok response: D = 0x0 @ 1315 ns +initiator4: Received ok response: D = 0x0 @ 1330 ns +initiator5: Received ok response: D = 0x0 @ 1355 ns +target4: Received read request: A = 0x4 @ 1395 ns +initiator1: Received ok response: D = 0x0 @ 1395 ns +initiator1: Send read request: A = 0x4 @ 1395 ns +target7: Received write request: A = 0x24, D = 0x9 @ 1420 ns +initiator4: Send read request: A = 0x30000008 @ 1420 ns +target6: Received write request: A = 0x24, D = 0x9 @ 1420 ns +initiator3: Received ok response: D = 0x1 @ 1425 ns +target5: Received read request: A = 0x4 @ 1470 ns +initiator7: Received ok response @ 1470 ns (1470 ns + 0 s) +initiator7: Send read request: A = 0x60000000 @ 1470 ns (1470 ns + 0 s) +initiator6: Received ok response @ 1470 ns (1470 ns + 0 s) +initiator6: Send read request: A = 0x50000000 @ 1470 ns (1470 ns + 0 s) +target3: Received read request: A = 0x8 @ 1495 ns +initiator5: Send read request: A = 0x40000008 @ 1495 ns +initiator4: Received ok response: D = 0x1 @ 1520 ns +target2: Received read request: A = 0x4 @ 1520 ns +initiator3: Send read request: A = 0x2000000c @ 1520 ns +initiator5: Received ok response: D = 0x1 @ 1595 ns +target1: Received read request: A = 0x4 @ 1620 ns +initiator2: Received ok response: D = 0x1 @ 1620 ns +initiator2: Send read request: A = 0x10000008 @ 1620 ns +initiator3: Received ok response: D = 0x2 @ 1630 ns +target4: Received read request: A = 0x8 @ 1720 ns +initiator1: Received ok response: D = 0x1 @ 1720 ns +initiator1: Send read request: A = 0x8 @ 1720 ns +target7: Received read request: A = 0x0 @ 1745 ns +initiator4: Send read request: A = 0x3000000c @ 1745 ns +initiator4: Received ok response: D = 0x2 @ 1845 ns +Sync'ing... +target6: Received read request: A = 0x0 @ 1845 ns +target5: Received read request: A = 0x8 @ 1845 ns +initiator7: Received ok response: D = 0x0 @ 1845 ns (1845 ns + 0 s) +initiator7: Send read request: A = 0x60000004 @ 1845 ns (1845 ns + 0 s) +target3: Received read request: A = 0xc @ 1870 ns +initiator5: Send read request: A = 0x4000000c @ 1870 ns +target2: Received read request: A = 0x8 @ 1895 ns +initiator3: Send read request: A = 0x20000010 @ 1895 ns +Sync'ing... +initiator6: Received ok response: D = 0x0 @ 1945 ns (1945 ns + 0 s) +initiator6: Send read request: A = 0x50000004 @ 1945 ns (1945 ns + 0 s) +initiator5: Received ok response: D = 0x2 @ 1970 ns +target1: Received read request: A = 0x8 @ 1995 ns +initiator2: Received ok response: D = 0x2 @ 1995 ns +initiator2: Send read request: A = 0x1000000c @ 1995 ns +initiator3: Received ok response: D = 0x3 @ 2005 ns +target4: Received read request: A = 0xc @ 2095 ns +initiator1: Received ok response: D = 0x2 @ 2095 ns +initiator1: Send read request: A = 0xc @ 2095 ns +target7: Received read request: A = 0x4 @ 2120 ns +initiator4: Send read request: A = 0x30000010 @ 2120 ns +target5: Received read request: A = 0xc @ 2220 ns +initiator4: Received ok response: D = 0x3 @ 2220 ns +Sync'ing... +initiator7: Received ok response: D = 0x1 @ 2220 ns (2220 ns + 0 s) +initiator7: Send read request: A = 0x60000008 @ 2220 ns (2220 ns + 0 s) +target3: Received read request: A = 0x10 @ 2245 ns +initiator5: Send read request: A = 0x40000010 @ 2245 ns +target6: Received read request: A = 0x4 @ 2270 ns +initiator3: Send read request: A = 0x20000014 @ 2270 ns +initiator5: Received ok response: D = 0x3 @ 2345 ns +target2: Received read request: A = 0xc @ 2345 ns +initiator3: Received ok response: D = 0x4 @ 2380 ns +Sync'ing... +initiator6: Received ok response: D = 0x1 @ 2380 ns (2380 ns + 0 s) +initiator6: Send read request: A = 0x50000008 @ 2380 ns (2380 ns + 0 s) +target1: Received read request: A = 0xc @ 2445 ns +initiator2: Received ok response: D = 0x3 @ 2445 ns +initiator2: Send read request: A = 0x10000010 @ 2445 ns +target4: Received read request: A = 0x10 @ 2545 ns +initiator1: Received ok response: D = 0x3 @ 2545 ns +initiator1: Send read request: A = 0x10 @ 2545 ns +target7: Received read request: A = 0x8 @ 2570 ns +initiator4: Send read request: A = 0x30000014 @ 2570 ns +target5: Received read request: A = 0x10 @ 2670 ns +initiator4: Received ok response: D = 0x4 @ 2670 ns +Sync'ing... +initiator7: Received ok response: D = 0x2 @ 2670 ns (2670 ns + 0 s) +initiator7: Send read request: A = 0x6000000c @ 2670 ns (2670 ns + 0 s) +target3: Received read request: A = 0x14 @ 2695 ns +initiator5: Send read request: A = 0x40000014 @ 2695 ns +target6: Received read request: A = 0x8 @ 2720 ns +initiator3: Send read request: A = 0x20000018 @ 2720 ns +initiator5: Received ok response: D = 0x4 @ 2795 ns +target2: Received read request: A = 0x10 @ 2795 ns +initiator3: Received ok response: D = 0x5 @ 2830 ns +Sync'ing... +initiator6: Received ok response: D = 0x2 @ 2830 ns (2830 ns + 0 s) +initiator6: Send read request: A = 0x5000000c @ 2830 ns (2830 ns + 0 s) +target1: Received read request: A = 0x10 @ 2895 ns +initiator2: Received ok response: D = 0x4 @ 2895 ns +initiator2: Send read request: A = 0x10000014 @ 2895 ns +target4: Received read request: A = 0x14 @ 2995 ns +initiator1: Received ok response: D = 0x4 @ 2995 ns +initiator1: Send read request: A = 0x14 @ 2995 ns +target7: Received read request: A = 0xc @ 3020 ns +initiator4: Send read request: A = 0x30000018 @ 3020 ns +target5: Received read request: A = 0x14 @ 3120 ns +initiator4: Received ok response: D = 0x5 @ 3120 ns +Sync'ing... +initiator7: Received ok response: D = 0x3 @ 3120 ns (3120 ns + 0 s) +initiator7: Send read request: A = 0x60000010 @ 3120 ns (3120 ns + 0 s) +target3: Received read request: A = 0x18 @ 3145 ns +initiator5: Send read request: A = 0x40000018 @ 3145 ns +target6: Received read request: A = 0xc @ 3170 ns +initiator3: Send read request: A = 0x2000001c @ 3170 ns +initiator5: Received ok response: D = 0x5 @ 3245 ns +target2: Received read request: A = 0x14 @ 3245 ns +initiator3: Received ok response: D = 0x6 @ 3280 ns +Sync'ing... +initiator6: Received ok response: D = 0x3 @ 3280 ns (3280 ns + 0 s) +initiator6: Send read request: A = 0x50000010 @ 3280 ns (3280 ns + 0 s) +target1: Received read request: A = 0x14 @ 3345 ns +initiator2: Received ok response: D = 0x5 @ 3345 ns +initiator2: Send read request: A = 0x10000018 @ 3345 ns +target4: Received read request: A = 0x18 @ 3445 ns +initiator1: Received ok response: D = 0x5 @ 3445 ns +initiator1: Send read request: A = 0x18 @ 3445 ns +target7: Received read request: A = 0x10 @ 3470 ns +initiator4: Send read request: A = 0x3000001c @ 3470 ns +target5: Received read request: A = 0x18 @ 3570 ns +initiator4: Received ok response: D = 0x6 @ 3570 ns +Sync'ing... +initiator7: Received ok response: D = 0x4 @ 3570 ns (3570 ns + 0 s) +initiator7: Send read request: A = 0x60000014 @ 3570 ns (3570 ns + 0 s) +target3: Received read request: A = 0x1c @ 3595 ns +initiator5: Send read request: A = 0x4000001c @ 3595 ns +target6: Received read request: A = 0x10 @ 3620 ns +initiator3: Send read request: A = 0x20000020 @ 3620 ns +initiator5: Received ok response: D = 0x6 @ 3695 ns +target2: Received read request: A = 0x18 @ 3695 ns +initiator3: Received ok response: D = 0x7 @ 3730 ns +Sync'ing... +initiator6: Received ok response: D = 0x4 @ 3730 ns (3730 ns + 0 s) +initiator6: Send read request: A = 0x50000014 @ 3730 ns (3730 ns + 0 s) +target1: Received read request: A = 0x18 @ 3795 ns +initiator2: Received ok response: D = 0x6 @ 3795 ns +initiator2: Send read request: A = 0x1000001c @ 3795 ns +target4: Received read request: A = 0x1c @ 3895 ns +initiator1: Received ok response: D = 0x6 @ 3895 ns +initiator1: Send read request: A = 0x1c @ 3895 ns +target7: Received read request: A = 0x14 @ 3920 ns +initiator4: Send read request: A = 0x30000020 @ 3920 ns +target5: Received read request: A = 0x1c @ 4020 ns +initiator4: Received ok response: D = 0x7 @ 4020 ns +Sync'ing... +initiator7: Received ok response: D = 0x5 @ 4020 ns (4020 ns + 0 s) +initiator7: Send read request: A = 0x60000018 @ 4020 ns (4020 ns + 0 s) +target3: Received read request: A = 0x20 @ 4045 ns +initiator5: Send read request: A = 0x40000020 @ 4045 ns +target6: Received read request: A = 0x14 @ 4070 ns +initiator3: Send read request: A = 0x20000024 @ 4070 ns +initiator5: Received ok response: D = 0x7 @ 4145 ns +target2: Received read request: A = 0x1c @ 4145 ns +initiator3: Received ok response: D = 0x8 @ 4180 ns +Sync'ing... +initiator6: Received ok response: D = 0x5 @ 4180 ns (4180 ns + 0 s) +initiator6: Send read request: A = 0x50000018 @ 4180 ns (4180 ns + 0 s) +target1: Received read request: A = 0x1c @ 4245 ns +initiator2: Received ok response: D = 0x7 @ 4245 ns +initiator2: Send read request: A = 0x10000020 @ 4245 ns +target4: Received read request: A = 0x20 @ 4345 ns +initiator1: Received ok response: D = 0x7 @ 4345 ns +initiator1: Send read request: A = 0x20 @ 4345 ns +target7: Received read request: A = 0x18 @ 4370 ns +initiator4: Send read request: A = 0x30000024 @ 4370 ns +target5: Received read request: A = 0x20 @ 4470 ns +initiator4: Received ok response: D = 0x8 @ 4470 ns +initiator7: Received ok response: D = 0x6 @ 4470 ns (4470 ns + 0 s) +initiator7: Send read request: A = 0x6000001c @ 4470 ns (4470 ns + 0 s) +target3: Received read request: A = 0x24 @ 4495 ns +initiator5: Send read request: A = 0x40000024 @ 4495 ns +target6: Received read request: A = 0x18 @ 4520 ns +initiator5: Received ok response: D = 0x8 @ 4595 ns +target2: Received read request: A = 0x20 @ 4595 ns +initiator3: Received ok response: D = 0x9 @ 4630 ns +Sync'ing... +initiator6: Received ok response: D = 0x6 @ 4630 ns (4630 ns + 0 s) +initiator6: Send read request: A = 0x5000001c @ 4630 ns (4630 ns + 0 s) +target1: Received read request: A = 0x20 @ 4695 ns +initiator2: Received ok response: D = 0x8 @ 4695 ns +initiator2: Send read request: A = 0x10000024 @ 4695 ns +target4: Received read request: A = 0x24 @ 4795 ns +initiator1: Received ok response: D = 0x8 @ 4795 ns +initiator1: Send read request: A = 0x24 @ 4795 ns +target7: Received read request: A = 0x1c @ 4820 ns +target5: Received read request: A = 0x24 @ 4920 ns +initiator4: Received ok response: D = 0x9 @ 4920 ns +Sync'ing... +initiator7: Received ok response: D = 0x7 @ 4920 ns (4920 ns + 0 s) +initiator7: Send read request: A = 0x60000020 @ 4920 ns (4920 ns + 0 s) +target6: Received read request: A = 0x1c @ 4945 ns +initiator5: Received ok response: D = 0x9 @ 5045 ns +target2: Received read request: A = 0x24 @ 5045 ns +Sync'ing... +initiator6: Received ok response: D = 0x7 @ 5055 ns (5055 ns + 0 s) +initiator6: Send read request: A = 0x50000020 @ 5055 ns (5055 ns + 0 s) +target1: Received read request: A = 0x24 @ 5145 ns +initiator2: Received ok response: D = 0x9 @ 5145 ns +target7: Received read request: A = 0x20 @ 5245 ns +initiator1: Received ok response: D = 0x9 @ 5245 ns +target6: Received read request: A = 0x20 @ 5345 ns +Sync'ing... +initiator7: Received ok response: D = 0x8 @ 5345 ns (5345 ns + 0 s) +initiator7: Send read request: A = 0x60000024 @ 5345 ns (5345 ns + 0 s) +target7: Received read request: A = 0x24 @ 5445 ns +initiator6: Received ok response: D = 0x8 @ 5445 ns (5445 ns + 0 s) +initiator6: Send read request: A = 0x50000024 @ 5445 ns (5445 ns + 0 s) +target6: Received read request: A = 0x24 @ 5545 ns +Sync'ing... +initiator7: Received ok response: D = 0x9 @ 5545 ns (5545 ns + 0 s) +Sync'ing... +initiator6: Received ok response: D = 0x9 @ 5645 ns (5645 ns + 0 s) + +Info: /OSCI/SystemC: Simulation stopped by user. diff --git a/src/systemc/tests/tlm/bus_dmi/bus_dmi.cpp b/src/systemc/tests/tlm/bus_dmi/bus_dmi.cpp new file mode 100644 index 000000000..20ff68577 --- /dev/null +++ b/src/systemc/tests/tlm/bus_dmi/bus_dmi.cpp @@ -0,0 +1,80 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ +#define SC_INCLUDE_DYNAMIC_PROCESSES +#include "tlm.h" + +#include "SimpleLTInitiator1_DMI.h" +#include "SimpleLTTarget1.h" +#include "SimpleLTInitiator2_DMI.h" +#include "SimpleLTTarget2.h" +#include "SimpleLTInitiator3_DMI.h" +#include "SimpleATInitiator1.h" +#include "SimpleATTarget1.h" +#include "SimpleATInitiator2.h" +#include "SimpleATTarget2.h" +#include "CoreDecouplingLTInitiator.h" +#include "ExplicitLTTarget.h" +#include "ExplicitATTarget.h" +#include "SimpleBusLT.h" + +int sc_main(int argc, char* argv[]) +{ + SimpleLTInitiator1_dmi initiator1("initiator1", 10, 0x00000000); + SimpleLTTarget1 target1("target1"); + + SimpleLTInitiator2_dmi initiator2("initiator2", 10, 0x10000000); + SimpleLTTarget2 target2("target2"); + + SimpleLTInitiator3_dmi initiator3("initiator3", 10, 0x20000000); + SimpleLTTarget2 target3("target3"); + + SimpleATInitiator1 initiator4("initiator4", 10, 0x30000000); + SimpleATTarget1 target4("target4"); + + SimpleATInitiator2 initiator5("initiator5", 10, 0x40000000); + SimpleATTarget2 target5("target5"); + + CoreDecouplingLTInitiator initiator6("initiator6", 10, 0x50000000); + ExplicitLTTarget target6("target6"); + + CoreDecouplingLTInitiator initiator7("initiator7", 10, 0x60000000); + ExplicitATTarget target7("target7"); + + SimpleBusLT<7, 7> bus("bus"); + + initiator1.socket(bus.target_socket[0]); + initiator2.socket(bus.target_socket[1]); + initiator3.socket(bus.target_socket[2]); + initiator4.socket(bus.target_socket[3]); + initiator5.socket(bus.target_socket[4]); + initiator6.socket(bus.target_socket[5]); + initiator7.socket(bus.target_socket[6]); + bus.initiator_socket[0](target1.socket); + bus.initiator_socket[1](target2.socket); + bus.initiator_socket[2](target3.socket); + bus.initiator_socket[3](target4.socket); + bus.initiator_socket[4](target5.socket); + bus.initiator_socket[5](target6.socket); + bus.initiator_socket[6](target7.socket); + + sc_core::sc_start(); + sc_core::sc_stop(); + + return 0; +} diff --git a/src/systemc/tests/tlm/bus_dmi/golden/bus_dmi.log b/src/systemc/tests/tlm/bus_dmi/golden/bus_dmi.log new file mode 100644 index 000000000..2e653101e --- /dev/null +++ b/src/systemc/tests/tlm/bus_dmi/golden/bus_dmi.log @@ -0,0 +1,381 @@ +SystemC Simulation +initiator1: Send write request: A = 0x0, D = 0x0 @ 0 s +target1: Received write request: A = 0x0, D = 0x0 @ 0 s +initiator2: Send write request: A = 0x10000000, D = 0x0 @ 0 s +initiator3: Send write request: A = 0x20000000, D = 0x0 @ 0 s +initiator4: Send write request: A = 0x30000000, D = 0x0 @ 0 s +initiator5: Send write request: A = 0x40000000, D = 0x0 @ 0 s +initiator6: Send write request: A = 0x50000000, D = 0x0 @ 0 s (0 s + 0 s) +target6: Received write request: A = 0x0, D = 0x0 @ 0 s +initiator7: Send write request: A = 0x60000000, D = 0x0 @ 0 s (0 s + 0 s) +target7: Received write request: A = 0x0, D = 0x0 @ 0 s +target4: Received write request: A = 0x0, D = 0x0 @ 0 s +target5: Received write request: A = 0x0, D = 0x0 @ 0 s +initiator1: Received ok response @ 10 ns +initiator1: Send write request: A = 0x4, D = 0x1 @ 10 ns +initiator2: Received ok response @ 10 ns +initiator2: Send write request: A = 0x10000004, D = 0x1 @ 10 ns +initiator3: Received ok response @ 10 ns +initiator3: Send write request: A = 0x20000004, D = 0x1 @ 10 ns +initiator1: Received ok response @ 20 ns +initiator1: Send write request: A = 0x8, D = 0x2 @ 20 ns +initiator3: Received ok response @ 20 ns +initiator3: Send write request: A = 0x20000008, D = 0x2 @ 20 ns +initiator2: Received ok response @ 20 ns +initiator2: Send write request: A = 0x10000008, D = 0x2 @ 20 ns +initiator3: Received ok response @ 30 ns +initiator3: Send write request: A = 0x2000000c, D = 0x3 @ 30 ns +initiator2: Received ok response @ 30 ns +initiator2: Send write request: A = 0x1000000c, D = 0x3 @ 30 ns +initiator1: Received ok response @ 30 ns +initiator1: Send write request: A = 0xc, D = 0x3 @ 30 ns +initiator3: Received ok response @ 40 ns +initiator3: Send write request: A = 0x20000010, D = 0x4 @ 40 ns +initiator1: Received ok response @ 40 ns +initiator1: Send write request: A = 0x10, D = 0x4 @ 40 ns +initiator2: Received ok response @ 40 ns +initiator2: Send write request: A = 0x10000010, D = 0x4 @ 40 ns +initiator6: Received ok response @ 50 ns (50 ns + 0 s) +initiator6: Send write request: A = 0x50000004, D = 0x1 @ 50 ns (50 ns + 0 s) +target6: Received write request: A = 0x4, D = 0x1 @ 50 ns +initiator2: Received ok response @ 50 ns +initiator2: Send write request: A = 0x10000014, D = 0x5 @ 50 ns +initiator3: Received ok response @ 50 ns +initiator3: Send write request: A = 0x20000014, D = 0x5 @ 50 ns +initiator1: Received ok response @ 50 ns +initiator1: Send write request: A = 0x14, D = 0x5 @ 50 ns +initiator7: Received ok response @ 50 ns (50 ns + 0 s) +initiator7: Send write request: A = 0x60000004, D = 0x1 @ 50 ns (50 ns + 0 s) +target7: Received write request: A = 0x4, D = 0x1 @ 50 ns +initiator2: Received ok response @ 60 ns +initiator2: Send write request: A = 0x10000018, D = 0x6 @ 60 ns +initiator3: Received ok response @ 60 ns +initiator3: Send write request: A = 0x20000018, D = 0x6 @ 60 ns +initiator1: Received ok response @ 60 ns +initiator1: Send write request: A = 0x18, D = 0x6 @ 60 ns +initiator2: Received ok response @ 70 ns +initiator2: Send write request: A = 0x1000001c, D = 0x7 @ 70 ns +initiator1: Received ok response @ 70 ns +initiator1: Send write request: A = 0x1c, D = 0x7 @ 70 ns +initiator3: Received ok response @ 70 ns +initiator3: Send write request: A = 0x2000001c, D = 0x7 @ 70 ns +initiator2: Received ok response @ 80 ns +initiator2: Send write request: A = 0x10000020, D = 0x8 @ 80 ns +initiator3: Received ok response @ 80 ns +initiator3: Send write request: A = 0x20000020, D = 0x8 @ 80 ns +initiator1: Received ok response @ 80 ns +initiator1: Send write request: A = 0x20, D = 0x8 @ 80 ns +initiator2: Received ok response @ 90 ns +initiator2: Send write request: A = 0x10000024, D = 0x9 @ 90 ns +initiator1: Received ok response @ 90 ns +initiator1: Send write request: A = 0x24, D = 0x9 @ 90 ns +initiator3: Received ok response @ 90 ns +initiator3: Send write request: A = 0x20000024, D = 0x9 @ 90 ns +initiator3: Received ok response @ 100 ns +initiator3: Send read request: A = 0x20000000 @ 100 ns +initiator6: Received ok response @ 100 ns (100 ns + 0 s) +initiator6: Send write request: A = 0x50000008, D = 0x2 @ 100 ns (100 ns + 0 s) +target6: Received write request: A = 0x8, D = 0x2 @ 100 ns +initiator2: Received ok response @ 100 ns +initiator2: Send read request: A = 0x10000000 @ 100 ns +initiator1: Received ok response @ 100 ns +initiator1: Send read request: A = 0x0 @ 100 ns +initiator7: Received ok response @ 100 ns (100 ns + 0 s) +initiator7: Send write request: A = 0x60000008, D = 0x2 @ 100 ns (100 ns + 0 s) +target7: Received write request: A = 0x8, D = 0x2 @ 100 ns +initiator5: Received ok response @ 125 ns +initiator4: Send write request: A = 0x30000004, D = 0x1 @ 125 ns +initiator5: Send write request: A = 0x40000004, D = 0x1 @ 125 ns +target4: Received write request: A = 0x4, D = 0x1 @ 125 ns +target5: Received write request: A = 0x4, D = 0x1 @ 125 ns +initiator4: Received ok response @ 135 ns +initiator6: Received ok response @ 150 ns (150 ns + 0 s) +initiator6: Send write request: A = 0x5000000c, D = 0x3 @ 150 ns (150 ns + 0 s) +target6: Received write request: A = 0xc, D = 0x3 @ 150 ns +initiator7: Received ok response @ 150 ns (150 ns + 0 s) +initiator7: Send write request: A = 0x6000000c, D = 0x3 @ 150 ns (150 ns + 0 s) +target7: Received write request: A = 0xc, D = 0x3 @ 150 ns +initiator2: Received ok response: D = 0x0 @ 200 ns +initiator2: Send read request: A = 0x10000004 @ 200 ns +initiator3: Received ok response: D = 0x0 @ 200 ns +initiator3: Send read request: A = 0x20000004 @ 200 ns +initiator1: Received ok response: D = 0x0 @ 200 ns +initiator1: Send read request: A = 0x4 @ 200 ns +initiator6: Received ok response @ 200 ns (200 ns + 0 s) +initiator6: Send write request: A = 0x50000010, D = 0x4 @ 200 ns (200 ns + 0 s) +target6: Received write request: A = 0x10, D = 0x4 @ 200 ns +initiator7: Received ok response @ 200 ns (200 ns + 0 s) +initiator7: Send write request: A = 0x60000010, D = 0x4 @ 200 ns (200 ns + 0 s) +target7: Received write request: A = 0x10, D = 0x4 @ 200 ns +initiator6: Received ok response @ 250 ns (250 ns + 0 s) +initiator6: Send write request: A = 0x50000014, D = 0x5 @ 250 ns (250 ns + 0 s) +target6: Received write request: A = 0x14, D = 0x5 @ 250 ns +initiator7: Received ok response @ 250 ns (250 ns + 0 s) +initiator7: Send write request: A = 0x60000014, D = 0x5 @ 250 ns (250 ns + 0 s) +initiator5: Received ok response @ 250 ns +target7: Received write request: A = 0x14, D = 0x5 @ 250 ns +initiator4: Send write request: A = 0x30000008, D = 0x2 @ 250 ns +initiator5: Send write request: A = 0x40000008, D = 0x2 @ 250 ns +target4: Received write request: A = 0x8, D = 0x2 @ 250 ns +target5: Received write request: A = 0x8, D = 0x2 @ 250 ns +initiator4: Received ok response @ 260 ns +initiator1: Received ok response: D = 0x1 @ 300 ns +initiator1: Send read request: A = 0x8 @ 300 ns +initiator6: Received ok response @ 300 ns (300 ns + 0 s) +initiator6: Send write request: A = 0x50000018, D = 0x6 @ 300 ns (300 ns + 0 s) +target6: Received write request: A = 0x18, D = 0x6 @ 300 ns +initiator3: Received ok response: D = 0x1 @ 300 ns +initiator3: Send read request: A = 0x20000008 @ 300 ns +initiator2: Received ok response: D = 0x1 @ 300 ns +initiator2: Send read request: A = 0x10000008 @ 300 ns +initiator7: Received ok response @ 300 ns (300 ns + 0 s) +initiator7: Send write request: A = 0x60000018, D = 0x6 @ 300 ns (300 ns + 0 s) +target7: Received write request: A = 0x18, D = 0x6 @ 300 ns +initiator6: Received ok response @ 350 ns (350 ns + 0 s) +initiator6: Send write request: A = 0x5000001c, D = 0x7 @ 350 ns (350 ns + 0 s) +target6: Received write request: A = 0x1c, D = 0x7 @ 350 ns +initiator7: Received ok response @ 350 ns (350 ns + 0 s) +initiator7: Send write request: A = 0x6000001c, D = 0x7 @ 350 ns (350 ns + 0 s) +target7: Received write request: A = 0x1c, D = 0x7 @ 350 ns +initiator5: Received ok response @ 375 ns +initiator5: Send write request: A = 0x4000000c, D = 0x3 @ 375 ns +initiator4: Send write request: A = 0x3000000c, D = 0x3 @ 375 ns +target5: Received write request: A = 0xc, D = 0x3 @ 375 ns +target4: Received write request: A = 0xc, D = 0x3 @ 375 ns +initiator4: Received ok response @ 385 ns +initiator1: Received ok response: D = 0x2 @ 400 ns +initiator1: Send read request: A = 0xc @ 400 ns +initiator3: Received ok response: D = 0x2 @ 400 ns +initiator3: Send read request: A = 0x2000000c @ 400 ns +initiator2: Received ok response: D = 0x2 @ 400 ns +initiator2: Send read request: A = 0x1000000c @ 400 ns +initiator6: Received ok response @ 400 ns (400 ns + 0 s) +initiator6: Send write request: A = 0x50000020, D = 0x8 @ 400 ns (400 ns + 0 s) +target6: Received write request: A = 0x20, D = 0x8 @ 400 ns +initiator7: Received ok response @ 400 ns (400 ns + 0 s) +initiator7: Send write request: A = 0x60000020, D = 0x8 @ 400 ns (400 ns + 0 s) +target7: Received write request: A = 0x20, D = 0x8 @ 400 ns +initiator6: Received ok response @ 450 ns (450 ns + 0 s) +initiator6: Send write request: A = 0x50000024, D = 0x9 @ 450 ns (450 ns + 0 s) +target6: Received write request: A = 0x24, D = 0x9 @ 450 ns +initiator7: Received ok response @ 450 ns (450 ns + 0 s) +initiator7: Send write request: A = 0x60000024, D = 0x9 @ 450 ns (450 ns + 0 s) +target7: Received write request: A = 0x24, D = 0x9 @ 450 ns +initiator1: Received ok response: D = 0x3 @ 500 ns +initiator1: Send read request: A = 0x10 @ 500 ns +Sync'ing... +initiator2: Received ok response: D = 0x3 @ 500 ns +initiator2: Send read request: A = 0x10000010 @ 500 ns +initiator3: Received ok response: D = 0x3 @ 500 ns +initiator3: Send read request: A = 0x20000010 @ 500 ns +initiator6: Received ok response @ 500 ns (500 ns + 0 s) +initiator6: Send read request: A = 0x50000000 @ 500 ns (500 ns + 0 s) +target6: Received read request: A = 0x0 @ 500 ns +initiator6: Received ok response: D = 0x0 @ 600 ns (500 ns + 100 ns) +initiator6: Send read request: A = 0x50000004 @ 600 ns (500 ns + 100 ns) +target6: Received read request: A = 0x4 @ 500 ns +initiator6: Received ok response: D = 0x1 @ 700 ns (500 ns + 200 ns) +initiator6: Send read request: A = 0x50000008 @ 700 ns (500 ns + 200 ns) +target6: Received read request: A = 0x8 @ 500 ns +initiator6: Received ok response: D = 0x2 @ 800 ns (500 ns + 300 ns) +initiator6: Send read request: A = 0x5000000c @ 800 ns (500 ns + 300 ns) +target6: Received read request: A = 0xc @ 500 ns +initiator6: Received ok response: D = 0x3 @ 900 ns (500 ns + 400 ns) +initiator6: Send read request: A = 0x50000010 @ 900 ns (500 ns + 400 ns) +target6: Received read request: A = 0x10 @ 500 ns +Sync'ing... +Sync'ing... +initiator5: Received ok response @ 500 ns +initiator7: Received ok response @ 500 ns (500 ns + 0 s) +initiator7: Send read request: A = 0x60000000 @ 500 ns (500 ns + 0 s) +target7: Received read request: A = 0x0 @ 500 ns +initiator4: Send write request: A = 0x30000010, D = 0x4 @ 500 ns +initiator5: Send write request: A = 0x40000010, D = 0x4 @ 500 ns +target4: Received write request: A = 0x10, D = 0x4 @ 500 ns +target5: Received write request: A = 0x10, D = 0x4 @ 500 ns +initiator4: Received ok response @ 510 ns +initiator3: Received ok response: D = 0x4 @ 600 ns +initiator3: Send read request: A = 0x20000014 @ 600 ns +initiator1: Received ok response: D = 0x4 @ 600 ns +initiator1: Send read request: A = 0x14 @ 600 ns +initiator2: Received ok response: D = 0x4 @ 600 ns +initiator2: Send read request: A = 0x10000014 @ 600 ns +initiator7: Received ok response: D = 0x0 @ 600 ns (600 ns + 0 s) +initiator7: Send read request: A = 0x60000004 @ 600 ns (600 ns + 0 s) +target7: Received read request: A = 0x4 @ 600 ns +initiator5: Received ok response @ 625 ns +initiator4: Send write request: A = 0x30000014, D = 0x5 @ 625 ns +initiator5: Send write request: A = 0x40000014, D = 0x5 @ 625 ns +target4: Received write request: A = 0x14, D = 0x5 @ 625 ns +target5: Received write request: A = 0x14, D = 0x5 @ 625 ns +initiator4: Received ok response @ 635 ns +initiator2: Received ok response: D = 0x5 @ 700 ns +initiator2: Send read request: A = 0x10000018 @ 700 ns +initiator3: Received ok response: D = 0x5 @ 700 ns +initiator3: Send read request: A = 0x20000018 @ 700 ns +initiator1: Received ok response: D = 0x5 @ 700 ns +initiator1: Send read request: A = 0x18 @ 700 ns +initiator7: Received ok response: D = 0x1 @ 700 ns (700 ns + 0 s) +initiator7: Send read request: A = 0x60000008 @ 700 ns (700 ns + 0 s) +target7: Received read request: A = 0x8 @ 700 ns +initiator5: Received ok response @ 750 ns +initiator4: Send write request: A = 0x30000018, D = 0x6 @ 750 ns +initiator5: Send write request: A = 0x40000018, D = 0x6 @ 750 ns +target4: Received write request: A = 0x18, D = 0x6 @ 750 ns +target5: Received write request: A = 0x18, D = 0x6 @ 750 ns +initiator4: Received ok response @ 760 ns +initiator1: Received ok response: D = 0x6 @ 800 ns +initiator1: Send read request: A = 0x1c @ 800 ns +initiator2: Received ok response: D = 0x6 @ 800 ns +initiator2: Send read request: A = 0x1000001c @ 800 ns +initiator3: Received ok response: D = 0x6 @ 800 ns +initiator3: Send read request: A = 0x2000001c @ 800 ns +initiator7: Received ok response: D = 0x2 @ 800 ns (800 ns + 0 s) +initiator7: Send read request: A = 0x6000000c @ 800 ns (800 ns + 0 s) +target7: Received read request: A = 0xc @ 800 ns +initiator5: Received ok response @ 875 ns +initiator4: Send write request: A = 0x3000001c, D = 0x7 @ 875 ns +initiator5: Send write request: A = 0x4000001c, D = 0x7 @ 875 ns +target4: Received write request: A = 0x1c, D = 0x7 @ 875 ns +target5: Received write request: A = 0x1c, D = 0x7 @ 875 ns +initiator4: Received ok response @ 885 ns +initiator1: Received ok response: D = 0x7 @ 900 ns +initiator1: Send read request: A = 0x20 @ 900 ns +initiator7: Received ok response: D = 0x3 @ 900 ns (900 ns + 0 s) +initiator7: Send read request: A = 0x60000010 @ 900 ns (900 ns + 0 s) +initiator2: Received ok response: D = 0x7 @ 900 ns +initiator2: Send read request: A = 0x10000020 @ 900 ns +initiator3: Received ok response: D = 0x7 @ 900 ns +initiator3: Send read request: A = 0x20000020 @ 900 ns +target7: Received read request: A = 0x10 @ 900 ns +initiator6: Received ok response: D = 0x4 @ 1 us (1 us + 0 s) +initiator6: Send read request: A = 0x50000014 @ 1 us (1 us + 0 s) +target6: Received read request: A = 0x14 @ 1 us +initiator6: Received ok response: D = 0x5 @ 1100 ns (1 us + 100 ns) +initiator6: Send read request: A = 0x50000018 @ 1100 ns (1 us + 100 ns) +target6: Received read request: A = 0x18 @ 1 us +initiator6: Received ok response: D = 0x6 @ 1200 ns (1 us + 200 ns) +initiator6: Send read request: A = 0x5000001c @ 1200 ns (1 us + 200 ns) +target6: Received read request: A = 0x1c @ 1 us +initiator6: Received ok response: D = 0x7 @ 1300 ns (1 us + 300 ns) +initiator6: Send read request: A = 0x50000020 @ 1300 ns (1 us + 300 ns) +target6: Received read request: A = 0x20 @ 1 us +initiator6: Received ok response: D = 0x8 @ 1400 ns (1 us + 400 ns) +initiator6: Send read request: A = 0x50000024 @ 1400 ns (1 us + 400 ns) +target6: Received read request: A = 0x24 @ 1 us +Sync'ing... +Sync'ing... +initiator3: Received ok response: D = 0x8 @ 1 us +initiator3: Send read request: A = 0x20000024 @ 1 us +initiator2: Received ok response: D = 0x8 @ 1 us +initiator2: Send read request: A = 0x10000024 @ 1 us +initiator1: Received ok response: D = 0x8 @ 1 us +initiator1: Send read request: A = 0x24 @ 1 us +initiator7: Received ok response: D = 0x4 @ 1 us (1 us + 0 s) +initiator7: Send read request: A = 0x60000014 @ 1 us (1 us + 0 s) +initiator5: Received ok response @ 1 us +target7: Received read request: A = 0x14 @ 1 us +initiator5: Send write request: A = 0x40000020, D = 0x8 @ 1 us +initiator4: Send write request: A = 0x30000020, D = 0x8 @ 1 us +target5: Received write request: A = 0x20, D = 0x8 @ 1 us +target4: Received write request: A = 0x20, D = 0x8 @ 1 us +initiator4: Received ok response @ 1010 ns +initiator3: Received ok response: D = 0x9 @ 1100 ns +initiator1: Received ok response: D = 0x9 @ 1100 ns +initiator7: Received ok response: D = 0x5 @ 1100 ns (1100 ns + 0 s) +initiator7: Send read request: A = 0x60000018 @ 1100 ns (1100 ns + 0 s) +initiator2: Received ok response: D = 0x9 @ 1100 ns +target7: Received read request: A = 0x18 @ 1100 ns +initiator5: Received ok response @ 1125 ns +initiator5: Send write request: A = 0x40000024, D = 0x9 @ 1125 ns +initiator4: Send write request: A = 0x30000024, D = 0x9 @ 1125 ns +target5: Received write request: A = 0x24, D = 0x9 @ 1125 ns +target4: Received write request: A = 0x24, D = 0x9 @ 1125 ns +initiator4: Received ok response @ 1135 ns +initiator7: Received ok response: D = 0x6 @ 1200 ns (1200 ns + 0 s) +initiator7: Send read request: A = 0x6000001c @ 1200 ns (1200 ns + 0 s) +target7: Received read request: A = 0x1c @ 1200 ns +initiator5: Received ok response @ 1250 ns +initiator5: Send read request: A = 0x40000000 @ 1250 ns +initiator4: Send read request: A = 0x30000000 @ 1250 ns +target5: Received read request: A = 0x0 @ 1250 ns +target4: Received read request: A = 0x0 @ 1250 ns +initiator4: Received ok response @ 1260 ns +initiator7: Received ok response: D = 0x7 @ 1300 ns (1300 ns + 0 s) +initiator7: Send read request: A = 0x60000020 @ 1300 ns (1300 ns + 0 s) +target7: Received read request: A = 0x20 @ 1300 ns +initiator5: Received ok response: D = 0x0 @ 1375 ns +initiator5: Send read request: A = 0x40000004 @ 1375 ns +initiator4: Send read request: A = 0x30000004 @ 1375 ns +target5: Received read request: A = 0x4 @ 1375 ns +target4: Received read request: A = 0x4 @ 1375 ns +initiator4: Received ok response: D = 0x0 @ 1385 ns +initiator7: Received ok response: D = 0x8 @ 1400 ns (1400 ns + 0 s) +initiator7: Send read request: A = 0x60000024 @ 1400 ns (1400 ns + 0 s) +target7: Received read request: A = 0x24 @ 1400 ns +Sync'ing... +initiator6: Received ok response: D = 0x9 @ 1500 ns (1500 ns + 0 s) +initiator7: Received ok response: D = 0x9 @ 1500 ns (1500 ns + 0 s) +initiator5: Received ok response: D = 0x1 @ 1500 ns +initiator4: Send read request: A = 0x30000008 @ 1500 ns +initiator5: Send read request: A = 0x40000008 @ 1500 ns +target4: Received read request: A = 0x8 @ 1500 ns +target5: Received read request: A = 0x8 @ 1500 ns +initiator4: Received ok response: D = 0x1 @ 1510 ns +initiator5: Received ok response: D = 0x2 @ 1625 ns +initiator4: Send read request: A = 0x3000000c @ 1625 ns +initiator5: Send read request: A = 0x4000000c @ 1625 ns +target4: Received read request: A = 0xc @ 1625 ns +target5: Received read request: A = 0xc @ 1625 ns +initiator4: Received ok response: D = 0x2 @ 1635 ns +initiator5: Received ok response: D = 0x3 @ 1750 ns +initiator4: Send read request: A = 0x30000010 @ 1750 ns +initiator5: Send read request: A = 0x40000010 @ 1750 ns +target4: Received read request: A = 0x10 @ 1750 ns +target5: Received read request: A = 0x10 @ 1750 ns +initiator4: Received ok response: D = 0x3 @ 1760 ns +initiator5: Received ok response: D = 0x4 @ 1875 ns +initiator4: Send read request: A = 0x30000014 @ 1875 ns +initiator5: Send read request: A = 0x40000014 @ 1875 ns +target4: Received read request: A = 0x14 @ 1875 ns +target5: Received read request: A = 0x14 @ 1875 ns +initiator4: Received ok response: D = 0x4 @ 1885 ns +initiator5: Received ok response: D = 0x5 @ 2 us +initiator4: Send read request: A = 0x30000018 @ 2 us +initiator5: Send read request: A = 0x40000018 @ 2 us +target4: Received read request: A = 0x18 @ 2 us +target5: Received read request: A = 0x18 @ 2 us +initiator4: Received ok response: D = 0x5 @ 2010 ns +initiator5: Received ok response: D = 0x6 @ 2125 ns +initiator4: Send read request: A = 0x3000001c @ 2125 ns +initiator5: Send read request: A = 0x4000001c @ 2125 ns +target4: Received read request: A = 0x1c @ 2125 ns +target5: Received read request: A = 0x1c @ 2125 ns +initiator4: Received ok response: D = 0x6 @ 2135 ns +initiator5: Received ok response: D = 0x7 @ 2250 ns +initiator4: Send read request: A = 0x30000020 @ 2250 ns +initiator5: Send read request: A = 0x40000020 @ 2250 ns +target4: Received read request: A = 0x20 @ 2250 ns +target5: Received read request: A = 0x20 @ 2250 ns +initiator4: Received ok response: D = 0x7 @ 2260 ns +initiator5: Received ok response: D = 0x8 @ 2375 ns +initiator4: Send read request: A = 0x30000024 @ 2375 ns +initiator5: Send read request: A = 0x40000024 @ 2375 ns +target4: Received read request: A = 0x24 @ 2375 ns +target5: Received read request: A = 0x24 @ 2375 ns +initiator4: Received ok response: D = 0x8 @ 2385 ns +initiator5: Received ok response: D = 0x9 @ 2500 ns +initiator4: Received ok response: D = 0x9 @ 2510 ns + +Info: /OSCI/SystemC: Simulation stopped by user. +initiator1, <<SimpleLTInitiator1>>: + +Mem @0 +00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 +04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 + +initiator2, <<SimpleLTInitiator1>>: + +Mem @10000000 +OK: debug transaction didn't give data. + diff --git a/src/systemc/tests/tlm/cancel_all/cancel_all.cpp b/src/systemc/tests/tlm/cancel_all/cancel_all.cpp new file mode 100644 index 000000000..df97d8962 --- /dev/null +++ b/src/systemc/tests/tlm/cancel_all/cancel_all.cpp @@ -0,0 +1,164 @@ +#define SC_INCLUDE_DYNAMIC_PROCESSES +#include "systemc" +using namespace sc_core; +using namespace sc_dt; +using namespace std; + +#include "tlm.h" +#include "tlm_utils/peq_with_cb_and_phase.h" +#include "tlm_utils/peq_with_get.h" + + +SC_MODULE(Test_peq_with_cb) +{ + + SC_CTOR(Test_peq_with_cb) + : m_peq(this, &Test_peq_with_cb::peq_cb), flag1(true), flag2(true) + { + SC_THREAD(thread); + } + + void thread() + { + section = 1; + + tlm::tlm_generic_payload *trans; + tlm::tlm_phase phase; + for (int i = 0; i < 50; i++) + { + trans = new tlm::tlm_generic_payload; + trans->set_address(i); + m_peq.notify( *trans, phase, sc_time(rand() % 100, SC_NS) ); + } + wait(50, SC_NS); + + m_peq.cancel_all(); + cout << "cancel_all\n"; + section = 2; + + for (int i = 100; i < 150; i++) + { + trans = new tlm::tlm_generic_payload; + trans->set_address(i); + m_peq.notify( *trans, phase, sc_time(rand() % 100, SC_NS) ); + } + wait(50, SC_NS); + m_peq.cancel_all(); + cout << "cancel_all\n"; + + wait(50, SC_NS); + } + + void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase) + { + sc_time t = sc_time_stamp(); + sc_dt::uint64 adr = trans.get_address(); + sc_assert( section == 1 || section == 2 ); + if (section == 1) + { + if (flag1) cout << "Called peq_cb with section = " << section << "\n"; + flag1 = false; + sc_assert( t >= sc_time(0, SC_NS) && t <= sc_time(50, SC_NS) ); + sc_assert( adr >= 0 && adr < 50); + } + else if (section == 2) + { + if (flag2) cout << "Called peq_cb with section = " << section << "\n"; + flag2 = false; + sc_assert( t >= sc_time(50, SC_NS) && t <= sc_time(100, SC_NS) ); + sc_assert( adr >= 100 && adr < 150); + } + } + + int section; + tlm_utils::peq_with_cb_and_phase<Test_peq_with_cb> m_peq; + bool flag1, flag2; +}; + + +SC_MODULE(Test_peq_with_get) +{ + + SC_CTOR(Test_peq_with_get) + : m_peq("foo"), flag3(true), flag4(true) + { + SC_THREAD(thread); + SC_THREAD(ass_end_thread); + } + + void thread() + { + wait(1000, SC_NS); + + section = 3; + + tlm::tlm_generic_payload *trans; + for (int i = 0; i < 50; i++) + { + trans = new tlm::tlm_generic_payload; + trans->set_address(i); + m_peq.notify( *trans, sc_time(rand() % 100, SC_NS) ); + } + wait(50, SC_NS); + + m_peq.cancel_all(); + cout << "cancel_all\n"; + section = 4; + + for (int i = 100; i < 150; i++) + { + trans = new tlm::tlm_generic_payload; + trans->set_address(i); + m_peq.notify( *trans, sc_time(rand() % 100, SC_NS) ); + } + wait(50, SC_NS); + m_peq.cancel_all(); + cout << "cancel_all\n"; + + wait(50, SC_NS); + } + + void ass_end_thread() + { + tlm::tlm_generic_payload *trans; + for(;;) + { + wait(m_peq.get_event()); + while( (trans = m_peq.get_next_transaction()) ) + { + sc_time t = sc_time_stamp(); + sc_dt::uint64 adr = trans->get_address(); + sc_assert( section == 3 || section == 4 ); + if (section == 3) + { + if (flag3) cout << "Called get_next_transaction with section = " << section << "\n"; + flag3 = false; + sc_assert( t >= sc_time(1000, SC_NS) && t <= sc_time(1050, SC_NS) ); + sc_assert( adr >= 0 && adr < 50); + } + else if (section == 4) + { + if (flag4) cout << "Called get_next_transaction with section = " << section << "\n"; + flag4 = false; + sc_assert( t >= sc_time(1050, SC_NS) && t <= sc_time(1100, SC_NS) ); + sc_assert( adr >= 100 && adr < 150); + } + } + } + } + + int section; + tlm_utils::peq_with_get<tlm::tlm_generic_payload> m_peq; + bool flag3, flag4; +}; + + +int sc_main(int argc, char* argv[]) +{ + cout << "Unit test for cancel_all()\n"; + Test_peq_with_cb cb("test_peq_with_cb"); + Test_peq_with_get get("test_peq_with_get"); + sc_start(); + return 0; +} + diff --git a/src/systemc/tests/tlm/cancel_all/golden/cancel_all.log b/src/systemc/tests/tlm/cancel_all/golden/cancel_all.log new file mode 100644 index 000000000..1077270d5 --- /dev/null +++ b/src/systemc/tests/tlm/cancel_all/golden/cancel_all.log @@ -0,0 +1,10 @@ +SystemC Simulation +Unit test for cancel_all() +Called peq_cb with section = 1 +cancel_all +Called peq_cb with section = 2 +cancel_all +Called get_next_transaction with section = 3 +cancel_all +Called get_next_transaction with section = 4 +cancel_all diff --git a/src/systemc/tests/tlm/endian_conv/golden/test_endian_conv.log b/src/systemc/tests/tlm/endian_conv/golden/test_endian_conv.log new file mode 100644 index 000000000..356868498 --- /dev/null +++ b/src/systemc/tests/tlm/endian_conv/golden/test_endian_conv.log @@ -0,0 +1,1204 @@ +SystemC Simulation + +TLM-2 Endianness Conversion Helper Functions Tester +March 2008 +January 2012 Updated to read from endian_conv/input.txt + +0 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 0 + Len = 16 + Bus Width = 8 + Data Word = 4 + Initiator offset = 0 + Byte enables = x + Byte enable length = 0 + Streaming width = 16 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 0 + +Converted Transaction + Addr = 0 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 1111111111111111, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = 45670123cdef89abxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +1 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 0 + Len = 16 + Bus Width = 8 + Data Word = 4 + Initiator offset = 0 + Byte enables = x + Byte enable length = 0 + Streaming width = 16 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 1 + +Converted Transaction + Addr = 0 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 1111111111111111, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = 45670123cdef89abxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +2 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 16 + Len = 16 + Bus Width = 8 + Data Word = 4 + Initiator offset = 0 + Byte enables = x + Byte enable length = 0 + Streaming width = 16 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 2 + +Converted Transaction + Addr = 16 + Len = 16 + Txn data pointer = changed + Byte enable length = 0 + Streaming width = 16 + +Memory States after Transaction + initiator = klmnghijstuvopqrxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +3 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 16 + Len = 16 + Bus Width = 8 + Data Word = 4 + Initiator offset = 4 + Byte enables = x + Byte enable length = 0 + Streaming width = 16 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 0 + +Converted Transaction + Addr = 16 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 1111111111111111, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = xxxxxxxxxxxxxxxx89ab4567ghijcdefxxxx + +4 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +Pool status: +Pool status: (16,16) +Pool status: (16,16) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 16 + Len = 16 + Bus Width = 8 + Data Word = 4 + Initiator offset = 4 + Byte enables = x + Byte enable length = 0 + Streaming width = 16 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 1 + +Converted Transaction + Addr = 16 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 1111111111111111, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = xxxxxxxxxxxxxxxx89ab4567ghijcdefxxxx + +5 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 0 + Len = 16 + Bus Width = 8 + Data Word = 4 + Initiator offset = 0 + Byte enables = x + Byte enable length = 0 + Streaming width = 16 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 2 + +Converted Transaction + Addr = 0 + Len = 16 + Txn data pointer = changed + Byte enable length = 0 + Streaming width = 16 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = 45670123cdef89abxxxxxxxxxxxxxxxxxxxx + +6 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 0 + Len = 16 + Bus Width = 8 + Data Word = 4 + Initiator offset = 0 + Byte enables = 1111000011110000 + Byte enable length = 16 + Streaming width = 16 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 0 + +Converted Transaction + Addr = 0 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 0000111100001111, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = 4567xxxxcdefxxxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +0 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 0 + Len = 16 + Bus Width = 8 + Data Word = 4 + Initiator offset = 0 + Byte enables = 1111000011110000 + Byte enable length = 16 + Streaming width = 16 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 1 + +Converted Transaction + Addr = 0 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 0000111100001111, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = 4567xxxxcdefxxxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +1 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 16 + Len = 16 + Bus Width = 8 + Data Word = 4 + Initiator offset = 0 + Byte enables = 1111000011110000 + Byte enable length = 16 + Streaming width = 16 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 2 + +Converted Transaction + Addr = 16 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 0000111100001111, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = klmnxxxxstuvxxxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +2 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 16 + Len = 16 + Bus Width = 8 + Data Word = 4 + Initiator offset = 4 + Byte enables = 1111000000001111 + Byte enable length = 16 + Streaming width = 16 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 0 + +Converted Transaction + Addr = 16 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 0000111111110000, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = xxxxxxxxxxxxxxxxxxxx4567ghijxxxxxxxx + +3 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 16 + Len = 16 + Bus Width = 8 + Data Word = 4 + Initiator offset = 4 + Byte enables = 1111000000001111 + Byte enable length = 16 + Streaming width = 16 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 1 + +Converted Transaction + Addr = 16 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 0000111111110000, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = xxxxxxxxxxxxxxxxxxxx4567ghijxxxxxxxx + +4 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +Pool status: (32,32) +Pool status: (32,32) (32,32) +Pool status: (32,32) (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 0 + Len = 16 + Bus Width = 8 + Data Word = 4 + Initiator offset = 0 + Byte enables = 1111000000001111 + Byte enable length = 16 + Streaming width = 16 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 2 + +Converted Transaction + Addr = 0 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 0000111111110000, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = xxxx0123cdefxxxxxxxxxxxxxxxxxxxxxxxx + +5 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 20 + Len = 4 + Bus Width = 8 + Data Word = 4 + Initiator offset = 0 + Byte enables = x + Byte enable length = 0 + Streaming width = 4 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 0 + +Converted Transaction + Addr = 16 + Len = 8 + Txn data pointer = changed + Byte enables and byte enable pointer = 11110000, changed + Byte enable length = 8 + Streaming width = 8 + +Memory States after Transaction + initiator = ghijxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +6 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 20 + Len = 4 + Bus Width = 8 + Data Word = 4 + Initiator offset = 0 + Byte enables = x + Byte enable length = 0 + Streaming width = 4 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 1 + +Converted Transaction + Addr = 16 + Len = 4 + Txn data pointer = changed + Byte enables and byte enable pointer = 1111, changed + Byte enable length = 4 + Streaming width = 4 + +Memory States after Transaction + initiator = ghijxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +0 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 20 + Len = 4 + Bus Width = 8 + Data Word = 4 + Initiator offset = 0 + Byte enables = x + Byte enable length = 0 + Streaming width = 4 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 3 + +Converted Transaction + Addr = 16 + Len = 4 + Txn data pointer = unchanged + Byte enable length = 0 + Streaming width = 4 + +Memory States after Transaction + initiator = ghijxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +1 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 28 + Len = 4 + Bus Width = 8 + Data Word = 4 + Initiator offset = 4 + Byte enables = x + Byte enable length = 0 + Streaming width = 4 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 0 + +Converted Transaction + Addr = 24 + Len = 8 + Txn data pointer = changed + Byte enables and byte enable pointer = 11110000, changed + Byte enable length = 8 + Streaming width = 8 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = xxxxxxxxxxxxxxxxxxxxxxxx4567xxxxxxxx + +2 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 28 + Len = 4 + Bus Width = 8 + Data Word = 4 + Initiator offset = 4 + Byte enables = x + Byte enable length = 0 + Streaming width = 4 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 1 + +Converted Transaction + Addr = 24 + Len = 4 + Txn data pointer = changed + Byte enables and byte enable pointer = 1111, changed + Byte enable length = 4 + Streaming width = 4 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = xxxxxxxxxxxxxxxxxxxxxxxx4567xxxxxxxx + +3 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 28 + Len = 4 + Bus Width = 8 + Data Word = 4 + Initiator offset = 4 + Byte enables = x + Byte enable length = 0 + Streaming width = 4 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 3 + +Converted Transaction + Addr = 24 + Len = 4 + Txn data pointer = unchanged + Byte enable length = 0 + Streaming width = 4 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = xxxxxxxxxxxxxxxxxxxxxxxx4567xxxxxxxx + +4 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +Pool status: (32,32) +Pool status: (32,32) (32,32) +Pool status: (32,32) (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 21 + Len = 2 + Bus Width = 8 + Data Word = 2 + Initiator offset = 0 + Byte enables = 11 + Byte enable length = 2 + Streaming width = 2 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 0 + +Converted Transaction + Addr = 16 + Len = 8 + Txn data pointer = changed + Byte enables and byte enable pointer = 01100000, changed + Byte enable length = 8 + Streaming width = 8 + +Memory States after Transaction + initiator = hixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +5 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 21 + Len = 2 + Bus Width = 8 + Data Word = 2 + Initiator offset = 0 + Byte enables = 11 + Byte enable length = 2 + Streaming width = 2 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 1 + +Converted Transaction + Addr = 16 + Len = 3 + Txn data pointer = changed + Byte enables and byte enable pointer = 011, changed + Byte enable length = 3 + Streaming width = 3 + +Memory States after Transaction + initiator = hixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +6 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 21 + Len = 2 + Bus Width = 8 + Data Word = 2 + Initiator offset = 0 + Byte enables = 11 + Byte enable length = 2 + Streaming width = 2 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 3 + +Converted Transaction + Addr = 17 + Len = 2 + Txn data pointer = unchanged + Byte enables and byte enable pointer = 11, unchanged + Byte enable length = 2 + Streaming width = 2 + +Memory States after Transaction + initiator = hixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +0 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 0 + Len = 4 + Bus Width = 4 + Data Word = 4 + Initiator offset = 25 + Byte enables = 1111 + Byte enable length = 4 + Streaming width = 4 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 0 + +Converted Transaction + Addr = 0 + Len = 4 + Txn data pointer = changed + Byte enables and byte enable pointer = 1111, changed + Byte enable length = 4 + Streaming width = 4 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = pqrsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +1 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 0 + Len = 4 + Bus Width = 4 + Data Word = 4 + Initiator offset = 25 + Byte enables = 1111 + Byte enable length = 4 + Streaming width = 4 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 1 + +Converted Transaction + Addr = 0 + Len = 4 + Txn data pointer = changed + Byte enables and byte enable pointer = 1111, changed + Byte enable length = 4 + Streaming width = 4 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = pqrsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +2 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 0 + Len = 4 + Bus Width = 4 + Data Word = 4 + Initiator offset = 25 + Byte enables = 1111 + Byte enable length = 4 + Streaming width = 4 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 3 + +Converted Transaction + Addr = 0 + Len = 4 + Txn data pointer = unchanged + Byte enables and byte enable pointer = 1111, unchanged + Byte enable length = 4 + Streaming width = 4 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = pqrsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +3 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 13 + Len = 14 + Bus Width = 8 + Data Word = 2 + Initiator offset = 0 + Byte enables = x + Byte enable length = 0 + Streaming width = 14 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 0 + +Converted Transaction + Addr = 8 + Len = 24 + Txn data pointer = changed + Byte enables and byte enable pointer = 111000001111111100000111, changed + Byte enable length = 24 + Streaming width = 24 + +Memory States after Transaction + initiator = 9an8lmjkhivgtuxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +4 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +Pool status: (32,32) +Pool status: (32,32) (32,32) +Pool status: (32,32) (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 5 + Len = 4 + Bus Width = 4 + Data Word = 1 + Initiator offset = 25 + Byte enables = x + Byte enable length = 0 + Streaming width = 4 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 0 + +Converted Transaction + Addr = 4 + Len = 8 + Txn data pointer = changed + Byte enables and byte enable pointer = 11100001, changed + Byte enable length = 8 + Streaming width = 8 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = xxxxrqpxxxxsxxxxxxxxxxxxxxxxxxxxxxxx + +5 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 10 + Len = 12 + Bus Width = 4 + Data Word = 4 + Initiator offset = 0 + Byte enables = 111100001111 + Byte enable length = 12 + Streaming width = 12 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 0 + +Converted Transaction + Addr = 8 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 1100001111000011, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = ef89xxxxmnghxxxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +6 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 15 + Len = 8 + Bus Width = 8 + Data Word = 4 + Initiator offset = 25 + Byte enables = 00001111 + Byte enable length = 8 + Streaming width = 8 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 0 + +Converted Transaction + Addr = 8 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 0000000001111000, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = xxxxxxxxxxxxxxxxxtuvwxxxxxxxxxxxxxxx + +0 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 13 + Len = 14 + Bus Width = 8 + Data Word = 2 + Initiator offset = 0 + Byte enables = x + Byte enable length = 0 + Streaming width = 14 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 1 + +Converted Transaction + Addr = 8 + Len = 24 + Txn data pointer = changed + Byte enables and byte enable pointer = 111000001111111100000111, changed + Byte enable length = 24 + Streaming width = 24 + +Memory States after Transaction + initiator = 9an8lmjkhivgtuxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +1 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 5 + Len = 4 + Bus Width = 4 + Data Word = 1 + Initiator offset = 25 + Byte enables = x + Byte enable length = 0 + Streaming width = 4 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 1 + +Converted Transaction + Addr = 4 + Len = 8 + Txn data pointer = changed + Byte enables and byte enable pointer = 11100001, changed + Byte enable length = 8 + Streaming width = 8 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = xxxxrqpxxxxsxxxxxxxxxxxxxxxxxxxxxxxx + +2 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 10 + Len = 12 + Bus Width = 4 + Data Word = 4 + Initiator offset = 0 + Byte enables = 111100001111 + Byte enable length = 12 + Streaming width = 12 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 1 + +Converted Transaction + Addr = 8 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 1100001111000011, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = ef89xxxxmnghxxxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +3 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 15 + Len = 8 + Bus Width = 8 + Data Word = 4 + Initiator offset = 25 + Byte enables = 00001111 + Byte enable length = 8 + Streaming width = 8 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 1 + +Converted Transaction + Addr = 8 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 0000000001111000, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = xxxxxxxxxxxxxxxxxtuvwxxxxxxxxxxxxxxx + +4 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: +Pool status: (32,32) +Pool status: (32,32) (32,32) +Pool status: (32,32) (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 13 + Len = 14 + Bus Width = 8 + Data Word = 2 + Initiator offset = 0 + Byte enables = x + Byte enable length = 0 + Streaming width = 2 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 0 + +Converted Transaction + Addr = 8 + Len = 56 + Txn data pointer = changed + Byte enables and byte enable pointer = 01100000011000000110000001100000011000000110000001100000, changed + Byte enable length = 56 + Streaming width = 8 + +Memory States after Transaction + initiator = 9a9a9a9a9a9a9axxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +5 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 5 + Len = 4 + Bus Width = 4 + Data Word = 1 + Initiator offset = 25 + Byte enables = 1101 + Byte enable length = 4 + Streaming width = 2 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 0 + +Converted Transaction + Addr = 4 + Len = 8 + Txn data pointer = changed + Byte enables and byte enable pointer = 01100100, changed + Byte enable length = 8 + Streaming width = 4 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz + target = xxxxxspxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +6 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 10 + Len = 12 + Bus Width = 4 + Data Word = 4 + Initiator offset = 0 + Byte enables = 11110000 + Byte enable length = 8 + Streaming width = 12 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 0 + +Converted Transaction + Addr = 8 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 1100001111000011, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = ef89xxxxmnghxxxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +0 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 15 + Len = 16 + Bus Width = 8 + Data Word = 4 + Initiator offset = 25 + Byte enables = 00001111 + Byte enable length = 8 + Streaming width = 30 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz01234567890abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 0 + +Converted Transaction + Addr = 8 + Len = 24 + Txn data pointer = changed + Byte enables and byte enable pointer = 000000000111100001111000, changed + Byte enable length = 24 + Streaming width = 24 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz01234567890abcdefghijklmnopqrstuvwxyz + target = xxxxxxxxxxxxxxxxxtuvwxxxx1234xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +1 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = R + Addr = 10 + Len = 12 + Bus Width = 4 + Data Word = 4 + Initiator offset = 0 + Byte enables = 11110000 + Byte enable length = 8 + Streaming width = 15 + Initiator memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Target memory = 0123456789abcdefghijklmnopqrstuvwxyz + Converter = 0 + +Converted Transaction + Addr = 8 + Len = 16 + Txn data pointer = changed + Byte enables and byte enable pointer = 1100001111000011, changed + Byte enable length = 16 + Streaming width = 16 + +Memory States after Transaction + initiator = ef89xxxxmnghxxxxxxxxxxxxxxxxxxxxxxxx + target = 0123456789abcdefghijklmnopqrstuvwxyz + +2 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +enter initiator memory state = (2048 characters) +enter target memory state = (2048 characters) +enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single) +Initiator Intent + Cmd = W + Addr = 15 + Len = 16 + Bus Width = 8 + Data Word = 4 + Initiator offset = 25 + Byte enables = 00001111 + Byte enable length = 8 + Streaming width = 16 + Initiator memory = 0123456789abcdefghijklmnopqrstuvwxyz01234567890abcdefghijklmnopqrstuvwxyz + Target memory = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + Converter = 0 + +Converted Transaction + Addr = 8 + Len = 24 + Txn data pointer = changed + Byte enables and byte enable pointer = 000000000111100001111000, changed + Byte enable length = 24 + Streaming width = 24 + +Memory States after Transaction + initiator = 0123456789abcdefghijklmnopqrstuvwxyz01234567890abcdefghijklmnopqrstuvwxyz + target = xxxxxxxxxxxxxxxxxtuvwxxxx1234xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +3 enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s +Pool status: (32,32) +Pool status: (32,32) (32,32) +Pool status: (32,32) (32,32) (32,32) +Pool status: (24,24) (32,32) (32,32) (32,32) +Pool status: (24,24) (32,32) (32,32) (32,32) +Pool status: (56,56) (24,24) (32,32) (32,32) (32,32) +Pool status: (18,18) (56,56) (24,24) (32,32) (32,32) (32,32) +Pool status: (20,20) (18,18) (56,56) (24,24) (32,32) (32,32) (32,32) diff --git a/src/systemc/tests/tlm/endian_conv/input.txt b/src/systemc/tests/tlm/endian_conv/input.txt new file mode 100644 index 000000000..672c1a55e --- /dev/null +++ b/src/systemc/tests/tlm/endian_conv/input.txt @@ -0,0 +1,198 @@ + +R aligned: addr=0 len=16 bus=8 word=4 dptr=0 be=x s=16 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=0 + +R aligned: addr=0 len=16 bus=8 word=4 dptr=0 be=x s=16 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=1 + +R aligned: addr=16 len=16 bus=8 word=4 dptr=0 be=x s=16 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=2 + +W aligned: addr=16 len=16 bus=8 word=4 dptr=4 be=x s=16 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=0 + +W aligned: addr=16 len=16 bus=8 word=4 dptr=4 be=x s=16 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=1 + +W aligned: addr=0 len=16 bus=8 word=4 dptr=0 be=x s=16 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=2 + +R aligned: addr=0 len=16 bus=8 word=4 dptr=0 be=1111000011110000 s=16 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=0 + +R aligned: addr=0 len=16 bus=8 word=4 dptr=0 be=1111000011110000 s=16 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=1 + +R aligned: addr=16 len=16 bus=8 word=4 dptr=0 be=1111000011110000 s=16 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=2 + +W aligned: addr=16 len=16 bus=8 word=4 dptr=4 be=1111000000001111 s=16 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=0 + +W aligned: addr=16 len=16 bus=8 word=4 dptr=4 be=1111000000001111 s=16 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=1 + +W aligned: addr=0 len=16 bus=8 word=4 dptr=0 be=1111000000001111 s=16 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=2 + + +R single: addr=20 len=4 bus=8 word=4 dptr=0 be=x s=4 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=0 + +R single: addr=20 len=4 bus=8 word=4 dptr=0 be=x s=4 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=1 + +R single: addr=20 len=4 bus=8 word=4 dptr=0 be=x s=4 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=3 + +W single: addr=28 len=4 bus=8 word=4 dptr=4 be=x s=4 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=0 + +W single: addr=28 len=4 bus=8 word=4 dptr=4 be=x s=4 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=1 + +W single: addr=28 len=4 bus=8 word=4 dptr=4 be=x s=4 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=3 + +R single: addr=21 len=2 bus=8 word=2 dptr=0 be=11 s=2 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=0 + +R single: addr=21 len=2 bus=8 word=2 dptr=0 be=11 s=2 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=1 + +R single: addr=21 len=2 bus=8 word=2 dptr=0 be=11 s=2 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=3 + +W single: addr=0 len=4 bus=4 word=4 dptr=25 be=1111 s=4 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=0 + +W single: addr=0 len=4 bus=4 word=4 dptr=25 be=1111 s=4 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=1 + +W single: addr=0 len=4 bus=4 word=4 dptr=25 be=1111 s=4 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=3 + + +R awkward: addr=13 len=14 bus=8 word=2 dptr=0 be=x s=14 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=0 + +W awkward: addr=5 len=4 bus=4 word=1 dptr=25 be=x s=4 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=0 + +R awkward: addr=10 len=12 bus=4 word=4 dptr=0 be=111100001111 s=12 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=0 + +W awkward: addr=15 len=8 bus=8 word=4 dptr=25 be=00001111 s=8 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=0 + + +R awkward: addr=13 len=14 bus=8 word=2 dptr=0 be=x s=14 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=1 + +W awkward: addr=5 len=4 bus=4 word=1 dptr=25 be=x s=4 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=1 + +R awkward: addr=10 len=12 bus=4 word=4 dptr=0 be=111100001111 s=12 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=1 + +W awkward: addr=15 len=8 bus=8 word=4 dptr=25 be=00001111 s=8 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=1 + + +R stream: addr=13 len=14 bus=8 word=2 dptr=0 be=x s=2 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=0 + +W stream: addr=5 len=4 bus=4 word=1 dptr=25 be=1101 s=2 +i=0123456789abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=0 + + +R byte-en-len: addr=10 len=12 bus=4 word=4 dptr=0 be=11110000 s=12 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=0 + +W byte-en-len: addr=15 len=16 bus=8 word=4 dptr=25 be=00001111 s=30 +i=0123456789abcdefghijklmnopqrstuvwxyz01234567890abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=0 + + +R stream-byte-en-len: addr=10 len=12 bus=4 word=4 dptr=0 be=11110000 s=15 +i=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +t=0123456789abcdefghijklmnopqrstuvwxyz +c=0 + +W stream-byte-en-len: addr=15 len=16 bus=8 word=4 dptr=25 be=00001111 s=16 +i=0123456789abcdefghijklmnopqrstuvwxyz01234567890abcdefghijklmnopqrstuvwxyz +t=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +c=0 + + diff --git a/src/systemc/tests/tlm/endian_conv/test_endian_conv.cpp b/src/systemc/tests/tlm/endian_conv/test_endian_conv.cpp new file mode 100644 index 000000000..8a6ff5c56 --- /dev/null +++ b/src/systemc/tests/tlm/endian_conv/test_endian_conv.cpp @@ -0,0 +1,419 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + + +/* +This C++ programme runs single transactions through a single +endianness conversion function, then through a simple memory model, +then converts it back. +Takes the initial memory state as input and provides the final +memory state as output. +*/ + + +#define BUFFER_SIZE 2048 + +#include<systemc> +#include "tlm.h" +#include<iostream> +#include<time.h> +#include <fstream> + +using namespace std; +using namespace tlm; +using namespace sc_dt; + + +// simple set of types with known sizeof(), for testing // +template<int SIZE> class dt { + char content[SIZE]; +}; + + +#define convert(function) \ + switch(data_width) { \ + case 1: function<dt<1> >(&txn,bus_width); break; \ + case 2: function<dt<2> >(&txn,bus_width); break; \ + case 4: function<dt<4> >(&txn,bus_width); break; \ + case 8: function<dt<8> >(&txn,bus_width); break; \ + case 16: function<dt<16> >(&txn,bus_width); break; \ + case 32: function<dt<32> >(&txn,bus_width); break; \ + default: cout << "bad data width\n"; \ + exit(1); \ + } + + +// forward declarations - see below +template<class DATAWORD> inline void +local_single_tohe(tlm_generic_payload *txn, unsigned int sizeof_databus); +template<class DATAWORD> inline void +local_single_fromhe(tlm_generic_payload *txn, unsigned int sizeof_databus); + + +void test_a_conversion(char cmd, tlm_generic_payload &txn, std::ifstream & fin) { + + if(cmd == 'R') txn.set_read(); + else txn.set_write(); + + fin.ignore(10000,'='); + uint64 a; + fin >> a; + txn.set_address(a); + + fin.ignore(10000,'='); + int l; + fin >> l; + txn.set_data_length(l); + + int bus_width; + fin.ignore(10000,'='); fin >> bus_width; + + int data_width; + fin.ignore(10000,'='); fin >> data_width; + + int initiator_offset; + fin.ignore(10000,'='); fin >> initiator_offset; + + unsigned char *original_byte_enable = 0; + unsigned char *byte_enable_legible = + new unsigned char[txn.get_data_length() + 1]; + memset(byte_enable_legible, 0, txn.get_data_length() + 1); + fin.ignore(10000,'='); + for(unsigned b=0; b<txn.get_data_length(); b++) { + char tmp; fin >> tmp; + if((tmp=='0')||(tmp=='1')||(tmp=='x')) byte_enable_legible[b]=tmp; + else break; + } + if((byte_enable_legible[0] == '1') || (byte_enable_legible[0] == '0')) { + txn.set_byte_enable_ptr(new unsigned char[txn.get_data_length()]); + txn.set_byte_enable_length(txn.get_data_length()); + original_byte_enable = txn.get_byte_enable_ptr(); + for(unsigned int i=0; i<txn.get_data_length(); i++) { + if(byte_enable_legible[i] == '0') { + txn.get_byte_enable_ptr()[i] = TLM_BYTE_DISABLED; + } else if(byte_enable_legible[i] == '1') { + txn.get_byte_enable_ptr()[i] = TLM_BYTE_ENABLED; + } else { + // not enough byte enables + txn.set_byte_enable_length(i); + break; + } + } + } else { + txn.set_byte_enable_ptr(0); + txn.set_byte_enable_length(0); + } + + int stream_width; + fin.ignore(10000,'='); fin >> stream_width; + txn.set_streaming_width(stream_width); + + cout << "enter initiator memory state = ("<< BUFFER_SIZE << " characters)\n"; + unsigned char initiator_mem[BUFFER_SIZE+1]; + memset(initiator_mem, 0, BUFFER_SIZE+1); + fin.ignore(10000,'='); fin >> initiator_mem; + + txn.set_data_ptr(initiator_mem + initiator_offset); + + cout << "enter target memory state = ("<< BUFFER_SIZE << " characters)\n"; + unsigned char target_mem[BUFFER_SIZE+1]; + memset(target_mem, 0, BUFFER_SIZE+1); + fin.ignore(10000,'='); fin >> target_mem; + + cout << "enter converter choice = (0 => generic, 1 => word, 2 => aligned, 3 => single)\n"; + int converter; + fin.ignore(10000,'='); fin >> converter; + + cout << "Initiator Intent\n"; + cout << " Cmd = " << cmd << endl; + cout << " Addr = " << txn.get_address() << endl; + cout << " Len = " << txn.get_data_length() << endl; + cout << " Bus Width = " << bus_width << endl; + cout << " Data Word = " << data_width << endl; +#ifdef VERBOSE + cout << " Initiator offset and txn data pointer = " << initiator_offset << ", " << int(txn.get_data_ptr()) << endl; + cout << " Byte enables and byte enable pointer = " << byte_enable_legible << ", " << int(txn.get_byte_enable_ptr()) << endl; +#else + cout << " Initiator offset = " << initiator_offset << endl; + cout << " Byte enables = " << byte_enable_legible << endl; +#endif + cout << " Byte enable length = " << txn.get_byte_enable_length() << endl; + cout << " Streaming width = " << txn.get_streaming_width() << endl; + cout << " Initiator memory = " << initiator_mem << endl; + cout << " Target memory = " << target_mem << endl; + cout << " Converter = " << converter << endl << endl; + + // initiator // + switch(converter) { + case 0: convert(tlm_to_hostendian_generic); break; + case 1: convert(tlm_to_hostendian_word); break; + case 2: convert(tlm_to_hostendian_aligned); break; + case 3: convert(tlm_to_hostendian_single); break; + case 4: convert(local_single_tohe); break; + default: cout << "no such converter as " << converter << endl; + exit(1); + } + + cout << "Converted Transaction\n"; + cout << " Addr = " << txn.get_address() << endl; + cout << " Len = " << txn.get_data_length() << endl; +#ifdef VERBOSE + cout << " Txn data pointer = " << int(txn.get_data_ptr()) << endl; + if(txn.get_byte_enable_ptr() != 0) { + cout << " Byte enables and byte enable pointer = "; + for(unsigned int i=0; i<txn.get_data_length(); i++) + cout << (txn.get_byte_enable_ptr()[i] ? '1' : '0'); + cout << ", " << int(txn.get_byte_enable_ptr()) << endl; + } +#else + cout << " Txn data pointer = " << + (txn.get_data_ptr() == initiator_mem+initiator_offset ? "unchanged" : "changed") << endl; + if(txn.get_byte_enable_ptr() != 0) { + cout << " Byte enables and byte enable pointer = "; + for(unsigned int i=0; i<txn.get_data_length(); i++) + cout << (txn.get_byte_enable_ptr()[i] ? '1' : '0'); + cout << ", " << + (txn.get_byte_enable_ptr() == original_byte_enable ? "unchanged" : "changed") << endl; + } +#endif + cout << " Byte enable length = " << txn.get_byte_enable_length() << endl; + cout << " Streaming width = " << txn.get_streaming_width() << endl; + cout << endl; + + // target // + int sw = txn.get_streaming_width(); + if((txn.get_data_length()/sw)*sw != txn.get_data_length()) { + cout << "ERROR: Data length not a multiple of streaming width\n"; + exit(1); + } + for(unsigned int ss = 0; ss < txn.get_data_length(); ss += sw) { + if(txn.get_byte_enable_ptr() == 0) { + // simple transaction can be processed by mem-copy + if(txn.is_read()) + memcpy(ss+txn.get_data_ptr(), target_mem+txn.get_address(), sw); + else + memcpy(target_mem+txn.get_address(), ss+txn.get_data_ptr(), sw); + } else { + // complex transaction, byte enables, maybe shorter than data + int bel = txn.get_byte_enable_length(); + if(txn.is_read()) { + for(int j=0; j<sw; j++) { + if(txn.get_byte_enable_ptr()[(ss+j) % bel]) + (txn.get_data_ptr())[ss+j] = target_mem[j+txn.get_address()]; + } + } else { + for(int j=0; j<sw; j++) { + if(txn.get_byte_enable_ptr()[(ss+j) % bel]) + target_mem[j+txn.get_address()] = (txn.get_data_ptr())[ss+j]; + } + } + } + } + + // initiator again // + if((rand() & 0x100) && (converter < 4)) { +#ifdef VERBOSE + cout << "using single entry point for response\n"; +#endif + tlm_from_hostendian(&txn); + } else { +#ifdef VERBOSE + cout << "using specific entry point for response\n"; +#endif + switch(converter) { + case 0: convert(tlm_from_hostendian_generic); break; + case 1: convert(tlm_from_hostendian_word); break; + case 2: convert(tlm_from_hostendian_aligned); break; + case 3: convert(tlm_from_hostendian_single); break; + case 4: convert(local_single_fromhe); break; + default: cout << "no such converter as " << converter << endl; + exit(1); + } + } + + // print the results // + cout << "Memory States after Transaction\n"; + cout << " initiator = " << initiator_mem << endl; + cout << " target = " << target_mem << endl << endl; + + // clean up + delete [] byte_enable_legible; + if(original_byte_enable != 0) delete [] original_byte_enable; +} + + +void pool_status() { + cout << "Pool status: "; + tlm_endian_context *f = global_tlm_endian_context_pool.first; + while(f!=0) { + cout << "(" << f->dbuf_size << "," << f->bebuf_size << ") "; + f = f->next; + } + cout << endl; +} + + +int sc_main(int argc, char **argv) { + + #include <string> + + // no command line parameters // + // get everything from stdin and build transaction object // + cout << "\nTLM-2 Endianness Conversion Helper Functions Tester\n"; + cout << "March 2008\n"; + cout << "January 2012 Updated to read from endian_conv/input.txt\n\n"; + + std::string filename; + std::ifstream fin; + + if (1 == argc) + filename = "endian_conv/input.txt"; + else if (2 == argc) + filename = argv[1]; + else { + std::cerr << "Too many input arguments" << std::endl; + return 1; + } + + + fin.open(filename.c_str(), ios_base::in); + if (!fin) { + std::cerr << "Could not open input filename " << filename << std::endl; + return 1; + } + + srand(time(NULL)); + const int nr_txns_in_pool = 7; + const int txn_to_cycle = 4; + tlm_generic_payload *txns[nr_txns_in_pool]; + for(int i=0; i < nr_txns_in_pool; i++) txns[i] = new tlm_generic_payload; + + for(int i=0; true; i = ((i+1) % nr_txns_in_pool)) { + cout << i << " enter {R|W}, addr=a, len=l, bus width=b, word width=w, initiator offset=i, be={x|01}, stream width=s\n"; + pool_status(); + char command; + fin >> command; + if(fin.eof()) break; + if((command != 'R') && (command != 'W')) break; + if(i==txn_to_cycle) { + // should cause 2 extensions to get pushed to the pool once they've been used + delete txns[i]; + pool_status(); + delete txns[i-1]; + pool_status(); + // and popped back later when these new ones establish contexts + txns[i] = new tlm_generic_payload; + txns[i-1] = new tlm_generic_payload; + pool_status(); + } + test_a_conversion(command, *txns[i], fin); + } + + for(int i=0; i < nr_txns_in_pool; i++) { + delete txns[i]; + pool_status(); + } + return 0; +} + + +// converter functions for non-aligned single transactions +// included here for validation only. not designed for general use. + +unsigned char *original_dptr; +sc_dt::uint64 original_addr; + +template<class DATAWORD> inline void +local_single_tohe(tlm_generic_payload *txn, unsigned int sizeof_databus) { + if(txn->get_data_length() != sizeof(DATAWORD)) { + cout << "Error: local_single_tohe() wrongly called\n"; + exit(1); + } + + sc_dt::uint64 mask = sizeof_databus - 1; + + // set up new buffers, length and address + if(sizeof(DATAWORD) > sizeof_databus) + txn->set_data_length(sizeof_databus + sizeof(DATAWORD)); + else + txn->set_data_length(2 * sizeof_databus); + txn->set_streaming_width(txn->get_data_length()); + unsigned char *new_data = new unsigned char[txn->get_data_length()]; + unsigned char *new_be = new unsigned char[txn->get_data_length()]; + // drive all BEs to zero initially + for(unsigned int i=0; i<txn->get_data_length(); i++) new_be[i] = 0; + sc_dt::uint64 new_addr = txn->get_address() & ~mask; + + // Comments assume arithmetic mode big endian initiator modelled on little + // endian host (but the functionality is the same for LE initiator on BE host) + + // iterate over the initiator word byte by byte, MSB first + unsigned char *curr_d = txn->get_data_ptr() + sizeof(DATAWORD) - 1; + unsigned char *curr_b = txn->get_byte_enable_ptr() + sizeof(DATAWORD) - 1; + + // initiator intent is to put the MSB at the address given in the transaction + sc_dt::uint64 curr_a = txn->get_address(); + + // iterate copying data and byte enables + for( ; curr_d >= txn->get_data_ptr(); curr_d--, curr_b--, curr_a++) { + // work out the address in the TLM interpretation of the initiator's intent + sc_dt::uint64 he_addr = curr_a ^ mask; + int idx = he_addr - new_addr; + if(txn->is_write()) new_data[idx] = *curr_d; + if(txn->get_byte_enable_ptr() == 0) new_be[idx] = 1; + else new_be[idx] = *curr_b; + } + + // replace the pointers + original_dptr = txn->get_data_ptr(); + txn->set_data_ptr(new_data); + txn->set_byte_enable_ptr(new_be); + txn->set_byte_enable_length(txn->get_data_length()); + original_addr = txn->get_address(); + txn->set_address(new_addr); +} + + +template<class DATAWORD> inline void +local_single_fromhe(tlm_generic_payload *txn, unsigned int sizeof_databus) { + sc_dt::uint64 mask = sizeof_databus - 1; + + // Comments assume arithmetic mode big endian initiator modelled on little + // endian host (but the functionality is the same for LE initiator on BE host) + + // iterate over the initiator word byte by byte, MSB first + unsigned char *curr_d = original_dptr + sizeof(DATAWORD) - 1; + + // initiator intent is to put the MSB at the address given in the transaction + sc_dt::uint64 curr_a = original_addr; + + // iterate copying data and byte enables + for( ; curr_d >= original_dptr; curr_d--, curr_a++) { + // work out the address in the TLM interpretation of the initiator's intent + sc_dt::uint64 he_addr = curr_a ^ mask; + int idx = he_addr - txn->get_address(); + if((txn->is_read()) && (txn->get_byte_enable_ptr()[idx] != 0)) + *curr_d = txn->get_data_ptr()[idx]; + } + + // clean up + delete [] txn->get_data_ptr(); + delete [] txn->get_byte_enable_ptr(); +} + diff --git a/src/systemc/tests/tlm/endian_conv/testall.py b/src/systemc/tests/tlm/endian_conv/testall.py new file mode 100644 index 000000000..63bf6abe8 --- /dev/null +++ b/src/systemc/tests/tlm/endian_conv/testall.py @@ -0,0 +1,456 @@ +""" +/***************************************************************************** + + 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. + + *****************************************************************************/ + +Python Script to test Endianness Conversion Functions for OSCI TLM-2 + +There is a simple testbench programme in C++ which runs a single +transaction through a single conversion function, to a simple target +memory and back. This script will run the testbench many times and test for +- incomplete execution, seg-faults, etc +- distributability of conversion function: each transaction should have +the same effect on initiator/target memory as a set of smaller transactions +that sum to it +- equivalence: all conversion functions should have the same functional +effect as each other + +The approach is to provide the initial state of the initiator and +target memory (as strings) and to capture their final states, so that +only the effect of the transaction on the data buffers is measured. + +Script works out for itself which conversion functions are legal for a +given transaction and applies all of them. Note that where data is +wider than bus, only one conversion function is legal and testing is +somewhat limited. + +Testing space (select a transaction at random from the space): +- with and without byte-enables (generated at random for each data word +and can be all-zero) +- data widths of (1,2,4,8,16) +- bus widths of (1,2,4,8,16), lower priority for those smaller than data +width +- transaction lengths of (1..32) x data width, higher probability for +lower values +- base address (0..1023) at bus_width steps +- offset address (0..bus width) with a higher priority for 0 +- address in initiator buffer uniform random +- read or write +- byte-enable length may be smaller than transasction length +- may be a streaming burst + +Transaction breakdown +- individual words (always) +- one random breakdown with each segment containing between 1 and N-1 +words, where N is the length in words +- one breakdown with two segments interleaved, using (additional) byte +enables to suppress the part where the other segment is active + +Data buffer definition: starts at 0, randomly filled +with lower case letters and numbers. Size 2 kB. Addresses are limited to +1 kB. +""" + + +import random +import string + + +class transaction: + """ contains read_not_write, address, length, byte_enable, + bus_width, data_width, data_pointer, stream_width """ + def __init__(self, **a): self.__dict__ = a + def __str__(self): + if self.read_not_write: a = "R: " + else: a = "W: " + a += "addr = %d, len = %d, bus = %d, word = %d, data = %d" % \ + (self.address, self.length, self.bus_width, self.data_width, \ + self.data_pointer) + if self.byte_enable: a += ", be = " + self.byte_enable + else: a += ", be = x" + a += ", sw = %d" % (self.stream_width) + return a + + +def txn_generator(nr): + pr_read = 0.5 + pr_byte_enable = 0.5 + pr_enabled = 0.5 + bus_widths = [1, 2, 4, 8, 16] + data_widths = [1, 2, 4, 8, 16] + [1, 2, 4, 8] + [1, 2, 4] + [1, 2] + lengths = range(1,33) + range(1,17) + range(1,9) + range(1,5) + range(1,3) + pr_short_be = 0.2 + pr_stream = 0.1 + nr_generated = 0 + while nr_generated < nr: + # create a random transaction + bus_width = random.choice(bus_widths) + while True: + data_width = random.choice(data_widths) + if data_width <= bus_width: break + if random.random() < 0.25: break + length = random.choice(lengths) + addr_base = random.choice(range(0,1024,bus_width)) + addr_offset = random.choice(range(bus_width)+[0]*(bus_width/2)) + txn = transaction( + bus_width = bus_width, + data_width = data_width, + read_not_write = random.random() < pr_read, + length = length * data_width, + address = addr_base + addr_offset, + byte_enable = False, + stream_width = length * data_width, + data_pointer = random.randint(0,1023) + ) + if random.random() < pr_byte_enable: + belen = length + if random.random() < pr_short_be: + belen = min(random.choice(lengths), length) + bep = ["0" * data_width, "1" * data_width] + txn.byte_enable = "".join([random.choice(bep) for x in range(belen)]) + if random.random() < pr_stream and length > 1: + strlen = length + while True: + strlen -= 1 + if strlen == 1 or \ + (random.random() < 0.5 and (length/strlen)*strlen == length): + break + txn.stream_width = strlen * data_width + nr_generated += 1 + yield txn + +# test code for transaction generator +if False: + for t in txn_generator(20): + print t + raise Exception +# end test code + + +class memory_state_cl: + buffer_size = 2048 + repeats = 10 * buffer_size / 36 + population = (string.lowercase + string.digits) * repeats + def __init__(self): + self.initiator = "".join( + random.sample(memory_state_cl.population, memory_state_cl.buffer_size)) + self.target = "".join( + random.sample(memory_state_cl.population, memory_state_cl.buffer_size)) + def copy(self): + r = memory_state_cl() + r.initiator = self.initiator + r.target = self.target + return r + def __eq__(self, golden): + return self.initiator==golden.initiator and self.target==golden.target + def __ne__(self, golden): + return self.initiator!=golden.initiator or self.target!=golden.target + def __str__(self): + return "initiator = " + self.initiator + "\n" + "target = " + self.target + + +# all fragmentation generators +def __FRAG__null(txn): + yield txn + +def __FRAG__word(txn): + curr_address = txn.address + reset_address = curr_address + txn.stream_width + if txn.byte_enable: + full_byte_enable = txn.byte_enable * (1+txn.length/len(txn.byte_enable)) + be_pos = 0 + d_pos = txn.data_pointer + end = txn.length + d_pos + while d_pos < end: + new_txn = transaction( + bus_width = txn.bus_width, + data_width = txn.data_width, + read_not_write = txn.read_not_write, + length = txn.data_width, + address = curr_address, + byte_enable = False, + stream_width = txn.data_width, + data_pointer = d_pos + ) + curr_address += txn.data_width + if curr_address == reset_address: curr_address = txn.address + d_pos += txn.data_width + if txn.byte_enable: + new_txn.byte_enable = full_byte_enable[be_pos:be_pos+txn.data_width] + be_pos += txn.data_width + yield new_txn + +def __FRAG__stream(txn): + if txn.byte_enable: + full_byte_enable = txn.byte_enable * (1+txn.length/len(txn.byte_enable)) + be_pos = 0 + bytes_done = 0 + while bytes_done < txn.length: + new_txn = transaction( + bus_width = txn.bus_width, + data_width = txn.data_width, + read_not_write = txn.read_not_write, + length = txn.stream_width, + address = txn.address, + byte_enable = False, + stream_width = txn.stream_width, + data_pointer = bytes_done + txn.data_pointer + ) + if txn.byte_enable: + new_txn.byte_enable = full_byte_enable[be_pos:be_pos+txn.stream_width] + be_pos += txn.stream_width + yield new_txn + bytes_done += txn.stream_width + +def __FRAG__random(stream_txn): + for txn in __FRAG__stream(stream_txn): + # txn has full byte enables and no stream feature guaranteed + pr_nofrag = 0.5 + end_address = txn.address + txn.length + curr_address = txn.address + be_pos = 0 + d_pos = txn.data_pointer + while curr_address < end_address: + new_txn = transaction( + bus_width = txn.bus_width, + data_width = txn.data_width, + read_not_write = txn.read_not_write, + length = txn.data_width, + address = curr_address, + byte_enable = txn.byte_enable, + stream_width = txn.data_width, + data_pointer = d_pos + ) + curr_address += txn.data_width + d_pos += txn.data_width + if txn.byte_enable: + new_txn.byte_enable = txn.byte_enable[be_pos:be_pos+txn.data_width] + be_pos += txn.data_width + while random.random() < pr_nofrag and curr_address < end_address: + new_txn.length += txn.data_width + new_txn.stream_width += txn.data_width + curr_address += txn.data_width + d_pos += txn.data_width + if txn.byte_enable: + new_txn.byte_enable += txn.byte_enable[be_pos:be_pos+txn.data_width] + be_pos += txn.data_width + yield new_txn + +def __FRAG__randinterleave(stream_txn): + for txn in __FRAG__stream(stream_txn): + # txn has full byte enables and no stream feature guaranteed + pr_frag = 0.5 + txns = [ transaction( + bus_width = txn.bus_width, + data_width = txn.data_width, + read_not_write = txn.read_not_write, + length = txn.length, + address = txn.address, + byte_enable = "", + stream_width = txn.length, + data_pointer = txn.data_pointer + ), transaction( + bus_width = txn.bus_width, + data_width = txn.data_width, + read_not_write = txn.read_not_write, + length = txn.length, + address = txn.address, + byte_enable = "", + stream_width = txn.length, + data_pointer = txn.data_pointer + ) ] + curr = 0 + be_pos = 0 + on = "1" * txn.data_width + off = "0" * txn.data_width + while be_pos < txn.length: + if txn.byte_enable: bew = txn.byte_enable[be_pos:be_pos+txn.data_width] + else: bew = on + txns[curr].byte_enable += bew + txns[1-curr].byte_enable += off + be_pos += txn.data_width + if random.random() < pr_frag: curr = 1-curr + yield txns[0] + yield txns[1] + +fragmenters = [globals()[n] for n in globals().keys() if n[:8]=="__FRAG__"] + +# test code for fragmenters +if False: + for t in txn_generator(1): + print t + print + for u in fragmenters[4](t): + print u + raise Exception +# end test code + + +# conversion functions are determined by an index (shared with C++) and +# a function that tests if they can be applied to a transaction +def __CHCK__generic(txn): + __CHCK__generic.nr = 0 + return True + +def __CHCK__word(txn): + __CHCK__word.nr = 1 + if txn.data_width > txn.bus_width: return False + if txn.stream_width < txn.length: return False + if txn.byte_enable and len(txn.byte_enable) < txn.length: return False + return True + +def __CHCK__aligned(txn): + __CHCK__aligned.nr = 2 + if txn.data_width > txn.bus_width: return False + if txn.stream_width < txn.length: return False + if txn.byte_enable and len(txn.byte_enable) < txn.length: return False + base_addr = txn.address / txn.bus_width + if base_addr * txn.bus_width != txn.address: return False + nr_bus_words = txn.length / txn.bus_width + if nr_bus_words * txn.bus_width != txn.length: return False + return True + +def __CHCK__single(txn): + __CHCK__single.nr = 3 + if txn.length != txn.data_width: return False + base_addr = txn.address / txn.bus_width + end_base_addr = (txn.address + txn.length - 1) / txn.bus_width + if base_addr != end_base_addr: return False + return True + +def __CHCK__local_single(txn): + __CHCK__local_single.nr = 4 + if txn.length != txn.data_width: return False + return True + +all_converters = [globals()[n] for n in globals().keys() if n[:8]=="__CHCK__"] +for x in all_converters: x.usage = 0 + + +class TesterFailure(Exception): pass +class SystemCFailure(Exception): pass +class ConverterDifference(Exception): pass +class FragmenterDifference(Exception): pass + +from subprocess import Popen, PIPE + +# test a single fragment in multiple ways +def test_a_fragment(f, ms): + # f is the (fragment of a) transaction + # ms is the memory state to use at start of test + + # run the same fragment through all applicable conversion functions + # and check they all do the same thing + # use the same sub-process for all of them + + # build complete stdin + convs = [c for c in all_converters if c(f)] + if len(convs) == 0: raise TesterFailure(f.str()) + txtin = "\n".join( + [("%s\n%s\nconverter = %d\n" % (f, ms, c.nr)) for c in convs]) + + # run and get stdout + txtout = "no output" + try: + sp = Popen("../build-unix/test_endian_conv.exe", stdin=PIPE, stdout=PIPE) + txtout = sp.communicate(txtin)[0] + tmp = txtout.splitlines() + initiators = [l.split()[-1] for l in tmp if l[:14] == " initiator = "] + targets = [l.split()[-1] for l in tmp if l[:11] == " target = "] + except: + raise SystemCFailure("\n" + txtin + txtout) + if sp.returncode != 0: raise SystemCFailure("\n" + txtin + txtout) + if len(initiators) != len(convs): raise SystemCFailure("\n" + txtin + txtout) + if len(targets) != len(convs): raise SystemCFailure("\n" + txtin + txtout) + for c in convs: c.usage += 1 + + ms_out = memory_state_cl() + ms_out.initiator = initiators[0] + ms_out.target = targets[0] + for i in range(1,len(convs)): + if initiators[i]!=ms_out.initiator or targets[i]!=ms_out.target: + raise ConverterDifference(""" +%s +start memory: +%s +converter = %d +golden memory: +%s +actual memory: +%s""" % (f, ms, i, golden_ms, ms_out)) + + return ms_out + + +# main loop + +from sys import argv + +print "Testing Endianness Conversion Functions" +print "March 2008" +print "OSCI TLM-2" + +try: nr_txns_to_test = int(argv[1]) +except: + print "No command line input for number of tests, using default" + nr_txns_to_test = 1000 + +print "Number to test:", nr_txns_to_test + +# generate and test a number of transactions +for txn in txn_generator(nr_txns_to_test): + + # each transaction has a random initial memory state + initial_memory = memory_state_cl() + + # iterate over all defined fragmentation functions + first_time = True + for fragmenter in fragmenters: + + # all versions of the transaction start in the same place + memory_state = initial_memory.copy() + + # now iterate over the fragments of the transaction, accumulating + # the memory state + for partial_txn in fragmenter(txn): + memory_state = test_a_fragment(partial_txn, memory_state) + + if first_time: + golden_memory_state = memory_state.copy() + first_time = False + else: + if memory_state != golden_memory_state: raise FragmenterDifference(""" +fragmenter: %s +transaction: +%s +start memory: +%s +golden memory: +%s +actual memory: +%s""" % (fragmenter, txn, initial_memory, golden_memory_state, memory_state)) + + print ".", +print + + +print "Conversion functions usage frequency:" +for c in all_converters: + print c.nr, c.__name__, c.usage + + diff --git a/src/systemc/tests/tlm/multi_sockets/MultiSocketSimpleSwitchAT.h b/src/systemc/tests/tlm/multi_sockets/MultiSocketSimpleSwitchAT.h new file mode 100644 index 000000000..3e03db312 --- /dev/null +++ b/src/systemc/tests/tlm/multi_sockets/MultiSocketSimpleSwitchAT.h @@ -0,0 +1,340 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __SIMPLESWITCHAT_H__ +#define __SIMPLESWITCHAT_H__ + +#include "tlm.h" + +#include "tlm_utils/multi_passthrough_initiator_socket.h" +#include "tlm_utils/multi_passthrough_target_socket.h" +#include "simpleAddressMap.h" +#include "extensionPool.h" +#include "tlm_utils/instance_specific_extensions.h" +#include "tlm_utils/peq_with_cb_and_phase.h" + + +/* +This class is a simple crossbar switch through which an arbitrary number of initiators +may communicate in parallel as long as they do not talk to the same target. + +If two masters address the same target at the same point of time, +the choice who will be allowed to communicate +is done non-deterministically (based on the SystemC process exectution order). + +This could be avoided by changing the fwPEQ into a priority PEQ of some kind. + +The switch ensures that the end_req and end_resp rules are not violated when +many initiator talk to the same target. +*/ +class MultiSocketSimpleSwitchAT : public sc_core::sc_module, public tlm::tlm_mm_interface +{ +public: + typedef tlm::tlm_generic_payload transaction_type; + typedef tlm::tlm_phase phase_type; + typedef tlm::tlm_sync_enum sync_enum_type; + typedef tlm_utils::multi_passthrough_target_socket<MultiSocketSimpleSwitchAT> target_socket_type; + typedef tlm_utils::multi_passthrough_initiator_socket<MultiSocketSimpleSwitchAT> initiator_socket_type; + +public: + target_socket_type target_socket; //the target multi socket + +private: + initiator_socket_type initiator_socket; //the initiator multi socket (private to enforce use of bindTarget function) + SimpleAddressMap m_addrMap; //a pretty simple address map + std::vector<std::deque<transaction_type*> > m_pendingReqs; //list of pending reqs per target + std::vector<std::deque<transaction_type*> > m_pendingResps; //list of pending resps per initiator + std::vector<sc_dt::uint64> m_masks; //address masks for each target + tlm_utils::instance_specific_extension_accessor accessMySpecificExtensions; //extension accessor to access private extensions + tlm_utils::peq_with_cb_and_phase<MultiSocketSimpleSwitchAT> m_bwPEQ; //PEQ in the fw direction + tlm_utils::peq_with_cb_and_phase<MultiSocketSimpleSwitchAT> m_fwPEQ; //PEQ in the bw direction + + + //an instance specific extension that tells us whether we are in a wrapped b_transport or not + class BTag : public tlm_utils::instance_specific_extension<BTag>{ + public: + sc_core::sc_event event; //trigger this event when transaction is done + }; + + //an instance specific extension that holds information about source and sink of a txn + // as well as information if the req still has to be cleared and if the txn is already + // complete on the target side + class ConnectionInfo : public tlm_utils::instance_specific_extension<ConnectionInfo>{ + public: + unsigned int fwID; //socket number of sink + unsigned int bwID; //socket number of source + bool clearReq; //is the txn still in req phase? + bool alreadyComplete; //has the txn already completed on the target side? + }; + + class internalPEQTypes{ //use the tpPEQ to delay connection infos + public: + typedef ConnectionInfo tlm_payload_type; + typedef tlm::tlm_phase tlm_phase_type; + }; + ExtensionPool<ConnectionInfo> m_connInfoPool; //our pool of extensions + unsigned int m_target_count; //number of connected targets (see bindTargetSocket for explanation) + +public: + SC_HAS_PROCESS(MultiSocketSimpleSwitchAT); + MultiSocketSimpleSwitchAT(sc_core::sc_module_name name) : + sc_core::sc_module(name), + target_socket("target_socket"), + initiator_socket("initiator_socket"), + m_bwPEQ(this, &MultiSocketSimpleSwitchAT::bwPEQcb), + m_fwPEQ(this, &MultiSocketSimpleSwitchAT::fwPEQcb), + m_connInfoPool(10), + m_target_count(0) + { + target_socket.register_nb_transport_fw(this, &MultiSocketSimpleSwitchAT::initiatorNBTransport); + target_socket.register_b_transport(this, &MultiSocketSimpleSwitchAT::b_transport); + initiator_socket.register_nb_transport_bw(this, &MultiSocketSimpleSwitchAT::targetNBTransport); + } + + void bindTargetSocket(initiator_socket_type::base_target_socket_type& target + ,sc_dt::uint64 low + ,sc_dt::uint64 high + ,sc_dt::uint64 mask = 0xffffffffffffffffULL){ + initiator_socket(target); //bind sockets + //insert into address map and increase target count + // (we have to count the targets manually, because target_socket.size() is only reliable during simulation + // as it gets evaluated during end_of_elaboration) + m_addrMap.insert(low, high, m_target_count++); + m_masks.push_back(mask); //add the mask for this target + } + + unsigned int decode(const sc_dt::uint64& address) + { + return m_addrMap.decode(address); + } + + void start_of_simulation(){ + //initialize the lists of pending reqs and resps + m_pendingReqs.resize(initiator_socket.size()); + m_pendingResps.resize(target_socket.size()); + } + + + void b_transport(int initiator_id, transaction_type& trans, sc_core::sc_time& t){ + //first make sure that there is no BTag (just for debugging) + BTag* btag; + accessMySpecificExtensions(trans).get_extension(btag); + sc_assert(!btag); + BTag tag; //now add our BTag + bool added_mm=!trans.has_mm(); //in case there is no MM in we add it now + if (added_mm){ + trans.set_mm(this); + trans.acquire(); //acquire the txn + } + accessMySpecificExtensions(trans).set_extension(&tag); + phase_type phase=tlm::BEGIN_REQ; //then simply use our nb implementation (respects all the rules) + initiatorNBTransport(initiator_id, trans, phase, t); + wait(tag.event); //and wait for the event to be triggered + if (added_mm){ //if we added MM + trans.release(); //we release our reference (this will not delete the txn but trigger the tag.event as soon as the ref count is zero) + if (trans.get_ref_count()) + wait(tag.event); //wait for the ref count to get to zero + trans.set_mm(NULL); //remove the MM + } + //don't forget to remove the extension (instance specific extensions are not cleared off by MM) + accessMySpecificExtensions(trans).clear_extension(&tag); + } + + void free(transaction_type* txn){ + BTag* btag; + accessMySpecificExtensions(*txn).get_extension(btag); + sc_assert(btag); + txn->reset(); //clean off all extension that were added down stream + btag->event.notify(); + } + + //do a fw transmission + void initiatorNBTransport_core(transaction_type& trans, + phase_type& phase, + sc_core::sc_time& t, + unsigned int tgtSocketNumber){ + switch (initiator_socket[tgtSocketNumber]->nb_transport_fw(trans, phase, t)) { + case tlm::TLM_ACCEPTED: + case tlm::TLM_UPDATED: + // Transaction not yet finished + if (phase != tlm::BEGIN_REQ) + { + sc_assert(phase!=tlm::END_RESP); + m_bwPEQ.notify(trans,phase,t); + } + break; + case tlm::TLM_COMPLETED: + // Transaction finished + ConnectionInfo* connInfo; + accessMySpecificExtensions(trans).get_extension(connInfo); + sc_assert(connInfo); + connInfo->alreadyComplete=true; + phase=tlm::BEGIN_RESP; + m_bwPEQ.notify(trans, phase, t); + break; + default: + sc_assert(0); exit(1); + }; + } + + //nb_transport_fw + sync_enum_type initiatorNBTransport(int initiator_id, + transaction_type& trans, + phase_type& phase, + sc_core::sc_time& t) + { + ConnectionInfo* connInfo; + accessMySpecificExtensions(trans).get_extension(connInfo); + m_fwPEQ.notify(trans,phase,t); + if (phase==tlm::BEGIN_REQ){ + //add our private information to the txn + sc_assert(!connInfo); + connInfo=m_connInfoPool.construct(); + connInfo->fwID=decode(trans.get_address()); + connInfo->bwID=initiator_id; + connInfo->clearReq=true; + connInfo->alreadyComplete=false; + accessMySpecificExtensions(trans).set_extension(connInfo); + } + else + if (phase==tlm::END_RESP){ + return tlm::TLM_COMPLETED; + } + else + {sc_assert(0); exit(1);} + return tlm::TLM_ACCEPTED; + } + + sync_enum_type targetNBTransport(int portId, + transaction_type& trans, + phase_type& phase, + sc_core::sc_time& t) + { + if (phase != tlm::END_REQ && phase != tlm::BEGIN_RESP) { + std::cout << "ERROR: '" << name() + << "': Illegal phase received from target." << std::endl; + sc_assert(false); exit(1); + } + //simply stuff it into the bw PEQ + m_bwPEQ.notify(trans,phase,t); + return tlm::TLM_ACCEPTED; + } + + void bwPEQcb(transaction_type& trans, const phase_type& phase){ + //first get our private info from the txn + ConnectionInfo* connInfo; + accessMySpecificExtensions(trans).get_extension(connInfo); + sc_assert(connInfo); + phase_type p=phase; + sc_core::sc_time t=sc_core::SC_ZERO_TIME; + BTag* btag; + accessMySpecificExtensions(trans).get_extension(btag); + bool doCall=btag==NULL; //we only will do a bw call if we are not in a wrapped b_transport + if ((phase==tlm::END_REQ) | (connInfo->clearReq)){ //in case the target left out end_req clearReq reminds us to unlock the req port + sc_assert(m_pendingReqs[connInfo->fwID].size()); + sc_assert(m_pendingReqs[connInfo->fwID].front()==&trans); + m_pendingReqs[connInfo->fwID].pop_front(); //allow another req to start at this target + if (m_pendingReqs[connInfo->fwID].size()){ //there was a pending req + phase_type ph=tlm::BEGIN_REQ; + initiatorNBTransport_core(*m_pendingReqs[connInfo->fwID].front(), ph, t,connInfo->fwID); + } + connInfo->clearReq=false; + } + //no else here, since we might clear the req AND begin a resp + if (phase==tlm::BEGIN_RESP){ + m_pendingResps[connInfo->bwID].push_back(&trans); + doCall=m_pendingResps[connInfo->bwID].size()==1; //do a call in case the response socket was free + } + + if (doCall){ //we have to do a call on the bw of fw path + if (btag){ //only possible if BEGIN_RESP and resp socket was free + phase_type ph=tlm::END_RESP; + m_fwPEQ.notify(trans, ph, t); + } + else + switch (target_socket[connInfo->bwID]->nb_transport_bw(trans, p, t)){ + case tlm::TLM_ACCEPTED: + case tlm::TLM_UPDATED: + break; + case tlm::TLM_COMPLETED:{ + //covers a piggy bagged END_RESP to START_RESP + phase_type ph=tlm::END_RESP; + m_fwPEQ.notify(trans, ph, t); + } + break; + default: + sc_assert(0); exit(1); + + }; + } + } + + //the following two functions (fwPEQcb and clearPEQcb) could be one, if we were allowed + // to stick END_RESP into a PEQ + void fwPEQcb(transaction_type& trans, const phase_type& phase){ + ConnectionInfo* connInfo; + accessMySpecificExtensions(trans).get_extension(connInfo); + sc_assert(connInfo); + phase_type ph=phase; + sc_core::sc_time t=sc_core::SC_ZERO_TIME; + if (phase==tlm::BEGIN_REQ){ + trans.set_address(trans.get_address()&m_masks[connInfo->fwID]); //mask address + m_pendingReqs[connInfo->fwID].push_back(&trans); + if (m_pendingReqs[connInfo->fwID].size()==1){ //the socket is free + initiatorNBTransport_core(trans, ph, t, connInfo->fwID); + } + } + else + { + //phase is always END_RESP + BTag* btag; + accessMySpecificExtensions(trans).get_extension(btag); + accessMySpecificExtensions(trans).clear_extension(connInfo); //remove our specific extension as it is not needed any more + if (!connInfo->alreadyComplete) { + sync_enum_type tmp=initiator_socket[connInfo->fwID]->nb_transport_fw(trans, ph, t); + sc_assert(tmp==tlm::TLM_COMPLETED); + } + sc_assert(m_pendingResps[connInfo->bwID].size()); + m_pendingResps[connInfo->bwID].pop_front(); //remove current response + if (m_pendingResps[connInfo->bwID].size()){ //if there was one pending + ph=tlm::BEGIN_RESP; //schedule its transmission + m_bwPEQ.notify(*m_pendingResps[connInfo->bwID].front(),ph,t); + } + m_connInfoPool.free(connInfo); //release connInfo + if (btag) btag->event.notify(t); //release b_transport + } + } + + void dump_status(){ + std::cout<<"At "<<sc_core::sc_time_stamp()<<" status of "<<name()<<" is "<<std::endl + <<" Number of connected initiators: "<<target_socket.size()<<std::endl + <<" Number of connected targets: "<<initiator_socket.size()<<std::endl + <<" Pending requests:"<<std::endl; + for (unsigned int i=0; i<m_pendingReqs.size(); i++) + std::cout<<" "<<m_pendingReqs[i].size()<<" pending requests for target number "<<i<<std::endl; + std::cout<<" Pending responses:"<<std::endl; + for (unsigned int i=0; i<m_pendingResps.size(); i++) + std::cout<<" "<<m_pendingResps[i].size()<<" pending responses for initiator number "<<i<<std::endl; + std::cout<<" The address map is:"<<std::endl; + m_addrMap.dumpMap(); + + } +}; + +#endif diff --git a/src/systemc/tests/tlm/multi_sockets/extensionPool.h b/src/systemc/tests/tlm/multi_sockets/extensionPool.h new file mode 100644 index 000000000..2f8955fa7 --- /dev/null +++ b/src/systemc/tests/tlm/multi_sockets/extensionPool.h @@ -0,0 +1,106 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __EXTENSION_POOL_H__ +#define __EXTENSION_POOL_H__ + +template <class T> +class ExtensionPool{ + struct entry{ + public: + entry(T* content){ + that=content; + next=NULL; + } + T* that; + entry* next; + }; + +public: + ExtensionPool(int size): used(NULL){ + unused=new entry(new T()); //create first one + mine.push_back(unused->that); + for (int i=0; i<size-1; i++){ + entry* e=new entry(new T()); + e->next=unused; + unused=e; + mine.push_back(unused->that); + } + } + + ~ExtensionPool(){ + //delete all T* that belong to this pool + for (unsigned int i=0; i<mine.size(); i++){ + delete mine[i]; + } + + //delete all unused elements + while (unused){ + entry* e=unused; + unused=unused->next; + delete e; + } + + //delete all used elements + while (used){ + entry* e=used; + used=used->next; + delete e; + } + } + + bool is_from(T* cont){ //slow!!! + for (int i=0; i<mine.size(); i++){ + if (mine[i]==cont) return true; + } + return false; + } + + T* construct(){ + entry* e; + if (unused==NULL){ + e=new entry(new T()); + mine.push_back(e->that); + } + else{ + e=unused; + unused=unused->next; + } + e->next=used; + used=e; + return used->that; //if all elements of pool are used, just create a new one and go on + } + + void free (T* cont){ + sc_assert(used); + entry* e=used; + used=e->next; + e->that=cont; + e->next=unused; + unused=e; + } + +private: + entry* unused; + entry* used; + std::vector<T*> mine; //just for clean up and is_from +}; + +#endif + diff --git a/src/systemc/tests/tlm/multi_sockets/golden/multi_sockets.log b/src/systemc/tests/tlm/multi_sockets/golden/multi_sockets.log new file mode 100644 index 000000000..6ca308579 --- /dev/null +++ b/src/systemc/tests/tlm/multi_sockets/golden/multi_sockets.log @@ -0,0 +1,151 @@ +SystemC Simulation +AT_I1: Send write request: A = 0x10000000, D = 0x0 @ 0 s +LT_I1: Send write request: A = 0x20000000, D = 0x0 @ 0 s +LT_I2: Send write request: A = 0x30000000, D = 0x0 @ 0 s +LT_I3: Send write request: A = 0x60000000, D = 0x0 @ 0 s +AT_I2: Send write request: A = 0x50000000, D = 0x0 @ 0 s +LT_I4: Send write request: A = 0x40000000, D = 0x0 @ 0 s (0 s + 0 s) +AT_T2: Received write request: A = 0x0, D = 0x0 @ 0 s +AT_T1: Received write request: A = 0x0, D = 0x0 @ 0 s +LT_T1: Received write request: A = 0x0, D = 0x0 @ 0 s +LT_T2: Received write request: A = 0x0, D = 0x0 @ 0 s +LT_T3: Received write request: A = 0x0, D = 0x0 @ 0 s +AT_T3: Received write request: A = 0x0, D = 0x0 @ 10 ns +LT_I1: Received ok response @ 10 ns +LT_I1: Send write request: A = 0x20000004, D = 0x1 @ 10 ns +LT_T1: Received write request: A = 0x4, D = 0x1 @ 10 ns +LT_I2: Received ok response @ 10 ns +LT_I2: Send write request: A = 0x30000004, D = 0x1 @ 10 ns +LT_T2: Received write request: A = 0x4, D = 0x1 @ 10 ns +LT_I1: Received ok response @ 20 ns +LT_I1: Send write request: A = 0x20000008, D = 0x2 @ 20 ns +LT_T1: Received write request: A = 0x8, D = 0x2 @ 20 ns +LT_I2: Received ok response @ 20 ns +LT_I2: Send write request: A = 0x30000008, D = 0x2 @ 20 ns +LT_T2: Received write request: A = 0x8, D = 0x2 @ 20 ns +AT_I2: Send write request: A = 0x50000004, D = 0x1 @ 25 ns +AT_T2: Received write request: A = 0x4, D = 0x1 @ 25 ns +AT_I1: Send write request: A = 0x10000004, D = 0x1 @ 25 ns +AT_T1: Received write request: A = 0x4, D = 0x1 @ 25 ns +LT_I1: Received ok response @ 30 ns +LT_I1: Send read request: A = 0x20000000 @ 30 ns +LT_T1: Received read request: A = 0x0 @ 30 ns +LT_I2: Received ok response @ 30 ns +LT_I2: Send read request: A = 0x30000000 @ 30 ns +LT_T2: Received read request: A = 0x0 @ 30 ns +AT_I2: Send write request: A = 0x50000008, D = 0x2 @ 50 ns +AT_T2: Received write request: A = 0x8, D = 0x2 @ 50 ns +AT_I1: Send write request: A = 0x10000008, D = 0x2 @ 50 ns +AT_T1: Received write request: A = 0x8, D = 0x2 @ 50 ns +LT_I4: Received ok response @ 50 ns (50 ns + 0 s) +LT_I4: Send write request: A = 0x40000004, D = 0x1 @ 50 ns (50 ns + 0 s) +LT_T3: Received write request: A = 0x4, D = 0x1 @ 50 ns +LT_I3: Received ok response @ 60 ns +LT_I3: Send write request: A = 0x60000004, D = 0x1 @ 60 ns +AT_I2: Send read request: A = 0x50000000 @ 75 ns +AT_T2: Received read request: A = 0x0 @ 75 ns +AT_I1: Send read request: A = 0x10000000 @ 75 ns +AT_T1: Received read request: A = 0x0 @ 75 ns +AT_I2: Send read request: A = 0x50000004 @ 100 ns +AT_T2: Received read request: A = 0x4 @ 100 ns +AT_I1: Send read request: A = 0x10000004 @ 100 ns +AT_T1: Received read request: A = 0x4 @ 100 ns +LT_I4: Received ok response @ 100 ns (100 ns + 0 s) +LT_I4: Send write request: A = 0x40000008, D = 0x2 @ 100 ns (100 ns + 0 s) +LT_T3: Received write request: A = 0x8, D = 0x2 @ 100 ns +AT_I2: Received ok response @ 125 ns +AT_I2: Send read request: A = 0x50000008 @ 125 ns +AT_T2: Received read request: A = 0x8 @ 125 ns +AT_I1: Send read request: A = 0x10000008 @ 125 ns +AT_T1: Received read request: A = 0x8 @ 125 ns +AT_T3: Received write request: A = 0x4, D = 0x1 @ 130 ns +LT_I1: Received ok response: D = 0x0 @ 130 ns +LT_I1: Send read request: A = 0x20000004 @ 130 ns +LT_T1: Received read request: A = 0x4 @ 130 ns +LT_I2: Received ok response: D = 0x0 @ 130 ns +LT_I2: Send read request: A = 0x30000004 @ 130 ns +LT_T2: Received read request: A = 0x4 @ 130 ns +AT_I1: Received ok response @ 135 ns +LT_I4: Received ok response @ 150 ns (150 ns + 0 s) +LT_I4: Send read request: A = 0x40000000 @ 150 ns (150 ns + 0 s) +LT_T3: Received read request: A = 0x0 @ 150 ns +LT_I3: Received ok response @ 180 ns +LT_I3: Send write request: A = 0x60000008, D = 0x2 @ 180 ns +AT_T3: Received write request: A = 0x8, D = 0x2 @ 230 ns +LT_I1: Received ok response: D = 0x1 @ 230 ns +LT_I1: Send read request: A = 0x20000008 @ 230 ns +LT_T1: Received read request: A = 0x8 @ 230 ns +LT_I2: Received ok response: D = 0x1 @ 230 ns +LT_I2: Send read request: A = 0x30000008 @ 230 ns +LT_T2: Received read request: A = 0x8 @ 230 ns +AT_I2: Received ok response @ 235 ns +AT_I1: Received ok response @ 245 ns +LT_I4: Received ok response: D = 0x0 @ 250 ns (250 ns + 0 s) +LT_I4: Send read request: A = 0x40000004 @ 250 ns (250 ns + 0 s) +LT_T3: Received read request: A = 0x4 @ 250 ns +LT_I3: Received ok response @ 280 ns +LT_I3: Send read request: A = 0x60000000 @ 280 ns +AT_T3: Received read request: A = 0x0 @ 330 ns +LT_I1: Received ok response: D = 0x2 @ 330 ns +LT_I2: Received ok response: D = 0x2 @ 330 ns +AT_I2: Received ok response @ 345 ns +LT_I4: Received ok response: D = 0x1 @ 350 ns (350 ns + 0 s) +LT_I4: Send read request: A = 0x40000008 @ 350 ns (350 ns + 0 s) +LT_T3: Received read request: A = 0x8 @ 350 ns +AT_I1: Received ok response @ 355 ns +LT_I3: Received ok response: D = 0x0 @ 430 ns +LT_I3: Send read request: A = 0x60000004 @ 430 ns +AT_T3: Received read request: A = 0x4 @ 430 ns +LT_I4: Received ok response: D = 0x2 @ 450 ns (450 ns + 0 s) +AT_I2: Received ok response: D = 0x0 @ 455 ns +AT_I1: Received ok response: D = 0x0 @ 465 ns +LT_I3: Received ok response: D = 0x1 @ 530 ns +LT_I3: Send read request: A = 0x60000008 @ 530 ns +AT_T3: Received read request: A = 0x8 @ 530 ns +AT_I2: Received ok response: D = 0x1 @ 565 ns +AT_I1: Received ok response: D = 0x1 @ 575 ns +LT_I3: Received ok response: D = 0x2 @ 630 ns +AT_I2: Received ok response: D = 0x2 @ 675 ns +AT_I1: Received ok response: D = 0x2 @ 685 ns +At 685 ns status of bus1 is + Number of connected initiators: 4 + Number of connected targets: 3 + Pending requests: + 0 pending requests for target number 0 + 0 pending requests for target number 1 + 0 pending requests for target number 2 + Pending responses: + 0 pending responses for initiator number 0 + 0 pending responses for initiator number 1 + 0 pending responses for initiator number 2 + 0 pending responses for initiator number 3 + The address map is: +SimpleAddressMap: printing the sorted MAP: +key: 10000000 value: 255 +key: 1000ffff value: 0 +key: 20000000 value: 255 +key: 2000ffff value: 1 +key: 30000000 value: 255 +key: 6000ffff value: 2 +At 685 ns status of bus2 is + Number of connected initiators: 3 + Number of connected targets: 4 + Pending requests: + 0 pending requests for target number 0 + 0 pending requests for target number 1 + 0 pending requests for target number 2 + 0 pending requests for target number 3 + Pending responses: + 0 pending responses for initiator number 0 + 0 pending responses for initiator number 1 + 0 pending responses for initiator number 2 + The address map is: +SimpleAddressMap: printing the sorted MAP: +key: 30000000 value: 255 +key: 3000ffff value: 1 +key: 40000000 value: 255 +key: 4000ffff value: 3 +key: 50000000 value: 255 +key: 5000ffff value: 0 +key: 60000000 value: 255 +key: 6000ffff value: 2 diff --git a/src/systemc/tests/tlm/multi_sockets/multi_sockets.cpp b/src/systemc/tests/tlm/multi_sockets/multi_sockets.cpp new file mode 100644 index 000000000..fd60e8ba4 --- /dev/null +++ b/src/systemc/tests/tlm/multi_sockets/multi_sockets.cpp @@ -0,0 +1,73 @@ +#define SC_INCLUDE_DYNAMIC_PROCESSES +#include "CoreDecouplingLTInitiator.h" +#include "SimpleATInitiator1.h" +#include "SimpleATInitiator2.h" +#include "SimpleLTInitiator1.h" +#include "SimpleLTInitiator2.h" +#include "SimpleLTInitiator3.h" +#include "SimpleATTarget1.h" +#include "SimpleATTarget2.h" +#include "SimpleLTTarget1.h" +#include "SimpleLTTarget2.h" +#include "ExplicitATTarget.h" +#include "ExplicitLTTarget.h" + +#include "MultiSocketSimpleSwitchAT.h" + +/* +Connection Map: Busses are written vertically + +AT_I1-B-AT_T1 +LT_I1-U-LT_T1 +LT_I2-S +LT_I3-1-B-LT_T2 + U-LT_T3 + AT_I2-S-AT_T2 + LT_I4-2-AT_T3 +*/ +int sc_main(int argc, char* argv[]){ + + MultiSocketSimpleSwitchAT bus1("bus1"); + MultiSocketSimpleSwitchAT bus2("bus2"); + + SimpleATInitiator1 at_i1("AT_I1", 3, 0x10000000); //AT_T1 + SimpleLTInitiator1 lt_i1("LT_I1", 3, 0x20000000); //LT_T1 + SimpleLTInitiator2 lt_i2("LT_I2", 3, 0x30000000); //LT_T2 + SimpleLTInitiator3 lt_i3("LT_I3", 3, 0x60000000); //AT_T3 + + + SimpleATInitiator2 at_i2("AT_I2", 3, 0x50000000); //AT_T2 + CoreDecouplingLTInitiator lt_i4("LT_I4", 3, 0x40000000); //LT_T3 + + SimpleATTarget1 at_t1("AT_T1"); + SimpleATTarget2 at_t2("AT_T2"); + ExplicitATTarget at_t3("AT_T3"); + SimpleLTTarget1 lt_t1("LT_T1"); + SimpleLTTarget2 lt_t2("LT_T2"); + ExplicitLTTarget lt_t3("LT_T3"); + + + at_i1.socket(bus1.target_socket); + lt_i1.socket(bus1.target_socket); + lt_i2.socket(bus1.target_socket); + lt_i3.socket(bus1.target_socket); + + at_i2.socket(bus2.target_socket); + lt_i4.socket(bus2.target_socket); + + bus1.bindTargetSocket(at_t1.socket, 0x10000000,0x1000ffff, 0xfffffff); + bus1.bindTargetSocket(lt_t1.socket, 0x20000000,0x2000ffff, 0xfffffff); + bus1.bindTargetSocket(bus2.target_socket, 0x30000000,0x6000ffff); + + bus2.bindTargetSocket(at_t2.socket, 0x50000000,0x5000ffff, 0xfffffff); + bus2.bindTargetSocket(lt_t2.socket, 0x30000000,0x3000ffff, 0xfffffff); + bus2.bindTargetSocket(at_t3.socket, 0x60000000,0x6000ffff, 0xfffffff); + bus2.bindTargetSocket(lt_t3.socket, 0x40000000,0x4000ffff, 0xfffffff); + + sc_core::sc_start(); + + bus1.dump_status(); + bus2.dump_status(); + + return 0; +} diff --git a/src/systemc/tests/tlm/multi_sockets/simpleAddressMap.h b/src/systemc/tests/tlm/multi_sockets/simpleAddressMap.h new file mode 100644 index 000000000..87ef7851e --- /dev/null +++ b/src/systemc/tests/tlm/multi_sockets/simpleAddressMap.h @@ -0,0 +1,148 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __simpleAddressMap_h__ +#define __simpleAddressMap_h__ + +#include <systemc> +#include <map> + + +//-------------------------------------------------------------------------- +/** + * Simple address map implementation for the generic protocol. + */ +//-------------------------------------------------------------------------- +class SimpleAddressMap +{ + typedef std::map<sc_dt::uint64, unsigned int> mapType; + typedef std::map<sc_dt::uint64, unsigned int>::iterator addressMapIterator; + +public: + SimpleAddressMap() {} + + //-------------------------------------------------------------------------- + /** + * Check for overlapping address ranges + */ + //-------------------------------------------------------------------------- + void checkSanity() + { + addressMapIterator pos; + for (pos=m_addressMap.begin();pos!=m_addressMap.end();++pos){ + if(pos->second!=255) + SC_REPORT_ERROR("SimpleAddressMap","Overlapping Address Regions."); + else + ++pos; + if(pos->second==255) + SC_REPORT_ERROR("SimpleAddressMap","Overlapping Address Regions."); + } + std::cout<<"Address check successful."<<std::endl; + } + + + //-------------------------------------------------------------------------- + /** + * Print map + */ + //-------------------------------------------------------------------------- + void dumpMap() + { + std::cout<<"SimpleAddressMap: printing the sorted MAP:"<<std::endl; + addressMapIterator pos; + for (pos=m_addressMap.begin();pos!=m_addressMap.end();++pos){ + if(pos->second==255) + printf("key: %x value: %i \n", (unsigned int) ((pos->first+1)>>1)-1, pos->second); + else + printf("key: %x value: %i \n", (unsigned int) (pos->first>>1)-1, pos->second); + } + } + + + //-------------------------------------------------------------------------- + /** + * Decode slave address. + * @param address_ A slave address. + * @return The decoded slave port number. On error, the value 255 is returned. + */ + //-------------------------------------------------------------------------- + unsigned int decode(sc_dt::uint64 address_) + { + addressMapIterator lbound; + + lbound=m_addressMap.lower_bound((address_+1)<<1); + if((lbound->second == 255) | (lbound==m_addressMap.end())){ + SC_REPORT_ERROR("SimpleAddressMap", "Address does not match any registered address range."); + } + else{ + return lbound->second; + } + return 255; + } + + const sc_dt::uint64& get_max(){ + if (m_addressMap.size()){ + addressMapIterator i=(m_addressMap.end()); + i--; + retval=(i->first>>1)-1; + return retval; + } + else { + SC_REPORT_ERROR("SimpleAddressMap", "get_max() called on empty address map."); + return retval; + } + } + + const sc_dt::uint64& get_min(){ + if (m_addressMap.size()){ + addressMapIterator i=(m_addressMap.begin()); + retval=((i->first+1)>>1)-1; + return retval; + } + else { + SC_REPORT_ERROR("SimpleAddressMap", "get_min() called on empty address map."); + return retval; + } + } + + //-------------------------------------------------------------------------- + /** + * Insert a slave into the address map + */ + //-------------------------------------------------------------------------- + void insert(sc_dt::uint64 baseAddress_, sc_dt::uint64 highAddress_, unsigned int portNumber_) + { + if(baseAddress_>highAddress_) + SC_REPORT_ERROR("SimpleAddressMap", "Base address must be lower than high address."); + if(portNumber_>=255) + SC_REPORT_ERROR("SimpleAddressMap", "Only ;-) 255 targets can be handled."); + m_addressMap.insert(mapType::value_type(((baseAddress_+1)<<1)-1, 255 )); + m_addressMap.insert(mapType::value_type( (highAddress_+1)<<1 ,portNumber_)); + } + +private: + sc_dt::uint64 retval; + /// the address map + mapType m_addressMap; +}; + + + + +#endif diff --git a/src/systemc/tests/tlm/nb2b_adapter/golden/nb2b_adapter.log b/src/systemc/tests/tlm/nb2b_adapter/golden/nb2b_adapter.log new file mode 100644 index 000000000..e8b02e2f3 --- /dev/null +++ b/src/systemc/tests/tlm/nb2b_adapter/golden/nb2b_adapter.log @@ -0,0 +1,2 @@ +SystemC Simulation +Unit test for nb2b adapter, PEQ, and instance-specific extensions. Should remain silent diff --git a/src/systemc/tests/tlm/nb2b_adapter/mm.h b/src/systemc/tests/tlm/nb2b_adapter/mm.h new file mode 100644 index 000000000..c91dd3ed5 --- /dev/null +++ b/src/systemc/tests/tlm/nb2b_adapter/mm.h @@ -0,0 +1,85 @@ + +// ******************************************************************* +// User-defined memory manager, which maintains a pool of transactions +// ******************************************************************* + +#include "tlm.h" + +class mm: public tlm::tlm_mm_interface +{ + typedef tlm::tlm_generic_payload gp_t; + +public: + mm() : free_list(0), empties(0) {} + + virtual ~mm() + { + gp_t* ptr; + + while (free_list) + { + ptr = free_list->trans; + + // Delete generic payload and all extensions + sc_assert(ptr); + delete ptr; + + free_list = free_list->next; + } + + while (empties) + { + access* x = empties; + empties = empties->next; + + // Delete free list access struct + delete x; + } + } + + gp_t* allocate(); + void free(gp_t* trans); + +private: + struct access + { + gp_t* trans; + access* next; + access* prev; + }; + + access* free_list; + access* empties; +}; + +mm::gp_t* mm::allocate() +{ + gp_t* ptr; + if (free_list) + { + ptr = free_list->trans; + empties = free_list; + free_list = free_list->next; + } + else + { + ptr = new gp_t(this); + } + return ptr; +} + +void mm::free(gp_t* trans) +{ + trans->reset(); // Delete auto extensions + if (!empties) + { + empties = new access; + empties->next = free_list; + empties->prev = 0; + if (free_list) + free_list->prev = empties; + } + free_list = empties; + free_list->trans = trans; + empties = free_list->prev; +} diff --git a/src/systemc/tests/tlm/nb2b_adapter/nb2b_adapter.cpp b/src/systemc/tests/tlm/nb2b_adapter/nb2b_adapter.cpp new file mode 100644 index 000000000..cde8b30bf --- /dev/null +++ b/src/systemc/tests/tlm/nb2b_adapter/nb2b_adapter.cpp @@ -0,0 +1,376 @@ + +// Unit test for nb2b adapter in simple_target_socket, PEQ, and instance-specific extensions +// Checks for bug in original version of simple_target_socket + +#include <iomanip> + +#define SC_INCLUDE_DYNAMIC_PROCESSES + +#include "systemc" +using namespace sc_core; +using namespace sc_dt; +using namespace std; + +#include "tlm.h" +#include "tlm_utils/simple_initiator_socket.h" +#include "tlm_utils/simple_target_socket.h" +#include "tlm_utils/multi_passthrough_initiator_socket.h" +#include "tlm_utils/multi_passthrough_target_socket.h" +#include "tlm_utils/peq_with_cb_and_phase.h" +#include "tlm_utils/instance_specific_extensions.h" + +#include "mm.h" + + +int rand_ps() +{ + int n = rand() % 100; + n = n * n * n; + return n / 100; +} + + +struct Initiator: sc_module +{ + tlm_utils::simple_initiator_socket<Initiator> socket; + + SC_CTOR(Initiator) + : socket("socket") + , request_in_progress(0) + , m_peq(this, &Initiator::peq_cb) + { + socket.register_nb_transport_bw(this, &Initiator::nb_transport_bw); + + SC_THREAD(thread_process); + } + + void thread_process() + { + tlm::tlm_generic_payload* trans; + tlm::tlm_phase phase; + sc_time delay; + + trans = m_mm.allocate(); + trans->acquire(); + + int adr = 0; + data[0] = adr; + + trans->set_command( tlm::TLM_WRITE_COMMAND ); + trans->set_address( adr ); + trans->set_data_ptr( reinterpret_cast<unsigned char*>(&data[0]) ); + trans->set_data_length( 4 ); + trans->set_streaming_width( 4 ); + trans->set_byte_enable_ptr( 0 ); + trans->set_dmi_allowed( false ); + trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); + + socket->b_transport( *trans, delay ); + + trans->release(); + + for (int i = 0; i < 5000; i++) + { + int adr = rand(); + tlm::tlm_command cmd = static_cast<tlm::tlm_command>(rand() % 2); + if (cmd == tlm::TLM_WRITE_COMMAND) data[i % 16] = adr; + + // Grab a new transaction from the memory manager + trans = m_mm.allocate(); + trans->acquire(); + + trans->set_command( cmd ); + trans->set_address( adr ); + trans->set_data_ptr( reinterpret_cast<unsigned char*>(&data[i % 16]) ); + trans->set_data_length( 4 ); + trans->set_streaming_width( 4 ); + trans->set_byte_enable_ptr( 0 ); + trans->set_dmi_allowed( false ); + trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); + + if (request_in_progress) + wait(end_request_event); + request_in_progress = trans; + phase = tlm::BEGIN_REQ; + + delay = sc_time(rand_ps(), SC_PS); + + tlm::tlm_sync_enum status; + status = socket->nb_transport_fw( *trans, phase, delay ); + previous_time = sc_time_stamp() + delay; + + if (status == tlm::TLM_UPDATED) + { + m_peq.notify( *trans, phase, delay ); + } + else if (status == tlm::TLM_COMPLETED) + { + request_in_progress = 0; + + check_transaction( *trans ); + + trans->release(); + } + wait( sc_time(rand_ps(), SC_PS) ); + } + } + + virtual tlm::tlm_sync_enum nb_transport_bw( tlm::tlm_generic_payload& trans, + tlm::tlm_phase& phase, sc_time& delay ) + { + if (sc_time_stamp() + delay < previous_time) + SC_REPORT_FATAL("TLM-2", "nb_transport_bw called with decreasing timing annotation"); + previous_time = sc_time_stamp() + delay; + + m_peq.notify( trans, phase, delay ); + return tlm::TLM_ACCEPTED; + } + + void peq_cb(tlm::tlm_generic_payload& trans, const tlm::tlm_phase& phase) + { + if (phase == tlm::END_REQ || (&trans == request_in_progress && phase == tlm::BEGIN_RESP)) + { + request_in_progress = 0; + end_request_event.notify(); + } + else if (phase == tlm::BEGIN_REQ || phase == tlm::END_RESP) + SC_REPORT_FATAL("TLM-2", "Illegal transaction phase received by initiator"); + + if (phase == tlm::BEGIN_RESP) + { + check_transaction( trans ); + + tlm::tlm_phase fw_phase = tlm::END_RESP; + sc_time delay = sc_time(rand_ps(), SC_PS); + socket->nb_transport_fw( trans, fw_phase, delay ); + previous_time = sc_time_stamp() + delay; + + trans.release(); + } + } + + void check_transaction(tlm::tlm_generic_payload& trans) + { + if ( trans.is_response_error() ) + { + char txt[100]; + sprintf(txt, "Transaction returned with error, response status = %s", + trans.get_response_string().c_str()); + SC_REPORT_ERROR("TLM-2", txt); + } + + tlm::tlm_command cmd = trans.get_command(); + sc_dt::uint64 adr = trans.get_address(); + int* ptr = reinterpret_cast<int*>( trans.get_data_ptr() ); + + if (cmd == tlm::TLM_READ_COMMAND) + sc_assert( *ptr == -int(adr) ); + } + + mm m_mm; + int data[16]; + tlm::tlm_generic_payload* request_in_progress; + sc_event end_request_event; + tlm_utils::peq_with_cb_and_phase<Initiator> m_peq; + sc_time previous_time; +}; + + +// Dumb interconnect that simply routes transactions through + +struct Interconnect: sc_module +{ + tlm_utils::multi_passthrough_target_socket<Interconnect, 32> targ_socket; + tlm_utils::multi_passthrough_initiator_socket<Interconnect, 32> init_socket; + + Interconnect(sc_module_name _name, unsigned int _offset) + : sc_module(_name) + , targ_socket("targ_socket") + , init_socket("init_socket") + , offset(_offset) + { + targ_socket.register_b_transport (this, &Interconnect::b_transport); + targ_socket.register_nb_transport_fw (this, &Interconnect::nb_transport_fw); + targ_socket.register_get_direct_mem_ptr (this, &Interconnect::get_direct_mem_ptr); + targ_socket.register_transport_dbg (this, &Interconnect::transport_dbg); + init_socket.register_nb_transport_bw (this, &Interconnect::nb_transport_bw); + init_socket.register_invalidate_direct_mem_ptr(this, &Interconnect::invalidate_direct_mem_ptr); + } + + void end_of_elaboration() + { + if ( targ_socket.size() != init_socket.size() ) + SC_REPORT_ERROR("TLM-2", "#initiators != #targets in Interconnect"); + } + + virtual void b_transport( int id, tlm::tlm_generic_payload& trans, sc_time& delay ) + { + unsigned int target = (id + offset) % init_socket.size(); // Route-through + + init_socket[target]->b_transport( trans, delay ); + } + + + struct route_extension: tlm_utils::instance_specific_extension<route_extension> + { + int id; + }; + + tlm_utils::instance_specific_extension_accessor accessor; + + + virtual tlm::tlm_sync_enum nb_transport_fw( int id, tlm::tlm_generic_payload& trans, + tlm::tlm_phase& phase, sc_time& delay ) + { + route_extension* ext = 0; + if (phase == tlm::BEGIN_REQ) + { + ext = new route_extension; + ext->id = id; + accessor(trans).set_extension(ext); + } + + unsigned int target = (id + offset) % init_socket.size(); // Route-through + + tlm::tlm_sync_enum status; + status = init_socket[target]->nb_transport_fw( trans, phase, delay ); + + if (status == tlm::TLM_COMPLETED) + { + accessor(trans).clear_extension(ext); + delete ext; + } + + return status; + } + + virtual bool get_direct_mem_ptr( int id, tlm::tlm_generic_payload& trans, + tlm::tlm_dmi& dmi_data) + { + unsigned int target = (id + offset) % init_socket.size(); // Route-through + + bool status = init_socket[target]->get_direct_mem_ptr( trans, dmi_data ); + + return status; + } + + virtual unsigned int transport_dbg( int id, tlm::tlm_generic_payload& trans ) + { + unsigned int target = (id + offset) % init_socket.size(); // Route-through + + return init_socket[target]->transport_dbg( trans ); + } + + + virtual tlm::tlm_sync_enum nb_transport_bw( int id, tlm::tlm_generic_payload& trans, + tlm::tlm_phase& phase, sc_time& delay ) + { + route_extension* ext = 0; + accessor(trans).get_extension(ext); + sc_assert(ext); + + tlm::tlm_sync_enum status; + status = targ_socket[ ext->id ]->nb_transport_bw( trans, phase, delay ); + + if (status == tlm::TLM_COMPLETED) + { + accessor(trans).clear_extension(ext); + delete ext; + } + + return status; + } + + virtual void invalidate_direct_mem_ptr( int id, sc_dt::uint64 start_range, + sc_dt::uint64 end_range ) + { + for (unsigned int i = 0; i < targ_socket.size(); i++) + targ_socket[i]->invalidate_direct_mem_ptr(start_range, end_range); + } + + unsigned int offset; +}; + + +struct Target: sc_module +{ + tlm_utils::simple_target_socket<Target> socket; + + SC_CTOR(Target) + : socket("socket") + { + socket.register_b_transport (this, &Target::b_transport); + } + + virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) + { + execute_transaction(trans); + } + + + void execute_transaction(tlm::tlm_generic_payload& trans) + { + tlm::tlm_command cmd = trans.get_command(); + sc_dt::uint64 adr = trans.get_address(); + unsigned char* ptr = trans.get_data_ptr(); + unsigned int len = trans.get_data_length(); + unsigned char* byt = trans.get_byte_enable_ptr(); + unsigned int wid = trans.get_streaming_width(); + + if (byt != 0) { + trans.set_response_status( tlm::TLM_BYTE_ENABLE_ERROR_RESPONSE ); + return; + } + if (len > 4 || wid < len) { + trans.set_response_status( tlm::TLM_BURST_ERROR_RESPONSE ); + return; + } + + if ( cmd == tlm::TLM_READ_COMMAND ) + { + *reinterpret_cast<int*>(ptr) = -int(adr); + } + else if ( cmd == tlm::TLM_WRITE_COMMAND ) + { + sc_assert( *reinterpret_cast<unsigned int*>(ptr) == adr ); + } + + trans.set_response_status( tlm::TLM_OK_RESPONSE ); + } + +}; + + +SC_MODULE(Top) +{ + Initiator *initiator1; + Initiator *initiator2; + Interconnect *interconnect; + Target *target1; + Target *target2; + + SC_CTOR(Top) + { + initiator1 = new Initiator ("initiator1"); + initiator2 = new Initiator ("initiator2"); + interconnect = new Interconnect("interconnect", 1); + target1 = new Target ("target1"); + target2 = new Target ("target2"); + + initiator1->socket.bind(interconnect->targ_socket); + initiator2->socket.bind(interconnect->targ_socket); + interconnect->init_socket.bind(target1->socket); + interconnect->init_socket.bind(target2->socket); + } +}; + + +int sc_main(int argc, char* argv[]) +{ + cout << "Unit test for nb2b adapter, PEQ, and instance-specific extensions. Should remain silent\n"; + + Top top("top"); + sc_start(); + return 0; +} + diff --git a/src/systemc/tests/tlm/p2p/BaseSocketLT/base_socket_LT.cpp b/src/systemc/tests/tlm/p2p/BaseSocketLT/base_socket_LT.cpp new file mode 100644 index 000000000..9f527fd53 --- /dev/null +++ b/src/systemc/tests/tlm/p2p/BaseSocketLT/base_socket_LT.cpp @@ -0,0 +1,36 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#include "tlm.h" + +#include "SimpleLTInitiator1.h" +#include "SimpleLTTarget1.h" + +int sc_main(int argc, char* argv[]) +{ + SimpleLTInitiator1 initiator("initiator"); + SimpleLTTarget1 target("target"); + + initiator.socket(target.socket); + + sc_core::sc_start(); + sc_core::sc_stop(); + + return 0; +} diff --git a/src/systemc/tests/tlm/p2p/BaseSocketLT/golden/base_socket_LT.log b/src/systemc/tests/tlm/p2p/BaseSocketLT/golden/base_socket_LT.log new file mode 100644 index 000000000..186648cba --- /dev/null +++ b/src/systemc/tests/tlm/p2p/BaseSocketLT/golden/base_socket_LT.log @@ -0,0 +1,33 @@ +SystemC Simulation +initiator: Send write request: A = 0x0, D = 0x0 @ 0 s +target: Received write request: A = 0x0, D = 0x0 @ 0 s +initiator: Received ok response @ 10 ns +initiator: Send write request: A = 0x4, D = 0x1 @ 10 ns +target: Received write request: A = 0x4, D = 0x1 @ 10 ns +initiator: Received ok response @ 20 ns +initiator: Send write request: A = 0x8, D = 0x2 @ 20 ns +target: Received write request: A = 0x8, D = 0x2 @ 20 ns +initiator: Received ok response @ 30 ns +initiator: Send write request: A = 0xc, D = 0x3 @ 30 ns +target: Received write request: A = 0xc, D = 0x3 @ 30 ns +initiator: Received ok response @ 40 ns +initiator: Send write request: A = 0x10, D = 0x4 @ 40 ns +target: Received write request: A = 0x10, D = 0x4 @ 40 ns +initiator: Received ok response @ 50 ns +initiator: Send read request: A = 0x0 @ 50 ns +target: Received read request: A = 0x0 @ 50 ns +initiator: Received ok response: D = 0x0 @ 150 ns +initiator: Send read request: A = 0x4 @ 150 ns +target: Received read request: A = 0x4 @ 150 ns +initiator: Received ok response: D = 0x1 @ 250 ns +initiator: Send read request: A = 0x8 @ 250 ns +target: Received read request: A = 0x8 @ 250 ns +initiator: Received ok response: D = 0x2 @ 350 ns +initiator: Send read request: A = 0xc @ 350 ns +target: Received read request: A = 0xc @ 350 ns +initiator: Received ok response: D = 0x3 @ 450 ns +initiator: Send read request: A = 0x10 @ 450 ns +target: Received read request: A = 0x10 @ 450 ns +initiator: Received ok response: D = 0x4 @ 550 ns + +Info: /OSCI/SystemC: Simulation stopped by user. diff --git a/src/systemc/tests/tlm/p2p/CoreDecoupling/core_decoupling.cpp b/src/systemc/tests/tlm/p2p/CoreDecoupling/core_decoupling.cpp new file mode 100644 index 000000000..aa68951f3 --- /dev/null +++ b/src/systemc/tests/tlm/p2p/CoreDecoupling/core_decoupling.cpp @@ -0,0 +1,36 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ +#define SC_INCLUDE_DYNAMIC_PROCESSES +#include "tlm.h" + +#include "CoreDecouplingLTInitiator.h" +#include "ExplicitLTTarget.h" + +int sc_main(int argc, char* argv[]) +{ + CoreDecouplingLTInitiator initiator("initiator", 10); + ExplicitLTTarget target("target"); + + initiator.socket(target.socket); + + sc_core::sc_start(); + sc_core::sc_stop(); + + return 0; +} diff --git a/src/systemc/tests/tlm/p2p/CoreDecoupling/golden/core_decoupling.log b/src/systemc/tests/tlm/p2p/CoreDecoupling/golden/core_decoupling.log new file mode 100644 index 000000000..b5a9e8314 --- /dev/null +++ b/src/systemc/tests/tlm/p2p/CoreDecoupling/golden/core_decoupling.log @@ -0,0 +1,66 @@ +SystemC Simulation +initiator: Send write request: A = 0x0, D = 0x0 @ 0 s (0 s + 0 s) +target: Received write request: A = 0x0, D = 0x0 @ 0 s +initiator: Received ok response @ 50 ns (50 ns + 0 s) +initiator: Send write request: A = 0x4, D = 0x1 @ 50 ns (50 ns + 0 s) +target: Received write request: A = 0x4, D = 0x1 @ 50 ns +initiator: Received ok response @ 100 ns (100 ns + 0 s) +initiator: Send write request: A = 0x8, D = 0x2 @ 100 ns (100 ns + 0 s) +target: Received write request: A = 0x8, D = 0x2 @ 100 ns +initiator: Received ok response @ 150 ns (150 ns + 0 s) +initiator: Send write request: A = 0xc, D = 0x3 @ 150 ns (150 ns + 0 s) +target: Received write request: A = 0xc, D = 0x3 @ 150 ns +initiator: Received ok response @ 200 ns (200 ns + 0 s) +initiator: Send write request: A = 0x10, D = 0x4 @ 200 ns (200 ns + 0 s) +target: Received write request: A = 0x10, D = 0x4 @ 200 ns +initiator: Received ok response @ 250 ns (250 ns + 0 s) +initiator: Send write request: A = 0x14, D = 0x5 @ 250 ns (250 ns + 0 s) +target: Received write request: A = 0x14, D = 0x5 @ 250 ns +initiator: Received ok response @ 300 ns (300 ns + 0 s) +initiator: Send write request: A = 0x18, D = 0x6 @ 300 ns (300 ns + 0 s) +target: Received write request: A = 0x18, D = 0x6 @ 300 ns +initiator: Received ok response @ 350 ns (350 ns + 0 s) +initiator: Send write request: A = 0x1c, D = 0x7 @ 350 ns (350 ns + 0 s) +target: Received write request: A = 0x1c, D = 0x7 @ 350 ns +initiator: Received ok response @ 400 ns (400 ns + 0 s) +initiator: Send write request: A = 0x20, D = 0x8 @ 400 ns (400 ns + 0 s) +target: Received write request: A = 0x20, D = 0x8 @ 400 ns +initiator: Received ok response @ 450 ns (450 ns + 0 s) +initiator: Send write request: A = 0x24, D = 0x9 @ 450 ns (450 ns + 0 s) +target: Received write request: A = 0x24, D = 0x9 @ 450 ns +Sync'ing... +initiator: Received ok response @ 500 ns (500 ns + 0 s) +initiator: Send read request: A = 0x0 @ 500 ns (500 ns + 0 s) +target: Received read request: A = 0x0 @ 500 ns +initiator: Received ok response: D = 0x0 @ 600 ns (500 ns + 100 ns) +initiator: Send read request: A = 0x4 @ 600 ns (500 ns + 100 ns) +target: Received read request: A = 0x4 @ 500 ns +initiator: Received ok response: D = 0x1 @ 700 ns (500 ns + 200 ns) +initiator: Send read request: A = 0x8 @ 700 ns (500 ns + 200 ns) +target: Received read request: A = 0x8 @ 500 ns +initiator: Received ok response: D = 0x2 @ 800 ns (500 ns + 300 ns) +initiator: Send read request: A = 0xc @ 800 ns (500 ns + 300 ns) +target: Received read request: A = 0xc @ 500 ns +initiator: Received ok response: D = 0x3 @ 900 ns (500 ns + 400 ns) +initiator: Send read request: A = 0x10 @ 900 ns (500 ns + 400 ns) +target: Received read request: A = 0x10 @ 500 ns +Sync'ing... +initiator: Received ok response: D = 0x4 @ 1 us (1 us + 0 s) +initiator: Send read request: A = 0x14 @ 1 us (1 us + 0 s) +target: Received read request: A = 0x14 @ 1 us +initiator: Received ok response: D = 0x5 @ 1100 ns (1 us + 100 ns) +initiator: Send read request: A = 0x18 @ 1100 ns (1 us + 100 ns) +target: Received read request: A = 0x18 @ 1 us +initiator: Received ok response: D = 0x6 @ 1200 ns (1 us + 200 ns) +initiator: Send read request: A = 0x1c @ 1200 ns (1 us + 200 ns) +target: Received read request: A = 0x1c @ 1 us +initiator: Received ok response: D = 0x7 @ 1300 ns (1 us + 300 ns) +initiator: Send read request: A = 0x20 @ 1300 ns (1 us + 300 ns) +target: Received read request: A = 0x20 @ 1 us +initiator: Received ok response: D = 0x8 @ 1400 ns (1 us + 400 ns) +initiator: Send read request: A = 0x24 @ 1400 ns (1 us + 400 ns) +target: Received read request: A = 0x24 @ 1 us +Sync'ing... +initiator: Received ok response: D = 0x9 @ 1500 ns (1500 ns + 0 s) + +Info: /OSCI/SystemC: Simulation stopped by user. diff --git a/src/systemc/tests/tlm/p2p/EndEventLT/end_event_LT.cpp b/src/systemc/tests/tlm/p2p/EndEventLT/end_event_LT.cpp new file mode 100644 index 000000000..1aca86b87 --- /dev/null +++ b/src/systemc/tests/tlm/p2p/EndEventLT/end_event_LT.cpp @@ -0,0 +1,36 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#include "tlm.h" + +#include "SimpleLTInitiator3.h" +#include "SimpleLTTarget2.h" + +int sc_main(int argc, char* argv[]) +{ + SimpleLTInitiator3 initiator("initiator"); + SimpleLTTarget2 target("target"); + + initiator.socket(target.socket); + + sc_core::sc_start(); + sc_core::sc_stop(); + + return 0; +} diff --git a/src/systemc/tests/tlm/p2p/EndEventLT/golden/end_event_LT.log b/src/systemc/tests/tlm/p2p/EndEventLT/golden/end_event_LT.log new file mode 100644 index 000000000..186648cba --- /dev/null +++ b/src/systemc/tests/tlm/p2p/EndEventLT/golden/end_event_LT.log @@ -0,0 +1,33 @@ +SystemC Simulation +initiator: Send write request: A = 0x0, D = 0x0 @ 0 s +target: Received write request: A = 0x0, D = 0x0 @ 0 s +initiator: Received ok response @ 10 ns +initiator: Send write request: A = 0x4, D = 0x1 @ 10 ns +target: Received write request: A = 0x4, D = 0x1 @ 10 ns +initiator: Received ok response @ 20 ns +initiator: Send write request: A = 0x8, D = 0x2 @ 20 ns +target: Received write request: A = 0x8, D = 0x2 @ 20 ns +initiator: Received ok response @ 30 ns +initiator: Send write request: A = 0xc, D = 0x3 @ 30 ns +target: Received write request: A = 0xc, D = 0x3 @ 30 ns +initiator: Received ok response @ 40 ns +initiator: Send write request: A = 0x10, D = 0x4 @ 40 ns +target: Received write request: A = 0x10, D = 0x4 @ 40 ns +initiator: Received ok response @ 50 ns +initiator: Send read request: A = 0x0 @ 50 ns +target: Received read request: A = 0x0 @ 50 ns +initiator: Received ok response: D = 0x0 @ 150 ns +initiator: Send read request: A = 0x4 @ 150 ns +target: Received read request: A = 0x4 @ 150 ns +initiator: Received ok response: D = 0x1 @ 250 ns +initiator: Send read request: A = 0x8 @ 250 ns +target: Received read request: A = 0x8 @ 250 ns +initiator: Received ok response: D = 0x2 @ 350 ns +initiator: Send read request: A = 0xc @ 350 ns +target: Received read request: A = 0xc @ 350 ns +initiator: Received ok response: D = 0x3 @ 450 ns +initiator: Send read request: A = 0x10 @ 450 ns +target: Received read request: A = 0x10 @ 450 ns +initiator: Received ok response: D = 0x4 @ 550 ns + +Info: /OSCI/SystemC: Simulation stopped by user. diff --git a/src/systemc/tests/tlm/p2p/HierarchicalSocket/SimpleInitiatorWrapper.h b/src/systemc/tests/tlm/p2p/HierarchicalSocket/SimpleInitiatorWrapper.h new file mode 100644 index 000000000..41b982ecd --- /dev/null +++ b/src/systemc/tests/tlm/p2p/HierarchicalSocket/SimpleInitiatorWrapper.h @@ -0,0 +1,55 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __SIMPLE_INITIATOR_WRAPPER_H__ +#define __SIMPLE_INITIATOR_WRAPPER_H__ + +#include "tlm.h" +#include "SimpleLTInitiator1.h" + +class SimpleInitiatorWrapper : public sc_core::sc_module +{ +public: + typedef tlm::tlm_generic_payload transaction_type; + typedef tlm::tlm_phase phase_type; + typedef tlm::tlm_sync_enum sync_enum_type; + typedef tlm::tlm_fw_transport_if<> fw_interface_type; + typedef tlm::tlm_bw_transport_if<> bw_interface_type; + typedef tlm::tlm_initiator_socket<> initiator_socket_type; + +public: + initiator_socket_type socket; + +public: + SimpleInitiatorWrapper(sc_core::sc_module_name name) : + sc_core::sc_module(name), + socket("socket"), + child("child") + { + child.socket(socket); + } + +protected: + SimpleLTInitiator1 child; + +}; + +#endif + + diff --git a/src/systemc/tests/tlm/p2p/HierarchicalSocket/SimpleTargetWrapper.h b/src/systemc/tests/tlm/p2p/HierarchicalSocket/SimpleTargetWrapper.h new file mode 100644 index 000000000..16212515c --- /dev/null +++ b/src/systemc/tests/tlm/p2p/HierarchicalSocket/SimpleTargetWrapper.h @@ -0,0 +1,55 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __SIMPLE_TARGET_WRAPPER_H__ +#define __SIMPLE_TARGET_WRAPPER_H__ + +#include "tlm.h" +#include "SimpleLTTarget1.h" + +class SimpleTargetWrapper : public sc_core::sc_module +{ +public: + typedef tlm::tlm_generic_payload transaction_type; + typedef tlm::tlm_phase phase_type; + typedef tlm::tlm_sync_enum sync_enum_type; + typedef tlm::tlm_fw_transport_if<> fw_interface_type; + typedef tlm::tlm_bw_transport_if<> bw_interface_type; + typedef tlm::tlm_target_socket<> target_socket_type; + +public: + target_socket_type socket; + +public: + SimpleTargetWrapper(sc_core::sc_module_name name) : + sc_core::sc_module(name), + socket("socket"), + child("child") + { + socket(child.socket); + } + +protected: + SimpleLTTarget1 child; + +}; + +#endif + + diff --git a/src/systemc/tests/tlm/p2p/HierarchicalSocket/golden/hierarchical_socket.log b/src/systemc/tests/tlm/p2p/HierarchicalSocket/golden/hierarchical_socket.log new file mode 100644 index 000000000..137330634 --- /dev/null +++ b/src/systemc/tests/tlm/p2p/HierarchicalSocket/golden/hierarchical_socket.log @@ -0,0 +1,33 @@ +SystemC Simulation +initiatorWrapper.child: Send write request: A = 0x0, D = 0x0 @ 0 s +targetWrapper.child: Received write request: A = 0x0, D = 0x0 @ 0 s +initiatorWrapper.child: Received ok response @ 10 ns +initiatorWrapper.child: Send write request: A = 0x4, D = 0x1 @ 10 ns +targetWrapper.child: Received write request: A = 0x4, D = 0x1 @ 10 ns +initiatorWrapper.child: Received ok response @ 20 ns +initiatorWrapper.child: Send write request: A = 0x8, D = 0x2 @ 20 ns +targetWrapper.child: Received write request: A = 0x8, D = 0x2 @ 20 ns +initiatorWrapper.child: Received ok response @ 30 ns +initiatorWrapper.child: Send write request: A = 0xc, D = 0x3 @ 30 ns +targetWrapper.child: Received write request: A = 0xc, D = 0x3 @ 30 ns +initiatorWrapper.child: Received ok response @ 40 ns +initiatorWrapper.child: Send write request: A = 0x10, D = 0x4 @ 40 ns +targetWrapper.child: Received write request: A = 0x10, D = 0x4 @ 40 ns +initiatorWrapper.child: Received ok response @ 50 ns +initiatorWrapper.child: Send read request: A = 0x0 @ 50 ns +targetWrapper.child: Received read request: A = 0x0 @ 50 ns +initiatorWrapper.child: Received ok response: D = 0x0 @ 150 ns +initiatorWrapper.child: Send read request: A = 0x4 @ 150 ns +targetWrapper.child: Received read request: A = 0x4 @ 150 ns +initiatorWrapper.child: Received ok response: D = 0x1 @ 250 ns +initiatorWrapper.child: Send read request: A = 0x8 @ 250 ns +targetWrapper.child: Received read request: A = 0x8 @ 250 ns +initiatorWrapper.child: Received ok response: D = 0x2 @ 350 ns +initiatorWrapper.child: Send read request: A = 0xc @ 350 ns +targetWrapper.child: Received read request: A = 0xc @ 350 ns +initiatorWrapper.child: Received ok response: D = 0x3 @ 450 ns +initiatorWrapper.child: Send read request: A = 0x10 @ 450 ns +targetWrapper.child: Received read request: A = 0x10 @ 450 ns +initiatorWrapper.child: Received ok response: D = 0x4 @ 550 ns + +Info: /OSCI/SystemC: Simulation stopped by user. diff --git a/src/systemc/tests/tlm/p2p/HierarchicalSocket/hierarchical_socket.cpp b/src/systemc/tests/tlm/p2p/HierarchicalSocket/hierarchical_socket.cpp new file mode 100644 index 000000000..be2ec433c --- /dev/null +++ b/src/systemc/tests/tlm/p2p/HierarchicalSocket/hierarchical_socket.cpp @@ -0,0 +1,40 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +//#include <iostream> + +//#include <systemc> + +#include "tlm.h" + +#include "SimpleInitiatorWrapper.h" +#include "SimpleTargetWrapper.h" + +int sc_main(int argc, char* argv[]) +{ + SimpleInitiatorWrapper initiator("initiatorWrapper"); + SimpleTargetWrapper target("targetWrapper"); + + initiator.socket(target.socket); + + sc_core::sc_start(); + sc_core::sc_stop(); + + return 0; +} diff --git a/src/systemc/tests/tlm/p2p/RegisterSocketProcessLT/golden/register_socket_process_LT.log b/src/systemc/tests/tlm/p2p/RegisterSocketProcessLT/golden/register_socket_process_LT.log new file mode 100644 index 000000000..186648cba --- /dev/null +++ b/src/systemc/tests/tlm/p2p/RegisterSocketProcessLT/golden/register_socket_process_LT.log @@ -0,0 +1,33 @@ +SystemC Simulation +initiator: Send write request: A = 0x0, D = 0x0 @ 0 s +target: Received write request: A = 0x0, D = 0x0 @ 0 s +initiator: Received ok response @ 10 ns +initiator: Send write request: A = 0x4, D = 0x1 @ 10 ns +target: Received write request: A = 0x4, D = 0x1 @ 10 ns +initiator: Received ok response @ 20 ns +initiator: Send write request: A = 0x8, D = 0x2 @ 20 ns +target: Received write request: A = 0x8, D = 0x2 @ 20 ns +initiator: Received ok response @ 30 ns +initiator: Send write request: A = 0xc, D = 0x3 @ 30 ns +target: Received write request: A = 0xc, D = 0x3 @ 30 ns +initiator: Received ok response @ 40 ns +initiator: Send write request: A = 0x10, D = 0x4 @ 40 ns +target: Received write request: A = 0x10, D = 0x4 @ 40 ns +initiator: Received ok response @ 50 ns +initiator: Send read request: A = 0x0 @ 50 ns +target: Received read request: A = 0x0 @ 50 ns +initiator: Received ok response: D = 0x0 @ 150 ns +initiator: Send read request: A = 0x4 @ 150 ns +target: Received read request: A = 0x4 @ 150 ns +initiator: Received ok response: D = 0x1 @ 250 ns +initiator: Send read request: A = 0x8 @ 250 ns +target: Received read request: A = 0x8 @ 250 ns +initiator: Received ok response: D = 0x2 @ 350 ns +initiator: Send read request: A = 0xc @ 350 ns +target: Received read request: A = 0xc @ 350 ns +initiator: Received ok response: D = 0x3 @ 450 ns +initiator: Send read request: A = 0x10 @ 450 ns +target: Received read request: A = 0x10 @ 450 ns +initiator: Received ok response: D = 0x4 @ 550 ns + +Info: /OSCI/SystemC: Simulation stopped by user. diff --git a/src/systemc/tests/tlm/p2p/RegisterSocketProcessLT/register_socket_process_LT.cpp b/src/systemc/tests/tlm/p2p/RegisterSocketProcessLT/register_socket_process_LT.cpp new file mode 100644 index 000000000..33b73faff --- /dev/null +++ b/src/systemc/tests/tlm/p2p/RegisterSocketProcessLT/register_socket_process_LT.cpp @@ -0,0 +1,35 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#include "tlm.h" + +#include "SimpleLTInitiator2.h" +#include "SimpleLTTarget2.h" +int sc_main(int argc, char* argv[]) +{ + SimpleLTInitiator2 initiator("initiator"); + SimpleLTTarget2 target("target"); + + initiator.socket(target.socket); + + sc_core::sc_start(); + sc_core::sc_stop(); + + return 0; +} diff --git a/src/systemc/tests/tlm/p2p/SimpleAT/golden/simple_AT.log b/src/systemc/tests/tlm/p2p/SimpleAT/golden/simple_AT.log new file mode 100644 index 000000000..e64d5ce44 --- /dev/null +++ b/src/systemc/tests/tlm/p2p/SimpleAT/golden/simple_AT.log @@ -0,0 +1,33 @@ +SystemC Simulation +initiator: Send write request: A = 0x0, D = 0x0 @ 0 s +target: Received write request: A = 0x0, D = 0x0 @ 0 s +initiator: Send write request: A = 0x4, D = 0x1 @ 25 ns +target: Received write request: A = 0x4, D = 0x1 @ 25 ns +initiator: Send write request: A = 0x8, D = 0x2 @ 50 ns +target: Received write request: A = 0x8, D = 0x2 @ 50 ns +initiator: Send write request: A = 0xc, D = 0x3 @ 75 ns +target: Received write request: A = 0xc, D = 0x3 @ 75 ns +initiator: Send write request: A = 0x10, D = 0x4 @ 100 ns +target: Received write request: A = 0x10, D = 0x4 @ 100 ns +initiator: Send read request: A = 0x0 @ 125 ns +target: Received read request: A = 0x0 @ 125 ns +initiator: Received ok response @ 135 ns +initiator: Send read request: A = 0x4 @ 150 ns +target: Received read request: A = 0x4 @ 150 ns +initiator: Send read request: A = 0x8 @ 175 ns +target: Received read request: A = 0x8 @ 175 ns +initiator: Send read request: A = 0xc @ 200 ns +target: Received read request: A = 0xc @ 200 ns +initiator: Send read request: A = 0x10 @ 225 ns +target: Received read request: A = 0x10 @ 225 ns +initiator: Received ok response @ 245 ns +initiator: Received ok response @ 355 ns +initiator: Received ok response @ 465 ns +initiator: Received ok response @ 575 ns +initiator: Received ok response: D = 0x0 @ 685 ns +initiator: Received ok response: D = 0x1 @ 795 ns +initiator: Received ok response: D = 0x2 @ 905 ns +initiator: Received ok response: D = 0x3 @ 1015 ns +initiator: Received ok response: D = 0x4 @ 1125 ns + +Info: /OSCI/SystemC: Simulation stopped by user. diff --git a/src/systemc/tests/tlm/p2p/SimpleAT/simple_AT.cpp b/src/systemc/tests/tlm/p2p/SimpleAT/simple_AT.cpp new file mode 100644 index 000000000..92e920369 --- /dev/null +++ b/src/systemc/tests/tlm/p2p/SimpleAT/simple_AT.cpp @@ -0,0 +1,36 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ +#define SC_INCLUDE_DYNAMIC_PROCESSES +#include "tlm.h" + +#include "SimpleATInitiator1.h" +#include "SimpleATTarget1.h" + +int sc_main(int argc, char* argv[]) +{ + SimpleATInitiator1 initiator("initiator"); + SimpleATTarget1 target("target"); + + initiator.socket(target.socket); + + sc_core::sc_start(); + sc_core::sc_stop(); + + return 0; +} diff --git a/src/systemc/tests/tlm/p2p/SimpleAT_TA/golden/simple_AT_TA.log b/src/systemc/tests/tlm/p2p/SimpleAT_TA/golden/simple_AT_TA.log new file mode 100644 index 000000000..4970861d2 --- /dev/null +++ b/src/systemc/tests/tlm/p2p/SimpleAT_TA/golden/simple_AT_TA.log @@ -0,0 +1,33 @@ +SystemC Simulation +initiator: Send write request: A = 0x0, D = 0x0 @ 0 s +target: Received write request: A = 0x0, D = 0x0 @ 0 s +initiator: Send write request: A = 0x4, D = 0x1 @ 25 ns +target: Received write request: A = 0x4, D = 0x1 @ 25 ns +initiator: Send write request: A = 0x8, D = 0x2 @ 50 ns +target: Received write request: A = 0x8, D = 0x2 @ 50 ns +initiator: Send write request: A = 0xc, D = 0x3 @ 75 ns +target: Received write request: A = 0xc, D = 0x3 @ 75 ns +initiator: Send write request: A = 0x10, D = 0x4 @ 100 ns +target: Received write request: A = 0x10, D = 0x4 @ 100 ns +initiator: Received ok response @ 125 ns +initiator: Send read request: A = 0x0 @ 125 ns +target: Received read request: A = 0x0 @ 125 ns +initiator: Send read request: A = 0x4 @ 150 ns +target: Received read request: A = 0x4 @ 150 ns +initiator: Send read request: A = 0x8 @ 175 ns +target: Received read request: A = 0x8 @ 175 ns +initiator: Send read request: A = 0xc @ 200 ns +target: Received read request: A = 0xc @ 200 ns +initiator: Send read request: A = 0x10 @ 225 ns +target: Received read request: A = 0x10 @ 225 ns +initiator: Received ok response @ 235 ns +initiator: Received ok response @ 345 ns +initiator: Received ok response @ 455 ns +initiator: Received ok response @ 565 ns +initiator: Received ok response: D = 0x0 @ 675 ns +initiator: Received ok response: D = 0x1 @ 785 ns +initiator: Received ok response: D = 0x2 @ 895 ns +initiator: Received ok response: D = 0x3 @ 1005 ns +initiator: Received ok response: D = 0x4 @ 1115 ns + +Info: /OSCI/SystemC: Simulation stopped by user. diff --git a/src/systemc/tests/tlm/p2p/SimpleAT_TA/simple_AT_TA.cpp b/src/systemc/tests/tlm/p2p/SimpleAT_TA/simple_AT_TA.cpp new file mode 100644 index 000000000..909ca9390 --- /dev/null +++ b/src/systemc/tests/tlm/p2p/SimpleAT_TA/simple_AT_TA.cpp @@ -0,0 +1,36 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ +#define SC_INCLUDE_DYNAMIC_PROCESSES +#include "tlm.h" + +#include "SimpleATInitiator2.h" +#include "SimpleATTarget2.h" + +int sc_main(int argc, char* argv[]) +{ + SimpleATInitiator2 initiator("initiator"); + SimpleATTarget2 target("target"); + + initiator.socket(target.socket); + + sc_core::sc_start(); + sc_core::sc_stop(); + + return 0; +} diff --git a/src/systemc/tests/tlm/static_extensions/ext2gp/SimpleLTInitiator_ext.h b/src/systemc/tests/tlm/static_extensions/ext2gp/SimpleLTInitiator_ext.h new file mode 100644 index 000000000..1d10e0785 --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/ext2gp/SimpleLTInitiator_ext.h @@ -0,0 +1,343 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __SIMPLE_LT_INITIATOR_EXT_H__ +#define __SIMPLE_LT_INITIATOR_EXT_H__ + +#include "tlm.h" +#include "tlm_utils/simple_initiator_socket.h" +#include "my_extension.h" + +#include <systemc> +#include <cassert> +#include <iostream> +#include <iomanip> +#include <map> + +class SimpleLTInitiator_ext : public sc_core::sc_module +{ +public: + typedef tlm::tlm_generic_payload transaction_type; + typedef tlm::tlm_dmi dmi_type; + typedef tlm::tlm_phase phase_type; + typedef tlm::tlm_sync_enum sync_enum_type; + typedef tlm_utils::simple_initiator_socket<SimpleLTInitiator_ext, 32, + my_extended_payload_types> initiator_socket_type; + +public: + initiator_socket_type socket; + +public: + SC_HAS_PROCESS(SimpleLTInitiator_ext); + SimpleLTInitiator_ext(sc_core::sc_module_name name, + unsigned int nrOfTransactions = 0x5, + unsigned int baseAddress = 0x0) : + sc_core::sc_module(name), + socket("socket"), + mNrOfTransactions(nrOfTransactions), + mBaseAddress(baseAddress), + mTransactionCount(0) + { + invalidate(mDMIData); + + // register nb_transport method + socket.register_nb_transport_bw(this, &SimpleLTInitiator_ext::myNBTransport); + socket.register_invalidate_direct_mem_ptr(this, &SimpleLTInitiator_ext::invalidate_direct_mem_ptr); + + // Initiator thread + SC_THREAD(run); + + } + + bool initTransaction(transaction_type& trans) + { + // initialize DMI hint: + trans.set_dmi_allowed(false); + + if (mTransactionCount < mNrOfTransactions) + { + trans.set_address(mBaseAddress + 4*mTransactionCount); + mData = mTransactionCount; + trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData)); + trans.set_command(tlm::TLM_WRITE_COMMAND); + + } + else if (mTransactionCount < 2 * mNrOfTransactions) + { + trans.set_address(mBaseAddress + 4*(mTransactionCount-mNrOfTransactions)); + mData = 0; + trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData)); + trans.set_command(tlm::TLM_READ_COMMAND); + + } + else + { + return false; + } + + ++mTransactionCount; + return true; + } + + void logStartTransation(transaction_type& trans) + { + if (trans.get_command() == tlm::TLM_WRITE_COMMAND) + { + std::cout << name() << ": Send write request: A = 0x" + << std::hex << (unsigned int)trans.get_address() + << ", D = 0x" << mData << std::dec + << " @ " << sc_core::sc_time_stamp() << std::endl; + + } + else + { + std::cout << name() << ": Send read request: A = 0x" + << std::hex << (unsigned int)trans.get_address() + << std::dec + << " @ " << sc_core::sc_time_stamp() << std::endl; + } + } + + void logEndTransaction(transaction_type& trans) + { + if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) { + std::cout << name() << ": Received error response @ " + << sc_core::sc_time_stamp() << std::endl; + } + else + { + std::cout << name() << ": Received ok response"; + if (trans.get_command() == tlm::TLM_READ_COMMAND) { + std::cout << ": D = 0x" << std::hex << mData << std::dec; + } + std::cout << " @ " << sc_core::sc_time_stamp() << std::endl; + } + } + + void run() + { + transaction_type trans; + phase_type phase; + sc_core::sc_time t; + // make sure that our transaction has the proper extension: + my_extension* tmp_ext = new my_extension(); + tmp_ext->m_data = 11; + + trans.set_extension(tmp_ext); + + while (initTransaction(trans)) + { + // Create transaction and initialise phase and t + phase = tlm::BEGIN_REQ; + t = sc_core::SC_ZERO_TIME; + + logStartTransation(trans); + /////////////////////////////////////////////////////////// + // DMI handling: + // We use the DMI hint to check if it makes sense to ask for + // DMI pointers. The pattern is: + // - if the address is covered by a DMI region do a DMI access + // - otherwise do a normal transaction + // -> check if we get a DMI hint and acquire the DMI pointers if it + // is set + /////////////////////////////////////////////////////////// + + // Check if the address is covered by our DMI region + if ( (trans.get_address() >= mDMIData.get_start_address()) && + (trans.get_address() <= mDMIData.get_end_address()) ) + { + // We can handle the data here. As the logEndTransaction is + // assuming something to happen in the data structure, we really + // need to do this: + trans.set_response_status(tlm::TLM_OK_RESPONSE); + sc_dt::uint64 tmp = trans.get_address() - mDMIData.get_start_address(); + if (trans.get_command() == tlm::TLM_WRITE_COMMAND) { + *(unsigned int*)&mDMIData.get_dmi_ptr()[tmp] = mData; + + } else { + mData = *(unsigned int*)&mDMIData.get_dmi_ptr()[tmp]; + } + + // Do the wait immediately. Note that doing the wait here eats + // almost all the performance anyway, so we only gain something + // if we're using temporal decoupling. + if (trans.get_command() == tlm::TLM_WRITE_COMMAND) { + wait(mDMIData.get_write_latency()); + + } else { + wait(mDMIData.get_read_latency()); + } + + logEndTransaction(trans); + + } else { // we need a full transaction + switch (socket->nb_transport_fw(trans, phase, t)) { + case tlm::TLM_COMPLETED: + // Transaction Finished, wait for the returned delay + wait(t); + break; + + case tlm::TLM_ACCEPTED: + case tlm::TLM_UPDATED: + // Transaction not yet finished, wait for the end of it + wait(mEndEvent); + break; + + default: + sc_assert(0); exit(1); + }; + + logEndTransaction(trans); + + // Acquire DMI pointer if one is available: + if (trans.is_dmi_allowed()) + { + trans.set_write(); + dmi_type tmp; + if (socket->get_direct_mem_ptr(trans, + tmp)) + { + // FIXME: No support for separate read/write ranges + sc_assert(tmp.is_read_write_allowed()); + mDMIData = tmp; + } + } + } + } + delete tmp_ext; + wait(); + + } + + sync_enum_type myNBTransport(transaction_type& trans, + phase_type& phase, + sc_core::sc_time& t) + { + switch (phase) { + case tlm::END_REQ: + // Request phase ended + return tlm::TLM_ACCEPTED; + + case tlm::BEGIN_RESP: + sc_assert(t == sc_core::SC_ZERO_TIME); // FIXME: can t != 0? + mEndEvent.notify(t); + // Not needed to update the phase if true is returned + return tlm::TLM_COMPLETED; + + case tlm::BEGIN_REQ: // fall-through + case tlm::END_RESP: // fall-through + default: + // A target should never call nb_transport with these phases + sc_assert(0); exit(1); +// return tlm::TLM_COMPLETED; //unreachable code + }; + } + + void invalidate(dmi_type& dmiData) + { + dmiData.set_start_address(1); + dmiData.set_end_address(0); + } + + // Invalidate DMI pointer(s) + void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, + sc_dt::uint64 end_range) + { + // do the invalidation if there is an address range overlap + if (start_range <= mDMIData.get_end_address ()&& + end_range >= mDMIData.get_start_address()) { + std::cout << name() << ": got DMI pointer invalidation" + << " @ " << sc_core::sc_time_stamp() << std::endl; + + invalidate(mDMIData); + } else { + std::cout << name() << ": ignored DMI invalidation for addresses " + << std::hex << start_range << ", " + << end_range << std::dec + << " @ " << sc_core::sc_time_stamp() << std::endl; + } + } + + // Test for transport_dbg, this one should fail in bus_dmi as we address + // a target that doesn't support transport_dbg: + // FIXME: use a configurable address + void end_of_simulation() + { + std::cout << name() << ", <<SimpleLTInitiator1>>:" << std::endl + << std::endl; + unsigned char data[32]; + + transaction_type trans; + trans.set_address(mBaseAddress); + trans.set_data_length(32); + trans.set_data_ptr(data); + trans.set_read(); + + unsigned int n = socket->transport_dbg(trans); + + std::cout << "Mem @" << std::hex << mBaseAddress << std::endl; + unsigned int j = 0; + + if (n > 0) + { + // always align endianness, so that we don't get a diff when + // printing the raw data + int e_start = 0; + int e_end = 4; + int e_increment = 1; + if (!tlm::host_has_little_endianness()) + { + e_start = 3; + e_end = -1; + e_increment = -1; + } + + for (unsigned int i=0; i<n; i+=4) + { + for (int k=e_start; k!=e_end; k+=e_increment) + { + std::cout << std::setw(2) << std::setfill('0') + << (int)data[i+k]; + j++; + if (j==16) { + j=0; + std::cout << std::endl; + } else { + std::cout << " "; + } + } + } + } + else + { + std::cout << "OK: debug transaction didn't give data." << std::endl; + } + std::cout << std::dec << std::endl; + } +private: + dmi_type mDMIData; + + sc_core::sc_event mEndEvent; + unsigned int mNrOfTransactions; + unsigned int mBaseAddress; + unsigned int mTransactionCount; + unsigned int mData; +}; + +#endif diff --git a/src/systemc/tests/tlm/static_extensions/ext2gp/ext2gp.cpp b/src/systemc/tests/tlm/static_extensions/ext2gp/ext2gp.cpp new file mode 100644 index 000000000..eb6bdbf22 --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/ext2gp/ext2gp.cpp @@ -0,0 +1,40 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ +#define SC_INCLUDE_DYNAMIC_PROCESSES +#include "tlm.h" + +#include "SimpleLTInitiator_ext.h" +#include "SimpleLTTarget1.h" +#include "extension_adaptors.h" + + +int sc_main(int argc, char* argv[]) +{ + SimpleLTInitiator_ext initiator("initiator", 10, 0x0); + adapt_ext2gp<32> bridge("bridge"); + SimpleLTTarget1 target("target", true); + + initiator.socket(bridge.target_socket); + bridge.initiator_socket(target.socket); + + sc_core::sc_start(); + sc_core::sc_stop(); + + return 0; +} diff --git a/src/systemc/tests/tlm/static_extensions/ext2gp/extension_adaptors.h b/src/systemc/tests/tlm/static_extensions/ext2gp/extension_adaptors.h new file mode 100644 index 000000000..a6b470e2a --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/ext2gp/extension_adaptors.h @@ -0,0 +1,212 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __EXTENSIONS_ADAPTORS_H__ +#define __EXTENSIONS_ADAPTORS_H__ + +#include "tlm.h" +#include "my_extension.h" + +#include "tlm_utils/simple_initiator_socket.h" +#include "tlm_utils/simple_target_socket.h" + +template <unsigned int BUSWIDTH = 32> +class adapt_ext2gp : public sc_core::sc_module +{ + public: + typedef tlm::tlm_generic_payload initiator_payload_type; + typedef tlm::tlm_generic_payload target_payload_type; + typedef tlm_utils::simple_initiator_socket<adapt_ext2gp, BUSWIDTH, + tlm::tlm_base_protocol_types> initiator_socket_type; + typedef tlm_utils::simple_target_socket<adapt_ext2gp, BUSWIDTH, + my_extended_payload_types> target_socket_type; + + target_socket_type target_socket; + initiator_socket_type initiator_socket; + + SC_HAS_PROCESS(adapt_ext2gp); + adapt_ext2gp(sc_core::sc_module_name name_) + : sc_core::sc_module(name_) + { + target_socket.register_nb_transport_fw(this, &adapt_ext2gp::forward_nb_transport); + target_socket.register_transport_dbg(this, &adapt_ext2gp::transport_debug); + target_socket.register_get_direct_mem_ptr(this, &adapt_ext2gp::get_dmi_pointer); + + initiator_socket.register_nb_transport_bw(this, &adapt_ext2gp::backward_nb_transport); + initiator_socket.register_invalidate_direct_mem_ptr(this, &adapt_ext2gp::invalidate_dmi_pointers); + } + + /////////////// + // NB transport + /////////////// + + // Forward direction: The initiator calls this method with an extended + // payload. We leave the extension class in the vector, and it will be + // ignored by the GP target. + tlm::tlm_sync_enum forward_nb_transport(initiator_payload_type& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& t) + { + return initiator_socket->nb_transport_fw(trans, phase, t); + } + // Backward direction: we can assume here that the payload we get + // as parameter is the same one that the initiator sent out. Thus, the + // extension vector is known to be present. + tlm::tlm_sync_enum backward_nb_transport(target_payload_type& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& t) + { + return target_socket->nb_transport_bw(trans, phase, t); + } + + bool get_dmi_pointer(target_payload_type& trans, + tlm::tlm_dmi& dmi_data) + { + bool tmp_ret = initiator_socket->get_direct_mem_ptr(trans, + dmi_data); + return tmp_ret; + } + + ////////////////////////// + // simple call forwarders: + ////////////////////////// + unsigned int transport_debug(target_payload_type& trans) + { + return initiator_socket->transport_dbg(trans); + } + void invalidate_dmi_pointers(sc_dt::uint64 start_range, + sc_dt::uint64 end_range) + { + target_socket->invalidate_direct_mem_ptr(start_range, + end_range); + } +}; + +template <unsigned int BUSWIDTH = 32> +class adapt_gp2ext : public sc_core::sc_module +{ + public: + typedef tlm::tlm_generic_payload initiator_payload_type; + typedef tlm::tlm_generic_payload target_payload_type; + typedef tlm_utils::simple_initiator_socket<adapt_gp2ext, BUSWIDTH, + my_extended_payload_types> initiator_socket_type; + typedef tlm_utils::simple_target_socket<adapt_gp2ext, BUSWIDTH, + tlm::tlm_base_protocol_types> target_socket_type; + + target_socket_type target_socket; + initiator_socket_type initiator_socket; + + SC_HAS_PROCESS(adapt_gp2ext); + adapt_gp2ext(sc_core::sc_module_name name_) + : sc_core::sc_module(name_) + { + // Optionally, we can initialize our private extension class + // here, if required. + + target_socket.register_nb_transport_fw(this, &adapt_gp2ext::forward_nb_transport); + target_socket.register_transport_dbg(this, &adapt_gp2ext::transport_debug); + target_socket.register_get_direct_mem_ptr(this, &adapt_gp2ext::get_dmi_pointer); + + initiator_socket.register_nb_transport_bw(this, &adapt_gp2ext::backward_nb_transport); + initiator_socket.register_invalidate_direct_mem_ptr(this, &adapt_gp2ext::invalidate_dmi_pointers); + + m_ext.m_data = 13; + } + + /////////////// + // NB transport + /////////////// + + // Forward direction: We extend the payload on the fly (if needed). + tlm::tlm_sync_enum forward_nb_transport(initiator_payload_type& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& t) + { + // If the mandatory extension is not there, we need to add it and + // store it so that we can re-construc the original state. + // Otherwise we don't touch the extension, so that we don't overwrite + // it in e.g. a nonGP->GP->nonGP (initiator->interconnect->target) + // setup. + // Note, however, that there might be situations where we might need to + // re-initialize the extension, e.g. for mutable data fields in + // different system setups. + trans.get_extension(m_initiator_ext); + if (!m_initiator_ext) + { + m_initiator_ext = trans.set_extension(&m_ext); + } + tlm::tlm_sync_enum tmp = + initiator_socket->nb_transport_fw(trans, phase, t); + if (tmp == tlm::TLM_COMPLETED) + { + m_initiator_ext = trans.set_extension(m_initiator_ext); + } + return tmp; + } + // Backward direction: only restore of original extension and static_cast. + tlm::tlm_sync_enum backward_nb_transport(target_payload_type& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& t) + { + m_initiator_ext = trans.set_extension(m_initiator_ext); + return target_socket->nb_transport_bw(trans, phase, t); + } + + bool get_dmi_pointer(target_payload_type& trans, + tlm::tlm_dmi& dmi_data) + { + // If the mandatory extension is not there, we need to add it and + // store it so that we can re-construc the original state. + // Otherwise we don't touch the extension, so that we don't overwrite + // it in e.g. a nonGP->GP->nonGP (initiator->interconnect->target) + // setup. + my_extension* tmp_ext; + trans.get_extension(tmp_ext); + if (!tmp_ext) + { + trans.set_extension(&m_ext); + } + bool tmp_ret = initiator_socket->get_direct_mem_ptr(trans, + dmi_data); + if(!tmp_ext) + { + trans.clear_extension(tmp_ext); + } + return tmp_ret; + } + ////////////////////////// + // simple call forwarders: + ////////////////////////// + unsigned int transport_debug(target_payload_type& trans) + { + return initiator_socket->transport_dbg(trans); + } + void invalidate_dmi_pointers(sc_dt::uint64 start_range, + sc_dt::uint64 end_range) + { + target_socket->invalidate_direct_mem_ptr(start_range, + end_range); + } + +private: + my_extension m_ext; + my_extension* m_initiator_ext; +}; + +#endif diff --git a/src/systemc/tests/tlm/static_extensions/ext2gp/golden/ext2gp.log b/src/systemc/tests/tlm/static_extensions/ext2gp/golden/ext2gp.log new file mode 100644 index 000000000..bffb34320 --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/ext2gp/golden/ext2gp.log @@ -0,0 +1,65 @@ +SystemC Simulation +initiator: Send write request: A = 0x0, D = 0x0 @ 0 s +target: Received write request: A = 0x0, D = 0x0 @ 0 s +initiator: Received ok response @ 10 ns +initiator: Send write request: A = 0x4, D = 0x1 @ 10 ns +initiator: Received ok response @ 20 ns +initiator: Send write request: A = 0x8, D = 0x2 @ 20 ns +initiator: Received ok response @ 30 ns +initiator: Send write request: A = 0xc, D = 0x3 @ 30 ns +initiator: got DMI pointer invalidation @ 35 ns +initiator: Received ok response @ 40 ns +initiator: Send write request: A = 0x10, D = 0x4 @ 40 ns +target: Received write request: A = 0x10, D = 0x4 @ 40 ns +initiator: Received ok response @ 50 ns +initiator: Send write request: A = 0x14, D = 0x5 @ 50 ns +initiator: Received ok response @ 60 ns +initiator: Send write request: A = 0x18, D = 0x6 @ 60 ns +initiator: Received ok response @ 70 ns +initiator: Send write request: A = 0x1c, D = 0x7 @ 70 ns +initiator: got DMI pointer invalidation @ 75 ns +initiator: Received ok response @ 80 ns +initiator: Send write request: A = 0x20, D = 0x8 @ 80 ns +target: Received write request: A = 0x20, D = 0x8 @ 80 ns +initiator: Received ok response @ 90 ns +initiator: Send write request: A = 0x24, D = 0x9 @ 90 ns +initiator: Received ok response @ 100 ns +initiator: Send read request: A = 0x0 @ 100 ns +initiator: got DMI pointer invalidation @ 115 ns +initiator: Received ok response: D = 0x0 @ 200 ns +initiator: Send read request: A = 0x4 @ 200 ns +target: Received read request: A = 0x4 @ 200 ns +initiator: Received ok response: D = 0x1 @ 300 ns +initiator: Send read request: A = 0x8 @ 300 ns +initiator: got DMI pointer invalidation @ 325 ns +initiator: Received ok response: D = 0x2 @ 400 ns +initiator: Send read request: A = 0xc @ 400 ns +target: Received read request: A = 0xc @ 400 ns +initiator: Received ok response: D = 0x3 @ 500 ns +initiator: Send read request: A = 0x10 @ 500 ns +initiator: got DMI pointer invalidation @ 525 ns +initiator: Received ok response: D = 0x4 @ 600 ns +initiator: Send read request: A = 0x14 @ 600 ns +target: Received read request: A = 0x14 @ 600 ns +initiator: Received ok response: D = 0x5 @ 700 ns +initiator: Send read request: A = 0x18 @ 700 ns +initiator: got DMI pointer invalidation @ 725 ns +initiator: Received ok response: D = 0x6 @ 800 ns +initiator: Send read request: A = 0x1c @ 800 ns +target: Received read request: A = 0x1c @ 800 ns +initiator: Received ok response: D = 0x7 @ 900 ns +initiator: Send read request: A = 0x20 @ 900 ns +initiator: got DMI pointer invalidation @ 925 ns +initiator: Received ok response: D = 0x8 @ 1 us +initiator: Send read request: A = 0x24 @ 1 us +target: Received read request: A = 0x24 @ 1 us +initiator: Received ok response: D = 0x9 @ 1100 ns +initiator: got DMI pointer invalidation @ 1125 ns + +Info: /OSCI/SystemC: Simulation stopped by user. +initiator, <<SimpleLTInitiator1>>: + +Mem @0 +00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 +04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 + diff --git a/src/systemc/tests/tlm/static_extensions/ext2gp/my_extension.h b/src/systemc/tests/tlm/static_extensions/ext2gp/my_extension.h new file mode 100644 index 000000000..650931cd1 --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/ext2gp/my_extension.h @@ -0,0 +1,56 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __MY_EXTENSION_H__ +#define __MY_EXTENSION_H__ + +#include "tlm.h" +#include <cassert> + +class my_extension : + public tlm::tlm_extension<my_extension> +{ +public: + my_extension() + : m_data(0) + {} + tlm_extension_base* clone() const + { + return new my_extension(*this); + } + void free() + { + delete this; + } + void copy_from(tlm_extension_base const & e) + { + sc_assert(typeid(this) == typeid(e)); + m_data = static_cast<my_extension const &>(e).m_data; + } + + int m_data; +}; + +struct my_extended_payload_types +{ + typedef tlm::tlm_base_protocol_types::tlm_payload_type tlm_payload_type; + typedef tlm::tlm_base_protocol_types::tlm_phase_type tlm_phase_type; +}; + +#endif diff --git a/src/systemc/tests/tlm/static_extensions/ext2gp2ext/SimpleLTInitiator_ext.h b/src/systemc/tests/tlm/static_extensions/ext2gp2ext/SimpleLTInitiator_ext.h new file mode 100644 index 000000000..1d10e0785 --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/ext2gp2ext/SimpleLTInitiator_ext.h @@ -0,0 +1,343 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __SIMPLE_LT_INITIATOR_EXT_H__ +#define __SIMPLE_LT_INITIATOR_EXT_H__ + +#include "tlm.h" +#include "tlm_utils/simple_initiator_socket.h" +#include "my_extension.h" + +#include <systemc> +#include <cassert> +#include <iostream> +#include <iomanip> +#include <map> + +class SimpleLTInitiator_ext : public sc_core::sc_module +{ +public: + typedef tlm::tlm_generic_payload transaction_type; + typedef tlm::tlm_dmi dmi_type; + typedef tlm::tlm_phase phase_type; + typedef tlm::tlm_sync_enum sync_enum_type; + typedef tlm_utils::simple_initiator_socket<SimpleLTInitiator_ext, 32, + my_extended_payload_types> initiator_socket_type; + +public: + initiator_socket_type socket; + +public: + SC_HAS_PROCESS(SimpleLTInitiator_ext); + SimpleLTInitiator_ext(sc_core::sc_module_name name, + unsigned int nrOfTransactions = 0x5, + unsigned int baseAddress = 0x0) : + sc_core::sc_module(name), + socket("socket"), + mNrOfTransactions(nrOfTransactions), + mBaseAddress(baseAddress), + mTransactionCount(0) + { + invalidate(mDMIData); + + // register nb_transport method + socket.register_nb_transport_bw(this, &SimpleLTInitiator_ext::myNBTransport); + socket.register_invalidate_direct_mem_ptr(this, &SimpleLTInitiator_ext::invalidate_direct_mem_ptr); + + // Initiator thread + SC_THREAD(run); + + } + + bool initTransaction(transaction_type& trans) + { + // initialize DMI hint: + trans.set_dmi_allowed(false); + + if (mTransactionCount < mNrOfTransactions) + { + trans.set_address(mBaseAddress + 4*mTransactionCount); + mData = mTransactionCount; + trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData)); + trans.set_command(tlm::TLM_WRITE_COMMAND); + + } + else if (mTransactionCount < 2 * mNrOfTransactions) + { + trans.set_address(mBaseAddress + 4*(mTransactionCount-mNrOfTransactions)); + mData = 0; + trans.set_data_ptr(reinterpret_cast<unsigned char*>(&mData)); + trans.set_command(tlm::TLM_READ_COMMAND); + + } + else + { + return false; + } + + ++mTransactionCount; + return true; + } + + void logStartTransation(transaction_type& trans) + { + if (trans.get_command() == tlm::TLM_WRITE_COMMAND) + { + std::cout << name() << ": Send write request: A = 0x" + << std::hex << (unsigned int)trans.get_address() + << ", D = 0x" << mData << std::dec + << " @ " << sc_core::sc_time_stamp() << std::endl; + + } + else + { + std::cout << name() << ": Send read request: A = 0x" + << std::hex << (unsigned int)trans.get_address() + << std::dec + << " @ " << sc_core::sc_time_stamp() << std::endl; + } + } + + void logEndTransaction(transaction_type& trans) + { + if (trans.get_response_status() != tlm::TLM_OK_RESPONSE) { + std::cout << name() << ": Received error response @ " + << sc_core::sc_time_stamp() << std::endl; + } + else + { + std::cout << name() << ": Received ok response"; + if (trans.get_command() == tlm::TLM_READ_COMMAND) { + std::cout << ": D = 0x" << std::hex << mData << std::dec; + } + std::cout << " @ " << sc_core::sc_time_stamp() << std::endl; + } + } + + void run() + { + transaction_type trans; + phase_type phase; + sc_core::sc_time t; + // make sure that our transaction has the proper extension: + my_extension* tmp_ext = new my_extension(); + tmp_ext->m_data = 11; + + trans.set_extension(tmp_ext); + + while (initTransaction(trans)) + { + // Create transaction and initialise phase and t + phase = tlm::BEGIN_REQ; + t = sc_core::SC_ZERO_TIME; + + logStartTransation(trans); + /////////////////////////////////////////////////////////// + // DMI handling: + // We use the DMI hint to check if it makes sense to ask for + // DMI pointers. The pattern is: + // - if the address is covered by a DMI region do a DMI access + // - otherwise do a normal transaction + // -> check if we get a DMI hint and acquire the DMI pointers if it + // is set + /////////////////////////////////////////////////////////// + + // Check if the address is covered by our DMI region + if ( (trans.get_address() >= mDMIData.get_start_address()) && + (trans.get_address() <= mDMIData.get_end_address()) ) + { + // We can handle the data here. As the logEndTransaction is + // assuming something to happen in the data structure, we really + // need to do this: + trans.set_response_status(tlm::TLM_OK_RESPONSE); + sc_dt::uint64 tmp = trans.get_address() - mDMIData.get_start_address(); + if (trans.get_command() == tlm::TLM_WRITE_COMMAND) { + *(unsigned int*)&mDMIData.get_dmi_ptr()[tmp] = mData; + + } else { + mData = *(unsigned int*)&mDMIData.get_dmi_ptr()[tmp]; + } + + // Do the wait immediately. Note that doing the wait here eats + // almost all the performance anyway, so we only gain something + // if we're using temporal decoupling. + if (trans.get_command() == tlm::TLM_WRITE_COMMAND) { + wait(mDMIData.get_write_latency()); + + } else { + wait(mDMIData.get_read_latency()); + } + + logEndTransaction(trans); + + } else { // we need a full transaction + switch (socket->nb_transport_fw(trans, phase, t)) { + case tlm::TLM_COMPLETED: + // Transaction Finished, wait for the returned delay + wait(t); + break; + + case tlm::TLM_ACCEPTED: + case tlm::TLM_UPDATED: + // Transaction not yet finished, wait for the end of it + wait(mEndEvent); + break; + + default: + sc_assert(0); exit(1); + }; + + logEndTransaction(trans); + + // Acquire DMI pointer if one is available: + if (trans.is_dmi_allowed()) + { + trans.set_write(); + dmi_type tmp; + if (socket->get_direct_mem_ptr(trans, + tmp)) + { + // FIXME: No support for separate read/write ranges + sc_assert(tmp.is_read_write_allowed()); + mDMIData = tmp; + } + } + } + } + delete tmp_ext; + wait(); + + } + + sync_enum_type myNBTransport(transaction_type& trans, + phase_type& phase, + sc_core::sc_time& t) + { + switch (phase) { + case tlm::END_REQ: + // Request phase ended + return tlm::TLM_ACCEPTED; + + case tlm::BEGIN_RESP: + sc_assert(t == sc_core::SC_ZERO_TIME); // FIXME: can t != 0? + mEndEvent.notify(t); + // Not needed to update the phase if true is returned + return tlm::TLM_COMPLETED; + + case tlm::BEGIN_REQ: // fall-through + case tlm::END_RESP: // fall-through + default: + // A target should never call nb_transport with these phases + sc_assert(0); exit(1); +// return tlm::TLM_COMPLETED; //unreachable code + }; + } + + void invalidate(dmi_type& dmiData) + { + dmiData.set_start_address(1); + dmiData.set_end_address(0); + } + + // Invalidate DMI pointer(s) + void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, + sc_dt::uint64 end_range) + { + // do the invalidation if there is an address range overlap + if (start_range <= mDMIData.get_end_address ()&& + end_range >= mDMIData.get_start_address()) { + std::cout << name() << ": got DMI pointer invalidation" + << " @ " << sc_core::sc_time_stamp() << std::endl; + + invalidate(mDMIData); + } else { + std::cout << name() << ": ignored DMI invalidation for addresses " + << std::hex << start_range << ", " + << end_range << std::dec + << " @ " << sc_core::sc_time_stamp() << std::endl; + } + } + + // Test for transport_dbg, this one should fail in bus_dmi as we address + // a target that doesn't support transport_dbg: + // FIXME: use a configurable address + void end_of_simulation() + { + std::cout << name() << ", <<SimpleLTInitiator1>>:" << std::endl + << std::endl; + unsigned char data[32]; + + transaction_type trans; + trans.set_address(mBaseAddress); + trans.set_data_length(32); + trans.set_data_ptr(data); + trans.set_read(); + + unsigned int n = socket->transport_dbg(trans); + + std::cout << "Mem @" << std::hex << mBaseAddress << std::endl; + unsigned int j = 0; + + if (n > 0) + { + // always align endianness, so that we don't get a diff when + // printing the raw data + int e_start = 0; + int e_end = 4; + int e_increment = 1; + if (!tlm::host_has_little_endianness()) + { + e_start = 3; + e_end = -1; + e_increment = -1; + } + + for (unsigned int i=0; i<n; i+=4) + { + for (int k=e_start; k!=e_end; k+=e_increment) + { + std::cout << std::setw(2) << std::setfill('0') + << (int)data[i+k]; + j++; + if (j==16) { + j=0; + std::cout << std::endl; + } else { + std::cout << " "; + } + } + } + } + else + { + std::cout << "OK: debug transaction didn't give data." << std::endl; + } + std::cout << std::dec << std::endl; + } +private: + dmi_type mDMIData; + + sc_core::sc_event mEndEvent; + unsigned int mNrOfTransactions; + unsigned int mBaseAddress; + unsigned int mTransactionCount; + unsigned int mData; +}; + +#endif diff --git a/src/systemc/tests/tlm/static_extensions/ext2gp2ext/SimpleLTTarget_ext.h b/src/systemc/tests/tlm/static_extensions/ext2gp2ext/SimpleLTTarget_ext.h new file mode 100644 index 000000000..c542c196d --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/ext2gp2ext/SimpleLTTarget_ext.h @@ -0,0 +1,186 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __SIMPLE_LT_TARGET2_H__ +#define __SIMPLE_LT_TARGET2_H__ + +#include "tlm.h" +#include "tlm_utils/simple_target_socket.h" +#include "my_extension.h" + +//#include <systemc> +#include <cassert> +#include <vector> +//#include <iostream> + +class SimpleLTTarget_ext : public sc_core::sc_module +{ +public: + typedef tlm::tlm_generic_payload transaction_type; + typedef tlm::tlm_phase phase_type; + typedef tlm::tlm_sync_enum sync_enum_type; + typedef tlm_utils::simple_target_socket<SimpleLTTarget_ext, 32, + my_extended_payload_types> target_socket_type; + +public: + target_socket_type socket; + +public: + SC_HAS_PROCESS(SimpleLTTarget_ext); + SimpleLTTarget_ext(sc_core::sc_module_name name, + sc_core::sc_time invalidate_dmi_time = sc_core::sc_time(25, sc_core::SC_NS)) : + sc_core::sc_module(name), + socket("socket") + { + // register nb_transport method + socket.register_nb_transport_fw(this, &SimpleLTTarget_ext::myNBTransport); + socket.register_get_direct_mem_ptr(this, &SimpleLTTarget_ext::myGetDMIPtr); + + socket.register_transport_dbg(this, &SimpleLTTarget_ext::transport_dbg); + + SC_METHOD(invalidate_dmi_method); + sensitive << m_invalidate_dmi_event; + dont_initialize(); + m_invalidate_dmi_time = invalidate_dmi_time; + } + + sync_enum_type myNBTransport(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) + { + sc_assert(phase == tlm::BEGIN_REQ); + + my_extension* tmp_ext; + trans.get_extension(tmp_ext); + if (!tmp_ext) + { + std::cout << name() << ": ERROR, extension not present" << std::endl; + } + else + { + std::cout << name() << ": OK, extension data = " + << tmp_ext->m_data << std::endl; + } + sc_dt::uint64 address = trans.get_address(); + sc_assert(address < 400); + + unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr()); + if (trans.get_command() == tlm::TLM_WRITE_COMMAND) { + std::cout << name() << ": Received write request: A = 0x" + << std::hex << (unsigned int)address + << ", D = 0x" << data << std::dec + << " @ " << sc_core::sc_time_stamp() << std::endl; + + *reinterpret_cast<unsigned int*>(&mMem[address]) = data; + t += sc_core::sc_time(10, sc_core::SC_NS); + + } else { + std::cout << name() << ": Received read request: A = 0x" + << std::hex << (unsigned int)address << std::dec + << " @ " << sc_core::sc_time_stamp() << std::endl; + + data = *reinterpret_cast<unsigned int*>(&mMem[address]); + t += sc_core::sc_time(100, sc_core::SC_NS); + } + + trans.set_response_status(tlm::TLM_OK_RESPONSE); + + trans.set_dmi_allowed(true); + + // LT target + // - always return true + // - not necessary to update phase (if true is returned) + return tlm::TLM_COMPLETED; + } + + unsigned int transport_dbg(transaction_type& r) + { + if (r.get_address() >= 400) return 0; + + unsigned int tmp = (int)r.get_address(); + unsigned int num_bytes; + if (tmp + r.get_data_length() >= 400) { + num_bytes = 400 - tmp; + + } else { + num_bytes = r.get_data_length(); + } + if (r.is_read()) { + for (unsigned int i = 0; i < num_bytes; ++i) { + r.get_data_ptr()[i] = mMem[i + tmp]; + } + + } else { + for (unsigned int i = 0; i < num_bytes; ++i) { + mMem[i + tmp] = r.get_data_ptr()[i]; + } + } + return num_bytes; + } + + bool myGetDMIPtr(transaction_type& trans, + tlm::tlm_dmi& dmi_data) + { + // notify DMI invalidation, just to check if this reaches the + // initiators properly + m_invalidate_dmi_event.notify(m_invalidate_dmi_time); + + // Check for DMI extension: + my_extension * tmp_ext; + trans.get_extension(tmp_ext); + if (tmp_ext) + { + std::cout << name() << ": get_direct_mem_ptr OK, extension data = " + <<tmp_ext->m_data << std::endl; + } + else + { + std::cout << name() << ", get_direct_mem_ptr ERROR: " + << "didn't get pointer to extension" + << std::endl; + } + if (trans.get_address() < 400) { + dmi_data.allow_read_write(); + dmi_data.set_start_address(0x0); + dmi_data.set_end_address(399); + dmi_data.set_dmi_ptr(mMem); + dmi_data.set_read_latency(sc_core::sc_time(100, sc_core::SC_NS)); + dmi_data.set_write_latency(sc_core::sc_time(10, sc_core::SC_NS)); + return true; + + } else { + // should not happen + dmi_data.set_start_address(trans.get_address()); + dmi_data.set_end_address(trans.get_address()); + return false; + + } + } + + void invalidate_dmi_method() + { + sc_dt::uint64 start_address = 0x0; + sc_dt::uint64 end_address = 399; + socket->invalidate_direct_mem_ptr(start_address, end_address); + } +private: + unsigned char mMem[400]; + sc_core::sc_event m_invalidate_dmi_event; + sc_core::sc_time m_invalidate_dmi_time; +}; + +#endif diff --git a/src/systemc/tests/tlm/static_extensions/ext2gp2ext/ext2gp2ext.cpp b/src/systemc/tests/tlm/static_extensions/ext2gp2ext/ext2gp2ext.cpp new file mode 100644 index 000000000..13f66f094 --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/ext2gp2ext/ext2gp2ext.cpp @@ -0,0 +1,45 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ +#define SC_INCLUDE_DYNAMIC_PROCESSES +#include "tlm.h" + +#include "SimpleLTInitiator_ext.h" +#include "SimpleBusLT.h" +#include "SimpleLTTarget_ext.h" +#include "extension_adaptors.h" + + +int sc_main(int argc, char* argv[]) +{ + SimpleLTInitiator_ext initiator("initiator1", 10, 0x0); + adapt_ext2gp<32> bridge1("bridge1"); + SimpleBusLT<1,1> bus("bus"); + adapt_gp2ext<32> bridge2("bridge2"); + SimpleLTTarget_ext target("target1"); + + initiator.socket(bridge1.target_socket); + bridge1.initiator_socket(bus.target_socket[0]); + bus.initiator_socket[0](bridge2.target_socket); + bridge2.initiator_socket(target.socket); + + sc_core::sc_start(); + sc_core::sc_stop(); + + return 0; +} diff --git a/src/systemc/tests/tlm/static_extensions/ext2gp2ext/extension_adaptors.h b/src/systemc/tests/tlm/static_extensions/ext2gp2ext/extension_adaptors.h new file mode 100644 index 000000000..a6b470e2a --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/ext2gp2ext/extension_adaptors.h @@ -0,0 +1,212 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __EXTENSIONS_ADAPTORS_H__ +#define __EXTENSIONS_ADAPTORS_H__ + +#include "tlm.h" +#include "my_extension.h" + +#include "tlm_utils/simple_initiator_socket.h" +#include "tlm_utils/simple_target_socket.h" + +template <unsigned int BUSWIDTH = 32> +class adapt_ext2gp : public sc_core::sc_module +{ + public: + typedef tlm::tlm_generic_payload initiator_payload_type; + typedef tlm::tlm_generic_payload target_payload_type; + typedef tlm_utils::simple_initiator_socket<adapt_ext2gp, BUSWIDTH, + tlm::tlm_base_protocol_types> initiator_socket_type; + typedef tlm_utils::simple_target_socket<adapt_ext2gp, BUSWIDTH, + my_extended_payload_types> target_socket_type; + + target_socket_type target_socket; + initiator_socket_type initiator_socket; + + SC_HAS_PROCESS(adapt_ext2gp); + adapt_ext2gp(sc_core::sc_module_name name_) + : sc_core::sc_module(name_) + { + target_socket.register_nb_transport_fw(this, &adapt_ext2gp::forward_nb_transport); + target_socket.register_transport_dbg(this, &adapt_ext2gp::transport_debug); + target_socket.register_get_direct_mem_ptr(this, &adapt_ext2gp::get_dmi_pointer); + + initiator_socket.register_nb_transport_bw(this, &adapt_ext2gp::backward_nb_transport); + initiator_socket.register_invalidate_direct_mem_ptr(this, &adapt_ext2gp::invalidate_dmi_pointers); + } + + /////////////// + // NB transport + /////////////// + + // Forward direction: The initiator calls this method with an extended + // payload. We leave the extension class in the vector, and it will be + // ignored by the GP target. + tlm::tlm_sync_enum forward_nb_transport(initiator_payload_type& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& t) + { + return initiator_socket->nb_transport_fw(trans, phase, t); + } + // Backward direction: we can assume here that the payload we get + // as parameter is the same one that the initiator sent out. Thus, the + // extension vector is known to be present. + tlm::tlm_sync_enum backward_nb_transport(target_payload_type& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& t) + { + return target_socket->nb_transport_bw(trans, phase, t); + } + + bool get_dmi_pointer(target_payload_type& trans, + tlm::tlm_dmi& dmi_data) + { + bool tmp_ret = initiator_socket->get_direct_mem_ptr(trans, + dmi_data); + return tmp_ret; + } + + ////////////////////////// + // simple call forwarders: + ////////////////////////// + unsigned int transport_debug(target_payload_type& trans) + { + return initiator_socket->transport_dbg(trans); + } + void invalidate_dmi_pointers(sc_dt::uint64 start_range, + sc_dt::uint64 end_range) + { + target_socket->invalidate_direct_mem_ptr(start_range, + end_range); + } +}; + +template <unsigned int BUSWIDTH = 32> +class adapt_gp2ext : public sc_core::sc_module +{ + public: + typedef tlm::tlm_generic_payload initiator_payload_type; + typedef tlm::tlm_generic_payload target_payload_type; + typedef tlm_utils::simple_initiator_socket<adapt_gp2ext, BUSWIDTH, + my_extended_payload_types> initiator_socket_type; + typedef tlm_utils::simple_target_socket<adapt_gp2ext, BUSWIDTH, + tlm::tlm_base_protocol_types> target_socket_type; + + target_socket_type target_socket; + initiator_socket_type initiator_socket; + + SC_HAS_PROCESS(adapt_gp2ext); + adapt_gp2ext(sc_core::sc_module_name name_) + : sc_core::sc_module(name_) + { + // Optionally, we can initialize our private extension class + // here, if required. + + target_socket.register_nb_transport_fw(this, &adapt_gp2ext::forward_nb_transport); + target_socket.register_transport_dbg(this, &adapt_gp2ext::transport_debug); + target_socket.register_get_direct_mem_ptr(this, &adapt_gp2ext::get_dmi_pointer); + + initiator_socket.register_nb_transport_bw(this, &adapt_gp2ext::backward_nb_transport); + initiator_socket.register_invalidate_direct_mem_ptr(this, &adapt_gp2ext::invalidate_dmi_pointers); + + m_ext.m_data = 13; + } + + /////////////// + // NB transport + /////////////// + + // Forward direction: We extend the payload on the fly (if needed). + tlm::tlm_sync_enum forward_nb_transport(initiator_payload_type& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& t) + { + // If the mandatory extension is not there, we need to add it and + // store it so that we can re-construc the original state. + // Otherwise we don't touch the extension, so that we don't overwrite + // it in e.g. a nonGP->GP->nonGP (initiator->interconnect->target) + // setup. + // Note, however, that there might be situations where we might need to + // re-initialize the extension, e.g. for mutable data fields in + // different system setups. + trans.get_extension(m_initiator_ext); + if (!m_initiator_ext) + { + m_initiator_ext = trans.set_extension(&m_ext); + } + tlm::tlm_sync_enum tmp = + initiator_socket->nb_transport_fw(trans, phase, t); + if (tmp == tlm::TLM_COMPLETED) + { + m_initiator_ext = trans.set_extension(m_initiator_ext); + } + return tmp; + } + // Backward direction: only restore of original extension and static_cast. + tlm::tlm_sync_enum backward_nb_transport(target_payload_type& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& t) + { + m_initiator_ext = trans.set_extension(m_initiator_ext); + return target_socket->nb_transport_bw(trans, phase, t); + } + + bool get_dmi_pointer(target_payload_type& trans, + tlm::tlm_dmi& dmi_data) + { + // If the mandatory extension is not there, we need to add it and + // store it so that we can re-construc the original state. + // Otherwise we don't touch the extension, so that we don't overwrite + // it in e.g. a nonGP->GP->nonGP (initiator->interconnect->target) + // setup. + my_extension* tmp_ext; + trans.get_extension(tmp_ext); + if (!tmp_ext) + { + trans.set_extension(&m_ext); + } + bool tmp_ret = initiator_socket->get_direct_mem_ptr(trans, + dmi_data); + if(!tmp_ext) + { + trans.clear_extension(tmp_ext); + } + return tmp_ret; + } + ////////////////////////// + // simple call forwarders: + ////////////////////////// + unsigned int transport_debug(target_payload_type& trans) + { + return initiator_socket->transport_dbg(trans); + } + void invalidate_dmi_pointers(sc_dt::uint64 start_range, + sc_dt::uint64 end_range) + { + target_socket->invalidate_direct_mem_ptr(start_range, + end_range); + } + +private: + my_extension m_ext; + my_extension* m_initiator_ext; +}; + +#endif diff --git a/src/systemc/tests/tlm/static_extensions/ext2gp2ext/golden/ext2gp2ext.log b/src/systemc/tests/tlm/static_extensions/ext2gp2ext/golden/ext2gp2ext.log new file mode 100644 index 000000000..4a27a6f7d --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/ext2gp2ext/golden/ext2gp2ext.log @@ -0,0 +1,81 @@ +SystemC Simulation +initiator1: Send write request: A = 0x0, D = 0x0 @ 0 s +target1: OK, extension data = 11 +target1: Received write request: A = 0x0, D = 0x0 @ 0 s +initiator1: Received ok response @ 10 ns +target1: get_direct_mem_ptr OK, extension data = 11 +initiator1: Send write request: A = 0x4, D = 0x1 @ 10 ns +initiator1: Received ok response @ 20 ns +initiator1: Send write request: A = 0x8, D = 0x2 @ 20 ns +initiator1: Received ok response @ 30 ns +initiator1: Send write request: A = 0xc, D = 0x3 @ 30 ns +initiator1: got DMI pointer invalidation @ 35 ns +initiator1: Received ok response @ 40 ns +initiator1: Send write request: A = 0x10, D = 0x4 @ 40 ns +target1: OK, extension data = 11 +target1: Received write request: A = 0x10, D = 0x4 @ 40 ns +initiator1: Received ok response @ 50 ns +target1: get_direct_mem_ptr OK, extension data = 11 +initiator1: Send write request: A = 0x14, D = 0x5 @ 50 ns +initiator1: Received ok response @ 60 ns +initiator1: Send write request: A = 0x18, D = 0x6 @ 60 ns +initiator1: Received ok response @ 70 ns +initiator1: Send write request: A = 0x1c, D = 0x7 @ 70 ns +initiator1: got DMI pointer invalidation @ 75 ns +initiator1: Received ok response @ 80 ns +initiator1: Send write request: A = 0x20, D = 0x8 @ 80 ns +target1: OK, extension data = 11 +target1: Received write request: A = 0x20, D = 0x8 @ 80 ns +initiator1: Received ok response @ 90 ns +target1: get_direct_mem_ptr OK, extension data = 11 +initiator1: Send write request: A = 0x24, D = 0x9 @ 90 ns +initiator1: Received ok response @ 100 ns +initiator1: Send read request: A = 0x0 @ 100 ns +initiator1: got DMI pointer invalidation @ 115 ns +initiator1: Received ok response: D = 0x0 @ 200 ns +initiator1: Send read request: A = 0x4 @ 200 ns +target1: OK, extension data = 11 +target1: Received read request: A = 0x4 @ 200 ns +initiator1: Received ok response: D = 0x1 @ 300 ns +target1: get_direct_mem_ptr OK, extension data = 11 +initiator1: Send read request: A = 0x8 @ 300 ns +initiator1: got DMI pointer invalidation @ 325 ns +initiator1: Received ok response: D = 0x2 @ 400 ns +initiator1: Send read request: A = 0xc @ 400 ns +target1: OK, extension data = 11 +target1: Received read request: A = 0xc @ 400 ns +initiator1: Received ok response: D = 0x3 @ 500 ns +target1: get_direct_mem_ptr OK, extension data = 11 +initiator1: Send read request: A = 0x10 @ 500 ns +initiator1: got DMI pointer invalidation @ 525 ns +initiator1: Received ok response: D = 0x4 @ 600 ns +initiator1: Send read request: A = 0x14 @ 600 ns +target1: OK, extension data = 11 +target1: Received read request: A = 0x14 @ 600 ns +initiator1: Received ok response: D = 0x5 @ 700 ns +target1: get_direct_mem_ptr OK, extension data = 11 +initiator1: Send read request: A = 0x18 @ 700 ns +initiator1: got DMI pointer invalidation @ 725 ns +initiator1: Received ok response: D = 0x6 @ 800 ns +initiator1: Send read request: A = 0x1c @ 800 ns +target1: OK, extension data = 11 +target1: Received read request: A = 0x1c @ 800 ns +initiator1: Received ok response: D = 0x7 @ 900 ns +target1: get_direct_mem_ptr OK, extension data = 11 +initiator1: Send read request: A = 0x20 @ 900 ns +initiator1: got DMI pointer invalidation @ 925 ns +initiator1: Received ok response: D = 0x8 @ 1 us +initiator1: Send read request: A = 0x24 @ 1 us +target1: OK, extension data = 11 +target1: Received read request: A = 0x24 @ 1 us +initiator1: Received ok response: D = 0x9 @ 1100 ns +target1: get_direct_mem_ptr OK, extension data = 11 +initiator1: got DMI pointer invalidation @ 1125 ns + +Info: /OSCI/SystemC: Simulation stopped by user. +initiator1, <<SimpleLTInitiator1>>: + +Mem @0 +00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 +04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 + diff --git a/src/systemc/tests/tlm/static_extensions/ext2gp2ext/my_extension.h b/src/systemc/tests/tlm/static_extensions/ext2gp2ext/my_extension.h new file mode 100644 index 000000000..650931cd1 --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/ext2gp2ext/my_extension.h @@ -0,0 +1,56 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __MY_EXTENSION_H__ +#define __MY_EXTENSION_H__ + +#include "tlm.h" +#include <cassert> + +class my_extension : + public tlm::tlm_extension<my_extension> +{ +public: + my_extension() + : m_data(0) + {} + tlm_extension_base* clone() const + { + return new my_extension(*this); + } + void free() + { + delete this; + } + void copy_from(tlm_extension_base const & e) + { + sc_assert(typeid(this) == typeid(e)); + m_data = static_cast<my_extension const &>(e).m_data; + } + + int m_data; +}; + +struct my_extended_payload_types +{ + typedef tlm::tlm_base_protocol_types::tlm_payload_type tlm_payload_type; + typedef tlm::tlm_base_protocol_types::tlm_phase_type tlm_phase_type; +}; + +#endif diff --git a/src/systemc/tests/tlm/static_extensions/gp2ext/SimpleLTTarget_ext.h b/src/systemc/tests/tlm/static_extensions/gp2ext/SimpleLTTarget_ext.h new file mode 100644 index 000000000..c542c196d --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/gp2ext/SimpleLTTarget_ext.h @@ -0,0 +1,186 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __SIMPLE_LT_TARGET2_H__ +#define __SIMPLE_LT_TARGET2_H__ + +#include "tlm.h" +#include "tlm_utils/simple_target_socket.h" +#include "my_extension.h" + +//#include <systemc> +#include <cassert> +#include <vector> +//#include <iostream> + +class SimpleLTTarget_ext : public sc_core::sc_module +{ +public: + typedef tlm::tlm_generic_payload transaction_type; + typedef tlm::tlm_phase phase_type; + typedef tlm::tlm_sync_enum sync_enum_type; + typedef tlm_utils::simple_target_socket<SimpleLTTarget_ext, 32, + my_extended_payload_types> target_socket_type; + +public: + target_socket_type socket; + +public: + SC_HAS_PROCESS(SimpleLTTarget_ext); + SimpleLTTarget_ext(sc_core::sc_module_name name, + sc_core::sc_time invalidate_dmi_time = sc_core::sc_time(25, sc_core::SC_NS)) : + sc_core::sc_module(name), + socket("socket") + { + // register nb_transport method + socket.register_nb_transport_fw(this, &SimpleLTTarget_ext::myNBTransport); + socket.register_get_direct_mem_ptr(this, &SimpleLTTarget_ext::myGetDMIPtr); + + socket.register_transport_dbg(this, &SimpleLTTarget_ext::transport_dbg); + + SC_METHOD(invalidate_dmi_method); + sensitive << m_invalidate_dmi_event; + dont_initialize(); + m_invalidate_dmi_time = invalidate_dmi_time; + } + + sync_enum_type myNBTransport(transaction_type& trans, phase_type& phase, sc_core::sc_time& t) + { + sc_assert(phase == tlm::BEGIN_REQ); + + my_extension* tmp_ext; + trans.get_extension(tmp_ext); + if (!tmp_ext) + { + std::cout << name() << ": ERROR, extension not present" << std::endl; + } + else + { + std::cout << name() << ": OK, extension data = " + << tmp_ext->m_data << std::endl; + } + sc_dt::uint64 address = trans.get_address(); + sc_assert(address < 400); + + unsigned int& data = *reinterpret_cast<unsigned int*>(trans.get_data_ptr()); + if (trans.get_command() == tlm::TLM_WRITE_COMMAND) { + std::cout << name() << ": Received write request: A = 0x" + << std::hex << (unsigned int)address + << ", D = 0x" << data << std::dec + << " @ " << sc_core::sc_time_stamp() << std::endl; + + *reinterpret_cast<unsigned int*>(&mMem[address]) = data; + t += sc_core::sc_time(10, sc_core::SC_NS); + + } else { + std::cout << name() << ": Received read request: A = 0x" + << std::hex << (unsigned int)address << std::dec + << " @ " << sc_core::sc_time_stamp() << std::endl; + + data = *reinterpret_cast<unsigned int*>(&mMem[address]); + t += sc_core::sc_time(100, sc_core::SC_NS); + } + + trans.set_response_status(tlm::TLM_OK_RESPONSE); + + trans.set_dmi_allowed(true); + + // LT target + // - always return true + // - not necessary to update phase (if true is returned) + return tlm::TLM_COMPLETED; + } + + unsigned int transport_dbg(transaction_type& r) + { + if (r.get_address() >= 400) return 0; + + unsigned int tmp = (int)r.get_address(); + unsigned int num_bytes; + if (tmp + r.get_data_length() >= 400) { + num_bytes = 400 - tmp; + + } else { + num_bytes = r.get_data_length(); + } + if (r.is_read()) { + for (unsigned int i = 0; i < num_bytes; ++i) { + r.get_data_ptr()[i] = mMem[i + tmp]; + } + + } else { + for (unsigned int i = 0; i < num_bytes; ++i) { + mMem[i + tmp] = r.get_data_ptr()[i]; + } + } + return num_bytes; + } + + bool myGetDMIPtr(transaction_type& trans, + tlm::tlm_dmi& dmi_data) + { + // notify DMI invalidation, just to check if this reaches the + // initiators properly + m_invalidate_dmi_event.notify(m_invalidate_dmi_time); + + // Check for DMI extension: + my_extension * tmp_ext; + trans.get_extension(tmp_ext); + if (tmp_ext) + { + std::cout << name() << ": get_direct_mem_ptr OK, extension data = " + <<tmp_ext->m_data << std::endl; + } + else + { + std::cout << name() << ", get_direct_mem_ptr ERROR: " + << "didn't get pointer to extension" + << std::endl; + } + if (trans.get_address() < 400) { + dmi_data.allow_read_write(); + dmi_data.set_start_address(0x0); + dmi_data.set_end_address(399); + dmi_data.set_dmi_ptr(mMem); + dmi_data.set_read_latency(sc_core::sc_time(100, sc_core::SC_NS)); + dmi_data.set_write_latency(sc_core::sc_time(10, sc_core::SC_NS)); + return true; + + } else { + // should not happen + dmi_data.set_start_address(trans.get_address()); + dmi_data.set_end_address(trans.get_address()); + return false; + + } + } + + void invalidate_dmi_method() + { + sc_dt::uint64 start_address = 0x0; + sc_dt::uint64 end_address = 399; + socket->invalidate_direct_mem_ptr(start_address, end_address); + } +private: + unsigned char mMem[400]; + sc_core::sc_event m_invalidate_dmi_event; + sc_core::sc_time m_invalidate_dmi_time; +}; + +#endif diff --git a/src/systemc/tests/tlm/static_extensions/gp2ext/extension_adaptors.h b/src/systemc/tests/tlm/static_extensions/gp2ext/extension_adaptors.h new file mode 100644 index 000000000..a6b470e2a --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/gp2ext/extension_adaptors.h @@ -0,0 +1,212 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __EXTENSIONS_ADAPTORS_H__ +#define __EXTENSIONS_ADAPTORS_H__ + +#include "tlm.h" +#include "my_extension.h" + +#include "tlm_utils/simple_initiator_socket.h" +#include "tlm_utils/simple_target_socket.h" + +template <unsigned int BUSWIDTH = 32> +class adapt_ext2gp : public sc_core::sc_module +{ + public: + typedef tlm::tlm_generic_payload initiator_payload_type; + typedef tlm::tlm_generic_payload target_payload_type; + typedef tlm_utils::simple_initiator_socket<adapt_ext2gp, BUSWIDTH, + tlm::tlm_base_protocol_types> initiator_socket_type; + typedef tlm_utils::simple_target_socket<adapt_ext2gp, BUSWIDTH, + my_extended_payload_types> target_socket_type; + + target_socket_type target_socket; + initiator_socket_type initiator_socket; + + SC_HAS_PROCESS(adapt_ext2gp); + adapt_ext2gp(sc_core::sc_module_name name_) + : sc_core::sc_module(name_) + { + target_socket.register_nb_transport_fw(this, &adapt_ext2gp::forward_nb_transport); + target_socket.register_transport_dbg(this, &adapt_ext2gp::transport_debug); + target_socket.register_get_direct_mem_ptr(this, &adapt_ext2gp::get_dmi_pointer); + + initiator_socket.register_nb_transport_bw(this, &adapt_ext2gp::backward_nb_transport); + initiator_socket.register_invalidate_direct_mem_ptr(this, &adapt_ext2gp::invalidate_dmi_pointers); + } + + /////////////// + // NB transport + /////////////// + + // Forward direction: The initiator calls this method with an extended + // payload. We leave the extension class in the vector, and it will be + // ignored by the GP target. + tlm::tlm_sync_enum forward_nb_transport(initiator_payload_type& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& t) + { + return initiator_socket->nb_transport_fw(trans, phase, t); + } + // Backward direction: we can assume here that the payload we get + // as parameter is the same one that the initiator sent out. Thus, the + // extension vector is known to be present. + tlm::tlm_sync_enum backward_nb_transport(target_payload_type& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& t) + { + return target_socket->nb_transport_bw(trans, phase, t); + } + + bool get_dmi_pointer(target_payload_type& trans, + tlm::tlm_dmi& dmi_data) + { + bool tmp_ret = initiator_socket->get_direct_mem_ptr(trans, + dmi_data); + return tmp_ret; + } + + ////////////////////////// + // simple call forwarders: + ////////////////////////// + unsigned int transport_debug(target_payload_type& trans) + { + return initiator_socket->transport_dbg(trans); + } + void invalidate_dmi_pointers(sc_dt::uint64 start_range, + sc_dt::uint64 end_range) + { + target_socket->invalidate_direct_mem_ptr(start_range, + end_range); + } +}; + +template <unsigned int BUSWIDTH = 32> +class adapt_gp2ext : public sc_core::sc_module +{ + public: + typedef tlm::tlm_generic_payload initiator_payload_type; + typedef tlm::tlm_generic_payload target_payload_type; + typedef tlm_utils::simple_initiator_socket<adapt_gp2ext, BUSWIDTH, + my_extended_payload_types> initiator_socket_type; + typedef tlm_utils::simple_target_socket<adapt_gp2ext, BUSWIDTH, + tlm::tlm_base_protocol_types> target_socket_type; + + target_socket_type target_socket; + initiator_socket_type initiator_socket; + + SC_HAS_PROCESS(adapt_gp2ext); + adapt_gp2ext(sc_core::sc_module_name name_) + : sc_core::sc_module(name_) + { + // Optionally, we can initialize our private extension class + // here, if required. + + target_socket.register_nb_transport_fw(this, &adapt_gp2ext::forward_nb_transport); + target_socket.register_transport_dbg(this, &adapt_gp2ext::transport_debug); + target_socket.register_get_direct_mem_ptr(this, &adapt_gp2ext::get_dmi_pointer); + + initiator_socket.register_nb_transport_bw(this, &adapt_gp2ext::backward_nb_transport); + initiator_socket.register_invalidate_direct_mem_ptr(this, &adapt_gp2ext::invalidate_dmi_pointers); + + m_ext.m_data = 13; + } + + /////////////// + // NB transport + /////////////// + + // Forward direction: We extend the payload on the fly (if needed). + tlm::tlm_sync_enum forward_nb_transport(initiator_payload_type& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& t) + { + // If the mandatory extension is not there, we need to add it and + // store it so that we can re-construc the original state. + // Otherwise we don't touch the extension, so that we don't overwrite + // it in e.g. a nonGP->GP->nonGP (initiator->interconnect->target) + // setup. + // Note, however, that there might be situations where we might need to + // re-initialize the extension, e.g. for mutable data fields in + // different system setups. + trans.get_extension(m_initiator_ext); + if (!m_initiator_ext) + { + m_initiator_ext = trans.set_extension(&m_ext); + } + tlm::tlm_sync_enum tmp = + initiator_socket->nb_transport_fw(trans, phase, t); + if (tmp == tlm::TLM_COMPLETED) + { + m_initiator_ext = trans.set_extension(m_initiator_ext); + } + return tmp; + } + // Backward direction: only restore of original extension and static_cast. + tlm::tlm_sync_enum backward_nb_transport(target_payload_type& trans, + tlm::tlm_phase& phase, + sc_core::sc_time& t) + { + m_initiator_ext = trans.set_extension(m_initiator_ext); + return target_socket->nb_transport_bw(trans, phase, t); + } + + bool get_dmi_pointer(target_payload_type& trans, + tlm::tlm_dmi& dmi_data) + { + // If the mandatory extension is not there, we need to add it and + // store it so that we can re-construc the original state. + // Otherwise we don't touch the extension, so that we don't overwrite + // it in e.g. a nonGP->GP->nonGP (initiator->interconnect->target) + // setup. + my_extension* tmp_ext; + trans.get_extension(tmp_ext); + if (!tmp_ext) + { + trans.set_extension(&m_ext); + } + bool tmp_ret = initiator_socket->get_direct_mem_ptr(trans, + dmi_data); + if(!tmp_ext) + { + trans.clear_extension(tmp_ext); + } + return tmp_ret; + } + ////////////////////////// + // simple call forwarders: + ////////////////////////// + unsigned int transport_debug(target_payload_type& trans) + { + return initiator_socket->transport_dbg(trans); + } + void invalidate_dmi_pointers(sc_dt::uint64 start_range, + sc_dt::uint64 end_range) + { + target_socket->invalidate_direct_mem_ptr(start_range, + end_range); + } + +private: + my_extension m_ext; + my_extension* m_initiator_ext; +}; + +#endif diff --git a/src/systemc/tests/tlm/static_extensions/gp2ext/golden/gp2ext.log b/src/systemc/tests/tlm/static_extensions/gp2ext/golden/gp2ext.log new file mode 100644 index 000000000..d43825d43 --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/gp2ext/golden/gp2ext.log @@ -0,0 +1,81 @@ +SystemC Simulation +initiator1: Send write request: A = 0x0, D = 0x0 @ 0 s +target1: OK, extension data = 13 +target1: Received write request: A = 0x0, D = 0x0 @ 0 s +initiator1: Received ok response @ 10 ns +target1: get_direct_mem_ptr OK, extension data = 13 +initiator1: Send write request: A = 0x4, D = 0x1 @ 10 ns +initiator1: Received ok response @ 20 ns +initiator1: Send write request: A = 0x8, D = 0x2 @ 20 ns +initiator1: Received ok response @ 30 ns +initiator1: Send write request: A = 0xc, D = 0x3 @ 30 ns +initiator1: got DMI pointer invalidation @ 35 ns +initiator1: Received ok response @ 40 ns +initiator1: Send write request: A = 0x10, D = 0x4 @ 40 ns +target1: OK, extension data = 13 +target1: Received write request: A = 0x10, D = 0x4 @ 40 ns +initiator1: Received ok response @ 50 ns +target1: get_direct_mem_ptr OK, extension data = 13 +initiator1: Send write request: A = 0x14, D = 0x5 @ 50 ns +initiator1: Received ok response @ 60 ns +initiator1: Send write request: A = 0x18, D = 0x6 @ 60 ns +initiator1: Received ok response @ 70 ns +initiator1: Send write request: A = 0x1c, D = 0x7 @ 70 ns +initiator1: got DMI pointer invalidation @ 75 ns +initiator1: Received ok response @ 80 ns +initiator1: Send write request: A = 0x20, D = 0x8 @ 80 ns +target1: OK, extension data = 13 +target1: Received write request: A = 0x20, D = 0x8 @ 80 ns +initiator1: Received ok response @ 90 ns +target1: get_direct_mem_ptr OK, extension data = 13 +initiator1: Send write request: A = 0x24, D = 0x9 @ 90 ns +initiator1: Received ok response @ 100 ns +initiator1: Send read request: A = 0x0 @ 100 ns +initiator1: got DMI pointer invalidation @ 115 ns +initiator1: Received ok response: D = 0x0 @ 200 ns +initiator1: Send read request: A = 0x4 @ 200 ns +target1: OK, extension data = 13 +target1: Received read request: A = 0x4 @ 200 ns +initiator1: Received ok response: D = 0x1 @ 300 ns +target1: get_direct_mem_ptr OK, extension data = 13 +initiator1: Send read request: A = 0x8 @ 300 ns +initiator1: got DMI pointer invalidation @ 325 ns +initiator1: Received ok response: D = 0x2 @ 400 ns +initiator1: Send read request: A = 0xc @ 400 ns +target1: OK, extension data = 13 +target1: Received read request: A = 0xc @ 400 ns +initiator1: Received ok response: D = 0x3 @ 500 ns +target1: get_direct_mem_ptr OK, extension data = 13 +initiator1: Send read request: A = 0x10 @ 500 ns +initiator1: got DMI pointer invalidation @ 525 ns +initiator1: Received ok response: D = 0x4 @ 600 ns +initiator1: Send read request: A = 0x14 @ 600 ns +target1: OK, extension data = 13 +target1: Received read request: A = 0x14 @ 600 ns +initiator1: Received ok response: D = 0x5 @ 700 ns +target1: get_direct_mem_ptr OK, extension data = 13 +initiator1: Send read request: A = 0x18 @ 700 ns +initiator1: got DMI pointer invalidation @ 725 ns +initiator1: Received ok response: D = 0x6 @ 800 ns +initiator1: Send read request: A = 0x1c @ 800 ns +target1: OK, extension data = 13 +target1: Received read request: A = 0x1c @ 800 ns +initiator1: Received ok response: D = 0x7 @ 900 ns +target1: get_direct_mem_ptr OK, extension data = 13 +initiator1: Send read request: A = 0x20 @ 900 ns +initiator1: got DMI pointer invalidation @ 925 ns +initiator1: Received ok response: D = 0x8 @ 1 us +initiator1: Send read request: A = 0x24 @ 1 us +target1: OK, extension data = 13 +target1: Received read request: A = 0x24 @ 1 us +initiator1: Received ok response: D = 0x9 @ 1100 ns +target1: get_direct_mem_ptr OK, extension data = 13 +initiator1: got DMI pointer invalidation @ 1125 ns + +Info: /OSCI/SystemC: Simulation stopped by user. +initiator1, <<SimpleLTInitiator1>>: + +Mem @0 +00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 +04 00 00 00 05 00 00 00 06 00 00 00 07 00 00 00 + diff --git a/src/systemc/tests/tlm/static_extensions/gp2ext/gp2ext.cpp b/src/systemc/tests/tlm/static_extensions/gp2ext/gp2ext.cpp new file mode 100644 index 000000000..0533e9d1b --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/gp2ext/gp2ext.cpp @@ -0,0 +1,40 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ +#define SC_INCLUDE_DYNAMIC_PROCESSES +#include "tlm.h" + +#include "SimpleLTInitiator1_DMI.h" +#include "SimpleLTTarget_ext.h" +#include "extension_adaptors.h" + + +int sc_main(int argc, char* argv[]) +{ + SimpleLTInitiator1_dmi initiator("initiator1", 10, 0x0); + adapt_gp2ext<32> bridge("bridge"); + SimpleLTTarget_ext target("target1"); + + initiator.socket(bridge.target_socket); + bridge.initiator_socket(target.socket); + + sc_core::sc_start(); + sc_core::sc_stop(); + + return 0; +} diff --git a/src/systemc/tests/tlm/static_extensions/gp2ext/my_extension.h b/src/systemc/tests/tlm/static_extensions/gp2ext/my_extension.h new file mode 100644 index 000000000..650931cd1 --- /dev/null +++ b/src/systemc/tests/tlm/static_extensions/gp2ext/my_extension.h @@ -0,0 +1,56 @@ +/***************************************************************************** + + 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. + + *****************************************************************************/ + +#ifndef __MY_EXTENSION_H__ +#define __MY_EXTENSION_H__ + +#include "tlm.h" +#include <cassert> + +class my_extension : + public tlm::tlm_extension<my_extension> +{ +public: + my_extension() + : m_data(0) + {} + tlm_extension_base* clone() const + { + return new my_extension(*this); + } + void free() + { + delete this; + } + void copy_from(tlm_extension_base const & e) + { + sc_assert(typeid(this) == typeid(e)); + m_data = static_cast<my_extension const &>(e).m_data; + } + + int m_data; +}; + +struct my_extended_payload_types +{ + typedef tlm::tlm_base_protocol_types::tlm_payload_type tlm_payload_type; + typedef tlm::tlm_base_protocol_types::tlm_phase_type tlm_phase_type; +}; + +#endif diff --git a/src/systemc/tests/tlm/update_original/golden/update_original.log b/src/systemc/tests/tlm/update_original/golden/update_original.log new file mode 100644 index 000000000..17680a7f7 --- /dev/null +++ b/src/systemc/tests/tlm/update_original/golden/update_original.log @@ -0,0 +1,2 @@ +SystemC Simulation +Unit test for update_original_from(). Should remain silent diff --git a/src/systemc/tests/tlm/update_original/mm.h b/src/systemc/tests/tlm/update_original/mm.h new file mode 100644 index 000000000..c91dd3ed5 --- /dev/null +++ b/src/systemc/tests/tlm/update_original/mm.h @@ -0,0 +1,85 @@ + +// ******************************************************************* +// User-defined memory manager, which maintains a pool of transactions +// ******************************************************************* + +#include "tlm.h" + +class mm: public tlm::tlm_mm_interface +{ + typedef tlm::tlm_generic_payload gp_t; + +public: + mm() : free_list(0), empties(0) {} + + virtual ~mm() + { + gp_t* ptr; + + while (free_list) + { + ptr = free_list->trans; + + // Delete generic payload and all extensions + sc_assert(ptr); + delete ptr; + + free_list = free_list->next; + } + + while (empties) + { + access* x = empties; + empties = empties->next; + + // Delete free list access struct + delete x; + } + } + + gp_t* allocate(); + void free(gp_t* trans); + +private: + struct access + { + gp_t* trans; + access* next; + access* prev; + }; + + access* free_list; + access* empties; +}; + +mm::gp_t* mm::allocate() +{ + gp_t* ptr; + if (free_list) + { + ptr = free_list->trans; + empties = free_list; + free_list = free_list->next; + } + else + { + ptr = new gp_t(this); + } + return ptr; +} + +void mm::free(gp_t* trans) +{ + trans->reset(); // Delete auto extensions + if (!empties) + { + empties = new access; + empties->next = free_list; + empties->prev = 0; + if (free_list) + free_list->prev = empties; + } + free_list = empties; + free_list->trans = trans; + empties = free_list->prev; +} diff --git a/src/systemc/tests/tlm/update_original/update_original.cpp b/src/systemc/tests/tlm/update_original/update_original.cpp new file mode 100644 index 000000000..e99d70c03 --- /dev/null +++ b/src/systemc/tests/tlm/update_original/update_original.cpp @@ -0,0 +1,270 @@ + +// Unit test for tlm_generic_payload update_original_from() method + +#include <iomanip> + +#define SC_INCLUDE_DYNAMIC_PROCESSES + +#include "systemc" +using namespace sc_core; +using namespace sc_dt; +using namespace std; + +#include "tlm.h" +#include "tlm_utils/simple_initiator_socket.h" +#include "tlm_utils/simple_target_socket.h" + +#include "mm.h" + +struct my_extension: tlm::tlm_extension<my_extension> +{ + my_extension() {} + + virtual tlm_extension_base* clone() const + { + my_extension* ext = new my_extension; + ext->len = len; + ext->bel = bel; + ext->ptr = ptr; + ext->byt = byt; + return ext; + } + + virtual void copy_from(tlm_extension_base const &ext) + { + len = static_cast<my_extension const &>(ext).len; + bel = static_cast<my_extension const &>(ext).bel; + ptr = static_cast<my_extension const &>(ext).ptr; + byt = static_cast<my_extension const &>(ext).byt; + } + + unsigned int len; + unsigned int bel; + unsigned char* ptr; + unsigned char* byt; +}; + + +struct Initiator: sc_module +{ + tlm_utils::simple_initiator_socket<Initiator> socket; + + typedef unsigned char uchar; + + SC_CTOR(Initiator) + : socket("socket") + { + SC_THREAD(thread_process); + data = new uchar[32]; + byte_enable = new uchar[32]; + } + + void thread_process() + { + tlm::tlm_generic_payload* trans; + sc_time delay = SC_ZERO_TIME; + + for (int i = 0; i < 1000000; i++) + { + int addr = 0; + tlm::tlm_command cmd = static_cast<tlm::tlm_command>(rand() % 2); + + unsigned int len = rand() % 33; + unsigned int bel = rand() % (len + 1); + + // Fix sizes when performing a speed test + //cmd = tlm::TLM_READ_COMMAND; + //len = 32; + //bel = 8; + + + for (unsigned int i = 0; i < len; i++) + if (cmd == tlm::TLM_WRITE_COMMAND) + { + data[i] = rand() % 256; + } + else + data[i] = 0x99; + + trans = m_mm.allocate(); + trans->acquire(); + + trans->set_command( cmd ); + trans->set_address( addr ); + trans->set_data_ptr( data ); + trans->set_data_length( len ); + trans->set_streaming_width( len ); + + trans->set_byte_enable_length( bel ); + + for (unsigned int i = 0; i < bel; i++) + { + byte_enable[i] = (rand() % 2) ? 0xff : 0; + } + + if (bel) + trans->set_byte_enable_ptr( byte_enable ); + else + trans->set_byte_enable_ptr( 0 ); + + trans->set_dmi_allowed( false ); + trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); + + // Add sticky extension diagnostics + my_extension* ext; + trans->get_extension(ext); + if (!ext) + { + ext = new my_extension; + trans->set_extension(ext); + } + + ext->len = len; + ext->bel = bel; + ext->ptr = data; + ext->byt = byte_enable; + + socket->b_transport( *trans, delay ); // Blocking transport call + + if ( trans->is_response_error() ) + SC_REPORT_ERROR("TLM-2", "Response error from b_transport"); + + //cout << "cmd = " << cmd << ", len = " << len << ", bel = " << bel << endl; + //cout << hex << setw(2) << setfill('0') << (unsigned int)data[i]; + + if (cmd == tlm::TLM_READ_COMMAND) + { + for (unsigned int i = 0; i < len; i++) + if (bel) + if (byte_enable[i % bel]) + sc_assert( data[i] == ext->ptr[i] ); + else + sc_assert( data[i] == 0x99 ); + else + sc_assert( data[i] == ext->ptr[i] ); + + } + trans->release(); + } + } + + mm m_mm; // Memory manager + unsigned char* data; // 32 bytes + unsigned char* byte_enable; +}; + + +struct Interconnect: sc_module +{ + tlm_utils::simple_target_socket <Interconnect> targ_socket; + tlm_utils::simple_initiator_socket<Interconnect> init_socket; + + SC_CTOR(Interconnect) + : targ_socket("targ_socket") + , init_socket("init_socket") + { + targ_socket.register_b_transport(this, &Interconnect::b_transport); + } + + virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) + { + unsigned int bel = trans.get_byte_enable_length(); + + trans2.set_data_ptr( data ); + if (bel) + trans2.set_byte_enable_ptr( byte_enable ); + trans2.deep_copy_from(trans); + + init_socket->b_transport( trans2, delay ); + + trans.update_original_from( trans2 ); + } + + tlm::tlm_generic_payload trans2; + unsigned char data[32]; + unsigned char byte_enable[32]; +}; + + +struct Target: sc_module +{ + tlm_utils::simple_target_socket<Target> socket; + + SC_CTOR(Target) + : socket("socket") + { + socket.register_b_transport(this, &Target ::b_transport); + + typedef unsigned char uchar; + data = new uchar[32]; + } + + + virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) + { + tlm::tlm_command cmd = trans.get_command(); + unsigned char* ptr = trans.get_data_ptr(); + unsigned int len = trans.get_data_length(); + unsigned char* byt = trans.get_byte_enable_ptr(); + unsigned int bel = trans.get_byte_enable_length(); + + my_extension* ext; + trans.get_extension(ext); + sc_assert( ext ); + + sc_assert( len == ext->len ); + sc_assert( bel == ext->bel ); + for (unsigned int i = 0; i < bel; i++) + sc_assert( byt[i] == ext->byt[i] ); + for (unsigned int i = 0; i < len; i++) + sc_assert( ptr[i] == ext->ptr[i] ); + + if (cmd == tlm::TLM_READ_COMMAND) + { + for (unsigned int i = 0; i < len; i++) + { + data[i] = rand() % 256; + ptr[i] = data[i]; + } + ext->ptr = data; + } + + trans.set_dmi_allowed( true ); + trans.set_response_status( tlm::TLM_OK_RESPONSE ); + } + + unsigned char* data; // 32 bytes +}; + + +SC_MODULE(Top) +{ + Initiator *initiator; + Interconnect *interconnect; + Target *target; + + SC_CTOR(Top) + { + // Instantiate components + initiator = new Initiator ("initiator"); + interconnect = new Interconnect("interconnect"); + target = new Target ("target"); + + // One initiator is bound directly to one target with no intervening bus + + // Bind initiator socket to target socket + initiator ->socket .bind( interconnect->targ_socket ); + interconnect ->init_socket.bind( target ->socket ); + } +}; + + +int sc_main(int argc, char* argv[]) +{ + cout << "Unit test for update_original_from(). Should remain silent\n"; + + Top top("top"); + sc_start(); + return 0; +} + |