1 2// Unit test for tlm_generic_payload update_original_from() method 3 4#include <iomanip> 5 6#define SC_INCLUDE_DYNAMIC_PROCESSES 7 8#include "systemc" 9using namespace sc_core; 10using namespace sc_dt; 11using namespace std; 12 13#include "tlm.h" 14#include "tlm_utils/simple_initiator_socket.h" 15#include "tlm_utils/simple_target_socket.h" 16 17#include "mm.h" 18 19struct my_extension: tlm::tlm_extension<my_extension> 20{ 21 my_extension() {} 22 23 virtual tlm_extension_base* clone() const 24 { 25 my_extension* ext = new my_extension; 26 ext->len = len; 27 ext->bel = bel; 28 ext->ptr = ptr; 29 ext->byt = byt; 30 return ext; 31 } 32 33 virtual void copy_from(tlm_extension_base const &ext) 34 { 35 len = static_cast<my_extension const &>(ext).len; 36 bel = static_cast<my_extension const &>(ext).bel; 37 ptr = static_cast<my_extension const &>(ext).ptr; 38 byt = static_cast<my_extension const &>(ext).byt; 39 } 40 41 unsigned int len; 42 unsigned int bel; 43 unsigned char* ptr; 44 unsigned char* byt; 45}; 46 47 48struct Initiator: sc_module 49{ 50 tlm_utils::simple_initiator_socket<Initiator> socket; 51 52 typedef unsigned char uchar; 53 54 SC_CTOR(Initiator) 55 : socket("socket") 56 { 57 SC_THREAD(thread_process); 58 data = new uchar[32]; 59 byte_enable = new uchar[32]; 60 } 61 62 void thread_process() 63 { 64 tlm::tlm_generic_payload* trans; 65 sc_time delay = SC_ZERO_TIME; 66 67 for (int i = 0; i < 1000000; i++) 68 { 69 int addr = 0; 70 tlm::tlm_command cmd = static_cast<tlm::tlm_command>(rand() % 2); 71 72 unsigned int len = rand() % 33; 73 unsigned int bel = rand() % (len + 1); 74 75 // Fix sizes when performing a speed test 76 //cmd = tlm::TLM_READ_COMMAND; 77 //len = 32; 78 //bel = 8; 79 80 81 for (unsigned int i = 0; i < len; i++) 82 if (cmd == tlm::TLM_WRITE_COMMAND) 83 { 84 data[i] = rand() % 256; 85 } 86 else 87 data[i] = 0x99; 88 89 trans = m_mm.allocate(); 90 trans->acquire(); 91 92 trans->set_command( cmd ); 93 trans->set_address( addr ); 94 trans->set_data_ptr( data ); 95 trans->set_data_length( len ); 96 trans->set_streaming_width( len ); 97 98 trans->set_byte_enable_length( bel ); 99 100 for (unsigned int i = 0; i < bel; i++) 101 { 102 byte_enable[i] = (rand() % 2) ? 0xff : 0; 103 } 104 105 if (bel) 106 trans->set_byte_enable_ptr( byte_enable ); 107 else 108 trans->set_byte_enable_ptr( 0 ); 109 110 trans->set_dmi_allowed( false ); 111 trans->set_response_status( tlm::TLM_INCOMPLETE_RESPONSE ); 112 113 // Add sticky extension diagnostics 114 my_extension* ext; 115 trans->get_extension(ext); 116 if (!ext) 117 { 118 ext = new my_extension; 119 trans->set_extension(ext); 120 } 121 122 ext->len = len; 123 ext->bel = bel; 124 ext->ptr = data; 125 ext->byt = byte_enable; 126 127 socket->b_transport( *trans, delay ); // Blocking transport call 128 129 if ( trans->is_response_error() ) 130 SC_REPORT_ERROR("TLM-2", "Response error from b_transport"); 131 132 //cout << "cmd = " << cmd << ", len = " << len << ", bel = " << bel << endl; 133 //cout << hex << setw(2) << setfill('0') << (unsigned int)data[i]; 134 135 if (cmd == tlm::TLM_READ_COMMAND) 136 { 137 for (unsigned int i = 0; i < len; i++) 138 if (bel) 139 if (byte_enable[i % bel]) 140 sc_assert( data[i] == ext->ptr[i] ); 141 else 142 sc_assert( data[i] == 0x99 ); 143 else 144 sc_assert( data[i] == ext->ptr[i] ); 145 146 } 147 trans->release(); 148 } 149 } 150 151 mm m_mm; // Memory manager 152 unsigned char* data; // 32 bytes 153 unsigned char* byte_enable; 154}; 155 156 157struct Interconnect: sc_module 158{ 159 tlm_utils::simple_target_socket <Interconnect> targ_socket; 160 tlm_utils::simple_initiator_socket<Interconnect> init_socket; 161 162 SC_CTOR(Interconnect) 163 : targ_socket("targ_socket") 164 , init_socket("init_socket") 165 { 166 targ_socket.register_b_transport(this, &Interconnect::b_transport); 167 } 168 169 virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) 170 { 171 unsigned int bel = trans.get_byte_enable_length(); 172 173 trans2.set_data_ptr( data ); 174 if (bel) 175 trans2.set_byte_enable_ptr( byte_enable ); 176 trans2.deep_copy_from(trans); 177 178 init_socket->b_transport( trans2, delay ); 179 180 trans.update_original_from( trans2 ); 181 } 182 183 tlm::tlm_generic_payload trans2; 184 unsigned char data[32]; 185 unsigned char byte_enable[32]; 186}; 187 188 189struct Target: sc_module 190{ 191 tlm_utils::simple_target_socket<Target> socket; 192 193 SC_CTOR(Target) 194 : socket("socket") 195 { 196 socket.register_b_transport(this, &Target ::b_transport); 197 198 typedef unsigned char uchar; 199 data = new uchar[32]; 200 } 201 202 203 virtual void b_transport( tlm::tlm_generic_payload& trans, sc_time& delay ) 204 { 205 tlm::tlm_command cmd = trans.get_command(); 206 unsigned char* ptr = trans.get_data_ptr(); 207 unsigned int len = trans.get_data_length(); 208 unsigned char* byt = trans.get_byte_enable_ptr(); 209 unsigned int bel = trans.get_byte_enable_length(); 210 211 my_extension* ext; 212 trans.get_extension(ext); 213 sc_assert( ext ); 214 215 sc_assert( len == ext->len ); 216 sc_assert( bel == ext->bel ); 217 for (unsigned int i = 0; i < bel; i++) 218 sc_assert( byt[i] == ext->byt[i] ); 219 for (unsigned int i = 0; i < len; i++) 220 sc_assert( ptr[i] == ext->ptr[i] ); 221 222 if (cmd == tlm::TLM_READ_COMMAND) 223 { 224 for (unsigned int i = 0; i < len; i++) 225 { 226 data[i] = rand() % 256; 227 ptr[i] = data[i]; 228 } 229 ext->ptr = data; 230 } 231 232 trans.set_dmi_allowed( true ); 233 trans.set_response_status( tlm::TLM_OK_RESPONSE ); 234 } 235 236 unsigned char* data; // 32 bytes 237}; 238 239 240SC_MODULE(Top) 241{ 242 Initiator *initiator; 243 Interconnect *interconnect; 244 Target *target; 245 246 SC_CTOR(Top) 247 { 248 // Instantiate components 249 initiator = new Initiator ("initiator"); 250 interconnect = new Interconnect("interconnect"); 251 target = new Target ("target"); 252 253 // One initiator is bound directly to one target with no intervening bus 254 255 // Bind initiator socket to target socket 256 initiator ->socket .bind( interconnect->targ_socket ); 257 interconnect ->init_socket.bind( target ->socket ); 258 } 259}; 260 261 262int sc_main(int argc, char* argv[]) 263{ 264 cout << "Unit test for update_original_from(). Should remain silent\n"; 265 266 Top top("top"); 267 sc_start(); 268 return 0; 269} 270 271