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 12

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 6 antanguay
                    pkt_tx_eop = 1;
101
                    pkt_tx_mod = pkt->length % 8;
102 2 antanguay
                }
103
                else {
104
                    pkt_tx_eop = 0;
105
                }
106
 
107
                wait();
108
            }
109
 
110
            pkt_tx_val = 0;
111
 
112
 
113
            //---
114
            // Pass packet to scoreboard
115
 
116
            sb->notify_packet_tx(sb_id, pkt);
117
 
118
            //---
119
            // Enforce minimum spacing between SOP's
120
 
121
            for (int i = (pkt->length+7)/8; i < 8; i++) {
122
                wait();
123
            }
124
        }
125
    }
126
};
127
 
128
 
129
void pkt_if::receive() {
130
 
131
    packet_t* pkt;
132
 
133
    sc_uint<64> data;
134
 
135
    wait();
136
 
137
    while (true) {
138
 
139
        if (pkt_rx_avail && !disable_rx) {
140
 
141
            pkt = new(packet_t);
142
            pkt->length = 0;
143
 
144
            // If reading already selected just keep going,
145
            // if not we must enable ren
146
            if (!pkt_rx_ren) {
147
                pkt_rx_ren = 1;
148
                wait();
149
            };
150
 
151
            while (true) {
152
 
153
                wait();
154
 
155
                if (!pkt_rx_val) {
156
                    continue;
157
                }
158
 
159
                // Check SOP
160
 
161
                if (pkt->length != 0 && pkt_rx_sop) {
162
                    if (allow_rx_sop_err) {
163
                        cout << "INFO: SOP errors allowed" << endl;
164
                        pkt->length = 0;
165
                        pkt->err_flags = 0;
166
                    }
167
                    else {
168
                        pkt->err_flags |= PKT_FLAG_ERR_SOP;
169
                    }
170
                }
171
 
172
                // Check error line
173
 
174
                if (pkt_rx_err) {
175
                    pkt->err_flags |= PKT_FLAG_ERR_SIG;
176
                }
177
 
178
                // Capture data
179
 
180
                data = pkt_rx_data;
181
 
182
                for (int lane = 0; lane < 8; lane++) {
183
 
184
                    pkt->data[pkt->length++] = (data >> (8 * lane)) & 0xff;
185
 
186
                    if (pkt->length >= 10000) {
187
                        cout << "ERROR: Packet too long" << endl;
188
                        sc_stop();
189
                    }
190
 
191 6 antanguay
                    if (pkt_rx_eop && (pkt_rx_mod == ((lane+1) % 8))) {
192 2 antanguay
                        break;
193
                    }
194
                }
195
 
196
                // Stop on EOP
197 6 antanguay
 
198 2 antanguay
                if (pkt_rx_eop) {
199
                    break;
200
                }
201
            }
202
 
203
            //---
204
            // Store packet
205
 
206
            unpack(pkt);
207
            //rx_fifo.write(pkt);
208
 
209
            //cout << "Receive PKT_IF packet:\n" << * pkt << endl;
210
 
211
            //---
212
            // Pass packet to scoreboard
213
 
214
            sb->notify_packet_rx(sb_id, pkt);
215
 
216
        }
217
        else {
218
            pkt_rx_ren = 0;
219
            wait();
220
        }
221
    }
222
};

powered by: WebSVN 2.1.0

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