sc_fifo.hh (13327:2b5b3da7a732) sc_fifo.hh (13407:7915c998957c)
1/*
2 * Copyright 2018 Google, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * Authors: Gabe Black
28 */
29
30#ifndef __SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__
31#define __SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__
32
33#include <list>
34#include <string>
35
36#include "../core/sc_module.hh" // for sc_gen_unique_name
37#include "../core/sc_prim.hh"
38#include "../utils/sc_report_handler.hh"
39#include "messages.hh"
40#include "sc_fifo_in_if.hh"
41#include "sc_fifo_out_if.hh"
42
43namespace sc_core
44{
45
46class sc_port_base;
47class sc_event;
48
49template <class T>
50class sc_fifo : public sc_fifo_in_if<T>,
51 public sc_fifo_out_if<T>,
52 public sc_prim_channel
53{
54 public:
55 explicit sc_fifo(int size=16) :
56 sc_fifo_in_if<T>(), sc_fifo_out_if<T>(),
57 sc_prim_channel(sc_gen_unique_name("fifo")),
58 _size(size), _num_free(size), _num_available(0),
59 _readsHappened(false), _writesHappened(false),
60 _reader(NULL), _writer(NULL)
61 {}
62 explicit sc_fifo(const char *name, int size=16) :
63 sc_fifo_in_if<T>(), sc_fifo_out_if<T>(),
64 sc_prim_channel(name), _size(size), _num_free(size),
65 _num_available(0), _readsHappened(false), _writesHappened(false),
66 _reader(NULL), _writer(NULL)
67 {}
68 virtual ~sc_fifo() {}
69
70 virtual void
71 register_port(sc_port_base &port, const char *iface_type_name)
72 {
73 std::string tn(iface_type_name);
74 if (tn == typeid(sc_fifo_in_if<T>).name() ||
75 tn == typeid(sc_fifo_blocking_in_if<T>).name()) {
76 if (_reader)
77 SC_REPORT_ERROR(SC_ID_MORE_THAN_ONE_FIFO_READER_, "");
78 _reader = &port;
79 } else if (tn == typeid(sc_fifo_out_if<T>).name() ||
80 tn == typeid(sc_fifo_blocking_out_if<T>).name()) {
81 if (_writer)
82 SC_REPORT_ERROR(SC_ID_MORE_THAN_ONE_FIFO_WRITER_, "");
83 _writer = &port;
84 } else {
85 SC_REPORT_ERROR(SC_ID_BIND_IF_TO_PORT_,
86 "sc_fifo<T> port not recognized");
87 }
88 }
89
90 virtual void
91 read(T &t)
92 {
93 while (num_available() == 0)
94 sc_core::wait(_dataWriteEvent);
95 _readsHappened = true;
96 t = _entries.front();
97 _entries.pop_front();
98 _num_available--;
99 request_update();
100 }
101 virtual T
102 read()
103 {
104 T t;
105 read(t);
106 return t;
107 }
108 virtual bool
109 nb_read(T &t)
110 {
111 if (num_available()) {
112 read(t);
113 return true;
114 } else {
115 return false;
116 }
117 }
118 operator T() { return read(); }
119
120 virtual void
121 write(const T &t)
122 {
123 while (num_free() == 0)
124 sc_core::wait(_dataReadEvent);
125 _writesHappened = true;
126 _entries.emplace_back(t);
127 _num_free--;
128 request_update();
129 }
130 virtual bool
131 nb_write(const T &t)
132 {
133 if (num_free()) {
134 write(t);
135 return true;
136 } else {
137 return false;
138 }
139 }
140 sc_fifo<T> &
141 operator = (const T &t)
142 {
143 write(t);
144 return *this;
145 }
146
147 virtual const sc_event &
148 data_written_event() const
149 {
150 return _dataWriteEvent;
151 }
152 virtual const sc_event &
153 data_read_event() const
154 {
155 return _dataReadEvent;
156 }
157
158 virtual int num_available() const { return _num_available; }
159 virtual int num_free() const { return _num_free; }
160
161 virtual void
162 print(std::ostream &os=std::cout) const
163 {
164 for (typename ::std::list<T>::iterator pos = _entries.begin();
165 pos != _entries.end(); pos++) {
166 os << *pos << ::std::endl;
167 }
168 }
169 virtual void
170 dump(std::ostream &os=std::cout) const
171 {
172 os << "name = " << name() << std::endl;
173 int idx = 0;
174 for (typename ::std::list<T>::iterator pos = _entries.begin();
175 pos != _entries.end(); pos++) {
176 os << "value[" << idx++ << "] = " << *pos << ::std::endl;
177 }
178 }
179 virtual const char *kind() const { return "sc_fifo"; }
180
181 protected:
182 virtual void
183 update()
184 {
185 _num_available = _entries.size();
186 _num_free = _size - _num_available;
187 if (_writesHappened) {
188 _writesHappened = false;
189 _dataWriteEvent.notify(SC_ZERO_TIME);
190 }
191 if (_readsHappened) {
192 _readsHappened = false;
193 _dataReadEvent.notify(SC_ZERO_TIME);
194 }
195 }
196
197 private:
198 // Disabled
1/*
2 * Copyright 2018 Google, Inc.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * Authors: Gabe Black
28 */
29
30#ifndef __SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__
31#define __SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__
32
33#include <list>
34#include <string>
35
36#include "../core/sc_module.hh" // for sc_gen_unique_name
37#include "../core/sc_prim.hh"
38#include "../utils/sc_report_handler.hh"
39#include "messages.hh"
40#include "sc_fifo_in_if.hh"
41#include "sc_fifo_out_if.hh"
42
43namespace sc_core
44{
45
46class sc_port_base;
47class sc_event;
48
49template <class T>
50class sc_fifo : public sc_fifo_in_if<T>,
51 public sc_fifo_out_if<T>,
52 public sc_prim_channel
53{
54 public:
55 explicit sc_fifo(int size=16) :
56 sc_fifo_in_if<T>(), sc_fifo_out_if<T>(),
57 sc_prim_channel(sc_gen_unique_name("fifo")),
58 _size(size), _num_free(size), _num_available(0),
59 _readsHappened(false), _writesHappened(false),
60 _reader(NULL), _writer(NULL)
61 {}
62 explicit sc_fifo(const char *name, int size=16) :
63 sc_fifo_in_if<T>(), sc_fifo_out_if<T>(),
64 sc_prim_channel(name), _size(size), _num_free(size),
65 _num_available(0), _readsHappened(false), _writesHappened(false),
66 _reader(NULL), _writer(NULL)
67 {}
68 virtual ~sc_fifo() {}
69
70 virtual void
71 register_port(sc_port_base &port, const char *iface_type_name)
72 {
73 std::string tn(iface_type_name);
74 if (tn == typeid(sc_fifo_in_if<T>).name() ||
75 tn == typeid(sc_fifo_blocking_in_if<T>).name()) {
76 if (_reader)
77 SC_REPORT_ERROR(SC_ID_MORE_THAN_ONE_FIFO_READER_, "");
78 _reader = &port;
79 } else if (tn == typeid(sc_fifo_out_if<T>).name() ||
80 tn == typeid(sc_fifo_blocking_out_if<T>).name()) {
81 if (_writer)
82 SC_REPORT_ERROR(SC_ID_MORE_THAN_ONE_FIFO_WRITER_, "");
83 _writer = &port;
84 } else {
85 SC_REPORT_ERROR(SC_ID_BIND_IF_TO_PORT_,
86 "sc_fifo<T> port not recognized");
87 }
88 }
89
90 virtual void
91 read(T &t)
92 {
93 while (num_available() == 0)
94 sc_core::wait(_dataWriteEvent);
95 _readsHappened = true;
96 t = _entries.front();
97 _entries.pop_front();
98 _num_available--;
99 request_update();
100 }
101 virtual T
102 read()
103 {
104 T t;
105 read(t);
106 return t;
107 }
108 virtual bool
109 nb_read(T &t)
110 {
111 if (num_available()) {
112 read(t);
113 return true;
114 } else {
115 return false;
116 }
117 }
118 operator T() { return read(); }
119
120 virtual void
121 write(const T &t)
122 {
123 while (num_free() == 0)
124 sc_core::wait(_dataReadEvent);
125 _writesHappened = true;
126 _entries.emplace_back(t);
127 _num_free--;
128 request_update();
129 }
130 virtual bool
131 nb_write(const T &t)
132 {
133 if (num_free()) {
134 write(t);
135 return true;
136 } else {
137 return false;
138 }
139 }
140 sc_fifo<T> &
141 operator = (const T &t)
142 {
143 write(t);
144 return *this;
145 }
146
147 virtual const sc_event &
148 data_written_event() const
149 {
150 return _dataWriteEvent;
151 }
152 virtual const sc_event &
153 data_read_event() const
154 {
155 return _dataReadEvent;
156 }
157
158 virtual int num_available() const { return _num_available; }
159 virtual int num_free() const { return _num_free; }
160
161 virtual void
162 print(std::ostream &os=std::cout) const
163 {
164 for (typename ::std::list<T>::iterator pos = _entries.begin();
165 pos != _entries.end(); pos++) {
166 os << *pos << ::std::endl;
167 }
168 }
169 virtual void
170 dump(std::ostream &os=std::cout) const
171 {
172 os << "name = " << name() << std::endl;
173 int idx = 0;
174 for (typename ::std::list<T>::iterator pos = _entries.begin();
175 pos != _entries.end(); pos++) {
176 os << "value[" << idx++ << "] = " << *pos << ::std::endl;
177 }
178 }
179 virtual const char *kind() const { return "sc_fifo"; }
180
181 protected:
182 virtual void
183 update()
184 {
185 _num_available = _entries.size();
186 _num_free = _size - _num_available;
187 if (_writesHappened) {
188 _writesHappened = false;
189 _dataWriteEvent.notify(SC_ZERO_TIME);
190 }
191 if (_readsHappened) {
192 _readsHappened = false;
193 _dataReadEvent.notify(SC_ZERO_TIME);
194 }
195 }
196
197 private:
198 // Disabled
199 sc_fifo(const sc_fifo &) :
200 sc_fifo_in_if<T>(), sc_fifo_in_if<T>(), sc_prim_channel()
199 sc_fifo(const sc_fifo<T> &) : sc_fifo_in_if<T>(), sc_prim_channel()
201 {}
202 sc_fifo &operator = (const sc_fifo<T> &) { return *this; }
203
204 sc_gem5::InternalScEvent _dataReadEvent;
205 sc_gem5::InternalScEvent _dataWriteEvent;
206
207 sc_port_base *_reader;
208 sc_port_base *_writer;
209
210 int _size;
211 int _num_free;
212 int _num_available;
213 mutable std::list<T> _entries;
214 bool _readsHappened;
215 bool _writesHappened;
216};
217
218template <class T>
219inline std::ostream &
220operator << (std::ostream &os, const sc_fifo<T> &f)
221{
222 f.print(os);
223 return os;
224}
225
226} // namespace sc_core
227
228#endif //__SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__
200 {}
201 sc_fifo &operator = (const sc_fifo<T> &) { return *this; }
202
203 sc_gem5::InternalScEvent _dataReadEvent;
204 sc_gem5::InternalScEvent _dataWriteEvent;
205
206 sc_port_base *_reader;
207 sc_port_base *_writer;
208
209 int _size;
210 int _num_free;
211 int _num_available;
212 mutable std::list<T> _entries;
213 bool _readsHappened;
214 bool _writesHappened;
215};
216
217template <class T>
218inline std::ostream &
219operator << (std::ostream &os, const sc_fifo<T> &f)
220{
221 f.print(os);
222 return os;
223}
224
225} // namespace sc_core
226
227#endif //__SYSTEMC_EXT_CHANNEL_SC_FIFO_HH__