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

Rev 28 → Rev 37

/sdm/define.h
0,0 → 1,51
/*
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 = 1; // 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, 0 means the maximal inject rate
 
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
 
// Channel Slicing will alter the port format
// #define ENABLE_CHANNEL_CLISING
 
#endif
/sdm/tb/netnode.v
0,0 → 1,70
/*
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 module of network node including the processing element and the network interface.
Currently the transmission FIFO is 500 frame deep.
History:
27/02/2011 Initial version. <wsong83@gmail.com>
30/05/2011 Clean up for opensource. <wsong83@gmail.com>
*/
 
`include "define.v"
 
module NetNode (
dia, do4, doa, di4,
do0, do1, do2, do3,
di0, di1, di2, di3,
rst_n)
//
// 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.
//
parameter DW = 32;
parameter VCN = 1;
parameter x = 2;
parameter y = 2;
parameter SCN = DW/2;
`ifdef ENABLE_CHANNEL_SLICING
input [VCN*SCN-1:0] dia;
input [VCN*SCN-1:0] do4;
output [VCN*SCN-1:0] doa;
output [VCN*SCN-1:0] di4;
`else
input [VCN-1:0] dia;
input [VCN-1:0] do4;
output [VCN-1:0] doa;
output [VCN-1:0] di4;
`endif // !`ifdef ENABLE_CHANNEL_SLICING
 
input [VCN*SCN-1:0] do0;
input [VCN*SCN-1:0] do1;
input [VCN*SCN-1:0] do2;
input [VCN*SCN-1:0] do3;
output [VCN*SCN-1:0] di0;
output [VCN*SCN-1:0] di1;
output [VCN*SCN-1:0] di2;
output [VCN*SCN-1:0] di3;
 
input rst_n;
 
endmodule // NetNode
 
/sdm/tb/netnode.h
0,0 → 1,236
/*
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 module of network node including the processing element and the network interface.
Currently the transmission FIFO is 500 frame deep.
History:
26/02/2011 Initial version. <wsong83@gmail.com>
30/05/2011 Clean up for opensource. <wsong83@gmail.com>
*/
 
#ifndef NETNODE_H_
#define NETNODE_H_
 
#include "define.h"
#include <systemc.h>
#include "ni.h"
#include "procelem.h"
#include "rtdriver.h"
 
class NetNode : public sc_module {
public:
RTDriver * LIOD [SubChN]; /* driving and convert I/O to/from router local port */
Network_Adapter * NI; /* network interface */
ProcElem * PE; /* processor element */
 
#ifdef ENABLE_CHANNEL_CLISING
sc_signal<sc_lv<ChBW*4> > rtia [SubChN]; /* input ack to router */
sc_signal<sc_lv<ChBW*4> > rtod4 [SubChN]; /* output eof to router */
sc_signal<sc_lv<ChBW*4> > rtoa [SubChN]; /* output ack from router */
sc_signal<sc_lv<ChBW*4> > rtid4 [SubChN]; /* input data from router */
sc_in<sc_lv<SubChN*ChBW*4> > dia; /* input ack, undivided */
sc_in<sc_lv<SubChN*ChBW*4> > do4; /* output eof, undivided */
sc_out<sc_lv<SubChN*ChBW*4> > doa; /* output ack, undivided */
sc_out<sc_lv<SubChN*ChBW*4> > di4; /* input eof, undivided */
#else
sc_signal<sc_logic > rtia [SubChN]; /* input ack to router */
sc_signal<sc_logic > rtod4 [SubChN]; /* output data to router */
sc_signal<sc_logic > rtoa [SubChN]; /* output ack from router */
sc_signal<sc_logic > rtid4 [SubChN]; /* input eof from router */
sc_in<sc_lv<SubChN> > dia; /* input ack, undivided */
sc_in<sc_lv<SubChN> > do4; /* output eof, undivided */
sc_out<sc_lv<SubChN> > doa; /* output ack, undivided */
sc_out<sc_lv<SubChN> > di4; /* input eof, undivided */
#endif
 
sc_signal<sc_lv<ChBW*4 > > rtod [SubChN][4]; /* output data to router */
sc_signal<sc_lv<ChBW*4 > > rtid [SubChN][4]; /* input data from router */
sc_in<sc_lv<SubChN*ChBW*4 > > do0; /* output d0, undivided */
sc_in<sc_lv<SubChN*ChBW*4 > > do1;
sc_in<sc_lv<SubChN*ChBW*4 > > do2;
sc_in<sc_lv<SubChN*ChBW*4 > > do3;
sc_out<sc_lv<SubChN*ChBW*4 > > di0; /* input data, undivided */
sc_out<sc_lv<SubChN*ChBW*4 > > di1;
sc_out<sc_lv<SubChN*ChBW*4 > > di2;
sc_out<sc_lv<SubChN*ChBW*4 > > di3;
sc_in<sc_logic > rst_n; /* global reste, from the verilog top level */
 
// signals between IOD and NI
sc_fifo<pdu_flit<ChBW> > * NI2P [SubChN]; /* flit fifo, from NI to IO driver */
sc_fifo<pdu_flit<ChBW> > * P2NI [SubChN]; /* flit fifo, from IO driver to NI */
 
// signals between NI and FG/FS
sc_fifo<pdu_frame<ChBW> > * FIQ; /* the frame fifo, from PE to NI */
sc_fifo<pdu_frame<ChBW> > * FOQ; /* the frame fifo, from NI to PE */
sc_signal<bool> brst_n; /* the reset in the SystemC modules */
 
int x, y; /* private local address */
 
SC_CTOR(NetNode)
: dia("dia"), do4("do4"), doa("doa"), di4("di4"),
do0("do0"), do1("do1"), do2("do2"), do3("do3"),
di0("di0"), di1("di1"), di2("di2"), di3("di3"),
rst_n("rst_n")
{
// dynamically get the parameters from Verilog test bench
ncsc_get_param("x", x);
ncsc_get_param("y", y);
 
// initialization
NI = new Network_Adapter("NI", x, y);
PE = new ProcElem("PE", x, y);
FIQ = new sc_fifo<pdu_frame<ChBW> >(500); /* currently the fifo from PE is 500 frame deep */
FOQ = new sc_fifo<pdu_frame<ChBW> >(1);
for(unsigned int j=0; j<SubChN; j++) {
LIOD[j] = new RTDriver("LIOD");
NI2P[j] = new sc_fifo<pdu_flit<ChBW> >(1);
P2NI[j] = new sc_fifo<pdu_flit<ChBW> >(1);
}
 
// connections
for(unsigned int j=0; j<SubChN; j++) {
LIOD[j]->NI2P(*NI2P[j]);
LIOD[j]->P2NI(*P2NI[j]);
for(unsigned int k=0; k<4; k++) {
LIOD[j]->rtid[k](rtid[j][k]);
LIOD[j]->rtod[k](rtod[j][k]);
}
LIOD[j]->rtia(rtia[j]);
LIOD[j]->rtid4(rtid4[j]);
LIOD[j]->rtoa(rtoa[j]);
LIOD[j]->rtod4(rtod4[j]);
}
 
NI->frame_in(*FIQ);
NI->frame_out(*FOQ);
for(unsigned int j=0; j<SubChN; j++) {
NI->IP[j](*P2NI[j]);
NI->OP[j](*NI2P[j]);
}
PE->rst_n(brst_n);
PE->Fout(*FIQ);
PE->Fin(*FOQ);
 
brst_n.write(false);
 
SC_METHOD(rst_proc);
sensitive << rst_n;
sc_spawn_options opt_inp;
opt_inp.spawn_method();
for(unsigned int j=0; j<SubChN; j++) {
opt_inp.set_sensitivity(&rtid[j][0]);
opt_inp.set_sensitivity(&rtid[j][1]);
opt_inp.set_sensitivity(&rtid[j][2]);
opt_inp.set_sensitivity(&rtid[j][3]);
opt_inp.set_sensitivity(&rtid4[j]);
}
opt_inp.set_sensitivity(&dia);
sc_spawn(sc_bind(&NetNode::VC_inp, this), NULL, &opt_inp);
 
sc_spawn_options opt_outp;
opt_outp.spawn_method();
for(unsigned int j=0; j<SubChN; j++) {
opt_outp.set_sensitivity(&rtoa[j]);
}
opt_outp.set_sensitivity(&do0);
opt_outp.set_sensitivity(&do1);
opt_outp.set_sensitivity(&do2);
opt_outp.set_sensitivity(&do3);
opt_outp.set_sensitivity(&do4);
sc_spawn(sc_bind(&NetNode::VC_outp, this), NULL, &opt_outp);
}
// thread to divide the input buses according to virtual circuits
void VC_inp() {
 
sc_lv<SubChN*ChBW*4> md[4];
#ifdef ENABLE_CHANNEL_CLISING
sc_lv<SubChN*ChBW*4> md4;
sc_lv<SubChN*ChBW*4> mda;
#else
sc_lv<SubChN> md4;
sc_lv<SubChN> mda;
#endif
 
mda = dia.read();
 
for(unsigned int i=0; i<SubChN; i++) {
#ifdef ENABLE_CHANNEL_CLISING
rtia[i].write(mda(ChBW*4*(i+1)-1, ChBW*4*i));
md4(ChBW*4*(i+1)-1, ChBW*4*i) = rtid4[i].read();
#else
rtia[i].write(mda[i]);
md4[i] = rtid4[i].read();
#endif
md[0](ChBW*4*(i+1)-1, ChBW*4*i) = rtid[i][0].read();
md[1](ChBW*4*(i+1)-1, ChBW*4*i) = rtid[i][1].read();
md[2](ChBW*4*(i+1)-1, ChBW*4*i) = rtid[i][2].read();
md[3](ChBW*4*(i+1)-1, ChBW*4*i) = rtid[i][3].read();
}
 
di0.write(md[0]);
di1.write(md[1]);
di2.write(md[2]);
di3.write(md[3]);
di4.write(md4);
}
 
// thread to combine the buses according to virtual circuits
void VC_outp() {
sc_lv<SubChN*ChBW*4> md[4];
#ifdef ENABLE_CHANNEL_CLISING
sc_lv<SubChN*ChBW*4> md4;
sc_lv<SubChN*ChBW*4> mda;
#else
sc_lv<SubChN> md4;
sc_lv<SubChN> mda;
#endif
 
md[0] = do0.read();
md[1] = do1.read();
md[2] = do2.read();
md[3] = do3.read();
md4 = do4.read();
 
 
for(unsigned int i=0; i<SubChN; i++) {
#ifdef ENABLE_CHANNEL_CLISING
mda(ChBW*4*(i+1)-1, ChBW*4*i) = rtoa[i].read();
rtod4[i].write(md4(ChBW*4*(i+1)-1, ChBW*4*i));
#else
mda[i] = rtoa[i].read();
rtod4[i].write(md4[i]);
#endif
rtod[i][0].write(md[0](ChBW*4*(i+1)-1, ChBW*4*i));
rtod[i][1].write(md[1](ChBW*4*(i+1)-1, ChBW*4*i));
rtod[i][2].write(md[2](ChBW*4*(i+1)-1, ChBW*4*i));
rtod[i][3].write(md[3](ChBW*4*(i+1)-1, ChBW*4*i));
}
 
doa.write(mda);
}
 
// generate the reset for SystemC modules
void rst_proc() {
bool mrst_n;
mrst_n = rst_n.read().is_01() ? rst_n.read().to_bool() : false;
brst_n.write(mrst_n);
}
};
 
 
#endif
/sdm/tb/rtdriver.cpp
0,0 → 1,289
/*
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 port driver between NI and router.
History:
27/04/2010 Initial version. <wsong83@gmail.com>
16/10/2010 Support SDM. <wsong83@gmail.com>
31/05/2011 Remove the sc_unit datatype to support data width larger than 64. <wsong83@gmail.com>
*/
 
