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

Subversion Repositories ht_tunnel

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 acastong
//InterfaceLayer.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 "../core/PacketContainer.h"
41
#include "InterfaceLayer.h"
42
 
43
#include <iostream>
44
 
45
using namespace std;
46
 
47
 
48
InterfaceLayer::InterfaceLayer(sc_module_name name) : sc_module(name){
49
        SC_THREAD(rx_process);
50
        sensitive_pos(clk);
51
 
52
        SC_THREAD(tx_process);
53
        sensitive_pos(clk);
54
 
55
        receivePacket = NULL;
56
        tx_state = TX_IDLE;
57
        rx_state = RX_IDLE;
58
}
59
 
60
InterfaceLayer::~InterfaceLayer(){
61
        ///Free all packet and data allocated memory
62
        for(deque<PacketAndData>::iterator i = packetQueue.begin();
63
                i != packetQueue.end(); i++)
64
        {
65
                delete (*i).packet;
66
                delete [] (*i).data;
67
        }
68
        //Might still be NULL, that's OK
69
        delete receivePacket;
70
}
71
 
72
void InterfaceLayer::tx_process(){
73
        while(true){
74
                if(!resetx.read()) tx_state = TX_IDLE;
75
                else{
76
                switch(tx_state){
77
                case TX_SEND_DATA:
78
                {
79
                        sc_bv<64> bv;
80
                        bv.range(63,32) = 0;
81
                        bv.range(31,0) = packetQueue.front().data[tx_data_sent];
82
                        usr_packet_ui = bv;
83
 
84
                        //Send data until we reached the data count for that packet
85
                        if(tx_data_sent++ == packetQueue.front().packet->getDataLengthm1()){
86
                                delete packetQueue.front().packet;
87
                                delete [] packetQueue.front().data;
88
                                packetQueue.pop_front();
89
                                tx_state = TX_IDLE;
90
                        }
91
                }
92
                        break;
93
                default:
94
                        //If nothing to send, don't activate user available
95
                        if(packetQueue.empty()) usr_available_ui = false;
96
                        else{
97
                                ///Check the VC of the next packet to send, and if it has data
98
                                VirtualChannel vc = packetQueue.front().packet->getVirtualChannel();
99
                                bool hasData = packetQueue.front().packet->hasDataAssociated();
100
 
101
                                ///Check if there is enough buffers so that it can be sent
102
                                bool canSend;
103
                                if(vc == VC_POSTED){
104
                                        canSend = (sc_bit)ui_freevc0_usr.read()[5] && (sc_bit)ui_freevc1_usr.read()[5] &&
105
                                                (!hasData || (sc_bit)ui_freevc0_usr.read()[4] && (sc_bit)ui_freevc1_usr.read()[4]);
106
                                }
107
                                else if(vc == VC_NON_POSTED){
108
                                        canSend = (sc_bit)ui_freevc0_usr.read()[3] && (sc_bit)ui_freevc1_usr.read()[3] &&
109
                                                (!hasData || (sc_bit)ui_freevc0_usr.read()[2] && (sc_bit)ui_freevc1_usr.read()[2]);
110
                                }
111
                                else{
112
                                        canSend = (sc_bit)ui_freevc0_usr.read()[1] && (sc_bit)ui_freevc1_usr.read()[1] &&
113
                                                (!hasData || (sc_bit)ui_freevc0_usr.read()[0] && (sc_bit)ui_freevc1_usr.read()[0]);
114
                                }
115
 
116
                                ///If enough buffers
117
                                if(canSend){
118
                                        ///Make the next dword available
119
                                        usr_available_ui = true;
120
                                        ///Output the packet
121
                                        usr_packet_ui = packetQueue.front().packet->getVector();
122
                                        ///If it has data associated, go to the state to send it
123
                                        if(hasData){
124
                                                tx_state = TX_SEND_DATA;
125
                                                tx_data_sent = 0;
126
                                        }
127
                                        //otherwise delete the current packet entry
128
                                        else{
129
                                                delete packetQueue.front().packet;
130
                                                delete [] packetQueue.front().data;
131
                                                packetQueue.pop_front();
132
                                        }
133
                                }
134
                                else  usr_available_ui = false;
135
                        }
136
                }
137
                }
138
                wait();
139
        }
140
}
141
 
142
void InterfaceLayer::rx_process(){
143
        //Always consume what is received
144
        usr_consume_ui = true;
145
        while(true){
146
                if(!resetx.read()) rx_state = RX_IDLE;
147
                else{
148
 
149
                switch(rx_state){
150
                case RX_RECEIVE_DATA:
151
                        //store data
152
                        receiveData[rx_received_data] = ui_packet_usr.read().range(31,0).to_int();
153
                        //If receiving data is done, go back to an idle state
154
                        if(rx_received_data++ == receivePacket->getDataLengthm1()){
155
                                handler->receivedInterfacePacketEvent(receivePacket,receiveData,
156
                                        receiveDirecRoute,receiveSide,this);
157
                                rx_state = RX_IDLE;
158
                        }
159
                        break;
160
                default:
161
                        //If there is data available
162
                        if(ui_available_usr.read()){
163
                                //Create a packet from the quad word
164
                                PacketContainer c = ControlPacket::createPacketFromQuadWord(ui_packet_usr);
165
                                //Delete the previous received packet and replace with new
166
                                delete receivePacket;
167
                                receivePacket = c.giveControl();
168
                                receiveSide = ui_side_usr.read();
169
                                receiveDirecRoute = ui_directroute_usr.read();
170
 
171
                                //If it has data, go to data receiving state
172
                                if(receivePacket->hasDataAssociated()){
173
                                        rx_state = RX_RECEIVE_DATA;
174
                                        rx_received_data = 0;
175
                                }
176
                                //Otherwise, launch event that packet is received
177
                                else{
178
                                        handler->receivedInterfacePacketEvent(receivePacket,NULL,
179
                                                receiveDirecRoute,receiveSide,this);
180
                                }
181
                        }
182
                }
183
                }
184
                wait();
185
 
186
        }
187
}
188
 
189
void InterfaceLayer::sendPacket(ControlPacket * packet,int * data,bool side){
190
        //Add the packet to the queue
191
        PacketAndData pad;
192
        pad.packet = packet;
193
        pad.data = data;
194
        pad.side = side;
195
        packetQueue.push_back(pad);
196
}
197
 
198
void InterfaceLayer::flush(){
199
        //wait until the send queue is empty
200
        while(!packetQueue.empty()) wait();
201
}
202
 
203
 
204
 

powered by: WebSVN 2.1.0

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