RubySlicc_ComponentMapping.hh revision 6145:15cca6ab723a
1
2/*
3 * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met: redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer;
10 * redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution;
13 * neither the name of the copyright holders nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/*
31 * $Id$
32 */
33
34#ifndef COMPONENTMAPPINGFNS_H
35#define COMPONENTMAPPINGFNS_H
36
37#include "Global.hh"
38#include "RubyConfig.hh"
39#include "NodeID.hh"
40#include "MachineID.hh"
41#include "Address.hh"
42#include "Set.hh"
43#include "NetDest.hh"
44#include "GenericMachineType.hh"
45
46#ifdef MACHINETYPE_L1Cache
47#define MACHINETYPE_L1CACHE_ENUM MachineType_L1Cache
48#else
49#define MACHINETYPE_L1CACHE_ENUM MachineType_NUM
50#endif
51
52#ifdef MACHINETYPE_L2Cache
53#define MACHINETYPE_L2CACHE_ENUM MachineType_L2Cache
54#else
55#define MACHINETYPE_L2CACHE_ENUM MachineType_NUM
56#endif
57
58#ifdef MACHINETYPE_L3Cache
59#define MACHINETYPE_L3CACHE_ENUM MachineType_L3Cache
60#else
61#define MACHINETYPE_L3CACHE_ENUM MachineType_NUM
62#endif
63
64#ifdef MACHINETYPE_PersistentArbiter
65#define MACHINETYPE_PERSISTENTARBITER_ENUM MachineType_PersistentArbiter
66#else
67#define MACHINETYPE_PERSISTENTARBITER_ENUM MachineType_NUM
68#endif
69
70#ifdef MACHINETYPE_Collector
71#define MACHINETYPE_COLLECTOR_ENUM MachineType_Collector
72#else
73#define MACHINETYPE_COLLECTOR_ENUM MachineType_NUM
74#endif
75
76
77// used to determine the correct L1 set
78// input parameters are the address and number of set bits for the L1 cache
79// returns a value between 0 and the total number of L1 cache sets
80inline
81int map_address_to_L1CacheSet(const Address& addr, int cache_num_set_bits)
82{
83  return addr.bitSelect(RubyConfig::dataBlockBits(),
84                        RubyConfig::dataBlockBits()+cache_num_set_bits-1);
85}
86
87// used to determine the correct L2 set
88// input parameters are the address and number of set bits for the L2 cache
89// returns a value between 0 and the total number of L2 cache sets
90inline
91int map_address_to_L2CacheSet(const Address& addr, int cache_num_set_bits)
92{
93  assert(cache_num_set_bits == L2_CACHE_NUM_SETS_BITS);  // ensure the l2 bank mapping functions agree with l2 set bits
94
95  if (MAP_L2BANKS_TO_LOWEST_BITS) {
96    return addr.bitSelect(RubyConfig::dataBlockBits()+RubyConfig::L2CachePerChipBits(),
97                          RubyConfig::dataBlockBits()+RubyConfig::L2CachePerChipBits()+cache_num_set_bits-1);
98  } else {
99    return addr.bitSelect(RubyConfig::dataBlockBits(),
100                          RubyConfig::dataBlockBits()+cache_num_set_bits-1);
101  }
102}
103
104// input parameter is the base ruby node of the L1 cache
105// returns a value between 0 and total_L2_Caches_within_the_system
106inline
107MachineID map_L1CacheMachId_to_L2Cache(const Address& addr, MachineID L1CacheMachId)
108{
109  int L2bank = 0;
110  MachineID mach = {MACHINETYPE_L2CACHE_ENUM, 0};
111
112  if (RubyConfig::L2CachePerChipBits() > 0) {
113    if (MAP_L2BANKS_TO_LOWEST_BITS) {
114      L2bank = addr.bitSelect(RubyConfig::dataBlockBits(),
115                         RubyConfig::dataBlockBits()+RubyConfig::L2CachePerChipBits()-1);
116    } else {
117      L2bank = addr.bitSelect(RubyConfig::dataBlockBits()+L2_CACHE_NUM_SETS_BITS,
118                         RubyConfig::dataBlockBits()+L2_CACHE_NUM_SETS_BITS+RubyConfig::L2CachePerChipBits()-1);
119    }
120  }
121
122  assert(L2bank < RubyConfig::numberOfL2CachePerChip());
123  assert(L2bank >= 0);
124
125  mach.num = RubyConfig::L1CacheNumToL2Base(L1CacheMachId.num)*RubyConfig::numberOfL2CachePerChip() // base #
126    + L2bank;  // bank #
127  assert(mach.num < RubyConfig::numberOfL2Cache());
128  return mach;
129}
130
131// used to determine the correct L2 bank
132// input parameter is the base ruby node of the L2 cache
133// returns a value between 0 and total_L2_Caches_within_the_system
134inline
135MachineID map_L2ChipId_to_L2Cache(const Address& addr, NodeID L2ChipId)
136{
137  assert(L2ChipId < RubyConfig::numberOfChips());
138
139  int L2bank = 0;
140  MachineID mach = {MACHINETYPE_L2CACHE_ENUM, 0};
141
142  if (RubyConfig::L2CachePerChipBits() > 0) {
143    if (MAP_L2BANKS_TO_LOWEST_BITS) {
144      L2bank = addr.bitSelect(RubyConfig::dataBlockBits(),
145                         RubyConfig::dataBlockBits()+RubyConfig::L2CachePerChipBits()-1);
146    } else {
147      L2bank = addr.bitSelect(RubyConfig::dataBlockBits()+L2_CACHE_NUM_SETS_BITS,
148                         RubyConfig::dataBlockBits()+L2_CACHE_NUM_SETS_BITS+RubyConfig::L2CachePerChipBits()-1);
149    }
150  }
151
152  assert(L2bank < RubyConfig::numberOfL2CachePerChip());
153  assert(L2bank >= 0);
154
155  mach.num = L2ChipId*RubyConfig::numberOfL2CachePerChip() // base #
156    + L2bank; // bank #
157  assert(mach.num < RubyConfig::numberOfL2Cache());
158  return mach;
159}
160
161// used to determine the home directory
162// returns a value between 0 and total_directories_within_the_system
163inline
164NodeID map_Address_to_DirectoryNode(const Address& addr)
165{
166  NodeID dirNode = 0;
167
168  if (RubyConfig::memoryBits() > 0) {
169    dirNode = addr.bitSelect(RubyConfig::dataBlockBits(),
170                        RubyConfig::dataBlockBits()+RubyConfig::memoryBits()-1);
171  }
172
173  //  Index indexHighPortion = address.bitSelect(MEMORY_SIZE_BITS-1, PAGE_SIZE_BITS+NUMBER_OF_MEMORY_MODULE_BITS);
174  //  Index indexLowPortion  = address.bitSelect(DATA_BLOCK_BITS, PAGE_SIZE_BITS-1);
175
176  //Index index = indexLowPortion | (indexHighPortion << (PAGE_SIZE_BITS - DATA_BLOCK_BITS));
177
178/*
179
180ADDRESS_WIDTH    MEMORY_SIZE_BITS        PAGE_SIZE_BITS  DATA_BLOCK_BITS
181  |                    |                       |               |
182 \ /                  \ /                     \ /             \ /       0
183  -----------------------------------------------------------------------
184  |       unused        |xxxxxxxxxxxxxxx|       |xxxxxxxxxxxxxxx|       |
185  |                     |xxxxxxxxxxxxxxx|       |xxxxxxxxxxxxxxx|       |
186  -----------------------------------------------------------------------
187                        indexHighPortion         indexLowPortion
188                                        <------->
189                               NUMBER_OF_MEMORY_MODULE_BITS
190  */
191
192  assert(dirNode < RubyConfig::numberOfMemories());
193  assert(dirNode >= 0);
194  return dirNode;
195}
196
197// used to determine the home directory
198// returns a value between 0 and total_directories_within_the_system
199inline
200MachineID map_Address_to_Directory(const Address &addr)
201{
202  MachineID mach = {MachineType_Directory, map_Address_to_DirectoryNode(addr)};
203  return mach;
204}
205
206inline
207MachineID map_Address_to_CentralArbiterNode(const Address& addr)
208{
209  MachineType t = MACHINETYPE_PERSISTENTARBITER_ENUM;
210  MachineID mach = {t, map_Address_to_DirectoryNode(addr)};
211
212  assert(mach.num < RubyConfig::numberOfMemories());
213  assert(mach.num >= 0);
214  return mach;
215}
216
217inline
218NetDest getMultiStaticL2BankNetDest(const Address& addr, const Set& sharers)  // set of L2RubyNodes
219{
220  NetDest dest;
221
222  for (int i = 0; i < sharers.getSize(); i++) {
223    if (sharers.isElement(i)) {
224      dest.add(map_L2ChipId_to_L2Cache(addr,i));
225    }
226  }
227  return dest;
228}
229
230inline
231NetDest getOtherLocalL1IDs(MachineID L1)
232{
233  int start = (L1.num / RubyConfig::numberOfProcsPerChip()) * RubyConfig::numberOfProcsPerChip();
234  NetDest ret;
235
236  assert(MACHINETYPE_L1CACHE_ENUM != MachineType_NUM);
237
238  for (int i = start; i < (start + RubyConfig::numberOfProcsPerChip()); i++) {
239    if (i != L1.num) {
240      MachineID mach = { MACHINETYPE_L1CACHE_ENUM, i };
241      ret.add( mach );
242    }
243  }
244
245  return ret;
246}
247
248inline
249NetDest getLocalL1IDs(MachineID mach)
250{
251  assert(MACHINETYPE_L1CACHE_ENUM != MachineType_NUM);
252
253  NetDest ret;
254
255  if (mach.type == MACHINETYPE_L1CACHE_ENUM) {
256
257    int start = (mach.num / RubyConfig::numberOfL1CachePerChip()) * RubyConfig::numberOfProcsPerChip();
258
259    for (int i = start; i < (start + RubyConfig::numberOfProcsPerChip()); i++) {
260      MachineID mach = { MACHINETYPE_L1CACHE_ENUM, i };
261      ret.add( mach );
262    }
263  }
264  else if (mach.type == MACHINETYPE_L2CACHE_ENUM) {
265
266    int chip = mach.num/RubyConfig::numberOfL2CachePerChip();
267    int start = ( chip*RubyConfig::numberOfL1CachePerChip());
268    for (int i = start; i < (start + RubyConfig::numberOfL1CachePerChip()); i++) {
269      MachineID mach = { MACHINETYPE_L1CACHE_ENUM, i };
270      ret.add( mach );
271    }
272  }
273
274  return ret;
275}
276
277inline
278NetDest getExternalL1IDs(MachineID L1)
279{
280  NetDest ret;
281
282  assert(MACHINETYPE_L1CACHE_ENUM != MachineType_NUM);
283
284  for (int i = 0; i < RubyConfig::numberOfProcessors(); i++) {
285    // ret.add( (NodeID) i);
286    MachineID mach = { MACHINETYPE_L1CACHE_ENUM, i };
287    ret.add( mach );
288  }
289
290  ret.removeNetDest(getLocalL1IDs(L1));
291
292  return ret;
293}
294
295inline
296bool isLocalProcessor(MachineID thisId, MachineID tarID)
297{
298  int start = (thisId.num / RubyConfig::numberOfProcsPerChip()) * RubyConfig::numberOfProcsPerChip();
299
300  for (int i = start; i < (start + RubyConfig::numberOfProcsPerChip()); i++) {
301    if (i == tarID.num) {
302      return true;
303    }
304  }
305  return false;
306}
307
308
309inline
310NetDest getAllPertinentL2Banks(const Address& addr)  // set of L2RubyNodes
311{
312  NetDest dest;
313
314  for (int i = 0; i < RubyConfig::numberOfChips(); i++) {
315    dest.add(map_L2ChipId_to_L2Cache(addr,i));
316  }
317  return dest;
318}
319
320inline
321bool isL1OnChip(MachineID L1machID, NodeID L2NodeID)
322{
323  if (L1machID.type == MACHINETYPE_L1CACHE_ENUM) {
324    return (L1machID.num == L2NodeID);
325  } else {
326    return false;
327  }
328}
329
330inline
331bool isL2OnChip(MachineID L2machID, NodeID L2NodeID)
332{
333  if (L2machID.type == MACHINETYPE_L2CACHE_ENUM) {
334    return (L2machID.num == L2NodeID);
335  } else {
336    return false;
337  }
338}
339
340inline
341NodeID closest_clockwise_distance(NodeID this_node, NodeID next_node)
342{
343  if (this_node <= next_node) {
344    return (next_node - this_node);
345  } else {
346    return (next_node - this_node + RubyConfig::numberOfChips());
347  }
348}
349
350inline
351bool closer_clockwise_processor(NodeID this_node, NodeID newer, NodeID older)
352{
353  return (closest_clockwise_distance(this_node, newer) < closest_clockwise_distance(this_node, older));
354}
355
356extern inline NodeID getChipID(MachineID L2machID)
357{
358  return (L2machID.num%RubyConfig::numberOfChips())/RubyConfig::numberOfProcsPerChip();
359}
360
361extern inline NodeID machineIDToNodeID(MachineID machID)
362{
363  // return machID.num%RubyConfig::numberOfChips();
364  return machID.num;
365}
366
367extern inline NodeID machineIDToVersion(MachineID machID)
368{
369  return machID.num/RubyConfig::numberOfChips();
370}
371
372extern inline MachineType machineIDToMachineType(MachineID machID)
373{
374  return machID.type;
375}
376
377extern inline NodeID L1CacheMachIDToProcessorNum(MachineID machID)
378{
379  assert(machID.type == MachineType_L1Cache);
380  return machID.num;
381}
382
383extern inline NodeID L2CacheMachIDToChipID(MachineID machID)
384{
385  assert(machID.type == MACHINETYPE_L2CACHE_ENUM);
386  return machID.num/RubyConfig::numberOfL2CachePerChip();
387}
388
389extern inline MachineID getCollectorDest(MachineID L1MachID)
390{
391  MachineID mach = {MACHINETYPE_COLLECTOR_ENUM, L1MachID.num};
392  return mach;
393}
394
395extern inline MachineID getCollectorL1Cache(MachineID colID)
396{
397  MachineID mach = {MACHINETYPE_L1CACHE_ENUM, colID.num};
398  return mach;
399}
400
401extern inline MachineID getL1MachineID(NodeID L1RubyNode)
402{
403  MachineID mach = {MACHINETYPE_L1CACHE_ENUM, L1RubyNode};
404  return mach;
405}
406
407extern inline GenericMachineType ConvertMachToGenericMach(MachineType machType) {
408  if (machType == MACHINETYPE_L1CACHE_ENUM) {
409    return GenericMachineType_L1Cache;
410  } else if (machType == MACHINETYPE_L2CACHE_ENUM) {
411    return GenericMachineType_L2Cache;
412  } else if (machType == MACHINETYPE_L3CACHE_ENUM) {
413    return GenericMachineType_L3Cache;
414  } else if (machType == MachineType_Directory) {
415    return GenericMachineType_Directory;
416  } else if (machType == MACHINETYPE_COLLECTOR_ENUM) {
417    return GenericMachineType_Collector;
418  } else {
419    ERROR_MSG("cannot convert to a GenericMachineType");
420    return GenericMachineType_NULL;
421  }
422}
423
424
425#endif  // COMPONENTMAPPINGFNS_H
426