#include "rtdriver.h"
 
RTDriver::RTDriver(sc_module_name mname)
: sc_module(mname),
NI2P("NI2P"),
P2NI("P2NI")
{
SC_METHOD(IPdetect);
sensitive << rtia;
 
SC_METHOD(OPdetect);
sensitive << rtod[0] << rtod[1] << rtod[2] << rtod[3] << rtod4;
 
SC_THREAD(send);
SC_THREAD(recv);
 
rtinp_sig = false;
rtoutp_sig = false;
}
void RTDriver::IPdetect() {
sc_logic ack_lv_high, ack_lv_low; // the sc_logic ack
 
// read the ack
#ifdef ENABLE_CHANNEL_CLISING
ack_lv_high = rtia.read().and_reduce();
ack_lv_low = rtia.read().or_reduce();
#else
ack_lv_high = rtia.read();
ack_lv_low = rtia.read();
#endif
 
if(ack_lv_high.is_01() && ack_lv_high.to_bool())
rtinp_sig = true;
if(ack_lv_low.is_01() && (!ack_lv_low.to_bool()))
rtinp_sig = false;
}
 
void RTDriver::OPdetect() {
sc_lv<ChBW*4> data_lv; // the ORed data
sc_logic data_lv_high, data_lv_low;
 
#ifdef ENABLE_CHANNEL_CLISING
data_lv = rtod[0].read() | rtod[1].read() | rtod[2].read() | rtod[3].read() | rtod4.read();
data_lv_high = data_lv.and_reduce();
data_lv_low = data_lv.or_reduce();
#else
data_lv = rtod[0].read() | rtod[1].read() | rtod[2].read() | rtod[3].read();
data_lv_high = data_lv.and_reduce() | rtod4.read();
data_lv_low = data_lv.or_reduce() | rtod4.read();
#endif
 
if(data_lv_high.is_01() && data_lv_high.to_bool())
rtoutp_sig = true;
if(data_lv_high.is_01() && (!data_lv_low.to_bool()))
rtoutp_sig = false;
}
 
