gem5  v21.2.1.1
fifo.hh
Go to the documentation of this file.
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 #ifndef __SYSTEMC_EXT_TLM_CORE_1_REQ_RSP_CHANNELS_FIFO_FIFO_HH__
21 #define __SYSTEMC_EXT_TLM_CORE_1_REQ_RSP_CHANNELS_FIFO_FIFO_HH__
22 
23 //
24 // This implements put, get and peek
25 //
26 // It also implements 0 and infinite size fifos - but the size
27 // zero fifos aren't rendezvous like zero length fifos, they simply are both
28 // full and empty at the same time.
29 //
30 // The size can be dynamically changed using the resize interface
31 //
32 // To get an infinite fifo use a -ve size in the constructor.
33 // The absolute value of the size is taken as the starting size of the
34 // actual physical buffer.
35 //
36 
37 #include "../../interfaces/fifo_ifs.hh"
38 #include "circular_buffer.hh"
39 
40 namespace tlm
41 {
42 
43 template <typename T>
44 class tlm_fifo : public virtual tlm_fifo_get_if<T>,
45  public virtual tlm_fifo_put_if<T>, public sc_core::sc_prim_channel
46 {
47  public:
48  // Constructors.
49  explicit tlm_fifo(int size_=1) :
51  {
52  init(size_);
53  }
54 
55  explicit tlm_fifo(const char *name_, int size_=1) :
56  sc_core::sc_prim_channel(name_)
57  {
58  init(size_);
59  }
60 
61  // Destructor..
62  virtual ~tlm_fifo() {}
63 
64  // Tlm get interface.
65  T get(tlm_tag<T> * =nullptr);
66 
67  bool nb_get(T &);
68  bool nb_can_get(tlm_tag<T> * =nullptr) const;
69  const sc_core::sc_event &
70  ok_to_get(tlm_tag<T> * =nullptr) const
71  {
72  return m_data_written_event;
73  }
74 
75  // Tlm peek interface.
76  T peek(tlm_tag<T> * =nullptr) const;
77 
78  bool nb_peek(T &) const;
79  bool nb_can_peek(tlm_tag<T> * =nullptr) const;
80  const sc_core::sc_event &
81  ok_to_peek(tlm_tag<T> * =nullptr) const
82  {
84  }
85 
86  // Tlm put interface.
87  void put(const T &);
88 
89  bool nb_put(const T &);
90  bool nb_can_put(tlm_tag<T> * =nullptr) const;
91  const sc_core::sc_event &
92  ok_to_put(tlm_tag<T> * =nullptr) const
93  {
94  return m_data_read_event;
95  }
96 
97  // Resize if.
98  void nb_expand(unsigned int n=1);
99  void nb_unbound(unsigned int n=16);
100 
101  bool nb_reduce(unsigned int n=1);
102  bool nb_bound(unsigned int n);
103 
104  // Debug interface.
105  bool nb_peek(T &, int n) const;
106  bool nb_poke(const T &, int n=0);
107 
108  int used() const { return m_num_readable - m_num_read; }
109  int size() const { return m_size; }
110 
111  void
112  debug() const
113  {
114  if (is_empty())
115  std::cout << "empty" << std::endl;
116  if (is_full())
117  std::cout << "full" << std::endl;
118 
119  std::cout << "size " << size() << " - " << used() << " used "
120  << std::endl;
121  std::cout << "readable " << m_num_readable << std::endl;
122  std::cout << "written/read " << m_num_written << "/" << m_num_read
123  << std::endl;
124  }
125 
126  // Support functions.
127  static const char * const kind_string;
128  const char *kind() const { return kind_string; }
129 
130  protected:
132  read_event(tlm_tag<T> * =nullptr)
133  {
134  return m_data_read_event;
135  }
136 
137  void update();
138  void init(int);
139 
140  circular_buffer<T> buffer;
141 
142  int m_size; // logical size of fifo
143 
144  int m_num_readable; // #samples readable
145  int m_num_read; // #samples read during this delta cycle
146  int m_num_written; // #samples written during this delta cycle
147  bool m_expand; // has an expand occurred during this delta cycle ?
148  // #samples read without notify during this delta cycle
150 
153 
154  private:
155  // disabled
156  tlm_fifo(const tlm_fifo<T> &);
157  tlm_fifo &operator = (const tlm_fifo<T> &);
158 
159  //
160  // use nb_can_get() and nb_can_put() rather than the following two
161  // private functions
162  //
163 
164  bool is_empty() const { return used() == 0; }
165 
166  bool
167  is_full() const
168  {
169  if (size() < 0)
170  return false;
171  else
172  return size() <= m_num_readable + m_num_written;
173  }
174 };
175 
176 template <typename T>
177 const char *const tlm_fifo<T>::kind_string = "tlm_fifo";
178 
179 /******************************************************************
180 //
181 // init and update
182 //
183 ******************************************************************/
184 
185 template <typename T>
186 inline void
187 tlm_fifo<T>::init(int size_)
188 {
189  if (size_ > 0) {
190  buffer.resize( size_ );
191  } else if (size_ < 0) {
192  buffer.resize(-size_);
193  } else {
194  buffer.resize(16);
195  }
196 
197  m_size = size_;
198  m_num_readable = 0;
199  m_num_read = 0;
200  m_num_written = 0;
201  m_expand = false;
202  m_num_read_no_notify = false;
203 }
204 
205 template <typename T>
206 inline void
208 {
209  if (m_num_read > m_num_read_no_notify || m_expand) {
210  m_data_read_event.notify(sc_core::SC_ZERO_TIME);
211  }
212 
213  if (m_num_written > 0) {
214  m_data_written_event.notify(sc_core::SC_ZERO_TIME);
215  }
216 
217  m_expand = false;
218  m_num_read = 0;
219  m_num_written = 0;
220  m_num_readable = buffer.used();
221  m_num_read_no_notify = 0;
222 }
223 
224 } // namespace tlm
225 
226 #include "fifo_peek.hh"
227 #include "fifo_put_get.hh"
228 #include "fifo_resize.hh"
229 
230 #endif /* __SYSTEMC_EXT_TLM_CORE_1_REQ_RSP_CHANNELS_FIFO_FIFO_HH__ */
tlm::tlm_fifo::tlm_fifo
tlm_fifo(int size_=1)
Definition: fifo.hh:83
tlm::tlm_fifo::m_expand
bool m_expand
Definition: fifo.hh:181
fifo_put_get.hh
tlm::tlm_fifo::ok_to_put
const sc_core::sc_event & ok_to_put(tlm_tag< T > *=nullptr) const
Definition: fifo.hh:126
tlm::tlm_fifo::nb_put
bool nb_put(const T &)
Definition: fifo_put_get.hh:104
tlm::tlm_fifo::is_empty
bool is_empty() const
Definition: fifo.hh:198
tlm::tlm_fifo::~tlm_fifo
virtual ~tlm_fifo()
Definition: fifo.hh:96
fifo_peek.hh
sc_core
Definition: messages.cc:31
tlm::tlm_fifo::buffer
circular_buffer< T > buffer
Definition: fifo.hh:174
sc_core::SC_ZERO_TIME
const sc_time SC_ZERO_TIME
Definition: sc_time.cc:290
tlm::tlm_fifo::nb_unbound
void nb_unbound(unsigned int n=16)
Definition: fifo_resize.hh:57
tlm::tlm_fifo::operator=
tlm_fifo & operator=(const tlm_fifo< T > &)
tlm::tlm_fifo::nb_can_put
bool nb_can_put(tlm_tag< T > *=nullptr) const
Definition: fifo_put_get.hh:123
tlm::tlm_fifo::kind_string
static const char *const kind_string
Definition: fifo.hh:161
tlm::tlm_fifo::get
T get(tlm_tag< T > *=nullptr)
Definition: fifo_put_get.hh:46
tlm::tlm_fifo::nb_can_get
bool nb_can_get(tlm_tag< T > *=nullptr) const
Definition: fifo_put_get.hh:77
fifo_resize.hh
tlm::tlm_fifo::m_data_read_event
sc_core::sc_event m_data_read_event
Definition: fifo.hh:185
tlm::tlm_fifo::nb_get
bool nb_get(T &)
Definition: fifo_put_get.hh:61
tlm::tlm_fifo::ok_to_peek
const sc_core::sc_event & ok_to_peek(tlm_tag< T > *=nullptr) const
Definition: fifo.hh:115
tlm::tlm_tag
Definition: tag.hh:44
tlm::tlm_fifo::m_size
int m_size
Definition: fifo.hh:176
sc_core::sc_event
Definition: sc_event.hh:169
tlm::tlm_fifo::init
void init(int)
Definition: fifo.hh:204
tlm::tlm_fifo::ok_to_get
const sc_core::sc_event & ok_to_get(tlm_tag< T > *=nullptr) const
Definition: fifo.hh:104
sc_core::sc_prim_channel::sc_prim_channel
sc_prim_channel()
Definition: sc_prim.cc:44
tlm::tlm_fifo::nb_bound
bool nb_bound(unsigned int n)
Definition: fifo_resize.hh:82
tlm::tlm_fifo::m_num_read_no_notify
int m_num_read_no_notify
Definition: fifo.hh:183
tlm::tlm_fifo::update
void update()
Definition: fifo.hh:224
sc_core::sc_gen_unique_name
const char * sc_gen_unique_name(const char *seed)
Definition: sc_module.cc:820
tlm
Definition: analysis_fifo.hh:27
tlm::tlm_fifo::read_event
sc_core::sc_event & read_event(tlm_tag< T > *=nullptr)
Definition: fifo.hh:166
tlm::tlm_fifo::nb_can_peek
bool nb_can_peek(tlm_tag< T > *=nullptr) const
Definition: fifo_peek.hh:85
tlm::tlm_fifo::m_num_read
int m_num_read
Definition: fifo.hh:179
tlm::tlm_fifo::m_data_written_event
sc_core::sc_event m_data_written_event
Definition: fifo.hh:186
tlm::tlm_fifo::is_full
bool is_full() const
Definition: fifo.hh:201
tlm::tlm_fifo::debug
void debug() const
Definition: fifo.hh:146
tlm::tlm_fifo::nb_peek
bool nb_peek(T &) const
Definition: fifo_peek.hh:57
gem5::ArmISA::n
Bitfield< 31 > n
Definition: misc_types.hh:456
sc_core::sc_prim_channel
Definition: sc_prim.hh:50
tlm::tlm_fifo
Definition: fifo.hh:61
tlm::tlm_fifo::kind
const char * kind() const
Definition: fifo.hh:162
tlm::tlm_fifo::m_num_readable
int m_num_readable
Definition: fifo.hh:178
tlm::tlm_fifo::nb_poke
bool nb_poke(const T &, int n=0)
Definition: fifo_peek.hh:92
circular_buffer.hh
tlm::tlm_fifo::size
int size() const
Definition: fifo.hh:143
tlm::tlm_fifo::nb_reduce
bool nb_reduce(unsigned int n=1)
Definition: fifo_resize.hh:71
tlm::tlm_fifo::peek
T peek(tlm_tag< T > *=nullptr) const
Definition: fifo_peek.hh:45
tlm::tlm_fifo::nb_expand
void nb_expand(unsigned int n=1)
Definition: fifo_resize.hh:46
tlm::tlm_fifo::used
int used() const
Definition: fifo.hh:142
tlm::tlm_fifo::put
void put(const T &)
Definition: fifo_put_get.hh:86
tlm::tlm_fifo::m_num_written
int m_num_written
Definition: fifo.hh:180

Generated on Wed May 4 2022 12:14:05 for gem5 by doxygen 1.8.17