1 |
31 |
wsong0210 |
/*
|
2 |
|
|
Asynchronous SDM NoC
|
3 |
|
|
(C)2011 Wei Song
|
4 |
|
|
Advanced Processor Technologies Group
|
5 |
|
|
Computer Science, the Univ. of Manchester, UK
|
6 |
|
|
|
7 |
|
|
Authors:
|
8 |
|
|
Wei Song wsong83@gmail.com
|
9 |
|
|
|
10 |
|
|
License: LGPL 3.0 or later
|
11 |
|
|
|
12 |
|
|
The SystemC module of network node including the processing element and the network interface.
|
13 |
|
|
Currently the transmission FIFO is 500 frame deep.
|
14 |
|
|
|
15 |
|
|
History:
|
16 |
|
|
26/02/2011 Initial version. <wsong83@gmail.com>
|
17 |
32 |
wsong0210 |
30/05/2011 Clean up for opensource. <wsong83@gmail.com>
|
18 |
31 |
wsong0210 |
|
19 |
|
|
*/
|
20 |
|
|
|
21 |
|
|
#ifndef NETNODE_H_
|
22 |
|
|
#define NETNODE_H_
|
23 |
|
|
|
24 |
32 |
wsong0210 |
#include "define.h"
|
25 |
31 |
wsong0210 |
#include <systemc.h>
|
26 |
|
|
#include "ni.h"
|
27 |
|
|
#include "procelem.h"
|
28 |
|
|
#include "rtdriver.h"
|
29 |
|
|
|
30 |
|
|
class NetNode : public sc_module {
|
31 |
|
|
public:
|
32 |
|
|
RTDriver * LIOD [SubChN]; /* driving and convert I/O to/from router local port */
|
33 |
|
|
Network_Adapter * NI; /* network interface */
|
34 |
|
|
ProcElem * PE; /* processor element */
|
35 |
|
|
|
36 |
|
|
#ifdef ENABLE_CHANNEL_CLISING
|
37 |
|
|
sc_signal<sc_lv<ChBW*4> > rtia [SubChN]; /* input ack to router */
|
38 |
|
|
sc_signal<sc_lv<ChBW*4> > rtod4 [SubChN]; /* output eof to router */
|
39 |
|
|
sc_signal<sc_lv<ChBW*4> > rtoa [SubChN]; /* output ack from router */
|
40 |
|
|
sc_signal<sc_lv<ChBW*4> > rtid4 [SubChN]; /* input data from router */
|
41 |
|
|
sc_in<sc_lv<SubChN*ChBW*4> > dia; /* input ack, undivided */
|
42 |
|
|
sc_in<sc_lv<SubChN*ChBW*4> > do4; /* output eof, undivided */
|
43 |
|
|
sc_out<sc_lv<SubChN*ChBW*4> > doa; /* output ack, undivided */
|
44 |
|
|
sc_out<sc_lv<SubChN*ChBW*4> > di4; /* input eof, undivided */
|
45 |
|
|
#else
|
46 |
|
|
sc_signal<sc_logic > rtia [SubChN]; /* input ack to router */
|
47 |
|
|
sc_signal<sc_logic > rtod4 [SubChN]; /* output data to router */
|
48 |
|
|
sc_signal<sc_logic > rtoa [SubChN]; /* output ack from router */
|
49 |
|
|
sc_signal<sc_logic > rtid4 [SubChN]; /* input eof from router */
|
50 |
|
|
sc_in<sc_lv<SubChN> > dia; /* input ack, undivided */
|
51 |
|
|
sc_in<sc_lv<SubChN> > do4; /* output eof, undivided */
|
52 |
|
|
sc_out<sc_lv<SubChN> > doa; /* output ack, undivided */
|
53 |
|
|
sc_out<sc_lv<SubChN> > di4; /* input eof, undivided */
|
54 |
|
|
#endif
|
55 |
|
|
|
56 |
|
|
sc_signal<sc_lv<ChBW*4 > > rtod [SubChN][4]; /* output data to router */
|
57 |
|
|
sc_signal<sc_lv<ChBW*4 > > rtid [SubChN][4]; /* input data from router */
|
58 |
|
|
sc_in<sc_lv<SubChN*ChBW*4 > > do0; /* output d0, undivided */
|
59 |
|
|
sc_in<sc_lv<SubChN*ChBW*4 > > do1;
|
60 |
|
|
sc_in<sc_lv<SubChN*ChBW*4 > > do2;
|
61 |
|
|
sc_in<sc_lv<SubChN*ChBW*4 > > do3;
|
62 |
|
|
sc_out<sc_lv<SubChN*ChBW*4 > > di0; /* input data, undivided */
|
63 |
|
|
sc_out<sc_lv<SubChN*ChBW*4 > > di1;
|
64 |
|
|
sc_out<sc_lv<SubChN*ChBW*4 > > di2;
|
65 |
|
|
sc_out<sc_lv<SubChN*ChBW*4 > > di3;
|
66 |
|
|
sc_in<sc_logic > rst_n; /* global reste, from the verilog top level */
|
67 |
|
|
|
68 |
|
|
// signals between IOD and NI
|
69 |
|
|
sc_fifo<pdu_flit<ChBW> > * NI2P [SubChN]; /* flit fifo, from NI to IO driver */
|
70 |
|
|
sc_fifo<pdu_flit<ChBW> > * P2NI [SubChN]; /* flit fifo, from IO driver to NI */
|
71 |
|
|
|
72 |
|
|
// signals between NI and FG/FS
|
73 |
|
|
sc_fifo<pdu_frame<ChBW> > * FIQ; /* the frame fifo, from PE to NI */
|
74 |
|
|
sc_fifo<pdu_frame<ChBW> > * FOQ; /* the frame fifo, from NI to PE */
|
75 |
|
|
sc_signal<bool> brst_n; /* the reset in the SystemC modules */
|
76 |
|
|
|
77 |
|
|
int x, y; /* private local address */
|
78 |
|
|
|
79 |
|
|
SC_CTOR(NetNode)
|
80 |
|
|
: dia("dia"), do4("do4"), doa("doa"), di4("di4"),
|
81 |
|
|
do0("do0"), do1("do1"), do2("do2"), do3("do3"),
|
82 |
|
|
di0("di0"), di1("di1"), di2("di2"), di3("di3"),
|
83 |
|
|
rst_n("rst_n")
|
84 |
|
|
{
|
85 |
|
|
// dynamically get the parameters from Verilog test bench
|
86 |
|
|
ncsc_get_param("x", x);
|
87 |
|
|
ncsc_get_param("y", y);
|
88 |
|
|
|
89 |
|
|
// initialization
|
90 |
|
|
NI = new Network_Adapter("NI", x, y);
|
91 |
|
|
PE = new ProcElem("PE", x, y);
|
92 |
|
|
FIQ = new sc_fifo<pdu_frame<ChBW> >(500); /* currently the fifo from PE is 500 frame deep */
|
93 |
|
|
FOQ = new sc_fifo<pdu_frame<ChBW> >(1);
|
94 |
|
|
for(unsigned int j=0; j<SubChN; j++) {
|
95 |
|
|
LIOD[j] = new RTDriver("LIOD");
|
96 |
|
|
NI2P[j] = new sc_fifo<pdu_flit<ChBW> >(1);
|
97 |
|
|
P2NI[j] = new sc_fifo<pdu_flit<ChBW> >(1);
|
98 |
|
|
}
|
99 |
|
|
|
100 |
|
|
// connections
|
101 |
|
|
for(unsigned int j=0; j<SubChN; j++) {
|
102 |
|
|
LIOD[j]->NI2P(*NI2P[j]);
|
103 |
|
|
LIOD[j]->P2NI(*P2NI[j]);
|
104 |
|
|
for(unsigned int k=0; k<4; k++) {
|
105 |
|
|
LIOD[j]->rtid[k](rtid[j][k]);
|
106 |
|
|
LIOD[j]->rtod[k](rtod[j][k]);
|
107 |
|
|
}
|
108 |
|
|
LIOD[j]->rtia(rtia[j]);
|
109 |
|
|
LIOD[j]->rtid4(rtid4[j]);
|
110 |
|
|
LIOD[j]->rtoa(rtoa[j]);
|
111 |
|
|
LIOD[j]->rtod4(rtod4[j]);
|
112 |
|
|
}
|
113 |
|
|
|
114 |
|
|
NI->frame_in(*FIQ);
|
115 |
|
|
NI->frame_out(*FOQ);
|
116 |
|
|
for(unsigned int j=0; j<SubChN; j++) {
|
117 |
|
|
NI->IP[j](*P2NI[j]);
|
118 |
|
|
NI->OP[j](*NI2P[j]);
|
119 |
|
|
}
|
120 |
|
|
|
121 |
|
|
PE->rst_n(brst_n);
|
122 |
|
|
PE->Fout(*FIQ);
|
123 |
|
|
PE->Fin(*FOQ);
|
124 |
|
|
|
125 |
|
|
brst_n.write(false);
|
126 |
|
|
|
127 |
|
|
SC_METHOD(rst_proc);
|
128 |
|
|
sensitive << rst_n;
|
129 |
|
|
|
130 |
|
|
sc_spawn_options opt_inp;
|
131 |
|
|
opt_inp.spawn_method();
|
132 |
|
|
for(unsigned int j=0; j<SubChN; j++) {
|
133 |
|
|
opt_inp.set_sensitivity(&rtid[j][0]);
|
134 |
|
|
opt_inp.set_sensitivity(&rtid[j][1]);
|
135 |
|
|
opt_inp.set_sensitivity(&rtid[j][2]);
|
136 |
|
|
opt_inp.set_sensitivity(&rtid[j][3]);
|
137 |
|
|
opt_inp.set_sensitivity(&rtid4[j]);
|
138 |
|
|
}
|
139 |
|
|
opt_inp.set_sensitivity(&dia);
|
140 |
|
|
sc_spawn(sc_bind(&NetNode::VC_inp, this), NULL, &opt_inp);
|
141 |
|
|
|
142 |
|
|
|
143 |
|
|
sc_spawn_options opt_outp;
|
144 |
|
|
opt_outp.spawn_method();
|
145 |
|
|
for(unsigned int j=0; j<SubChN; j++) {
|
146 |
|
|
opt_outp.set_sensitivity(&rtoa[j]);
|
147 |
|
|
}
|
148 |
|
|
opt_outp.set_sensitivity(&do0);
|
149 |
|
|
opt_outp.set_sensitivity(&do1);
|
150 |
|
|
opt_outp.set_sensitivity(&do2);
|
151 |
|
|
opt_outp.set_sensitivity(&do3);
|
152 |
|
|
opt_outp.set_sensitivity(&do4);
|
153 |
|
|
sc_spawn(sc_bind(&NetNode::VC_outp, this), NULL, &opt_outp);
|
154 |
|
|
}
|
155 |
|
|
|
156 |
|
|
|
157 |
|
|
// thread to divide the input buses according to virtual circuits
|
158 |
|
|
void VC_inp() {
|
159 |
|
|
|
160 |
|
|
sc_lv<SubChN*ChBW*4> md[4];
|
161 |
|
|
#ifdef ENABLE_CHANNEL_CLISING
|
162 |
|
|
sc_lv<SubChN*ChBW*4> md4;
|
163 |
|
|
sc_lv<SubChN*ChBW*4> mda;
|
164 |
|
|
#else
|
165 |
|
|
sc_lv<SubChN> md4;
|
166 |
|
|
sc_lv<SubChN> mda;
|
167 |
|
|
#endif
|
168 |
|
|
|
169 |
|
|
mda = dia.read();
|
170 |
|
|
|
171 |
|
|
for(unsigned int i=0; i<SubChN; i++) {
|
172 |
|
|
#ifdef ENABLE_CHANNEL_CLISING
|
173 |
|
|
rtia[i].write(mda(ChBW*4*(i+1)-1, ChBW*4*i));
|
174 |
|
|
md4(ChBW*4*(i+1)-1, ChBW*4*i) = rtid4[i].read();
|
175 |
|
|
#else
|
176 |
|
|
rtia[i].write(mda[i]);
|
177 |
|
|
md4[i] = rtid4[i].read();
|
178 |
|
|
#endif
|
179 |
|
|
md[0](ChBW*4*(i+1)-1, ChBW*4*i) = rtid[i][0].read();
|
180 |
|
|
md[1](ChBW*4*(i+1)-1, ChBW*4*i) = rtid[i][1].read();
|
181 |
|
|
md[2](ChBW*4*(i+1)-1, ChBW*4*i) = rtid[i][2].read();
|
182 |
|
|
md[3](ChBW*4*(i+1)-1, ChBW*4*i) = rtid[i][3].read();
|
183 |
|
|
}
|
184 |
|
|
|
185 |
|
|
di0.write(md[0]);
|
186 |
|
|
di1.write(md[1]);
|
187 |
|
|
di2.write(md[2]);
|
188 |
|
|
di3.write(md[3]);
|
189 |
|
|
di4.write(md4);
|
190 |
|
|
}
|
191 |
|
|
|
192 |
|
|
// thread to combine the buses according to virtual circuits
|
193 |
|
|
void VC_outp() {
|
194 |
|
|
sc_lv<SubChN*ChBW*4> md[4];
|
195 |
|
|
#ifdef ENABLE_CHANNEL_CLISING
|
196 |
|
|
sc_lv<SubChN*ChBW*4> md4;
|
197 |
|
|
sc_lv<SubChN*ChBW*4> mda;
|
198 |
|
|
#else
|
199 |
|
|
sc_lv<SubChN> md4;
|
200 |
|
|
sc_lv<SubChN> mda;
|
201 |
|
|
#endif
|
202 |
|
|
|
203 |
|
|
md[0] = do0.read();
|
204 |
|
|
md[1] = do1.read();
|
205 |
|
|
md[2] = do2.read();
|
206 |
|
|
md[3] = do3.read();
|
207 |
|
|
md4 = do4.read();
|
208 |
|
|
|
209 |
|
|
|
210 |
|
|
for(unsigned int i=0; i<SubChN; i++) {
|
211 |
|
|
#ifdef ENABLE_CHANNEL_CLISING
|
212 |
|
|
mda(ChBW*4*(i+1)-1, ChBW*4*i) = rtoa[i].read();
|
213 |
|
|
rtod4[i].write(md4(ChBW*4*(i+1)-1, ChBW*4*i));
|
214 |
|
|
#else
|
215 |
|
|
mda[i] = rtoa[i].read();
|
216 |
|
|
rtod4[i].write(md4[i]);
|
217 |
|
|
#endif
|
218 |
|
|
rtod[i][0].write(md[0](ChBW*4*(i+1)-1, ChBW*4*i));
|
219 |
|
|
rtod[i][1].write(md[1](ChBW*4*(i+1)-1, ChBW*4*i));
|
220 |
|
|
rtod[i][2].write(md[2](ChBW*4*(i+1)-1, ChBW*4*i));
|
221 |
|
|
rtod[i][3].write(md[3](ChBW*4*(i+1)-1, ChBW*4*i));
|
222 |
|
|
}
|
223 |
|
|
|
224 |
|
|
doa.write(mda);
|
225 |
|
|
}
|
226 |
|
|
|
227 |
|
|
// generate the reset for SystemC modules
|
228 |
|
|
void rst_proc() {
|
229 |
|
|
bool mrst_n;
|
230 |
|
|
mrst_n = rst_n.read().is_01() ? rst_n.read().to_bool() : false;
|
231 |
|
|
brst_n.write(mrst_n);
|
232 |
|
|
}
|
233 |
|
|
};
|
234 |
|
|
|
235 |
|
|
|
236 |
|
|
#endif
|