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 ==
"description")
79 return "A generic RAM component.";
94 names.push_back(
"dump");
103 if (methodName ==
"dump")
112 const vector<string>& arguments)
114 if (methodName ==
"dump") {
115 uint64_t vaddr = m_lastDumpAddr;
117 if (arguments.size() > 1) {
122 if (arguments.size() == 1) {
128 ss.flags(std::ios::hex);
132 const int nRows = 16;
133 for (
int i=0; i<nRows; i++) {
134 const size_t len = 16;
135 unsigned char data[len];
139 ss.flags(std::ios::hex);
141 if (vaddr > 0xffffffff)
146 ss << std::setfill(
'0') << vaddr;
149 for (k=0; k<len; ++k) {
156 for (k=0; k<len; ++k) {
160 ss << std::setw(2) << std::setfill(
'0');
169 for (k=0; k<len; ++k) {
187 m_lastDumpAddr = vaddr;
205 m_addressSelect = address;
207 uint64_t blockNr = address >> m_blockSizeShift;
209 if (blockNr+1 > m_memoryBlocks.size())
210 m_selectedHostMemoryBlock = NULL;
212 m_selectedHostMemoryBlock = m_memoryBlocks[blockNr];
214 m_selectedOffsetWithinBlock = address & (m_blockSize-1);
218 void* RAMComponent::AllocateBlock()
220 void * p = mmap(NULL, m_blockSize, PROT_WRITE | PROT_READ,
221 MAP_ANON | MAP_PRIVATE, -1, 0);
223 if (p == MAP_FAILED || p == NULL) {
224 std::cerr <<
"RAMComponent::AllocateBlock: Could not allocate "
225 << m_blockSize <<
" bytes. Aborting.\n";
226 throw std::exception();
229 uint64_t blockNr = m_addressSelect >> m_blockSizeShift;
231 if (blockNr+1 > m_memoryBlocks.size())
232 m_memoryBlocks.resize(blockNr + 1);
234 m_memoryBlocks[blockNr] = p;
242 if (m_selectedHostMemoryBlock == NULL)
245 data = (((uint8_t*)m_selectedHostMemoryBlock)
246 [m_selectedOffsetWithinBlock]);
254 assert((m_addressSelect & 1) == 0);
256 if (m_selectedHostMemoryBlock == NULL)
259 data = (((uint16_t*)m_selectedHostMemoryBlock)
260 [m_selectedOffsetWithinBlock >> 1]);
273 assert((m_addressSelect & 3) == 0);
275 if (m_selectedHostMemoryBlock == NULL)
278 data = (((uint32_t*)m_selectedHostMemoryBlock)
279 [m_selectedOffsetWithinBlock >> 2]);
292 assert((m_addressSelect & 7) == 0);
294 if (m_selectedHostMemoryBlock == NULL)
297 data = (((uint64_t*)m_selectedHostMemoryBlock)
298 [m_selectedOffsetWithinBlock >> 3]);
311 if (m_writeProtected)
314 if (m_selectedHostMemoryBlock == NULL)
315 m_selectedHostMemoryBlock = AllocateBlock();
317 (((uint8_t*)m_selectedHostMemoryBlock)
318 [m_selectedOffsetWithinBlock]) =
data;
326 assert((m_addressSelect & 1) == 0);
328 if (m_writeProtected)
331 if (m_selectedHostMemoryBlock == NULL)
332 m_selectedHostMemoryBlock = AllocateBlock();
340 (((uint16_t*)m_selectedHostMemoryBlock)
341 [m_selectedOffsetWithinBlock >> 1]) = d;
349 assert((m_addressSelect & 3) == 0);
351 if (m_writeProtected)
354 if (m_selectedHostMemoryBlock == NULL)
355 m_selectedHostMemoryBlock = AllocateBlock();
363 (((uint32_t*)m_selectedHostMemoryBlock)
364 [m_selectedOffsetWithinBlock >> 2]) = d;
372 assert((m_addressSelect & 7) == 0);
374 if (m_writeProtected)
377 if (m_selectedHostMemoryBlock == NULL)
378 m_selectedHostMemoryBlock = AllocateBlock();
386 (((uint64_t*)m_selectedHostMemoryBlock)
387 [m_selectedOffsetWithinBlock >> 3]) = d;
400 static void Test_RAMComponent_AddressDataBus()
406 "AddressDataBus interface", bus != NULL);
409 static void Test_RAMComponent_InitiallyZero()
421 uint16_t data16 = 142;
425 uint32_t data32 = 342;
429 uint64_t data64 = 942;
452 static void Test_RAMComponent_WriteThenRead()
459 uint64_t data64 = ((uint64_t)0x1234567 << 32) | 0x89abcdef;
462 uint64_t data64_b = 0;
467 uint32_t data32_b = 0;
471 "in big endian mode", data32_b, data64 >> 32);
473 uint16_t data16_b = 0;
477 "in big endian mode", data16_b, data64 >> 48);
483 "in big endian mode", data8_b, data64 >> 56);
486 static void Test_RAMComponent_WriteThenRead_ReverseEndianness()
493 uint64_t data64 = ((uint64_t)0x1234567 << 32) | 0x89abcdef;
498 uint32_t data32_b = 0;
503 uint16_t data16_b = 0;
514 static void Test_RAMComponent_WriteProtect()
519 uint32_t data32 = 0x89abcdef;
524 uint16_t data16_a = 0;
554 static void Test_RAMComponent_ClearOnReset()
559 uint32_t data32 = 0x89abcdef;
563 uint16_t data16_a = 0;
570 uint16_t data16_b = 0;
576 static void Test_RAMComponent_Clone()
581 uint32_t data32 = 0x89abcdef;
585 uint16_t data16_a = 0x1234;
605 static void Test_RAMComponent_ManualSerialization()
610 uint32_t data32 = 0x89abcde5;
614 uint16_t data16_a = 0x1235;
622 string result = ss.str();
624 stringstream messages;
639 static void Test_RAMComponent_Methods_Reexecutableness()
652 UNITTEST(Test_RAMComponent_AddressDataBus);
653 UNITTEST(Test_RAMComponent_InitiallyZero);
654 UNITTEST(Test_RAMComponent_WriteThenRead);
655 UNITTEST(Test_RAMComponent_WriteThenRead_ReverseEndianness);
656 UNITTEST(Test_RAMComponent_WriteProtect);
657 UNITTEST(Test_RAMComponent_ClearOnReset);
659 UNITTEST(Test_RAMComponent_ManualSerialization);
660 UNITTEST(Test_RAMComponent_Methods_Reexecutableness);