1 /*****************************************************************************
2 
3   Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4   more contributor license agreements.  See the NOTICE file distributed
5   with this work for additional information regarding copyright ownership.
6   Accellera licenses this file to you under the Apache License, Version 2.0
7   (the "License"); you may not use this file except in compliance with the
8   License.  You may obtain a copy of the License at
9 
10     http://www.apache.org/licenses/LICENSE-2.0
11 
12   Unless required by applicable law or agreed to in writing, software
13   distributed under the License is distributed on an "AS IS" BASIS,
14   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15   implied.  See the License for the specific language governing
16   permissions and limitations under the License.
17 
18  *****************************************************************************/
19 
20 //=====================================================================
21 /// @file me_traffic_generator.h
22 //
23 /// @brief traffic_generator class header
24 //
25 //=====================================================================
26 //  Authors:
27 //    Bill Bunton, ESLX
28 //    Charles Wilson, ESLX
29 //    Jack Donovan, ESLX
30 //====================================================================
31 
32 #ifndef __ME_TRAFFIC_GENERATOR_H__
33 #define __ME_TRAFFIC_GENERATOR_H__
34 
35 #include "tlm.h"                              	// TLM headers
36 #include <queue>                                // queue header from std lib
37 #include <list>
38 
39 class me_traffic_generator                       	// traffic_generator
40 : public sc_core::sc_module                    	// sc_module
41 {
42 
43 // Member Methods  ====================================================
44 
45   public:
46   //=====================================================================
47   ///  @fn me_traffic_generator
48   //
49   ///  @brief me_traffic_generator constructor
50   //
51   ///  @details
52   ///    Initializes Traffic Generator
53   //
54   //=====================================================================
55 
56   me_traffic_generator
57   ( sc_core::sc_module_name name            	  ///< module name for SC
58   , const unsigned int      ID               	  ///< initiator ID
59   , sc_dt::uint64           base_address_1    	///< first base address
60   , sc_dt::uint64           base_address_2    	///< second base address
61   );
62 
63 
64   //=============================================================================
65   ///  @fn me_traffic_generator_thread
66   //
67   ///  @brief traffic_generator processing thread
68   //
69   ///  @details
70   ///    Method actually called by SC simulator to generate and
71   ///    check traffic. Generate Writes then Reads to check the
72   ///    Writes
73   //
74   //=============================================================================
75 
76   void
77   me_traffic_generator_thread
78   ( void
79   );
80 
81   // Transaction Pool (queue)
82   class pool_c : public tlm::tlm_mm_interface {
83   public:
pool_c()84     pool_c() {
85       m_size = m_initial_size;
86       m_available = 0;
87       m_stack = new tlm::tlm_generic_payload* [m_size];
88     }
89 
~pool_c()90     ~pool_c() {
91       for(std::list<tlm::tlm_generic_payload *>::iterator
92         i = all_payloads.begin(); i != all_payloads.end(); i++) {
93         delete *i;
94       }
95       delete [] m_stack;
96     }
97 
pop()98     tlm::tlm_generic_payload *pop() {
99       tlm::tlm_generic_payload *transaction_ptr;
100       if(m_available == 0) {
101         transaction_ptr = new tlm::tlm_generic_payload(this);
102         all_payloads.push_back(transaction_ptr);
103       } else {
104         transaction_ptr = m_stack[--m_available];
105       }
106       transaction_ptr->acquire();
107       return transaction_ptr;
108     }
109 
push(tlm::tlm_generic_payload * transaction_ptr)110     void push(tlm::tlm_generic_payload *transaction_ptr) {
111       transaction_ptr->release();
112     }
113 
free(tlm::tlm_generic_payload * transaction_ptr)114     void free (tlm::tlm_generic_payload *transaction_ptr) {
115       transaction_ptr->reset();
116       if(m_available == m_size) {
117         // stack is full.  make a new one twice as big
118         m_size *= 2;
119         tlm::tlm_generic_payload
120           **new_stack = new tlm::tlm_generic_payload* [m_size];
121         for(unsigned i=0; i<m_available; i++) new_stack[i] = m_stack[i];
122         delete [] m_stack;
123         m_stack = new_stack;
124       }
125       m_stack[m_available++] = transaction_ptr;
126     }
127 
128   private:
129     tlm::tlm_generic_payload **m_stack;   /// stack of available payloads
130     std::list<tlm::tlm_generic_payload *> all_payloads;
131     unsigned m_size, m_available;
132     static const unsigned m_initial_size = 1;
133   };  // pool_c class definition
134 
135   private:
136     void do_transaction(std::string &user_command);
137     void do_load(std::istringstream &iss);
138     void do_store(std::istringstream &iss);
139     template<typename T> void do_do_load(std::istringstream &iss);
140     template<typename T> void do_do_store(std::istringstream &iss);
141 
142 
143 //=============================================================================
144 // Member Variables
145 
146   private:
147 
148   const unsigned int  m_ID;                   	    // initiator ID
149   std::string m_prompt;
150 
151   sc_dt::uint64       m_base_address_1;      	      // first base address
152   sc_dt::uint64       m_base_address_2;       	    // second base address
153 
154   pool_c        m_txn_pool;                   // transaction pool
155 
156   tlm::tlm_endianness m_endianness, m_host_endianness;
157 
158   static const int m_buffer_size = 1024;
159   unsigned char m_buffer[m_buffer_size];
160 
161   /// Synchronisation between mixed-endian traffic generators
162   static std::list<me_traffic_generator *> me_ui_waiters;
163   static sc_core::sc_event me_ui_change_event;
164 
165   public:
166 
167   /// Port for requests to the initiator
168   sc_core::sc_port<sc_core::sc_fifo_out_if <tlm::tlm_generic_payload *> > request_out_port;
169 
170   /// Port for responses from the initiator
171   sc_core::sc_port<sc_core::sc_fifo_in_if  <tlm::tlm_generic_payload *> > response_in_port;
172 };
173 #endif /* __ME_TRAFFIC_GENERATOR_H__ */
174