OpenCores
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
    /async_sdm_noc/trunk/common/tb
    from Rev 22 to Rev 37
    Reverse comparison

Rev 22 → Rev 37

/hash_table.h
0,0 → 1,145
/*
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
A hash table container to store the frames under transmission.
?? Using STL may be better?
 
Sorry, I have no intention to explain the codes below as it is unlikely to modify it.
If there are bugs here, please email me.
History:
29/06/2010 Initial version. <wsong83@gmail.com>
27/05/2011 Clean up for opensource. <wsong83@gmail.com>
*/
 
#ifndef HASH_TABLE_H_
#define HASH_TABLE_H_
 
#include <ostream>
 
using namespace std;
 
template<typename T, unsigned int HSIZE>
class hash_table;
 
 
template<typename T, unsigned int HSIZE>
ostream& operator<< (ostream& os, const hash_table<T,HSIZE>& HB) {
T * item;
os << "Records in hash table:" << endl;
for(unsigned int i=0; i<HSIZE; i++) {
os << "vector " << i << ": ";
item = HB.dat[i][0];
while(item != NULL) {
os << *item << "| ";
item = item->next;
}
os << endl;
}
return os;
}
 
template<typename T, unsigned int HSIZE>
class hash_table {
 
public:
T * dat [HSIZE][2];
hash_table() {
for(unsigned int i=0; i<HSIZE; i++) {
dat[i][0] = NULL;
dat[i][1] = NULL;
}
}
 
void insert ( T& ); /* insert an item into the hash table */
T * find ( long ); /* find an item */
T * find ( const T& ); /* find an item by reading an existing item */
void clear ( T * ); /* delete an item in the hash table */
~hash_table() {
for(unsigned int i=0; i<HSIZE; i++) {
if(dat[i][0] != NULL) {
delete dat[i][0];
dat[i][0] = NULL;
dat[i][1] = NULL;
}
}
}
 
friend ostream& operator<< <T,HSIZE> (ostream&, const hash_table<T,HSIZE>&);
 
private:
T* search (T*, long);
};
 
template<typename T, unsigned int HSIZE>
void hash_table<T,HSIZE>::insert ( T& RD) {
long key = RD.key;
unsigned int vcn = key%HSIZE;
T * entry = dat[vcn][1];
if(entry == NULL) { /* the whole vector is empty right now */
dat[vcn][0] = &RD;
dat[vcn][1] = &RD;
} else { /* non-empty vector */
entry->next = &RD;
RD.pre = entry;
dat[vcn][1] = &RD;
}
}
 
template<typename T, unsigned int HSIZE>
T * hash_table<T,HSIZE>::find ( long mkey) {
unsigned int vcn = mkey%HSIZE;
return search(dat[vcn][0], mkey);
}
 
template<typename T, unsigned int HSIZE>
T * hash_table<T,HSIZE>::find ( const T& RD) {
return find((long)(RD));
}
template<typename T, unsigned int HSIZE>
void hash_table<T,HSIZE>::clear ( T * RD) {
unsigned int vcn = ((long)(*RD)) % HSIZE;
if(RD->pre == NULL) /* head of a vector */
dat[vcn][0] = RD->next;
if(RD->next == NULL) /* tail of a vector */
dat[vcn][1] = RD->pre;
 
if(RD->pre != NULL)
(RD->pre)->next = RD->next;
 
if(RD->next != NULL)
(RD->next)->pre = RD->pre;
 
RD->pre = NULL;
RD->next = NULL;
 
delete RD;
}
 
template<typename T, unsigned int HSIZE>
T* hash_table<T,HSIZE>::search (T* entry, long mkey) {
while(entry != NULL) {
if((long)(*entry) == mkey)
return entry;
else
entry = entry->next;
}
return NULL;
}
 
#endif
/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 class 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);
 
/anaproc.v
0,0 → 1,32
/*
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>
30/05/2011 Clean up for opensource. <wsong83@gmail.com>
*/
 
module AnaProc ()
//
// The foreign attribute string value must be a SystemC value.
//
(* integer foreign = "SystemC";
*);
//
// Verilog port names must match port names exactly as they appear in the
// sc_module class in SystemC; they must also match in order, mode, and type.
//
endmodule
/sim_ana.cpp
0,0 → 1,186
/*
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
Simulation analyzer, gethering info. for performance analyses.
Possible bugs:
* the histograph function has not been tested yet.
 
 
History:
29/06/2010 Initial version. <wsong83@gmail.com>
27/05/2011 Clean up for opensource. <wsong83@gmail.com>
*/
 
#include "sim_ana.h"
 
bool sim_ana::set_ana_parameters(double mwt, double mrp) {
if((mwt < 0) || (mrp < 0))
return false;
 
warm_time = mwt;
record_period = mrp;
return true;
}
 
bool sim_ana::analyze_delay(string mfname) {
ofstream file_handle;
 
delay_ana = true;
delay_file = mfname;
file_handle.open(delay_file.data(), fstream::trunc);
file_handle.close();
 
return true;
}
 