void RTDriver::send() {
FLIT mflit; // the local flit buffer
unsigned int i, j; // local loop index
sc_lv<ChBW*4> mdata[4]; // local data copy
#ifdef ENABLE_CHANNEL_CLISING
sc_lv<ChBW*4> mdata4; // local copy of eof
#else
sc_logic mdata4; // local copy of eof
#endif
// initialize the output ports
mdata[0] = 0;
mdata[1] = 0;
mdata[2] = 0;
mdata[3] = 0;
#ifdef ENABLE_CHANNEL_CLISING
mdata4 = 0;
#else
mdata4 = false;
#endif
 
rtid[0].write(mdata[0]);
rtid[1].write(mdata[1]);
rtid[2].write(mdata[2]);
rtid[3].write(mdata[3]);
rtid4.write(mdata4);
 
while(true) {
mflit = NI2P->read(); // read in the flit
 
// write the flit
if(mflit.ftype == F_HD) {
// the target address
mdata[mflit.addrx&0x3][0] = SC_LOGIC_1;
mdata[(mflit.addrx&0xc)>>2][1] = SC_LOGIC_1;
mdata[mflit.addry&0x3][2] = SC_LOGIC_1;
mdata[(mflit.addry&0xc)>>2][3] = SC_LOGIC_1;
for(i=0,j=4; i<(ChBW-1)*4; i++, j++) {
switch((mflit[i/4] >> ((i%4)*2)) & 0x3) {
case 0: mdata[0][j] = SC_LOGIC_1; break;
case 1: mdata[1][j] = SC_LOGIC_1; break;
case 2: mdata[2][j] = SC_LOGIC_1; break;
case 3: mdata[3][j] = SC_LOGIC_1; break;
}
}
} else {
for(i=0; i<ChBW*4; i++) {
switch((mflit[i/4] >> ((i%4)*2)) & 0x3) {
case 0: mdata[0][i] = SC_LOGIC_1; break;
case 1: mdata[1][i] = SC_LOGIC_1; break;
case 2: mdata[2][i] = SC_LOGIC_1; break;
case 3: mdata[3][i] = SC_LOGIC_1; break;
}
}
}
// write to the port
rtid[0].write(mdata[0]);
rtid[1].write(mdata[1]);
rtid[2].write(mdata[2]);
rtid[3].write(mdata[3]);
 
// wait for the router to capture the data
wait(rtinp_sig.posedge_event());
wait(0.2, SC_NS); // a delay to avoid data override
// clear the data
mdata[0] = 0;
mdata[1] = 0;
mdata[2] = 0;
mdata[3] = 0;
rtid[0].write(mdata[0]);
rtid[1].write(mdata[1]);
rtid[2].write(mdata[2]);
rtid[3].write(mdata[3]);
// wait for the input port be ready again
wait(rtinp_sig.negedge_event());
wait(0.2, SC_NS); // a delay to avoid data override
 
// check whether a tailf flit is needed
if(mflit.ftype == F_TL) {
// write the eof
rtid4.write(~mdata4);
// wait for the router to capture the data
wait(rtinp_sig.posedge_event());
wait(0.2, SC_NS); // a delay to avoid data override
// clear the eof
rtid4.write(mdata4);
 
// wait for the input port be ready again
wait(rtinp_sig.negedge_event());
wait(0.2, SC_NS); // a delay to avoid data override
}
}
}
 
void RTDriver::recv() {
FLIT mflit; // the local flit buffer
sc_lv<ChBW*4> mdata[4]; // local data copy
#ifdef ENABLE_CHANNEL_CLISING
sc_lv<ChBW*4> mdata4; // local copy of eof
sc_lv<ChBW*4> mack = 0; // local copy of ack
#else
sc_logic mdata4; // local copy of eof
sc_logic mack = SC_LOGIC_0; // local copy of ack
#endif
sc_lv<4> dd; // the current 1-of-4 data under process
unsigned int i, j; // local loop index
 
bool is_hd = true; // the current flit is a header flit
// initialize the ack signal
rtoa.write(mack);
 
while(true) {
// clear the flit
mflit.clear();
 
// wait for an incoming flit
wait(rtoutp_sig.posedge_event());
 
// analyse the flit
mdata[0] = rtod[0].read();
mdata[1] = rtod[1].read();
mdata[2] = rtod[2].read();
mdata[3] = rtod[3].read();
mdata4 = rtod4.read();
 
if(is_hd) {
mflit.ftype = F_HD;
is_hd = false;
}
#ifdef ENABLE_CHANNEL_CLISING
else if(mdata4[0].to_bool()) {
mflit.ftype = F_TL;
is_hd = true;
}
#else
else if(mdata4.to_bool()) {
mflit.ftype = F_TL;
is_hd = true;
}
#endif
else {
mflit.ftype = F_DAT;
}
 
if(mflit.ftype == F_HD) {
// fetch the address
dd[0] = mdata[0][0]; dd[1] = mdata[1][0]; dd[2] = mdata[2][0]; dd[3] = mdata[3][0];
mflit.addrx |= (c1o42b(dd.to_uint()) << 0);
dd[0] = mdata[0][1]; dd[1] = mdata[1][1]; dd[2] = mdata[2][1]; dd[3] = mdata[3][1];
mflit.addrx |= (c1o42b(dd.to_uint()) << 2);
dd[0] = mdata[0][2]; dd[1] = mdata[1][2]; dd[2] = mdata[2][2]; dd[3] = mdata[3][2];
mflit.addry |= (c1o42b(dd.to_uint()) << 0);
dd[0] = mdata[0][3]; dd[1] = mdata[1][3]; dd[2] = mdata[2][3]; dd[3] = mdata[3][3];
mflit.addry |= (c1o42b(dd.to_uint()) << 2);
// fill in data
for(i=1; i<ChBW; i++) {
for(j=0; j<4; j++) {
dd[0] = mdata[0][i*4+j];
dd[1] = mdata[1][i*4+j];
dd[2] = mdata[2][i*4+j];
dd[3] = mdata[3][i*4+j];
mflit[i-1] |= c1o42b(dd.to_uint()) << j*2;
}
}
} else if (mflit.ftype != F_TL) {
// fill in data
for(i=0; i<ChBW; i++) {
for(j=0; j<4; j++) {
dd[0] = mdata[0][i*4+j];
dd[1] = mdata[1][i*4+j];
dd[2] = mdata[2][i*4+j];
dd[3] = mdata[3][i*4+j];
mflit[i] |= c1o42b(dd.to_uint()) << j*2;
}
}
}
// send the flit to the NI
P2NI->write(mflit);
wait(0.2, SC_NS); // a delay to avoid data override
rtoa.write(~mack); // notify that data is captured
 
// wait for the data withdrawal
wait(rtoutp_sig.negedge_event());
wait(0.2, SC_NS); // a delay to avoid data override
rtoa.write(mack); // notify that data is captured
}
}
unsigned int RTDriver::c1o42b(unsigned int dd) {
switch(dd) {
case 1: return 0;
case 2: return 1;
case 4: return 2;
case 8: return 3;
default: return 0xff;
}
}
/sdm/tb/noc_top.v
0,0 → 1,136
/*
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 mesh network for simulation.
History:
03/03/2011 Initial version. <wsong83@gmail.com>
30/05/2011 Clean up for opensource. <wsong83@gmail.com>
*/
 
// the router structure definitions
`include "define.v"
 
module noc_top(/*AUTOARG*/
// Inputs
rst_n
);
input rst_n;
 
parameter DW = 32;
parameter VCN = 1;
parameter DIMX = 8;
parameter DIMY = 8;
parameter SCN = DW/2;
 
wire [DIMX-1:0][DIMY-1:0][3:0][VCN*SCN-1:0] di0, di1, di2, di3;
wire [DIMX-1:0][DIMY-1:0][3:0][VCN*SCN-1:0] do0, do1, do2, do3;
`ifdef ENABLE_CHANNEL_SLICING
wire [DIMX-1:0][DIMY-1:0][3:0][VCN*SCN-1:0] di4, dia;
wire [DIMX-1:0][DIMY-1:0][3:0][VCN*SCN-1:0] do4, doa;
`else
wire [DIMX-1:0][DIMY-1:0][3:0][VCN-1:0] di4, dia;
wire [DIMX-1:0][DIMY-1:0][3:0][VCN-1:0] do4, doa;
`endif
 
