Started from SystemC-Quickstart
This commit is contained in:
		
							
								
								
									
										18
									
								
								components/components.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								components/components.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| /* | ||||
|  * components.h | ||||
|  * | ||||
|  *  Created on: 02.12.2018 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #ifndef COMPONENTS_H_ | ||||
| #define COMPONENTS_H_ | ||||
|  | ||||
| //#include "tx_example_mods.h" | ||||
| #include <systemc.h> | ||||
| #include "logging.h" | ||||
| #include "initiator.h" | ||||
| #include "router.h" | ||||
| #include "target.h" | ||||
|  | ||||
| #endif /* COMPONENTS_H_ */ | ||||
							
								
								
									
										136
									
								
								components/initiator.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								components/initiator.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | ||||
| /* | ||||
|  * initiator.cpp | ||||
|  * | ||||
|  *  Created on: 02.12.2018 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #include "initiator.h" | ||||
| #include "logging.h" | ||||
|  | ||||
|  | ||||
| Initiator::Initiator(::sc_core::sc_module_name nm) | ||||
| : socket("socket")  // Construct and name socket | ||||
| , dmi_ptr_valid(false) | ||||
| { | ||||
|     // Register callbacks for incoming interface method calls | ||||
|     socket.register_invalidate_direct_mem_ptr(this, &Initiator::invalidate_direct_mem_ptr); | ||||
|  | ||||
|     SC_THREAD(thread_process); | ||||
| } | ||||
|  | ||||
| void Initiator::thread_process() { | ||||
|     { | ||||
|         // TLM-2 generic payload transaction, reused across calls to b_transport, DMI and debug | ||||
|         tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload; | ||||
|         sc_time delay = sc_time(10, SC_NS); | ||||
|  | ||||
|         // Generate a random sequence of reads and writes | ||||
|         for (int i = 256-64; i < 256+64; i += 4) | ||||
|         { | ||||
|             int data; | ||||
|             tlm::tlm_command cmd = static_cast<tlm::tlm_command>(rand() % 2); | ||||
|             if (cmd == tlm::TLM_WRITE_COMMAND) data = 0xFF000000 | i; | ||||
|  | ||||
|             // Use DMI if it is available | ||||
|             if (dmi_ptr_valid && sc_dt::uint64(i) >= dmi_data.get_start_address() | ||||
|                     && sc_dt::uint64(i) <= dmi_data.get_end_address()) | ||||
|             { | ||||
|                 // Bypass transport interface and use direct memory interface | ||||
|                 // Implement target latency | ||||
|                 if ( cmd == tlm::TLM_READ_COMMAND ) | ||||
|                 { | ||||
|                     assert( dmi_data.is_read_allowed() ); | ||||
|                     memcpy(&data, dmi_data.get_dmi_ptr() + i - dmi_data.get_start_address(), 4); | ||||
|                     wait( dmi_data.get_read_latency() ); | ||||
|                 } | ||||
|                 else if ( cmd == tlm::TLM_WRITE_COMMAND ) | ||||
|                 { | ||||
|                     assert( dmi_data.is_write_allowed() ); | ||||
|                     memcpy(dmi_data.get_dmi_ptr() + i - dmi_data.get_start_address(), &data, 4); | ||||
|                     wait( dmi_data.get_write_latency() ); | ||||
|                 } | ||||
|  | ||||
|                 LOG_INFO << "DMI   = { " << (cmd ? 'W' : 'R') << ", " << hex << i | ||||
|                         << " } , data = " << hex << data << " at time " << sc_time_stamp(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 trans->set_command( cmd ); | ||||
|                 trans->set_address( i ); | ||||
|                 trans->set_data_ptr( reinterpret_cast<unsigned char*>(&data) ); | ||||
|                 trans->set_data_length( 4 ); | ||||
|                 trans->set_streaming_width( 4 ); // = data_length to indicate no streaming | ||||
|                 trans->set_byte_enable_ptr( 0 ); // 0 indicates unused | ||||
|                 trans->set_dmi_allowed( false ); // Mandatory initial value | ||||
|                 trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); // Mandatory initial value | ||||
|  | ||||
|  | ||||
| #ifdef INJECT_ERROR | ||||
|                 if (i > 90) trans->set_streaming_width(2); | ||||
| #endif | ||||
|  | ||||
|                 // Other fields default: byte enable = 0, streaming width = 0, DMI_hint = false, no extensions | ||||
|  | ||||
|                 socket->b_transport( *trans, delay );  // Blocking transport call | ||||
|  | ||||
|                 // Initiator obliged to check response status | ||||
|                 if ( trans->is_response_error() ) | ||||
|                 { | ||||
|                     // Print response string | ||||
|                     char txt[100]; | ||||
|                     sprintf(txt, "Error from b_transport, response status = %s", | ||||
|                             trans->get_response_string().c_str()); | ||||
|                     SC_REPORT_ERROR("TLM-2", txt); | ||||
|  | ||||
|                 } | ||||
|  | ||||
|                 // Check DMI hint | ||||
|                 if ( trans->is_dmi_allowed() ) | ||||
|                 { | ||||
|                     // ********************************************* | ||||
|                     // Re-use transaction object for DMI. Reset the address because it could | ||||
|                     // have been modified by the interconnect on the previous transport call | ||||
|                     // ********************************************* | ||||
|  | ||||
|                     trans->set_address( i ); | ||||
|                     dmi_ptr_valid = socket->get_direct_mem_ptr( *trans, dmi_data ); | ||||
|                 } | ||||
|  | ||||
|                 LOG_INFO << "trans = { " << (cmd ? 'W' : 'R') << ", " << hex << i | ||||
|                         << " } , data = " << hex << data << " at time " << sc_time_stamp(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Use debug transaction interface to dump memory contents, reusing same transaction object | ||||
|         sc_dt::uint64 A = 128; | ||||
|         trans->set_address(A); | ||||
|         trans->set_read(); | ||||
|         trans->set_data_length(256); | ||||
|  | ||||
|         unsigned char* data = new unsigned char[256]; | ||||
|         trans->set_data_ptr(data); | ||||
|  | ||||
|         unsigned int n_bytes = socket->transport_dbg( *trans ); | ||||
|  | ||||
|         for (unsigned int i = 0; i < n_bytes; i += 4) | ||||
|         { | ||||
|             LOG_INFO << "mem[" << (A + i) << "] = " | ||||
|                     << *(reinterpret_cast<unsigned int*>( &data[i] )); | ||||
|         } | ||||
|  | ||||
|         A = 256; | ||||
|         trans->set_address(A); | ||||
|         trans->set_data_length(128); | ||||
|  | ||||
|         n_bytes = socket->transport_dbg( *trans ); | ||||
|  | ||||
|         for (unsigned int i = 0; i < n_bytes; i += 4) | ||||
|         { | ||||
|             LOG_INFO << "mem[" << (A + i) << "] = " | ||||
|                     << *(reinterpret_cast<unsigned int*>( &data[i] )); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										36
									
								
								components/initiator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								components/initiator.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| #ifndef INITIATOR_H | ||||
| #define INITIATOR_H | ||||
|  | ||||
| #include "systemc" | ||||
| using namespace sc_core; | ||||
| using namespace sc_dt; | ||||
| using namespace std; | ||||
|  | ||||
| #include "tlm.h" | ||||
| #include "tlm_utils/simple_initiator_socket.h" | ||||
|  | ||||
|  | ||||
| // Initiator module generating generic payload transactions | ||||
|  | ||||
| struct Initiator: sc_module | ||||
| { | ||||
|   // TLM-2 socket, defaults to 32-bits wide, base protocol | ||||
|   tlm_utils::simple_initiator_socket<Initiator> socket; | ||||
|  | ||||
|   SC_HAS_PROCESS(Initiator); | ||||
|  | ||||
|   Initiator( ::sc_core::sc_module_name ); | ||||
|  | ||||
|   void thread_process(); | ||||
|  | ||||
|   // TLM-2 backward DMI method | ||||
|   void invalidate_direct_mem_ptr(sc_dt::uint64 start_range, sc_dt::uint64 end_range){ | ||||
|     // Ignore range and invalidate all DMI pointers regardless | ||||
|     dmi_ptr_valid = false; | ||||
|   } | ||||
|  | ||||
|   bool dmi_ptr_valid; | ||||
|   tlm::tlm_dmi dmi_data; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										115
									
								
								components/logging.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										115
									
								
								components/logging.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,115 @@ | ||||
| /* | ||||
|  * logging.cpp | ||||
|  * | ||||
|  *  Created on: 24.12.2018 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include "logging.h" | ||||
| #include <systemc> | ||||
| #include <deque> | ||||
| #include <array> | ||||
| #include <sstream> | ||||
| #include <iomanip> | ||||
|  | ||||
| using namespace sc_core; | ||||
|  | ||||
| enum log_level {NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE}; | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| static std::deque<std::string> msg_buf; | ||||
|  | ||||
| inline log_level verbosity2log(int verb) { | ||||
|     if (verb >= sc_core::SC_FULL) return TRACE; | ||||
|     if (verb >= sc_core::SC_HIGH) return DEBUG; | ||||
|     return INFO; | ||||
| } | ||||
|  | ||||
| std::string time2string(const sc_core::sc_time &t) { | ||||
|     const std::array<const char *, 6> time_units{"fs", "ps", "ns", "us", "ms", "s "}; | ||||
|     const std::array<uint64_t, 6> multiplier{1ULL, | ||||
|                                              1000ULL, | ||||
|                                              1000ULL * 1000, | ||||
|                                              1000ULL * 1000 * 1000, | ||||
|                                              1000ULL * 1000 * 1000 * 1000, | ||||
|                                              1000ULL * 1000 * 1000 * 1000 * 1000}; | ||||
|     std::ostringstream oss; | ||||
|     const sc_core::sc_time_tuple tt{t}; | ||||
|     const auto val = tt.value(); | ||||
|     if (!val) { | ||||
|         oss << "0 s"; | ||||
|     } else { | ||||
|         const unsigned scale = tt.unit(); | ||||
|         const auto fs_val = val * multiplier[scale]; | ||||
|         for (int j = multiplier.size() - 1; j >= scale; --j) { | ||||
|             if (fs_val > multiplier[j]) { | ||||
|                 const auto i = val / multiplier[j - scale]; | ||||
|                 const auto f = val % multiplier[j - scale]; | ||||
|                 oss << i << '.' << std::setw(3 * (j - scale)) << std::setfill('0') << std::left << f << ' ' | ||||
|                     << time_units[j]; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return oss.str(); | ||||
| } | ||||
|  | ||||
| const std::string compose_message(const sc_report &rep) { | ||||
|     std::stringstream os; | ||||
|     os << "[" << std::setw(20) << time2string(sc_core::sc_time_stamp()) << "] "; | ||||
|     if (rep.get_id() >= 0) | ||||
|         os << "(" | ||||
|            << "IWEF"[rep.get_severity()] << rep.get_id() << ") "; | ||||
|     os << rep.get_msg_type(); | ||||
|     if (*rep.get_msg()) os << ": " << rep.get_msg(); | ||||
|     if (rep.get_severity() > SC_INFO) { | ||||
|         std::array<char, 16> line_number_str; | ||||
|         os << " [FILE:" << rep.get_file_name() << ":" << rep.get_line_number() << "]"; | ||||
|         sc_simcontext *simc = sc_get_curr_simcontext(); | ||||
|         if (simc && sc_is_running()) { | ||||
|             const char *proc_name = rep.get_process_name(); | ||||
|             if (proc_name) os << "[PROCESS:" << proc_name << "]"; | ||||
|         } | ||||
|     } | ||||
|     return os.str(); | ||||
| } | ||||
|  | ||||
| void report_handler(const sc_report &rep, const sc_actions &actions) { | ||||
|     std::array<const log_level, 4> map = {{INFO, WARNING, ERROR, FATAL}}; | ||||
|     if (actions & SC_DISPLAY) { | ||||
|         auto level = rep.get_severity() > sc_core::SC_INFO ? map[rep.get_severity()] : verbosity2log(rep.get_verbosity()); | ||||
|         msg_buf.push_back(compose_message(rep)); | ||||
|     } | ||||
|     if (actions & SC_STOP) sc_stop(); | ||||
|     if (actions & SC_ABORT) abort(); | ||||
|     if (actions & SC_THROW) throw rep; | ||||
| } | ||||
| } | ||||
|  | ||||
| bool has_output(){ | ||||
|     return !msg_buf.empty(); | ||||
| } | ||||
|  | ||||
| std::string get_output(){ | ||||
|     std::string ret = msg_buf.front(); | ||||
|     msg_buf.pop_front(); | ||||
|     return ret; | ||||
| } | ||||
|  | ||||
| void init_logging(unsigned level) { | ||||
|     const std::array<int, 8> verbosity = {SC_NONE,   // Logging::NONE | ||||
|                                           SC_LOW,    // Logging::FATAL | ||||
|                                           SC_LOW,    // Logging::ERROR | ||||
|                                           SC_LOW,    // Logging::WARNING | ||||
|                                           SC_MEDIUM, // Logging::INFO | ||||
|                                           SC_HIGH,   // logging::DEBUG | ||||
|                                           SC_FULL,   // logging::TRACE | ||||
|                                           SC_DEBUG}; // logging::TRACE+1 | ||||
|     sc_report_handler::set_verbosity_level(verbosity[level]); | ||||
|     sc_report_handler::set_handler(report_handler); | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
							
								
								
									
										42
									
								
								components/logging.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								components/logging.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| /* | ||||
|  * logging.h | ||||
|  * | ||||
|  *  Created on: 24.12.2018 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #ifndef LOGGING_H_ | ||||
| #define LOGGING_H_ | ||||
|  | ||||
| #include <string> | ||||
| #include <sstream> | ||||
| #include <systemc.h> | ||||
|  | ||||
| bool has_output(); | ||||
| std::string get_output(); | ||||
| void init_logging(unsigned level); | ||||
|  | ||||
| class Log { | ||||
| public: | ||||
|    Log(const char* file, int line):messageLevel(sc_core::SC_INFO), file(file), line(line){}; | ||||
|    Log(const Log&) = delete; | ||||
|    Log& operator =(const Log&) = delete; | ||||
|    virtual ~Log(){ | ||||
|        ::sc_core::sc_report_handler::report(messageLevel, "", os.str().c_str(), file, line ); | ||||
|     } | ||||
|    std::ostringstream& Get(sc_core::sc_severity level = sc_core::SC_INFO){ | ||||
|        messageLevel = level; | ||||
|        return os; | ||||
|     } | ||||
| protected: | ||||
|    std::ostringstream os; | ||||
|    sc_core::sc_severity messageLevel; | ||||
|    const char* file; | ||||
|    int line; | ||||
| }; | ||||
|  | ||||
| #define LOG(level) Log(__FILE__, __LINE__).Get(level) | ||||
| #define LOG_INFO   Log(__FILE__, __LINE__).Get(sc_core::SC_INFO) | ||||
| #define LOG_WARN   Log(__FILE__, __LINE__).Get(sc_core::SC_WARNING) | ||||
| #define LOG_ERR   Log(__FILE__, __LINE__).Get(sc_core::SC_ERROR) | ||||
| #endif /* LOGGING_H_ */ | ||||
							
								
								
									
										133
									
								
								components/router.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								components/router.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| #ifndef ROUTER_H | ||||
