byteman  1.3 (Build #225)
Bitstream relocation and manipulation tool
XUS_Output.cpp
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 #include<iostream>
18 #include<string>
19 #include<stdexcept>
20 #include<fstream>
21 #include<cstring>
22 
23 #include "XilinxUltraScale.h"
24 #include "../../../Common/FileIO.h"
25 #include "../../../Common/str.h"
26 
27 using namespace std;
28 
29 void XilinxUltraScale::outputBitstreamGlobalHeaderSequence(ofstream& fout, bool fullBitstream, Endianness e)
30 {
31 
32 }
33 
34 void XilinxUltraScale::outputBitstreamGlobalFooterSequence(ofstream& fout, bool fullBitstream, Endianness e)
35 {
36  XCAP_writeNOP(fout, 400, 0, loadedBitstreamEndianness);
37 }
38 
39 void XilinxUltraScale::outputBitstreamSLRHeaderBitstreamSequence(ofstream& fout, int slr, bool fullBitstream, Endianness e)
40 {
41  XCAP_writeNOP(fout, 132, 0, e);
43  XCAP_writeNOP(fout, 2, 0, e);
44  //XCAP_writeRegister(fout, XCAP::Register::MAGIC0, 0x00000000);
45  XCAP_writeRegister(fout, XCAP::Register::IDCODE, SLRinfo[slr].IDCODE, e);
46  uint32_t cor0 = XCAP_getCOR0value(7, 0, 0, 0, 0, 0, 0, DONE_CYCLE::Phase4, MATCH_CYCLE::NoWait, LOCK_CYCLE::NoWait, GTS_CYCLE::Phase5, GWE_CYCLE::Phase6); // no clue where the '7' comes from (ask Vivado)
48  //XCAP_writeRegister(fout, XCAP::Register::COR1, 0x00400000);
49  //XCAP_writeCommand(fout, XCAP::Command::SWITCH, e);
50  //Optional Shutdown + 1 NOP ?
51  XCAP_writeNOP(fout, 1, 0, e);
53  XCAP_writeNOP(fout, 20, 0, e);
55  XCAP_writeNOP(fout, 100, 0, e);
57  uint32_t ctrl0 = XCAP_getCTRL0value(0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0); //disable fallback bitstream, enable overwriting of LUTs
58  XCAP_writeMaskAndRegister(fout, XCAP::Register::CTRL0, ctrl0, ctrl0, e);
59  //XCAP_writeMaskAndRegister(fout, XCAP::Register::CTRL1, 0x20000, 0, e);// TODO: why does vivado do that? : bit at 0x20000 is undocumented
60 }
61 
62 void XilinxUltraScale::outputBitstreamSLRFooterBitstreamSequence(ofstream& fout, int slr, bool fullBitstream, Endianness e)
63 {
64  if(fullBitstream) // Add GRESTORE since it is full device bitstream.
65  {
67  XCAP_writeNOP(fout, 2, 0, e);
69  XCAP_writeNOP(fout, 20, 0, e);
70  }
71 
72  XCAP_writeNOP(fout, 1, 0, e);
73  uint32_t ctrl0 = XCAP_getCTRL0value(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0);
74  XCAP_writeMaskAndRegister(fout, XCAP::Register::CTRL0, ctrl0, ctrl0, e);
75 
77  XCAP_writeNOP(fout, 20, 0, e);
78 
79 
81  XCAP_writeNOP(fout, 1, 0, e);
82 
84  XCAP_writeNOP(fout, 1, 0, e);
86  XCAP_writeNOP(fout, 2, 0, e);
88  XCAP_writeNOP(fout, 16, 0, e);
89 }
90 
91 void XilinxUltraScale::outputBitstreamSLRHeaderAfterBitstreamSequence(ofstream& fout, int slr, bool fullBitstream, Endianness e)
92 {
93  if((slr + 1) < numberOfSLRs) { // If there are more SLRs, output the magic
94  XCAP_writeNOP(fout, 400, 0, e);
95  XCAP_writeSYNQ(fout, e);
96  XCAP_writeNOP(fout, 1, 0, e);
97  //Optional Shutdown + 1 NOP ?
99  XCAP_writeNOP(fout, 2, 0, e);
100 
102  slrMagicInstrLocation[slr] = fout.tellp();
103  XCAP_writeType2(fout, 0, e);
104  }
105 }
106 
107 void XilinxUltraScale::outputBitstreamSLRWrapUpSequence(ofstream& fout, int slr, bool fullBitstream, Endianness e)
108 {
109  streamoff currentStreamHead = fout.tellp();
110  streamoff bypassSize = (currentStreamHead - slrMagicInstrLocation[slr])/4 - 1;
111  fout.seekp(slrMagicInstrLocation[slr]);
112  FileIO::write32(fout, static_cast<uint32_t>(bypassSize), e);
113  fout.seekp(currentStreamHead);
114  XCAP_writeNOP(fout, 16, 0, loadedBitstreamEndianness);
115  XCAP_writeCommand(fout, XCAP::Command::START, loadedBitstreamEndianness);
116  XCAP_writeNOP(fout, 1, 0, loadedBitstreamEndianness);
117  XCAP_writeCommand(fout, XCAP::Command::DESYNC, loadedBitstreamEndianness);
118  XCAP_writeNOP(fout, 16, 0, loadedBitstreamEndianness);
119 }
120 
121 void XilinxUltraScale::outputBitstreamEmptySLRHeaderSequence(ofstream& fout, int slr, bool fullBitstream, Endianness e)
122 {
123  XCAP_writeNOP(fout, 132, 0, e);
124  uint32_t cor0 = XCAP_getCOR0value(7, 0, 0, 0, 0, 0, 0, DONE_CYCLE::Phase4, MATCH_CYCLE::NoWait, LOCK_CYCLE::NoWait, GTS_CYCLE::Phase5, GWE_CYCLE::Phase6); // no clue where the '7' comes from (ask Vivado)
126  //Optional Shutdown + 1 NOP ?
128  XCAP_writeNOP(fout, 2, 0, e);
129  XCAP_writeRegister(fout, XCAP::Register::IDCODE, SLRinfo[slr].IDCODE, e);
131 
132  if((slr + 1) < numberOfSLRs) { // If there are more SLRs, output the magic
134  slrMagicInstrLocation[slr] = fout.tellp();
135  XCAP_writeType2(fout, 0, e);
136  }
137 }
138 
139 void XilinxUltraScale::outputBitstreamEmptySLRWrapUpSequence(ofstream& fout, int slr, bool fullBitstream, Endianness e)
140 {
141  streamoff currentStreamHead = fout.tellp();
142  streamoff bypassSize = (currentStreamHead - slrMagicInstrLocation[slr])/4 - 1;
143  fout.seekp(slrMagicInstrLocation[slr]);
144  FileIO::write32(fout, static_cast<uint32_t>(bypassSize), e);
145  fout.seekp(currentStreamHead);
146  XCAP_writeNOP(fout, 16, 0, loadedBitstreamEndianness);
147  XCAP_writeCommand(fout, XCAP::Command::START, loadedBitstreamEndianness);
148  XCAP_writeNOP(fout, 1, 0, loadedBitstreamEndianness);
149  XCAP_writeCommand(fout, XCAP::Command::DESYNC, loadedBitstreamEndianness);
150  XCAP_writeNOP(fout, 16, 0, loadedBitstreamEndianness);
151 }
152 
153 /**************************************************************************/
160 void XilinxUltraScale::writeBitstream(string filename, string params, Rect2D cmdRect)
161 {
162  size_t dotpos = filename.rfind(".");
163  if(dotpos == string::npos)
164  throw runtime_error(string("Invalid file name: \"").append(filename).append("\"!\n"));
165  designName = filename.substr(0, dotpos);
166 
167  log("Writing Xilinx UltraScale bitstream to file \"" + filename + "\":");
168 
169  parseParams(params);
170 
171  if(selectedOptions.partialNotFull) {
172  if((cmdRect.position.row % XUS_CLB_PER_CLOCK_REGION != 0) || (cmdRect.size.row % XUS_CLB_PER_CLOCK_REGION != 0))
173  throw runtime_error(string("Currently only full clock region height relocations are supported (use row numbers multiple of ").append(to_string(XUS_CLB_PER_CLOCK_REGION)).append("."));
174  if(cmdRect.size.row <= 0 || cmdRect.size.col <= 0)
175  throw runtime_error("Invalid output size dimentions.");
176  }
177 
178  ofstream fout (filename, ofstream::binary | ofstream::trunc);
179  if(!fout.good())
180  throw runtime_error(string("Could not open file: \"").append(filename).append("\"!\n"));
181  if(str::iff::stringEndsWith(filename, ".bit"))
182  writeBitstreamBIT(fout, cmdRect);
183  else if(str::iff::stringEndsWith(filename, ".bin"))
184  writeBitstreamBIN(fout, cmdRect);
185  else
186  throw runtime_error(string("Unknown Xilinx UltraScale file format tried to be written.\n"));
187  fout.close();
188  log("Xilinx UltraScale bitstream file \"" + filename + "\" written successfully.");
189 }
Endianness
< Endianness in byteman is represented not only by big/little endian, but also by potential bit swapp...
Definition: Endianness.h:47
#define XUS_CLB_PER_CLOCK_REGION
Definition: XUS_Fabric.h:42
void outputBitstreamGlobalHeaderSequence(std::ofstream &, bool, Endianness) override
Written by outputBitstreamSLRHeaderAfterBitstreamSequence(), outputBitstreamEmptySLRHeaderSequence() ...
Definition: XUS_Output.cpp:29
void outputBitstreamEmptySLRWrapUpSequence(std::ofstream &, int, bool, Endianness) override
Definition: XUS_Output.cpp:139
void outputBitstreamGlobalFooterSequence(std::ofstream &, bool, Endianness) override
Definition: XUS_Output.cpp:34
void outputBitstreamSLRWrapUpSequence(std::ofstream &, int, bool, Endianness) override
Definition: XUS_Output.cpp:107
void outputBitstreamSLRHeaderAfterBitstreamSequence(std::ofstream &, int, bool, Endianness) override
Definition: XUS_Output.cpp:91
void outputBitstreamEmptySLRHeaderSequence(std::ofstream &, int, bool, Endianness) override
Definition: XUS_Output.cpp:121
void outputBitstreamSLRHeaderBitstreamSequence(std::ofstream &, int, bool, Endianness) override
Definition: XUS_Output.cpp:39
void writeBitstream(std::string, std::string, Rect2D)
Definition: XUS_Output.cpp:160
void outputBitstreamSLRFooterBitstreamSequence(std::ofstream &, int, bool, Endianness) override
Definition: XUS_Output.cpp:62
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
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_writeSYNQ(std::ofstream &fout, Endianness e)
Generate and write an SYNQ command.
Definition: inlineCAP.h:436
void XCAP_writeSelectRegister(std::ofstream &fout, XCAP::Register reg, Endianness e)
Generate the encoding for "selecting" a CAP register and write it to file ofstream.
Definition: inlineCAP.h:368
void XCAP_writeType2(std::ofstream &fout, int wordCount, Endianness e)
Generate and write only a type 2 FDRI command.
Definition: inlineCAP.h:410
void XCAP_writeMaskAndRegister(std::ofstream &fout, XCAP::Register reg, int writeMask, int writeValue, Endianness e)
Generate the encoding for writing a CAP register with a mask and write it to file ofstream.
Definition: inlineCAP.h:396
uint32_t XCAP_getCOR0value(int Reserved_31_27, int ECLK_EN, int Reserved_25, int DRIVE_DONE, int Reserved_23, int OSCFSEL, int Reserved_16_15, DONE_CYCLE selDONE_CYCLE, MATCH_CYCLE selMATCH_CYCLE, LOCK_CYCLE selLOCK_CYCLE, GTS_CYCLE selGTS_CYCLE, GWE_CYCLE selGWE_CYCLE)
Generate COR0 register write value.
Definition: inlineCAP.h:493
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_getCTRL0value(int EFUSE_KEY, int ICAP_SELECT, int Reserved_29_13, int OverTempShutDown, int Reserved_11, int ConfigFallback, int Reserved_9, int GLUTMASK_B, int Reserved_7, int DEC, int SBITS, int PERSIST, int Reserved_2_1, int GTS_USR_B)
Generate CTRL0 register write value.
Definition: inlineCAP.h:513
uint32_t XCAP_getFarFarInstruction()
Generate and return the encoding for a Far FAR instruction.
Definition: inlineFAR.h:194
void writeBitstreamBIT(std::ofstream &fout, Rect2D cmdRect)
Definition: inlineOutput.h:189
void writeBitstreamBIN(std::ofstream &fout, Rect2D cmdRect)
Definition: inlineOutput.h:207
void parseParams(std::string params)
std::string to_string(Endianness e)
Definition: Endianness.h:56
void write32(std::ofstream &fout, uint32_t writeValue, Endianness e=Endianness::NATIVE)
Definition: FileIO.h:419
bool stringEndsWith(std::string checkedString)
Returns false. End of recursion for template.
Definition: iff.h:32
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