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
- from Rev 28 to Rev 29
- ↔ Reverse comparison
Rev 28 → Rev 29
/branches/init/common/tb/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 |
/branches/init/common/tb/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; |
} |
|
/branches/init/common/tb/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 |
/branches/init/common/tb/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> |
27/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 |