OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [src_c/] [synfull/] [pronoc-interface/] [src/] [dpi_interface.cpp] - Blame information for rev 54

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 54 alirezamon
#include <stdio.h>
2
#include <stdlib.h>
3
#include <sstream>
4
#include <cassert>
5
#include <cstdlib>
6
#include <cstdio>
7
#include <cerrno>
8
#include "socketstream.h"
9
#include "messages.h"
10
#include "svdpi.h"
11
#include "dpi_interface.hpp"
12
 
13
 
14
extern "C" void connection_init (
15
        svLogic startCom, svLogic *ready
16
        )
17
{
18
 
19
    if ( startCom == 1 )
20
    {
21
        _connection_manager = new connection_manager;
22
        rp = new RequestPacket();
23
        _connection_manager->Init();
24
        *ready = '1';
25
    }
26
 
27
}
28
 
29
extern "C" void c_dpi_interface (
30
        svLogic startCom, svLogic getData, svLogic ejectReq,  svLogic queueReq, svLogic *endCom,
31
        svLogic *newReq, svBitVec32 source_all[NE], svBitVec32 destination_all[NE],
32
        svBitVec32 address_all[NE], svBitVec32 opcode_all[NE], svBitVec32 id_all[NE],
33
        svBitVec32 valid_all[NE], svBitVec32 rtrn_pkgid_all[NE],
34
        svBitVec32 rtrn_valid_all[NE], svBitVec32 NEready_all[NE],
35
        svBitVec32 size_all[NE] ,
36
        svBitVec32 enqueue_valid[NE]   ,
37
        svBitVec32 enqueue_src[NE]     ,
38
        svBitVec32 enqueue_dst[NE]     ,
39
        svBitVec32 enqueue_id[NE]      ,
40
        svBitVec32 enqueue_size[NE]
41
        )
