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

Subversion Repositories async_sdm_noc

[/] [async_sdm_noc/] [branches/] [clos_opt/] [vc/] [tb/] [rtdriver.cpp] - Blame information for rev 59

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 45 wsong0210
    rtoca("rtoca")
32 43 wsong0210
{
33
  SC_METHOD(IPdetect);
34
  sensitive << rtia;
35
 
36
  SC_METHOD(OPdetect);
37
  sensitive << rtod[0] << rtod[1] << rtod[2] << rtod[3] << rtovc << rtoft;
38
 
39
  SC_METHOD(Creditdetect);
40
  for(unsigned int i = 0; i<SubChN; i++) {
41
    sensitive << CPa[i];
42
    sensitive << out_cred[i];
43
  }
44
  sensitive << rtic << rtoca;
45
 
46
  SC_THREAD(send);
47
  SC_THREAD(recv);
48
 
49
  rtinp_sig = false;
50
  rtoutp_sig = false;
51
}
52
 
53
void RTDriver::IPdetect() {
54
  sc_logic ack_lv_high, ack_lv_low;             // the sc_logic ack
55
 
56
  ack_lv_high = rtia.read();
57
  ack_lv_low = rtia.read();
58
 
59
  if(ack_lv_high.is_01() && ack_lv_high.to_bool())
60
    rtinp_sig = true;
61
 
62
  if(ack_lv_low.is_01() && (!ack_lv_low.to_bool()))
63
    rtinp_sig = false;
64
}
65
 
66
void RTDriver::OPdetect() {
67
  sc_lv<ChBW*4> data_lv;        // the ORed data
68
  sc_logic data_lv_high, data_lv_low;
69 45 wsong0210
  sc_lv<SubChN> vc_lv;          // the local copy of vc number
70
  sc_lv<3> ft_lv;               // the local copy of flit type
71 43 wsong0210
 
72
  data_lv = rtod[0].read() | rtod[1].read() | rtod[2].read() | rtod[3].read();
73 45 wsong0210
  vc_lv = rtovc.read();
74
  ft_lv = rtoft.read();
75
  data_lv_high = (sc_logic)(data_lv.and_reduce()) & (sc_logic)(vc_lv.or_reduce()) & (sc_logic)(ft_lv.or_reduce());
76
  data_lv_low = (sc_logic)(data_lv.or_reduce()) | (sc_logic)(vc_lv.or_reduce()) | (sc_logic)(ft_lv.or_reduce());
77 43 wsong0210
 
78
  if(data_lv_high.is_01() && data_lv_high.to_bool())
79
    rtoutp_sig = true;
80
 
81
  if(data_lv_high.is_01() && (!data_lv_low.to_bool()))
82
    rtoutp_sig = false;
83
}
84
 
85
void RTDriver::Creditdetect() {
86
  sc_lv<SubChN> mic;            // the local input credit
87
  sc_lv<SubChN> mica;           // the local input credit ack
88
  sc_lv<SubChN> moc;            // the local output credit;
89
  sc_lv<SubChN> moca;           // the local output credit ack;
90
 
91
  mic = rtic.read();
92
  moca = rtoca.read();
93
 
94
  for(unsigned int i=0; i<SubChN; i++) {
95
    CP[i].write(mic[i].is_01()? mic[i].to_bool():false);
96
    out_cred_ack[i] = moca[i].is_01()? moca[i].to_bool():false;
97
    mica[i] = CPa[i].read();
98
    moc[i] = out_cred[i];
99
  }
100
 
101
  rtica.write(mica);
102
  rtoc.write(moc);
103
}
104
 