genvar x, y;
 
generate for(x=0; x<DIMX; x++) begin: DX
for(y=0; y<DIMY; y++) begin: DY
node_top #(.DW(DW), .VCN(VCN), .x(x), .y(y))
NN (
.si0 (di0[x][y][0]), .si1 (di1[x][y][0]), .si2 (di2[x][y][0]), .si3 (di3[x][y][0]), .si4 (di4[x][y][0]), .sia (dia[x][y][0]),
.wi0 (di0[x][y][1]), .wi1 (di1[x][y][1]), .wi2 (di2[x][y][1]), .wi3 (di3[x][y][1]), .wi4 (di4[x][y][1]), .wia (dia[x][y][1]),
.ni0 (di0[x][y][2]), .ni1 (di1[x][y][2]), .ni2 (di2[x][y][2]), .ni3 (di3[x][y][2]), .ni4 (di4[x][y][2]), .nia (dia[x][y][2]),
.ei0 (di0[x][y][3]), .ei1 (di1[x][y][3]), .ei2 (di2[x][y][3]), .ei3 (di3[x][y][3]), .ei4 (di4[x][y][3]), .eia (dia[x][y][3]),
.so0 (do0[x][y][0]), .so1 (do1[x][y][0]), .so2 (do2[x][y][0]), .so3 (do3[x][y][0]), .so4 (do4[x][y][0]), .soa (doa[x][y][0]),
.wo0 (do0[x][y][1]), .wo1 (do1[x][y][1]), .wo2 (do2[x][y][1]), .wo3 (do3[x][y][1]), .wo4 (do4[x][y][1]), .woa (doa[x][y][1]),
.no0 (do0[x][y][2]), .no1 (do1[x][y][2]), .no2 (do2[x][y][2]), .no3 (do3[x][y][2]), .no4 (do4[x][y][2]), .noa (doa[x][y][2]),
.eo0 (do0[x][y][3]), .eo1 (do1[x][y][3]), .eo2 (do2[x][y][3]), .eo3 (do3[x][y][3]), .eo4 (do4[x][y][3]), .eoa (doa[x][y][3]),
.rst_n(rst_n)
);
// north link
if(x==0) begin
assign di0[x][y][2] = do0[x][y][2];
assign di1[x][y][2] = do1[x][y][2];
assign di2[x][y][2] = do2[x][y][2];
assign di3[x][y][2] = do3[x][y][2];
assign di4[x][y][2] = do4[x][y][2];
assign doa[x][y][2] = dia[x][y][2];
end else begin
assign di0[x][y][2] = do0[x-1][y][0];
assign di1[x][y][2] = do1[x-1][y][0];
assign di2[x][y][2] = do2[x-1][y][0];
assign di3[x][y][2] = do3[x-1][y][0];
assign di4[x][y][2] = do4[x-1][y][0];
assign doa[x-1][y][0] = dia[x][y][2];
end
 
// south link
if(x==DIMX-1) begin
assign di0[x][y][0] = do0[x][y][0];
assign di1[x][y][0] = do1[x][y][0];
assign di2[x][y][0] = do2[x][y][0];
assign di3[x][y][0] = do3[x][y][0];
assign di4[x][y][0] = do4[x][y][0];
assign doa[x][y][0] = dia[x][y][0];
end else begin
assign di0[x][y][0] = do0[x+1][y][2];
assign di1[x][y][0] = do1[x+1][y][2];
assign di2[x][y][0] = do2[x+1][y][2];
assign di3[x][y][0] = do3[x+1][y][2];
assign di4[x][y][0] = do4[x+1][y][2];
assign doa[x+1][y][2] = dia[x][y][0];
end
 
// west link
if(y==0) begin
assign di0[x][y][1] = do0[x][y][1];
assign di1[x][y][1] = do1[x][y][1];
assign di2[x][y][1] = do2[x][y][1];
assign di3[x][y][1] = do3[x][y][1];
assign di4[x][y][1] = do4[x][y][1];
assign doa[x][y][1] = dia[x][y][1];
end else begin
assign di0[x][y][1] = do0[x][y-1][3];
assign di1[x][y][1] = do1[x][y-1][3];
assign di2[x][y][1] = do2[x][y-1][3];
assign di3[x][y][1] = do3[x][y-1][3];
assign di4[x][y][1] = do4[x][y-1][3];
assign doa[x][y-1][3] = dia[x][y][1];
end // else: !if(y==0)
 
// east link
if(y==DIMY-1) begin
assign di0[x][y][3] = do0[x][y][3];
assign di1[x][y][3] = do1[x][y][3];
assign di2[x][y][3] = do2[x][y][3];
assign di3[x][y][3] = do3[x][y][3];
assign di4[x][y][3] = do4[x][y][3];
assign doa[x][y][3] = dia[x][y][3];
end else begin
assign di0[x][y][3] = do0[x][y+1][1];
assign di1[x][y][3] = do1[x][y+1][1];
assign di2[x][y][3] = do2[x][y+1][1];
assign di3[x][y][3] = do3[x][y+1][1];
assign di4[x][y][3] = do4[x][y+1][1];
assign doa[x][y+1][1] = dia[x][y][3];
end // else: !if(y==DIMY-1)
 
end // block: DY
end // block: DX
endgenerate
endmodule // noc_top
/sdm/tb/ni.cpp
0,0 → 1,94
/*
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 SystemC network adapter/interface for NoC simulation.
History:
23/12/2008 Initial version. <wsong83@gmail.com>
30/09/2010 Use template style packet definition. <wsong83@gmail.com>
16/10/2010 Support SDM. <wsong83@gmail.com>
29/05/2011 CLean up for opensource. <wsong83@gmail.com>
 
*/
 
#include "ni.h"
 
Network_Adapter::Network_Adapter(
sc_module_name name // module name
,unsigned int x // location x
,unsigned int y // location y
):
sc_module(name),
frame_in("FrmIn"),
frame_out("FrmOut"),
loc_x(x),
loc_y(y)
{
sc_spawn_options opt;
 
for(unsigned int i=0; i<SubChN; i++) {
sc_spawn(sc_bind(&Network_Adapter::ibuffer_thread, this, i), NULL, &opt);
sc_spawn(sc_bind(&Network_Adapter::obuffer_thread, this, i), NULL, &opt);
}
}
 
Network_Adapter::~Network_Adapter()
{
}
 
// read in the incoming frame
void Network_Adapter::ibuffer_thread(unsigned int ii){
FRAME mframe;
FLIT mflit;
 
while(1){
mframe.clear();
while(1) {
mflit = IP[ii]->read();
mframe << mflit;
if(mflit.ftype == F_TL) break;
}
 
frame_out->write(mframe);
}
}
 
// send out a frame
void Network_Adapter::obuffer_thread(unsigned int ii){
 
FRAME mframe;
FLIT mflit;
 
while(1){
mframe = frame_in->read();
while(1) {
mframe >> mflit;
mflit.vcn = ii;
 
OP[ii]->write(mflit);
 
if(mflit.ftype == F_TL) break;
}
}
}
 