42
{
43
 
44
    bool process_more = true;
45
    int msgDone = 0;
46
    *endCom = '0';
47
    *newReq = '0';
48
    int noreq=0;
49
    int node_dst;
50
    int node_src;
51
    int toDataPort=0;
52
    int toRspPort=0;
53
    int id_cnt=0;
54
 
55
    int rtrn_valid_all_[NE];
56
    int _enqueue_valid[NE] ;
57
 
58
    for(int i=0; i<NE; i++) {
59
        valid_all[i] = 0;
60
        rtrn_valid_all_[i] = rtrn_valid_all[i];
61
        _enqueue_valid[i] = enqueue_valid[i];
62
    }
63
 
64
 
65
    if (startCom == 1 && getData == 1)
66
    {
67
        //cout << "\n*** new clock *** " << endl
68
 
69
 
70
        while ( process_more )
71
        {
72
            // read message
73
            _connection_manager->readMsg();
74
 
75
 
76
            switch(_msg->type)
77
            {
78
                case STEP_REQ: //2
79
                    {
80
                        StepResMsg res;
81
                        *_channel << res;
82
 
83
                        if (queueReq == 1)
84
                        {
85
                            // enqueue packets from pronoc
86
                            for(int k=0; k<NE; k++)
87
                            {
88
                                if (_enqueue_valid[k] == 1){
89
                                    _req->size    = enqueue_size[k];
90
                                    _req->dest    = enqueue_dst[k];
91
                                    _req->source  = enqueue_src[k];
92
                                    _req->id      = enqueue_id[k];
93
 
94
                                    if (_inject_buffer.empty())
95
                                    {
96
                                        _inject_buffer.push(_req);
97
                                        //cout << "<enqueue> id: " << _req->id << endl;
98
                                    }
99
                                    else
100
                                    {
101
                                        int quesize = _inject_buffer.size();
102
                                        for(int i=0;i<quesize;i++)
103
                                        {
104
                                            _req_tmp = _inject_buffer.front();
105
                                            _inject_buffer.pop();
106
                                            if ( _req->id == _req_tmp->id ) id_cnt++;
107
                                            _inject_buffer.push(_req_tmp);
108
                                        }
109
                                        if(id_cnt == 0)
110
                                        {
111
                                            _inject_buffer.push(_req);
112
                                            //cout << "<enqueue> id: " << _req->id << endl;
113
                                        }
114
                                        id_cnt=0;
115
                                    }
116
                                    _enqueue_valid[k] = 0;
117
                                }
118
                            }
119
                        }
120
 
121
                        //dequeue packets to send to pronoc
122
                        if (!_inject_buffer.empty()) {
123
                            int quesize = _inject_buffer.size();
124
 
125
                            for(int i=0;i<quesize;i++){
126
                                _req = _inject_buffer.front();
127
                                _inject_buffer.pop();
128
 
129
                                if(NEready_all[_req->source] == 1 & valid_all[_req->source] == 0)
130
                                {
131
                                    address_all[_req->source]     = _req->address     ;
132
                                    size_all[_req->source]        = _req->packetSize  ;
133
                                    destination_all[_req->source] = _req->dest        ;
134
                                    source_all[_req->source]      = _req->source      ;
135
                                    opcode_all[_req->source]      = _req->coType      ;
136
                                    id_all[_req->source]          = _req->id          ;
137
                                    valid_all[_req->source]       = 1                 ;
138
                                    //cout << "<inject> id: " << _req->id << " src: " << _req->source << " dst: " << _req->dest << " size: " << _req->size << endl;
139
                                }
140
                                else
141
                                {
142
                                    _inject_buffer.push(_req);
143
                                    //cout << "<wait> id: " << _req->id << endl;
144
                                }
145
 
146
                            }
147
                        }
148
                        //cout << "<end cycle>" << endl;
149
 
150
                        // fall-through and increment your network one cycle
151
                        process_more = false;
152
 
153
                       break;
154
                    }
155
                case INJECT_REQ: //4
156
                    {
157
                        _req = (InjectReqMsg*) _msg;
158
                        _connection_manager->sendAckReqMsg();
159
                        noreq = 0;
160
 
161
                            //enqueue packets from synfull
162
                            _inject_buffer.push(_req);
163
 
164
                        //cout << "<inject> id:" << _req->id << " mt:" << _req->msgType << " ct:" << _req->coType 
165
                        //    << " src:" << _req->source << " dst:" << _req->dest << endl;
166
 
167
                        break;
168
                    }
169
                case EJECT_REQ:  //6
170
                    {
171
                        if(ejectReq == 1)
172
                        {
173
                            //cout << "\n*** EJECT_REQ *** " << endl;
174
                            for(int k=0; k<NE; k++)
175
                            {
176
                                if (rtrn_valid_all_[k] == 1){
177
                                    _res.id =  rtrn_pkgid_all[k];
178
                                    _eject_buffer.push(_res);
179
                                    rtrn_valid_all_[k] = 0;
180
                                }
181
                            }
182
                        }
183
                        else
184
                        {
185
                            _res.id = -1; //not pckage
186
                        }
187
 
188
                        if (!_eject_buffer.empty()) {
189
                                _res = _eject_buffer.front();
190
                                _eject_buffer.pop();
191
                                _res.remainingRequests = _eject_buffer.size();
192
                                _connection_manager->sendResMsg();
193
                                //cout << "<eject> id:" << _res.id << endl;
194
                        }
195
                        else
196
                        {
197
                            _connection_manager->sendResMsg();
198
                        }
199
 
200
                        break;
201
                    }
202
                case QUIT_REQ:
203
                    {
204
                        // acknowledge quit
205
                        QuitResMsg res;
206
                        *_channel << res;
207
 
208
                        *endCom = '1';
209
 
210
                        process_more = false;
211
 
212
                        break;
213
                    }
214
                default:
215
                    {
216
                        cout << "<ERROR:> Unknown message type: " << _msg->type << endl;
217
                        break;
218
                    }
219
 
220
            }
221
        }
222
 
223
        *newReq = msgDone     ;
224
 
225
 
226
        StreamMessage::destroy(_msg);
227
 
228
    }
229
 
230
}
231
 
232
//*****************************************************************
233
// Connection Manager
234
//*****************************************************************
235
connection_manager::connection_manager(){
236
    _channel = NULL;
237
    _sources = 4;
238
    _dests   = 4;
239
    _duplicate_networks = 1;
240
}
241
 
242
//--
243
int connection_manager::Init() {
244
    // Start listening for incoming connections
245
    if (_listenSocket.listen(NS_HOST, NS_PORT) < 0) {
246
        return -1;
247
    }
248
 
249
    // Waiting to connect
250
    _channel = _listenSocket.accept();
251
 
252
    cout << "Connected... " << endl;
253
 
254
    // Initialize client
255
    InitializeReqMsg req;
256
    InitializeResMsg res;
257
    *_channel >> req << res;
258
 
259
    return 0;
260
}
261
 
262
int connection_manager::readMsg()
263
{
264
    _msg = NULL;
265
 
266
    if (_channel)
267
    {
268
        *_channel >> (StreamMessage*&) _msg;
269
    }
270
    return 0;
271
}
272
 
273
int connection_manager::sendResMsg()
274
{
275
    *_channel << _res;
276
    return 0;
277
}
278
 
279
int connection_manager::sendAckMsg()
280
{
281
    *_channel << _ackRes;
282
    return 0;
283
}
284
 
285
int connection_manager::sendAckReqMsg()
286
{
287
    *_channel << _ackReq;
288
    return 0;
289
}
290
 
