23 #include <boost/crc.hpp>
26 using namespace torc::common;
31 void VirtexBitstream::readPackets(std::istream& inStream) {
32 uint32_t bitstreamWordLength = mBitstreamByteLength >> 2;
34 while(cumulativeWordLength < bitstreamWordLength) {
35 push_back(VirtexPacket::read(inStream));
36 cumulativeWordLength += back().getWordSize();
40 void VirtexBitstream::writePackets(std::ostream& inStream) {
41 const_iterator p = begin();
42 const_iterator e = end();
43 while(p < e) p++->write(inStream);
49 iterator
position = deleteFramePackets();
51 if(inBitstreamType == eBitstreamTypeFull) {
52 insert(position, generateFullBitstreamPackets());
54 insert(position, generatePartialBitstreamPackets(inFrameInclusion));
62 if(inBitstreamType == eBitstreamTypeFull) {
64 append(generateFullBitstreamPrefix());
66 append(generateFullBitstreamPackets());
68 append(generateFullBitstreamSuffix());
71 append(generatePartialBitstreamPrefix(inBitstreamType));
73 append(generatePartialBitstreamPackets(inFrameInclusion));
75 append(generatePartialBitstreamSuffix(inBitstreamType));
80 std::cerr << inName <<
" is not yet implemented for this architecture." << std::endl;
83 void VirtexBitstream::readFramePackets(
void) {
84 unimplemented(
"readFramePackets(void)");
88 template void VirtexBitstream::readFramePackets4567<Virtex7>(uint32_t inBlockFrameIndexBounds[],
89 std::map<Virtex7::FrameAddress, uint32_t>& inFrameAddressToIndex,
90 std::map<uint32_t, Virtex7::FrameAddress>& inFrameIndexToAddress);
91 template void VirtexBitstream::readFramePackets4567<Virtex6>(uint32_t inBlockFrameIndexBounds[],
92 std::map<Virtex6::FrameAddress, uint32_t>& inFrameAddressToIndex,
93 std::map<uint32_t, Virtex6::FrameAddress>& inFrameIndexToAddress);
94 template void VirtexBitstream::readFramePackets4567<Virtex5>(uint32_t inBlockFrameIndexBounds[],
95 std::map<Virtex5::FrameAddress, uint32_t>& inFrameAddressToIndex,
96 std::map<uint32_t, Virtex5::FrameAddress>& inFrameIndexToAddress);
97 template void VirtexBitstream::readFramePackets4567<Virtex4>(uint32_t inBlockFrameIndexBounds[],
98 std::map<Virtex4::FrameAddress, uint32_t>& inFrameAddressToIndex,
99 std::map<uint32_t, Virtex4::FrameAddress>& inFrameIndexToAddress);
101 template <
class ARCH>
void VirtexBitstream::readFramePackets4567(
103 std::map<typename ARCH::FrameAddress, uint32_t>& inFrameAddressToIndex,
104 std::map<uint32_t, typename ARCH::FrameAddress>& inFrameIndexToAddress) {
106 typedef typename ARCH::FrameAddress FrameAddress;
107 typedef std::map<FrameAddress, uint32_t> FrameAddressToIndex;
108 typedef std::map<uint32_t, FrameAddress> FrameIndexToAddress;
110 boost::shared_array<uint32_t> frameWords;
112 uint32_t frameStart[eBlockTypeCount + 1];
115 for(
int i = 0; i < eBlockTypeCount; i++) {
116 frameStart[i + 1] = frameStart[i] + inBlockFrameIndexBounds[i];
118 mFrameBlocks.mBlock[i].clear();
120 for(
uint32_t j = 0; j < inBlockFrameIndexBounds[i]; j++) {
123 mFrameBlocks.mBlock[i].back()->setUsed(
false);
127 const uint32_t frameLength = getFrameLength();
129 FrameAddress frameAddress;
130 typename ARCH::ERegister lastAddress =
typename ARCH::ERegister();
131 typename ARCH::iterator p = begin();
132 typename ARCH::iterator e = end();
138 frameAddress =
typename ARCH::FrameAddress(packet[1]);
140 typename FrameAddressToIndex::iterator ip
141 = inFrameAddressToIndex.find(frameAddress);
142 if(ip != inFrameAddressToIndex.end()) frameIndex = ip->second;
148 (packet.
isType2() && lastAddress == ARCH::eRegisterFDRI)
156 boost::shared_array<uint32_t> frameWords(packet.
getWords());
159 while(position + frameLength <= numWords) {
161 typename ARCH::EFarBlockType blockType = frameAddress.mBlockType;
162 uint32_t index = frameIndex - frameStart[blockType];
164 (
new VirtexFrame(frameLength, &frameWords[position]));
165 mFrameBlocks.mBlock[blockType][index]->setUsed();
166 position += frameLength;
168 typename FrameIndexToAddress::iterator ap
169 = inFrameIndexToAddress.find(frameIndex);
170 if(ap != inFrameIndexToAddress.end()) frameAddress = ap->second;
172 if(position > numWords) {
173 std::cerr <<
"Overflowed expected frame counts for device." << std::endl;
177 if(frameIndex != frameStart[frameAddress.mBlockType + 1]) {
180 if(inFrameIndexToAddress.find(frameIndex) == inFrameIndexToAddress.end())
182 if(inFrameIndexToAddress.find(frameIndex) == inFrameIndexToAddress.end())
185 typename FrameIndexToAddress::iterator ap
186 = inFrameIndexToAddress.find(frameIndex);
187 if(ap != inFrameIndexToAddress.end()) frameAddress = ap->second;
188 else if(frameIndex == frameStart[frameAddress.mBlockType + 1]) ;
190 std::cerr <<
"Failed to find the next valid frame address at the end of a "
191 "packet." << std::endl;
196 if(packet.
isType1()) lastAddress =
typename ARCH::ERegister(packet.
getAddress());
202 VirtexPacketVector::iterator VirtexBitstream::deleteFramePackets(
void) {
203 unimplemented(
"deleteFramePackets()");
208 template VirtexPacketVector::iterator VirtexBitstream::deleteFramePackets4567<Virtex7>(void);
209 template VirtexPacketVector::iterator VirtexBitstream::deleteFramePackets4567<Virtex6>(void);
210 template VirtexPacketVector::iterator VirtexBitstream::deleteFramePackets4567<Virtex5>(void);
211 template VirtexPacketVector::iterator VirtexBitstream::deleteFramePackets4567<Virtex4>(void);
213 template <
class ARCH> VirtexPacketVector::iterator VirtexBitstream::deleteFramePackets4567(
void)
217 iterator b = begin();
227 if(start == e && packet.
isWrite() && packet.
getAddress() == ARCH::eRegisterFAR) {
233 if((p+1)->isWrite() && (p+1)->isType2()) fdri++;
238 && packet.
getAddress() == ARCH::eRegisterCRC) {
249 if(start < e && stop > b && !(
256 (packet.
getAddress() == ARCH::eRegisterCMD && packet[1] == ARCH::eCommandWCFG)
259 std::cerr <<
"Unable to safely distinguish frame packets." << std::endl;
264 if(start < stop && b < stop) {
273 unimplemented(
"generateFullBitstreamPackets()");
278 template VirtexPacketVector VirtexBitstream::generateFullBitstreamPackets4567<Virtex7>(
279 uint32_t inBlockFrameIndexBounds[]);
280 template VirtexPacketVector VirtexBitstream::generateFullBitstreamPackets4567<Virtex6>(
281 uint32_t inBlockFrameIndexBounds[]);
282 template VirtexPacketVector VirtexBitstream::generateFullBitstreamPackets4567<Virtex5>(
283 uint32_t inBlockFrameIndexBounds[]);
284 template VirtexPacketVector VirtexBitstream::generateFullBitstreamPackets4567<Virtex4>(
285 uint32_t inBlockFrameIndexBounds[]);
288 uint32_t inBlockFrameIndexBounds[]) {
293 VirtexPacket nop(VirtexPacket::makeHeader(ePacketType1, eOpcodeNOP, 0, 0));
297 for(
int i = 0; i < eBlockTypeCount; i++)
298 size += inBlockFrameIndexBounds[i] * getFrameLength();
300 word_t* pos = frameContents;
302 for(
int i = 0; i < eBlockTypeCount; i++) {
306 VirtexFrameSet::iterator p = frameSet.begin();
307 VirtexFrameSet::iterator e = frameSet.end();
312 const word_t* wp = framePtr->getWords();
313 const word_t* we = wp + framePtr->getLength();
315 if(wp)
do { *pos++ = *wp++; }
while(wp < we);
316 else do { *pos++ = 0; wp++; }
while(wp < we);
320 packets.push_back(VirtexPacket::makeType1Write(ARCH::eRegisterFAR, 0));
322 packets.push_back(VirtexPacket::makeType1Write(ARCH::eRegisterCMD, ARCH::eCommandWCFG));
323 packets.push_back(nop);
325 packets.push_back(VirtexPacket::makeNullType1Write(ARCH::eRegisterFDRI));
327 packets.push_back(VirtexPacket::makeType2Write(size, frameContents));
334 unimplemented(
"generateFullBitstreamPrefix()");
339 unimplemented(
"generateFullBitstreamSuffix()");
345 unimplemented(
"generatePartialBitstreamPackets()");
350 template VirtexPacketVector VirtexBitstream::generatePartialBitstreamPackets4567<Virtex7>(
351 EFrameInclude inFrameInclusion,
352 std::map<Virtex7::FrameAddress, uint32_t>& inFrameAddressToIndex,
353 std::map<uint32_t, Virtex7::FrameAddress>& inFrameIndexToAddress);
354 template VirtexPacketVector VirtexBitstream::generatePartialBitstreamPackets4567<Virtex6>(
355 EFrameInclude inFrameInclusion,
356 std::map<Virtex6::FrameAddress, uint32_t>& inFrameAddressToIndex,
357 std::map<uint32_t, Virtex6::FrameAddress>& inFrameIndexToAddress);
358 template VirtexPacketVector VirtexBitstream::generatePartialBitstreamPackets4567<Virtex5>(
359 EFrameInclude inFrameInclusion,
360 std::map<Virtex5::FrameAddress, uint32_t>& inFrameAddressToIndex,
361 std::map<uint32_t, Virtex5::FrameAddress>& inFrameIndexToAddress);
362 template VirtexPacketVector VirtexBitstream::generatePartialBitstreamPackets4567<Virtex4>(
363 EFrameInclude inFrameInclusion,
364 std::map<Virtex4::FrameAddress, uint32_t>& inFrameAddressToIndex,
365 std::map<uint32_t, Virtex4::FrameAddress>& inFrameIndexToAddress);
369 std::map<typename ARCH::FrameAddress, uint32_t>& inFrameAddressToIndex,
370 std::map<uint32_t, typename ARCH::FrameAddress>& inFrameIndexToAddress) {
372 typedef typename ARCH::FrameAddress FrameAddress;
373 typedef std::map<FrameAddress, uint32_t> FrameAddressToIndex;
374 typedef std::map<uint32_t, FrameAddress> FrameIndexToAddress;
379 VirtexPacket nop(VirtexPacket::makeHeader(ePacketType1, eOpcodeNOP, 0, 0));
382 packets.push_back(VirtexPacket::makeType1Write(ARCH::eRegisterFAR, 0));
384 packets.push_back(VirtexPacket::makeType1Write(ARCH::eRegisterCMD, ARCH::eCommandWCFG));
385 packets.push_back(nop);
391 for(
int i = 0; i < eBlockTypeCount; i++) {
394 bool started =
false;
399 VirtexFrameSet::iterator p = frameSet.begin();
400 VirtexFrameSet::iterator e = frameSet.end();
412 || (inFrameInclusion == eFrameIncludeAllUsedFrames && framePtr->isUsed())
413 || (started && blockStart + index < inFrameIndexToAddress.size() &&
414 inFrameIndexToAddress.find(blockStart + index)
415 == inFrameIndexToAddress.end())
419 if((started && !include)) {
421 uint32_t stopIndex = index + (p == e ? 1 : 0);
425 if(inFrameIndexToAddress.find(blockStart + stopIndex + 1)
426 == inFrameIndexToAddress.end()) {
428 if(inFrameIndexToAddress.find(blockStart + stopIndex + 1)
429 == inFrameIndexToAddress.end())
433 size_t size = (stopIndex - startIndex) * getFrameLength();
436 word_t* pos = frameContents;
437 while(currentIndex < stopIndex) {
441 const word_t* wp = framePtr->getWords();
442 const word_t* we = wp + framePtr->getLength();
444 if(wp)
do { *pos++ = *wp++; }
while(wp < we);
445 else do { *pos++ = 0; wp++; }
while(wp < we);
449 packets.push_back(VirtexPacket::makeType1Write(ARCH::eRegisterFAR,
450 inFrameIndexToAddress[blockStart + startIndex]));
451 packets.push_back(nop);
455 packets.push_back(VirtexPacket::makeNullType1Write(ARCH::eRegisterFDRI));
457 packets.push_back(VirtexPacket::makeType2Write(size, frameContents));
460 packets.push_back(VirtexPacket::makeType1Write(ARCH::eRegisterFDRI, size,
463 if(size) empty =
false;
465 }
else if(!started && include) {
476 if(empty) packets.clear();
483 unimplemented(
"generatePartialBitstreamPrefix()");
489 unimplemented(
"generatePartialBitstreamSuffix()");
493 void VirtexBitstream::preflightPackets(
void) {
500 updateCrc16(family);
break;
505 updateCrc32(family);
break;
516 bool autoCrc =
false;
519 cmdRegister = Virtex::eRegisterCMD; rcrcCommand = Virtex::eCommandRCRC;
520 fdriRegister = Virtex::eRegisterFDRI; crcRegister = Virtex::eRegisterCRC;
521 addressLength = 4; autoCrc =
false;
524 cmdRegister = Virtex2::eRegisterCMD; rcrcCommand = Virtex2::eCommandRCRC;
525 fdriRegister = Virtex2::eRegisterFDRI; crcRegister = Virtex::eRegisterCRC;
526 addressLength = 5; autoCrc =
true;
529 std::cerr <<
"Unsupported architecture in VirtexBitstream::updateCrc16()." << std::endl;
534 iterator p = begin();
537 boost::crc_basic<16> crc16(0x8005, 0, 0,
false,
true);
542 if(!packet.
isWrite())
continue;
545 if(wordCount == 0)
continue;
547 if(address == crcRegister) {
550 *(p-1) = VirtexPacket::makeType1Write(crcRegister, crc16.checksum());
553 }
else if(address == cmdRegister && wordCount >= 1 && packet[1] == rcrcCommand) {
559 for(
uint32_t i = 1; i <= wordCount; i++) {
563 for(j = 0, mask = 1; j < 32; j++, mask <<= 1) {
564 crc16.process_bit((word & mask) ? 1 : 0);
566 for(j = 0, mask = 1; j < addressLength; j++, mask <<= 1) {
567 crc16.process_bit((address & mask) ? 1 : 0);
571 if(autoCrc && address == fdriRegister) {
589 cmdRegister = Virtex4::eRegisterCMD; rcrcCommand = Virtex4::eCommandRCRC;
590 crcRegister = Virtex4::eRegisterCRC;
593 cmdRegister = Virtex5::eRegisterCMD; rcrcCommand = Virtex5::eCommandRCRC;
594 crcRegister = Virtex5::eRegisterCRC;
597 cmdRegister = Virtex6::eRegisterCMD; rcrcCommand = Virtex6::eCommandRCRC;
598 crcRegister = Virtex6::eRegisterCRC;
602 cmdRegister = Virtex7::eRegisterCMD; rcrcCommand = Virtex7::eCommandRCRC;
603 crcRegister = Virtex7::eRegisterCRC;
606 std::cerr <<
"Unsupported architecture in VirtexBitstream::updateCrc32()." << std::endl;
611 iterator p = begin();
614 boost::crc_basic<32> crc32(0x1edc6f41, 0, 0,
false,
true);
619 if(!packet.
isWrite())
continue;
622 if(wordCount == 0)
continue;
624 if(address == crcRegister) {
627 *(p-1) = VirtexPacket::makeType1Write(crcRegister, crc32.checksum());
630 }
else if(address == cmdRegister && wordCount >= 1 && packet[1] == rcrcCommand) {
636 for(
uint32_t i = 1; i <= wordCount; i++) {
640 for(j = 0, mask = 1; j < 32; j++, mask <<= 1) {
641 crc32.process_bit((word & mask) ? 1 : 0);
643 for(j = 0, mask = 1; j < addressLength; j++, mask <<= 1) {
644 crc32.process_bit((address & mask) ? 1 : 0);
651 void VirtexBitstream::updatePacketLength(
void) {
653 iterator p = begin();
655 while(p < e) totalWordCount += (p++)->getWordSize();
656 mBitstreamByteLength = totalWordCount << 2;
Header for the VirtexBitstream class.
Encapsulation of a device designator and its constituent elements.
Header for the Virtex4 class.
const EFamily & getFamily(void) const
Returns the device family.
Frame< uint32_t > VirtexFrame
Virtex frame type.
EFrameInclude
The frames to include in a partial bitstream. Use eFrameIncludeOnlyDirtyFrames to include only dirty...
Header for the Virtex6 class.
Header for the Virtex5 class.
uint32_t getWordCount(void) const
Returns the number of payload words in the packet, excluding the header word.
boost::uint32_t uint32_t
Imported type name.
int getAddress(void) const
VirtexFrame::word_t word_t
FrameSet word type.
EBitstreamType
The bitstream type to generate. Use eBitstreamFull to fully reconfigure a device, eBitstreamTypePartialActive to partially reconfigure it while it continues to run, or eBitstreamTypePartialShutdown to partially recongifure it after shutting it down.
boost::shared_ptr< VirtexFrame > FrameSharedPtr
Shared pointer encapsulation of a Frame.
std::vector< VirtexPacket > VirtexPacketVector
Vector of Virtex packets.
Header for the Virtex class.
const WordSharedArray getWords(void) const
brief Returns the raw packet words, including the header word.
boost::shared_ptr< VirtexFrame > VirtexFrameSharedPtr
Virtex frame type.
VirtexFrame::word_t word_t
FrameSet word type.
Header for the Virtex2 class.
Bitstream packet for Virtex class architectures.
WORD_TYPE word_t
Frame word type.
Header for the Virtex7 class.