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

Subversion Repositories ht_tunnel

[/] [ht_tunnel/] [tags/] [START/] [rtl/] [systemc/] [core_synth/] [synth_control_packet.cpp] - Blame information for rev 19

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 acastong
//synth_control_packet.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
#ifndef SYNTH_CONTROL_PACKET_CPP
41
#define SYNTH_CONTROL_PACKET_CPP
42
 
43
#include "synth_datatypes.h"
44
 
45
/**
46
        To parse a cmd vector
47
*/
48
PacketCommand getPacketCommand(const sc_bv<6> &cmd){
49
 
50
        //Check the command vector against all known
51
        //sequences
52
        sc_uint<6> command_value = cmd;
53
 
54
        PacketCommand return_val;
55
 
56
        switch(command_value){
57
        case 0:
58
                return_val = NOP;
59
                break;
60
        case 0x3F: //0b111111
61
                return_val = SYNC;
62
                break;
63
        case 0x30: //0b110000
64
                return_val = RD_RESPONSE;
65
                break;
66
        case 0x33: //0b110011
67
                return_val = TGTDONE;
68
                break;
69
        case 0x3A: //0b111010
70
                return_val = BROADCAST;
71
                break;
72
        case 0x3C: //0b111100
73
                return_val = FENCE;
74
                break;
75
        case 0x3D: //0b111101
76
                return_val = ATOMIC;
77
                break;
78
        case 0x37: //0b110111
79
                return_val = EXTENDED_FLOW;
80
                break;
81
        case 0x3E: //0b111110
82
                return_val = ADDR_EXT;
83
                break;
84
        case 0x02: //0b000010
85
                return_val = FLUSH;
86
                break;
87
        default:
88
                if(command_value.range(4 , 3) == 1){//          if(command_value.range(4 , 3) == "01"){
89
                        return_val = WRITE;
90
                }
91
                else if(command_value.range(5 , 4) == 1){//else if(command_value.range(5 , 4) == "01"){
92
                        return_val = READ;
93
                }
94
                else{
95
                        return_val = RESERVED_CMD;
96
                }
97
 
98
        }
99
        return return_val;
100
}
101
 
102
/**
103
        To know the type of packet from a command vector
104
*/
105
PacketType getPacketType(const sc_bv<6> &cmd){
106
 
107
        PacketType return_val;
108
 
109
        sc_bv<6> cmd_buf = cmd;//Workaround for a synthesis problem
110
 
111
        //Check the command vector against all known
112
        //sequences
113
        if(cmd_buf == "000000" || cmd_buf == "111111" || cmd_buf == "110111"){
114
                return_val = INFO;
115
        }
116
        else if(cmd_buf == "110000" || cmd_buf == "110011"){
117
                return_val = RESPONSE;
118
        }
119
        else if(cmd_buf.range(5 , 3) == "001" || cmd_buf.range(5 , 3) == "101"
120
                || cmd_buf.range(5 , 4) == "01" || cmd_buf == "111010"
121
                || cmd_buf == "111100" || cmd_buf == "111101" || cmd_buf == "000010")
122
        {
123
                return_val = REQUEST;
124
        }
125
        else if(cmd_buf == "111101"){
126
                return_val = ADDR_EXT_TYPE;
127
        }
128
        else{
129
                return_val = RESERVED_TYPE;
130
        }
131
        return return_val;
132
}
133
 
134
bool isDwordPacket(const sc_bv<64> &pkt, const PacketCommand &cmd){
135
        bool return_val;
136
 
137
        switch(cmd){
138
        case WRITE:
139
        case READ:
140
        case BROADCAST:
141
        case ATOMIC:
142
        case RESERVED_CMD:
143
                return_val = false;
144
                break;
145
        case EXTENDED_FLOW:
146
                return_val = !(bool)((sc_bit)pkt[6]);
147
                break;
148
        //case ADDR_EXT:
149
        //case FLUSH:
150
        //case NOP:
151
        //case SYNC:
152
        //case RD_RESPONSE:
153
        //case TGTDONE:
154
        //case FENCE:
155
        default:
156
                return_val = true;
157
 
158
        }
159
        return return_val;
160
 
161
}
162
 
163
VirtualChannel getVirtualChannel(const sc_bv<64> &pkt, const PacketCommand &cmd){
164
 
165
        VirtualChannel return_val;
166
 
167
        switch(cmd){
168
        case WRITE:
169
                if(pkt[5] == true){
170
                        return_val = VC_POSTED;
171
                }
172
                else{
173
                        return_val = VC_NON_POSTED;
174
                }
175
                break;
176
        case ATOMIC:
177
        case FLUSH:
178
        case READ:
179
                return_val = VC_NON_POSTED;
180
                break;
181
        case FENCE:
182
        case BROADCAST:
183
                return_val = VC_POSTED;
184
                break;
185
 
186
        case RD_RESPONSE:
187
        case TGTDONE:
188
                return_val = VC_RESPONSE;
189
                break;
190
 
191
        //case SYNC:
192
        //case RESERVED_CMD:
193
        //case ADDR_EXT:
194
        //case NOP:
195
        //case EXTENDED_FLOW:
196
        default:
197
                return_val = VC_NONE;
198
 
199
        }
200
        return return_val;
201
}
202
 