291
int connection_manager::checkInjection(){
292
    return _newInjection;
293
}
294
 
295
int connection_manager::getPronocEndPoint(int node){
296
    return (node-(node%2))/2 ;
297
}
298
 
299
int connection_manager::getSynfullEndPoint(int node){
300
    return (((node-(node%3))/3)*2)+!(node%3);
301
}
302
 
303
int connection_manager::getMsgType(int opcode)
304
{
305
    int type;
306
    switch (opcode)
307
    {
308
        case 1: // readshared - read 
309
            type = 1; // req
310
            break;
311
        case 4: // compdata - data 
312
            type = 0; // req
313
            break;
314
        default:
315
            type = 2;
316
            break;
317
    }
318
    return type;
319
}
320
 
321
int connection_manager::getChiOpc(int opcode, int type)
322
{
323
    int chiopc;
324
    switch (type)
325
    {
326
        case 1:
327
            switch (opcode)
328
            {
329
                case 1: // readshared - read 
330
                    chiopc = 1 ;
331
                    break;
332
                default:
333
                    chiopc = 999;
334
                    cout << "(req) coherency message not supported" << endl;
335
                    break;
336
            }
337
            break;
338
        case 2:
339
            switch (opcode)
340
            {
341
                case 2: // compdata - data 
342
                    chiopc = 4;
343
                    break;
344
                case 5: // compack - unblock 
345
                    chiopc = 2;
346
                    break;
347
                default:
348
                    chiopc = 999;
349
                    cout << "(resp) coherency message not supported" << endl;
350
                    break;
351
            }
352
            break;
353
        default:
354
            chiopc = 999;
355
            cout << "coherency message not supported" << endl;
356
            break;
357
    }
358
    return chiopc;
359
}
360
 
361
//-------Debug functions Neiel-Leyva
362
 
363
int connection_manager::printResMsg(EjectResMsg res) {
364
    cout << "Debug Neiel: res.id                = " << res.id << endl;
365
    cout << "Debug Neiel: res.remainingRequests = " << res.remainingRequests << endl;
366
    cout << "Debug Neiel: res.source            = " << res.source << endl;
367
    cout << "Debug Neiel: res.destination       = " << res.dest << endl;
368
    cout << "Debug Neiel: req.packetSize        = " << res.packetSize   << endl;
369
    cout << "Debug Neiel: res.network           = " << res.network << endl;
370
    cout << "Debug Neiel: res.cl                = " << res.cl << endl;
371
    cout << "Debug Neiel: res.miss_prediction   = " << res.miss_pred << endl;
372
    return 0;
373
};
374
 
375
int connection_manager::printReqMsg(InjectReqMsg *req) {
376
    cout << "  " << endl;
377
    cout << "Debug Neiel: req.source     = " << req->source       << endl;
378
    cout << "Debug Neiel: req.dest       = " << req->dest         << endl;
379
    cout << "Debug Neiel: req.id         = " << req->id           << endl;
380
    cout << "Debug Neiel: req.packetSize = " << req->packetSize   << endl;
381
    cout << "Debug Neiel: req.network    = " << req->network      << endl;
382
    cout << "Debug Neiel: req.cl         = " << req->cl           << endl;
383
    cout << "Debug Neiel: req.msgType    = " << req->msgType      << endl;
384
    cout << "Debug Neiel: req.coType     = " << req->coType       << endl;
385
    cout << "Debug Neiel: req.address    = " << req->address      << endl;
386
    return 0;
387
};
388
 
389
 
390
 
391
//*****************************************************************************
392
// SocketStream
393
//*****************************************************************************
394
 
