--- /dev/null
+.SUFFIXES: .cc
+
+OBJS = bufcx.o hubtest.o
+
+CXX = g++
+CXXFLAGS = -g -O3 -Wall -fPIC
+LD = g++
+LDFLAGS =
+LIBS = -lm -ldl -rdynamic
+
+all: hubtest
+
+hubtest: $(OBJS) Makefile hubtest.o
+ $(LD) $(LDFLAGS) $(OBJS) $(LIBS) -o hubtest
+
+.cc.o:
+ @echo compiling $<
+ $(CXX) $(CXXFLAGS) -c $<
+
+
+clean:
+ @rm -f $(OBJS) hubtest *.o
+
--- /dev/null
+#ifndef BASIC
+#define BASIC
+
+
+#include <iostream>
+#include <math.h>
+
+using namespace std;
+
+#define in int
+#define out int
+#define state int
+
+#define in_vector STD_LOGIC_ARRAY
+#define out_vector STD_LOGIC_ARRAY
+
+#define in_vector28 vector28
+#define out_vector28 vector28
+
+#define in_vector8 vector8
+#define out_vector8 vector8
+
+#define NOCHANGEMODE 0
+
+#define FREEMODE 1
+//FREEMODE means that all data are put to output
+
+#define KEEPMODE 2
+//means that EMPTY is hidden - do not use this port for a while
+
+#define ACKMODE 3
+//means that EMPTY should be anded - please wait until we are complete
+
+#define TRANSFERMODE 4
+//port is during transfer
+
+#define TERMMODE 5
+
+#define WAITINGMODE 6
+
+#define ERRORMODE 7
+
+#define STATUSBITS 0,1
+#define HEADER_HEADER 0x0
+#define HEADER_TERM 0x1
+#define HEADER_BUF 0x2
+#define HEADER_DATA 0x3
+
+//
+// logic array
+//
+
+class STD_LOGIC_ARRAY {
+ public:
+ STD_LOGIC_ARRAY(int mysize) {
+ cont= new int[mysize];
+ size=mysize;
+ };
+ STD_LOGIC_ARRAY() {
+ size=0;
+ }
+
+ unsigned int get_value(int a, int b) {
+ unsigned int bla=0;
+ for (int i=a,j=1;i<b;i++,j*=2) {
+ if (cont[i]) bla+=j;
+ }
+ return bla;
+ };
+
+ //void operator=(const unsigned int & bla){
+// for (int i=0;i<size;i++)
+// cont[i]=bla;
+// };
+
+ void set(unsigned int bla) {
+ unsigned int val = pow(2.,size);
+ for (int i=(size-1);i>=0;i--) {
+ if (bla >= val) {
+ bla -= val;
+ cont[i]=1;
+ } else {
+ cont[i]=0;
+ }
+
+ val /=2;
+
+ }
+
+ }
+
+ void operator=(const STD_LOGIC_ARRAY & other){
+ for (int i=0;i<size;i++)
+ cont[i]=other.cont[i];
+ };
+
+ int operator()(int ar) const {
+ return cont[ar];
+ };
+
+ int & operator()(int ar) {
+ return cont[ar];
+ };
+
+ protected:
+
+ int * cont;
+ int size;
+};
+
+class vector28 : public STD_LOGIC_ARRAY {
+ public:
+ vector28(){
+ cont= new int[28];
+ size=28;
+ };
+};
+
+class vector8 : public STD_LOGIC_ARRAY {
+ public:
+ vector8(){
+ cont= new int[28];
+ size=8;
+ };
+};
+
+//
+// The classical flip-flop
+//
+
+class FLIPFLOP {
+public:
+ FLIPFLOP() {RESET();};
+ in SIGIN;
+ out SIGOUT;
+ void RESET() {SIGIN=SIGOUT=0;};
+ void NextCLK(void){SIGOUT=SIGIN;};
+};
+
+//
+// 28 Bit register
+//
+class REG28 {
+public:
+ REG28() {RESET();};
+ in_vector28 SIGIN;
+ in WRITE;
+ out_vector28 SIGOUT;
+ void RESET() {
+ for (int i=0; i<28; i++) (SIGIN(i))=(SIGOUT(i))=0;
+ };
+ void NextCLK(void) {
+ for (int i=0; i<28; i++)
+ if (WRITE) (SIGOUT(i))=(SIGIN(i));
+ };
+ void Logic(void){};
+};
+
+//
+// 8- Bit counter
+//
+class COUNTER8 {
+public:
+ COUNTER8() {RESET();};
+ out_vector8 SIGOUT;
+ void RESET() {
+ for (int i=0; i<8; i++)
+ (SIGOUT(i))=0;counter=0;
+ };
+ void NextCLK(void){
+ counter++;
+ for (int i=0; i<8; i++)
+ (SIGOUT(i))=((counter << i) & 0x1);
+ };
+ private:
+ unsigned int counter;
+};
+
+//
+// 28 bit wide fifo
+// depth can be choosen in the constructor
+// = would be "generic" in vhdl
+//
+// BUGBUG fifo full missing
+// This would be an error condition
+//
+// Special feature: If fifo is emtpy, output is input
+class FIFO28 {
+public:
+ FIFO28(int mydepth) {
+ RESET();
+ depth=mydepth;
+ regarray = new REG28[depth];
+ };
+
+ void RESET() {
+ counter=WRITE=READ=0;
+ pointer_write=pointer_read=0;
+ EMPTY=1;
+ };
+
+ in WRITE,READ;
+ out EMPTY;
+ in_vector28 SIGIN;
+ out_vector28 SIGOUT;
+
+ void Logic(void){
+ if (counter) EMPTY=0; else EMPTY=1;
+ for (int i=0;i<28;i++) {
+ (regarray[pointer_write].SIGIN(i))=(SIGIN(i));
+ (SIGOUT(i))=(regarray[pointer_read].SIGOUT(i));
+ }
+ }
+
+ void NextCLK(void){
+ if (WRITE) {
+ counter++;
+ //cout << "ac=" << counter << endl;
+ pointer_write++;
+ if (pointer_write == depth) pointer_write=0;
+ }
+ if (READ && !EMPTY) {
+ counter--;
+ //cout << "ec=" << counter << endl;
+ pointer_read++;
+ if (pointer_read == depth) pointer_read=0;
+ }
+ for (int i=0;i<depth;i++) regarray[i].NextCLK();
+ }
+ private:
+ unsigned int counter, depth;
+ unsigned int pointer_write,pointer_read;
+ REG28 * regarray;
+};
+
+
+
+#endif
--- /dev/null
+#include "bufcx.h"
+
+
+void IBUFCX::Logic(void){
+ STATEOUT=mystate; //forward internal state to outer world
+ header.SIGIN = SIGIN; //input lines for the header
+ SIGOUT = buffer->SIGOUT;
+ buffer->SIGIN = SIGIN;
+
+ if (WRITE == 1) { //BUGBUG check if fifo is not full
+ buffer->WRITE = 1;
+ } else{ //BUGBUG check if fifo is not full
+ buffer->WRITE = 0;
+ }
+
+
+ if ((!(buffer->EMPTY)) || (WRITE)) { //BUFFER has data
+ if (mystate==FREEMODE) {
+ if (buffer->SIGOUT.get_value(STATUSBITS) == HEADER_HEADER) { //word to be read is a header
+ buffer->READ = READ; //yes, read header
+ header.WRITE = 1;
+ headerterm.WRITE = 0;
+ DATAREADY = 1;
+ nextstate = TRANSFERMODE;
+ } else if (buffer->SIGOUT.get_value(STATUSBITS) == HEADER_TERM) { //TERM transfer
+ buffer->READ = 1; //clean TERM
+ header.WRITE = 0;
+ headerterm.WRITE = 1; //
+ DATAREADY = 0;
+ nextstate = TERMMODE;
+ } else { //something is wrong...first word MUST be header or TERM
+ buffer->READ = 1; //clean wrong word
+ header.WRITE = 0;
+ headerterm.WRITE = 0;
+ DATAREADY = 0;
+ nextstate = ERRORMODE;
+ }
+ } //FREEMODE
+ else if (mystate==TRANSFERMODE) {
+ if (buffer->SIGOUT.get_value(STATUSBITS) == HEADER_HEADER) { //word to be read is a header
+ buffer->READ = READ; //yes, read header
+ //cout << "a" << endl;
+ header.WRITE = 1;
+ headerterm.WRITE = 0;
+ DATAREADY = 1;
+ nextstate = TRANSFERMODE;
+ } else if (buffer->SIGOUT.get_value(STATUSBITS) == HEADER_TERM) { //TERM transfer
+ buffer->READ = 1; //clean TERM
+ header.WRITE = 0;
+ headerterm.WRITE = 1; //
+ DATAREADY = 0;
+ nextstate = TERMMODE;
+ } else if (buffer->SIGOUT.get_value(STATUSBITS) == HEADER_BUF) { //ask for new buffer
+ buffer->READ = 1; //clean TERM
+ header.WRITE = 0;
+ headerterm.WRITE = 0; //I do not keep BUF header?
+ DATAREADY = 0;
+ nextstate = WAITINGMODE;
+ } else if (buffer->SIGOUT.get_value(STATUSBITS) == HEADER_DATA) {
+ buffer->READ = READ;
+ header.WRITE = 0;
+ headerterm.WRITE = 0; //I do not keep BUF header?
+ DATAREADY = 0;
+ nextstate = WAITINGMODE;
+ }
+ }//TRANSFER
+ else if ((mystate==TERMMODE) || (mystate==WAITINGMODE)) { //after TERM, nothing should be inside
+ buffer->READ = 1;
+ header.WRITE = 0;
+ headerterm.WRITE = 0; //I do not keep BUF header?
+ DATAREADY = 0;
+ nextstate = ERRORMODE;
+ }
+ } // BUFFER is not EMPTY
+ else { //BUFFER IS EMPTY
+ if (mystate==FREEMODE) {
+ buffer->READ = 0;
+ header.WRITE = 0;
+ headerterm.WRITE = 0;
+ DATAREADY = 0;
+ nextstate = FREEMODE;
+ } else if (mystate==TRANSFERMODE) {
+ buffer->READ = 0;
+ header.WRITE = 0;
+ headerterm.WRITE = 0;
+ DATAREADY = 0;
+ nextstate = TRANSFERMODE;
+ } else if (mystate==WAITINGMODE) {
+ buffer->READ = 0;
+ header.WRITE = 0;
+ headerterm.WRITE = 0;
+ DATAREADY = 0;
+ if (CLEAN)
+ nextstate = FREEMODE;
+ else
+ nextstate = WAITINGMODE;
+ } else if (mystate==TERMMODE) {
+ buffer->READ = 0;
+ header.WRITE = 0;
+ headerterm.WRITE = 0;
+ DATAREADY = 0;
+ if (CLEAN)
+ nextstate = FREEMODE;
+ else
+ nextstate = WAITINGMODE;
+ }
+ }
+
+
+ buffer->Logic();
+ header.Logic();
+ headerterm.Logic();
+};
+
+void IBUFCX::NextCLK(void){
+ mystate = nextstate;
+ buffer->NextCLK();
+ header.NextCLK();
+ headerterm.NextCLK();
+}
+
+
+void IBUFCX::Dump(void) {
+
+ cout << "W=" << WRITE << " R=" << READ << " DR=" << DATAREADY << " st=" << mystate
+ << " EMP=" << buffer->EMPTY
+ << " buf=" << buffer->SIGOUT.get_value(0,27)
+
+ << endl;
+}
--- /dev/null
+#ifndef BUFCX
+#define BUFCX
+
+
+#include "basic.h"
+
+//
+// input buffer for ONE channel and ONE port
+//
+
+
+class IBUFCX {
+public:
+ IBUFCX() {RESET();};
+ void RESET() {
+ buffer = new FIFO28(16);
+ buffer->RESET();
+ WRITE=READ=DATAREADY=TERM=BUFFEREND=CLEAN=0;
+ mystate=FREEMODE;
+ };
+ in WRITE,READ,RESENDHEADER,CLEAN;
+ out DATAREADY; //means that data can be transferred
+ out TERM; //TERM header arrived
+ out BUFFEREND; //ACK cycle has to be done
+
+ void Logic(void);
+
+ in STATEIN;
+ out STATEOUT;
+ in_vector28 SIGIN;
+ out_vector28 SIGOUT,HEADER,TERMHEADER;
+
+
+ void NextCLK(void);
+
+ void Dump(void);
+
+
+ FIFO28 * buffer;
+ private:
+
+ state mystate, nextstate;
+ REG28 header, headerterm;
+
+};
+
+#endif
--- /dev/null
+#include "bufcx.h"
+
+int main(void) {
+
+ IBUFCX buf;
+
+ for (int i=0; i<10; i++) {
+
+ //TESTBENCH
+ if (i==0) {
+ //write a word into buf
+ buf.WRITE=1;
+ buf.READ=1;
+ buf.SIGIN.set(0x0000u); // empty header
+ }
+ else if (i==1) {
+ buf.READ=0;
+ buf.WRITE=0;
+ }
+ else {
+ buf.READ=0;
+ buf.WRITE=0;
+ }
+
+ for (int l=0;l<100;l++) buf.Logic();
+
+ buf.Dump();
+ //asign CLK
+ buf.NextCLK();
+ cout << "next CLK" << endl;
+ }
+
+
+}