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

Subversion Repositories xge_mac

[/] [xge_mac/] [trunk/] [tbench/] [systemc/] [sc_pkt_if.cpp] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 antanguay
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  File name "sc_pkt_if.cpp"                                   ////
4
////                                                              ////
5
////  This file is part of the "10GE MAC" project                 ////
6
////  http://www.opencores.org/cores/xge_mac/                     ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - A. Tanguay (antanguay@opencores.org)                  ////
10
////                                                              ////
11
//////////////////////////////////////////////////////////////////////
12
////                                                              ////
13
//// Copyright (C) 2008 AUTHORS. All rights reserved.             ////
14
////                                                              ////
15
//// This source file may be used and distributed without         ////
16
//// restriction provided that this copyright statement is not    ////
17
//// removed from the file and that any derivative work contains  ////
18
//// the original copyright notice and the associated disclaimer. ////
19
////                                                              ////
20
//// This source file is free software; you can redistribute it   ////
21
//// and/or modify it under the terms of the GNU Lesser General   ////
22
//// Public License as published by the Free Software Foundation; ////
23
//// either version 2.1 of the License, or (at your option) any   ////
24
//// later version.                                               ////
25
////                                                              ////
26
//// This source is distributed in the hope that it will be       ////
27
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
28
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
29
//// PURPOSE.  See the GNU Lesser General Public License for more ////
30
//// details.                                                     ////
31
////                                                              ////
32
//// You should have received a copy of the GNU Lesser General    ////
33
//// Public License along with this source; if not, download it   ////
34
//// from http://www.opencores.org/lgpl.shtml                     ////
35
////                                                              ////
36
//////////////////////////////////////////////////////////////////////
37
 
38
#include <stdio.h>
39
#include <iostream>
40
#include <sys/times.h>
41
#include <sys/stat.h>
42
 
43
#include "systemc.h"
44
 
45
#include "sc_pkt_if.h"
46
 
47
sc_fifo<packet_t*> * pkt_if::get_tx_fifo_ptr() {
48
    return &tx_fifo;
49
}
50
 
51
sc_fifo<packet_t*> * pkt_if::get_rx_fifo_ptr() {
52
    return &rx_fifo;
53
}
54
 
55
void pkt_if::init(void) {
56
    disable_rx = false;
57
    allow_rx_sop_err = false;
58
}
59
 
60
void pkt_if::connect_scoreboard(scoreboard *sbptr, scoreboard::sbSourceId sid) {
61
    sb = sbptr;
62
    sb_id = sid;
63
}
64
 
65
void pkt_if::transmit() {
66
 
67
    packet_t* pkt;
68
 
69
    while (true) {
70
 
71
        wait();
72
 
73
        if (tx_fifo.nb_read(pkt)) {
74
 
75
            pack(pkt);
76
 
77
            //cout << "Transmit PKT_IF packet:\n" << * pkt << endl;
78
 
79
            pkt_tx_val = 1;
80
 
81
            for (int i = 0; i < pkt->length; i += 8) {
82
 
83
                pkt_tx_data = pkt->data[i+7] << 56 |
84
                    pkt->data[i+6] << 48 |
85
                    pkt->data[i+5] << 40 |
86
                    pkt->data[i+4] << 32 |
87
                    pkt->data[i+3] << 24 |
88
                    pkt->data[i+2] << 16 |
89
                    pkt->data[i+1] << 8 |
90
                    pkt->data[i];
91
 
92
                if (i == 0) {
93
                    pkt_tx_sop = 1;
94
                }
95
                else {
96
                    pkt_tx_sop = 0;
97
                }
98
 
99
                if (i + 8 >= pkt->length) {
100
                    pkt_tx_eop = 0x1 << ((pkt->length - 1) % 8);
101
                }
102
                else {
103
                    pkt_tx_eop = 0;
104
                }
105
 
106
                wait();
107
            }
108
 
109
            pkt_tx_val = 0;
110
 
111
 
112
            //---
113
            // Pass packet to scoreboard
114
 
115
            sb->notify_packet_tx(sb_id, pkt);
116
 
117
            //---
118
            // Enforce minimum spacing between SOP's
119
 
120
            for (int i = (pkt->length+7)/8; i < 8; i++) {
121
                wait();
122
            }
123
        }
124
    }
125
};
126
 
127
 
128
void pkt_if::receive() {
129
 
130
    packet_t* pkt;
131
 
132
    sc_uint<64> data;
133
 
134
    wait();
135
 
136
    while (true) {
137
 
138
        if (pkt_rx_avail && !disable_rx) {
139
 
140
            pkt = new(packet_t);
141
            pkt->length = 0;
142
 
143
            // If reading already selected just keep going,
144
            // if not we must enable ren
145
            if (!pkt_rx_ren) {
146
                pkt_rx_ren = 1;
147
                wait();
148
            };
149
 
150
            while (true) {
151
 
152
                wait();
153
 
154
                if (!pkt_rx_val) {
155
                    continue;
156
                }
157
 
158
                // Check SOP
159
 
160
                if (pkt->length != 0 && pkt_rx_sop) {
161
                    if (allow_rx_sop_err) {
162
                        cout << "INFO: SOP errors allowed" << endl;
163
                        pkt->length = 0;
164
                        pkt->err_flags = 0;
165
                    }
166
                    else {
167
                        pkt->err_flags |= PKT_FLAG_ERR_SOP;
168
                    }
169
                }
170
 
171
                // Check error line
172
 
173
                if (pkt_rx_err) {
174
                    pkt->err_flags |= PKT_FLAG_ERR_SIG;
175
                }
176
 
177
                // Capture data
178
 
179
                data = pkt_rx_data;
180
 
181
                for (int lane = 0; lane < 8; lane++) {
182
 
183
                    pkt->data[pkt->length++] = (data >> (8 * lane)) & 0xff;
184
 
185
                    if (pkt->length >= 10000) {
186
                        cout << "ERROR: Packet too long" << endl;
187
                        sc_stop();
188
                    }
189
 
190
                    if ((pkt_rx_eop >> lane) & 0x1 == 1) {
191
                        break;
192
                    }
193
                }
194
 
195
                // Stop on EOP
196
 
197
                if (pkt_rx_eop) {
198
                    break;
199
                }
200
            }
201
 
202
            //---
203
            // Store packet
204
 
205
            unpack(pkt);
206
            //rx_fifo.write(pkt);
207
 
208
            //cout << "Receive PKT_IF packet:\n" << * pkt << endl;
209
 
210
            //---
211
            // Pass packet to scoreboard
212
 
213
            sb->notify_packet_rx(sb_id, pkt);
214
 
215
        }
216
        else {
217
            pkt_rx_ren = 0;
218
            wait();
219
        }
220
    }
221
};

powered by: WebSVN 2.1.0

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