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
    /
    from Rev 28 to Rev 29
    Reverse comparison

Rev 28 → Rev 29

/async_sdm_noc/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
/async_sdm_noc/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;
}
 
/async_sdm_noc/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
/async_sdm_noc/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

powered by: WebSVN 2.1.0

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