| #define ROUTER_H | ||||
|  | ||||
| #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" | ||||
|  | ||||
|  | ||||
| // ********************************************* | ||||
| // Generic payload blocking transport router | ||||
| // ********************************************* | ||||
|  | ||||
| template<unsigned int N_TARGETS> | ||||
| struct Router: sc_module | ||||
| { | ||||
|   // TLM-2 socket, defaults to 32-bits wide, base protocol | ||||
|   tlm_utils::simple_target_socket<Router>            target_socket; | ||||
|  | ||||
|   // ********************************************* | ||||
|   // Use tagged sockets to be able to distinguish incoming backward path calls | ||||
|   // ********************************************* | ||||
|  | ||||
|   sc_core::sc_vector<tlm_utils::simple_initiator_socket_tagged<Router>> initiator_socket; | ||||
|  | ||||
|   SC_CTOR(Router) | ||||
|   : target_socket("target_socket") | ||||
|   , initiator_socket("socket", N_TARGETS) | ||||
|   { | ||||
|     // Register callbacks for incoming interface method calls | ||||
|     target_socket.register_b_transport(       this, &Router::b_transport); | ||||
|     target_socket.register_get_direct_mem_ptr(this, &Router::get_direct_mem_ptr); | ||||
|     target_socket.register_transport_dbg(     this, &Router::transport_dbg); | ||||
|  | ||||
|     for (unsigned int i = 0; i < N_TARGETS; i++) | ||||
|     { | ||||
|       char txt[20]; | ||||
|       sprintf(txt, "socket_%d", i); | ||||
|  | ||||
|       // ********************************************* | ||||
|       // Register callbacks for incoming interface method calls, including tags | ||||
|       // ********************************************* | ||||
|       initiator_socket[i].register_invalidate_direct_mem_ptr(this, &Router::invalidate_direct_mem_ptr, i); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // **************** | ||||
|   // FORWARD PATH | ||||
|   // **************** | ||||
|  | ||||
|   // TLM-2 blocking transport method | ||||
|   virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) | ||||
|   { | ||||
|     sc_dt::uint64 address = trans.get_address(); | ||||
|     sc_dt::uint64 masked_address; | ||||
|     unsigned int target_nr = decode_address( address, masked_address); | ||||
|  | ||||
|     // Modify address within transaction | ||||
|     trans.set_address( masked_address ); | ||||
|  | ||||
|     // Forward transaction to appropriate target | ||||
|     initiator_socket[target_nr]->b_transport( trans, delay ); | ||||
|   } | ||||
|  | ||||
|   // TLM-2 forward DMI method | ||||
|   virtual bool get_direct_mem_ptr(tlm::tlm_generic_payload& trans, | ||||
|                                   tlm::tlm_dmi& dmi_data) | ||||
|   { | ||||
|     sc_dt::uint64 masked_address; | ||||
|     unsigned int target_nr = decode_address( trans.get_address(), masked_address ); | ||||
|     trans.set_address( masked_address ); | ||||
|  | ||||
|     bool status = initiator_socket[target_nr]->get_direct_mem_ptr( trans, dmi_data ); | ||||
|  | ||||
|     // Calculate DMI address of target in system address space | ||||
|     dmi_data.set_start_address( compose_address( target_nr, dmi_data.get_start_address() )); | ||||
|     dmi_data.set_end_address  ( compose_address( target_nr, dmi_data.get_end_address() )); | ||||
|  | ||||
|     return status; | ||||
|   } | ||||
|  | ||||
|   // TLM-2 debug transaction method | ||||
|   virtual unsigned int transport_dbg(tlm::tlm_generic_payload& trans) | ||||
|   { | ||||
|     sc_dt::uint64 masked_address; | ||||
|     unsigned int target_nr = decode_address( trans.get_address(), masked_address ); | ||||
|     trans.set_address( masked_address ); | ||||
|  | ||||
|     // Forward debug transaction to appropriate target | ||||
|     return initiator_socket[target_nr]->transport_dbg( trans ); | ||||
|   } | ||||
|  | ||||
|   // **************** | ||||
|   // BACKWARD PATH | ||||
|   // **************** | ||||
|  | ||||
|   // ************************** | ||||
|   // Tagged backward DMI method | ||||
|   // ************************** | ||||
|  | ||||
|   virtual void invalidate_direct_mem_ptr(int id, | ||||
|                                          sc_dt::uint64 start_range, | ||||
|                                          sc_dt::uint64 end_range) | ||||
|   { | ||||
|     // Reconstruct address range in system memory map | ||||
|     sc_dt::uint64 bw_start_range = compose_address( id, start_range ); | ||||
|     sc_dt::uint64 bw_end_range   = compose_address( id, end_range ); | ||||
|     target_socket->invalidate_direct_mem_ptr(bw_start_range, bw_end_range); | ||||
|   } | ||||
|  | ||||
|   // **************** | ||||
|   // ROUTER INTERNALS | ||||
|   // **************** | ||||
|  | ||||
|   // Simple fixed address decoding | ||||
|   inline unsigned int decode_address( sc_dt::uint64 address, sc_dt::uint64& masked_address ) | ||||
|   { | ||||
|     unsigned int target_nr = static_cast<unsigned int>( (address >> 8) & 0x3 ); | ||||
|     masked_address = address & 0xFF; | ||||
|     return target_nr; | ||||
|   } | ||||
|  | ||||
|   inline sc_dt::uint64 compose_address( unsigned int target_nr, sc_dt::uint64 address) | ||||
|   { | ||||
|     return (target_nr << 8) | (address & 0xFF); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										18
									
								
								components/router_example.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								components/router_example.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| /* | ||||
|  * router_example.cpp | ||||
|  * | ||||
|  *  Created on: 02.12.2018 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
|  | ||||
| #include "top.h" | ||||
|  | ||||
| int sc_main(int argc, char* argv[]) | ||||
| { | ||||
|   Top top("top"); | ||||
|   sc_start(); | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										102
									
								
								components/target.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								components/target.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| /* | ||||
|  * target.cpp | ||||
|  * | ||||
|  *  Created on: 02.12.2018 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #include "target.h" | ||||
|  | ||||
| void Memory::b_transport(tlm::tlm_generic_payload& trans, sc_time& delay)   { | ||||
|     tlm::tlm_command cmd = trans.get_command(); | ||||
|     sc_dt::uint64    adr = trans.get_address() / 4; | ||||
|     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(); | ||||
|  | ||||
|     // Obliged to check address range and check for unsupported features, | ||||
|     //   i.e. byte enables, streaming, and bursts | ||||
|     // Can ignore extensions | ||||
|  | ||||
|     // Generate the appropriate error response | ||||
|     if (adr >= SIZE) { | ||||
|       trans.set_response_status( tlm::TLM_ADDRESS_ERROR_RESPONSE ); | ||||
|       return; | ||||
|     } | ||||
|     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; | ||||
|     } | ||||
|  | ||||
|     wait(delay); | ||||
|     delay = SC_ZERO_TIME; | ||||
|  | ||||
|     // Obliged to implement read and write commands | ||||
|     if ( cmd == tlm::TLM_READ_COMMAND ) | ||||
|       memcpy(ptr, &mem[adr], len); | ||||
|     else if ( cmd == tlm::TLM_WRITE_COMMAND ) | ||||
|       memcpy(&mem[adr], ptr, len); | ||||
|  | ||||
|     // Set DMI hint to indicated that DMI is supported | ||||
|     trans.set_dmi_allowed(true); | ||||
|  | ||||
|     // Obliged to set response status to indicate successful completion | ||||
|     trans.set_response_status( tlm::TLM_OK_RESPONSE ); | ||||
|   } | ||||
|  | ||||
| bool Memory::get_direct_mem_ptr(tlm::tlm_generic_payload& trans, | ||||
|                                 tlm::tlm_dmi& dmi_data) | ||||
| { | ||||
|   // Permit read and write access | ||||
|   dmi_data.allow_read_write(); | ||||
|  | ||||
|   // Set other details of DMI region | ||||
|   dmi_data.set_dmi_ptr( reinterpret_cast<unsigned char*>( &mem[0] ) ); | ||||
|   dmi_data.set_start_address( 0 ); | ||||
|   dmi_data.set_end_address( SIZE*4-1 ); | ||||
|   dmi_data.set_read_latency( LATENCY ); | ||||
|   dmi_data.set_write_latency( LATENCY ); | ||||
|  | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| Memory::Memory(sc_core::sc_module_name nm) | ||||
| : socket("socket"), LATENCY(10, SC_NS) | ||||
| { | ||||
|   // Register callbacks for incoming interface method calls | ||||
|   socket.register_b_transport(       this, &Memory::b_transport); | ||||
|   socket.register_get_direct_mem_ptr(this, &Memory::get_direct_mem_ptr); | ||||
|   socket.register_transport_dbg(     this, &Memory::transport_dbg); | ||||
|  | ||||
|   // Initialize memory with random data | ||||
|   for (int i = 0; i < SIZE; i++) | ||||
|     mem[i] = 0xAA000000 | (mem_nr << 20) | (rand() % 256); | ||||
|  | ||||
|   ++mem_nr; | ||||
| } | ||||
|  | ||||
| // TLM-2 debug transaction method | ||||
| unsigned int Memory::transport_dbg(tlm::tlm_generic_payload& trans) | ||||
| { | ||||
|   tlm::tlm_command cmd = trans.get_command(); | ||||
|   sc_dt::uint64    adr = trans.get_address() / 4; | ||||
|   unsigned char*   ptr = trans.get_data_ptr(); | ||||
|   unsigned int     len = trans.get_data_length(); | ||||
|  | ||||
|   // Calculate the number of bytes to be actually copied | ||||
|   unsigned int num_bytes = (len < (SIZE - adr) * 4) ? len : (SIZE - adr) * 4; | ||||
|  | ||||
|   if ( cmd == tlm::TLM_READ_COMMAND ) | ||||
|     memcpy(ptr, &mem[adr], num_bytes); | ||||
|   else if ( cmd == tlm::TLM_WRITE_COMMAND ) | ||||
|     memcpy(&mem[adr], ptr, num_bytes); | ||||
|  | ||||
|   return num_bytes; | ||||
| } | ||||
|  | ||||
|  | ||||
							
								
								
									
										46
									
								
								components/target.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								components/target.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| #ifndef TARGET_H | ||||
| #define TARGET_H | ||||
|  | ||||
| // Needed for the simple_target_socket | ||||
| #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_target_socket.h" | ||||
|  | ||||
|  | ||||
| // Target module representing a simple memory | ||||
|  | ||||
| struct Memory: sc_module | ||||
| { | ||||
|   // TLM-2 socket, defaults to 32-bits wide, base protocol | ||||
|   tlm_utils::simple_target_socket<Memory> socket; | ||||
|  | ||||
|   enum { SIZE = 256 }; | ||||
|   const sc_time LATENCY; | ||||
|  | ||||
|   SC_HAS_PROCESS(Memory); | ||||
|  | ||||
|   Memory(sc_core::sc_module_name nm); | ||||
|  | ||||
| protected: | ||||
|   // TLM-2 blocking transport method | ||||
|   void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ); | ||||
|  | ||||
|   // TLM-2 forward DMI method | ||||
|   bool get_direct_mem_ptr(tlm::tlm_generic_payload& trans, | ||||
|                                   tlm::tlm_dmi& dmi_data); | ||||
|   // TLM-2 debug transaction method | ||||
|   unsigned int transport_dbg(tlm::tlm_generic_payload& trans); | ||||
|  | ||||
|   int mem[SIZE]; | ||||
|   static unsigned int mem_nr; | ||||
| }; | ||||
|  | ||||
| unsigned int Memory::mem_nr = 0; | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										33
									
								
								components/top.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								components/top.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| #ifndef TOP_H | ||||
| #define TOP_H | ||||
|  | ||||
| #include "initiator.h" | ||||
| #include "target.h" | ||||
| #include "router.h" | ||||
|  | ||||
| SC_MODULE(Top) | ||||
| { | ||||
|   Initiator* initiator; | ||||
|   Router<4>* router; | ||||
|   Memory*    memory[4]; | ||||
|  | ||||
|   SC_CTOR(Top) | ||||
|   { | ||||
|     // Instantiate components | ||||
|     initiator = new Initiator("initiator"); | ||||
|     router    = new Router<4>("router"); | ||||
|     for (int i = 0; i < 4; i++) | ||||
|     { | ||||
|       char txt[20]; | ||||
|       sprintf(txt, "memory_%d", i); | ||||
|       memory[i]   = new Memory(txt); | ||||
|     } | ||||
|  | ||||
|     // Bind sockets | ||||
|     initiator->socket.bind( router->target_socket ); | ||||
|     for (int i = 0; i < 4; i++) | ||||
|       router->initiator_socket[i].bind( memory[i]->socket ); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										44
									
								
								components/tx_example.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								components/tx_example.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | ||||
| //  -*- C++ -*- <this line is for emacs to recognize it as C++ code> | ||||
| /***************************************************************************** | ||||
|  | ||||
|   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 code compiles and runs with our latest prototype for this specification | ||||
|  | ||||
| #include "txtop.h" | ||||
|  | ||||
| int sc_main (int argc , char *argv[]) | ||||
| { | ||||
|    scv_startup(); | ||||
|  | ||||
|    scv_tr_text_init(); | ||||
|    scv_tr_db db("transaction_example.txlog"); | ||||
|    scv_tr_db::set_default_db(&db); | ||||
|  | ||||
|    tx_top top("top"); | ||||
|  | ||||
|    // Accellera SystemC >=2.2 got picky about multiple drivers. | ||||
|    // Disable check for bus simulation. | ||||
|    sc_report_handler::set_actions(SC_ID_MORE_THAN_ONE_SIGNAL_DRIVER_, SC_DO_NOTHING); | ||||
|    // run the simulation | ||||
|    sc_start(1.0, SC_MS); | ||||
|  | ||||
|    return 0; | ||||
| } | ||||
|  | ||||
							
								
								
									
										140
									
								
								components/tx_example_mods.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								components/tx_example_mods.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,140 @@ | ||||
| //  -*- C++ -*- <this line is for emacs to recognize it as C++ code> | ||||
| /***************************************************************************** | ||||
|  | ||||
|   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 code compiles and runs with our latest prototype for this specification | ||||
|  | ||||
| #include "tx_example_mods.h" | ||||
|  | ||||
| rw_task_if::data_t rw_pipelined_transactor::read(const rw_task_if::addr_t*  | ||||
| addr) { | ||||
|    addr_phase.lock(); | ||||
|    scv_tr_handle h = read_gen.begin_transaction(*addr); | ||||
|  | ||||
|    scv_tr_handle h1 = addr_gen.begin_transaction(*addr,"addr_phase",h); | ||||
|    wait(clk->posedge_event()); | ||||
|    bus_addr = *addr; | ||||
|    addr_req = 1; | ||||
|    wait(addr_ack->posedge_event()); | ||||
|    wait(clk->negedge_event()); | ||||
|    addr_req = 0; | ||||
|    wait(addr_ack->negedge_event()); | ||||
|    addr_gen.end_transaction(h1); | ||||
|    addr_phase.unlock(); | ||||
|  | ||||
|    data_phase.lock(); | ||||
|    scv_tr_handle h2 = data_gen.begin_transaction("data_phase",h); | ||||
|    wait(data_rdy->posedge_event()); | ||||
|    data_t data = bus_data.read(); | ||||
|    wait(data_rdy->negedge_event()); | ||||
|    data_gen.end_transaction(h2); | ||||
|    read_gen.end_transaction(h,data); | ||||
|    data_phase.unlock(); | ||||
|  | ||||
|    return data; | ||||
| } | ||||
|  | ||||
| void rw_pipelined_transactor::write(const write_t * req) { | ||||
|    scv_tr_handle h = write_gen.begin_transaction(req->addr); | ||||
|    // ... | ||||
|    write_gen.end_transaction(h,req->data); | ||||
| } | ||||
|  | ||||
| void test::main() { | ||||
|    // simple sequential tests | ||||
|    for (int i=0; i<3; i++) { | ||||
|      rw_task_if::addr_t addr = i; | ||||
|      rw_task_if::data_t data = transactor->read(&addr); | ||||
|      cout << "at time " << sc_time_stamp() << ": "; | ||||
|      cout << "received data : " << data << endl; | ||||
|    } | ||||
|  | ||||
|    scv_smart_ptr<rw_task_if::addr_t> addr; | ||||
|    for (int i=0; i<3; i++) { | ||||
|  | ||||
|      addr->next(); | ||||
|      rw_task_if::data_t data = transactor->read( addr->get_instance() ); | ||||
|      cout << "data for address " << *addr << " is " << data << endl; | ||||
|    } | ||||
|  | ||||
|    scv_smart_ptr<rw_task_if::write_t> write; | ||||
|    for (int i=0; i<3; i++) { | ||||
|      write->next(); | ||||
|      transactor->write( write->get_instance() ); | ||||
|      cout << "send data : " << write->data << endl; | ||||
|    } | ||||
|  | ||||
|    scv_smart_ptr<int> data; | ||||
|    scv_bag<int> distribution; | ||||
|    distribution.push(1,40); | ||||
|    distribution.push(2,60); | ||||
|    data->set_mode(distribution); | ||||
|    for (int i=0;i<3; i++) { data->next(); process(data); } | ||||
| } | ||||
|  | ||||
| void design::addr_phase() { | ||||
|    while (1) { | ||||
|      while (addr_req.read() != 1) { | ||||
|        wait(addr_req->value_changed_event()); | ||||
|      } | ||||
|      sc_uint<8> _addr = bus_addr.read(); | ||||
|      bool _rw = rw.read(); | ||||
|  | ||||
|      int cycle = rand() % 10 + 1; | ||||
|      while (cycle-- > 0) { | ||||
|        wait(clk->posedge_event()); | ||||
|      } | ||||
|  | ||||
|      addr_ack = 1; | ||||
|      wait(clk->posedge_event()); | ||||
|      addr_ack = 0; | ||||
|  | ||||
|      outstandingAddresses.push_back(_addr); | ||||
|      outstandingType.push_back(_rw); | ||||
|      cout << "at time " << sc_time_stamp() << ": "; | ||||
|      cout << "received request for memory address " << _addr << endl; | ||||
|    } | ||||
| } | ||||
|  | ||||
| void design::data_phase() { | ||||
|    while (1) { | ||||
|      while (outstandingAddresses.empty()) { | ||||
|        wait(clk->posedge_event()); | ||||
|      } | ||||
|      int cycle = rand() % 10 + 1; | ||||
|      while (cycle-- > 0) { | ||||
|        wait(clk->posedge_event()); | ||||
|      } | ||||
|      if (outstandingType.front() == 0) { | ||||
|        cout << "reading memory address " << outstandingAddresses.front() | ||||
|             << " with value " << memory[outstandingAddresses.front().to_ulong()] << endl; | ||||
|        bus_data = memory[outstandingAddresses.front().to_ulong()]; | ||||
|        data_rdy = 1; | ||||
|        wait(clk->posedge_event()); | ||||
|        data_rdy = 0; | ||||
|  | ||||
|      } else { | ||||
|        cout << "not implemented yet" << endl; | ||||
|      } | ||||
|      outstandingAddresses.pop_front(); | ||||
|      outstandingType.pop_front(); | ||||
|    } | ||||
| } | ||||
|  | ||||
							
								
								
									
										136
									
								
								components/tx_example_mods.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								components/tx_example_mods.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | ||||
| //  -*- C++ -*- <this line is for emacs to recognize it as C++ code> | ||||
| /***************************************************************************** | ||||
|  | ||||
|   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 code compiles and runs with our latest prototype for this specification | ||||
|  | ||||
| #include <scv.h> | ||||
| #include <systemc.h> | ||||
|  | ||||
| // hack to fake a true fifo_mutex | ||||
| #define fifo_mutex sc_mutex | ||||
|  | ||||
| const unsigned ram_size = 256; | ||||
|  | ||||
| class rw_task_if : virtual public sc_interface { | ||||
| public: | ||||
|    typedef sc_uint<8> addr_t; | ||||
|    typedef sc_uint<8> data_t; | ||||
|    struct write_t { | ||||
|      addr_t addr; | ||||
|      data_t data; | ||||
|    }; | ||||
|  | ||||
|    virtual data_t read(const addr_t*) = 0; | ||||
|    virtual void write(const write_t*) = 0; | ||||
| }; | ||||
|  | ||||
| SCV_EXTENSIONS(rw_task_if::write_t) { | ||||
| public: | ||||
|    scv_extensions<rw_task_if::addr_t> addr; | ||||
|    scv_extensions<rw_task_if::data_t> data; | ||||
|    SCV_EXTENSIONS_CTOR(rw_task_if::write_t) { | ||||
|      SCV_FIELD(addr); | ||||
|      SCV_FIELD(data); | ||||
|    } | ||||
| }; | ||||
|  | ||||
| class pipelined_bus_ports : public sc_module { | ||||
| public: | ||||
|    sc_in< bool > clk; | ||||
|    sc_inout< bool > rw; | ||||
|    sc_inout< bool > addr_req; | ||||
|    sc_inout< bool > addr_ack; | ||||
|    sc_inout< sc_uint<8> > bus_addr; | ||||
|    sc_inout< bool > data_rdy; | ||||
|    sc_inout< sc_uint<8> > bus_data; | ||||
|  | ||||
|    SC_CTOR(pipelined_bus_ports) | ||||
|      : clk("clk"), rw("rw"), | ||||
|        addr_req("addr_req"), | ||||
|        addr_ack("addr_ack"), bus_addr("bus_addr"), | ||||
|        data_rdy("data_rdy"), bus_data("bus_data") {} | ||||
| }; | ||||
|  | ||||
| class rw_pipelined_transactor | ||||
|    : public rw_task_if, | ||||
|      public pipelined_bus_ports { | ||||
|  | ||||
|    fifo_mutex addr_phase; | ||||
|    fifo_mutex data_phase; | ||||
|  | ||||
|    scv_tr_stream pipelined_stream; | ||||
|    scv_tr_stream addr_stream; | ||||
|    scv_tr_stream data_stream; | ||||
|    scv_tr_generator<sc_uint<8>, sc_uint<8> > read_gen; | ||||
|    scv_tr_generator<sc_uint<8>, sc_uint<8> > write_gen; | ||||
|    scv_tr_generator<sc_uint<8> > addr_gen; | ||||
|    scv_tr_generator<sc_uint<8> > data_gen; | ||||
|  | ||||
| public: | ||||
|    rw_pipelined_transactor(sc_module_name nm) : | ||||
|        pipelined_bus_ports(nm), | ||||
|        addr_phase("addr_phase"), | ||||
|        data_phase("data_phase"), | ||||
|        pipelined_stream("pipelined_stream", "transactor"), | ||||
|        addr_stream("addr_stream", "transactor"), | ||||
|        data_stream("data_stream", "transactor"), | ||||
|        read_gen("read",pipelined_stream,"addr","data"), | ||||
|        write_gen("write",pipelined_stream,"addr","data"), | ||||
|        addr_gen("addr",addr_stream,"addr"), | ||||
|        data_gen("data",data_stream,"data") | ||||
|    {} | ||||
|    virtual data_t read(const addr_t* p_addr); | ||||
|    virtual void write(const write_t * req); | ||||
| }; | ||||
| class test : public sc_module { | ||||
| public: | ||||
|    sc_port< rw_task_if > transactor; | ||||
|    SC_CTOR(test) { | ||||
|      SC_THREAD(main); | ||||
|    } | ||||
|    void main(); | ||||
| }; | ||||
|  | ||||
| class write_constraint : virtual public scv_constraint_base { | ||||
| public: | ||||
|    scv_smart_ptr<rw_task_if::write_t> write; | ||||
|    SCV_CONSTRAINT_CTOR(write_constraint) { | ||||
|      SCV_CONSTRAINT( write->addr() <= ram_size ); | ||||
|      SCV_CONSTRAINT( write->addr() != write->data() ); | ||||
|    } | ||||
| }; | ||||
|  | ||||
| inline void process(scv_smart_ptr<int> data) {} | ||||
| class design : public pipelined_bus_ports { | ||||
|    std::list< sc_uint<8> > outstandingAddresses; | ||||
|    std::list< bool > outstandingType; | ||||
|    sc_uint<8>  memory[ram_size]; | ||||
|  | ||||
| public: | ||||
|    SC_HAS_PROCESS(design); | ||||
|    design(sc_module_name nm) : pipelined_bus_ports(nm) { | ||||
|      for (unsigned i=0; i<ram_size; ++i) { memory[i] = i; } | ||||
|      SC_THREAD(addr_phase); | ||||
|      SC_THREAD(data_phase); | ||||
|    } | ||||
|    void addr_phase(); | ||||
|    void data_phase(); | ||||
| }; | ||||
							
								
								
									
										49
									
								
								components/txtop.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								components/txtop.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| /* | ||||
|  * top1.cpp | ||||
|  * | ||||
|  *  Created on: 02.12.2018 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #include "txtop.h" | ||||
| using namespace sc_core; | ||||
|  | ||||
| tx_top::tx_top(sc_core::sc_module_name nm) | ||||
| : sc_module(nm) | ||||
| , clk("clk", 20.0, SC_NS, 0.5 ,0.0, SC_NS, true) | ||||
| , rw("rw") | ||||
| , addr_req("addr_reg") | ||||
| , addr_ack("addr_ack") | ||||
| , bus_addr("bus_addr") | ||||
| , data_rdy("data_rdy") | ||||
| , bus_data("bus_data") | ||||
| , t("t") | ||||
| , tr("tr") | ||||
| , duv("duv") | ||||
| { | ||||
|     // TODO Auto-generated constructor stub | ||||
|     // connect them up | ||||
|     t.transactor(tr); | ||||
|  | ||||
|     tr.clk(clk); | ||||
|     tr.rw(rw); | ||||
|     tr.addr_req(addr_req); | ||||
|     tr.addr_ack(addr_ack); | ||||
|     tr.bus_addr(bus_addr); | ||||
|     tr.data_rdy(data_rdy); | ||||
|     tr.bus_data(bus_data); | ||||
|  | ||||
|     duv.clk(clk); | ||||
|     duv.rw(rw); | ||||
|     duv.addr_req(addr_req); | ||||
|     duv.addr_ack(addr_ack); | ||||
|     duv.bus_addr(bus_addr); | ||||
|     duv.data_rdy(data_rdy); | ||||
|     duv.bus_data(bus_data); | ||||
|  | ||||
| } | ||||
|  | ||||
| tx_top::~tx_top() { | ||||
|     // TODO Auto-generated destructor stub | ||||
| } | ||||
|  | ||||
							
								
								
									
										31
									
								
								components/txtop.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								components/txtop.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| /* | ||||
|  * top1.h | ||||
|  * | ||||
|  *  Created on: 02.12.2018 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #ifndef TXTOP_H_ | ||||
| #define TXTOP_H_ | ||||
|  | ||||
| #include "tx_example_mods.h" | ||||
| #include <systemc> | ||||
|  | ||||
| class tx_top: public sc_core::sc_module { | ||||
| public: | ||||
|     tx_top(sc_core::sc_module_name nm); | ||||
|     virtual ~tx_top(); | ||||
|     sc_core::sc_clock clk; | ||||
|     sc_core::sc_signal< bool > rw; | ||||
|     sc_core::sc_signal< bool > addr_req; | ||||
|     sc_core::sc_signal< bool > addr_ack; | ||||
|     sc_core::sc_signal< sc_dt::sc_uint<8> > bus_addr; | ||||
|     sc_core::sc_signal< bool > data_rdy; | ||||
|     sc_core::sc_signal< sc_dt::sc_uint<8> > bus_data; | ||||
|     test t; | ||||
|     rw_pipelined_transactor tr; | ||||
|     design duv; | ||||
|  | ||||
| }; | ||||
|  | ||||
| #endif /* TXTOP_H_ */ | ||||
		Reference in New Issue
	
	Block a user