395
int SocketStream::listen(const char *host, int port){
396
 
397
    char *socket_path = "./socket";
398
 
399
    // Create a socket
400
    if ( (so = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
401
        cout << "Error creating socket." << endl;
402
        return -1;
403
    }
404
 
405
    memset(&addr, 0, sizeof(addr));
406
    addr.sun_family = AF_UNIX;
407
    strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);
408
 
409
    // Bind it to the listening port
410
    unlink(socket_path);
411
    if (bind(so, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
412
         cout << "Error binding socket." << endl;
413
         return -1;
414
    }
415
 
416
    //// Listen for connections
417
    if (::listen(so, NS_MAX_PENDING) != 0) {
418
         cout << "Error listening on socket." << endl;
419
         return -1;
420
    }
421
 
422
    bIsAlive = true;
423
 
424
#ifdef NS_DEBUG
425
    cout << "Listening on socket" << endl;
426
#endif
427
 
428
    return 0;
429
}
430
 
431
// accept a new connection
432
SocketStream* SocketStream::accept()
433
{
434
    struct sockaddr_un clientaddr;
435
    socklen_t clientaddrlen = sizeof clientaddr;
436
    int clientsock = ::accept(so, (struct sockaddr*)&clientaddr, &clientaddrlen);
437
 
438
    if ( clientsock < 0 ){
439
        cout << "Error accepting a connection";
440
        return NULL;
441
    }
442
 
443
    return new SocketStream(clientsock, (struct sockaddr*)&clientaddr, clientaddrlen);
444
}
445
 
446
int SocketStream::connect(const char *host, int port)
447
{
448
    char *socket_path = "./socket";
449
    // Create a socket.
450
    if ( (so = socket(AF_UNIX, SOCK_STREAM, 0)) < 0 ){
451
        cout << "Error creating socket." << endl;
452
        return -1;
453
    }
454
    memset(&addr, 0, sizeof(addr));
455
    addr.sun_family = AF_UNIX;
456
    strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1);
457
 
458
    // Connect to the server.
459
    if ( ::connect(so, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
460
        cout << "Connection failed." << endl;
461
        return -1;
462
    }
463
 
464
    bIsAlive = true;
465
 
466
#ifdef NS_DEBUG
467
    cout << "Connected to host" << endl;
468
#endif
469
 
470
    return 0;
471
}
472
 
473
// read from the socket
474
int SocketStream::get(void *data, int number)
475
{
476
 
477
    int remaining = number;
478
    int received = 0;
479
    char *dataRemaining = (char*) data;
480
 
481
    errno = 0;
482
    while (remaining > 0 && (errno == 0 || errno == EINTR))
483
    {
484
        received = recv(so, dataRemaining, remaining, 0); // MSG_WAITALL
485
        if (received > 0)
486
        {
487
            dataRemaining += received;
488
            remaining -= received;
489
        }
490
    }
491
 
492
    return number - remaining;
493
}
494
 
495
// write to socket
496
int SocketStream::put(const void *data, int number)
497
{
498
    // MSG_NOSIGNAL prevents SIGPIPE signal from being generated on failed send
499
    return send(so, data, number, MSG_NOSIGNAL);
500
}
501
 
502
 
503
//*****************************************************************
504
//*****************************************************************
505
 
506
 
507
using namespace std;
508
 
509
SocketStream& operator<<(SocketStream& os, StreamMessage& msg)
510
{
511
#ifdef NS_DEBUG_EXTRA
512
    std::cout << "<MessageSend> Sending message: " << msg.type << ", size: " << msg.size << std::endl;
513
#endif
514
 
515
    // cork the connection
516
    int flag = 1;
517
    setsockopt (os.so, SOL_TCP, TCP_CORK, &flag, sizeof (flag));
518
 
519
    os.put(&(msg.size), sizeof(int));
520
    os.put(&msg, msg.size);
521
 
522
    // uncork the connection
523
    flag = 0;
524
    setsockopt (os.so, SOL_TCP, TCP_CORK, &flag, sizeof (flag));
525
 
526
    // os.flush();
527
 
528
    return os;
529
}
530
 
531
SocketStream& operator>>(SocketStream& is, StreamMessage*& msg)
532
{
533
#ifdef NS_DEBUG_EXTRA
534
    std::cout << "<MessageRecv> Waiting for message" << std::endl;
535
#endif
536
 
537
    int msgSize = -1;
538
    int gotBytes = is.get(&msgSize, sizeof(int));
539
 
540
    if (gotBytes != sizeof(int))
541
        return is;
542
 
543
    assert(msgSize > 0);
544
 
545
    msg = (StreamMessage*) malloc(msgSize);
546
    is.get(msg, msgSize);
547
 
548
 
549
#ifdef NS_DEBUG_EXTRA
550
    std::cout << "<MessageRecv> Got message: " << msg->type << std::endl;
551
#endif
552
 
553
    return is;
554
}
555
 
556
SocketStream& operator>>(SocketStream& is, StreamMessage& msg)
557
{
558
#ifdef NS_DEBUG_EXTRA
559
    std::cout << "<MessageRecvSync> Waiting for message" << std::endl;
560
#endif
561
 
562
    int msgSize = -1;
563
    int gotBytes = is.get(&msgSize, sizeof(int));
564
 
565
    if (gotBytes != sizeof(int))
566
        return is;
567
 
568
    assert(msgSize == msg.size);
569
    is.get(&msg, msgSize);
570
 
571
#ifdef NS_DEBUG_EXTRA
572
    std::cout << "<MessageRecvSync> Got message: " << msg.type << std::endl;
573
#endif
574
 
575
    return is;
576
}
577
 
578
void StreamMessage::destroy(StreamMessage* msg)
579
{
580
    assert (msg != NULL);
581
    free(msg);
582
}
583
 

powered by: WebSVN 2.1.0

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