torc-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Spartan6Bitstream.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 Spartan6Bitstream::readPackets(std::istream& inStream) {
28  uint16_t bitstreamWordLength = mBitstreamByteLength >> 1;
29  uint16_t cumulativeWordLength = 0;
30  while(cumulativeWordLength < bitstreamWordLength) {
31  push_back(Spartan6Packet::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  uint16_t autoCrcHi = 0;
37  uint16_t autoCrcLo = 0;
38  inStream.read((char*) &autoCrcHi, sizeof(autoCrcHi));
39  inStream.read((char*) &autoCrcLo, sizeof(autoCrcLo));
40  autoCrcHi = ntohs(autoCrcHi);
41  autoCrcLo = ntohs(autoCrcLo);
42  push_back(Spartan6Packet(autoCrcHi, autoCrcLo));
43  cumulativeWordLength += 2;
44  }
45  }
46 
47  void Spartan6Bitstream::writePackets(std::ostream& inStream) {
48  const_iterator p = begin();
49  const_iterator e = end();
50  while(p < e) p++->write(inStream);
51  }
52 
53  void Spartan6Bitstream::preflightPackets(void) {
54  // determine which architecture this is
55  DeviceDesignator deviceDesignator(getDeviceName());
56  DeviceDesignator::EFamily family = deviceDesignator.getFamily();
57  // set up family-specific variables
58  uint32_t crcRegister = 0;
59  uint32_t cmdRegister = 0;
60  uint32_t fdriRegister = 0;
61  uint32_t rcrcCommand = 0;
62  uint32_t addressLength = 0;
63  bool autoCrc = false;
64  switch(family) {
66  cmdRegister = Spartan6::eRegisterCMD; rcrcCommand = Spartan6::eCommandRCRC;
67  fdriRegister = Spartan6::eRegisterFDRI; crcRegister = Spartan6::eRegisterCRC;
68  /*addressLength = 6*/ (void) addressLength; autoCrc = true;
69  break;
70  default:
71  std::cerr << "Unsupported architecture in Spartan6Bitstream::preflightPackets()."
72  << std::endl;
73  break;
74  }
75  // begin CRC calculation: calculation is derived from one of the following simulation files:
76  // ISE/verilog/src/unisims/SIM_CONFIG_S6.v
77  // ISE/vhdl/src/unisims/primitive/SIM_CONFIG_S6.vhd
78  CRC crc;
79  iterator p = begin();
80  iterator e = end();
81  while(p < e) {
82  // look up the current packet
83  const Spartan6Packet& packet = *p++;
84  // only process write packets with non-zero payload length
85  if(!packet.isWrite()) continue;
86  uint32_t address = packet.getAddress();
87  uint32_t wordCount = packet.getWordCount();
88  if(wordCount == 0) continue;
89  // CRC register write (this is what compares the expected and supplied CRC values)
90  if(address == crcRegister) {
91  //printf("Expected CRC16: %8.8x\n", uint32_t(packet[1]) << 16 | packet[2]);
92  //printf("Calculated CRC16: %8.8x\n", uint32_t(crc));
93  *(p-1) = Spartan6Packet::makeType1Write32(crcRegister, crc);
94  crc.reset();
95  // reset CRC command
96  } else if(address == cmdRegister && wordCount >= 1 && packet[1] == rcrcCommand) {
97  crc.reset();
98  // registers that are omitted from CRC calculation
99  } else if(address == Spartan6::eRegisterBOOSTS || address == Spartan6::eRegisterSTAT
100  || address == Spartan6::eRegisterLOUT || address == Spartan6::eRegisterCSBO
101  || address == Spartan6::eRegisterRDBK_SIGN || address == Spartan6::eRegisterFDRO) {
102  // process packet contents
103  } else {
104  for(uint32_t i = 1; i <= wordCount; i++) {
105  uint32_t word = packet[i];
106  //printf("Address: %4.4x\n", address);
107  //printf("Word: %8.8x\n", word);
108  crc.update(address, word);
109  // debugging output
110  //for(int32_t c = sizeof(crc_curr) - 1; c >= 0; c--) printf("%d", crc_curr[c]);
111  //printf("\n");
112  }
113  // process the Auto CRC
114  if(autoCrc && address == fdriRegister) {
115  //printf("Expected Auto CRC16: %8.8x\n", (uint32_t((*p)[0]) << 16) | (*p)[1]);
116  //printf("Calculated Auto CRC16: %8.8x\n", uint32_t(crc));
117  // current packet is FDRI, next is Auto CRC
118  *p = Spartan6Packet(crc >> 16, crc & 0xffff);
119  // unlike the Spartan3E, the CRC is not reset after an Auto CRC
120  //crc.reset();
121  }
122  }
123  }
124  }
125 
126  void Spartan6Bitstream::updatePacketLength(void) {
127  uint32_t totalWordCount = 0;
128  iterator p = begin();
129  iterator e = end();
130  while(p < e) totalWordCount += (p++)->getWordSize();
131  mBitstreamByteLength = totalWordCount << 1;
132  }
133 
134 } // namespace bitstream
135 } // namespace torc
Header for the Spartan6Bitstream class.
Encapsulation of a device designator and its constituent elements.
uint32_t getWordCount(void) const
Returns the number of payload words in the packet, excluding the header word.
const EFamily & getFamily(void) const
Returns the device family.
void reset(void)
Function to clear the CRC calculation.
void update(uint32_t inAddress, uint32_t inWord)
Update the CRC with new data.
Bitstream packet for Spartan 16 bit class architectures.
Header for the DeviceDesignator class.
Header for the Spartan6 class.
boost::uint32_t uint32_t
Imported type name.
CRC class for the Spartan6 architecture.
boost::uint16_t uint16_t
Imported type name.