105
void RTDriver::send() {
106
  FLIT mflit;                   // the local flit buffer
107
  unsigned int i, j;            // local loop index
108
  sc_lv<ChBW*4> mdata[4];       // local data copy
109
  sc_lv<SubChN> mvc;            // local vcn
110
  sc_lv<3> mft;                 // local flit type
111
 
112
  // initialize the output ports
113
  mdata[0] = 0;
114
  mdata[1] = 0;
115
  mdata[2] = 0;
116
  mdata[3] = 0;
117
  mvc = 0;
118
  mft = 0;
119
 
120
 
121
  rtid[0].write(mdata[0]);
122
  rtid[1].write(mdata[1]);
123
  rtid[2].write(mdata[2]);
124
  rtid[3].write(mdata[3]);
125
  rtivc.write(mvc);
126
  rtift.write(mft);
127
 
128
  while(true) {
129
    mflit = NI2P->read();       // read in the flit
130
 
131
    // write the flit
132
    if(mflit.ftype == F_HD) {
133
      // the target address
134
      mdata[mflit.addrx&0x3][0] = SC_LOGIC_1;
135
      mdata[(mflit.addrx&0xc)>>2][1] = SC_LOGIC_1;
136
      mdata[mflit.addry&0x3][2] = SC_LOGIC_1;
137
      mdata[(mflit.addry&0xc)>>2][3] = SC_LOGIC_1;
138
 
139
      for(i=0,j=4; i<(ChBW-1)*4; i++, j++) {
140
        switch((mflit[i/4] >> ((i%4)*2)) & 0x3) {
141
        case 0: mdata[0][j] = SC_LOGIC_1; break;
142
        case 1: mdata[1][j] = SC_LOGIC_1; break;
143
        case 2: mdata[2][j] = SC_LOGIC_1; break;
144
        case 3: mdata[3][j] = SC_LOGIC_1; break;
145
        }
146
      }
147
    } else {
148
      for(i=0; i<ChBW*4; i++) {
149
        switch((mflit[i/4] >> ((i%4)*2)) & 0x3) {
150
        case 0: mdata[0][i] = SC_LOGIC_1; break;
151
        case 1: mdata[1][i] = SC_LOGIC_1; break;
152
        case 2: mdata[2][i] = SC_LOGIC_1; break;
153
        case 3: mdata[3][i] = SC_LOGIC_1; break;
154
        }
155
      }
156
    }
157
 
158
    // flit type
159
    switch(mflit.ftype) {
160
    case F_HD: mft[0] = SC_LOGIC_1; break;
161
    case F_DAT: mft[1] = SC_LOGIC_1; break;
162
    case F_TL: mft[2] = SC_LOGIC_1; break;
163 45 wsong0210
    default: break;
164 43 wsong0210
    }
165
 
166
    // VC number
167
    mvc[mflit.vcn] = SC_LOGIC_1;
168
 
169
    // write to the port
170
    rtid[0].write(mdata[0]);
171
    rtid[1].write(mdata[1]);
172
    rtid[2].write(mdata[2]);
173
    rtid[3].write(mdata[3]);
174
    rtivc.write(mvc);
175
    rtift.write(mft);
176
 
177
    // wait for the router to capture the data
178
    wait(rtinp_sig.posedge_event());
179
    wait(0.2, SC_NS);           // a delay to avoid data override
180
 
181
    // clear the data
182
    mdata[0] = 0;
183
    mdata[1] = 0;
184
    mdata[2] = 0;
185
    mdata[3] = 0;
186
    mvc = 0;
187
    mft = 0;
188
 
189
    rtid[0].write(mdata[0]);
190
    rtid[1].write(mdata[1]);
191
    rtid[2].write(mdata[2]);
192
    rtid[3].write(mdata[3]);
193
    rtivc.write(mvc);
194
    rtift.write(mft);
195
 
196
    // wait for the input port be ready again
197
    wait(rtinp_sig.negedge_event());
198
    wait(0.2, SC_NS);           // a delay to avoid data override
199
  }
200
}
201
 
202
void RTDriver::recv() {
203
  FLIT mflit;                   // the local flit buffer
204
  sc_lv<ChBW*4> mdata[4];       // local data copy
205
  sc_lv<SubChN> mvc;            // local vc number
206
  sc_lv<3> mft;                 // local flit type
207
  sc_logic mack = SC_LOGIC_0;   // local copy of ack
208
  sc_lv<4> dd;                // the current 1-of-4 data under process
209
  unsigned int i, j;          // local loop index
210
 
211
  // initialize the ack signal
212
  rtoa.write(mack);
213
 
214
  while(true) {
215 45 wsong0210
    // wait for an incoming flit
216
    wait(rtoutp_sig.posedge_event());
217
    if(out_cred_ack[mflit.vcn].read())
218
      wait(out_cred_ack[mflit.vcn].negedge_event());
219
 
220 43 wsong0210
    // clear the flit
221
    mflit.clear();
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 45 wsong0210
    while(fvcn != 1) {
274 43 wsong0210
      mflit.vcn += 1;
275
      fvcn >>= 1;
276
    }
277
 
278
    // send the flit to the NI
279
    P2NI->write(mflit);
280 45 wsong0210
 
281
    // send back a credit
282
    out_cred[mflit.vcn] = true;
283 43 wsong0210
 
284
    wait(0.2, SC_NS);           // a delay to avoid data override
285
    rtoa.write(~mack);          // notify that data is captured
286
 
287
    // wait for the data withdrawal
288
    wait(rtoutp_sig.negedge_event());
289 45 wsong0210
    if(!out_cred_ack[mflit.vcn].read())
290
      wait(out_cred_ack[mflit.vcn].posedge_event());
291
 
292 43 wsong0210
    wait(0.2, SC_NS);           // a delay to avoid data override
293
    rtoa.write(mack);           // notify that data is captured
294 45 wsong0210
    out_cred[mflit.vcn] = false;
295 43 wsong0210
  }
296
}
297
 
298
unsigned int RTDriver::c1o42b(unsigned int dd) {
299
  switch(dd) {
300
  case 1: return 0;
301
  case 2: return 1;
302
  case 4: return 2;
303
  case 8: return 3;
304
  default: return 0xff;
305
  }
306
}

powered by: WebSVN 2.1.0

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