38 , m_blockSizeShift(22)
39 , m_blockSize(1 << m_blockSizeShift)
40 , m_dataHandler(*this)
41 , m_writeProtected(false)
44 , m_selectedHostMemoryBlock(NULL)
45 , m_selectedOffsetWithinBlock(0)
59 void RAMComponent::ReleaseAllBlocks()
61 for (
size_t i=0; i<m_memoryBlocks.size(); ++i) {
62 if (m_memoryBlocks[i] != NULL) {
63 munmap(m_memoryBlocks[i], m_blockSize);
64 m_memoryBlocks[i] = NULL;
78 if (attributeName ==
"stable")
81 if (attributeName ==
"description")
82 return "A generic RAM component.";
97 names.push_back(
"dump");
106 if (methodName ==
"dump")
115 const vector<string>& arguments)
117 if (methodName ==
"dump") {
118 uint64_t vaddr = m_lastDumpAddr;
120 if (arguments.size() > 1) {
125 if (arguments.size() == 1) {
131 ss.flags(std::ios::hex);
135 const int nRows = 16;
136 for (
int i=0; i<nRows; i++) {
137 const size_t len = 16;
138 unsigned char data[len];
142 ss.flags(std::ios::hex);
144 if (vaddr > 0xffffffff)
149 ss << std::setfill(
'0') << vaddr;
152 for (k=0; k<len; ++k) {
159 for (k=0; k<len; ++k) {
163 ss << std::setw(2) << std::setfill(
'0');
172 for (k=0; k<len; ++k) {
190 m_lastDumpAddr = vaddr;
208 m_addressSelect = address;
210 uint64_t blockNr = address >> m_blockSizeShift;
212 if (blockNr+1 > m_memoryBlocks.size())
213 m_selectedHostMemoryBlock = NULL;
215 m_selectedHostMemoryBlock = m_memoryBlocks[blockNr];
217 m_selectedOffsetWithinBlock = address & (m_blockSize-1);
221 void* RAMComponent::AllocateBlock()
223 void * p = mmap(NULL, m_blockSize, PROT_WRITE | PROT_READ,
224 MAP_ANON | MAP_PRIVATE, -1, 0);
226 if (p == MAP_FAILED || p == NULL) {
227 std::cerr <<
"RAMComponent::AllocateBlock: Could not allocate "
228 << m_blockSize <<
" bytes. Aborting.\n";
229 throw std::exception();
232 uint64_t blockNr = m_addressSelect >> m_blockSizeShift;
234 if (blockNr+1 > m_memoryBlocks.size())
235 m_memoryBlocks.resize(blockNr + 1);
237 m_memoryBlocks[blockNr] = p;
245 if (m_selectedHostMemoryBlock == NULL)
248 data = (((uint8_t*)m_selectedHostMemoryBlock)
249 [m_selectedOffsetWithinBlock]);
257 assert((m_addressSelect & 1) == 0);
259 if (m_selectedHostMemoryBlock == NULL)
262 data = (((uint16_t*)m_selectedHostMemoryBlock)
263 [m_selectedOffsetWithinBlock >> 1]);
276 assert((m_addressSelect & 3) == 0);
278 if (m_selectedHostMemoryBlock == NULL)
281 data = (((uint32_t*)m_selectedHostMemoryBlock)
282 [m_selectedOffsetWithinBlock >> 2]);
295 assert((m_addressSelect & 7) == 0);
297 if (m_selectedHostMemoryBlock == NULL)
300 data = (((uint64_t*)m_selectedHostMemoryBlock)
301 [m_selectedOffsetWithinBlock >> 3]);
314 if (m_writeProtected)
317 if (m_selectedHostMemoryBlock == NULL)
318 m_selectedHostMemoryBlock = AllocateBlock();
320 (((uint8_t*)m_selectedHostMemoryBlock)
321 [m_selectedOffsetWithinBlock]) =
data;
329 assert((m_addressSelect & 1) == 0);
331 if (m_writeProtected)
334 if (m_selectedHostMemoryBlock == NULL)
335 m_selectedHostMemoryBlock = AllocateBlock();
343 (((uint16_t*)m_selectedHostMemoryBlock)
344 [m_selectedOffsetWithinBlock >> 1]) = d;
352 assert((m_addressSelect & 3) == 0);
354 if (m_writeProtected)
357 if (m_selectedHostMemoryBlock == NULL)
358 m_selectedHostMemoryBlock = AllocateBlock();
366 (((uint32_t*)m_selectedHostMemoryBlock)
367 [m_selectedOffsetWithinBlock >> 2]) = d;
375 assert((m_addressSelect & 7) == 0);
377 if (m_writeProtected)
380 if (m_selectedHostMemoryBlock == NULL)
381 m_selectedHostMemoryBlock = AllocateBlock();
389 (((uint64_t*)m_selectedHostMemoryBlock)
390 [m_selectedOffsetWithinBlock >> 3]) = d;
403 static void Test_RAMComponent_IsStable()
409 static void Test_RAMComponent_AddressDataBus()
415 "AddressDataBus interface", bus != NULL);
418 static void Test_RAMComponent_InitiallyZero()
430 uint16_t data16 = 142;
434 uint32_t data32 = 342;
438 uint64_t data64 = 942;
461 static void Test_RAMComponent_WriteThenRead()
468 uint64_t data64 = ((uint64_t)0x1234567 << 32) | 0x89abcdef;
471 uint64_t data64_b = 0;
476 uint32_t data32_b = 0;
480 "in big endian mode", data32_b, data64 >> 32);
482 uint16_t data16_b = 0;
486 "in big endian mode", data16_b, data64 >> 48);
492 "in big endian mode", data8_b, data64 >> 56);
495 static void Test_RAMComponent_WriteThenRead_ReverseEndianness()
502 uint64_t data64 = ((uint64_t)0x1234567 << 32) | 0x89abcdef;
507 uint32_t data32_b = 0;
512 uint16_t data16_b = 0;
523 static void Test_RAMComponent_WriteProtect()
528 uint32_t data32 = 0x89abcdef;
533 uint16_t data16_a = 0;
563 static void Test_RAMComponent_ClearOnReset()
568 uint32_t data32 = 0x89abcdef;
572 uint16_t data16_a = 0;
579 uint16_t data16_b = 0;
585 static void Test_RAMComponent_Clone()
590 uint32_t data32 = 0x89abcdef;
594 uint16_t data16_a = 0x1234;
614 static void Test_RAMComponent_ManualSerialization()
619 uint32_t data32 = 0x89abcde5;
623 uint16_t data16_a = 0x1235;
631 string result = ss.str();
633 stringstream messages;
648 static void Test_RAMComponent_Methods_Reexecutableness()
661 UNITTEST(Test_RAMComponent_IsStable);
662 UNITTEST(Test_RAMComponent_AddressDataBus);
663 UNITTEST(Test_RAMComponent_InitiallyZero);
664 UNITTEST(Test_RAMComponent_WriteThenRead);
665 UNITTEST(Test_RAMComponent_WriteThenRead_ReverseEndianness);
666 UNITTEST(Test_RAMComponent_WriteProtect);
667 UNITTEST(Test_RAMComponent_ClearOnReset);
669 UNITTEST(Test_RAMComponent_ManualSerialization);
670 UNITTEST(Test_RAMComponent_Methods_Reexecutableness);