bool sim_ana::analyze_throughput(string mfname) {
ofstream file_handle;
 
throughput_ana = true;
throughput_file = mfname;
file_handle.open(throughput_file.data(), fstream::trunc);
file_handle.close();
 
return true;
}
 
bool sim_ana::analyze_delay_histo(string mframe, double tstart, double tend, unsigned int binnum) {
ofstream file_handle;
if((tstart < 0) || (tend <= tstart) || (binnum < 3))
return false;
 
delay_histo_ana = true;
delay_histo_file = mframe;
 
file_handle.open(delay_histo_file.data(), fstream::trunc);
file_handle.close();
 
delay_histo_start = tstart;
delay_histo_end = tend;
delay_histo_gap = (tstart - tend) / (binnum - 2);
delay_histo_binnum = binnum;
 
histo_data = new unsigned long [binnum];
 
for(unsigned int i=0; i<binnum; i++)
histo_data[i] = 0;
 
return true;
}
bool sim_ana::start(long mkey, double mtime) {
sim_record<2> * mrd;
mrd = new sim_record<2> (mtime, mkey);
 
ANA.insert(*mrd);
 
return true;
}
 
bool sim_ana::stop(long mkey, double mtime, unsigned int payload) {
ofstream file_handle;
sim_record<2> * mrd;
 
mrd = ANA.find(mkey);
if(mrd == NULL)
return false;
 
// cout << mtime << " " << mtime - mrd->stamp[0] << endl;
 
if(mtime < warm_time) {
ANA.clear(mrd);
return true;
}
 
if(delay_ana) {
fm_dly += (mtime - mrd->stamp[0]);
pth_dly += (mrd->stamp[1] - mrd->stamp[0]);
}
 
if(throughput_ana) {
th_value += payload;
}
 
if(delay_histo_ana) {
double delay = mtime - mrd->stamp[0];
if(delay >= delay_histo_end)
histo_data[delay_histo_binnum-1]++;
else {
delay -= delay_histo_start;
if(delay < 0)
histo_data[0]++;
else {
histo_data[(unsigned long)(1 + delay/delay_histo_gap)]++;
}
}
}
 
ANA.clear(mrd);
 
// check whether need to write out
if(floor(mtime/record_period) > floor(last_time/record_period)) {
if(delay_ana) {
file_handle.open(delay_file.data(), fstream::app);
file_handle << mtime << "\t" << fm_dly.avalue() << "\t" << pth_dly.avalue() << endl;
file_handle.close();
}
if(throughput_ana) {
file_handle.open(throughput_file.data(), fstream::app);
file_handle << mtime << "\t" << th_value.value() << endl;
file_handle.close();
}
 
last_time = mtime;
}
 
return true;
}
bool sim_ana::record(long mkey, double mtime) {
sim_record<2> * mrd;
 
mrd = ANA.find(mkey);
if(mrd == NULL)
return false;
 
mrd->stamp[mrd->index] = mtime;
 
return true;
}
 
sim_ana::~sim_ana() {
ofstream file_handle;
 
if(delay_histo_ana) {
file_handle.open(delay_histo_file.data(), fstream::app);
for(unsigned int i=0; i<delay_histo_binnum; i++)
file_handle << (double)(delay_histo_start + i*delay_histo_gap) << "\t" << histo_data[i] << endl;
 
file_handle.close();
}
 
if(histo_data != NULL)
delete[] histo_data;
}
 
/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
/pdu_def.h
0,0 → 1,307
/*
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>
30/05/2011 Clear the addresses field when clear a flit. <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;
addrx = 0;
addry = 0;
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_ */
/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>
31/05/2011 Clean up for opensource. <wsong83@gmail.com>
*/
 
#ifndef PROCELEM_H_
#define PROCELEM_H_
 
#include "define.h"
#include <systemc.h>
 
 
// a function to generate random numbers comply with an exponential distribution with expection exp
double rand_exponential(double exp) {
unsigned int rint = rand() % (unsigned int)(1e6);
double rdat = rint * 1.0 / 1e6;
return (-1.0 * exp * log(rdat));
}
 
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
 
/sim_record.h
0,0 → 1,90
/*
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
Simulation record element.
History:
28/06/2010 Initial version. <wsong83@gmail.com>
27/05/2011 Clean up for opensource. <wsong83@gmail.com>
*/
 
#ifndef SIM_RECORD_H_
#define SIM_RECORD_H_
 
#include <ostream>
 
using namespace std;
 
template<unsigned int TSIZE>
class sim_record;
 
template<unsigned int TSIZE>
ostream& operator<< (ostream& os, const sim_record<TSIZE>& mrd) {
os << hex << mrd.key << " " << dec;
for(unsigned int i=0; i<TSIZE; i++)
os << mrd.stamp[i] << " ";
return os;
}
 