bool Network_Adapter::check_frame(const FRAME& frame)
{
// TODO: check the integerity, dummy right noe
return true;
}
 
 
 
 
/sdm/tb/rtdriver.h
0,0 → 1,66
/*
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 port driver between NI and router.
History:
27/04/2010 Initial version. <wsong83@gmail.com>
16/10/2010 Support SDM. <wsong83@gmail.com>
30/05/2011 Remove the sc_unit datatype to support data width larger than 64. <wsong83@gmail.com>
*/
 
#ifndef RT_DRIVER_H_
#define RT_DRIVER_H_
 
#include "define.h"
#include <systemc.h>
#include "pdu_def.h"
 
SC_MODULE(RTDriver) {
 
public:
// port with network interface
sc_port<sc_fifo_in_if<FLIT> > NI2P;
sc_port<sc_fifo_out_if<FLIT> > P2NI;
// signals from interface to router
sc_out<sc_lv<ChBW*4> > rtid [4];
sc_in<sc_lv<ChBW*4> > rtod [4];
 
#ifdef ENABLE_CHANNEL_CLISING
sc_out<sc_lv<ChBW*4> > rtid4;
sc_in<sc_lv<ChBW*4> > rtod4;
sc_in<sc_lv<ChBW*4> > rtia;
sc_out<sc_lv<ChBW*4> > rtoa;
#else
sc_out<sc_logic > rtid4;
sc_in<sc_logic > rtod4;
sc_in<sc_logic> rtia;
sc_out<sc_logic> rtoa;
#endif
SC_HAS_PROCESS(RTDriver);
RTDriver(sc_module_name name);
void IPdetect(); // Method to detect the router input port
void OPdetect(); // Method to detect the router output port
void send(); // thread of sending a flit
void recv(); // thread to recveive a flit
 
sc_signal<bool> rtinp_sig; // fire when the router input port is ready for a new flit
sc_signal<bool> rtoutp_sig; // fire when the router output port has a new flit
unsigned int c1o42b(unsigned int); // convert 1-of-4 to binary
};
 
 
#endif
/sdm/tb/noctb.v
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
Test bench.
History:
03/03/2011 Initial version. <wsong83@gmail.com>
30/05/2011 Clean up for opensource. <wsong83@gmail.com>
*/
 
`timescale 1ns/1ps
 
module noctb;
parameter DW = 8; // the data width of a single virtual circuit
parameter VCN = 1; // the number of virtual circuits per direction
parameter DIMX = 4; // the X dimension
parameter DIMY = 4; // the Y dimension
reg rst_n;
noc_top #(.DW(DW), .VCN(VCN), .DIMX(DIMX), .DIMY(DIMY))
NoC (.rst_n(rst_n)); // the mesh network
 
AnaProc ANAM(); // the global performance analyser
initial begin
rst_n = 0;
 
# 133;
 
rst_n = 1;
 
end
 
endmodule // noctb
 
 
 
/sdm/tb/rtwrapper.v
0,0 → 1,222
/*
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 wrapper for the synthesized router.
History:
28/05/2009 Initial version. <wsong83@gmail.com>
30/05/2011 Clean up for opensource. <wsong83@gmail.com>
*/
 
// the router structure definitions
`include "define.v"
 
module router_hdl(/*AUTOARG*/
// Outputs
so0, so1, so2, so3, wo0, wo1, wo2, wo3, no0, no1, no2, no3, eo0,
eo1, eo2, eo3, lo0, lo1, lo2, lo3, so4, wo4, no4, eo4, lo4, sia,
wia, nia, eia, lia,
// Inputs
si0, si1, si2, si3, wi0, wi1, wi2, wi3, ni0, ni1, ni2, ni3, ei0,
ei1, ei2, ei3, li0, li1, li2, li3, si4, wi4, ni4, ei4, li4, soa,
woa, noa, eoa, loa, addrx, addry, rst_n
);
 