203
bool isChain(const sc_bv<64> &pkt){
204
        bool return_val;
205
        //if(posted && write && bit chain)
206
        if(pkt.range(5 , 3) == "101" &&
207
           pkt[19] == true) return_val = true;
208
        else return_val = false;
209
        return return_val;
210
}
211
 
212
///Packet has data associated
213
/**
214
                To know if there is a data packet associated with this control
215
                packet
216
 
217
                @return If the packet has data associated
218
*/
219
bool hasDataAssociated(const PacketCommand &cmd){
220
        bool return_val;
221
 
222
        switch(cmd){
223
        case WRITE:
224
        case RD_RESPONSE:
225
        case ATOMIC:
226
                return_val = true;
227
                break;
228
 
229
        //case TGTDONE:
230
        //case SYNC:
231
        //case RESERVED_CMD:
232
        //case ADDR_EXT:
233
        //case NOP:
234
        //case EXTENDED_FLOW:
235
        //case FLUSH:
236
        //case BROADCAST:
237
        //case FENCE:
238
        //case READ:
239
        default:
240
                return_val = false;
241
                break;
242
 
243
        }
244
 
245
        return return_val;
246
 
247
}
248
 
249
///Get the length-1 of the data associated
250
/**
251
                Gets the number of doublewords of data associated with this ctl packet
252
                minus 1.  So a returned number of 0 represents 1 doubleWord.
253
                If there is no data associated, the result is undefined.
254
                The number returned also includes the doubleword mask in a byte write
255
 
256
                @return Length-1 of data associated with the packet, or undefined
257
                if the packet has no data associated
258
*/
259
sc_uint<4> getDataLengthm1(const sc_bv<64> &pkt){
260
        sc_uint<4> return_val;
261
 
262
        //If a byte read (cmd starts by 01 for read, and pkt[2]=0 for byte
263
        if(pkt[5] == false && pkt[4] == true && pkt[2] == false){
264
                //DataLength is Doubleword
265
                return_val = 0;
266
        }
267
        else{
268
                sc_bv<4> temp = pkt.range(25,22);
269
                return_val = temp;
270
        }
271
        return return_val;
272
}
273
 
274
bool getPassPW(const sc_bv<64> &pkt){
275
        return (sc_bit)(pkt[15]);
276
}
277
 
278
bool getResponsePassPW(const sc_bv<32> &pkt){
279
        return (sc_bit)(pkt[15]);
280
}
281
 
282
sc_uint<40> getRequestAddr(const sc_bv<64> &request_pkt, const PacketCommand &cmd){
283
        sc_uint<40> addr = 0;
284
 
285
        //If the packet only has 32 bits, dont return an address
286
        //of only zeros, its the job of the caller to check before calling
287
        //
288
        //if(!isDwordPacket(request_pkt,cmd)) {
289
 
290
                //Copy the standard range of addresses
291
                addr.range(39,3) = sc_bv<37>(request_pkt.range(63,27));
292
 
293
                //Copy the last bit of the address.  An exception is made for
294
                //the ATOMIC packet, that has this bit always at 0
295
                if(cmd != ATOMIC) addr[2] = sc_bit(request_pkt[26]);
296
        //}
297
 
298
        //Return the address
299
        return addr;
300
}
301
 
302
 
303
sc_uint<5> getUnitID(const sc_bv<64> &pkt){
304
        return sc_bv<5>(pkt.range(12,8));
305
}
306
 
307
bool request_getCompatOrIsoc(const sc_bv<64> &pkt){
308
        return sc_bit(pkt[21]);
309
}
310
 
311
 
312
 
313
bool isInAddressRange(const sc_bv<64> &pkt,  const PacketCommand &cmd, const sc_uint<32> &low,
314
                                                                                 const sc_uint<32> &high) {
315
        bool isInAddressRange_val = false;
316
        if(!isDwordPacket(pkt,cmd)){
317
                sc_uint<32> addr = getRequestAddr(pkt,cmd).range(39,8);
318
                isInAddressRange_val = (addr >= low && addr < high);
319
        }
320
        return isInAddressRange_val;
321
}
322
 
323
#ifdef SYSTEMC_SIM
324
 
325
bool isInAddressRange(const sc_bv<64> &pkt,  const PacketCommand &cmd, const sc_uint<40> &low,
326
                                                                                 const sc_uint<40> &high) {
327
        bool isInAddressRange_val = false;
328
        if(!isDwordPacket(pkt,cmd)){
329
                sc_uint<40> addr = getRequestAddr(pkt,cmd);
330
                isInAddressRange_val = (addr >= low && addr < high);
331
        }
332
        return isInAddressRange_val;
333
}
334
 
335
                                                                                 bool isInAddressRange(const sc_bv<64> &pkt,  const PacketCommand &cmd, const sc_bv<40> &low, const sc_bv<40> &high) {
336
        //Start by converting the strings to uint
337
        sc_uint<40> low_uint(low);
338
        sc_uint<40> high_uint(high);
339
 
340
        //Call the function taking uints
341
        return isInAddressRange(pkt,cmd,low_uint,high_uint);
342
}
343
#endif
344
 
