OpenCores
URL https://opencores.org/ocsvn/async_sdm_noc/async_sdm_noc/trunk

Subversion Repositories async_sdm_noc

[/] [async_sdm_noc/] [trunk/] [sdm/] [tb/] [rtdriver.cpp] - Blame information for rev 37

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 32 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 port driver between NI and router.
13
 
14
 History:
15
 27/04/2010  Initial version. <wsong83@gmail.com>
16
 16/10/2010  Support SDM. <wsong83@gmail.com>
17 33 wsong0210
 31/05/2011  Remove the sc_unit datatype to support data width larger than 64. <wsong83@gmail.com>
18 32 wsong0210
 
19
*/
20
 
21
#include "rtdriver.h"
22
 
23
RTDriver::RTDriver(sc_module_name mname)
24
  : sc_module(mname),
25
    NI2P("NI2P"),
26
    P2NI("P2NI")
27
{
28
  SC_METHOD(IPdetect);
29
  sensitive << rtia;
30
 
31
  SC_METHOD(OPdetect);
32
  sensitive << rtod[0] << rtod[1] << rtod[2] << rtod[3] << rtod4;
33
 
34
  SC_THREAD(send);
35
  SC_THREAD(recv);
36
 
37
  rtinp_sig = false;
38
  rtoutp_sig = false;
39
}
40
 
41
void RTDriver::IPdetect() {
42
  sc_logic ack_lv_high, ack_lv_low;             // the sc_logic ack
43
 
44
  // read the ack
45
#ifdef ENABLE_CHANNEL_CLISING
46
  ack_lv_high = rtia.read().and_reduce();
47 34 wsong0210
  ack_lv_low = rtia.read().or_reduce();
48 32 wsong0210
#else
49
  ack_lv_high = rtia.read();
50 34 wsong0210
  ack_lv_low = rtia.read();
51 32 wsong0210
#endif  
52
 
53
  if(ack_lv_high.is_01() && ack_lv_high.to_bool())
54
    rtinp_sig = true;
55
 
56
  if(ack_lv_low.is_01() && (!ack_lv_low.to_bool()))
57
    rtinp_sig = false;
58
}
59
 
60
void RTDriver::OPdetect() {
61
  sc_lv<ChBW*4> data_lv;        // the ORed data
62
  sc_logic data_lv_high, data_lv_low;
63
 
64
#ifdef ENABLE_CHANNEL_CLISING
65
  data_lv = rtod[0].read() | rtod[1].read() | rtod[2].read() | rtod[3].read() | rtod4.read();
66
  data_lv_high = data_lv.and_reduce();
67
  data_lv_low = data_lv.or_reduce();
68
#else
69
  data_lv = rtod[0].read() | rtod[1].read() | rtod[2].read() | rtod[3].read();
70 34 wsong0210
  data_lv_high = data_lv.and_reduce() | rtod4.read();
71 32 wsong0210
  data_lv_low = data_lv.or_reduce() | rtod4.read();
72
#endif
73
 
74
  if(data_lv_high.is_01() && data_lv_high.to_bool())
75
    rtoutp_sig = true;
76
 
77
  if(data_lv_high.is_01() && (!data_lv_low.to_bool()))
78
    rtoutp_sig = false;
79
}
80
 
