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

Subversion Repositories async_sdm_noc

[/] [async_sdm_noc/] [branches/] [init/] [vc/] [tb/] [rtdriver.cpp] - Blame information for rev 43

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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