/*
|
/*
|
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 SystemC processing element.
|
The SystemC processing element.
|
|
|
History:
|
History:
|
26/02/2011 Initial version. <wsong83@gmail.com>
|
26/02/2011 Initial version. <wsong83@gmail.com>
|
30/05/2011 Clean up for opensource. <wsong83@gmail.com>
|
31/05/2011 Clean up for opensource. <wsong83@gmail.com>
|
|
|
*/
|
*/
|
|
|
#ifndef PROCELEM_H_
|
#ifndef PROCELEM_H_
|
#define PROCELEM_H_
|
#define PROCELEM_H_
|
|
|
#include "define.h"
|
#include "define.h"
|
#include <systemc.h>
|
#include <systemc.h>
|
|
|
|
|
// a function to generate random numbers comply with an exponential distribution with expection exp
|
// a function to generate random numbers comply with an exponential distribution with expection exp
|
double rand_exponential(double exp) {
|
double rand_exponential(double exp) {
|
unsigned int rint = rand() % (unsigned int)(1e6);
|
unsigned int rint = rand() % (unsigned int)(1e6);
|
double rdat = rint * 1.0 / 1e6;
|
double rdat = rint * 1.0 / 1e6;
|
return (-1 * exp * log(rint));
|
return (-1.0 * exp * log(rdat));
|
}
|
}
|
|
|
class ProcElem : public sc_module {
|
class ProcElem : public sc_module {
|
|
|
public:
|
public:
|
sc_in<bool> rst_n; // active low reset
|
sc_in<bool> rst_n; // active low reset
|
sc_port<sc_fifo_out_if<FRAME> > Fout; // frame output port
|
sc_port<sc_fifo_out_if<FRAME> > Fout; // frame output port
|
sc_port<sc_fifo_in_if<FRAME> > Fin; // frame input port
|
sc_port<sc_fifo_in_if<FRAME> > Fin; // frame input port
|
|
|
SC_HAS_PROCESS(ProcElem);
|
SC_HAS_PROCESS(ProcElem);
|
|
|
unsigned int addrx, addry; // the local address
|
unsigned int addrx, addry; // the local address
|
|
|
ProcElem(sc_module_name nm, unsigned int addrx, unsigned int addry)
|
ProcElem(sc_module_name nm, unsigned int addrx, unsigned int addry)
|
: sc_module(nm), addrx(addrx), addry(addry)
|
: sc_module(nm), addrx(addrx), addry(addry)
|
{
|
{
|
SC_THREAD(tproc); // frame transmission thread
|
SC_THREAD(tproc); // frame transmission thread
|
SC_THREAD(rproc); // frame receiving thread
|
SC_THREAD(rproc); // frame receiving thread
|
}
|
}
|
|
|
// the transmission thread
|
// the transmission thread
|
void tproc() {
|
void tproc() {
|
// waiting for reset
|
// waiting for reset
|
wait(rst_n.posedge_event());
|
wait(rst_n.posedge_event());
|
|
|
while(1) {
|
while(1) {
|
// wait for a random interval
|
// wait for a random interval
|
if(FFreq != 0) {
|
if(FFreq != 0) {
|
double rnum = rand_exponential(1e6/FFreq);
|
double rnum = rand_exponential(1e6/FFreq);
|
wait(rnum, SC_PS);
|
wait(rnum, SC_PS);
|
}
|
}
|
|
|
// generate a frame
|
// generate a frame
|
// specify the target address according to random uniform traffic
|
// specify the target address according to random uniform traffic
|
unsigned int rint, tarx, tary;
|
unsigned int rint, tarx, tary;
|
rint = rand()%(DIMX*DIMY-1);
|
rint = rand()%(DIMX*DIMY-1);
|
if(rint == addrx*DIMY + addry)
|
if(rint == addrx*DIMY + addry)
|
rint = DIMX*DIMY-1;
|
rint = DIMX*DIMY-1;
|
|
|
tarx = rint/DIMY;
|
tarx = rint/DIMY;
|
tary = rint%DIMY;
|
tary = rint%DIMY;
|
|
|
// initialize the frame object
|
// initialize the frame object
|
FRAME tframe(FLEN);
|
FRAME tframe(FLEN);
|
|
|
// fill in the fields
|
// fill in the fields
|
tframe.addrx = tarx;
|
tframe.addrx = tarx;
|
tframe.addry = tary;
|
tframe.addry = tary;
|
for(unsigned int i=0; i<FLEN; i++)
|
for(unsigned int i=0; i<FLEN; i++)
|
tframe.push(rand()&0xff);
|
tframe.push(rand()&0xff);
|
|
|
// specify the unique key of each frame
|
// specify the unique key of each frame
|
// a key is 32 bits log
|
// a key is 32 bits log
|
// in this test bench, it is the first 4 bytes of the frame payload
|
// in this test bench, it is the first 4 bytes of the frame payload
|
unsigned long key = 0;
|
unsigned long key = 0;
|
for(unsigned int i=0; (i<FLEN && i<4); i++) {
|
for(unsigned int i=0; (i<FLEN && i<4); i++) {
|
key <<= 8;
|
key <<= 8;
|
key |= tframe[i];
|
key |= tframe[i];
|
}
|
}
|
|
|
// record the new frame
|
// record the new frame
|
ANA->start(key, sc_time_stamp().to_double());
|
ANA->start(key, sc_time_stamp().to_double());
|
|
|
// sen the frame to the router
|
// sen the frame to the router
|
Fout->write(tframe);
|
Fout->write(tframe);
|
}
|
}
|
}
|
}
|
|
|
// the receiving thread
|
// the receiving thread
|
void rproc() {
|
void rproc() {
|
while(1) {
|
while(1) {
|
// initialize a space for the frame
|
// initialize a space for the frame
|
FRAME rframe;
|
FRAME rframe;
|
|
|
// read in the frame
|
// read in the frame
|
rframe = Fin->read();
|
rframe = Fin->read();
|
unsigned long key = 0;
|
unsigned long key = 0;
|
|
|
// regenerate the unique key
|
// regenerate the unique key
|
for(unsigned int i=0; (i<FLEN && i<4); i++) {
|
for(unsigned int i=0; (i<FLEN && i<4); i++) {
|
key <<= 8;
|
key <<= 8;
|
key |= rframe[i];
|
key |= rframe[i];
|
}
|
}
|
|
|
// check the key in the simulation analysis database and update info.
|
// check the key in the simulation analysis database and update info.
|
if(!ANA->stop(key, sc_time_stamp().to_double(), rframe.psize())) {
|
if(!ANA->stop(key, sc_time_stamp().to_double(), rframe.psize())) {
|
// report error when no match is found
|
// report error when no match is found
|
cout << sc_time_stamp() << " " << name() ;
|
cout << sc_time_stamp() << " " << name() ;
|
cout << "packet did not find!" << endl;
|
cout << "packet did not find!" << endl;
|
cout << rframe << endl;
|
cout << rframe << endl;
|
sc_stop();
|
sc_stop();
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
};
|
};
|
|
|
#endif
|
#endif
|
|
|
|
|