parameter VCN = 1; // number of virtual circuits in each direction. When VCN == 1, it is a wormhole router
parameter DW = 32; // the datawidth of a single virtual circuit, the total data width of the router is DW*VCN
parameter SCN = DW/2; // the number of 1-of-4 sub-channel in each virtual circuit
input [VCN*SCN-1:0] si0, si1, si2, si3;
input [VCN*SCN-1:0] wi0, wi1, wi2, wi3;
input [VCN*SCN-1:0] ni0, ni1, ni2, ni3;
input [VCN*SCN-1:0] ei0, ei1, ei2, ei3;
input [VCN*SCN-1:0] li0, li1, li2, li3;
output [VCN*SCN-1:0] so0, so1, so2, so3;
output [VCN*SCN-1:0] wo0, wo1, wo2, wo3;
output [VCN*SCN-1:0] no0, no1, no2, no3;
output [VCN*SCN-1:0] eo0, eo1, eo2, eo3;
output [VCN*SCN-1:0] lo0, lo1, lo2, lo3;
// eof bits and ack lines
`ifdef ENABLE_CHANNEL_SLICING
input [VCN*SCN-1:0] si4, wi4, ni4, ei4, li4;
output [VCN*SCN-1:0] so4, wo4, no4, eo4, lo4;
output [VCN*SCN-1:0] sia, wia, nia, eia, lia;
input [VCN*SCN-1:0] soa, woa, noa, eoa, loa;
`else
input [VCN-1:0] si4, wi4, ni4, ei4, li4;
output [VCN-1:0] so4, wo4, no4, eo4, lo4;
output [VCN-1:0] sia, wia, nia, eia, lia;
input [VCN-1:0] soa, woa, noa, eoa, loa;
`endif // !`ifdef ENABLE_CHANNEL_SLICING
input [7:0] addrx, addry;
input rst_n;
wire [VCN*SCN-1:0] psi0, psi1, psi2, psi3;
wire [VCN*SCN-1:0] pwi0, pwi1, pwi2, pwi3;
wire [VCN*SCN-1:0] pni0, pni1, pni2, pni3;
wire [VCN*SCN-1:0] pei0, pei1, pei2, pei3;
wire [VCN*SCN-1:0] pli0, pli1, pli2, pli3;
wire [VCN*SCN-1:0] pso0, pso1, pso2, pso3;
wire [VCN*SCN-1:0] pwo0, pwo1, pwo2, pwo3;
wire [VCN*SCN-1:0] pno0, pno1, pno2, pno3;
wire [VCN*SCN-1:0] peo0, peo1, peo2, peo3;
wire [VCN*SCN-1:0] plo0, plo1, plo2, plo3;
// eof bits and ack lines
`ifdef ENABLE_CHANNEL_SLICING
wire [VCN*SCN-1:0] psi4, pwi4, pni4, pei4, pli4;
wire [VCN*SCN-1:0] pso4, pwo4, pno4, peo4, plo4;
wire [VCN*SCN-1:0] psia, pwia, pnia, peia, plia;
wire [VCN*SCN-1:0] psoa, pwoa, pnoa, peoa, ploa;
`else
wire [VCN-1:0] psi4, pwi4, pni4, pei4, pli4;
wire [VCN-1:0] pso4, pwo4, pno4, peo4, plo4;
wire [VCN-1:0] psia, pwia, pnia, peia, plia;
wire [VCN-1:0] psoa, pwoa, pnoa, peoa, ploa;
`endif // !`ifdef ENABLE_CHANNEL_SLICING
wire [7:0] paddrx, paddry;
wire prst_n;
router RT (
.sia ( psia ),
.wia ( pwia ),
.nia ( pnia ),
.eia ( peia ),
.lia ( plia ),
.so0 ( pso0 ),
.so1 ( pso1 ),
.so2 ( pso2 ),
.so3 ( pso3 ),
.wo0 ( pwo0 ),
.wo1 ( pwo1 ),
.wo2 ( pwo2 ),
.wo3 ( pwo3 ),
.no0 ( pno0 ),
.no1 ( pno1 ),
.no2 ( pno2 ),
.no3 ( pno3 ),
.eo0 ( peo0 ),
.eo1 ( peo1 ),
.eo2 ( peo2 ),
.eo3 ( peo3 ),
.lo0 ( plo0 ),
.lo1 ( plo1 ),
.lo2 ( plo2 ),
.lo3 ( plo3 ),
.so4 ( pso4 ),
.wo4 ( pwo4 ),
.no4 ( pno4 ),
.eo4 ( peo4 ),
.lo4 ( plo4 ),
.si0 ( psi0 ),
.si1 ( psi1 ),
.si2 ( psi2 ),
.si3 ( psi3 ),
.wi0 ( pwi0 ),
.wi1 ( pwi1 ),
.wi2 ( pwi2 ),
.wi3 ( pwi3 ),
.ni0 ( pni0 ),
.ni1 ( pni1 ),
.ni2 ( pni2 ),
.ni3 ( pni3 ),
.ei0 ( pei0 ),
.ei1 ( pei1 ),
.ei2 ( pei2 ),
.ei3 ( pei3 ),
.li0 ( pli0 ),
.li1 ( pli1 ),
.li2 ( pli2 ),
.li3 ( pli3 ),
.si4 ( psi4 ),
.wi4 ( pwi4 ),
.ni4 ( pni4 ),
.ei4 ( pei4 ),
.li4 ( pli4 ),
.soa ( psoa ),
.woa ( pwoa ),
.noa ( pnoa ),
.eoa ( peoa ),
.loa ( ploa ),
.addrx ( paddrx ),
.addry ( paddry ),
.rst_n ( prst_n )
);
assign sia = psia ;
assign wia = pwia ;
assign nia = pnia ;
assign eia = peia ;
assign lia = plia ;
assign so0 = pso0 ;
assign so1 = pso1 ;
assign so2 = pso2 ;
assign so3 = pso3 ;
assign wo0 = pwo0 ;
assign wo1 = pwo1 ;
assign wo2 = pwo2 ;
assign wo3 = pwo3 ;
assign no0 = pno0 ;
assign no1 = pno1 ;
assign no2 = pno2 ;
assign no3 = pno3 ;
assign eo0 = peo0 ;
assign eo1 = peo1 ;
assign eo2 = peo2 ;
assign eo3 = peo3 ;
assign lo0 = plo0 ;
assign lo1 = plo1 ;
assign lo2 = plo2 ;
assign lo3 = plo3 ;
assign so4 = pso4 ;
assign wo4 = pwo4 ;
assign no4 = pno4 ;
assign eo4 = peo4 ;
assign lo4 = plo4 ;
assign psi0 = si0 ;
assign psi1 = si1 ;
assign psi2 = si2 ;
assign psi3 = si3 ;
assign pwi0 = wi0 ;
assign pwi1 = wi1 ;
assign pwi2 = wi2 ;
assign pwi3 = wi3 ;
assign pni0 = ni0 ;
assign pni1 = ni1 ;
assign pni2 = ni2 ;
assign pni3 = ni3 ;
assign pei0 = ei0 ;
assign pei1 = ei1 ;
assign pei2 = ei2 ;
assign pei3 = ei3 ;
assign pli0 = li0 ;
assign pli1 = li1 ;
assign pli2 = li2 ;
assign pli3 = li3 ;
assign psi4 = si4 ;
assign pwi4 = wi4 ;
assign pni4 = ni4 ;
assign pei4 = ei4 ;
assign pli4 = li4 ;
assign psoa = soa ;
assign pwoa = woa ;
assign pnoa = noa ;
assign peoa = eoa ;
assign ploa = loa ;
assign paddrx = addrx ;
assign paddry = addry ;
assign prst_n = rst_n ;
 
