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