OpenCores
URL https://opencores.org/ocsvn/async_sdm_noc/async_sdm_noc/trunk

Subversion Repositories async_sdm_noc

[/] [async_sdm_noc/] [trunk/] [vc/] [tb/] [rtdriver.cpp] - Diff between revs 45 and 47

Only display areas with differences | Details | Blame | View Log

Rev 45 Rev 47
/*
/*
 Asynchronous SDM NoC
 Asynchronous SDM NoC
 (C)2011 Wei Song
 (C)2011 Wei Song
 Advanced Processor Technologies Group
 Advanced Processor Technologies Group
 Computer Science, the Univ. of Manchester, UK
 Computer Science, the Univ. of Manchester, UK
 
 
 Authors:
 Authors:
 Wei Song     wsong83@gmail.com
 Wei Song     wsong83@gmail.com
 
 
 License: LGPL 3.0 or later
 License: LGPL 3.0 or later
 
 
 The port driver between NI and router.
 The port driver between NI and router.
 
 
 History:
 History:
 02/05/2010  Initial version. <wsong83@gmail.com>
 02/05/2010  Initial version. <wsong83@gmail.com>
 03/06/2011  Remove the sc_unit datatype to support data width larger than 64. <wsong83@gmail.com>
 03/06/2011  Remove the sc_unit datatype to support data width larger than 64. <wsong83@gmail.com>
 
 
*/
*/
 
 
#include "rtdriver.h"
#include "rtdriver.h"
 
 
RTDriver::RTDriver(sc_module_name mname)
RTDriver::RTDriver(sc_module_name mname)
  : sc_module(mname),
  : sc_module(mname),
    NI2P("NI2P"),
    NI2P("NI2P"),
    P2NI("P2NI"),
    P2NI("P2NI"),
    rtia("rtia"),
    rtia("rtia"),
    rtic("rtic"),
    rtic("rtic"),
    rtica("rtica"),
    rtica("rtica"),
    rtoa("rtoa"),
    rtoa("rtoa"),
    rtoc("rtoc"),
    rtoc("rtoc"),
    rtoca("rtoca")
    rtoca("rtoca")
{
{
  SC_METHOD(IPdetect);
  SC_METHOD(IPdetect);
  sensitive << rtia;
  sensitive << rtia;
 
 
  SC_METHOD(OPdetect);
  SC_METHOD(OPdetect);
  sensitive << rtod[0] << rtod[1] << rtod[2] << rtod[3] << rtovc << rtoft;
  sensitive << rtod[0] << rtod[1] << rtod[2] << rtod[3] << rtovc << rtoft;
 
 
  SC_METHOD(Creditdetect);
  SC_METHOD(Creditdetect);
  for(unsigned int i = 0; i<SubChN; i++) {
  for(unsigned int i = 0; i<SubChN; i++) {
    sensitive << CPa[i];
    sensitive << CPa[i];
    sensitive << out_cred[i];
    sensitive << out_cred[i];
  }
  }
  sensitive << rtic << rtoca;
  sensitive << rtic << rtoca;
 
 
  SC_THREAD(send);
  SC_THREAD(send);
  SC_THREAD(recv);
  SC_THREAD(recv);
 
 
  rtinp_sig = false;
  rtinp_sig = false;
  rtoutp_sig = false;
  rtoutp_sig = false;
}
}
 
 
void RTDriver::IPdetect() {
void RTDriver::IPdetect() {
  sc_logic ack_lv_high, ack_lv_low;             // the sc_logic ack
  sc_logic ack_lv_high, ack_lv_low;             // the sc_logic ack
 
 
  ack_lv_high = rtia.read();
  ack_lv_high = rtia.read();
  ack_lv_low = rtia.read();
  ack_lv_low = rtia.read();
 
 
  if(ack_lv_high.is_01() && ack_lv_high.to_bool())
  if(ack_lv_high.is_01() && ack_lv_high.to_bool())
    rtinp_sig = true;
    rtinp_sig = true;
 
 
  if(ack_lv_low.is_01() && (!ack_lv_low.to_bool()))
  if(ack_lv_low.is_01() && (!ack_lv_low.to_bool()))
    rtinp_sig = false;
    rtinp_sig = false;
}
}
 
 
void RTDriver::OPdetect() {
void RTDriver::OPdetect() {
  sc_lv<ChBW*4> data_lv;        // the ORed data
  sc_lv<ChBW*4> data_lv;        // the ORed data
  sc_logic data_lv_high, data_lv_low;
  sc_logic data_lv_high, data_lv_low;
  sc_lv<SubChN> vc_lv;          // the local copy of vc number
  sc_lv<SubChN> vc_lv;          // the local copy of vc number
  sc_lv<3> ft_lv;               // the local copy of flit type
  sc_lv<3> ft_lv;               // the local copy of flit type
 
 
  data_lv = rtod[0].read() | rtod[1].read() | rtod[2].read() | rtod[3].read();
  data_lv = rtod[0].read() | rtod[1].read() | rtod[2].read() | rtod[3].read();
  vc_lv = rtovc.read();
  vc_lv = rtovc.read();
  ft_lv = rtoft.read();
  ft_lv = rtoft.read();
  data_lv_high = (sc_logic)(data_lv.and_reduce()) & (sc_logic)(vc_lv.or_reduce()) & (sc_logic)(ft_lv.or_reduce());
  data_lv_high = (sc_logic)(data_lv.and_reduce()) & (sc_logic)(vc_lv.or_reduce()) & (sc_logic)(ft_lv.or_reduce());
  data_lv_low = (sc_logic)(data_lv.or_reduce()) | (sc_logic)(vc_lv.or_reduce()) | (sc_logic)(ft_lv.or_reduce());
  data_lv_low = (sc_logic)(data_lv.or_reduce()) | (sc_logic)(vc_lv.or_reduce()) | (sc_logic)(ft_lv.or_reduce());
 
 
  if(data_lv_high.is_01() && data_lv_high.to_bool())
  if(data_lv_high.is_01() && data_lv_high.to_bool())
    rtoutp_sig = true;
    rtoutp_sig = true;
 
 
  if(data_lv_high.is_01() && (!data_lv_low.to_bool()))
  if(data_lv_high.is_01() && (!data_lv_low.to_bool()))
    rtoutp_sig = false;
    rtoutp_sig = false;
}
}
 
 
void RTDriver::Creditdetect() {
void RTDriver::Creditdetect() {
  sc_lv<SubChN> mic;            // the local input credit
  sc_lv<SubChN> mic;            // the local input credit
  sc_lv<SubChN> mica;           // the local input credit ack
  sc_lv<SubChN> mica;           // the local input credit ack
  sc_lv<SubChN> moc;            // the local output credit;
  sc_lv<SubChN> moc;            // the local output credit;
  sc_lv<SubChN> moca;           // the local output credit ack;
  sc_lv<SubChN> moca;           // the local output credit ack;
 
 
  mic = rtic.read();
  mic = rtic.read();
  moca = rtoca.read();
  moca = rtoca.read();
 
 
  for(unsigned int i=0; i<SubChN; i++) {
  for(unsigned int i=0; i<SubChN; i++) {
    CP[i].write(mic[i].is_01()? mic[i].to_bool():false);
    CP[i].write(mic[i].is_01()? mic[i].to_bool():false);
    out_cred_ack[i] = moca[i].is_01()? moca[i].to_bool():false;
    out_cred_ack[i] = moca[i].is_01()? moca[i].to_bool():false;
    mica[i] = CPa[i].read();
    mica[i] = CPa[i].read();
    moc[i] = out_cred[i];
    moc[i] = out_cred[i];
  }
  }
 
 
  rtica.write(mica);
  rtica.write(mica);
  rtoc.write(moc);
  rtoc.write(moc);
}
}
 
 
void RTDriver::send() {
void RTDriver::send() {
  FLIT mflit;                   // the local flit buffer
  FLIT mflit;                   // the local flit buffer
  unsigned int i, j;            // local loop index
  unsigned int i, j;            // local loop index
  sc_lv<ChBW*4> mdata[4];       // local data copy
  sc_lv<ChBW*4> mdata[4];       // local data copy
  sc_lv<SubChN> mvc;            // local vcn
  sc_lv<SubChN> mvc;            // local vcn
  sc_lv<3> mft;                 // local flit type
  sc_lv<3> mft;                 // local flit type
 
 
  // initialize the output ports
  // initialize the output ports
  mdata[0] = 0;
  mdata[0] = 0;
  mdata[1] = 0;
  mdata[1] = 0;
  mdata[2] = 0;
  mdata[2] = 0;
  mdata[3] = 0;
  mdata[3] = 0;
  mvc = 0;
  mvc = 0;
  mft = 0;
  mft = 0;
 
 
 
 
  rtid[0].write(mdata[0]);
  rtid[0].write(mdata[0]);
  rtid[1].write(mdata[1]);
  rtid[1].write(mdata[1]);
  rtid[2].write(mdata[2]);
  rtid[2].write(mdata[2]);
  rtid[3].write(mdata[3]);
  rtid[3].write(mdata[3]);
  rtivc.write(mvc);
  rtivc.write(mvc);
  rtift.write(mft);
  rtift.write(mft);
 
 
  while(true) {
  while(true) {
    mflit = NI2P->read();       // read in the flit
    mflit = NI2P->read();       // read in the flit
 
 
    // write the flit
    // write the flit
    if(mflit.ftype == F_HD) {
    if(mflit.ftype == F_HD) {
      // the target address
      // the target address
      mdata[mflit.addrx&0x3][0] = SC_LOGIC_1;
      mdata[mflit.addrx&0x3][0] = SC_LOGIC_1;
      mdata[(mflit.addrx&0xc)>>2][1] = SC_LOGIC_1;
      mdata[(mflit.addrx&0xc)>>2][1] = SC_LOGIC_1;
      mdata[mflit.addry&0x3][2] = SC_LOGIC_1;
      mdata[mflit.addry&0x3][2] = SC_LOGIC_1;
      mdata[(mflit.addry&0xc)>>2][3] = SC_LOGIC_1;
      mdata[(mflit.addry&0xc)>>2][3] = SC_LOGIC_1;
 
 
      for(i=0,j=4; i<(ChBW-1)*4; i++, j++) {
      for(i=0,j=4; i<(ChBW-1)*4; i++, j++) {
        switch((mflit[i/4] >> ((i%4)*2)) & 0x3) {
        switch((mflit[i/4] >> ((i%4)*2)) & 0x3) {
        case 0: mdata[0][j] = SC_LOGIC_1; break;
        case 0: mdata[0][j] = SC_LOGIC_1; break;
        case 1: mdata[1][j] = SC_LOGIC_1; break;
        case 1: mdata[1][j] = SC_LOGIC_1; break;
        case 2: mdata[2][j] = SC_LOGIC_1; break;
        case 2: mdata[2][j] = SC_LOGIC_1; break;
        case 3: mdata[3][j] = SC_LOGIC_1; break;
        case 3: mdata[3][j] = SC_LOGIC_1; break;
        }
        }
      }
      }
    } else {
    } else {
      for(i=0; i<ChBW*4; i++) {
      for(i=0; i<ChBW*4; i++) {
        switch((mflit[i/4] >> ((i%4)*2)) & 0x3) {
        switch((mflit[i/4] >> ((i%4)*2)) & 0x3) {
        case 0: mdata[0][i] = SC_LOGIC_1; break;
        case 0: mdata[0][i] = SC_LOGIC_1; break;
        case 1: mdata[1][i] = SC_LOGIC_1; break;
        case 1: mdata[1][i] = SC_LOGIC_1; break;
        case 2: mdata[2][i] = SC_LOGIC_1; break;
        case 2: mdata[2][i] = SC_LOGIC_1; break;
        case 3: mdata[3][i] = SC_LOGIC_1; break;
        case 3: mdata[3][i] = SC_LOGIC_1; break;
        }
        }
      }
      }
    }
    }
 
 
    // flit type
    // flit type
    switch(mflit.ftype) {
    switch(mflit.ftype) {
    case F_HD: mft[0] = SC_LOGIC_1; break;
    case F_HD: mft[0] = SC_LOGIC_1; break;
    case F_DAT: mft[1] = SC_LOGIC_1; break;
    case F_DAT: mft[1] = SC_LOGIC_1; break;
    case F_TL: mft[2] = SC_LOGIC_1; break;
    case F_TL: mft[2] = SC_LOGIC_1; break;
    default: break;
    default: break;
    }
    }
 
 
    // VC number
    // VC number
    mvc[mflit.vcn] = SC_LOGIC_1;
    mvc[mflit.vcn] = SC_LOGIC_1;
 
 
    // write to the port
    // write to the port
    rtid[0].write(mdata[0]);
    rtid[0].write(mdata[0]);
    rtid[1].write(mdata[1]);
    rtid[1].write(mdata[1]);
    rtid[2].write(mdata[2]);
    rtid[2].write(mdata[2]);
    rtid[3].write(mdata[3]);
    rtid[3].write(mdata[3]);
    rtivc.write(mvc);
    rtivc.write(mvc);
    rtift.write(mft);
    rtift.write(mft);
 
 
    // wait for the router to capture the data
    // wait for the router to capture the data
    wait(rtinp_sig.posedge_event());
    wait(rtinp_sig.posedge_event());
    wait(0.2, SC_NS);           // a delay to avoid data override
    wait(0.2, SC_NS);           // a delay to avoid data override
 
 
    // clear the data
    // clear the data
    mdata[0] = 0;
    mdata[0] = 0;
    mdata[1] = 0;
    mdata[1] = 0;
    mdata[2] = 0;
    mdata[2] = 0;
    mdata[3] = 0;
    mdata[3] = 0;
    mvc = 0;
    mvc = 0;
    mft = 0;
    mft = 0;
 
 
    rtid[0].write(mdata[0]);
    rtid[0].write(mdata[0]);
    rtid[1].write(mdata[1]);
    rtid[1].write(mdata[1]);
    rtid[2].write(mdata[2]);
    rtid[2].write(mdata[2]);
    rtid[3].write(mdata[3]);
    rtid[3].write(mdata[3]);
    rtivc.write(mvc);
    rtivc.write(mvc);
    rtift.write(mft);
    rtift.write(mft);
 
 
    // wait for the input port be ready again
    // wait for the input port be ready again
    wait(rtinp_sig.negedge_event());
    wait(rtinp_sig.negedge_event());
    wait(0.2, SC_NS);           // a delay to avoid data override
    wait(0.2, SC_NS);           // a delay to avoid data override
  }
  }
}
}
 
 
void RTDriver::recv() {
void RTDriver::recv() {
  FLIT mflit;                   // the local flit buffer
  FLIT mflit;                   // the local flit buffer
  sc_lv<ChBW*4> mdata[4];       // local data copy
  sc_lv<ChBW*4> mdata[4];       // local data copy
  sc_lv<SubChN> mvc;            // local vc number
  sc_lv<SubChN> mvc;            // local vc number
  sc_lv<3> mft;                 // local flit type
  sc_lv<3> mft;                 // local flit type
  sc_logic mack = SC_LOGIC_0;   // local copy of ack
  sc_logic mack = SC_LOGIC_0;   // local copy of ack
  sc_lv<4> dd;                // the current 1-of-4 data under process
  sc_lv<4> dd;                // the current 1-of-4 data under process
  unsigned int i, j;          // local loop index
  unsigned int i, j;          // local loop index
 
 
  // initialize the ack signal
  // initialize the ack signal
  rtoa.write(mack);
  rtoa.write(mack);
 
 
  while(true) {
  while(true) {
    // wait for an incoming flit
    // wait for an incoming flit
    wait(rtoutp_sig.posedge_event());
    wait(rtoutp_sig.posedge_event());
    if(out_cred_ack[mflit.vcn].read())
    if(out_cred_ack[mflit.vcn].read())
      wait(out_cred_ack[mflit.vcn].negedge_event());
      wait(out_cred_ack[mflit.vcn].negedge_event());
 
 
    // clear the flit
    // clear the flit
    mflit.clear();
    mflit.clear();
 
 
    // analyse the flit
    // analyse the flit
    mdata[0] = rtod[0].read();
    mdata[0] = rtod[0].read();
    mdata[1] = rtod[1].read();
    mdata[1] = rtod[1].read();
    mdata[2] = rtod[2].read();
    mdata[2] = rtod[2].read();
    mdata[3] = rtod[3].read();
    mdata[3] = rtod[3].read();
    mft = rtoft.read();
    mft = rtoft.read();
    mvc = rtovc.read();
    mvc = rtovc.read();
 
 
    switch(mft.to_uint()) {
    switch(mft.to_uint()) {
    case 1: mflit.ftype = F_HD; break;
    case 1: mflit.ftype = F_HD; break;
    case 2: mflit.ftype = F_DAT; break;
    case 2: mflit.ftype = F_DAT; break;
    case 4: mflit.ftype = F_TL; break;
    case 4: mflit.ftype = F_TL; break;
    default: mflit.ftype = F_IDLE; // shoudle not happen
    default: mflit.ftype = F_IDLE; // shoudle not happen
    }
    }
 
 
    if(mflit.ftype == F_HD) {
    if(mflit.ftype == F_HD) {
      // fetch the address
      // fetch the address
      dd[0] = mdata[0][0]; dd[1] = mdata[1][0]; dd[2] = mdata[2][0]; dd[3] = mdata[3][0];
      dd[0] = mdata[0][0]; dd[1] = mdata[1][0]; dd[2] = mdata[2][0]; dd[3] = mdata[3][0];
      mflit.addrx |= (c1o42b(dd.to_uint()) << 0);
      mflit.addrx |= (c1o42b(dd.to_uint()) << 0);
      dd[0] = mdata[0][1]; dd[1] = mdata[1][1]; dd[2] = mdata[2][1]; dd[3] = mdata[3][1];
      dd[0] = mdata[0][1]; dd[1] = mdata[1][1]; dd[2] = mdata[2][1]; dd[3] = mdata[3][1];
      mflit.addrx |= (c1o42b(dd.to_uint()) << 2);
      mflit.addrx |= (c1o42b(dd.to_uint()) << 2);
      dd[0] = mdata[0][2]; dd[1] = mdata[1][2]; dd[2] = mdata[2][2]; dd[3] = mdata[3][2];
      dd[0] = mdata[0][2]; dd[1] = mdata[1][2]; dd[2] = mdata[2][2]; dd[3] = mdata[3][2];
      mflit.addry |= (c1o42b(dd.to_uint()) << 0);
      mflit.addry |= (c1o42b(dd.to_uint()) << 0);
      dd[0] = mdata[0][3]; dd[1] = mdata[1][3]; dd[2] = mdata[2][3]; dd[3] = mdata[3][3];
      dd[0] = mdata[0][3]; dd[1] = mdata[1][3]; dd[2] = mdata[2][3]; dd[3] = mdata[3][3];
      mflit.addry |= (c1o42b(dd.to_uint()) << 2);
      mflit.addry |= (c1o42b(dd.to_uint()) << 2);
 
 
      // fill in data
      // fill in data
      for(i=1; i<ChBW; i++) {
      for(i=1; i<ChBW; i++) {
        for(j=0; j<4; j++) {
        for(j=0; j<4; j++) {
          dd[0] = mdata[0][i*4+j];
          dd[0] = mdata[0][i*4+j];
          dd[1] = mdata[1][i*4+j];
          dd[1] = mdata[1][i*4+j];
          dd[2] = mdata[2][i*4+j];
          dd[2] = mdata[2][i*4+j];
          dd[3] = mdata[3][i*4+j];
          dd[3] = mdata[3][i*4+j];
          mflit[i-1] |= c1o42b(dd.to_uint()) << j*2;
          mflit[i-1] |= c1o42b(dd.to_uint()) << j*2;
        }
        }
      }
      }
    } else{
    } else{
      for(i=0; i<ChBW; i++) {
      for(i=0; i<ChBW; i++) {
        for(j=0; j<4; j++) {
        for(j=0; j<4; j++) {
          dd[0] = mdata[0][i*4+j];
          dd[0] = mdata[0][i*4+j];
          dd[1] = mdata[1][i*4+j];
          dd[1] = mdata[1][i*4+j];
          dd[2] = mdata[2][i*4+j];
          dd[2] = mdata[2][i*4+j];
          dd[3] = mdata[3][i*4+j];
          dd[3] = mdata[3][i*4+j];
          mflit[i] |= c1o42b(dd.to_uint()) << j*2;
          mflit[i] |= c1o42b(dd.to_uint()) << j*2;
        }
        }
      }
      }
    }
    }
 
 
    // get the binary vc number
    // get the binary vc number
    unsigned int fvcn = mvc.to_uint();
    unsigned int fvcn = mvc.to_uint();
    while(fvcn != 1) {
    while(fvcn != 1) {
      mflit.vcn += 1;
      mflit.vcn += 1;
      fvcn >>= 1;
      fvcn >>= 1;
    }
    }
 
 
    // send the flit to the NI
    // send the flit to the NI
    P2NI->write(mflit);
    P2NI->write(mflit);
 
 
    // send back a credit
    // send back a credit
    out_cred[mflit.vcn] = true;
    out_cred[mflit.vcn] = true;
 
 
    wait(0.2, SC_NS);           // a delay to avoid data override
    wait(0.2, SC_NS);           // a delay to avoid data override
    rtoa.write(~mack);          // notify that data is captured
    rtoa.write(~mack);          // notify that data is captured
 
 
    // wait for the data withdrawal
    // wait for the data withdrawal
    wait(rtoutp_sig.negedge_event());
    wait(rtoutp_sig.negedge_event());
    if(!out_cred_ack[mflit.vcn].read())
    if(!out_cred_ack[mflit.vcn].read())
      wait(out_cred_ack[mflit.vcn].posedge_event());
      wait(out_cred_ack[mflit.vcn].posedge_event());
 
 
    wait(0.2, SC_NS);           // a delay to avoid data override
    wait(0.2, SC_NS);           // a delay to avoid data override
    rtoa.write(mack);           // notify that data is captured
    rtoa.write(mack);           // notify that data is captured
    out_cred[mflit.vcn] = false;
    out_cred[mflit.vcn] = false;
  }
  }
}
}
 
 
unsigned int RTDriver::c1o42b(unsigned int dd) {
unsigned int RTDriver::c1o42b(unsigned int dd) {
  switch(dd) {
  switch(dd) {
  case 1: return 0;
  case 1: return 0;
  case 2: return 1;
  case 2: return 1;
  case 4: return 2;
  case 4: return 2;
  case 8: return 3;
  case 8: return 3;
  default: return 0xff;
  default: return 0xff;
  }
  }
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.