initial $sdf_annotate("../syn/file/router.sdf", RT);
endmodule
sdm/tb/rtwrapper.v Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: sdm/tb/node_top.v =================================================================== --- sdm/tb/node_top.v (nonexistent) +++ sdm/tb/node_top.v (revision 37) @@ -0,0 +1,117 @@ +/* + 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 network node including a router, a NI and a processing element. + + History: + 03/03/2011 Initial version. + 30/05/2011 Clean up for opensource. + +*/ + +// the router structure definitions +`include "define.v" + +module node_top(/*AUTOARG*/ + // Outputs + so0, so1, so2, so3, wo0, wo1, wo2, wo3, no0, no1, no2, no3, eo0, + eo1, eo2, eo3, sia, wia, nia, eia, so4, wo4, no4, eo4, + // Inputs + si0, si1, si2, si3, wi0, wi1, wi2, wi3, ni0, ni1, ni2, ni3, ei0, + ei1, ei2, ei3, si4, wi4, ni4, ei4, soa, woa, noa, eoa, rst_n + ); + parameter DW = 32; + parameter VCN = 1; + parameter x = 0; + parameter y = 0; + parameter SCN = DW/2; + + input [VCN*SCN-1:0] si0, si1, si2, si3; + input [VCN*SCN-1:0] wi0, wi1, wi2, wi3; + input [VCN*SCN-1:0] ni0, ni1, ni2, ni3; + input [VCN*SCN-1:0] ei0, ei1, ei2, ei3; + output [VCN*SCN-1:0] so0, so1, so2, so3; + output [VCN*SCN-1:0] wo0, wo1, wo2, wo3; + output [VCN*SCN-1:0] no0, no1, no2, no3; + output [VCN*SCN-1:0] eo0, eo1, eo2, eo3; + wire [VCN*SCN-1:0] li0, li1, li2, li3; + wire [VCN*SCN-1:0] lo0, lo1, lo2, lo3; +`ifdef ENABLE_CHANNEL_SLICING + input [VCN*SCN-1:0] si4, wi4, ni4, ei4; + output [VCN*SCN-1:0] sia, wia, nia, eia; + output [VCN*SCN-1:0] so4, wo4, no4, eo4; + input [VCN*SCN-1:0] soa, woa, noa, eoa; + wire [VCN*SCN-1:0] li4, lia, lo4, loa; +`else + input [VCN-1:0] si4, wi4, ni4, ei4; + output [VCN-1:0] sia, wia, nia, eia; + output [VCN-1:0] so4, wo4, no4, eo4; + input [VCN-1:0] soa, woa, noa, eoa; + wire [VCN-1:0] li4, lia, lo4, loa; +`endif // !`ifdef ENABLE_CHANNEL_SLICING + + input rst_n; + + + // the network node + NetNode #(.DW(DW), .VCN(VCN), .x(x), .y(y)) + Node ( + .dia ( lia ), + .do4 ( lo4 ), + .doa ( loa ), + .di4 ( li4 ), + .do0 ( lo0 ), + .do1 ( lo1 ), + .do2 ( lo2 ), + .do3 ( lo3 ), + .di0 ( li0 ), + .di1 ( li1 ), + .di2 ( li2 ), + .di3 ( li3 ), + .rst_n ( rst_n ) + ); + + + // router wrapper + router_hdl #(.DW(DW), .VCN(VCN)) + RTN ( + .so0(so0), .so1(so1), .so2(so2), .so3(so3), .so4(so4), .soa(soa), + .wo0(wo0), .wo1(wo1), .wo2(wo2), .wo3(wo3), .wo4(wo4), .woa(woa), + .no0(no0), .no1(no1), .no2(no2), .no3(no3), .no4(no4), .noa(noa), + .eo0(eo0), .eo1(eo1), .eo2(eo2), .eo3(eo3), .eo4(eo4), .eoa(eoa), + .lo0(lo0), .lo1(lo1), .lo2(lo2), .lo3(lo3), .lo4(lo4), .loa(loa), + .si0(si0), .si1(si1), .si2(si2), .si3(si3), .si4(si4), .sia(sia), + .wi0(wi0), .wi1(wi1), .wi2(wi2), .wi3(wi3), .wi4(wi4), .wia(wia), + .ni0(ni0), .ni1(ni1), .ni2(ni2), .ni3(ni3), .ni4(ni4), .nia(nia), + .ei0(ei0), .ei1(ei1), .ei2(ei2), .ei3(ei3), .ei4(ei4), .eia(eia), + .li0(li0), .li1(li1), .li2(li2), .li3(li3), .li4(li4), .lia(lia), + .addrx (b2chain(x)), + .addry (b2chain(y)), + .rst_n (rst_n) + ); + + + // binary to 1-of-4 (Chain) converter + function [7:0] b2chain; + input [3:0] data; + begin + b2chain[0] = (data[1:0] == 2'b00); + b2chain[1] = (data[1:0] == 2'b01); + b2chain[2] = (data[1:0] == 2'b10); + b2chain[3] = (data[1:0] == 2'b11); + b2chain[4] = (data[3:2] == 2'b00); + b2chain[5] = (data[3:2] == 2'b01); + b2chain[6] = (data[3:2] == 2'b10); + b2chain[7] = (data[3:2] == 2'b11); + end + endfunction + +endmodule // node_top Index: sdm/tb/ni.h =================================================================== --- sdm/tb/ni.h (nonexistent) +++ sdm/tb/ni.h (revision 37) @@ -0,0 +1,59 @@ +/* + 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 SystemC network adapter/interface for NoC simulation. + + History: + 20/08/2008 Initial version. + 30/09/2010 Use template style packet definition. + 16/10/2010 Support SDM. + 30/05/2011 CLean up for opensource. + +*/ + +#ifndef NETWORK_ADAPTER_H_ +#define NETWORK_ADAPTER_H_ + +#include "define.h" +#include + +SC_MODULE(Network_Adapter) +{ + +public: + SC_HAS_PROCESS(Network_Adapter); + Network_Adapter( + sc_module_name name // module name + ,unsigned int x // location x + ,unsigned int y // location y + ); + ~Network_Adapter(); + + // interface with processor + sc_port > frame_in; // frame for transmission + sc_port > frame_out; // frame for receiving + + // interface with router + sc_port > IP [SubChN]; // input port from IO driver + sc_port > OP [SubChN]; // output port to IO driver + +private: + unsigned int loc_x,loc_y; // location information + + // functional thread + void ibuffer_thread(unsigned int); // input buffer respond thread + void obuffer_thread(unsigned int); // output buffer respond thread + + // other functions + bool check_frame(const FRAME& frame); // check the correctness of frame received +}; + +#endif /*NETWORK_ADAPTER_H_*/ Index: sdm/tb/netnode.cpp =================================================================== --- sdm/tb/netnode.cpp (nonexistent) +++ sdm/tb/netnode.cpp (revision 37) @@ -0,0 +1,23 @@ +/* + 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 module of network node including the processing element and the network interface. + Currently the transmission FIFO is 500 frame deep. + + History: + 26/02/2011 Initial version. + +*/ + +#include "netnode.h" + +NCSC_MODULE_EXPORT(NetNode) + Index: sdm/src/im_alloc.v =================================================================== --- sdm/src/im_alloc.v (revision 28) +++ sdm/src/im_alloc.v (revision 37) @@ -90,7 +90,7 @@ `else assign IPr[i][j] = |IPrm[i][j]; for(k=0; k +# + +# make sure the LDVHOME environment is ready for NC-Simulator, IUS/LDV, Cadence +export NCSC_GCC=${LDVHOME}/tools/systemc/gcc/bin/g++ + +CXXFLAG="-c -g -Wall -I../../common/tb -I../tb -I../" + +# remove the files from last run +rm -fr INCA_libs +rm *.o +rm *.so + +# compile verilog files +# cell library +ncvlog -nowarn RECOMP ../../lib/NangateOpenCellLibrary_typical_conditional.v +# synthesized design +ncvlog ../syn/file/router_syn.v +# other verilog test bench files +ncvlog -incdir ../ ../../common/tb/anaproc.v +ncvlog -sv -incdir ../ ../tb/rtwrapper.v +ncvlog -incdir ../ ../tb/netnode.v +ncvlog -sv -incdir ../ ../tb/noc_top.v +ncvlog -sv -incdir ../ ../tb/node_top.v +ncvlog ../tb/noctb.v + +#compile SystemC files +ncsc -compiler $NCSC_GCC -cflags "${CXXFLAG}" ../../common/tb/sim_ana.cpp +ncsc -compiler $NCSC_GCC -cflags "${CXXFLAG}" ../../common/tb/anaproc.cpp +ncsc -compiler $NCSC_GCC -cflags "${CXXFLAG}" ../tb/netnode.cpp +ncsc -compiler $NCSC_GCC -cflags "${CXXFLAG}" ../tb/ni.cpp +ncsc -compiler $NCSC_GCC -cflags "${CXXFLAG}" ../tb/rtdriver.cpp + +# build the run time link library +${NCSC_GCC} -Wl -shared -o sysc.so -L${CDS_LNX86_ROOT}/ldv_2009_sc/tools/lib \ + sim_ana.o anaproc.o netnode.o ni.o rtdriver.o \ + ${CDS_LNX86_ROOT}/ldv_2009_sc/tools/systemc/lib/gnu/libncscCoSim_sh.so \ + ${CDS_LNX86_ROOT}/ldv_2009_sc/tools/systemc/lib/gnu/libncscCoroutines_sh.so \ + ${CDS_LNX86_ROOT}/ldv_2009_sc/tools/systemc/lib/gnu/libsystemc_sh.so + +# elaborate the simulation +ncelab -timescale 1ns/1ps -access +rwc -loadsc sysc.so worklib.noctb +
sdm/sim/compile.sh Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: sdm/syn/script/constraint.tcl =================================================================== --- sdm/syn/script/constraint.tcl (revision 28) +++ sdm/syn/script/constraint.tcl (revision 37) @@ -41,7 +41,7 @@ # the delay cell in the lookahead pipeline # It is not a problem to get errors here if ENABLE_LOOKAHEAD is not defined. foreach_in_collection celln [get_references -hierarchical outp_buf_*] { - set_disable_timing [get_object_name $celln]/DLY/U -from A -to Z + set_disable_timing [get_object_name $celln]/*DLY/U -from A -to Z } # set some timing path ending points @@ -61,8 +61,8 @@ # set the timing constraints for data paths and ack paths # For better speed performance, please tune these delay and factors according different cell libraries -set DATA_dly 5 -set ACK_dly 8 +set DATA_dly 1.0 +set ACK_dly 1.6 set_max_delay [expr ${DATA_dly} * 1.00] -from ${DPA} -to ${DPD} -group G_DATA set_max_delay [expr ${ACK_dly} * 1.00] -from ${DPA} -to ${DPA} -group G_ACK @@ -81,4 +81,4 @@ set_max_area 0 # timing path disabled by user constraints -suppress_message TIM-175 \ No newline at end of file +suppress_message TIM-175
/sdm/syn/script/compile.tcl
12,7 → 12,7
# currently using the Nangate 45nm cell lib.
#
# History:
# 26/05/2009 Initial version. <wsong83@gmail.com>
# 31/05/2009 Initial version. <wsong83@gmail.com>
 
