]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
bidirectional handshake working, Ingo
authorhades <hades>
Fri, 10 Mar 2006 17:29:37 +0000 (17:29 +0000)
committerhades <hades>
Fri, 10 Mar 2006 17:29:37 +0000 (17:29 +0000)
Makefile
basic.h
hubtest.cc
ibufcx.cc
ibufcx.h
iobufcx.cc
iobufcx.h
iofifo.cc [new file with mode: 0644]
iofifo.h [new file with mode: 0644]
obufcx.cc

index 85b3f03fdae1f680e006c80b0ced469e4ee4fc33..8c15b618c7809e96c6b12d0a13e54e41407a8db4 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 .SUFFIXES: .cc
 
-OBJS            = ibufcx.o obufcx.o iobufcx.o hubtest.o basic.o
+OBJS            = ibufcx.o obufcx.o iobufcx.o iofifo.o hubtest.o basic.o
 
 CXX           = g++
 CXXFLAGS      = -g -O3 -Wall -fPIC
diff --git a/basic.h b/basic.h
index d2c6de596063ae4ec8748b8fca93afd0db5bf4c4..5f3f56b507b7a5804e30ce2961bf428c99a58170 100644 (file)
--- a/basic.h
+++ b/basic.h
@@ -46,10 +46,12 @@ using namespace std;
 
 
 #define STATUSBITS    24,26
-#define HEADER_HEADER 0x0
-#define HEADER_TERM   0x1
-#define HEADER_BUF    0x2
-#define HEADER_DATA   0x3
+#define HEADER_HEADER 0x1
+#define HEADER_TERM   0x2
+#define HEADER_BUF    0x3
+#define HEADER_DATA   0x4
+#define HEADER_ACK    0x5
+
 
 //
 // logic array
index bcc1c2338cb63d8a6fb90838c4516b11c9229e94..69a0faba0b869b57ac834cdd6410ed9f3b17147b 100644 (file)
@@ -1,4 +1,5 @@
 #include "iobufcx.h"
