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

Subversion Repositories ht_tunnel

[/] [ht_tunnel/] [trunk/] [bench/] [vc_ht_tunnel_l1_tb/] [PhysicalLayer.cpp] - Blame information for rev 19

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 acastong
//PhysicalLayer.cpp
2
 
3
/* ***** BEGIN LICENSE BLOCK *****
4
 * Version: MPL 1.1
5
 *
6
 * The contents of this file are subject to the Mozilla Public License Version
7
 * 1.1 (the "License"); you may not use this file except in compliance with
8
 * the License. You may obtain a copy of the License at
9
 * http://www.mozilla.org/MPL/
10
 *
11
 * Software distributed under the License is distributed on an "AS IS" basis,
12
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
 * for the specific language governing rights and limitations under the
14
 * License.
15
 *
16
 * The Original Code is HyperTransport Tunnel IP Core.
17
 *
18
 * The Initial Developer of the Original Code is
19
 * Ecole Polytechnique de Montreal.
20
 * Portions created by the Initial Developer are Copyright (C) 2005
21
 * the Initial Developer. All Rights Reserved.
22
 *
23
 * Contributor(s):
24
 *   Ami Castonguay <acastong@grm.polymtl.ca>
25
 *
26
 * Alternatively, the contents of this file may be used under the terms
27
 * of the Polytechnique HyperTransport Tunnel IP Core Source Code License
28
 * (the  "PHTICSCL License", see the file PHTICSCL.txt), in which case the
29
 * provisions of PHTICSCL License are applicable instead of those
30
 * above. If you wish to allow use of your version of this file only
31
 * under the terms of the PHTICSCL License and not to allow others to use
32
 * your version of this file under the MPL, indicate your decision by
33
 * deleting the provisions above and replace them with the notice and
34
 * other provisions required by the PHTICSCL License. If you do not delete
35
 * the provisions above, a recipient may use your version of this file
36
 * under either the MPL or the PHTICSCL License."
37
 *
38
 * ***** END LICENSE BLOCK ***** */
39
 
40
#include "PhysicalLayer.h"
41
 
42
#include <iostream>
43
 
44
const int PhysicalLayer::PHYSICAL_LAYER_CRC_POLY = 0x04C11DB7;
45
 
46
PhysicalLayer::PhysicalLayer(sc_module_name name) : sc_module(name){
47
        SC_THREAD(receiveThread);
48
        sensitive_pos(clk);
49
 
50
        SC_THREAD(transmitThread);
51
        sensitive_pos(clk);
52
 
53
        inter = NULL;
54
        tx_connected = false;
55
        rx_connected = false;
56
        retryDisconnectCountTX = 0;
57
        retryDisconnectCountRX = 0;
58
        ldtstop_sequence = false;
59
        ldtstop_sequence_complete = false;
60
 
61
        //Get a vector of all zeros and ones;
62
        v0 = 0;
63
        v1 = ~v0;
64
}
65
 
66
void PhysicalLayer::ldtstopDisconnect(){
67
        ldtstop_sequence = true;
68
        ldtstop_sequence_complete = false;
69
        ltdstop_last_crc_window = false;
70
}
71
 
72
void PhysicalLayer::ldtstopConnect(){
73
        ldtstop_sequence = false;
74
        ldtstop_sequence_complete = false;
75
}
76
 
77
void PhysicalLayer::retryDisconnectAndReconnect(){
78
        retryDisconnectCountTX = 60;
79
        retryDisconnectCountRX = 40;
80
}
81
 
82
void PhysicalLayer::receiveThread(){
83
        phy_consume_lk = true;
84
        while(inter){
85
                //Do nothing while disconnected
86
                while(!resetx.read() || ltdstop_rx_received_disconnect || retryDisconnectCountRX){
87
                        if(retryDisconnectCountRX) retryDisconnectCountRX--;
88
                        rx_connected = false;
89
                        wait();
90
                        if(!ldtstop_sequence) ltdstop_rx_received_disconnect = false;
91
                }
92
                if(!rx_connected) rx_connect();
93
                receiveDwordOrCrc();
94
        }
95
        cout << "ERROR: No interface connected to the PhysicalLayer" << endl;
96
}
97
 