81
void RTDriver::send() {
82
  FLIT mflit;                   // the local flit buffer
83
  unsigned int i, j;            // local loop index
84
  sc_lv<ChBW*4> mdata[4];       // local data copy
85
#ifdef ENABLE_CHANNEL_CLISING
86
  sc_lv<ChBW*4>  mdata4;        // local copy of eof
87
#else
88
  sc_logic mdata4;              // local copy of eof
89
#endif
90
 
91
  // initialize the output ports
92
  mdata[0] = 0;
93
  mdata[1] = 0;
94
  mdata[2] = 0;
95
  mdata[3] = 0;
96
#ifdef ENABLE_CHANNEL_CLISING
97
  mdata4 = 0;
98
#else
99
  mdata4 = false;
100
#endif
101
 
102
  rtid[0].write(mdata[0]);
103
  rtid[1].write(mdata[1]);
104
  rtid[2].write(mdata[2]);
105
  rtid[3].write(mdata[3]);
106
  rtid4.write(mdata4);
107
 
108
  while(true) {
109
    mflit = NI2P->read();       // read in the flit
110
 
111
    // write the flit
112
    if(mflit.ftype == F_HD) {
113
      // the target address
114
      mdata[mflit.addrx&0x3][0] = SC_LOGIC_1;
115
      mdata[(mflit.addrx&0xc)>>2][1] = SC_LOGIC_1;
116
      mdata[mflit.addry&0x3][2] = SC_LOGIC_1;
117
      mdata[(mflit.addry&0xc)>>2][3] = SC_LOGIC_1;
118
 
119
      for(i=0,j=4; i<(ChBW-1)*4; i++, j++) {
120
        switch((mflit[i/4] >> ((i%4)*2)) & 0x3) {
121
        case 0: mdata[0][j] = SC_LOGIC_1; break;
122
        case 1: mdata[1][j] = SC_LOGIC_1; break;
123
        case 2: mdata[2][j] = SC_LOGIC_1; break;
124
        case 3: mdata[3][j] = SC_LOGIC_1; break;
125
        }
126
      }
127
    } else {
128
      for(i=0; i<ChBW*4; i++) {
129
        switch((mflit[i/4] >> ((i%4)*2)) & 0x3) {
130
        case 0: mdata[0][i] = SC_LOGIC_1; break;
131
        case 1: mdata[1][i] = SC_LOGIC_1; break;
132
        case 2: mdata[2][i] = SC_LOGIC_1; break;
133
        case 3: mdata[3][i] = SC_LOGIC_1; break;
134
        }
135
      }
136
    }
137
 
138
    // write to the port
139
    rtid[0].write(mdata[0]);
140
    rtid[1].write(mdata[1]);
141
    rtid[2].write(mdata[2]);
142
    rtid[3].write(mdata[3]);
143
 
144
    // wait for the router to capture the data
145
    wait(rtinp_sig.posedge_event());
146
    wait(0.2, SC_NS);           // a delay to avoid data override
147
 
148
    // clear the data
149
    mdata[0] = 0;
150
    mdata[1] = 0;
151
    mdata[2] = 0;
152
    mdata[3] = 0;
153
 
154
    rtid[0].write(mdata[0]);
155
    rtid[1].write(mdata[1]);
156
    rtid[2].write(mdata[2]);
157
    rtid[3].write(mdata[3]);
158
 
159
    // wait for the input port be ready again
160
    wait(rtinp_sig.negedge_event());
161
    wait(0.2, SC_NS);           // a delay to avoid data override
162
 
163
    // check whether a tailf flit is needed
164
    if(mflit.ftype == F_TL) {
165
      // write the eof
166
      rtid4.write(~mdata4);
167
 
168
      // wait for the router to capture the data
169
      wait(rtinp_sig.posedge_event());
170
      wait(0.2, SC_NS);         // a delay to avoid data override
171
 
172
      // clear the eof
173 35 wsong0210
      rtid4.write(mdata4);
174 32 wsong0210
 
175
      // wait for the input port be ready again
176
      wait(rtinp_sig.negedge_event());
177
      wait(0.2, SC_NS);         // a delay to avoid data override
178
    }
179
  }
180
}
181
 
