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