byteman  1.3 (Build #225)
Bitstream relocation and manipulation tool
inlineOutput.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2022 Kristiyan Manev (University of Manchester)
3  *
4  * Licensed under the Apache License, Version 2.0(the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *****************************************************************************/
16 
17 inline void updateDateAndTime()
18 {
19  time_t timestamp = time(0);
20  struct tm tstruct;
21  char buf[80];
22  tstruct = *localtime(&timestamp);
23  strftime(buf, sizeof(buf), "%Y/%m/%d", &tstruct);
24  fileDate = std::string(buf);
25  strftime(buf, sizeof(buf), "%H:%M:%S", &tstruct);
26  fileTime = std::string(buf);
27 }
28 
29 inline void outputBITheader16bString(std::ofstream& fout, Endianness e, std::string s){
30  FileIO::write16(fout, static_cast<uint16_t>(s.size() + 1), e);
31  FileIO::writeString(fout, s, e);
32 }
33 
34 inline void outputBITheader(std::ofstream& fout, Endianness e)
35 {
36  log("Generating bitstream header in " + Endian::to_string(e) + ".");
37  outputBITheader16bString(fout, e, std::string("\x0F\xF0\x0F\xF0\x0F\xF0\x0F\xF0"));
38  FileIO::write16(fout, 1, e);//16-bit BE value = 1
39  FileIO::write8(fout, 'a', e);
40  outputBITheader16bString(fout, e, designName);
41  FileIO::write8(fout, 'b', e);//8-bit BE value = 'b'
42  outputBITheader16bString(fout, e, partName);
43  FileIO::write8(fout, 'c', e);//8-bit BE value = 'c'
44  outputBITheader16bString(fout, e, fileDate);
45  FileIO::write8(fout, 'd', e);//8-bit BE value = 'd'
46  outputBITheader16bString(fout, e, fileTime);
47  FileIO::write8(fout, 'e', e);//8-bit BE value = 'e'
48  headerLocationOfRemainingFileLength = fout.tellp();
49  FileIO::write32(fout, 0, e);//32-bit BE value = 0 representing remaining file size. needs to be fixed later
50 }
51 
52 inline void outputBITheaderLengthField(std::ofstream& fout, Endianness e)
53 {
54  std::streamoff finalFileSize = fout.tellp();
55  std::streamoff reportDiff = finalFileSize - (headerLocationOfRemainingFileLength + 4);
56  fout.seekp(headerLocationOfRemainingFileLength);
57  FileIO::write32(fout, static_cast<uint32_t>(reportDiff), e);
58 }
59 
60 inline void outputCAPheaderConstant(std::ofstream& fout, Endianness e)
61 {
62  for(int i = 0 ; i < 16 ; i++) // 64 bytes of 0xFF
63  FileIO::write32(fout, 0xFFFFFFFF, e);//32-bit BE value = 0xFFFFFFFF
64  FileIO::write32(fout, 0x000000BB, e);
65  FileIO::write32(fout, 0x11220044, e);
66  FileIO::write32(fout, 0xFFFFFFFF, e);
67  FileIO::write32(fout, 0xFFFFFFFF, e);
69 }
70 
71 inline void writeBitstreamMainEmptySLR(std::ofstream& fout, int slr)
72 {
73  outputCAPheaderConstant(fout, loadedBitstreamEndianness);
74  outputBitstreamEmptySLRHeaderSequence(fout, slr, false, loadedBitstreamEndianness);
75 }
76 
77 inline void writeBitstreamMainSingleRegion(std::ofstream& fout, int slr, Rect2D writeRect)
78 {
79  void *blankFrame = calloc(WORDS_PER_FRAME, 4);
80 
81  if(rect::empty(writeRect)) // If output region is empty, just return
82  return;
83  int srcR = writeRect.position.row / CLB_PER_CLOCK_REGION;
84  int sizeR = writeRect.size.row / CLB_PER_CLOCK_REGION;
85  for(int r = 0 ; r < sizeR ; r++){
86  int fromCol = writeRect.position.col;
87  int toCol = writeRect.position.col + writeRect.size.col;
88  if(selectedOptions.skipUnused){
89  for( ; (fromCol < numberOfCols[r] && LUT_isFrameUnusedForResourceLetter[(uint8_t)resourceString[srcR + r][fromCol]]) ; fromCol++);
90  for( ; (toCol > 0 && LUT_isFrameUnusedForResourceLetter[(uint8_t)resourceString[srcR + r][toCol]]) ; toCol--);
91  if(fromCol >= toCol)
92  continue;
93  }
94  if(selectedOptions.clb){
95  int framesToWrite = numberOfFramesBeforeCol[r][toCol]-numberOfFramesBeforeCol[r][fromCol];
96  uint32_t farValue = XCAP_getFAR(slr, BLOCKTYPE_LOGIC, srcR + r, fromCol, 0);
97  if(selectedOptions.blank){
98  XCAP_writeRegister(fout, XCAP::Register::FAR, farValue, loadedBitstreamEndianness);
99  XCAP_writeCommand(fout, XCAP::Command::WCFG, loadedBitstreamEndianness);
100  XCAP_writeNOP(fout, 1, 0, loadedBitstreamEndianness);
101  XCAP_writeFDRI(fout, ((framesToWrite + 1)*WORDS_PER_FRAME), loadedBitstreamEndianness);
102  for(int i = 0 ; i <= framesToWrite ; i++)
103  fout.write((char*)blankFrame, WORDS_PER_FRAME * 4);
104  }//selectedOptions.blank
105  XCAP_writeRegister(fout, XCAP::Register::FAR, farValue, loadedBitstreamEndianness);
106  XCAP_writeCommand(fout, XCAP::Command::WCFG, loadedBitstreamEndianness);
107  XCAP_writeNOP(fout, 1, 0, loadedBitstreamEndianness);
108  XCAP_writeFDRI(fout, ((framesToWrite + 1)*WORDS_PER_FRAME), loadedBitstreamEndianness);
109 
110  fout.write((char*)&bitstreamCLB[srcR + r][fromCol][0], framesToWrite * WORDS_PER_FRAME * 4);
111  fout.write((char*)blankFrame, WORDS_PER_FRAME * 4);
112  }//selectedOptions.clb
113  if(selectedOptions.bram){
114  int framesToWrite = FRAMES_PER_BRAM_CONTENT_COLUMN * (numberOfBRAMsBeforeCol[r][toCol]-numberOfBRAMsBeforeCol[r][fromCol]);
115  if(framesToWrite > 0) {
116  uint32_t farValue = XCAP_getFAR(slr, BLOCKTYPE_BLOCKRAM, srcR + r, numberOfBRAMsBeforeCol[r][fromCol], 0);
117  XCAP_writeRegister(fout, XCAP::Register::FAR, farValue, loadedBitstreamEndianness);
118  XCAP_writeCommand(fout, XCAP::Command::WCFG, loadedBitstreamEndianness);
119  XCAP_writeNOP(fout, 1, 0, loadedBitstreamEndianness);
120  XCAP_writeFDRI(fout, ((framesToWrite + 1)*WORDS_PER_FRAME), loadedBitstreamEndianness);
121 
122  fout.write((char*)&bitstreamBRAM[srcR + r][numberOfBRAMsBeforeCol[r][fromCol]][0], framesToWrite * WORDS_PER_FRAME * 4);
123  fout.write((char*)blankFrame, WORDS_PER_FRAME * 4);
124  }
125  }//selectedOptions.bram
126  }
127 }
128 
129 inline void writeBitstreamMainSingleSLR(std::ofstream& fout, int slr, Rect2D cmdRect)
130 {
131  Rect2D slrCoordsRect = {{0, 0}, {0, 0}};
132  slrCoordsRect.position.row = SLRinfo[slr].fromRow * CLB_PER_CLOCK_REGION;
133  slrCoordsRect.size.row = (SLRinfo[slr].toRow - SLRinfo[slr].fromRow + 1) * CLB_PER_CLOCK_REGION;
134  slrCoordsRect.size.col = maxNumberOfCols;
135 
136  outputCAPheaderConstant(fout, loadedBitstreamEndianness);
137  outputBitstreamSLRHeaderBitstreamSequence(fout, slr, (!selectedOptions.partialNotFull), loadedBitstreamEndianness);
138 
139  if(selectedOptions.partialNotFull){
140  for (Rect2D selRect : regionSelection) {
141  writeBitstreamMainSingleRegion(fout, slr, rect::getOverlap(selRect, slrCoordsRect));
142  }
143  writeBitstreamMainSingleRegion(fout, slr, rect::getOverlap(cmdRect, slrCoordsRect));
144  } else {// full
145  writeBitstreamMainSingleRegion(fout, slr, slrCoordsRect);
146  }
147 
148  outputBitstreamSLRFooterBitstreamSequence(fout, slr, (!selectedOptions.partialNotFull), loadedBitstreamEndianness);
149  outputBitstreamSLRHeaderAfterBitstreamSequence(fout, slr, (!selectedOptions.partialNotFull), loadedBitstreamEndianness);
150 }
151 
152 inline void writeBitstreamMain(std::ofstream& fout, Rect2D cmdRect)
153 {
154  bool overlap[MAX_SLRS];
155  for(int slr = 0 ; slr < numberOfSLRs ; slr++){
156  //Check if there is overlap between selected regions and the current SLR.
157  Rect2D slrCoordsRect = {{0, 0}, {0, 0}};
158  slrCoordsRect.position.row = SLRinfo[slr].fromRow * CLB_PER_CLOCK_REGION;
159  slrCoordsRect.size.row = (SLRinfo[slr].toRow - SLRinfo[slr].fromRow + 1) * CLB_PER_CLOCK_REGION;
160  slrCoordsRect.size.col = maxNumberOfCols;
161  overlap[slr] = false;
162  if(selectedOptions.partialNotFull){
163  for (Rect2D selRect : regionSelection) {
164  if(!rect::empty(rect::getOverlap(selRect, slrCoordsRect))){
165  overlap[slr] = true;
166  break;
167  }
168  }
169  if(!rect::empty(rect::getOverlap(cmdRect, slrCoordsRect)))
170  overlap[slr] = true;
171  } else {// full bitstream output
172  overlap[slr] = true;
173  }
174  }
175  for(int slr = 0 ; slr < numberOfSLRs ; slr++){
176  if(overlap[slr])
177  writeBitstreamMainSingleSLR(fout, slr, cmdRect);
178  else
179  writeBitstreamMainEmptySLR(fout, slr);
180  }
181  for(int slr = numberOfSLRs - 2 ; slr >= 0 ; slr--){
182  if(overlap[slr])
183  outputBitstreamSLRWrapUpSequence(fout, slr, (!selectedOptions.partialNotFull), loadedBitstreamEndianness);
184  else
185  outputBitstreamEmptySLRWrapUpSequence(fout, slr, false, loadedBitstreamEndianness);
186  }
187 }
188 
189 inline void writeBitstreamBIT(std::ofstream& fout, Rect2D cmdRect)
190 {
191  //if needing to ensure all .bit files MUST be bigendian, uncomment next line
192  //ensureSelectedEndianness(Endianness::BE);
193  if(selectedOptions.partialNotFull)
194  designName.append(";PARTIAL=TRUE");
195  designName.append(";bytemanVersion=").append(VERSION).append(":").append(VERSION_BUILD);
196 
198  outputBITheader(fout, loadedBitstreamEndianness);//.bit always big endian
199 
200  outputBitstreamGlobalHeaderSequence(fout, (!selectedOptions.partialNotFull), loadedBitstreamEndianness);
201  writeBitstreamMain(fout, cmdRect);
202  outputBitstreamGlobalFooterSequence(fout, (!selectedOptions.partialNotFull), loadedBitstreamEndianness);
203 
204  outputBITheaderLengthField(fout, loadedBitstreamEndianness);
205 }
206 
207 inline void writeBitstreamBIN(std::ofstream& fout, Rect2D cmdRect)
208 {
209  outputBitstreamGlobalHeaderSequence(fout, (!selectedOptions.partialNotFull), loadedBitstreamEndianness);
210  writeBitstreamMain(fout, cmdRect);
211  outputBitstreamGlobalFooterSequence(fout, (!selectedOptions.partialNotFull), loadedBitstreamEndianness);
212 }
Endianness
< Endianness in byteman is represented not only by big/little endian, but also by potential bit swapp...
Definition: Endianness.h:47
void XCAP_writeRegister(std::ofstream &fout, XCAP::Register reg, int writeValue, Endianness e)
Generate the encoding for writing a CAP register and write it to file ofstream.
Definition: inlineCAP.h:382
uint32_t XCAP_getSyncInstruction()
Generate and return the encoding for a SYNC instruction.
Definition: inlineCAP.h:430
void XCAP_writeCommand(std::ofstream &fout, XCAP::Command cmd, Endianness e)
Generate the encoding for writing a CAP command and write it to file ofstream.
Definition: inlineCAP.h:390
void XCAP_writeFDRI(std::ofstream &fout, int wordCount, Endianness e)
Generate and write an FDRI command. Always uses type 2 command for simplicity.
Definition: inlineCAP.h:417
void XCAP_writeNOP(std::ofstream &fout, int cnt, int payload, Endianness e)
Generate the encoding for NOP instructions and write them to file ofstream.
Definition: inlineCAP.h:352
uint32_t XCAP_getFAR(int slr, int blockType, int globalRowAddress, int columnAddress, int minorAddress)
Definition: inlineFAR.h:174
void writeBitstreamBIT(std::ofstream &fout, Rect2D cmdRect)
Definition: inlineOutput.h:189
void outputBITheader(std::ofstream &fout, Endianness e)
Definition: inlineOutput.h:34
void updateDateAndTime()
Definition: inlineOutput.h:17
void writeBitstreamBIN(std::ofstream &fout, Rect2D cmdRect)
Definition: inlineOutput.h:207
void writeBitstreamMain(std::ofstream &fout, Rect2D cmdRect)
Definition: inlineOutput.h:152
void writeBitstreamMainEmptySLR(std::ofstream &fout, int slr)
Definition: inlineOutput.h:71
void writeBitstreamMainSingleSLR(std::ofstream &fout, int slr, Rect2D cmdRect)
Definition: inlineOutput.h:129
void outputCAPheaderConstant(std::ofstream &fout, Endianness e)
Definition: inlineOutput.h:60
void outputBITheaderLengthField(std::ofstream &fout, Endianness e)
Definition: inlineOutput.h:52
void outputBITheader16bString(std::ofstream &fout, Endianness e, std::string s)
Definition: inlineOutput.h:29
void writeBitstreamMainSingleRegion(std::ofstream &fout, int slr, Rect2D writeRect)
Definition: inlineOutput.h:77
std::string to_string(Endianness e)
Definition: Endianness.h:56
void writeString(std::ofstream &fout, std::string writeString, size_t outputSize=0)
Definition: FileIO.h:332
void write16(std::ofstream &fout, uint16_t writeValue, Endianness e=Endianness::NATIVE)
Definition: FileIO.h:432
void write8(std::ofstream &fout, uint8_t writeValue, Endianness e=Endianness::NATIVE)
Definition: FileIO.h:445
void write32(std::ofstream &fout, uint32_t writeValue, Endianness e=Endianness::NATIVE)
Definition: FileIO.h:419
bool empty(Rect2D r)
Definition: Coords.h:48
Rect2D getOverlap(Rect2D r1, Rect2D r2)
Definition: Coords.h:34
int col
Definition: Coords.h:25
int row
Definition: Coords.h:24
Definition: Coords.h:29
Coord2D size
Definition: Coords.h:31
Coord2D position
Definition: Coords.h:30