gem5  v21.1.0.2
NetworkBridge.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Advanced Micro Devices, Inc.
3  * All rights reserved.
4  *
5  * For use for simulation and test purposes only
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived from this
19  * software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 
36 
37 #include <cmath>
38 
39 #include "debug/RubyNetwork.hh"
40 #include "params/GarnetIntLink.hh"
41 
42 namespace gem5
43 {
44 
45 namespace ruby
46 {
47 
48 namespace garnet
49 {
50 
52  :CreditLink(p)
53 {
54  enCdc = true;
55  enSerDes = true;
56  mType = p.vtype;
57 
58  cdcLatency = p.cdc_latency;
59  serDesLatency = p.serdes_latency;
60  lastScheduledAt = 0;
61 
62  nLink = p.link;
63  if (mType == enums::LINK_OBJECT) {
64  nLink->setLinkConsumer(this);
66  } else if (mType == enums::OBJECT_LINK) {
69  } else {
70  // CDC type must be set
71  panic("CDC type must be set");
72  }
73 }
74 
75 void
76 NetworkBridge::setVcsPerVnet(uint32_t consumerVcs)
77 {
78  DPRINTF(RubyNetwork, "VcsPerVnet VC: %d\n", consumerVcs);
79  NetworkLink::setVcsPerVnet(consumerVcs);
80  lenBuffer.resize(consumerVcs * m_virt_nets);
81  sizeSent.resize(consumerVcs * m_virt_nets);
82  flitsSent.resize(consumerVcs * m_virt_nets);
83  extraCredit.resize(consumerVcs * m_virt_nets);
84 
85  nLink->setVcsPerVnet(consumerVcs);
86 }
87 
88 void
89 NetworkBridge::initBridge(NetworkBridge *coBrid, bool cdc_en, bool serdes_en)
90 {
91  coBridge = coBrid;
92  enCdc = cdc_en;
93  enSerDes = serdes_en;
94 }
95 
97 {
98 }
99 
100 void
102 {
103  Cycles totLatency = latency;
104 
105  if (enCdc) {
106  // Add the CDC latency
107  totLatency = latency + cdcLatency;
108  }
109 
110  Tick sendTime = link_consumer->getObject()->clockEdge(totLatency);
111  Tick nextAvailTick = lastScheduledAt + link_consumer->getObject()->\ cyclesToTicks(Cycles(1));
112  sendTime = std::max(nextAvailTick, sendTime);
113  t_flit->set_time(sendTime);
114  lastScheduledAt = sendTime;
115  linkBuffer.insert(t_flit);
117 }
118 
119 void
120 NetworkBridge::neutralize(int vc, int eCredit)
121 {
122  extraCredit[vc].push(eCredit);
123 }
124 
125 void
127 {
128  // Serialize-Deserialize only if it is enabled
129  if (enSerDes) {
130  // Calculate the target-width
131  int target_width = bitWidth;
132  int cur_width = nLink->bitWidth;
133  if (mType == enums::OBJECT_LINK) {
134  target_width = nLink->bitWidth;
135  cur_width = bitWidth;
136  }
137 
138  DPRINTF(RubyNetwork, "Target width: %d Current: %d\n",
139  target_width, cur_width);
140  assert(target_width != cur_width);
141 
142  int vc = t_flit->get_vc();
143 
144  if (target_width > cur_width) {
145  // Deserialize
146  // This deserializer combines flits from the
147  // same message together
148  int num_flits = 0;
149  int flitPossible = 0;
150  if (t_flit->get_type() == CREDIT_) {
151  lenBuffer[vc]++;
152  assert(extraCredit[vc].front());
153  if (lenBuffer[vc] == extraCredit[vc].front()) {
154  flitPossible = 1;
155  extraCredit[vc].pop();
156  lenBuffer[vc] = 0;
157  }
158  } else if (t_flit->get_type() == TAIL_ ||
159  t_flit->get_type() == HEAD_TAIL_) {
160  // If its the end of packet, then send whatever
161  // is available.
162  int sizeAvail = (t_flit->msgSize - sizeSent[vc]);
163  flitPossible = ceil((float)sizeAvail/(float)target_width);
164  assert (flitPossible < 2);
165  num_flits = (t_flit->get_id() + 1) - flitsSent[vc];
166  // Stop tracking the packet.
167  flitsSent[vc] = 0;
168  sizeSent[vc] = 0;
169  } else {
170  // If we are yet to receive the complete packet
171  // track the size recieved and flits deserialized.
172  int sizeAvail =
173  ((t_flit->get_id() + 1)*cur_width) - sizeSent[vc];
174  flitPossible = floor((float)sizeAvail/(float)target_width);
175  assert (flitPossible < 2);
176  num_flits = (t_flit->get_id() + 1) - flitsSent[vc];
177  if (flitPossible) {
178  sizeSent[vc] += target_width;
179  flitsSent[vc] = t_flit->get_id() + 1;
180  }
181  }
182 
183  DPRINTF(RubyNetwork, "Deserialize :%dB -----> %dB "
184  " vc:%d\n", cur_width, target_width, vc);
185 
186  flit *fl = NULL;
187  if (flitPossible) {
188  fl = t_flit->deserialize(lenBuffer[vc], num_flits,
189  target_width);
190  }
191 
192  // Inform the credit serializer about the number
193  // of flits that were generated.
194  if (t_flit->get_type() != CREDIT_ && fl) {
195  coBridge->neutralize(vc, num_flits);
196  }
197 
198  // Schedule only if we are done deserializing
199  if (fl) {
200  DPRINTF(RubyNetwork, "Scheduling a flit\n");
201  lenBuffer[vc] = 0;
203  }
204  // Delete this flit, new flit is sent in any case
205  delete t_flit;
206  } else {
207  // Serialize
208  DPRINTF(RubyNetwork, "Serializing flit :%d -----> %d "
209  "(vc:%d, Original Message Size: %d)\n",
210  cur_width, target_width, vc, t_flit->msgSize);
211 
212  int flitPossible = 0;
213  if (t_flit->get_type() == CREDIT_) {
214  // We store the deserialization ratio and then
215  // access it when serializing credits in the
216  // oppposite direction.
217  assert(extraCredit[vc].front());
218  flitPossible = extraCredit[vc].front();
219  extraCredit[vc].pop();
220  } else if (t_flit->get_type() == HEAD_ ||
221  t_flit->get_type() == BODY_) {
222  int sizeAvail =
223  ((t_flit->get_id() + 1)*cur_width) - sizeSent[vc];
224  flitPossible = floor((float)sizeAvail/(float)target_width);
225  if (flitPossible) {
226  sizeSent[vc] += flitPossible*target_width;
227  flitsSent[vc] += flitPossible;
228  }
229  } else {
230  int sizeAvail = t_flit->msgSize - sizeSent[vc];
231  flitPossible = ceil((float)sizeAvail/(float)target_width);
232  sizeSent[vc] = 0;
233  flitsSent[vc] = 0;
234  }
235  assert(flitPossible > 0);
236 
237  // Schedule all the flits
238  // num_flits could be zero for credits
239  for (int i = 0; i < flitPossible; i++) {
240  // Ignore neutralized credits
241  flit *fl = t_flit->serialize(i, flitPossible, target_width);
243  DPRINTF(RubyNetwork, "Serialized to flit[%d of %d parts]:"
244  " %s\n", i+1, flitPossible, *fl);
245  }
246 
247  if (t_flit->get_type() != CREDIT_) {
248  coBridge->neutralize(vc, flitPossible);
249  }
250  // Delete this flit, new flit is sent in any case
251  delete t_flit;
252  }
253  return;
254  }
255 
256  // If only CDC is enabled schedule it
257  scheduleFlit(t_flit, Cycles(0));
258 }
259 void
261 {
262  flit *t_flit;
263 
264  if (link_srcQueue->isReady(curTick())) {
265  t_flit = link_srcQueue->getTopFlit();
266  DPRINTF(RubyNetwork, "Recieved flit %s\n", *t_flit);
267  flitisizeAndSend(t_flit);
268  }
269 
270  // Reschedule in case there is a waiting flit.
271  if (!link_srcQueue->isEmpty()) {
272  scheduleEvent(Cycles(1));
273  }
274 }
275 
276 } // namespace garnet
277 } // namespace ruby
278 } // namespace gem5
279 
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::ruby::garnet::flit
Definition: flit.hh:50
gem5::ruby::garnet::NetworkBridge::coBridge
NetworkBridge * coBridge
Definition: NetworkBridge.hh:79
gem5::ruby::garnet::HEAD_TAIL_
@ HEAD_TAIL_
Definition: CommonTypes.hh:47
gem5::ruby::garnet::NetworkBridge::flitsSent
std::vector< int > flitsSent
Definition: NetworkBridge.hh:102
gem5::ruby::garnet::NetworkBridge::extraCredit
std::vector< std::queue< int > > extraCredit
Definition: NetworkBridge.hh:103
gem5::ruby::garnet::NetworkBridge::~NetworkBridge
~NetworkBridge()
Definition: NetworkBridge.cc:96
gem5::ruby::garnet::NetworkBridge::sizeSent
std::vector< int > sizeSent
Definition: NetworkBridge.hh:101
gem5::ruby::garnet::flit::set_time
void set_time(Tick time)
Definition: flit.hh:74
gem5::ruby::garnet::NetworkBridge::wakeup
void wakeup()
Definition: NetworkBridge.cc:261
gem5::ruby::garnet::NetworkBridge
Definition: NetworkBridge.hh:60
gem5::ruby::garnet::flit::deserialize
virtual flit * deserialize(int des_id, int num_flits, uint32_t bWidth)
Definition: flit.cc:93
gem5::ruby::garnet::flit::msgSize
int msgSize
Definition: flit.hh:115
gem5::ruby::garnet::NetworkBridge::scheduleFlit
void scheduleFlit(flit *t_flit, Cycles latency)
Definition: NetworkBridge.cc:101
gem5::ruby::garnet::flitBuffer::isReady
bool isReady(Tick curTime)
Definition: flitBuffer.cc:60
gem5::ruby::garnet::NetworkBridge::mType
int mType
Definition: NetworkBridge.hh:92
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
gem5::Cycles
Cycles is a wrapper class for representing cycle counts, i.e.
Definition: types.hh:78
gem5::ruby::garnet::NetworkBridge::setVcsPerVnet
void setVcsPerVnet(uint32_t consumerVcs)
Definition: NetworkBridge.cc:76
gem5::ruby::garnet::BODY_
@ BODY_
Definition: CommonTypes.hh:47
gem5::ruby::garnet::flit::get_vc
int get_vc()
Definition: flit.hh:66
gem5::ruby::garnet::HEAD_
@ HEAD_
Definition: CommonTypes.hh:47
gem5::ruby::Consumer::scheduleEvent
void scheduleEvent(Cycles timeDelta)
Definition: Consumer.cc:56
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::ruby::garnet::flitBuffer::getTopFlit
flit * getTopFlit()
Definition: flitBuffer.hh:64
gem5::ruby::garnet::NetworkBridge::initBridge
void initBridge(NetworkBridge *coBrid, bool cdc_en, bool serdes_en)
Definition: NetworkBridge.cc:89
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
NetworkBridge.hh
gem5::ruby::garnet::flitBuffer::insert
void insert(flit *flt)
Definition: flitBuffer.hh:78
gem5::ruby::garnet::NetworkBridge::enCdc
bool enCdc
Definition: NetworkBridge.hh:87
gem5::ruby::garnet::NetworkBridge::nLink
NetworkLink * nLink
Definition: NetworkBridge.hh:84
gem5::ruby::garnet::flit::get_id
int get_id()
Definition: flit.hh:63
gem5::ruby::garnet::NetworkBridge::enSerDes
bool enSerDes
Definition: NetworkBridge.hh:89
gem5::Clocked::clockEdge
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Definition: clocked_object.hh:177
gem5::ruby::garnet::NetworkBridge::serDesLatency
Cycles serDesLatency
Definition: NetworkBridge.hh:95
gem5::ruby::garnet::NetworkBridge::neutralize
void neutralize(int vc, int eCredit)
Definition: NetworkBridge.cc:121
gem5::ruby::garnet::NetworkBridge::flitisizeAndSend
void flitisizeAndSend(flit *t_flit)
Definition: NetworkBridge.cc:127
gem5::ruby::garnet::NetworkBridge::NetworkBridge
NetworkBridge(const Params &p)
Definition: NetworkBridge.cc:51
gem5::ruby::garnet::TAIL_
@ TAIL_
Definition: CommonTypes.hh:47
gem5::ruby::garnet::NetworkBridge::lenBuffer
std::vector< int > lenBuffer
Definition: NetworkBridge.hh:100
gem5::ruby::garnet::flit::get_type
flit_type get_type()
Definition: flit.hh:69
gem5::ruby::garnet::NetworkBridge::cdcLatency
Cycles cdcLatency
Definition: NetworkBridge.hh:94
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::ruby::garnet::flit::serialize
virtual flit * serialize(int ser_id, int parts, uint32_t bWidth)
Definition: flit.cc:76
gem5::ruby::garnet::flitBuffer::isEmpty
bool isEmpty()
Definition: flitBuffer.cc:54
gem5::ruby::Consumer::scheduleEventAbsolute
void scheduleEventAbsolute(Tick timeAbs)
Definition: Consumer.cc:63
gem5::ruby::Consumer::getObject
ClockedObject * getObject()
Definition: Consumer.hh:81
gem5::ruby::garnet::NetworkBridge::lastScheduledAt
Tick lastScheduledAt
Definition: NetworkBridge.hh:97
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::ruby::garnet::CREDIT_
@ CREDIT_
Definition: CommonTypes.hh:48

Generated on Tue Sep 21 2021 12:25:41 for gem5 by doxygen 1.8.17