help="the number of rows in the mesh topology")
 parser.add_option("--garnet-network", type="string", default=none,
                   help="'fixed'|'flexible'")
+parser.add_option("--numa-high-bit", type="int", default=none,
+                  help="high order address bit to use for numa mapping")
 
 # ruby sparse memory options
 parser.add_option("--use-map", action="store_true", default=False)
 
   physical_address_t getAddress() const {return m_address;}
   // selects bits inclusive
   physical_address_t bitSelect(int small, int big) const;
+  physical_address_t bitRemove(int small, int big) const;
   physical_address_t maskLowOrderBits(int number) const;
   physical_address_t maskHighOrderBits(int number) const;
   physical_address_t shiftLowOrderBits(int number) const;
   }
 }
 
+// removes bits inclusive
+inline
+physical_address_t Address::bitRemove(int small, int big) const
+{
+    physical_address_t mask;
+    assert((unsigned)big >= (unsigned)small);
+    
+    if (small >= ADDRESS_WIDTH - 1) {
+        return m_address;
+    } else if (big >= ADDRESS_WIDTH - 1) {
+        mask = (physical_address_t)~0 >> small;
+        return (m_address & mask);
+    } else if (small == 0) {
+        mask = (physical_address_t)~0 << big;
+        return (m_address & mask);
+    } else {
+        mask = ~((physical_address_t)~0 << small);
+        physical_address_t lower_bits = m_address & mask;
+        mask = (physical_address_t)~0 << (big + 1);
+        physical_address_t higher_bits = m_address & mask;
+
+        //
+        // Shift the valid high bits over the removed section
+        //
+        higher_bits = higher_bits >> (big - small);
+        return (higher_bits | lower_bits);
+    }
+}
+
 inline
 physical_address_t Address::maskLowOrderBits(int number) const
 {
 
 int DirectoryMemory::m_num_directories = 0;
 int DirectoryMemory::m_num_directories_bits = 0;
 uint64_t DirectoryMemory::m_total_size_bytes = 0;
+int DirectoryMemory::m_numa_high_bit = 0;
 
 DirectoryMemory::DirectoryMemory(const Params *p)
     : SimObject(p)
     m_num_entries = 0;
     m_use_map = p->use_map;
     m_map_levels = p->map_levels;
+    m_numa_high_bit = p->numa_high_bit;
 }
 
 void DirectoryMemory::init()
   m_num_directories++;
   m_num_directories_bits = log_int(m_num_directories);
   m_total_size_bytes += m_size_bytes;
+
+  if (m_numa_high_bit == 0) {
+      m_numa_high_bit = RubySystem::getMemorySizeBits();
+  }
+  assert(m_numa_high_bit != 0);
 }
 
 DirectoryMemory::~DirectoryMemory()
   out << "  number of directory memories: " << m_num_directories << endl;
   if (m_num_directories > 1) {
     out << "  number of selection bits: " << m_num_directories_bits << endl;
-    out << "  selection bits: " << RubySystem::getBlockSizeBits()+m_num_directories_bits-1
-        << "-" << RubySystem::getBlockSizeBits() << endl;
+    out << "  selection bits: " << m_numa_high_bit
+        << "-" << m_numa_high_bit-m_num_directories_bits 
+        << endl;
   }
   out << "  total memory size bytes: " << m_total_size_bytes << endl;
   out << "  total memory bits: " << log_int(m_total_size_bytes) << endl;
 uint64 DirectoryMemory::mapAddressToDirectoryVersion(PhysAddress address)
 {
   if (m_num_directories_bits == 0) return 0;
-  uint64 ret = address.bitSelect(RubySystem::getBlockSizeBits(),
-                              RubySystem::getBlockSizeBits()+m_num_directories_bits-1);
+  uint64 ret = address.bitSelect(m_numa_high_bit - m_num_directories_bits,
+                                 m_numa_high_bit);
   return ret;
 }
 
 
 uint64 DirectoryMemory::mapAddressToLocalIdx(PhysAddress address)
 {
-  uint64 ret = address.getAddress()
-      >> (RubySystem::getBlockSizeBits() + m_num_directories_bits);
-  return ret;
+    uint64 ret = address.bitRemove(m_numa_high_bit - m_num_directories_bits,
+                                   m_numa_high_bit)
+        >> (RubySystem::getBlockSizeBits());
+    return ret;
 }
 
 Directory_Entry& DirectoryMemory::lookup(PhysAddress address)
 
   static int m_num_directories;
   static int m_num_directories_bits;
   static uint64_t m_total_size_bytes;
+  static int m_numa_high_bit;
 
   MemoryVector* m_ram;
   SparseMemory* m_sparseMemory;
 
     size = Param.MemorySize("1GB", "capacity in bytes")
     use_map = Param.Bool(False, "enable sparse memory")
     map_levels = Param.Int(4, "sparse memory map levels")
+    numa_high_bit = Param.Int(0, "numa high bit")