template<unsigned int TSIZE>
class sim_record {
 
public:
double stamp [TSIZE]; /* vector to record time information */
long key; /* the hash key for searching */
unsigned int index; /* the current stamp index */
sim_record<TSIZE> * next; /* pointer to the next record */
sim_record<TSIZE> * pre; /* pointer to the previous record */
 
sim_record()
: key(0), index(0), next(NULL), pre(NULL)
{}
sim_record(double mt, long mkey, sim_record<TSIZE> * mnp = NULL, sim_record<TSIZE> * mpp = NULL)
: key(mkey), index(1), next(mnp), pre(mpp) {
for(unsigned int i=0; i<TSIZE; i++)
stamp[i] = mt;
}
 
sim_record( const sim_record<TSIZE>& mrd )
: key(mrd.key), index(mrd.index), next(NULL), pre(NULL) {
for(unsigned int i=0; i<TSIZE; i++)
stamp[i] = mrd.stamp[i];
}
 
sim_record<TSIZE>& operator= ( const sim_record<TSIZE>& mrd ) {
key = mrd.key;
index = mrd.index;
next = NULL;
pre = NULL;
for(unsigned int i=0; i<TSIZE; i++)
stamp[i] = mrd.stamp[i];
}
 
~sim_record() {
if(next != NULL) {
delete next;
next = NULL;
}
pre = NULL;
}
 
operator long() const {
return key;
}
 
friend ostream& operator<< <TSIZE> (ostream&, const sim_record<TSIZE>&);
 
};
 
 
#endif
/sim_ana.h
0,0 → 1,141
/*
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
Simulation analyzer, gethering info. for performance analyses.
Possible bugs:
* the histograph function has not been tested yet.
 
 
History:
29/06/2010 Initial version. <wsong83@gmail.com>
28/05/2011 Clean up for opensource. <wsong83@gmail.com>
*/
 
#ifndef SIM_ANA_H_
#define SIM_ANA_H_
 
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <fstream>
#include <string>
#include "sim_record.h"
#include "hash_table.h"
 
using namespace std;
 
// a data type for accumulative performance, such as throughput analysis
class accu_record{
private:
double V1, V2; /* two values to avoid loss of accuracy, V1 save the accumulated V2 of at least 512 records */
unsigned int N1, N2;
public:
accu_record()
:V1(0), V2(0), N1(0), N2(0)
{}
accu_record& operator+= (const double m) {
N2++;
V2 += m;
if(N2 >= N1/512) {
N1 += N2;
V1 += V2;
N2 = 0;
V2 = 0;
}
return(*this);
}
 
double avalue() { /* return averged value */
double rt;
 
if(0 == N1+N2)
rt = 0;
else
rt = (V1 + V2) / (N1 + N2);
 
V1 = 0;
V2 = 0;
N1 = 0;
N2 = 0;
return rt;
}
 
double value() { /* return the accumulative value */
double rt;
 
if(0 == N1+N2)
rt = 0;
else
rt = (V1 + V2);
 
V1 = 0;
V2 = 0;
N1 = 0;
N2 = 0;
return rt;
}
};
 
/* the major simulation record class, only one such object in one simulation */
class sim_ana {
public:
 
sim_ana()
: warm_time(0), record_period(0),last_time(0),
delay_ana(false), throughput_ana(false), delay_histo_ana(false),
histo_data(NULL) {}
sim_ana(double mwt, double mrp)
: warm_time(mwt), record_period(mrp), last_time(0),
delay_ana(false), throughput_ana(false), delay_histo_ana(false),
histo_data(NULL) {}
 
~sim_ana();
 
/* currently 16 table entries is enough and good for memory efficiency */
hash_table<sim_record<2>,16> ANA;
 
bool start(long, double); /* start to record a new record */
bool record(long, double); /* record a time stamp */
bool stop(long, double, unsigned int); /* stop an old record */
 
bool set_ana_parameters(double, double); /* set analysis time parameters */
bool analyze_delay(string); /* enable delay analysis */
bool analyze_throughput(string); /* enable throughput analysis */
bool analyze_delay_histo(string, double, double, unsigned int); /* enable delay histo analysis */
 
private:
double warm_time;
double record_period;
double last_time;
bool delay_ana; /* whether analyze frame delay */
bool throughput_ana; /* whether analyze throughput */
bool delay_histo_ana; /* whether analyze frame delay histo */
unsigned int delay_histo_binnum; /* bin number of the histo graph */
double delay_histo_start; /* histo begin level */
double delay_histo_end; /* histo end level */
double delay_histo_gap; /* gap bewteen two levels (gap = (start-end)/(binnum-2)) */
unsigned long * histo_data;
 
string delay_file; /* the name for delay analyses result file */
string throughput_file; /* the name for throughput analyses result file */
string delay_histo_file; /* the name for histograph analyses file */
accu_record fm_dly; /* records of frame delay */
accu_record pth_dly; /* records of path delay */
accu_record th_value; /* records of throughput */
};
 
#endif

powered by: WebSVN 2.1.0

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