URL
https://opencores.org/ocsvn/async_sdm_noc/async_sdm_noc/trunk
Subversion Repositories async_sdm_noc
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 29 to Rev 30
- ↔ Reverse comparison
Rev 29 → Rev 30
/async_sdm_noc/branches/init/sdm/define.h
0,0 → 1,48
/* |
Asynchronous SDM NoC |
(C)2011 Wei Song |
Advanced Processor Technologies Group |
Computer Science, the Univ. of Manchester, UK |
|
Authors: |
Wei Song wsong83@gmail.com |
|
License: LGPL 3.0 or later |
|
The define file for the SystemC test modules |
|
History: |
28/05/2011 Clean up for opensource. <wsong83@gmail.com> |
|
*/ |
|
#ifndef NOC_DEF_H_ |
#define NOC_DEF_H_ |
|
#define SC_INCLUDE_DYNAMIC_PROCESSES |
#include "sim_ana.h" |
#include "pdu_def.h" |
|
// channel bandwidth |
const unsigned int ChBW = 1; // the data width of a single virtual circuit in unit of bytes |
const unsigned int SubChN = 4; // the number of virtual circuits or VCs per direction |
const unsigned int FSIZE_MAX = 512; // the longest frame has 512 bytes of data |
|
const unsigned int DIMX = 4; // the X size of the mesh network |
const unsigned int DIMY = 4; // the Y size of the mesh network |
const unsigned int FLEN = 64; // the payload size of a frame in unit of bytes |
|
const unsigned int BufDepth = 1; // the depth of the input buffer (only useful in VC routers to determine the inital tokens in output ports) |
|
const double FFreq = 0.1; // Node injection rate, in unit of MFlit/second |
|
const double Record_Period = 1e3 * 1e3; // the interval of recording the average performance to log files, in unit of ps |
const double Warm_UP = 0e4 * 1e3; // the warm up time of performance analysis, in unit of ps |
const double SIM_TIME = 1e3 * 1e3; // the overall simulation time of the netowrk, in unit of ns |
|
extern sim_ana * ANA; // declaration of the global simulation analysis module |
|
typedef pdu_flit<ChBW> FLIT; // define the template of flit |
typedef pdu_frame<ChBW> FRAME; // define the template of frame |
|
#endif |
/async_sdm_noc/branches/init/common/tb/anaproc.cpp
0,0 → 1,26
/* |
Asynchronous SDM NoC |
(C)2011 Wei Song |
Advanced Processor Technologies Group |
Computer Science, the Univ. of Manchester, UK |
|
Authors: |
Wei Song wsong83@gmail.com |
|
License: LGPL 3.0 or later |
|
The SystemC to keep a module of the simulation analysis object. |
|
History: |
27/02/2011 Initial version. <wsong83@gmail.com> |
28/05/2011 Clean up for opensource. <wsong83@gmail.com> |
|
*/ |
|
#include "anaproc.h" |
|
NCSC_MODULE_EXPORT(AnaProc) |
|
// the simulation analysis object, global object |
sim_ana * ANA = new sim_ana(Warm_UP, Record_Period); |
|
/async_sdm_noc/branches/init/common/tb/anaproc.h
0,0 → 1,46
/* |
Asynchronous SDM NoC |
(C)2011 Wei Song |
Advanced Processor Technologies Group |
Computer Science, the Univ. of Manchester, UK |
|
Authors: |
Wei Song wsong83@gmail.com |
|
License: LGPL 3.0 or later |
|
The SystemC to keep a module of the simulation analysis object. |
|
History: |
27/02/2011 Initial version. <wsong83@gmail.com> |
28/05/2011 Clean up for opensource. <wsong83@gmail.com> |
|
*/ |
|
#ifndef ANA_PROC_H_ |
#define ANA_PROC_H_ |
|
#include "define.h" |
#include <systemc.h> |
|
class AnaProc : public sc_module { |
|
public: |
SC_CTOR(AnaProc) |
{ |
ANA->analyze_delay("delay.ana"); |
ANA->analyze_throughput("throughput.ana"); |
SC_THREAD(run_proc); |
} |
|
void run_proc() { |
while(1){ |
wait(SIM_TIME, SC_NS); |
} |
} |
|
}; |
|
|
|
#endif |
/async_sdm_noc/branches/init/common/tb/pdu_def.h
0,0 → 1,304
/* |
Asynchronous SDM NoC |
(C)2011 Wei Song |
Advanced Processor Technologies Group |
Computer Science, the Univ. of Manchester, UK |
|
Authors: |
Wei Song wsong83@gmail.com |
|
License: LGPL 3.0 or later |
|
Package definition. |
|
History: |
19/08/2008 Initial version. <wsong83@gmail.com> |
04/08/2008 Add the check empty function. <wsong83@gmail.com> |
22/09/2008 Override the copy and = operations. <wsong83@gmail.com> |
21/09/2010 Support VC and use templates. <wsong83@gmail.com> |
19/11/2010 Fixed to support the minimal 8bit VC. <wsong83@gmail.com> |
27/05/2011 Clean up for opensource. <wsong83@gmail.com> |
|
*/ |
|
#ifndef PDU_DEF_H_ |
#define PDU_DEF_H_ |
|
#include <ostream> |
#include <iomanip> |
|
using namespace std; |
|
// flit types: data, idle, head and tail |
enum ftype_t {F_DAT, F_IDLE, F_HD, F_TL}; |
|
template<unsigned int BW> |
class pdu_flit; |
|
// override the method to stream out flits |
template<unsigned int BW> |
ostream& operator<< (ostream& os, const pdu_flit<BW>& dd) { |
switch(dd.ftype) { |
case F_DAT: |
os << hex << "<DATA:" << (unsigned int)(dd.vcn) << ":" << (unsigned int)(dd.prio) << ":"; |
for(unsigned int i=0; i<BW; i++) |
os << setw(2) << setfill('0') << (unsigned int)(dd[i]); |
os << setw(0) << dec << ">"; |
break; |
case F_HD: |
os << hex << "<HEAD:" << (unsigned int)(dd.vcn) << ":" << (unsigned int)(dd.prio) << ":" << (unsigned int)(dd.addrx) << "," << (unsigned int)(dd.addry) << ":"; |
for(unsigned int i=0; i<BW-1; i++) |
os << setw(2) << setfill('0') << (unsigned int)(dd[i]); |
os << setw(0) << dec << ">"; |
break; |
case F_TL: |
os << hex << "<TAIL:" << (unsigned int)(dd.vcn) << ":" << (unsigned int)(dd.prio) << ":"; |
for(unsigned int i=0; i<BW; i++) |
os << setw(2) << setfill('0') << (unsigned int)(dd[i]); |
os << setw(0) << dec << ">"; |
break; |
case F_IDLE: |
os << "<IDLE>" ; |
break; |
default: |
os << "<ERR!>" ; |
break; |
} |
|
return os; |
} |
|
// flit used in NoC communication |
template<unsigned int BW> |
class pdu_flit { |
public: |
unsigned char vcn; |
unsigned char prio; |
ftype_t ftype; |
unsigned int addrx, addry; |
private: |
unsigned char data [BW]; |
|
void copy(const pdu_flit<BW>& dd) { |
vcn = dd.vcn; |
prio = dd.prio; |
ftype = dd.ftype; |
addrx = dd.addrx; |
addry = dd.addry; |
for(unsigned int i=0; i<BW; i++) data[i] = dd.data[i]; |
} |
|
public: |
pdu_flit() |
: vcn(0), prio(0), ftype(F_IDLE) |
{ |
for(unsigned int i=0; i<BW; i++) data[i] = 0; |
} |
|
void clear(){ // clear the flit |
vcn = 0; |
prio = 0; |
ftype = F_IDLE; |
for(unsigned int i=0; i<BW; i++) data[i] = 0; |
} |
|
unsigned char& operator[] (unsigned int index){ // read as a vector |
return data[index]; |
} |
|
const unsigned char& operator[] (unsigned int index) const { // read as a vector |
return data[index]; |
} |
|
friend ostream& operator<< <BW> (ostream& os, const pdu_flit<BW>& dd); // output to standard output stream |
|
pdu_flit(const pdu_flit<BW>& dd){ // override the default copy operation |
copy(dd); |
} |
|
pdu_flit& operator=(const pdu_flit<BW>& dd){ // override the default eque with operation |
copy(dd); |
return(*this); |
} |
}; |
|
//=============================================================================== |
// method to stream out frames |
template<unsigned int BW> |
class pdu_frame; |
|
template<unsigned int BW> |
ostream& operator<< (ostream& os, const pdu_frame<BW>& dd) { |
os << hex << "<FRAME:p" << (unsigned int)(dd.prio) << ":a" << (unsigned int)(dd.addrx) << "," << (unsigned int)(dd.addry) << ":s" << dd.fsize << ":"; |
// os << setw(2) << setfill('0'); |
for(unsigned int i=0; i<dd.fsize; i++) |
os << setw(2) << setfill('0') << (unsigned int)(dd[i]); |
os << setw(0) << dec << ">"; |
return os; |
} |
|
// frame definition |
template<unsigned int BW> |
class pdu_frame{ |
|
public: |
unsigned int addrx, addry; |
unsigned char prio; |
unsigned int fsize; |
int rptr, wptr; |
|
private: |
unsigned char * data; // data field |
|
public: |
pdu_frame() |
: addrx(0), addry(0), prio(0), fsize(0), rptr(-1), wptr(0), data(NULL) |
{} |
|
pdu_frame(unsigned int fs) |
: addrx(0), addry(0), prio(0), fsize(fs), rptr(-1), wptr(0) |
{ |
data = new unsigned char [fs]; |
} |
|
~pdu_frame() { |
if(data != NULL) { |
delete[] data; |
data = NULL; |
} |
} |
|
void clear() { |
rptr = -1; |
wptr = 0; |
} |
|
unsigned char& operator[] (unsigned int index) { |
if(index > fsize) // need to enlarge the buf |
resize(index); |
|
return data[index]; |
} |
|
const unsigned char& operator[] (unsigned int index) const { |
return data[index]; |
} |
|
bool empty() { |
return ((rptr == wptr) || (wptr == 0)); |
} |
|
void push(unsigned char dd) { |
if(wptr==fsize) |
resize(fsize+1); |
|
data[wptr++] = dd; |
} |
|
unsigned char pop() { |
if(empty()) |
return 0; |
|
return data[rptr++]; |
} |
|
pdu_frame& operator<< (const pdu_flit<BW>& dd) { |
switch(dd.ftype) { |
case F_DAT: |
for(unsigned int i=0; i<BW; i++) |
push(dd[i]); |
break; |
case F_HD: |
addrx = dd.addrx; |
addry = dd.addry; |
prio = dd.prio; |
for(unsigned int i=0; i<BW-1; i++) |
push(dd[i]); |
break; |
case F_TL: |
for(unsigned int i=0; i<BW; i++) |
push(dd[i]); |
resize(wptr); |
break; |
default: |
break; |
} |
return *this; |
} |
|
pdu_frame& operator>> (pdu_flit<BW>& dd) { |
if(rptr==-1) { |
dd.ftype = F_HD; |
rptr++; |
for(unsigned int i=0; i<BW-1; i++) { |
dd[i] = pop(); |
} |
dd.addrx = addrx; |
dd.addry = addry; |
} else { |
dd.ftype = F_DAT; |
for(unsigned int i=0; i<BW; i++) { |
dd[i] = pop(); |
} |
} |
if(empty()) |
dd.ftype = F_TL; |
|
return *this; |
} |
|
// friend ostream& operator<< <BW> (ostream& os, const pdu_frame<BW>& dd); |
|
pdu_frame(const pdu_frame<BW>& dd) { |
copy(dd); |
} |
|
pdu_frame<BW>& operator=(const pdu_frame<BW>& dd) { |
copy(dd); |
return (*this); |
} |
|
unsigned int psize() { |
unsigned int prac_size = fsize; |
while(1) { |
if(data[prac_size-1] == 0) |
prac_size--; |
else |
break; |
} |
return prac_size; |
} |
|
private: |
void resize(unsigned int fs) { |
// boundry check |
if(fs == fsize) |
return; |
|
// resize the buffer |
unsigned char * buf = new unsigned char [fs]; |
for(unsigned int i=0; (i<fsize && i<fs); i++) { |
buf[i] = data[i]; |
} |
fsize = fs; |
delete[] data; |
data = buf; |
} |
|
void copy(const pdu_frame<BW>& dd) { |
addrx = dd.addrx; |
addry = dd.addry; |
prio = dd.prio; |
resize(dd.fsize); |
rptr = dd.rptr; |
wptr = dd.wptr; |
|
for(unsigned int i=0; i<fsize; i++) { |
data[i] = dd.data[i]; |
} |
} |
|
}; |
|
|
#endif /* PDU_DEF_H_ */ |
/async_sdm_noc/branches/init/common/tb/procelem.h
0,0 → 1,130
/* |
Asynchronous SDM NoC |
(C)2011 Wei Song |
Advanced Processor Technologies Group |
Computer Science, the Univ. of Manchester, UK |
|
Authors: |
Wei Song wsong83@gmail.com |
|
License: LGPL 3.0 or later |
|
The SystemC processing element. |
|
History: |
26/02/2011 Initial version. <wsong83@gmail.com> |
28/05/2011 Clean up for opensource. <wsong83@gmail.com> |
|
*/ |
|
#ifndef PROCELEM_H_ |
#define PROCELEM_H_ |
|
#include "noc_define.h" |
#include <systemc.h> |
|
|
// a function to generate random numbers comply with an exponential distribution with expection exp |
double rand_exp(double exp) { |
unsigned int rint = rand()%1e6; |
double rdat = rint * 1.0 / 1e6; |
return (-1 * exp * log(rint)); |
} |
|
class ProcElem : public sc_module { |
|
public: |
sc_in<bool> rst_n; // active low reset |
sc_port<sc_fifo_out_if<FRAME> > Fout; // frame output port |
sc_port<sc_fifo_in_if<FRAME> > Fin; // frame input port |
|
SC_HAS_PROCESS(ProcElem); |
|
unsigned int addrx, addry; // the local address |
|
ProcElem(sc_module_name nm, unsigned int addrx, unsigned int addry) |
: sc_module(nm), addrx(addrx), addry(addry) |
{ |
SC_THREAD(tproc); // frame transmission thread |
SC_THREAD(rproc); // frame receiving thread |
} |
|
// the transmission thread |
void tproc() { |
// waiting for reset |
wait(rst_n.posedge_event()); |
|
while(1) { |
// wait for a random interval |
if(FFreq != 0) { |
double rnum = rand_exponential(1e6/FFreq); |
wait(rnum, SC_PS); |
} |
|
// generate a frame |
// specify the target address according to random uniform traffic |
unsigned int rint, tarx, tary; |
rint = rand()%(DIMX*DIMY-1); |
if(rint == addrx*DIMY + addry) |
rint = DIMX*DIMY-1; |
|
tarx = rint/DIMY; |
tary = rint%DIMY; |
|
// initialize the frame object |
FRAME tframe(FLEN); |
|
// fill in the fields |
tframe.addrx = tarx; |
tframe.addry = tary; |
for(unsigned int i=0; i<FLEN; i++) |
tframe.push(rand()&0xff); |
|
// specify the unique key of each frame |
// a key is 32 bits log |
// in this test bench, it is the first 4 bytes of the frame payload |
unsigned long key = 0; |
for(unsigned int i=0; (i<FLEN && i<4); i++) { |
key <<= 8; |
key |= tframe[i]; |
} |
|
// record the new frame |
ANA->start(key, sc_time_stamp().to_double()); |
|
// sen the frame to the router |
Fout->write(tframe); |
} |
} |
|
// the receiving thread |
void rproc() { |
while(1) { |
// initialize a space for the frame |
FRAME rframe; |
|
// read in the frame |
rframe = Fin->read(); |
unsigned long key = 0; |
|
// regenerate the unique key |
for(unsigned int i=0; (i<FLEN && i<4); i++) { |
key <<= 8; |
key |= rframe[i]; |
} |
|
// check the key in the simulation analysis database and update info. |
if(!ANA->stop(key, sc_time_stamp().to_double(), rframe.psize())) { |
// report error when no match is found |
cout << sc_time_stamp() << " " << name() ; |
cout << "packet did not find!" << endl; |
cout << rframe << endl; |
sc_stop(); |
} |
} |
} |
|
}; |
|
#endif |
|
/async_sdm_noc/branches/init/common/tb/sim_ana.h
17,7 → 17,7
|
History: |
29/06/2010 Initial version. <wsong83@gmail.com> |
27/05/2011 Clean up for opensource. <wsong83@gmail.com> |
28/05/2011 Clean up for opensource. <wsong83@gmail.com> |
|
*/ |
|