set rm_top router
set rm_para "VCN=>1, DW=>8, IPD=>1, OPD=>1"
36,6 → 36,7
 
# elaborate the design
elaborate ${rm_top} -parameters ${rm_para}
rename_design ${current_design} router
 
link
 
58,7 → 59,6
 
write -format verilog -hierarchy -out file/${current_design}_syn.v $current_design
write_sdf -significant_digits 5 file/${current_design}.sdf
write_sdc file/${current_design}.sdc
 
report_constraints -verbose
 
/TODO
0,0 → 1,9
01/06/2011 Urgent Clean up the VC router
01/06/2011 Urgent Provide better documents
01/06/2011 Support other routing algorithms
01/06/2011 Long time Support QoS ?? (necessary?) who needs it pls contact me
01/06/2011 Keep channel slicing inside routers
01/06/2011 Provide network interface
01/06/2011 Lookahead routing
01/06/2011 Support variable number of ports
01/06/2011 Unify local port by serialization/parallelization
/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
/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 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);
 
/common/tb/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
/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;
}
 
/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
/common/tb/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_ */
/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>
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
 
/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
/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>
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
/common/src/cell_lib.v
16,7 → 16,7
05/05/2009 Initial version. <wsong83@gmail.com>
20/05/2011 Change to general verilog description for opensource.
The Nangate cell library is used. <wsong83@gmail.com>
01/06/2011 The bugs in the C2 and C2P1 gates are fixed. <wsong83@gmail.com>
*/
 
// General 2-input C-element
30,7 → 30,7
nand U1 (m[0], a0, a1);
nand U2 (m[1], a0, q);
nand U3 (m[2], a1, q);
assign q = &m;
assign q = ~&m;
endmodule
 
46,7 → 46,7
nand U1 (m[0], a, d);
nand U2 (m[1], d, q);
nand U3 (m[2], a, q);
assign q = &m;
assign q = ~&m;
 
endmodule
 
105,7 → 105,7
nand U1 (m[0], a0, a1, b);
nand U2 (m[1], a0, q);
nand U3 (m[2], a1, q);
assign q = &m;
assign q = ~&m;
 
endmodule
 
/README
0,0 → 1,103
 
Asynchronous Spatial Division Multiplexing Router for On-Chip Networks
 
Version: 0.1
 
On-chip networks or networks-on-chip (NoCs) are the on-chip communication fabric for
current and future multiprocessor SoCs (MPSoCs) and chip multiprocessors (CMPs).
Compared with synchronous NoCs, asynchronous NoCs have following benefits:
* Tolerance to all kinds of delay variations caused by process, power and temperature
variations.
* Low transmission latency.
* Zero dynamic power when idle.
* Unified sync/async interface and easy clock domain integration.
 
Most NoCs use the wormhole flow control method. Many complex flow control methods are
built upon the wormhole method, such as virtual channel (VC), TDMA, and SDM. VC is the
most utilized flow control in both sync and async NoCs. However, it is found VC
compromises the throughput performance of asynchronous NoCs. This project provides a new
asynchronous router structure which use SDM rather than VC. It has been shown that SDM
achieve better throughput than VC in the same router configuration.
 
This project provide a reconfigurable asynchronous SDM router which can be configured
into a basic wormhole router or an SDM router with multiple virtual circuits in every
direction.
 
Features:
* 5-port router for mesh network (0 south, 1 west, 2 north, 3 east, 4 local)
* The dimension order routing (XY routing)
* Available flow control methods: wormhole, SDM
* Reconfigurable number of virtual circuits, buffer size, data width
* Fully synthesizable router implementation
* SystemC testbench provided
 
Languages:
* Routers are written in synthesizable SystemVerilog
* Test benches are provided by SystemC
 
Software requirements:
* The open source Nangate 45nm cell library
* Synopsys Design Compiler (Synthesis)
* Cadence IUS -- NC Simulator (for SystemC/Verilog co-simulation)
 
File structure:
* common files needed for both SDM and VC routers
\- script synthesis scripts for all routers
|- src HDL for all routers
\- tb test bench files for all routers
* doc documents
* lib minimal Nangate 45nm cell lib
* sdm SDM/wormhole router design
\- define.v HDL configuration file
|- define.h test bench configuration
|- sim simulation run dir
|- src HDL
|- syn synthesis run dir
\- script synthesis script
\- tb test bench
* vc VC router (ongoing)
 
How to run:
* to synthesize a router
1. set up your design compiler enviornment and your cell library.
2. modify the "define.v" configuration file for the strcture your want.
currently including:
ENABLE_CLOS use the 2-stage Clos switch instead of crossbar
ENABLE_CRRD use the CRRD dispatching algorithm for the Clos
ENABLE_MRMA use the multi-resource matching arbiter instead of MNMA
ENABLE_CHANNEL_SLICING use channel slicing
ENABLE_LOOKAHEAD use the lookahead pipelines
ENABLE_EOF router use eof bit to indicate end-of-frame
3. modify the "compile.tcl" scription for the design parameters.
currently including:
VCN number of virtual circuits
DW the data width of a single virtual circuit
IPD the depth of input buffers
OPD the depth of putput buffers
4. if another cell lib is used, change "cell_lib.v" in common\src and other related
files. (very likely you need to email me for further instructions :-) )
5. modify the "tech.tcl" in common/script for your cell library.
6. run the synthesis at [sdm/vc]/syn
dc_shell -f script/compile.tcl
7. the synthesized netlist is inside [sdm/vc]/syn/file/
 
* to run post-synthesis simulation
1. check the netlists in [sdm/vc]/syn/file/
2. modify the testbench configuration "define.h" according to your requirements.
3. make sure your NC-Simulator is installed alright (proper SystemC support).
4. run the compilation at [sdm/vc]/sim
compile.tcl
5. run the simulation at [sdm/vc]/sim
ncsim -tcl noctb
6. the simulation output files are *.ana at [sdm/vc]/sim
"throughput.ana":
{simulation time in ps} TAB {throughput in bytes}
"delay.ana":
{simulation time in ps} TAB {avg. frame latency} TAB {avg. path setup delay}
 
For any questions and bug reports,
please email to Wei Song from wsong83@gmail.com
 
Wei Song
01/06/2011
/.
. Property changes : Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /async_sdm_noc/branches/init:r28-36

powered by: WebSVN 2.1.0

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