dol: initial dol commit
[jump.git] / dol / src / dol / visitor / hds / lib / Fifo.cpp
diff --git a/dol/src/dol/visitor/hds/lib/Fifo.cpp b/dol/src/dol/visitor/hds/lib/Fifo.cpp
new file mode 100644 (file)
index 0000000..4c66c4c
--- /dev/null
@@ -0,0 +1,254 @@
+#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