182
void RTDriver::recv() {
183
  FLIT mflit;                   // the local flit buffer
184
  sc_lv<ChBW*4> mdata[4];       // local data copy
185
#ifdef ENABLE_CHANNEL_CLISING
186
  sc_lv<ChBW*4>  mdata4;        // local copy of eof
187
  sc_lv<ChBW*4>  mack = 0;       // local copy of ack
188
#else
189
  sc_logic mdata4;              // local copy of eof
190
  sc_logic mack = SC_LOGIC_0;   // local copy of ack
191
#endif
192
  sc_lv<4> dd;                // the current 1-of-4 data under process
193
  unsigned int i, j;            // local loop index
194
 
195
  bool is_hd = true;            // the current flit is a header flit
196
 
197 33 wsong0210
  // initialize the ack signal
198
  rtoa.write(mack);
199
 
200 32 wsong0210
  while(true) {
201
    // clear the flit
202
    mflit.clear();
203
 
204
    // wait for an incoming flit
205
    wait(rtoutp_sig.posedge_event());
206
 
207
    // analyse the flit
208
    mdata[0] = rtod[0].read();
209
    mdata[1] = rtod[1].read();
210
    mdata[2] = rtod[2].read();
211
    mdata[3] = rtod[3].read();
212
    mdata4 = rtod4.read();
213
 
214
    if(is_hd) {
215
      mflit.ftype = F_HD;
216
      is_hd = false;
217
    }
218
#ifdef ENABLE_CHANNEL_CLISING
219
    else if(mdata4[0].to_bool()) {
220
      mflit.ftype = F_TL;
221
      is_hd = true;
222
    }
223
#else
224
    else if(mdata4.to_bool()) {
225
      mflit.ftype = F_TL;
226
      is_hd = true;
227
    }
228
#endif
229
    else {
230
      mflit.ftype = F_DAT;
231
    }
232
 
233
    if(mflit.ftype == F_HD) {
234
      // fetch the address
235
      dd[0] = mdata[0][0]; dd[1] = mdata[1][0]; dd[2] = mdata[2][0]; dd[3] = mdata[3][0];
236
      mflit.addrx |= (c1o42b(dd.to_uint()) << 0);
237
      dd[0] = mdata[0][1]; dd[1] = mdata[1][1]; dd[2] = mdata[2][1]; dd[3] = mdata[3][1];
238
      mflit.addrx |= (c1o42b(dd.to_uint()) << 2);
239
      dd[0] = mdata[0][2]; dd[1] = mdata[1][2]; dd[2] = mdata[2][2]; dd[3] = mdata[3][2];
240
      mflit.addry |= (c1o42b(dd.to_uint()) << 0);
241
      dd[0] = mdata[0][3]; dd[1] = mdata[1][3]; dd[2] = mdata[2][3]; dd[3] = mdata[3][3];
242
      mflit.addry |= (c1o42b(dd.to_uint()) << 2);
243
 
244
      // fill in data
245
      for(i=1; i<ChBW; i++) {
246
        for(j=0; j<4; j++) {
247
          dd[0] = mdata[0][i*4+j];
248
          dd[1] = mdata[1][i*4+j];
249
          dd[2] = mdata[2][i*4+j];
250
          dd[3] = mdata[3][i*4+j];
251 34 wsong0210
          mflit[i-1] |= c1o42b(dd.to_uint()) << j*2;
252 32 wsong0210
        }
253
      }
254
    } else if (mflit.ftype != F_TL) {
255
      // fill in data
256
      for(i=0; i<ChBW; i++) {
257
        for(j=0; j<4; j++) {
258
          dd[0] = mdata[0][i*4+j];
259
          dd[1] = mdata[1][i*4+j];
260
          dd[2] = mdata[2][i*4+j];
261
          dd[3] = mdata[3][i*4+j];
262 34 wsong0210
          mflit[i] |= c1o42b(dd.to_uint()) << j*2;
263 32 wsong0210
        }
264
      }
265
    }
266
 
267
    // send the flit to the NI
268
    P2NI->write(mflit);
269
 
270
    wait(0.2, SC_NS);           // a delay to avoid data override
271
    rtoa.write(~mack);          // notify that data is captured
272
 
273
    // wait for the data withdrawal
274
    wait(rtoutp_sig.negedge_event());
275
    wait(0.2, SC_NS);           // a delay to avoid data override
276
    rtoa.write(mack);           // notify that data is captured
277
 
278
  }
279
}
280
 
281
unsigned int RTDriver::c1o42b(unsigned int dd) {
282
  switch(dd) {
283
  case 1: return 0;
284
  case 2: return 1;
285
  case 4: return 2;
286
  case 8: return 3;
287
  default: return 0xff;
288
  }
289
}

powered by: WebSVN 2.1.0

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