98
void PhysicalLayer::transmitThread(){
99
        phy_available_lk = true;
100
        while(inter){
101
                if(!resetx.read() || ldtstop_sequence && ldtstop_sequence_complete || retryDisconnectCountTX)
102
                        holdResetSignaling();
103
                if(!tx_connected) tx_connect();
104
                sendNextDwordOrCrc();
105
        }
106
}
107
 
108
void PhysicalLayer::holdResetSignaling(){
109
        tx_connected = false;
110
        phy_ctl_lk = v0;
111
        for(int n = 0; n < CAD_OUT_WIDTH;n++) phy_cad_lk[n] = v1;
112
        //while reset, LDTSTOP sequence of RETRY disconnect, keep sending reset signaling
113
        while(!resetx.read() || ldtstop_sequence && ldtstop_sequence_complete  || retryDisconnectCountTX){
114
                if(retryDisconnectCountTX){
115
                        retryDisconnectCountTX--;
116
                }
117
                if(!resetx.read()) ldtstop_sequence = false;
118
                wait();
119
        }
120
}
121
 
122
 
123
void PhysicalLayer::tx_connect(){
124
        cout << "Starting TX Connect" << endl;
125
        //Connect sequence phase 1
126
        phy_ctl_lk = v1;
127
 
128
        for(int n = 0; n < CAD_OUT_WIDTH;n++) phy_cad_lk[n] = v1;
129
 
130
        //Wait for RX CTL to be asserted
131
        while(!(bool)(sc_bit)lk_ctl_phy.read()[0]) wait();
132
 
133
        //Wait a minimum time
134
        for(int n = 0; n < 4; n++) wait();
135
 
136
 
137
        //Connect sequence phase 2
138
        phy_ctl_lk = v0;
139
        for(int n = 0; n < CAD_OUT_WIDTH;n++) phy_cad_lk[n] = v0;
140
        for(int n = 0; n < 128; n++) wait();
141
 
142
 
143
 
144
        //Connect sequence phase 3
145
        for(int n = 0; n < CAD_OUT_WIDTH;n++) phy_cad_lk[n] = v1;
146
        wait();
147
        cout << "Done TX Connect" << endl;
148
 
149
        tx_firstCrcWindow = true;
150
        current_tx_crc = 0xFFFFFFFF;
151
        tx_crc_count = 0;
152
        tx_connected = true;
153
}
154
 
155
void PhysicalLayer::calculateCrc(int &crc,int dword,bool lctl,bool hctl){
156
        //Break loop in 4 because data is bigger than 32 bits
157
        for(int n=0; n < 4;n++){
158
                int ctl_or = 0;
159
                if(((n == 0 || n == 1) && lctl) || (n == 2 || n == 3) && hctl){
160
                        ctl_or = 0x100;
161
                }
162
 
163
                int data =( (dword >> (n * 8)) & 0xFF) | ctl_or;
164
 
165
                //Code taken from HT spec
166
                for(int i = 0; i < 9; i++){
167
                        int tmp = crc >> 31;//store highest bit
168
                        crc = (crc << 1) | ((data >> i) & 1);//shift message in
169
                        crc = (tmp) ? crc ^ PHYSICAL_LAYER_CRC_POLY : crc;//substract poly if greater
170
                }
171
        }
172
}
173
 
174
void PhysicalLayer::sendNextDwordOrCrc(){
175
        //Get next dword to send through interface
176
        sc_bv<32> dword;
177
        bool lctl;
178
        bool hctl;
179
        if(!ldtstop_sequence)
180
                inter->dwordToSendRequested(dword,lctl,hctl);
181
        else{
182
                dword = 64; lctl = true; hctl = true;
183
        }
184
 
185
        //Calculate the CRC for it
186
        calculateCrc(current_tx_crc,dword.to_int(),lctl,hctl);
187
 
188
        //Send it
189
        sendDword(dword,lctl,hctl);
190
 
191
        //Now send crc if at the right position in the window
192
        tx_crc_count++;
193
        if(!tx_firstCrcWindow && tx_crc_count == 16){
194
                sc_bv<32> dword_to_sent = ~current_tx_crc;
195
                sendDword(dword_to_sent,true,true);
196
                if(ltdstop_last_crc_window) ldtstop_sequence_complete = true;
197
        }
198
 
199
        if(tx_crc_count == 128){
200
                if(ldtstop_sequence) ltdstop_last_crc_window = true;
201
                tx_firstCrcWindow = false;
202
                tx_crc_count = 0;
203
                last_tx_crc = current_tx_crc;
204
                current_tx_crc = 0xFFFFFFFF;
205
        }
206
}
207
 