+#include "iofifo.h"
 
 int acktest(void) {
 
@@ -10,19 +11,17 @@ int acktest(void) {
        if (i==0) {
            //write a word into buf   
            buf.WRITE=1;
-           buf.SIGIN.set(0x00000000u); // empty header
+           buf.SIGIN.set(0x01000000u); // empty header
        }
        else if (i==1) { 
            buf.WRITE=1;
-           buf.SIGIN.set(0x03000000u); // data word
+           buf.SIGIN.set(0x04000000u); // data word
        }
        else if (i==2) { 
            buf.WRITE=1;
-           //buf.SIGIN.set(0x01000000u); // term word
-           buf.SIGIN.set(0x02000000u); // EOB word
+           //buf.SIGIN.set(0x02000000u); // term word
+           buf.SIGIN.set(0x03000000u); // EOB word
        } 
-       
-
        else buf.WRITE=0; 
 
        if (i==2) 
@@ -52,11 +51,96 @@ int acktest(void) {
 
 }
 
+void connect(IOBUFCX * a, IOBUFCX * b) {
+    //cross-connect 2 buffers
+    //this is what the OSI_LINK_LAYER should do
+    
+    b->SIGIN = a->SIGOUT;
+    a->SIGIN = b->SIGOUT;
+    
+    a->READ = a->DATAREADY;
+    b->READ = b->DATAREADY;
+    
+    b->WRITE = a->DATAREADY;
+    a->WRITE = b->DATAREADY;
 
-void main(void) {
+}
 
-    //acktest();
+int iofifotest(void) {
+
+    IOFIFO send,end;
 
+    for (int i=0; i<15; i++) {
+        
+       //TESTBENCH
+       if (i==0) {
+           //write a word into send   
+           send.WRITE=1;
+           send.SIGIN.set(0x00adfaceu); 
+       }
+       else if (i==1) { 
+           send.WRITE=1;
+           send.SIGIN.set(0x00345678u); // data word
+       }
+       else if (i==2) { 
+           send.WRITE=1;
+           send.SIGIN.set(0x01212u); // data word
+       } else {
+           send.WRITE=0;
+       }
+       
+       //HEADER activate
+       if (i==3) {
+           send.WRITE_SENDER_HEADER=1;
+           send.SENDER_HEADER.set(0x01000000u); 
+       } else send.WRITE_SENDER_HEADER=0;
+
+       //ENDPOINT
+       end.WRITE=0;
+       //end.READ=0;
+       end.WRITE_SENDER_HEADER=0;
+
+       //LOGIC
+       for (int l=0;l<100;l++) {
+           //simulate READER
+           if (end.DATAREADY) end.READ=1;
+           else end.READ=0;
+           send.Logic();
+           end.Logic();
+           connect(&send.iobuffer, &end.iobuffer);         
+       }
+
+       //
+       if (send.iobuffer.DATAREADY)
+           cout << "DOWN MEDIA SIGOUT " << std::hex << send.iobuffer.SIGOUT.get_value(0,27) << endl;
+       else cout << "NO DOWN MEDIA DATA" << endl;
+
+       if (end.iobuffer.DATAREADY)
+           cout << "UP MEDIA SIGOUT " << std::hex << end.iobuffer.SIGOUT.get_value(0,27) << endl;
+       else cout << "NO UP MEDIA DATA" << endl;
+
+       //cout << "OBUF: ";send.iobuffer.myobuf.Dump();
+       //cout << "IOFIFO: ";send.Dump();
+
+       //cout << "END:OBUF: ";end.iobuffer.myobuf.Dump();
+
+       //buf.myobuf.Dump();
+       //asign CLK
+       send.NextCLK();
+       end.NextCLK();
+       cout << "--------------------" << endl;
+    }
+
+
+}
+
+
+
+
+int main(void) {
+
+    //acktest();
 
+    iofifotest();
 
 }
index 25d1489d0017f042cb594d9d81412802b9b1ba67..01e00f9eb5d45ce0193aa0259a21e5ed8edc3bc5 100644 (file)
--- a/ibufcx.cc
+++ b/ibufcx.cc
@@ -14,43 +14,55 @@ void IBUFCX::Logic(void){
     }
        
     if ((!(buffer->EMPTY))) { //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;
-               if (READ)
-                   nextstate = TRANSFERMODE;
-               else
-                   nextstate = FREEMODE;
-           } else if (buffer->SIGOUT.get_value(STATUSBITS) == HEADER_TERM) { //TERM transfer
-               buffer->READ =  1;  //clean TERM
-               header.WRITE =  0; 
-               headerterm.WRITE =  1;  //
-               DATAREADY = 0;
-               if (READ)
-                   nextstate = TERMMODE;
-               else
+
+       //ACK is something special, it must be killed after one CLK cycle
+       if (buffer->SIGOUT.get_value(STATUSBITS) == HEADER_ACK) {
+           GOT_ACK = 1;
+           buffer->READ =  1;  //clean TERM
+           header.WRITE =  0; 
+           headerterm.WRITE =  0;  //
+           DATAREADY = 0;
+           nextstate = mystate;
+       }
+       else { 
+           GOT_ACK = 0;
+           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;
+                   if (READ)
+                       nextstate = TRANSFERMODE;
+                   else
                    nextstate = FREEMODE;
-           } 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
-               //cout << buffer->SIGOUT.get_value(STATUSBITS) << endl;
+               } else if (buffer->SIGOUT.get_value(STATUSBITS) == HEADER_TERM) { //TERM transfer
+                   buffer->READ =  1;  //clean TERM
+                   header.WRITE =  0; 
+                   headerterm.WRITE =  1;  //
+                   DATAREADY = 0;
+                   if (READ)
+                       nextstate = TERMMODE;
+                   else
+                       nextstate = FREEMODE;
+               } 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
+                   //cout << buffer->SIGOUT.get_value(STATUSBITS) << endl;
                buffer->READ =  1;  //clean TERM
                header.WRITE =  0; 
                headerterm.WRITE =  1;  //
@@ -80,6 +92,7 @@ void IBUFCX::Logic(void){
            else
                nextstate = mystate;
        }
+       }// END NOACK
     } // BUFFER is not EMPTY
     else { //BUFFER IS EMPTY
        if (mystate==FREEMODE) {            
index 4a51f9d26ca2b0b2a13d87e048ad4efcf3ade4ea..03c4f22e006cf8d24baa709ef52f3bc2c8208513 100644 (file)
--- a/ibufcx.h
+++ b/ibufcx.h
@@ -20,6 +20,7 @@ public:
     };
     in WRITE,READ,RESENDHEADER,CLEAR;
     out DATAREADY; //means that data can be transferred
+    out GOT_ACK;
     //   out TERM;  //TERM header arrived
     //   out BUFFEREND;  //ACK cycle has to be done
 
index f5a316f3b4c2ab52d328f1023aaf91a37f50968d..79537fe835bf368bca37f7dad226c3c429968dd0 100644 (file)
@@ -15,14 +15,71 @@ void IOBUFCX::Logic(void){
     myibuf.RESENDHEADER = RESENDHEADER_IN_INT;
     DATAREADY_OUT_INT = myibuf.DATAREADY;
     
-
     //connect to media
-    SIGOUT = myobuf.SIGOUT;
+
     myibuf.SIGIN = SIGIN;
-    myobuf.READ = READ;
-    DATAREADY = myobuf.DATAREADY;
     myibuf.WRITE = WRITE;
 
+    if (READ)
+       next_word_counter = word_counter +1;
+
+    if (word_counter == 0) {
+       if (block_counter < MAX_BLOCKS) {
+           //resend header
+           RESENDHEADER_OUT_INT = 1;
+           SIGOUT = myobuf.SIGOUT;
+           DATAREADY = myobuf.DATAREADY;       //forward the DATAREADY from the input
+           myobuf.READ = READ;         
+           next_block_counter = block_counter;
+           if (READ)
+               next_word_counter = word_counter +1;
+           else
+               next_word_counter = word_counter;
+       } else { //transfer continued
+           if (myibuf.GOT_ACK) {
+               RESENDHEADER_OUT_INT = 1;
+               SIGOUT = myobuf.SIGOUT;
+               DATAREADY = 0;
+               myobuf.READ = 0;
+               next_block_counter = block_counter - 1;
+               next_word_counter = 0;
+           } else { //transfer stalled
+               RESENDHEADER_OUT_INT = 1;
+               SIGOUT = myobuf.SIGOUT;
+               DATAREADY = 0;
+               myobuf.READ = 0;
+               next_block_counter = block_counter;
+               next_word_counter = word_counter;
+           }
+       }
+    } else if (word_counter == (MAX_WORD-1)) {
+       // send EOB
+       RESENDHEADER_OUT_INT = 0;
+       SIGOUT.set(HEADER_BUF << 24);
+       DATAREADY = 1;  //so I have DATAREADY 
+       myobuf.READ = 0;        
+       if (READ) {
+           next_word_counter = 0;
+           if (!myibuf.GOT_ACK) //async ACK
+               next_block_counter = block_counter + 1;
+           else
+               next_block_counter = block_counter;
+       }
+       else {
+           next_word_counter = word_counter;
+           next_block_counter = block_counter;
+       }
+    } else {
+       RESENDHEADER_OUT_INT = 0; 
+       SIGOUT = myobuf.SIGOUT;
+       DATAREADY = myobuf.DATAREADY;   
+       myobuf.READ = READ;    
+       next_block_counter = block_counter;
+       if (READ)
+           next_word_counter = word_counter + 1;
+       else
+           next_word_counter = word_counter;
+    }
 
     myibuf.Logic();
     myobuf.Logic();
@@ -30,6 +87,8 @@ void IOBUFCX::Logic(void){
 };
 
 void IOBUFCX::NextCLK(void){
+    word_counter = next_word_counter;
+    block_counter = next_block_counter;
     myibuf.NextCLK();
     myobuf.NextCLK();
 }
index 2ec451d93b812e5c9fc6b32c9841ffe8f79d0acd..252387750ba893ad075c3892f0535c873c5d0277 100644 (file)
--- a/iobufcx.h
+++ b/iobufcx.h
 // output buffer for ONE channel and ONE port
 //
 
+//hardcoded, later to be made with LSYNC
+#define MAX_WORD   3
+#define MAX_BLOCKS 2
 
 class IOBUFCX {
  public:
     IOBUFCX() {RESET();};
     void RESET() {
+       word_counter =0;
+       block_counter=0;
     };
 
     void Logic(void);
@@ -30,9 +35,10 @@ class IOBUFCX {
     out READ_OUT_INT;       //IOBUF is activating internal logic
     out DATAREADY_OUT_INT;  //means that data can be transferred
     in  DATAREADY_IN_INT;   //from other IBUF (stream partner)
-    out READ_OUT;  //read from other IBUF (stream partner)
-    
+
     in RESENDHEADER_IN_INT; //in-streaming have to resend header
+    out RESENDHEADER_OUT_INT; //internal logic has to resend header
+
     in WRITE;               //media is putting data into IBUF
     out READ;               //media is reading data
     out DATAREADY;          //media knows that I have somthing to offer
@@ -47,7 +53,8 @@ class IOBUFCX {
 
 
  private:
-
+    unsigned int next_word_counter, word_counter;
+    unsigned int block_counter, next_block_counter;
 
 };
 
diff --git a/iofifo.cc b/iofifo.cc
new file mode 100644 (file)
index 0000000..2bda75e
--- /dev/null
+++ b/iofifo.cc
@@ -0,0 +1,79 @@
+#include "iofifo.h"
+
+// WRITE data to network
+// way1.) write the header first, then the data
+// way2.) write first the data, data transfer is locked until you write the header
+// after transfer, write a TERM header to the header register
+// TODO: IDLE mode...
+
+
+
+void IOFIFO::Logic(void){
+
+    //header control
+    reg_sender_header.SIGIN = SENDER_HEADER;
+    reg_sender_header.WRITE = WRITE_SENDER_HEADER;
+
+    //input fifo -> decouples writing from network transfer
+    buffer->SIGIN = SIGIN;
+    buffer->WRITE = WRITE;
+        
+    //output device
+    SIGOUT = iobuffer.SIGOUT_INT;
+    iobuffer.READ_IN_INT = READ;
+    DATAREADY = iobuffer.DATAREADY_OUT_INT;
+
+    if (mystate == IOFIFO_FREEMODE) {  //nothing happened so far...
+       iobuffer.SIGIN_INT = SIGIN;
+       iobuffer.DATAREADY_IN_INT = 0;
+       buffer->READ = 0;
+       if (reg_sender_header.SIGOUT.get_value(STATUSBITS) == HEADER_HEADER) {
+           nextstate = IOFIFO_SENDHEADER;
+       } else
+           nextstate = IOFIFO_FREEMODE;        
+    } // end FREEMODE
+    else if (mystate == IOFIFO_SENDHEADER) {
+       iobuffer.SIGIN_INT = reg_sender_header.SIGOUT;
+       iobuffer.DATAREADY_IN_INT = 1;
+       buffer->READ = 0;
+       if (iobuffer.READ_OUT_INT)  //yes, buffer reads my header
+           nextstate = IOFIFO_SENDMODE;
+       else
+           nextstate = IOFIFO_SENDHEADER;
+    } // end SENDHEADER
+    else if (mystate == IOFIFO_SENDMODE) {
+       if (iobuffer.RESENDHEADER_OUT_INT) {
+           iobuffer.SIGIN_INT = reg_sender_header.SIGOUT;
+           iobuffer.DATAREADY_IN_INT = 1;
+           buffer->READ = 0;
+       } else {
+           iobuffer.SIGIN_INT = buffer->SIGOUT;
+           if (reg_sender_header.SIGOUT.get_value(STATUSBITS) == HEADER_HEADER) {
+               iobuffer.DATAREADY_IN_INT = (!buffer->EMPTY);
+               nextstate = IOFIFO_SENDMODE;
+           }
+           else {
+               iobuffer.DATAREADY_IN_INT = 0;
+               nextstate = IOFIFO_FREEMODE;
+           }
+           buffer->READ = iobuffer.READ_OUT_INT;
+       }
+    }
+
+    buffer->Logic();
+    iobuffer.Logic();
+    reg_sender_header.Logic();
+
+}
+
+
+void IOFIFO::NextCLK(void){
+    mystate = nextstate;
+    buffer->NextCLK();
+    iobuffer.NextCLK();
+    reg_sender_header.NextCLK();
+}
+
+void IOFIFO::Dump(void){
+    cout << "ST:" << mystate << " BUFREAD " << buffer->READ << " HH " << reg_sender_header.SIGOUT.get_value(STATUSBITS) << " HW " << reg_sender_header.WRITE << " IOB_DR " << iobuffer.DATAREADY_IN_INT << " IOB_RSH " <<iobuffer.RESENDHEADER_OUT_INT << endl;
+}
diff --git a/iofifo.h b/iofifo.h
new file mode 100644 (file)
index 0000000..228f804
--- /dev/null
+++ b/iofifo.h
@@ -0,0 +1,54 @@
+#ifndef IOFIFO_H
+#define IOFIFO_H
+
+#define IOFIFO_FREEMODE 1
+#define IOFIFO_SENDHEADER 2 
+#define IOFIFO_SENDMODE 3
+
+#include "iobufcx.h"
+
+class IOFIFO {
+ public:
+    IOFIFO() {
+       buffer = new FIFO28(16);
+       RESET();
+    };
+    void RESET() {
+       mystate = IOFIFO_FREEMODE;
+       reg_sender_header.WRITE = 1;
+       reg_sender_header.SIGIN.set(0xfffffff);
+       reg_sender_header.NextCLK();
+       reg_sender_header.WRITE = 0;
+       
+    };
+    
+    in_vector28 SENDER_HEADER;
+    in WRITE_SENDER_HEADER;
+    in_vector28 SIGIN;   //write data from host
+    in WRITE;            //write data from host
+    out FULL;            //fifo full (not yet implemented)
+
+    out_vector28 SIGOUT; //data from network
+    in READ;             //read data from host
+    out DATAREADY;       //data can be read
+    
+    //now some lines for the media
+    
+
+    void Logic(void);
+
+    void NextCLK(void);
+    
+    void Dump(void);
+
+    IOBUFCX iobuffer;
+    FIFO28 * buffer;  //in principle 24 Bit would be enough....
+    REG28 reg_sender_header;;
+
+ private:
+    state mystate, nextstate;
+
+};
+
+
+#endif
index 1db71db8edcad01cd801de9395595aee4c5106ba..97f6a0f95c1f2a5c09e76b7e734baf155bb2d731 100644 (file)
--- a/obufcx.cc
+++ b/obufcx.cc
@@ -5,7 +5,7 @@ void OBUFCX::Logic(void){
     if ((mystate==OBUF_FREEMODE) || (mystate==OBUF_WAITINGMODE)) {
        if (IBUF_STATEIN == WAITINGMODE) {
            //partner has got EOB and we should send an ACK         
-           SIGOUT.set(HEADER_TERM << 24);  //prepare ACK
+           SIGOUT.set(HEADER_ACK << 24);  //prepare ACK
            if (READ) 
                nextstate = OBUF_CLEARMODE;
            else 
@@ -34,7 +34,7 @@ void OBUFCX::Logic(void){
 };
 
 void OBUFCX::NextCLK(void){
-    mystate = nextstate;
+    mystate = nextstate;    
 }