--- /dev/null
+#include "Fifo.h"\r
+\r
+/**\r
+ *\r
+ */\r
+Fifo::Fifo(char* name, unsigned size = 18) {\r
+ //std::cout << "Create Fifo." << std::endl;\r
+ //except at the beginning, _head and _tail must never overlap,\r
+ //otherwise one does not know whether the buffer is full or\r
+ //empty. to have nevertheless a buffer with the given capacity,\r
+ //a buffer with one more element is allocated.\r
+ _size = size;\r
+ _buffer = new char[_size];\r
+ //_head = 0;\r
+ _use = 0;\r
+ _tail = 0;\r
+ _name = new char[strlen(name) + 1];\r
+ strcpy(_name, name);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+Fifo::~Fifo() {\r
+ //std::cout << "Delete Fifo." << std::endl;\r
+ if (_buffer) {\r
+ delete _buffer;\r
+ }\r
+ if (_name) {\r
+ delete _name;\r
+ }\r
+ _buffer = 0;\r
+ //_head = 0;\r
+ _use = 0;\r
+ _tail = 0;\r
+ _name = 0;\r
+ //std::cout << "Deleted Fifo." << std::endl;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::read(void *destination, unsigned len) {\r
+ char* buffer = (char*)destination;\r
+ unsigned read = 0;\r
+ //std::cout << "Try to read " << len << " bytes from Fifo " << _name << "." << std::endl;\r
+\r
+\r
+ while (read < len) {\r
+ while( _use < len)\r
+ wait(_writeEvent);\r
+ unsigned tocopy = (len - read <= _use ? len - read : _use);\r
+\r
+ if ((unsigned)_tail + tocopy < _size) {\r
+ memcpy(buffer, _buffer + (unsigned)_tail, tocopy);\r
+ }\r
+ else {\r
+ memcpy(buffer, _buffer + (unsigned)_tail, _size - (unsigned)_tail);\r
+ memcpy(buffer + _size - (unsigned)_tail, _buffer, tocopy - _size + (unsigned)_tail);\r
+ }\r
+\r
+ read += tocopy;\r
+ buffer += tocopy;\r
+ _tail = (_tail + tocopy) % _size;\r
+ _use -= read;\r
+ _readEvent.notify();\r
+ }\r
+\r
+ /*while (read < len) {\r
+ if (used() == 0) {\r
+ wait(_writeEvent);\r
+ } else if ((len - read) < used()) {\r
+ while (read < len) {\r
+ unsigned tocopy = (len - read + _tail >= _size) ? _size - _tail : len - read;\r
+ memcpy(buffer, _buffer + _tail, tocopy);\r
+ _tail = (_tail + tocopy) % _size;\r
+ read += tocopy;\r
+ buffer += tocopy;\r
+ }\r
+ _readEvent.notify();\r
+ } else {\r
+ *buffer++ = *(_buffer + _tail % _size);\r
+ _tail = (_tail + 1) % _size;\r
+ read++;\r
+ _readEvent.notify();\r
+ }\r
+ }*/\r
+\r
+ //std::cout << "Read " << read << " bytes from Fifo " << _name << "." << std::endl;\r
+ return read;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::write(const void *source, unsigned len) {\r
+ char* buffer = (char*)source;\r
+ unsigned write = 0;\r
+ unsigned head = (_tail + _use) % _size;\r
+ //std::cout << "Try to write " << len << " bytes to Fifo " << _name << std::endl;\r
+\r
+ while (write < len) {\r
+ while (unused() < len) \r
+ wait(_readEvent);\r
+ unsigned tocopy = (len - write <= unused() ? len - write : unused());\r
+\r
+ if (head + tocopy < _size) {\r
+ memcpy(_buffer + head, buffer, tocopy);\r
+ }\r
+ else {\r
+ memcpy(_buffer + head, buffer, _size - head);\r
+ memcpy(_buffer, buffer + _size - head, tocopy - _size + head);\r
+ }\r
+\r
+ write += tocopy;\r
+ buffer += tocopy;\r
+ head = (head + tocopy) % _size;\r
+ _use += write;\r
+ _writeEvent.notify();\r
+ }\r
+\r
+ /* while (write < len) {\r
+ if (unused() == 0) {\r
+ wait(_readEvent);\r
+ } else if ((len - write) < unused()) {\r
+ while (write < len) {\r
+ unsigned tocopy = (len - write + _head >= _size) ? _size - _head : len - write;\r
+ memcpy(_buffer + _head, buffer, tocopy);\r
+ _head = (_head + tocopy) % _size;\r
+ write += tocopy;\r
+ buffer += tocopy;\r
+ }\r
+ _writeEvent.notify();\r
+ } else {\r
+ *(_buffer + (unsigned)(_head) % _size) = *buffer++;\r
+ _head = (_head + 1) % _size;\r
+ write++;\r
+ _writeEvent.notify();\r
+ }\r
+ }*/\r
+\r
+ //std::cout << "Wrote " << write << " bytes to Fifo " << _name << "." << std::endl;\r
+ return write;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::size() const {\r
+ return (_size);\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::unused() const {\r
+ return (_size) - _use;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+unsigned Fifo::used() const {\r
+ return _use;\r
+}\r
+\r
+/**\r
+ *\r
+ */\r
+char* Fifo::getName() const {\r
+ return _name;\r
+}\r
+\r
+/**\r
+ * Test the implementation\r
+ */\r
+/*\r
+class producer : public sc_module\r
+{\r
+ public:\r
+ Fifo *fifo;\r
+\r
+ SC_HAS_PROCESS(producer);\r
+\r
+ producer(sc_module_name name) : sc_module(name)\r
+ {\r
+ SC_THREAD(main);\r
+ }\r
+\r
+ void main()\r
+ {\r
+ const char *str =\r
+ "Visit www.systemc.org and see what SystemC can do for you today!\n";\r
+\r
+ while (*str) {\r
+ fifo->write((void*)str++, 4);\r
+ }\r
+ }\r
+};\r
+\r
+class consumer : public sc_module\r
+{\r
+ public:\r
+ Fifo *fifo;\r
+\r
+ SC_HAS_PROCESS(consumer);\r
+\r
+ consumer(sc_module_name name) : sc_module(name)\r
+ {\r
+ SC_THREAD(main);\r
+ }\r
+\r
+ void main()\r
+ {\r
+ char c;\r
+ cout << endl << endl;\r
+\r
+ while (true) {\r
+ fifo->read(&c, 4);\r
+ cout << c << flush;\r
+\r
+ if (fifo->used() == 1)\r
+ cout << "<1>" << flush;\r
+ if (fifo->used() == 9)\r
+ cout << "<9>" << flush;\r
+ }\r
+ }\r
+};\r
+\r
+class top : public sc_module\r
+{\r
+ public:\r
+ Fifo *fifo_inst;\r
+ producer *prod_inst;\r
+ consumer *cons_inst;\r
+\r
+ top(sc_module_name name) : sc_module(name)\r
+ {\r
+ fifo_inst = new Fifo("myfifo", 10);\r
+\r
+ prod_inst = new producer("producer");\r
+ prod_inst->fifo = fifo_inst;\r
+\r
+ cons_inst = new consumer("consumer");\r
+ cons_inst->fifo = fifo_inst;\r
+ }\r
+};\r
+\r
+int sc_main (int argc , char *argv[]) {\r
+ top top1("top");\r
+ sc_start();\r
+ return 0;\r
+}\r
+*/\r