208
void PhysicalLayer::sendDword(sc_bv<32> &dword,bool lctl,bool hctl){
209
        sc_bv<CAD_IN_DEPTH> v;
210
 
211
        //Send the ctl bits
212
        for(int n = 0; n < CAD_IN_DEPTH/2;n++) v[n] = lctl;
213
        for(int n = CAD_IN_DEPTH/2; n < CAD_IN_DEPTH;n++) v[n] = hctl;
214
        phy_ctl_lk = v;
215
 
216
        //Send the cad bits
217
        for(int y = 0; y < CAD_IN_WIDTH;y++){
218
                for(int x = 0; x < CAD_IN_DEPTH;x++){
219
                        v[x] = dword[x * CAD_IN_WIDTH + y];
220
                }
221
                phy_cad_lk[y] = v;
222
        }
223
        //Send the dword
224
        wait();
225
}
226
 
227
void PhysicalLayer::rx_connect(){
228
        cout << "Begin RX connect" << endl;
229
 
230
        //Phase 1 - reset signaling
231
        while(lk_ctl_phy.read()[0] == false)wait();
232
 
233
        //Phase 2 - CTL activated
234
        while(lk_ctl_phy.read()[0] == true)wait();
235
 
236
        //Phase 3 - Wait for CAD to activate
237
        while(lk_cad_phy[0].read()[0] == false)wait();
238
 
239
        cout << "Done RX connect" << endl;
240
 
241
        //Wait for the next valid data
242
        wait();
243
        rx_crc_count = 0;
244
        current_rx_crc = 0xFFFFFFFF;
245
        rx_firstCrcWindow = true;
246
        rx_connected = true;
247
}
248
 
249
void PhysicalLayer::receiveDwordOrCrc(){
250
        sc_bv<32> dword;
251
        bool lctl;
252
        bool hctl;
253
 
254
        //Receive Dword
255
        receiveDword(dword,lctl,hctl);
256
        calculateCrc(current_rx_crc,dword.to_int(),lctl,hctl);
257
        rx_crc_count++;
258
 
259
        if(dword == 0x40 && lctl && hctl && ldtstop_sequence){
260
                ltdstop_rx_received_disconnect = true;
261
                return;
262
        }
263
 
264
        //cout << "Sending received dword: " << dword << endl;
265
        inter->receivedDwordEvent(dword,lctl,hctl);
266
 
267
        //Check CRC at the right moment in the windows
268
        if(!rx_firstCrcWindow && rx_crc_count == 16){
269
                receiveDword(dword,lctl,hctl);
270
                if(~last_rx_crc != dword.to_int()){
271
                        //cout << "CRC received: " << dword.to_string(SC_HEX) << endl;
272
                        //cout << "CRC expected: " << sc_uint<32>(last_rx_crc).to_string() << endl;
273
                        inter->crcErrorDetected();
274
                }
275
        }
276
 
277
        //Reset window after 128 dwords
278
        if(rx_crc_count == 128){
279
                last_rx_crc = current_rx_crc;
280
                current_rx_crc = 0xFFFFFFFF;
281
                rx_crc_count = 0;
282
                rx_firstCrcWindow = false;
283
        }
284
}
285
 
286
void PhysicalLayer::receiveDword(sc_bv<32> &dword,bool &lctl,bool &hctl){
287
        sc_bv<CAD_OUT_DEPTH> v;
288
 
289
        //Receive the CTLS
290
        lctl = (sc_bit)lk_ctl_phy.read()[0];
291
        hctl = (sc_bit)lk_ctl_phy.read()[CAD_OUT_DEPTH/2];
292
 
293
        //Receive cad bits
294
        for(int y = 0; y < CAD_OUT_WIDTH;y++){
295
                v = lk_cad_phy[y].read();
296
                for(int x = 0; x < CAD_OUT_DEPTH;x++){
297
                        dword[x * CAD_OUT_WIDTH + y] = v[x];
298
                }
299
        }
300
 
301
        //Allow to receive next dword
302
        wait();
303
}
304
 

powered by: WebSVN 2.1.0

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