torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SpartanBitstream.cpp
Go to the documentation of this file.
1 // Torc - Copyright 2011-2013 University of Southern California. All Rights Reserved.
2 // $HeadURL$
3 // $Id$
4 
5 // This program is free software: you can redistribute it and/or modify it under the terms of the
6 // GNU General Public License as published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
10 // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
11 // the GNU General Public License for more details.
12 //
13 // You should have received a copy of the GNU General Public License along with this program. If
14 // not, see <http://www.gnu.org/licenses/>.
15 
19 #include <boost/crc.hpp>
20 #include <stdio.h>
21 
22 using namespace torc::common;
23 
24 namespace torc {
25 namespace bitstream {
26 
27  void SpartanBitstream::readPackets(std::istream& inStream) {
28  uint32_t bitstreamWordLength = mBitstreamByteLength >> 2;
29  uint32_t cumulativeWordLength = 0;
30  while(cumulativeWordLength < bitstreamWordLength) {
31  push_back(SpartanPacket::read(inStream));
32  uint32_t wordSize = back().getWordSize();
33  cumulativeWordLength += wordSize;
34  // infer Auto CRCs for writes equal to or longer than one frame (not rigorously correct)
35  if(wordSize <= getFrameLength()) continue;
36  uint32_t autoCrc = 0;
37  inStream.read((char*) &autoCrc, sizeof(autoCrc));
38  autoCrc = ntohl(autoCrc);
39  push_back(SpartanPacket(autoCrc));
40  cumulativeWordLength++;
41  }
42  }
43 
44  void SpartanBitstream::writePackets(std::ostream& inStream) {
45  const_iterator p = begin();
46  const_iterator e = end();
47  while(p < e) p++->write(inStream);
48  }
49 
50  void SpartanBitstream::preflightPackets(void) {
51  // determine which architecture this is
52  DeviceDesignator deviceDesignator(getDeviceName());
53  DeviceDesignator::EFamily family = deviceDesignator.getFamily();
54  // set up family-specific variables
55  uint32_t crcRegister = 0;
56  uint32_t cmdRegister = 0;
57  uint32_t fdriRegister = 0;
58  uint32_t rcrcCommand = 0;
59  uint32_t addressLength = 0;
60  bool autoCrc = false;
61  switch(family) {
63  cmdRegister = Spartan3E::eRegisterCMD; rcrcCommand = Spartan3E::eCommandRCRC;
64  fdriRegister = Spartan3E::eRegisterFDRI; crcRegister = Spartan3E::eRegisterCRC;
65  addressLength = 5; autoCrc = true;
66  break;
67  default:
68  std::cerr << "Unsupported architecture in SpartanBitstream::preflightPackets()."
69  << std::endl;
70  break;
71  }
72  // begin CRC calculation
73  uint32_t address = 0;
74  iterator p = begin();
75  iterator e = end();
76  // CRC-16-IBM polynomial for Spartan3/6 and Virtex/E/2/2P families
77  boost::crc_basic<16> crc16(0x8005, 0, 0, false, true);
78  while(p < e) {
79  // look up the current packet
80  const SpartanPacket& packet = *p++;
81  // only process write packets with non-zero payload length
82  if(!packet.isWrite()) continue;
83  if(packet.isType1()) address = packet.getAddress();
84  uint32_t wordCount = packet.getWordCount();
85  if(wordCount == 0) continue;
86  // CRC register write (this is what compares the expected and supplied CRC values)
87  if(address == crcRegister) {
88  //printf("Expected CRC16: %4.4x\n", packet[1]);
89  //printf("Calculated CRC16: %4.4x\n", crc16.checksum());
90  *(p-1) = SpartanPacket::makeType1Write(crcRegister, crc16.checksum());
91  crc16.reset();
92  // reset CRC command
93  } else if(address == cmdRegister && wordCount >= 1 && packet[1] == rcrcCommand) {
94  crc16.reset();
95  // process packet contents
96  } else {
97  uint32_t j;
98  uint32_t mask;
99  for(uint32_t i = 1; i <= wordCount; i++) {
100  uint32_t word = packet[i];
101  //printf("Address: %4.4x\n", address);
102  //printf("Word: %8.8x\n", word);
103  for(j = 0, mask = 1; j < 32; j++, mask <<= 1) {
104  crc16.process_bit((word & mask) ? 1 : 0);
105  }
106  for(j = 0, mask = 1; j < addressLength; j++, mask <<= 1) {
107  crc16.process_bit((address & mask) ? 1 : 0);
108  }
109  }
110  // process the Auto CRC
111  if(autoCrc && address == fdriRegister) {
112  //printf("Expected Auto CRC16: %4.4x\n", (*p)[0]);
113  //printf("Calculated Auto CRC16: %4.4x\n", crc16.checksum());
114  *p = SpartanPacket(crc16.checksum()); // current word is FDRI, next is Auto CRC
115  crc16.reset();
116  }
117  }
118  }
119  }
120 
121  void SpartanBitstream::updatePacketLength(void) {
122  uint32_t totalWordCount = 0;
123  iterator p = begin();
124  iterator e = end();
125  while(p < e) totalWordCount += (p++)->getWordSize();
126  mBitstreamByteLength = totalWordCount << 2;
127  }
128 
129 } // namespace bitstream
130 } // namespace torc
Encapsulation of a device designator and its constituent elements.
const EFamily & getFamily(void) const
Returns the device family.
Header for the DeviceDesignator class.
boost::uint32_t uint32_t
Imported type name.
Header for the SpartanBitstream class.
Header for the Spartan3E class.
Bitstream packet for Spartan class architectures.
uint32_t getWordCount(void) const
Returns the number of payload words in the packet, excluding the header word.