1 #include "WindowedFifo.h"
\r
6 WindowedFifo::WindowedFifo(char* name, unsigned size = 20) {
\r
7 //std::cout << "Create WindowedFifo." << std::endl;
\r
9 _buffer = new char[_size];
\r
15 //indicates whether Fifo is empty or full if _head == _tail
\r
17 _isHeadReserved = false;
\r
18 _isTailReserved = false;
\r
19 _name = new char[strlen(name) + 1];
\r
20 strcpy(_name, name);
\r
26 WindowedFifo::~WindowedFifo() {
\r
27 //std::cout << "Delete WindowedFifo." << std::endl;
\r
39 //std::cout << "Deleted WindowedFifo." << std::endl;
\r
45 unsigned WindowedFifo::reserve(void** dest, unsigned len) {
\r
46 char** destination = (char**)dest;
\r
47 //std::cout << "Attempt to reserve " << len << " bytes." << std::endl;
\r
49 //can only reserve once piece at a time
\r
50 if (_isHeadReserved) {
\r
55 while (unused() == 0) {
\r
59 //reserve at most as much memory as still available in the buffer
\r
60 unsigned write = (len <= _size - _use ? len : _size - _use);
\r
63 //if wrap-around in buffer: return only buffer for the
\r
64 //contiguous buffer space
\r
65 if (_head + write > _size) {
\r
66 write = _size - _head;
\r
69 _headRoom = (_head + write) == _size? 0 : _head + write;
\r
70 *destination = &(_buffer[_head]);
\r
71 _isHeadReserved = true;
\r
73 //the following comparison is unsafe in a multi-threaded
\r
74 //environment and potentially leads to race-conditions
\r
75 /*if (_headRoom == _tail) {
\r
82 //std::cout << "Reserved " << write << " bytes." << std::endl;
\r
83 _writeReserve = write;
\r
90 void WindowedFifo::release() {
\r
91 if (_isHeadReserved) {
\r
92 //std::cout << "Released " << _headRoom - _head << " bytes." << std::endl;
\r
94 _use += _writeReserve;
\r
95 _isHeadReserved = false;
\r
96 _writeEvent.notify();
\r
103 unsigned WindowedFifo::capture(void **dest, unsigned len) {
\r
104 char** destination = (char**)dest;
\r
105 //std::cout << "Attempt to capture " << len << " bytes." << std::endl;
\r
107 if (_isTailReserved) {
\r
108 //std::cout << "Only one attempt to capture allowed." << std::endl;
\r
113 while (used() == 0) {
\r
117 //capture at most as much data as available in the buffer
\r
118 unsigned read = (len <= _use ? len : _use);
\r
121 //if wrap-around in buffer: return only buffer for the
\r
122 //contiguous buffer space
\r
123 if (_tail + read> _size) {
\r
124 read = _size - _tail;
\r
127 _tailRoom = (_tail + read) == _size ? 0 : _tailRoom = _tail + read;
\r
128 *destination = &(_buffer[_tail]);
\r
129 _isTailReserved = true;
\r
132 //std::cout << "Captured " << read << " bytes." << std::endl;
\r
134 _readReserve = read;
\r
141 void WindowedFifo::consume() {
\r
142 if (_isTailReserved) {
\r
143 //std::cout << "Consumed " << _tailRoom - _tail << " bytes." << std::endl;
\r
145 _use -= _readReserve;
\r
146 _isTailReserved = false;
\r
148 _readEvent.notify();
\r
155 unsigned WindowedFifo::size() const {
\r
162 unsigned WindowedFifo::unused() const {
\r
163 return _size - _use;
\r
169 unsigned WindowedFifo::used() const {
\r
171 /*if (_headRoom > _tail) {
\r
172 return _headRoom - _tail;
\r
173 } else if (_headRoom == _tail) {
\r
174 if (_isFull == true) {
\r
180 return _headRoom + _size - _tail;*/
\r
186 char* WindowedFifo::getName() const {
\r
191 * Test the implementation
\r
194 #include <iostream>
\r
198 class producer : public sc_module
\r
201 WindowedFifo *wfifo;
\r
203 SC_HAS_PROCESS(producer);
\r
205 producer(sc_module_name name) : sc_module(name)
\r
212 for (int j = 0; j < LENGTH; j++) {
\r
213 //std::cout << "write " << i << " to Fifo. ";
\r
215 int write = wfifo->reserve((void**)&buf1, sizeof(int));
\r
217 if (write == sizeof(int)) {
\r
220 //std::cout << "used: " << std::setw(2) << wfifo->used()
\r
221 // << ", unused: " << std::setw(2) << wfifo->unused()
\r
222 // << ", size: " << std::setw(2) << wfifo->size()
\r
225 std::cout << "Not successful: " << write << std::endl;
\r
228 printf("producer returns.\n");
\r
232 class consumer : public sc_module
\r
235 WindowedFifo *wfifo;
\r
237 SC_HAS_PROCESS(consumer);
\r
239 consumer(sc_module_name name) : sc_module(name)
\r
246 for (int j = 0; j < LENGTH; j++) {
\r
248 int read = wfifo->capture((void**)&buf3, sizeof(int));
\r
249 if (read == sizeof(int)) {
\r
250 std::cout << "read " << (unsigned)*buf3 << " from WindowedFifo ";
\r
251 std::cout << "used: " << std::setw(2) << wfifo->used()
\r
252 << ", unused: " << std::setw(2) << wfifo->unused()
\r
253 << ", size: " << std::setw(2) << wfifo->size()
\r
257 std::cout << "Read nothing from WindowedFifo." << std::endl;
\r
260 printf("consumer returns.\n");
\r
264 class top : public sc_module
\r
267 WindowedFifo *wfifo_inst;
\r
268 producer *prod_inst;
\r
269 consumer *cons_inst;
\r
271 top(sc_module_name name) : sc_module(name)
\r
273 wfifo_inst = new WindowedFifo("myfifo", 4);
\r
275 prod_inst = new producer("producer");
\r
276 prod_inst->wfifo = wfifo_inst;
\r
278 cons_inst = new consumer("consumer");
\r
279 cons_inst->wfifo = wfifo_inst;
\r
283 int sc_main (int argc , char *argv[]) {
\r