345
sc_bv<4> request_getSeqID(const sc_bv<64> &pkt){
346
        sc_bv<4> temp;
347
        temp.range(3,2) = pkt.range(7,6);
348
        temp.range(1,0) = pkt.range(14,13);
349
        return temp;
350
}
351
 
352
bool write_getDataError(const sc_bv<64> &pkt) {
353
        bool dataError;
354
        if(pkt[5] == true) dataError = sc_bit(pkt[20]);
355
        else dataError = false;
356
        return dataError;
357
}
358
 
359
ResponseError response_getResponseError(const sc_bv<64> &pkt) {
360
        ResponseError error;
361
        if(pkt[20] == false){
362
                if(pkt[28] == false) error = RE_NORMAL;
363
                error = RE_DATA_ERROR;
364
        }
365
        else{
366
                if(pkt[28] == false) error = RE_TARGET_ABORT;
367
                error = RE_MASTER_ABORT;
368
        }
369
        return error;
370
}
371
 
372
sc_bv<5> request_getSrcTag(const sc_bv<64> &pkt) {
373
        return pkt.range(20,16);
374
}
375
 
376
sc_bv<32> generateReadResponse(const sc_bv<5> &unitID,
377
                                                 const sc_bv<5> &srcTag,
378
                                                 const sc_bv<2> &rqUID,
379
                                                 const sc_bv<4> &count,
380
                                                 bool bridge,
381
                                                 ResponseError error,
382
                                                 bool passPW,
383
                                                 bool isoc)
384
{
385
        sc_bv<32> packet = 0;
386
        packet.range(25,22) = count;
387
 
388
        sc_bv<6> packet_command = "110000";
389
        packet.range(5,0) = packet_command;
390
        packet.range(12,8) = unitID;
391
        packet.range(20,16) = srcTag;
392
        packet.range(31,30) = rqUID;
393
 
394
        //Error 0 => bv[20]
395
        //Error 1 => bv[28]
396
 
397
        if(error == RE_NORMAL || error == RE_DATA_ERROR)
398
                packet[20] = false;
399
        else
400
                packet[20] = true;
401
 
402
        if(error == RE_NORMAL || error == RE_TARGET_ABORT)
403
                packet[28] = false;
404
        else
405
                packet[28] = true;
406
 
407
        packet[14] = bridge;
408
        packet[15] = passPW;
409
        packet[7] = isoc;
410
 
411
        return packet;
412
}
413
 
414
sc_bv<32> generateTargetDone(const sc_bv<5> &unitID,
415
                                                 const sc_bv<5> &srcTag,
416
                                                 const sc_bv<2> &rqUID,
417
                                                 bool bridge,
418
                                                 ResponseError error,
419
                                                 bool passPW,
420
                                                 bool isoc){
421
        sc_bv<32> packet = 0;
422
        sc_bv<6> packet_command = "110011";
423
        packet.range(5,0) = packet_command;
424
        packet.range(12,8) = unitID;
425
        packet.range(20,16) = srcTag;
426
        packet.range(31,30) = rqUID;
427
 
428
        //Error 0 => bv[20]
429
        //Error 1 => bv[28]
430
 
431
        if(error == RE_NORMAL || error == RE_DATA_ERROR)
432
                packet[20] = false;
433
        else
434
                packet[20] = true;
435
 
436
        if(error == RE_NORMAL || error == RE_TARGET_ABORT)
437
                packet[28] = false;
438
        else
439
                packet[28] = true;
440
 
441
        packet[14] = bridge;
442
        packet[15] = passPW;
443
        packet[7] = isoc;
444
 
445
        return packet;
446
}
447
 
448
 
449
sc_uint<5> getPacketSizeWithDatam1(const sc_bv<64> &pkt, const PacketCommand &cmd){
450
        sc_uint<5> pkt_size;
451
        sc_uint<2> packet_size_selector;
452
        packet_size_selector[1] = isDwordPacket(pkt,cmd);
453
        packet_size_selector[0] = hasDataAssociated(cmd);
454
 
455
        sc_uint<4> datalength_m1 = getDataLengthm1(pkt);
456
 
457
        switch(packet_size_selector){
458
                case 3:
459
                        pkt_size = datalength_m1 + 1;
460
                        break;
461
                case 2:
462
                        pkt_size = 0;
463
                        break;
464
                case 1:
465
                        pkt_size = datalength_m1 + 2;
466
                        break;
467
                default:
468
                        pkt_size = 1;
469
        }
470
        return pkt_size;
471
}
472
 
473
sc_uint<5> getDwordPacketSizeWithDatam1(const sc_bv<64> &pkt, const PacketCommand &cmd){
474
        sc_uint<5> pkt_size;
475
        if(hasDataAssociated(cmd)){
476
                pkt_size = getDataLengthm1(pkt) + 1;
477
        }
478
        else{
479
                pkt_size = 0;
480
        }
481
        return pkt_size;
482
}
483
 
484
#endif

powered by: WebSVN 2.1.0

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