<86>Mar 18 14:34:20 userdel[2517986]: delete user 'rooter' <86>Mar 18 14:34:20 groupadd[2518040]: group added to /etc/group: name=rooter, GID=705 <86>Mar 18 14:34:20 groupadd[2518040]: group added to /etc/gshadow: name=rooter <86>Mar 18 14:34:20 groupadd[2518040]: new group: name=rooter, GID=705 <86>Mar 18 14:34:20 useradd[2518078]: new user: name=rooter, UID=705, GID=705, home=/root, shell=/bin/bash <86>Mar 18 14:34:20 userdel[2518101]: delete user 'builder' <86>Mar 18 14:34:20 groupadd[2518148]: group added to /etc/group: name=builder, GID=706 <86>Mar 18 14:34:20 groupadd[2518148]: group added to /etc/gshadow: name=builder <86>Mar 18 14:34:20 groupadd[2518148]: new group: name=builder, GID=706 <86>Mar 18 14:34:20 useradd[2518183]: new user: name=builder, UID=706, GID=706, home=/usr/src, shell=/bin/bash <13>Mar 18 14:34:23 rpmi: libgdbm-1.8.3-alt10 1454943334 installed <13>Mar 18 14:34:23 rpmi: libexpat-2.2.10-alt1 sisyphus+259966.100.1.1 1602824518 installed <13>Mar 18 14:34:23 rpmi: libp11-kit-0.23.15-alt2 sisyphus+252784.100.2.2 1591274901 installed <13>Mar 18 14:34:23 rpmi: libtasn1-4.16.0-alt1 sisyphus+245480.100.1.1 1580825062 installed <13>Mar 18 14:34:23 rpmi: rpm-macros-alternatives-0.5.1-alt1 sisyphus+226946.100.1.1 1554830426 installed <13>Mar 18 14:34:23 rpmi: alternatives-0.5.1-alt1 sisyphus+226946.100.1.1 1554830426 installed <13>Mar 18 14:34:23 rpmi: ca-certificates-2021.01.27-alt1 sisyphus+265371.200.1.1 1611759824 installed <13>Mar 18 14:34:23 rpmi: ca-trust-0.1.2-alt1 sisyphus+233348.100.1.1 1561653823 installed <13>Mar 18 14:34:23 rpmi: p11-kit-trust-0.23.15-alt2 sisyphus+252784.100.2.2 1591274901 installed <13>Mar 18 14:34:24 rpmi: libcrypto1.1-1.1.1j-alt1 sisyphus+267718.100.1.1 1615557676 installed <13>Mar 18 14:34:24 rpmi: libssl1.1-1.1.1j-alt1 sisyphus+267718.100.1.1 1615557676 installed <13>Mar 18 14:34:24 rpmi: python3-3.9.2-alt1 sisyphus+267062.100.1.1 1614381721 installed <13>Mar 18 14:34:24 rpmi: python3-base-3.9.2-alt1 sisyphus+267062.100.1.1 1614381721 installed <13>Mar 18 14:34:25 rpmi: libpython3-3.9.2-alt1 sisyphus+267062.100.1.1 1614381721 installed <13>Mar 18 14:34:25 rpmi: tests-for-installed-python3-pkgs-0.1.13.1-alt2 1535450458 installed <13>Mar 18 14:34:25 rpmi: rpm-build-python3-0.1.13.1-alt2 1535450458 installed <13>Mar 18 14:34:28 rpmi: libusb-1.0.23-alt1 sisyphus+237317.100.1.1 1568059905 installed <13>Mar 18 14:34:28 rpmi: libftdi1-1.4-alt5 sisyphus+253270.100.1.1 1591942165 installed <13>Mar 18 14:34:28 rpmi: libusb-devel-1.0.23-alt1 sisyphus+237317.100.1.1 1568059905 installed <13>Mar 18 14:34:28 rpmi: gcc-c++-common-1.4.27-alt1 sisyphus+262033.600.7.2 1607340230 installed <13>Mar 18 14:34:28 rpmi: libstdc++10-devel-10.2.1-alt3 sisyphus+267829.100.1.1 1615808579 installed <13>Mar 18 14:34:29 rpmi: gcc10-c++-10.2.1-alt3 sisyphus+267829.100.1.1 1615808579 installed <13>Mar 18 14:34:29 rpmi: gcc-c++-10-alt1 sisyphus+263054.200.3.1 1607516810 installed <13>Mar 18 14:34:29 rpmi: libftdi1-devel-1.4-alt5 sisyphus+253270.100.1.1 1591942165 installed Building target platforms: i586 Building for target i586 Wrote: /usr/src/in/nosrpm/icestorm-0.0.0.618.gf029975-alt2.nosrc.rpm (w1.gzdio) Installing icestorm-0.0.0.618.gf029975-alt2.src.rpm Building target platforms: i586 Building for target i586 Executing(%prep): /bin/sh -e /usr/src/tmp/rpm-tmp.79100 + umask 022 + /bin/mkdir -p /usr/src/RPM/BUILD + cd /usr/src/RPM/BUILD + cd /usr/src/RPM/BUILD + rm -rf icestorm-0.0.0.618.gf029975 + echo 'Source #0 (icestorm-0.0.0.618.gf029975.tar):' Source #0 (icestorm-0.0.0.618.gf029975.tar): + /bin/tar -xf /usr/src/RPM/SOURCES/icestorm-0.0.0.618.gf029975.tar + cd icestorm-0.0.0.618.gf029975 + /bin/chmod -c -Rf u+rwX,go-w . + exit 0 Executing(%build): /bin/sh -e /usr/src/tmp/rpm-tmp.79100 + umask 022 + /bin/mkdir -p /usr/src/RPM/BUILD + cd /usr/src/RPM/BUILD + cd icestorm-0.0.0.618.gf029975 ++ pkg-config --cflags libftdi1 ++ pkg-config --libs libftdi1 + make -j8 CC=gcc CXX=g++ 'CFLAGS=-pipe -frecord-gcc-switches -Wall -g -O2 -march=i586 -mtune=generic -Wextra -I/usr/include/libftdi1 -I/usr/include/libusb-1.0' 'CXXFLAGS=-pipe -frecord-gcc-switches -Wall -g -O2 -march=i586 -mtune=generic -Wextra' 'LDLIBS=-lftdi1 -lusb-1.0 -lm' for dir in icebox icepack iceprog icemulti icepll icetime icebram; do \ make -C $dir all || exit; \ done make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icebox' python3 icebox_chipdb.py -3 > chipdb-384.new mv chipdb-384.new chipdb-384.txt make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icebox' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icebox' python3 icebox_chipdb.py > chipdb-1k.new mv chipdb-1k.new chipdb-1k.txt make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icebox' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icebox' python3 icebox_chipdb.py -4 > chipdb-lm4k.new mv chipdb-lm4k.new chipdb-lm4k.txt make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icebox' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icebox' python3 icebox_chipdb.py -5 > chipdb-5k.new mv chipdb-5k.new chipdb-5k.txt make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icebox' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icebox' python3 icebox_chipdb.py -8 > chipdb-8k.new mv chipdb-8k.new chipdb-8k.txt make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icebox' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icepack' g++ -pipe -frecord-gcc-switches -Wall -g -O2 -march=i586 -mtune=generic -Wextra -c -o icepack.o icepack.cc icepack.cc: In member function 'void FpgaConfig::write_ascii(std::ostream&) const': icepack.cc:53:41: warning: format '%lu' expects argument of type 'long unsigned int', but argument 6 has type 'std::vector >::size_type' {aka 'unsigned int'} [-Wformat=] 53 | #define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 54 | #define panic(fmt, ...) do { fprintf(stderr, "Internal Error at %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__); abort(); } while (0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 55 | | 56 | string vstringf(const char *fmt, va_list ap) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 57 | { | ~ 58 | string string; | ~~~~~~~~~~~~~~ 59 | char *str = NULL; | ~~~~~~~~~~~~~~~~~ 60 | | 61 | #ifdef _WIN32 | ~~~~~~~~~~~~~ 62 | int sz = 64, rc; | ~~~~~~~~~~~~~~~~ 63 | while (1) { | ~~~~~~~~~~~ 64 | va_list apc; | ~~~~~~~~~~~~ 65 | va_copy(apc, ap); | ~~~~~~~~~~~~~~~~~ 66 | str = (char*)realloc(str, sz); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 67 | rc = vsnprintf(str, sz, fmt, apc); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | va_end(apc); | ~~~~~~~~~~~~ 69 | if (rc >= 0 && rc < sz) | ~~~~~~~~~~~~~~~~~~~~~~~ 70 | break; | ~~~~~~ 71 | sz *= 2; | ~~~~~~~~ 72 | } | ~ 73 | #else | ~~~~~ 74 | if (vasprintf(&str, fmt, ap) < 0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 75 | str = NULL; | ~~~~~~~~~~~ 76 | #endif | ~~~~~~ 77 | | 78 | if (str != NULL) { | ~~~~~~~~~~~~~~~~~~ 79 | string = str; | ~~~~~~~~~~~~~ 80 | free(str); | ~~~~~~~~~~ 81 | } | ~ 82 | | 83 | return string; | ~~~~~~~~~~~~~~ 84 | } | ~ 85 | | 86 | string stringf(const char *fmt, ...) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 87 | { | ~ 88 | string string; | ~~~~~~~~~~~~~~ 89 | va_list ap; | ~~~~~~~~~~~ 90 | | 91 | va_start(ap, fmt); | ~~~~~~~~~~~~~~~~~~ 92 | string = vstringf(fmt, ap); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 93 | va_end(ap); | ~~~~~~~~~~~ 94 | | 95 | return string; | ~~~~~~~~~~~~~~ 96 | } | ~ 97 | | 98 | // ================================================================== | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 99 | // FpgaConfig stuff | ~~~~~~~~~~~~~~~~~~~ 100 | | 101 | struct FpgaConfig | ~~~~~~~~~~~~~~~~~ 102 | { | ~ 103 | string device; | ~~~~~~~~~~~~~~ 104 | string freqrange; | ~~~~~~~~~~~~~~~~~ 105 | string nosleep; | ~~~~~~~~~~~~~~~ 106 | string warmboot; | ~~~~~~~~~~~~~~~~ 107 | | 108 | // cram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 109 | int cram_width, cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 110 | vector>> cram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 111 | | 112 | // bram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 113 | int bram_width, bram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 114 | vector>> bram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 115 | | 116 | // data before preamble | ~~~~~~~~~~~~~~~~~~~~~~~ 117 | vector initblop; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 118 | | 119 | // bitstream i/o | ~~~~~~~~~~~~~~~~ 120 | void read_bits(std::istream &ifs); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 121 | void write_bits(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 122 | | 123 | // icebox i/o | ~~~~~~~~~~~~~ 124 | void read_ascii(std::istream &ifs, bool nosleep); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 125 | void write_ascii(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 126 | | 127 | // netpbm i/o | ~~~~~~~~~~~~~ 128 | void write_cram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 129 | void write_bram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 130 | | 131 | // query chip type metadata | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 132 | int chip_width() const; | ~~~~~~~~~~~~~~~~~~~~~~~ 133 | int chip_height() const; | ~~~~~~~~~~~~~~~~~~~~~~~~ 134 | vector chip_cols() const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 135 | | 136 | // query tile metadata | ~~~~~~~~~~~~~~~~~~~~~~ 137 | string tile_type(int x, int y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 138 | int tile_width(const string &type) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 139 | | 140 | // cram bit manipulation | ~~~~~~~~~~~~~~~~~~~~~~~~ 141 | void cram_clear(); | ~~~~~~~~~~~~~~~~~~ 142 | void cram_fill_tiles(); | ~~~~~~~~~~~~~~~~~~~~~~~ 143 | void cram_checkerboard(int m = 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 144 | }; | ~~ 145 | | 146 | struct CramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 147 | { | ~ 148 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 149 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 150 | | 151 | string tile_type; | ~~~~~~~~~~~~~~~~~ 152 | int tile_width; | ~~~~~~~~~~~~~~~ 153 | int column_width; | ~~~~~~~~~~~~~~~~~ 154 | | 155 | bool left_right_io; | ~~~~~~~~~~~~~~~~~~~ 156 | bool right_half; | ~~~~~~~~~~~~~~~~ 157 | bool top_half; | ~~~~~~~~~~~~~~ 158 | | 159 | int bank_num; | ~~~~~~~~~~~~~ 160 | int bank_tx; | ~~~~~~~~~~~~ 161 | int bank_ty; | ~~~~~~~~~~~~ 162 | int bank_xoff; | ~~~~~~~~~~~~~~ 163 | int bank_yoff; | ~~~~~~~~~~~~~~ 164 | | 165 | CramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 166 | void get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 167 | }; | ~~ 168 | | 169 | struct BramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 170 | { | ~ 171 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 172 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 173 | | 174 | int bank_num; | ~~~~~~~~~~~~~ 175 | int bank_off; | ~~~~~~~~~~~~~ 176 | | 177 | BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 178 | void get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 179 | }; | ~~ 180 | | 181 | static void update_crc16(uint16_t &crc, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 182 | { | ~ 183 | // CRC-16-CCITT, Initialize to 0xFFFF, No zero padding | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 184 | for (int i = 7; i >= 0; i--) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 185 | uint16_t xor_value = ((crc >> 15) ^ ((byte >> i) & 1)) ? 0x1021 : 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 186 | crc = (crc << 1) ^ xor_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 187 | } | ~ 188 | } | ~ 189 | | 190 | static uint8_t read_byte(std::istream &ifs, uint16_t &crc_value, int &file_offset) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 191 | { | ~ 192 | int byte = ifs.get(); | ~~~~~~~~~~~~~~~~~~~~~ 193 | | 194 | if (byte < 0) | ~~~~~~~~~~~~~ 195 | error("Unexpected end of file.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 196 | | 197 | file_offset++; | ~~~~~~~~~~~~~~ 198 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 199 | | 200 | return byte; | ~~~~~~~~~~~~ 201 | } | ~ 202 | | 203 | static void write_byte(std::ostream &ofs, uint16_t &crc_value, int &file_offset, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 204 | { | ~ 205 | ofs << byte; | ~~~~~~~~~~~~ 206 | file_offset++; | ~~~~~~~~~~~~~~ 207 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 208 | } | ~ 209 | | 210 | void FpgaConfig::read_bits(std::istream &ifs) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 211 | { | ~ 212 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 213 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 214 | | 215 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 216 | info("Parsing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 217 | | 218 | // skip initial comments until preamble is found | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 219 | | 220 | uint32_t preamble = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 221 | | 222 | while (1) | ~~~~~~~~~ 223 | { | ~ 224 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 225 | preamble = (preamble << 8) | byte; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 226 | if (preamble == 0xffffffff) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 227 | error("No preamble found in bitstream.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 228 | if (preamble == 0x7EAA997E) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 229 | info("Found preamble at offset %d.\n", file_offset-4); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 230 | break; | ~~~~~~ 231 | } | ~ 232 | initblop.push_back(byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 233 | } | ~ 234 | | 235 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 236 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 237 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 238 | | 239 | // main parser loop | ~~~~~~~~~~~~~~~~~~~ 240 | | 241 | int current_bank = 0; | ~~~~~~~~~~~~~~~~~~~~~ 242 | int current_width = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 243 | int current_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 244 | int current_offset = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 245 | bool wakeup = false; | ~~~~~~~~~~~~~~~~~~~~ 246 | | 247 | this->cram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 248 | this->cram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 249 | | 250 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 251 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 252 | | 253 | while (!wakeup) | ~~~~~~~~~~~~~~~ 254 | { | ~ 255 | // one command byte. the lower 4 bits of the command byte specify | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 256 | // the length of the command payload. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 257 | | 258 | uint8_t command = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 259 | uint32_t payload = 0; | ~~~~~~~~~~~~~~~~~~~~~ 260 | | 261 | for (int i = 0; i < (command & 0x0f); i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 262 | payload = (payload << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 263 | | 264 | debug("Next command at offset %d: 0x%02x 0x%0*x\n", file_offset - 1 - (command & 0x0f), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 265 | command, 2*(command & 0x0f), payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 266 | | 267 | uint16_t end_token; | ~~~~~~~~~~~~~~~~~~~ 268 | | 269 | switch (command & 0xf0) | ~~~~~~~~~~~~~~~~~~~~~~~ 270 | { | ~ 271 | case 0x00: | ~~~~~~~~~~ 272 | switch (payload) | ~~~~~~~~~~~~~~~~ 273 | { | ~ 274 | case 0x01: | ~~~~~~~~~~ 275 | info("CRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 276 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 277 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 278 | | 279 | this->cram_width = std::max(this->cram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 280 | this->cram_height = std::max(this->cram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 281 | | 282 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 283 | this->cram[current_bank].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 284 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 285 | this->cram[current_bank][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 286 | | 287 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 288 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 289 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 290 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 291 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 292 | this->cram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 293 | } | ~ 294 | } | ~ 295 | | 296 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 297 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 298 | if (end_token) | ~~~~~~~~~~~~~~ 299 | error("Expeded 0x0000 after CRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 300 | break; | ~~~~~~ 301 | | 302 | case 0x03: | ~~~~~~~~~~ 303 | info("BRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 304 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 305 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 306 | | 307 | this->bram_width = std::max(this->bram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 308 | this->bram_height = std::max(this->bram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 309 | | 310 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 311 | this->bram[current_bank].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 312 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 313 | this->bram[current_bank][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 314 | | 315 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 316 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 317 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 318 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 319 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 320 | this->bram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 321 | } | ~ 322 | } | ~ 323 | | 324 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 325 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 326 | if (end_token) | ~~~~~~~~~~~~~~ 327 | error("Expeded 0x0000 after BRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 328 | break; | ~~~~~~ 329 | | 330 | case 0x05: | ~~~~~~~~~~ 331 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 332 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 333 | break; | ~~~~~~ 334 | | 335 | case 0x06: | ~~~~~~~~~~ 336 | info("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~ 337 | wakeup = true; | ~~~~~~~~~~~~~~ 338 | break; | ~~~~~~ 339 | | 340 | default: | ~~~~~~~~ 341 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 342 | } | ~ 343 | break; | ~~~~~~ 344 | | 345 | case 0x10: | ~~~~~~~~~~ 346 | current_bank = payload; | ~~~~~~~~~~~~~~~~~~~~~~~ 347 | debug("Set bank to %d.\n", current_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 348 | break; | ~~~~~~ 349 | | 350 | case 0x20: | ~~~~~~~~~~ 351 | if (crc_value != 0) | ~~~~~~~~~~~~~~~~~~~ 352 | error("CRC Check FAILED.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 353 | info("CRC Check OK.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~ 354 | break; | ~~~~~~ 355 | | 356 | case 0x50: | ~~~~~~~~~~ 357 | if (payload == 0) | ~~~~~~~~~~~~~~~~~ 358 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 359 | else if (payload == 1) | ~~~~~~~~~~~~~~~~~~~~~~ 360 | this->freqrange = "medium"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 361 | else if (payload == 2) | ~~~~~~~~~~~~~~~~~~~~~~ 362 | this->freqrange = "high"; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 363 | else | ~~~~ 364 | error("Unknown freqrange payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 365 | info("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 366 | break; | ~~~~~~ 367 | | 368 | case 0x60: | ~~~~~~~~~~ 369 | current_width = payload + 1; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 370 | debug("Setting bank width to %d.\n", current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 371 | break; | ~~~~~~ 372 | | 373 | case 0x70: | ~~~~~~~~~~ 374 | current_height = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 375 | debug("Setting bank height to %d.\n", current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 376 | break; | ~~~~~~ 377 | | 378 | case 0x80: | ~~~~~~~~~~ 379 | current_offset = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 380 | debug("Setting bank offset to %d.\n", current_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 381 | break; | ~~~~~~ 382 | | 383 | case 0x90: | ~~~~~~~~~~ 384 | switch(payload) | ~~~~~~~~~~~~~~~ 385 | { | ~ 386 | case 0: | ~~~~~~~ 387 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 388 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 389 | break; | ~~~~~~ 390 | case 1: | ~~~~~~~ 391 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 392 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 393 | break; | ~~~~~~ 394 | case 32: | ~~~~~~~~ 395 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 396 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 397 | break; | ~~~~~~ 398 | case 33: | ~~~~~~~~ 399 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 400 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 401 | break; | ~~~~~~ 402 | default: | ~~~~~~~~ 403 | error("Unknown warmboot/nosleep payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 404 | } | ~ 405 | info("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 406 | break; | ~~~~~~ 407 | | 408 | default: | ~~~~~~~~ 409 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 410 | } | ~ 411 | } | ~ 412 | | 413 | if (this->cram_width == 182 && this->cram_height == 80) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 414 | this->device = "384"; | ~~~~~~~~~~~~~~~~~~~~~ 415 | else if (this->cram_width == 332 && this->cram_height == 144) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 416 | this->device = "1k"; | ~~~~~~~~~~~~~~~~~~~~ 417 | else if (this->cram_width == 872 && this->cram_height == 272) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 418 | this->device = "8k"; | ~~~~~~~~~~~~~~~~~~~~ 419 | else if (this->cram_width == 692 && this->cram_height == 336) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 420 | this->device = "5k"; | ~~~~~~~~~~~~~~~~~~~~ 421 | else if (this->cram_width == 692 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 422 | this->device = "u4k"; | ~~~~~~~~~~~~~~~~~~~~~ 423 | else if (this->cram_width == 656 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 424 | this->device = "lm4k"; | ~~~~~~~~~~~~~~~~~~~~~~ 425 | else | ~~~~ 426 | error("Failed to detect chip type.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 427 | | 428 | info("Chip type is '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 429 | } | ~ 430 | | 431 | void FpgaConfig::write_bits(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 432 | { | ~ 433 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 434 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 435 | | 436 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 437 | info("Writing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 438 | | 439 | for (auto byte : this->initblop) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 440 | ofs << byte; | ~~~~~~~~~~~~ 441 | | 442 | debug("Writing preamble.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 443 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 444 | write_byte(ofs, crc_value, file_offset, 0xAA); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 445 | write_byte(ofs, crc_value, file_offset, 0x99); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 446 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 447 | | 448 | debug("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 449 | write_byte(ofs, crc_value, file_offset, 0x51); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 450 | if (this->freqrange == "low") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 451 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 452 | else if (this->freqrange == "medium") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 453 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 454 | else if (this->freqrange == "high") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 455 | write_byte(ofs, crc_value, file_offset, 0x02); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 456 | else | ~~~~ 457 | error("Unknown freqrange '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 458 | | 459 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 460 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 461 | write_byte(ofs, crc_value, file_offset, 0x05); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 462 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 463 | | 464 | { | ~ 465 | uint8_t nosleep_flag; | ~~~~~~~~~~~~~~~~~~~~~ 466 | debug("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 467 | write_byte(ofs, crc_value, file_offset, 0x92); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 468 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 469 | | 470 | if (this->nosleep == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 471 | nosleep_flag = 0; | ~~~~~~~~~~~~~~~~~ 472 | else if (this->nosleep == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 473 | nosleep_flag = 1; | ~~~~~~~~~~~~~~~~~ 474 | else | ~~~~ 475 | error("Unknown nosleep setting '%s'.\n", this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 476 | | 477 | if (this->warmboot == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 478 | write_byte(ofs, crc_value, file_offset, 0x00 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 479 | else if (this->warmboot == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 480 | write_byte(ofs, crc_value, file_offset, 0x20 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 481 | else | ~~~~ 482 | error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 483 | } | ~ 484 | | 485 | debug("CRAM: Setting bank width to %d.\n", this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 486 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 487 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 488 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 489 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 490 | debug("CRAM: Setting bank height to %d.\n", this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 491 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 492 | write_byte(ofs, crc_value, file_offset, this->cram_height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 493 | write_byte(ofs, crc_value, file_offset, this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 494 | } | ~ 495 | | 496 | debug("CRAM: Setting bank offset to 0.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 497 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 498 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 499 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 500 | | 501 | for (int cram_bank = 0; cram_bank < 4; cram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 502 | { | ~ 503 | vector cram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 504 | int height = this->cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 505 | if(this->device == "5k" && ((cram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 506 | height = height / 2 + 8; | ~~~~~~~~~~~~~~~~~~~~~~~~ 507 | for (int cram_y = 0; cram_y < height; cram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 508 | for (int cram_x = 0; cram_x < this->cram_width; cram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 509 | cram_bits.push_back(this->cram[cram_bank][cram_x][cram_y]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 510 | | 511 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 512 | debug("CRAM: Setting bank height to %d.\n", height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 513 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 514 | write_byte(ofs, crc_value, file_offset, height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 515 | write_byte(ofs, crc_value, file_offset, height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 516 | } | ~ 517 | | 518 | debug("CRAM: Setting bank %d.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 519 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 520 | write_byte(ofs, crc_value, file_offset, cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 521 | | 522 | debug("CRAM: Writing bank %d data.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 523 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 524 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 525 | for (int i = 0; i < int(cram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 526 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 527 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 528 | byte = (byte << 1) | (cram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 529 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 530 | } | ~ 531 | | 532 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 533 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 534 | } | ~ 535 | | 536 | int bram_chunk_size = 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 537 | | 538 | if (this->bram_width && this->bram_height) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 539 | { | ~ 540 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 541 | debug("BRAM: Setting bank width to %d.\n", this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 542 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 543 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 544 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 545 | } | ~ 546 | | 547 | | 548 | debug("BRAM: Setting bank height to %d.\n", this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 549 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 550 | write_byte(ofs, crc_value, file_offset, bram_chunk_size >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 551 | write_byte(ofs, crc_value, file_offset, bram_chunk_size); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 552 | | 553 | for (int bram_bank = 0; bram_bank < 4; bram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 554 | { | ~ 555 | debug("BRAM: Setting bank %d.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 556 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 557 | write_byte(ofs, crc_value, file_offset, bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 558 | | 559 | for (int offset = 0; offset < this->bram_height; offset += bram_chunk_size) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 560 | { | ~ 561 | vector bram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 562 | int width = this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 563 | if(this->device == "5k" && ((bram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 564 | width = width / 2; | ~~~~~~~~~~~~~~~~~~ 565 | for (int bram_y = 0; bram_y < bram_chunk_size; bram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 566 | for (int bram_x = 0; bram_x < width; bram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 567 | bram_bits.push_back(this->bram[bram_bank][bram_x][bram_y+offset]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 568 | | 569 | debug("BRAM: Setting bank offset to %d.\n", offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 570 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 571 | write_byte(ofs, crc_value, file_offset, offset >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 572 | write_byte(ofs, crc_value, file_offset, offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 573 | | 574 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 575 | debug("BRAM: Setting bank width to %d.\n", width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 576 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 577 | write_byte(ofs, crc_value, file_offset, (width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 578 | write_byte(ofs, crc_value, file_offset, (width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 579 | } | ~ 580 | | 581 | | 582 | debug("BRAM: Writing bank %d data.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 583 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 584 | write_byte(ofs, crc_value, file_offset, 0x03); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 585 | for (int i = 0; i < int(bram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 586 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 587 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 588 | byte = (byte << 1) | (bram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 589 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 590 | } | ~ 591 | | 592 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 593 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 594 | } | ~ 595 | } | ~ 596 | } | ~ 597 | | 598 | debug("Writing CRC value.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 599 | write_byte(ofs, crc_value, file_offset, 0x22); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 600 | uint8_t crc_hi = crc_value >> 8, crc_lo = crc_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 601 | write_byte(ofs, crc_value, file_offset, crc_hi); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 602 | write_byte(ofs, crc_value, file_offset, crc_lo); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 603 | | 604 | debug("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~~ 605 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 606 | write_byte(ofs, crc_value, file_offset, 0x06); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 607 | | 608 | debug("Padding byte.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 609 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 610 | } | ~ 611 | | 612 | void FpgaConfig::read_ascii(std::istream &ifs, bool nosleep) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 613 | { | ~ 614 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 615 | info("Parsing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 616 | | 617 | bool got_device = false; | ~~~~~~~~~~~~~~~~~~~~~~~~ 618 | this->cram.clear(); | ~~~~~~~~~~~~~~~~~~~ 619 | this->bram.clear(); | ~~~~~~~~~~~~~~~~~~~ 620 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 621 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 622 | | 623 | bool reuse_line = true; | ~~~~~~~~~~~~~~~~~~~~~~~ 624 | string line, command; | ~~~~~~~~~~~~~~~~~~~~~ 625 | | 626 | while (reuse_line || getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 627 | { | ~ 628 | reuse_line = false; | ~~~~~~~~~~~~~~~~~~~ 629 | | 630 | std::istringstream is(line); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 631 | is >> command; | ~~~~~~~~~~~~~~ 632 | | 633 | if (command.empty()) | ~~~~~~~~~~~~~~~~~~~~ 634 | continue; | ~~~~~~~~~ 635 | | 636 | debug("Next command: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 637 | | 638 | if (command == ".comment") | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 639 | { | ~ 640 | this->initblop.clear(); | ~~~~~~~~~~~~~~~~~~~~~~~ 641 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 642 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 643 | | 644 | while (getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 645 | { | ~ 646 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 647 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 648 | break; | ~~~~~~ 649 | } | ~ 650 | | 651 | for (auto ch : line) | ~~~~~~~~~~~~~~~~~~~~ 652 | this->initblop.push_back(ch); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 653 | this->initblop.push_back(0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 654 | } | ~ 655 | | 656 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 657 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 658 | continue; | ~~~~~~~~~ 659 | } | ~ 660 | | 661 | if (command == ".device") | ~~~~~~~~~~~~~~~~~~~~~~~~~ 662 | { | ~ 663 | if (got_device) | ~~~~~~~~~~~~~~~ 664 | error("More than one .device statement.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 665 | | 666 | is >> this->device; | ~~~~~~~~~~~~~~~~~~~ 667 | | 668 | if (this->device == "384") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 669 | this->cram_width = 182; | ~~~~~~~~~~~~~~~~~~~~~~~ 670 | this->cram_height = 80; | ~~~~~~~~~~~~~~~~~~~~~~~ 671 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 672 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 673 | } else | ~~~~~~ 674 | if (this->device == "1k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 675 | this->cram_width = 332; | ~~~~~~~~~~~~~~~~~~~~~~~ 676 | this->cram_height = 144; | ~~~~~~~~~~~~~~~~~~~~~~~~ 677 | this->bram_width = 64; | ~~~~~~~~~~~~~~~~~~~~~~ 678 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 679 | } else | ~~~~~~ 680 | if (this->device == "8k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 681 | this->cram_width = 872; | ~~~~~~~~~~~~~~~~~~~~~~~ 682 | this->cram_height = 272; | ~~~~~~~~~~~~~~~~~~~~~~~~ 683 | this->bram_width = 128; | ~~~~~~~~~~~~~~~~~~~~~~~ 684 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 685 | } else | ~~~~~~ 686 | if (this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 687 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 688 | this->cram_height = 336; | ~~~~~~~~~~~~~~~~~~~~~~~~ 689 | this->bram_width = 160; | ~~~~~~~~~~~~~~~~~~~~~~~ 690 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 691 | } else | ~~~~~~ 692 | if (this->device == "u4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 693 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 694 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 695 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 696 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 697 | } else | ~~~~~~ 698 | if (this->device == "lm4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 699 | this->cram_width = 656; | ~~~~~~~~~~~~~~~~~~~~~~~ 700 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 701 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 702 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 703 | } else | ~~~~~~ 704 | error("Unsupported chip type '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 705 | | 706 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 707 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 708 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 709 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 710 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 711 | this->cram[i][x].resize(((i % 2) == 1) ? (this->cram_height / 2 + 8) : this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 712 | } | ~ 713 | | 714 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 715 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 716 | int width = ((i % 2) == 1) ? (this->bram_width / 2) : this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 717 | this->bram[i].resize(width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 718 | for (int x = 0; x < width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 719 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 720 | } | ~ 721 | } else { | ~~~~~~~~ 722 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 723 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 724 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 725 | this->cram[i][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 726 | } | ~ 727 | | 728 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 729 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 730 | this->bram[i].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 731 | for (int x = 0; x < this->bram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 732 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 733 | } | ~ 734 | } | ~ 735 | | 736 | | 737 | got_device = true; | ~~~~~~~~~~~~~~~~~~ 738 | continue; | ~~~~~~~~~ 739 | } | ~ 740 | | 741 | if (command == ".warmboot") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 742 | { | ~ 743 | is >> this->warmboot; | ~~~~~~~~~~~~~~~~~~~~~ 744 | | 745 | if (this->warmboot != "disabled" && | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 746 | this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 747 | error("Unknown warmboot setting '%s'.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 748 | this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~ 749 | | 750 | continue; | ~~~~~~~~~ 751 | } | ~ 752 | | 753 | // No ".nosleep" section despite sharing the same byte as .warmboot. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 754 | // ".nosleep" is specified when icepack is invoked, which is too late. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 755 | // So we inject the section based on command line argument. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 756 | if (nosleep) | ~~~~~~~~~~~~ 757 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 758 | else | ~~~~ 759 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 760 | | 761 | if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile" || command.substr(0, 4) == ".dsp" || command == ".ipcon_tile") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 762 | { | ~ 763 | if (!got_device) | ~~~~~~~~~~~~~~~~ 764 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 765 | | 766 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 767 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 768 | | 769 | CramIndexConverter cic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 770 | | 771 | if (("." + cic.tile_type + "_tile") != command) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 772 | error("Got %s statement for %s tile %d %d.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 773 | command.c_str(), cic.tile_type.c_str(), tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 774 | | 775 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 776 | { | ~ 777 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 778 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 779 | break; | ~~~~~~ 780 | } | ~ 781 | | 782 | for (int bit_x = 0; bit_x < int(line.size()) && bit_x < cic.tile_width; bit_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 783 | if (line[bit_x] == '1') { | ~~~~~~~~~~~~~~~~~~~~~~~~~ 784 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 785 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 786 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 787 | } | ~ 788 | } | ~ 789 | | 790 | continue; | ~~~~~~~~~ 791 | } | ~ 792 | | 793 | if (command == ".ram_data") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 794 | { | ~ 795 | if (!got_device) | ~~~~~~~~~~~~~~~~ 796 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 797 | | 798 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 799 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 800 | | 801 | BramIndexConverter bic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 802 | | 803 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 804 | { | ~ 805 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 806 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 807 | break; | ~~~~~~ 808 | } | ~ 809 | | 810 | for (int bit_x = 256-4, ch_idx = 0; ch_idx < int(line.size()) && bit_x >= 0; bit_x -= 4, ch_idx++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 811 | { | ~ 812 | int value = -1; | ~~~~~~~~~~~~~~~ 813 | if ('0' <= line[ch_idx] && line[ch_idx] <= '9') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 814 | value = line[ch_idx] - '0'; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 815 | if ('a' <= line[ch_idx] && line[ch_idx] <= 'f') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 816 | value = line[ch_idx] - 'a' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 817 | if ('A' <= line[ch_idx] && line[ch_idx] <= 'F') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 818 | value = line[ch_idx] - 'A' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 819 | if (value < 0) | ~~~~~~~~~~~~~~ 820 | error("Not a hex character: '%c' (in line '%s')\n", line[ch_idx], line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 821 | | 822 | for (int i = 0; i < 4; i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 823 | if ((value & (1 << i)) != 0) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 824 | int bram_bank, bram_x, bram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 825 | bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 826 | this->bram[bram_bank][bram_x][bram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 827 | } | ~ 828 | } | ~ 829 | } | ~ 830 | | 831 | continue; | ~~~~~~~~~ 832 | } | ~ 833 | | 834 | if (command == ".extra_bit") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 835 | { | ~ 836 | if (!got_device) | ~~~~~~~~~~~~~~~~ 837 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 838 | | 839 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 840 | is >> cram_bank >> cram_x >> cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 841 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 842 | | 843 | continue; | ~~~~~~~~~ 844 | } | ~ 845 | | 846 | if (command == ".sym") | ~~~~~~~~~~~~~~~~~~~~~~ 847 | continue; | ~~~~~~~~~ 848 | | 849 | if (command.substr(0, 1) == ".") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 850 | error("Unknown statement: %s\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 851 | error("Unexpected data line: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 852 | } | ~ 853 | } | ~ 854 | | 855 | void FpgaConfig::write_ascii(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 856 | { | ~ 857 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 858 | info("Writing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 859 | | 860 | ofs << ".comment"; | ~~~~~~~~~~~~~~~~~~ 861 | bool insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 862 | for (auto ch : this->initblop) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 863 | if (ch == 0) { | ~~~~~~~~~~~~~~ 864 | insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~ 865 | } else if (ch == 0xff) { | ~~~~~~~~~~~~~~~~~~~~~~~~ 866 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 867 | } else { | ~~~~~~~~ 868 | if (insert_newline) | ~~~~~~~~~~~~~~~~~~~ 869 | ofs << '\n'; | ~~~~~~~~~~~~ 870 | ofs << ch; | ~~~~~~~~~~ 871 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 872 | } | ~ 873 | } | ~ 874 | | 875 | ofs << stringf("\n.device %s\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 876 | if (this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 877 | ofs << stringf(".warmboot %s\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 878 | | 879 | // As "nosleep" is an icepack command, we do not write out a ".nosleep" | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 880 | // section. However, we parse it in read_bits() and notify the user in | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 881 | // info. | ~~~~~~~~ 882 | | 883 | typedef std::tuple tile_bit_t; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 884 | std::set tile_bits; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 885 | | 886 | for (int y = 0; y <= this->chip_height()+1; y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 887 | for (int x = 0; x <= this->chip_width()+1; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 888 | { | ~ 889 | CramIndexConverter cic(this, x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 890 | | 891 | if (cic.tile_type == "corner" || cic.tile_type == "unsupported") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 892 | continue; | ~~~~~~~~~ 893 | | 894 | ofs << stringf(".%s_tile %d %d\n", cic.tile_type.c_str(), x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 895 | | 896 | for (int bit_y = 0; bit_y < 16; bit_y++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 897 | for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 898 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 899 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 900 | tile_bits.insert(tile_bit_t(cram_bank, cram_x, cram_y)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 901 | if (cram_x > int(this->cram[cram_bank].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 902 | error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | std::vector >::size_type {aka unsigned int} icepack.cc:902:6: note: in expansion of macro 'error' 902 | error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); | ^~~~~ icepack.cc:902:60: note: format string is defined here 902 | error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); | ~~^ | | | long unsigned int | %u icepack.cc:53:41: warning: format '%lu' expects argument of type 'long unsigned int', but argument 7 has type 'std::vector::size_type' {aka 'unsigned int'} [-Wformat=] 53 | #define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 54 | #define panic(fmt, ...) do { fprintf(stderr, "Internal Error at %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__); abort(); } while (0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 55 | | 56 | string vstringf(const char *fmt, va_list ap) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 57 | { | ~ 58 | string string; | ~~~~~~~~~~~~~~ 59 | char *str = NULL; | ~~~~~~~~~~~~~~~~~ 60 | | 61 | #ifdef _WIN32 | ~~~~~~~~~~~~~ 62 | int sz = 64, rc; | ~~~~~~~~~~~~~~~~ 63 | while (1) { | ~~~~~~~~~~~ 64 | va_list apc; | ~~~~~~~~~~~~ 65 | va_copy(apc, ap); | ~~~~~~~~~~~~~~~~~ 66 | str = (char*)realloc(str, sz); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 67 | rc = vsnprintf(str, sz, fmt, apc); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | va_end(apc); | ~~~~~~~~~~~~ 69 | if (rc >= 0 && rc < sz) | ~~~~~~~~~~~~~~~~~~~~~~~ 70 | break; | ~~~~~~ 71 | sz *= 2; | ~~~~~~~~ 72 | } | ~ 73 | #else | ~~~~~ 74 | if (vasprintf(&str, fmt, ap) < 0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 75 | str = NULL; | ~~~~~~~~~~~ 76 | #endif | ~~~~~~ 77 | | 78 | if (str != NULL) { | ~~~~~~~~~~~~~~~~~~ 79 | string = str; | ~~~~~~~~~~~~~ 80 | free(str); | ~~~~~~~~~~ 81 | } | ~ 82 | | 83 | return string; | ~~~~~~~~~~~~~~ 84 | } | ~ 85 | | 86 | string stringf(const char *fmt, ...) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 87 | { | ~ 88 | string string; | ~~~~~~~~~~~~~~ 89 | va_list ap; | ~~~~~~~~~~~ 90 | | 91 | va_start(ap, fmt); | ~~~~~~~~~~~~~~~~~~ 92 | string = vstringf(fmt, ap); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 93 | va_end(ap); | ~~~~~~~~~~~ 94 | | 95 | return string; | ~~~~~~~~~~~~~~ 96 | } | ~ 97 | | 98 | // ================================================================== | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 99 | // FpgaConfig stuff | ~~~~~~~~~~~~~~~~~~~ 100 | | 101 | struct FpgaConfig | ~~~~~~~~~~~~~~~~~ 102 | { | ~ 103 | string device; | ~~~~~~~~~~~~~~ 104 | string freqrange; | ~~~~~~~~~~~~~~~~~ 105 | string nosleep; | ~~~~~~~~~~~~~~~ 106 | string warmboot; | ~~~~~~~~~~~~~~~~ 107 | | 108 | // cram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 109 | int cram_width, cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 110 | vector>> cram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 111 | | 112 | // bram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 113 | int bram_width, bram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 114 | vector>> bram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 115 | | 116 | // data before preamble | ~~~~~~~~~~~~~~~~~~~~~~~ 117 | vector initblop; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 118 | | 119 | // bitstream i/o | ~~~~~~~~~~~~~~~~ 120 | void read_bits(std::istream &ifs); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 121 | void write_bits(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 122 | | 123 | // icebox i/o | ~~~~~~~~~~~~~ 124 | void read_ascii(std::istream &ifs, bool nosleep); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 125 | void write_ascii(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 126 | | 127 | // netpbm i/o | ~~~~~~~~~~~~~ 128 | void write_cram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 129 | void write_bram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 130 | | 131 | // query chip type metadata | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 132 | int chip_width() const; | ~~~~~~~~~~~~~~~~~~~~~~~ 133 | int chip_height() const; | ~~~~~~~~~~~~~~~~~~~~~~~~ 134 | vector chip_cols() const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 135 | | 136 | // query tile metadata | ~~~~~~~~~~~~~~~~~~~~~~ 137 | string tile_type(int x, int y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 138 | int tile_width(const string &type) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 139 | | 140 | // cram bit manipulation | ~~~~~~~~~~~~~~~~~~~~~~~~ 141 | void cram_clear(); | ~~~~~~~~~~~~~~~~~~ 142 | void cram_fill_tiles(); | ~~~~~~~~~~~~~~~~~~~~~~~ 143 | void cram_checkerboard(int m = 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 144 | }; | ~~ 145 | | 146 | struct CramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 147 | { | ~ 148 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 149 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 150 | | 151 | string tile_type; | ~~~~~~~~~~~~~~~~~ 152 | int tile_width; | ~~~~~~~~~~~~~~~ 153 | int column_width; | ~~~~~~~~~~~~~~~~~ 154 | | 155 | bool left_right_io; | ~~~~~~~~~~~~~~~~~~~ 156 | bool right_half; | ~~~~~~~~~~~~~~~~ 157 | bool top_half; | ~~~~~~~~~~~~~~ 158 | | 159 | int bank_num; | ~~~~~~~~~~~~~ 160 | int bank_tx; | ~~~~~~~~~~~~ 161 | int bank_ty; | ~~~~~~~~~~~~ 162 | int bank_xoff; | ~~~~~~~~~~~~~~ 163 | int bank_yoff; | ~~~~~~~~~~~~~~ 164 | | 165 | CramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 166 | void get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 167 | }; | ~~ 168 | | 169 | struct BramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 170 | { | ~ 171 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 172 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 173 | | 174 | int bank_num; | ~~~~~~~~~~~~~ 175 | int bank_off; | ~~~~~~~~~~~~~ 176 | | 177 | BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 178 | void get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 179 | }; | ~~ 180 | | 181 | static void update_crc16(uint16_t &crc, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 182 | { | ~ 183 | // CRC-16-CCITT, Initialize to 0xFFFF, No zero padding | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 184 | for (int i = 7; i >= 0; i--) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 185 | uint16_t xor_value = ((crc >> 15) ^ ((byte >> i) & 1)) ? 0x1021 : 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 186 | crc = (crc << 1) ^ xor_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 187 | } | ~ 188 | } | ~ 189 | | 190 | static uint8_t read_byte(std::istream &ifs, uint16_t &crc_value, int &file_offset) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 191 | { | ~ 192 | int byte = ifs.get(); | ~~~~~~~~~~~~~~~~~~~~~ 193 | | 194 | if (byte < 0) | ~~~~~~~~~~~~~ 195 | error("Unexpected end of file.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 196 | | 197 | file_offset++; | ~~~~~~~~~~~~~~ 198 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 199 | | 200 | return byte; | ~~~~~~~~~~~~ 201 | } | ~ 202 | | 203 | static void write_byte(std::ostream &ofs, uint16_t &crc_value, int &file_offset, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 204 | { | ~ 205 | ofs << byte; | ~~~~~~~~~~~~ 206 | file_offset++; | ~~~~~~~~~~~~~~ 207 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 208 | } | ~ 209 | | 210 | void FpgaConfig::read_bits(std::istream &ifs) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 211 | { | ~ 212 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 213 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 214 | | 215 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 216 | info("Parsing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 217 | | 218 | // skip initial comments until preamble is found | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 219 | | 220 | uint32_t preamble = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 221 | | 222 | while (1) | ~~~~~~~~~ 223 | { | ~ 224 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 225 | preamble = (preamble << 8) | byte; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 226 | if (preamble == 0xffffffff) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 227 | error("No preamble found in bitstream.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 228 | if (preamble == 0x7EAA997E) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 229 | info("Found preamble at offset %d.\n", file_offset-4); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 230 | break; | ~~~~~~ 231 | } | ~ 232 | initblop.push_back(byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 233 | } | ~ 234 | | 235 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 236 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 237 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 238 | | 239 | // main parser loop | ~~~~~~~~~~~~~~~~~~~ 240 | | 241 | int current_bank = 0; | ~~~~~~~~~~~~~~~~~~~~~ 242 | int current_width = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 243 | int current_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 244 | int current_offset = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 245 | bool wakeup = false; | ~~~~~~~~~~~~~~~~~~~~ 246 | | 247 | this->cram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 248 | this->cram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 249 | | 250 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 251 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 252 | | 253 | while (!wakeup) | ~~~~~~~~~~~~~~~ 254 | { | ~ 255 | // one command byte. the lower 4 bits of the command byte specify | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 256 | // the length of the command payload. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 257 | | 258 | uint8_t command = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 259 | uint32_t payload = 0; | ~~~~~~~~~~~~~~~~~~~~~ 260 | | 261 | for (int i = 0; i < (command & 0x0f); i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 262 | payload = (payload << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 263 | | 264 | debug("Next command at offset %d: 0x%02x 0x%0*x\n", file_offset - 1 - (command & 0x0f), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 265 | command, 2*(command & 0x0f), payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 266 | | 267 | uint16_t end_token; | ~~~~~~~~~~~~~~~~~~~ 268 | | 269 | switch (command & 0xf0) | ~~~~~~~~~~~~~~~~~~~~~~~ 270 | { | ~ 271 | case 0x00: | ~~~~~~~~~~ 272 | switch (payload) | ~~~~~~~~~~~~~~~~ 273 | { | ~ 274 | case 0x01: | ~~~~~~~~~~ 275 | info("CRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 276 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 277 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 278 | | 279 | this->cram_width = std::max(this->cram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 280 | this->cram_height = std::max(this->cram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 281 | | 282 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 283 | this->cram[current_bank].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 284 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 285 | this->cram[current_bank][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 286 | | 287 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 288 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 289 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 290 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 291 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 292 | this->cram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 293 | } | ~ 294 | } | ~ 295 | | 296 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 297 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 298 | if (end_token) | ~~~~~~~~~~~~~~ 299 | error("Expeded 0x0000 after CRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 300 | break; | ~~~~~~ 301 | | 302 | case 0x03: | ~~~~~~~~~~ 303 | info("BRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 304 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 305 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 306 | | 307 | this->bram_width = std::max(this->bram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 308 | this->bram_height = std::max(this->bram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 309 | | 310 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 311 | this->bram[current_bank].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 312 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 313 | this->bram[current_bank][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 314 | | 315 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 316 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 317 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 318 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 319 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 320 | this->bram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 321 | } | ~ 322 | } | ~ 323 | | 324 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 325 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 326 | if (end_token) | ~~~~~~~~~~~~~~ 327 | error("Expeded 0x0000 after BRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 328 | break; | ~~~~~~ 329 | | 330 | case 0x05: | ~~~~~~~~~~ 331 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 332 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 333 | break; | ~~~~~~ 334 | | 335 | case 0x06: | ~~~~~~~~~~ 336 | info("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~ 337 | wakeup = true; | ~~~~~~~~~~~~~~ 338 | break; | ~~~~~~ 339 | | 340 | default: | ~~~~~~~~ 341 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 342 | } | ~ 343 | break; | ~~~~~~ 344 | | 345 | case 0x10: | ~~~~~~~~~~ 346 | current_bank = payload; | ~~~~~~~~~~~~~~~~~~~~~~~ 347 | debug("Set bank to %d.\n", current_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 348 | break; | ~~~~~~ 349 | | 350 | case 0x20: | ~~~~~~~~~~ 351 | if (crc_value != 0) | ~~~~~~~~~~~~~~~~~~~ 352 | error("CRC Check FAILED.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 353 | info("CRC Check OK.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~ 354 | break; | ~~~~~~ 355 | | 356 | case 0x50: | ~~~~~~~~~~ 357 | if (payload == 0) | ~~~~~~~~~~~~~~~~~ 358 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 359 | else if (payload == 1) | ~~~~~~~~~~~~~~~~~~~~~~ 360 | this->freqrange = "medium"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 361 | else if (payload == 2) | ~~~~~~~~~~~~~~~~~~~~~~ 362 | this->freqrange = "high"; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 363 | else | ~~~~ 364 | error("Unknown freqrange payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 365 | info("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 366 | break; | ~~~~~~ 367 | | 368 | case 0x60: | ~~~~~~~~~~ 369 | current_width = payload + 1; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 370 | debug("Setting bank width to %d.\n", current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 371 | break; | ~~~~~~ 372 | | 373 | case 0x70: | ~~~~~~~~~~ 374 | current_height = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 375 | debug("Setting bank height to %d.\n", current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 376 | break; | ~~~~~~ 377 | | 378 | case 0x80: | ~~~~~~~~~~ 379 | current_offset = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 380 | debug("Setting bank offset to %d.\n", current_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 381 | break; | ~~~~~~ 382 | | 383 | case 0x90: | ~~~~~~~~~~ 384 | switch(payload) | ~~~~~~~~~~~~~~~ 385 | { | ~ 386 | case 0: | ~~~~~~~ 387 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 388 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 389 | break; | ~~~~~~ 390 | case 1: | ~~~~~~~ 391 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 392 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 393 | break; | ~~~~~~ 394 | case 32: | ~~~~~~~~ 395 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 396 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 397 | break; | ~~~~~~ 398 | case 33: | ~~~~~~~~ 399 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 400 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 401 | break; | ~~~~~~ 402 | default: | ~~~~~~~~ 403 | error("Unknown warmboot/nosleep payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 404 | } | ~ 405 | info("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 406 | break; | ~~~~~~ 407 | | 408 | default: | ~~~~~~~~ 409 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 410 | } | ~ 411 | } | ~ 412 | | 413 | if (this->cram_width == 182 && this->cram_height == 80) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 414 | this->device = "384"; | ~~~~~~~~~~~~~~~~~~~~~ 415 | else if (this->cram_width == 332 && this->cram_height == 144) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 416 | this->device = "1k"; | ~~~~~~~~~~~~~~~~~~~~ 417 | else if (this->cram_width == 872 && this->cram_height == 272) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 418 | this->device = "8k"; | ~~~~~~~~~~~~~~~~~~~~ 419 | else if (this->cram_width == 692 && this->cram_height == 336) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 420 | this->device = "5k"; | ~~~~~~~~~~~~~~~~~~~~ 421 | else if (this->cram_width == 692 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 422 | this->device = "u4k"; | ~~~~~~~~~~~~~~~~~~~~~ 423 | else if (this->cram_width == 656 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 424 | this->device = "lm4k"; | ~~~~~~~~~~~~~~~~~~~~~~ 425 | else | ~~~~ 426 | error("Failed to detect chip type.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 427 | | 428 | info("Chip type is '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 429 | } | ~ 430 | | 431 | void FpgaConfig::write_bits(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 432 | { | ~ 433 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 434 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 435 | | 436 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 437 | info("Writing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 438 | | 439 | for (auto byte : this->initblop) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 440 | ofs << byte; | ~~~~~~~~~~~~ 441 | | 442 | debug("Writing preamble.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 443 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 444 | write_byte(ofs, crc_value, file_offset, 0xAA); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 445 | write_byte(ofs, crc_value, file_offset, 0x99); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 446 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 447 | | 448 | debug("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 449 | write_byte(ofs, crc_value, file_offset, 0x51); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 450 | if (this->freqrange == "low") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 451 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 452 | else if (this->freqrange == "medium") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 453 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 454 | else if (this->freqrange == "high") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 455 | write_byte(ofs, crc_value, file_offset, 0x02); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 456 | else | ~~~~ 457 | error("Unknown freqrange '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 458 | | 459 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 460 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 461 | write_byte(ofs, crc_value, file_offset, 0x05); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 462 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 463 | | 464 | { | ~ 465 | uint8_t nosleep_flag; | ~~~~~~~~~~~~~~~~~~~~~ 466 | debug("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 467 | write_byte(ofs, crc_value, file_offset, 0x92); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 468 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 469 | | 470 | if (this->nosleep == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 471 | nosleep_flag = 0; | ~~~~~~~~~~~~~~~~~ 472 | else if (this->nosleep == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 473 | nosleep_flag = 1; | ~~~~~~~~~~~~~~~~~ 474 | else | ~~~~ 475 | error("Unknown nosleep setting '%s'.\n", this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 476 | | 477 | if (this->warmboot == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 478 | write_byte(ofs, crc_value, file_offset, 0x00 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 479 | else if (this->warmboot == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 480 | write_byte(ofs, crc_value, file_offset, 0x20 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 481 | else | ~~~~ 482 | error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 483 | } | ~ 484 | | 485 | debug("CRAM: Setting bank width to %d.\n", this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 486 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 487 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 488 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 489 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 490 | debug("CRAM: Setting bank height to %d.\n", this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 491 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 492 | write_byte(ofs, crc_value, file_offset, this->cram_height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 493 | write_byte(ofs, crc_value, file_offset, this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 494 | } | ~ 495 | | 496 | debug("CRAM: Setting bank offset to 0.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 497 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 498 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 499 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 500 | | 501 | for (int cram_bank = 0; cram_bank < 4; cram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 502 | { | ~ 503 | vector cram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 504 | int height = this->cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 505 | if(this->device == "5k" && ((cram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 506 | height = height / 2 + 8; | ~~~~~~~~~~~~~~~~~~~~~~~~ 507 | for (int cram_y = 0; cram_y < height; cram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 508 | for (int cram_x = 0; cram_x < this->cram_width; cram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 509 | cram_bits.push_back(this->cram[cram_bank][cram_x][cram_y]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 510 | | 511 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 512 | debug("CRAM: Setting bank height to %d.\n", height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 513 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 514 | write_byte(ofs, crc_value, file_offset, height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 515 | write_byte(ofs, crc_value, file_offset, height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 516 | } | ~ 517 | | 518 | debug("CRAM: Setting bank %d.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 519 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 520 | write_byte(ofs, crc_value, file_offset, cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 521 | | 522 | debug("CRAM: Writing bank %d data.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 523 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 524 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 525 | for (int i = 0; i < int(cram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 526 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 527 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 528 | byte = (byte << 1) | (cram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 529 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 530 | } | ~ 531 | | 532 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 533 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 534 | } | ~ 535 | | 536 | int bram_chunk_size = 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 537 | | 538 | if (this->bram_width && this->bram_height) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 539 | { | ~ 540 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 541 | debug("BRAM: Setting bank width to %d.\n", this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 542 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 543 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 544 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 545 | } | ~ 546 | | 547 | | 548 | debug("BRAM: Setting bank height to %d.\n", this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 549 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 550 | write_byte(ofs, crc_value, file_offset, bram_chunk_size >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 551 | write_byte(ofs, crc_value, file_offset, bram_chunk_size); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 552 | | 553 | for (int bram_bank = 0; bram_bank < 4; bram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 554 | { | ~ 555 | debug("BRAM: Setting bank %d.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 556 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 557 | write_byte(ofs, crc_value, file_offset, bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 558 | | 559 | for (int offset = 0; offset < this->bram_height; offset += bram_chunk_size) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 560 | { | ~ 561 | vector bram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 562 | int width = this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 563 | if(this->device == "5k" && ((bram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 564 | width = width / 2; | ~~~~~~~~~~~~~~~~~~ 565 | for (int bram_y = 0; bram_y < bram_chunk_size; bram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 566 | for (int bram_x = 0; bram_x < width; bram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 567 | bram_bits.push_back(this->bram[bram_bank][bram_x][bram_y+offset]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 568 | | 569 | debug("BRAM: Setting bank offset to %d.\n", offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 570 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 571 | write_byte(ofs, crc_value, file_offset, offset >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 572 | write_byte(ofs, crc_value, file_offset, offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 573 | | 574 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 575 | debug("BRAM: Setting bank width to %d.\n", width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 576 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 577 | write_byte(ofs, crc_value, file_offset, (width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 578 | write_byte(ofs, crc_value, file_offset, (width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 579 | } | ~ 580 | | 581 | | 582 | debug("BRAM: Writing bank %d data.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 583 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 584 | write_byte(ofs, crc_value, file_offset, 0x03); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 585 | for (int i = 0; i < int(bram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 586 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 587 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 588 | byte = (byte << 1) | (bram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 589 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 590 | } | ~ 591 | | 592 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 593 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 594 | } | ~ 595 | } | ~ 596 | } | ~ 597 | | 598 | debug("Writing CRC value.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 599 | write_byte(ofs, crc_value, file_offset, 0x22); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 600 | uint8_t crc_hi = crc_value >> 8, crc_lo = crc_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 601 | write_byte(ofs, crc_value, file_offset, crc_hi); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 602 | write_byte(ofs, crc_value, file_offset, crc_lo); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 603 | | 604 | debug("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~~ 605 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 606 | write_byte(ofs, crc_value, file_offset, 0x06); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 607 | | 608 | debug("Padding byte.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 609 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 610 | } | ~ 611 | | 612 | void FpgaConfig::read_ascii(std::istream &ifs, bool nosleep) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 613 | { | ~ 614 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 615 | info("Parsing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 616 | | 617 | bool got_device = false; | ~~~~~~~~~~~~~~~~~~~~~~~~ 618 | this->cram.clear(); | ~~~~~~~~~~~~~~~~~~~ 619 | this->bram.clear(); | ~~~~~~~~~~~~~~~~~~~ 620 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 621 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 622 | | 623 | bool reuse_line = true; | ~~~~~~~~~~~~~~~~~~~~~~~ 624 | string line, command; | ~~~~~~~~~~~~~~~~~~~~~ 625 | | 626 | while (reuse_line || getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 627 | { | ~ 628 | reuse_line = false; | ~~~~~~~~~~~~~~~~~~~ 629 | | 630 | std::istringstream is(line); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 631 | is >> command; | ~~~~~~~~~~~~~~ 632 | | 633 | if (command.empty()) | ~~~~~~~~~~~~~~~~~~~~ 634 | continue; | ~~~~~~~~~ 635 | | 636 | debug("Next command: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 637 | | 638 | if (command == ".comment") | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 639 | { | ~ 640 | this->initblop.clear(); | ~~~~~~~~~~~~~~~~~~~~~~~ 641 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 642 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 643 | | 644 | while (getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 645 | { | ~ 646 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 647 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 648 | break; | ~~~~~~ 649 | } | ~ 650 | | 651 | for (auto ch : line) | ~~~~~~~~~~~~~~~~~~~~ 652 | this->initblop.push_back(ch); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 653 | this->initblop.push_back(0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 654 | } | ~ 655 | | 656 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 657 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 658 | continue; | ~~~~~~~~~ 659 | } | ~ 660 | | 661 | if (command == ".device") | ~~~~~~~~~~~~~~~~~~~~~~~~~ 662 | { | ~ 663 | if (got_device) | ~~~~~~~~~~~~~~~ 664 | error("More than one .device statement.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 665 | | 666 | is >> this->device; | ~~~~~~~~~~~~~~~~~~~ 667 | | 668 | if (this->device == "384") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 669 | this->cram_width = 182; | ~~~~~~~~~~~~~~~~~~~~~~~ 670 | this->cram_height = 80; | ~~~~~~~~~~~~~~~~~~~~~~~ 671 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 672 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 673 | } else | ~~~~~~ 674 | if (this->device == "1k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 675 | this->cram_width = 332; | ~~~~~~~~~~~~~~~~~~~~~~~ 676 | this->cram_height = 144; | ~~~~~~~~~~~~~~~~~~~~~~~~ 677 | this->bram_width = 64; | ~~~~~~~~~~~~~~~~~~~~~~ 678 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 679 | } else | ~~~~~~ 680 | if (this->device == "8k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 681 | this->cram_width = 872; | ~~~~~~~~~~~~~~~~~~~~~~~ 682 | this->cram_height = 272; | ~~~~~~~~~~~~~~~~~~~~~~~~ 683 | this->bram_width = 128; | ~~~~~~~~~~~~~~~~~~~~~~~ 684 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 685 | } else | ~~~~~~ 686 | if (this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 687 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 688 | this->cram_height = 336; | ~~~~~~~~~~~~~~~~~~~~~~~~ 689 | this->bram_width = 160; | ~~~~~~~~~~~~~~~~~~~~~~~ 690 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 691 | } else | ~~~~~~ 692 | if (this->device == "u4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 693 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 694 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 695 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 696 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 697 | } else | ~~~~~~ 698 | if (this->device == "lm4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 699 | this->cram_width = 656; | ~~~~~~~~~~~~~~~~~~~~~~~ 700 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 701 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 702 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 703 | } else | ~~~~~~ 704 | error("Unsupported chip type '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 705 | | 706 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 707 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 708 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 709 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 710 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 711 | this->cram[i][x].resize(((i % 2) == 1) ? (this->cram_height / 2 + 8) : this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 712 | } | ~ 713 | | 714 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 715 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 716 | int width = ((i % 2) == 1) ? (this->bram_width / 2) : this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 717 | this->bram[i].resize(width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 718 | for (int x = 0; x < width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 719 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 720 | } | ~ 721 | } else { | ~~~~~~~~ 722 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 723 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 724 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 725 | this->cram[i][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 726 | } | ~ 727 | | 728 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 729 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 730 | this->bram[i].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 731 | for (int x = 0; x < this->bram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 732 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 733 | } | ~ 734 | } | ~ 735 | | 736 | | 737 | got_device = true; | ~~~~~~~~~~~~~~~~~~ 738 | continue; | ~~~~~~~~~ 739 | } | ~ 740 | | 741 | if (command == ".warmboot") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 742 | { | ~ 743 | is >> this->warmboot; | ~~~~~~~~~~~~~~~~~~~~~ 744 | | 745 | if (this->warmboot != "disabled" && | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 746 | this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 747 | error("Unknown warmboot setting '%s'.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 748 | this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~ 749 | | 750 | continue; | ~~~~~~~~~ 751 | } | ~ 752 | | 753 | // No ".nosleep" section despite sharing the same byte as .warmboot. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 754 | // ".nosleep" is specified when icepack is invoked, which is too late. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 755 | // So we inject the section based on command line argument. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 756 | if (nosleep) | ~~~~~~~~~~~~ 757 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 758 | else | ~~~~ 759 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 760 | | 761 | if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile" || command.substr(0, 4) == ".dsp" || command == ".ipcon_tile") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 762 | { | ~ 763 | if (!got_device) | ~~~~~~~~~~~~~~~~ 764 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 765 | | 766 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 767 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 768 | | 769 | CramIndexConverter cic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 770 | | 771 | if (("." + cic.tile_type + "_tile") != command) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 772 | error("Got %s statement for %s tile %d %d.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 773 | command.c_str(), cic.tile_type.c_str(), tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 774 | | 775 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 776 | { | ~ 777 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 778 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 779 | break; | ~~~~~~ 780 | } | ~ 781 | | 782 | for (int bit_x = 0; bit_x < int(line.size()) && bit_x < cic.tile_width; bit_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 783 | if (line[bit_x] == '1') { | ~~~~~~~~~~~~~~~~~~~~~~~~~ 784 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 785 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 786 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 787 | } | ~ 788 | } | ~ 789 | | 790 | continue; | ~~~~~~~~~ 791 | } | ~ 792 | | 793 | if (command == ".ram_data") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 794 | { | ~ 795 | if (!got_device) | ~~~~~~~~~~~~~~~~ 796 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 797 | | 798 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 799 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 800 | | 801 | BramIndexConverter bic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 802 | | 803 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 804 | { | ~ 805 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 806 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 807 | break; | ~~~~~~ 808 | } | ~ 809 | | 810 | for (int bit_x = 256-4, ch_idx = 0; ch_idx < int(line.size()) && bit_x >= 0; bit_x -= 4, ch_idx++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 811 | { | ~ 812 | int value = -1; | ~~~~~~~~~~~~~~~ 813 | if ('0' <= line[ch_idx] && line[ch_idx] <= '9') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 814 | value = line[ch_idx] - '0'; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 815 | if ('a' <= line[ch_idx] && line[ch_idx] <= 'f') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 816 | value = line[ch_idx] - 'a' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 817 | if ('A' <= line[ch_idx] && line[ch_idx] <= 'F') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 818 | value = line[ch_idx] - 'A' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 819 | if (value < 0) | ~~~~~~~~~~~~~~ 820 | error("Not a hex character: '%c' (in line '%s')\n", line[ch_idx], line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 821 | | 822 | for (int i = 0; i < 4; i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 823 | if ((value & (1 << i)) != 0) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 824 | int bram_bank, bram_x, bram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 825 | bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 826 | this->bram[bram_bank][bram_x][bram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 827 | } | ~ 828 | } | ~ 829 | } | ~ 830 | | 831 | continue; | ~~~~~~~~~ 832 | } | ~ 833 | | 834 | if (command == ".extra_bit") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 835 | { | ~ 836 | if (!got_device) | ~~~~~~~~~~~~~~~~ 837 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 838 | | 839 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 840 | is >> cram_bank >> cram_x >> cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 841 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 842 | | 843 | continue; | ~~~~~~~~~ 844 | } | ~ 845 | | 846 | if (command == ".sym") | ~~~~~~~~~~~~~~~~~~~~~~ 847 | continue; | ~~~~~~~~~ 848 | | 849 | if (command.substr(0, 1) == ".") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 850 | error("Unknown statement: %s\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 851 | error("Unexpected data line: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 852 | } | ~ 853 | } | ~ 854 | | 855 | void FpgaConfig::write_ascii(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 856 | { | ~ 857 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 858 | info("Writing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 859 | | 860 | ofs << ".comment"; | ~~~~~~~~~~~~~~~~~~ 861 | bool insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 862 | for (auto ch : this->initblop) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 863 | if (ch == 0) { | ~~~~~~~~~~~~~~ 864 | insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~ 865 | } else if (ch == 0xff) { | ~~~~~~~~~~~~~~~~~~~~~~~~ 866 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 867 | } else { | ~~~~~~~~ 868 | if (insert_newline) | ~~~~~~~~~~~~~~~~~~~ 869 | ofs << '\n'; | ~~~~~~~~~~~~ 870 | ofs << ch; | ~~~~~~~~~~ 871 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 872 | } | ~ 873 | } | ~ 874 | | 875 | ofs << stringf("\n.device %s\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 876 | if (this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 877 | ofs << stringf(".warmboot %s\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 878 | | 879 | // As "nosleep" is an icepack command, we do not write out a ".nosleep" | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 880 | // section. However, we parse it in read_bits() and notify the user in | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 881 | // info. | ~~~~~~~~ 882 | | 883 | typedef std::tuple tile_bit_t; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 884 | std::set tile_bits; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 885 | | 886 | for (int y = 0; y <= this->chip_height()+1; y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 887 | for (int x = 0; x <= this->chip_width()+1; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 888 | { | ~ 889 | CramIndexConverter cic(this, x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 890 | | 891 | if (cic.tile_type == "corner" || cic.tile_type == "unsupported") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 892 | continue; | ~~~~~~~~~ 893 | | 894 | ofs << stringf(".%s_tile %d %d\n", cic.tile_type.c_str(), x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 895 | | 896 | for (int bit_y = 0; bit_y < 16; bit_y++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 897 | for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 898 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 899 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 900 | tile_bits.insert(tile_bit_t(cram_bank, cram_x, cram_y)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 901 | if (cram_x > int(this->cram[cram_bank].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 902 | error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 903 | } | ~ 904 | if (cram_y > int(this->cram[cram_bank][cram_x].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 905 | error("cram_y %d (bit %d, %d) larger than bank %d size %lu\n", cram_y, bit_x, bit_y, cram_bank, this->cram[cram_bank][cram_x].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | std::vector::size_type {aka unsigned int} icepack.cc:905:6: note: in expansion of macro 'error' 905 | error("cram_y %d (bit %d, %d) larger than bank %d size %lu\n", cram_y, bit_x, bit_y, cram_bank, this->cram[cram_bank][cram_x].size()); | ^~~~~ icepack.cc:905:63: note: format string is defined here 905 | error("cram_y %d (bit %d, %d) larger than bank %d size %lu\n", cram_y, bit_x, bit_y, cram_bank, this->cram[cram_bank][cram_x].size()); | ~~^ | | | long unsigned int | %u icepack.cc:53:41: warning: format '%lu' expects argument of type 'long unsigned int', but argument 6 has type 'std::vector >::size_type' {aka 'unsigned int'} [-Wformat=] 53 | #define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 54 | #define panic(fmt, ...) do { fprintf(stderr, "Internal Error at %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__); abort(); } while (0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 55 | | 56 | string vstringf(const char *fmt, va_list ap) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 57 | { | ~ 58 | string string; | ~~~~~~~~~~~~~~ 59 | char *str = NULL; | ~~~~~~~~~~~~~~~~~ 60 | | 61 | #ifdef _WIN32 | ~~~~~~~~~~~~~ 62 | int sz = 64, rc; | ~~~~~~~~~~~~~~~~ 63 | while (1) { | ~~~~~~~~~~~ 64 | va_list apc; | ~~~~~~~~~~~~ 65 | va_copy(apc, ap); | ~~~~~~~~~~~~~~~~~ 66 | str = (char*)realloc(str, sz); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 67 | rc = vsnprintf(str, sz, fmt, apc); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | va_end(apc); | ~~~~~~~~~~~~ 69 | if (rc >= 0 && rc < sz) | ~~~~~~~~~~~~~~~~~~~~~~~ 70 | break; | ~~~~~~ 71 | sz *= 2; | ~~~~~~~~ 72 | } | ~ 73 | #else | ~~~~~ 74 | if (vasprintf(&str, fmt, ap) < 0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 75 | str = NULL; | ~~~~~~~~~~~ 76 | #endif | ~~~~~~ 77 | | 78 | if (str != NULL) { | ~~~~~~~~~~~~~~~~~~ 79 | string = str; | ~~~~~~~~~~~~~ 80 | free(str); | ~~~~~~~~~~ 81 | } | ~ 82 | | 83 | return string; | ~~~~~~~~~~~~~~ 84 | } | ~ 85 | | 86 | string stringf(const char *fmt, ...) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 87 | { | ~ 88 | string string; | ~~~~~~~~~~~~~~ 89 | va_list ap; | ~~~~~~~~~~~ 90 | | 91 | va_start(ap, fmt); | ~~~~~~~~~~~~~~~~~~ 92 | string = vstringf(fmt, ap); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 93 | va_end(ap); | ~~~~~~~~~~~ 94 | | 95 | return string; | ~~~~~~~~~~~~~~ 96 | } | ~ 97 | | 98 | // ================================================================== | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 99 | // FpgaConfig stuff | ~~~~~~~~~~~~~~~~~~~ 100 | | 101 | struct FpgaConfig | ~~~~~~~~~~~~~~~~~ 102 | { | ~ 103 | string device; | ~~~~~~~~~~~~~~ 104 | string freqrange; | ~~~~~~~~~~~~~~~~~ 105 | string nosleep; | ~~~~~~~~~~~~~~~ 106 | string warmboot; | ~~~~~~~~~~~~~~~~ 107 | | 108 | // cram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 109 | int cram_width, cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 110 | vector>> cram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 111 | | 112 | // bram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 113 | int bram_width, bram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 114 | vector>> bram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 115 | | 116 | // data before preamble | ~~~~~~~~~~~~~~~~~~~~~~~ 117 | vector initblop; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 118 | | 119 | // bitstream i/o | ~~~~~~~~~~~~~~~~ 120 | void read_bits(std::istream &ifs); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 121 | void write_bits(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 122 | | 123 | // icebox i/o | ~~~~~~~~~~~~~ 124 | void read_ascii(std::istream &ifs, bool nosleep); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 125 | void write_ascii(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 126 | | 127 | // netpbm i/o | ~~~~~~~~~~~~~ 128 | void write_cram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 129 | void write_bram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 130 | | 131 | // query chip type metadata | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 132 | int chip_width() const; | ~~~~~~~~~~~~~~~~~~~~~~~ 133 | int chip_height() const; | ~~~~~~~~~~~~~~~~~~~~~~~~ 134 | vector chip_cols() const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 135 | | 136 | // query tile metadata | ~~~~~~~~~~~~~~~~~~~~~~ 137 | string tile_type(int x, int y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 138 | int tile_width(const string &type) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 139 | | 140 | // cram bit manipulation | ~~~~~~~~~~~~~~~~~~~~~~~~ 141 | void cram_clear(); | ~~~~~~~~~~~~~~~~~~ 142 | void cram_fill_tiles(); | ~~~~~~~~~~~~~~~~~~~~~~~ 143 | void cram_checkerboard(int m = 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 144 | }; | ~~ 145 | | 146 | struct CramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 147 | { | ~ 148 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 149 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 150 | | 151 | string tile_type; | ~~~~~~~~~~~~~~~~~ 152 | int tile_width; | ~~~~~~~~~~~~~~~ 153 | int column_width; | ~~~~~~~~~~~~~~~~~ 154 | | 155 | bool left_right_io; | ~~~~~~~~~~~~~~~~~~~ 156 | bool right_half; | ~~~~~~~~~~~~~~~~ 157 | bool top_half; | ~~~~~~~~~~~~~~ 158 | | 159 | int bank_num; | ~~~~~~~~~~~~~ 160 | int bank_tx; | ~~~~~~~~~~~~ 161 | int bank_ty; | ~~~~~~~~~~~~ 162 | int bank_xoff; | ~~~~~~~~~~~~~~ 163 | int bank_yoff; | ~~~~~~~~~~~~~~ 164 | | 165 | CramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 166 | void get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 167 | }; | ~~ 168 | | 169 | struct BramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 170 | { | ~ 171 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 172 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 173 | | 174 | int bank_num; | ~~~~~~~~~~~~~ 175 | int bank_off; | ~~~~~~~~~~~~~ 176 | | 177 | BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 178 | void get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 179 | }; | ~~ 180 | | 181 | static void update_crc16(uint16_t &crc, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 182 | { | ~ 183 | // CRC-16-CCITT, Initialize to 0xFFFF, No zero padding | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 184 | for (int i = 7; i >= 0; i--) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 185 | uint16_t xor_value = ((crc >> 15) ^ ((byte >> i) & 1)) ? 0x1021 : 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 186 | crc = (crc << 1) ^ xor_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 187 | } | ~ 188 | } | ~ 189 | | 190 | static uint8_t read_byte(std::istream &ifs, uint16_t &crc_value, int &file_offset) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 191 | { | ~ 192 | int byte = ifs.get(); | ~~~~~~~~~~~~~~~~~~~~~ 193 | | 194 | if (byte < 0) | ~~~~~~~~~~~~~ 195 | error("Unexpected end of file.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 196 | | 197 | file_offset++; | ~~~~~~~~~~~~~~ 198 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 199 | | 200 | return byte; | ~~~~~~~~~~~~ 201 | } | ~ 202 | | 203 | static void write_byte(std::ostream &ofs, uint16_t &crc_value, int &file_offset, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 204 | { | ~ 205 | ofs << byte; | ~~~~~~~~~~~~ 206 | file_offset++; | ~~~~~~~~~~~~~~ 207 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 208 | } | ~ 209 | | 210 | void FpgaConfig::read_bits(std::istream &ifs) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 211 | { | ~ 212 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 213 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 214 | | 215 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 216 | info("Parsing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 217 | | 218 | // skip initial comments until preamble is found | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 219 | | 220 | uint32_t preamble = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 221 | | 222 | while (1) | ~~~~~~~~~ 223 | { | ~ 224 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 225 | preamble = (preamble << 8) | byte; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 226 | if (preamble == 0xffffffff) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 227 | error("No preamble found in bitstream.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 228 | if (preamble == 0x7EAA997E) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 229 | info("Found preamble at offset %d.\n", file_offset-4); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 230 | break; | ~~~~~~ 231 | } | ~ 232 | initblop.push_back(byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 233 | } | ~ 234 | | 235 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 236 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 237 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 238 | | 239 | // main parser loop | ~~~~~~~~~~~~~~~~~~~ 240 | | 241 | int current_bank = 0; | ~~~~~~~~~~~~~~~~~~~~~ 242 | int current_width = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 243 | int current_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 244 | int current_offset = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 245 | bool wakeup = false; | ~~~~~~~~~~~~~~~~~~~~ 246 | | 247 | this->cram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 248 | this->cram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 249 | | 250 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 251 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 252 | | 253 | while (!wakeup) | ~~~~~~~~~~~~~~~ 254 | { | ~ 255 | // one command byte. the lower 4 bits of the command byte specify | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 256 | // the length of the command payload. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 257 | | 258 | uint8_t command = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 259 | uint32_t payload = 0; | ~~~~~~~~~~~~~~~~~~~~~ 260 | | 261 | for (int i = 0; i < (command & 0x0f); i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 262 | payload = (payload << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 263 | | 264 | debug("Next command at offset %d: 0x%02x 0x%0*x\n", file_offset - 1 - (command & 0x0f), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 265 | command, 2*(command & 0x0f), payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 266 | | 267 | uint16_t end_token; | ~~~~~~~~~~~~~~~~~~~ 268 | | 269 | switch (command & 0xf0) | ~~~~~~~~~~~~~~~~~~~~~~~ 270 | { | ~ 271 | case 0x00: | ~~~~~~~~~~ 272 | switch (payload) | ~~~~~~~~~~~~~~~~ 273 | { | ~ 274 | case 0x01: | ~~~~~~~~~~ 275 | info("CRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 276 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 277 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 278 | | 279 | this->cram_width = std::max(this->cram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 280 | this->cram_height = std::max(this->cram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 281 | | 282 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 283 | this->cram[current_bank].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 284 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 285 | this->cram[current_bank][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 286 | | 287 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 288 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 289 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 290 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 291 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 292 | this->cram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 293 | } | ~ 294 | } | ~ 295 | | 296 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 297 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 298 | if (end_token) | ~~~~~~~~~~~~~~ 299 | error("Expeded 0x0000 after CRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 300 | break; | ~~~~~~ 301 | | 302 | case 0x03: | ~~~~~~~~~~ 303 | info("BRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 304 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 305 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 306 | | 307 | this->bram_width = std::max(this->bram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 308 | this->bram_height = std::max(this->bram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 309 | | 310 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 311 | this->bram[current_bank].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 312 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 313 | this->bram[current_bank][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 314 | | 315 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 316 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 317 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 318 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 319 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 320 | this->bram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 321 | } | ~ 322 | } | ~ 323 | | 324 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 325 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 326 | if (end_token) | ~~~~~~~~~~~~~~ 327 | error("Expeded 0x0000 after BRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 328 | break; | ~~~~~~ 329 | | 330 | case 0x05: | ~~~~~~~~~~ 331 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 332 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 333 | break; | ~~~~~~ 334 | | 335 | case 0x06: | ~~~~~~~~~~ 336 | info("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~ 337 | wakeup = true; | ~~~~~~~~~~~~~~ 338 | break; | ~~~~~~ 339 | | 340 | default: | ~~~~~~~~ 341 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 342 | } | ~ 343 | break; | ~~~~~~ 344 | | 345 | case 0x10: | ~~~~~~~~~~ 346 | current_bank = payload; | ~~~~~~~~~~~~~~~~~~~~~~~ 347 | debug("Set bank to %d.\n", current_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 348 | break; | ~~~~~~ 349 | | 350 | case 0x20: | ~~~~~~~~~~ 351 | if (crc_value != 0) | ~~~~~~~~~~~~~~~~~~~ 352 | error("CRC Check FAILED.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 353 | info("CRC Check OK.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~ 354 | break; | ~~~~~~ 355 | | 356 | case 0x50: | ~~~~~~~~~~ 357 | if (payload == 0) | ~~~~~~~~~~~~~~~~~ 358 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 359 | else if (payload == 1) | ~~~~~~~~~~~~~~~~~~~~~~ 360 | this->freqrange = "medium"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 361 | else if (payload == 2) | ~~~~~~~~~~~~~~~~~~~~~~ 362 | this->freqrange = "high"; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 363 | else | ~~~~ 364 | error("Unknown freqrange payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 365 | info("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 366 | break; | ~~~~~~ 367 | | 368 | case 0x60: | ~~~~~~~~~~ 369 | current_width = payload + 1; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 370 | debug("Setting bank width to %d.\n", current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 371 | break; | ~~~~~~ 372 | | 373 | case 0x70: | ~~~~~~~~~~ 374 | current_height = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 375 | debug("Setting bank height to %d.\n", current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 376 | break; | ~~~~~~ 377 | | 378 | case 0x80: | ~~~~~~~~~~ 379 | current_offset = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 380 | debug("Setting bank offset to %d.\n", current_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 381 | break; | ~~~~~~ 382 | | 383 | case 0x90: | ~~~~~~~~~~ 384 | switch(payload) | ~~~~~~~~~~~~~~~ 385 | { | ~ 386 | case 0: | ~~~~~~~ 387 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 388 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 389 | break; | ~~~~~~ 390 | case 1: | ~~~~~~~ 391 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 392 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 393 | break; | ~~~~~~ 394 | case 32: | ~~~~~~~~ 395 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 396 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 397 | break; | ~~~~~~ 398 | case 33: | ~~~~~~~~ 399 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 400 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 401 | break; | ~~~~~~ 402 | default: | ~~~~~~~~ 403 | error("Unknown warmboot/nosleep payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 404 | } | ~ 405 | info("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 406 | break; | ~~~~~~ 407 | | 408 | default: | ~~~~~~~~ 409 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 410 | } | ~ 411 | } | ~ 412 | | 413 | if (this->cram_width == 182 && this->cram_height == 80) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 414 | this->device = "384"; | ~~~~~~~~~~~~~~~~~~~~~ 415 | else if (this->cram_width == 332 && this->cram_height == 144) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 416 | this->device = "1k"; | ~~~~~~~~~~~~~~~~~~~~ 417 | else if (this->cram_width == 872 && this->cram_height == 272) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 418 | this->device = "8k"; | ~~~~~~~~~~~~~~~~~~~~ 419 | else if (this->cram_width == 692 && this->cram_height == 336) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 420 | this->device = "5k"; | ~~~~~~~~~~~~~~~~~~~~ 421 | else if (this->cram_width == 692 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 422 | this->device = "u4k"; | ~~~~~~~~~~~~~~~~~~~~~ 423 | else if (this->cram_width == 656 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 424 | this->device = "lm4k"; | ~~~~~~~~~~~~~~~~~~~~~~ 425 | else | ~~~~ 426 | error("Failed to detect chip type.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 427 | | 428 | info("Chip type is '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 429 | } | ~ 430 | | 431 | void FpgaConfig::write_bits(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 432 | { | ~ 433 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 434 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 435 | | 436 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 437 | info("Writing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 438 | | 439 | for (auto byte : this->initblop) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 440 | ofs << byte; | ~~~~~~~~~~~~ 441 | | 442 | debug("Writing preamble.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 443 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 444 | write_byte(ofs, crc_value, file_offset, 0xAA); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 445 | write_byte(ofs, crc_value, file_offset, 0x99); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 446 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 447 | | 448 | debug("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 449 | write_byte(ofs, crc_value, file_offset, 0x51); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 450 | if (this->freqrange == "low") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 451 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 452 | else if (this->freqrange == "medium") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 453 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 454 | else if (this->freqrange == "high") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 455 | write_byte(ofs, crc_value, file_offset, 0x02); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 456 | else | ~~~~ 457 | error("Unknown freqrange '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 458 | | 459 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 460 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 461 | write_byte(ofs, crc_value, file_offset, 0x05); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 462 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 463 | | 464 | { | ~ 465 | uint8_t nosleep_flag; | ~~~~~~~~~~~~~~~~~~~~~ 466 | debug("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 467 | write_byte(ofs, crc_value, file_offset, 0x92); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 468 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 469 | | 470 | if (this->nosleep == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 471 | nosleep_flag = 0; | ~~~~~~~~~~~~~~~~~ 472 | else if (this->nosleep == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 473 | nosleep_flag = 1; | ~~~~~~~~~~~~~~~~~ 474 | else | ~~~~ 475 | error("Unknown nosleep setting '%s'.\n", this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 476 | | 477 | if (this->warmboot == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 478 | write_byte(ofs, crc_value, file_offset, 0x00 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 479 | else if (this->warmboot == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 480 | write_byte(ofs, crc_value, file_offset, 0x20 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 481 | else | ~~~~ 482 | error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 483 | } | ~ 484 | | 485 | debug("CRAM: Setting bank width to %d.\n", this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 486 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 487 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 488 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 489 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 490 | debug("CRAM: Setting bank height to %d.\n", this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 491 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 492 | write_byte(ofs, crc_value, file_offset, this->cram_height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 493 | write_byte(ofs, crc_value, file_offset, this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 494 | } | ~ 495 | | 496 | debug("CRAM: Setting bank offset to 0.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 497 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 498 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 499 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 500 | | 501 | for (int cram_bank = 0; cram_bank < 4; cram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 502 | { | ~ 503 | vector cram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 504 | int height = this->cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 505 | if(this->device == "5k" && ((cram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 506 | height = height / 2 + 8; | ~~~~~~~~~~~~~~~~~~~~~~~~ 507 | for (int cram_y = 0; cram_y < height; cram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 508 | for (int cram_x = 0; cram_x < this->cram_width; cram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 509 | cram_bits.push_back(this->cram[cram_bank][cram_x][cram_y]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 510 | | 511 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 512 | debug("CRAM: Setting bank height to %d.\n", height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 513 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 514 | write_byte(ofs, crc_value, file_offset, height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 515 | write_byte(ofs, crc_value, file_offset, height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 516 | } | ~ 517 | | 518 | debug("CRAM: Setting bank %d.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 519 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 520 | write_byte(ofs, crc_value, file_offset, cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 521 | | 522 | debug("CRAM: Writing bank %d data.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 523 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 524 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 525 | for (int i = 0; i < int(cram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 526 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 527 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 528 | byte = (byte << 1) | (cram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 529 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 530 | } | ~ 531 | | 532 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 533 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 534 | } | ~ 535 | | 536 | int bram_chunk_size = 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 537 | | 538 | if (this->bram_width && this->bram_height) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 539 | { | ~ 540 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 541 | debug("BRAM: Setting bank width to %d.\n", this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 542 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 543 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 544 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 545 | } | ~ 546 | | 547 | | 548 | debug("BRAM: Setting bank height to %d.\n", this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 549 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 550 | write_byte(ofs, crc_value, file_offset, bram_chunk_size >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 551 | write_byte(ofs, crc_value, file_offset, bram_chunk_size); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 552 | | 553 | for (int bram_bank = 0; bram_bank < 4; bram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 554 | { | ~ 555 | debug("BRAM: Setting bank %d.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 556 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 557 | write_byte(ofs, crc_value, file_offset, bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 558 | | 559 | for (int offset = 0; offset < this->bram_height; offset += bram_chunk_size) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 560 | { | ~ 561 | vector bram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 562 | int width = this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 563 | if(this->device == "5k" && ((bram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 564 | width = width / 2; | ~~~~~~~~~~~~~~~~~~ 565 | for (int bram_y = 0; bram_y < bram_chunk_size; bram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 566 | for (int bram_x = 0; bram_x < width; bram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 567 | bram_bits.push_back(this->bram[bram_bank][bram_x][bram_y+offset]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 568 | | 569 | debug("BRAM: Setting bank offset to %d.\n", offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 570 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 571 | write_byte(ofs, crc_value, file_offset, offset >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 572 | write_byte(ofs, crc_value, file_offset, offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 573 | | 574 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 575 | debug("BRAM: Setting bank width to %d.\n", width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 576 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 577 | write_byte(ofs, crc_value, file_offset, (width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 578 | write_byte(ofs, crc_value, file_offset, (width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 579 | } | ~ 580 | | 581 | | 582 | debug("BRAM: Writing bank %d data.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 583 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 584 | write_byte(ofs, crc_value, file_offset, 0x03); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 585 | for (int i = 0; i < int(bram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 586 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 587 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 588 | byte = (byte << 1) | (bram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 589 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 590 | } | ~ 591 | | 592 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 593 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 594 | } | ~ 595 | } | ~ 596 | } | ~ 597 | | 598 | debug("Writing CRC value.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 599 | write_byte(ofs, crc_value, file_offset, 0x22); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 600 | uint8_t crc_hi = crc_value >> 8, crc_lo = crc_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 601 | write_byte(ofs, crc_value, file_offset, crc_hi); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 602 | write_byte(ofs, crc_value, file_offset, crc_lo); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 603 | | 604 | debug("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~~ 605 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 606 | write_byte(ofs, crc_value, file_offset, 0x06); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 607 | | 608 | debug("Padding byte.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 609 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 610 | } | ~ 611 | | 612 | void FpgaConfig::read_ascii(std::istream &ifs, bool nosleep) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 613 | { | ~ 614 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 615 | info("Parsing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 616 | | 617 | bool got_device = false; | ~~~~~~~~~~~~~~~~~~~~~~~~ 618 | this->cram.clear(); | ~~~~~~~~~~~~~~~~~~~ 619 | this->bram.clear(); | ~~~~~~~~~~~~~~~~~~~ 620 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 621 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 622 | | 623 | bool reuse_line = true; | ~~~~~~~~~~~~~~~~~~~~~~~ 624 | string line, command; | ~~~~~~~~~~~~~~~~~~~~~ 625 | | 626 | while (reuse_line || getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 627 | { | ~ 628 | reuse_line = false; | ~~~~~~~~~~~~~~~~~~~ 629 | | 630 | std::istringstream is(line); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 631 | is >> command; | ~~~~~~~~~~~~~~ 632 | | 633 | if (command.empty()) | ~~~~~~~~~~~~~~~~~~~~ 634 | continue; | ~~~~~~~~~ 635 | | 636 | debug("Next command: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 637 | | 638 | if (command == ".comment") | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 639 | { | ~ 640 | this->initblop.clear(); | ~~~~~~~~~~~~~~~~~~~~~~~ 641 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 642 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 643 | | 644 | while (getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 645 | { | ~ 646 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 647 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 648 | break; | ~~~~~~ 649 | } | ~ 650 | | 651 | for (auto ch : line) | ~~~~~~~~~~~~~~~~~~~~ 652 | this->initblop.push_back(ch); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 653 | this->initblop.push_back(0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 654 | } | ~ 655 | | 656 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 657 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 658 | continue; | ~~~~~~~~~ 659 | } | ~ 660 | | 661 | if (command == ".device") | ~~~~~~~~~~~~~~~~~~~~~~~~~ 662 | { | ~ 663 | if (got_device) | ~~~~~~~~~~~~~~~ 664 | error("More than one .device statement.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 665 | | 666 | is >> this->device; | ~~~~~~~~~~~~~~~~~~~ 667 | | 668 | if (this->device == "384") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 669 | this->cram_width = 182; | ~~~~~~~~~~~~~~~~~~~~~~~ 670 | this->cram_height = 80; | ~~~~~~~~~~~~~~~~~~~~~~~ 671 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 672 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 673 | } else | ~~~~~~ 674 | if (this->device == "1k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 675 | this->cram_width = 332; | ~~~~~~~~~~~~~~~~~~~~~~~ 676 | this->cram_height = 144; | ~~~~~~~~~~~~~~~~~~~~~~~~ 677 | this->bram_width = 64; | ~~~~~~~~~~~~~~~~~~~~~~ 678 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 679 | } else | ~~~~~~ 680 | if (this->device == "8k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 681 | this->cram_width = 872; | ~~~~~~~~~~~~~~~~~~~~~~~ 682 | this->cram_height = 272; | ~~~~~~~~~~~~~~~~~~~~~~~~ 683 | this->bram_width = 128; | ~~~~~~~~~~~~~~~~~~~~~~~ 684 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 685 | } else | ~~~~~~ 686 | if (this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 687 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 688 | this->cram_height = 336; | ~~~~~~~~~~~~~~~~~~~~~~~~ 689 | this->bram_width = 160; | ~~~~~~~~~~~~~~~~~~~~~~~ 690 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 691 | } else | ~~~~~~ 692 | if (this->device == "u4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 693 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 694 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 695 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 696 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 697 | } else | ~~~~~~ 698 | if (this->device == "lm4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 699 | this->cram_width = 656; | ~~~~~~~~~~~~~~~~~~~~~~~ 700 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 701 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 702 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 703 | } else | ~~~~~~ 704 | error("Unsupported chip type '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 705 | | 706 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 707 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 708 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 709 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 710 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 711 | this->cram[i][x].resize(((i % 2) == 1) ? (this->cram_height / 2 + 8) : this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 712 | } | ~ 713 | | 714 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 715 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 716 | int width = ((i % 2) == 1) ? (this->bram_width / 2) : this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 717 | this->bram[i].resize(width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 718 | for (int x = 0; x < width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 719 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 720 | } | ~ 721 | } else { | ~~~~~~~~ 722 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 723 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 724 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 725 | this->cram[i][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 726 | } | ~ 727 | | 728 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 729 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 730 | this->bram[i].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 731 | for (int x = 0; x < this->bram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 732 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 733 | } | ~ 734 | } | ~ 735 | | 736 | | 737 | got_device = true; | ~~~~~~~~~~~~~~~~~~ 738 | continue; | ~~~~~~~~~ 739 | } | ~ 740 | | 741 | if (command == ".warmboot") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 742 | { | ~ 743 | is >> this->warmboot; | ~~~~~~~~~~~~~~~~~~~~~ 744 | | 745 | if (this->warmboot != "disabled" && | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 746 | this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 747 | error("Unknown warmboot setting '%s'.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 748 | this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~ 749 | | 750 | continue; | ~~~~~~~~~ 751 | } | ~ 752 | | 753 | // No ".nosleep" section despite sharing the same byte as .warmboot. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 754 | // ".nosleep" is specified when icepack is invoked, which is too late. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 755 | // So we inject the section based on command line argument. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 756 | if (nosleep) | ~~~~~~~~~~~~ 757 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 758 | else | ~~~~ 759 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 760 | | 761 | if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile" || command.substr(0, 4) == ".dsp" || command == ".ipcon_tile") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 762 | { | ~ 763 | if (!got_device) | ~~~~~~~~~~~~~~~~ 764 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 765 | | 766 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 767 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 768 | | 769 | CramIndexConverter cic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 770 | | 771 | if (("." + cic.tile_type + "_tile") != command) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 772 | error("Got %s statement for %s tile %d %d.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 773 | command.c_str(), cic.tile_type.c_str(), tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 774 | | 775 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 776 | { | ~ 777 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 778 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 779 | break; | ~~~~~~ 780 | } | ~ 781 | | 782 | for (int bit_x = 0; bit_x < int(line.size()) && bit_x < cic.tile_width; bit_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 783 | if (line[bit_x] == '1') { | ~~~~~~~~~~~~~~~~~~~~~~~~~ 784 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 785 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 786 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 787 | } | ~ 788 | } | ~ 789 | | 790 | continue; | ~~~~~~~~~ 791 | } | ~ 792 | | 793 | if (command == ".ram_data") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 794 | { | ~ 795 | if (!got_device) | ~~~~~~~~~~~~~~~~ 796 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 797 | | 798 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 799 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 800 | | 801 | BramIndexConverter bic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 802 | | 803 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 804 | { | ~ 805 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 806 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 807 | break; | ~~~~~~ 808 | } | ~ 809 | | 810 | for (int bit_x = 256-4, ch_idx = 0; ch_idx < int(line.size()) && bit_x >= 0; bit_x -= 4, ch_idx++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 811 | { | ~ 812 | int value = -1; | ~~~~~~~~~~~~~~~ 813 | if ('0' <= line[ch_idx] && line[ch_idx] <= '9') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 814 | value = line[ch_idx] - '0'; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 815 | if ('a' <= line[ch_idx] && line[ch_idx] <= 'f') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 816 | value = line[ch_idx] - 'a' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 817 | if ('A' <= line[ch_idx] && line[ch_idx] <= 'F') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 818 | value = line[ch_idx] - 'A' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 819 | if (value < 0) | ~~~~~~~~~~~~~~ 820 | error("Not a hex character: '%c' (in line '%s')\n", line[ch_idx], line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 821 | | 822 | for (int i = 0; i < 4; i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 823 | if ((value & (1 << i)) != 0) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 824 | int bram_bank, bram_x, bram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 825 | bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 826 | this->bram[bram_bank][bram_x][bram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 827 | } | ~ 828 | } | ~ 829 | } | ~ 830 | | 831 | continue; | ~~~~~~~~~ 832 | } | ~ 833 | | 834 | if (command == ".extra_bit") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 835 | { | ~ 836 | if (!got_device) | ~~~~~~~~~~~~~~~~ 837 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 838 | | 839 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 840 | is >> cram_bank >> cram_x >> cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 841 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 842 | | 843 | continue; | ~~~~~~~~~ 844 | } | ~ 845 | | 846 | if (command == ".sym") | ~~~~~~~~~~~~~~~~~~~~~~ 847 | continue; | ~~~~~~~~~ 848 | | 849 | if (command.substr(0, 1) == ".") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 850 | error("Unknown statement: %s\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 851 | error("Unexpected data line: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 852 | } | ~ 853 | } | ~ 854 | | 855 | void FpgaConfig::write_ascii(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 856 | { | ~ 857 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 858 | info("Writing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 859 | | 860 | ofs << ".comment"; | ~~~~~~~~~~~~~~~~~~ 861 | bool insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 862 | for (auto ch : this->initblop) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 863 | if (ch == 0) { | ~~~~~~~~~~~~~~ 864 | insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~ 865 | } else if (ch == 0xff) { | ~~~~~~~~~~~~~~~~~~~~~~~~ 866 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 867 | } else { | ~~~~~~~~ 868 | if (insert_newline) | ~~~~~~~~~~~~~~~~~~~ 869 | ofs << '\n'; | ~~~~~~~~~~~~ 870 | ofs << ch; | ~~~~~~~~~~ 871 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 872 | } | ~ 873 | } | ~ 874 | | 875 | ofs << stringf("\n.device %s\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 876 | if (this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 877 | ofs << stringf(".warmboot %s\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 878 | | 879 | // As "nosleep" is an icepack command, we do not write out a ".nosleep" | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 880 | // section. However, we parse it in read_bits() and notify the user in | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 881 | // info. | ~~~~~~~~ 882 | | 883 | typedef std::tuple tile_bit_t; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 884 | std::set tile_bits; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 885 | | 886 | for (int y = 0; y <= this->chip_height()+1; y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 887 | for (int x = 0; x <= this->chip_width()+1; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 888 | { | ~ 889 | CramIndexConverter cic(this, x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 890 | | 891 | if (cic.tile_type == "corner" || cic.tile_type == "unsupported") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 892 | continue; | ~~~~~~~~~ 893 | | 894 | ofs << stringf(".%s_tile %d %d\n", cic.tile_type.c_str(), x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 895 | | 896 | for (int bit_y = 0; bit_y < 16; bit_y++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 897 | for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 898 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 899 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 900 | tile_bits.insert(tile_bit_t(cram_bank, cram_x, cram_y)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 901 | if (cram_x > int(this->cram[cram_bank].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 902 | error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 903 | } | ~ 904 | if (cram_y > int(this->cram[cram_bank][cram_x].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 905 | error("cram_y %d (bit %d, %d) larger than bank %d size %lu\n", cram_y, bit_x, bit_y, cram_bank, this->cram[cram_bank][cram_x].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 906 | } | ~ 907 | ofs << (this->cram[cram_bank][cram_x][cram_y] ? '1' : '0'); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 908 | } | ~ 909 | ofs << '\n'; | ~~~~~~~~~~~~ 910 | } | ~ 911 | | 912 | if (cic.tile_type == "ramb") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 913 | { | ~ 914 | BramIndexConverter bic(this, x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 915 | ofs << stringf(".ram_data %d %d\n", x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 916 | | 917 | for (int bit_y = 0; bit_y < 16; bit_y++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 918 | for (int bit_x = 256-4; bit_x >= 0; bit_x -= 4) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 919 | int value = 0; | ~~~~~~~~~~~~~~ 920 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 921 | int bram_bank, bram_x, bram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 922 | bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 923 | if (bram_x >= int(this->bram[bram_bank].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 924 | error("%d %d bram_x %d higher than loaded bram size %lu\n",bit_x+i, bit_y, bram_x, this->bram[bram_bank].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | std::vector >::size_type {aka unsigned int} icepack.cc:924:8: note: in expansion of macro 'error' 924 | error("%d %d bram_x %d higher than loaded bram size %lu\n",bit_x+i, bit_y, bram_x, this->bram[bram_bank].size()); | ^~~~~ icepack.cc:924:62: note: format string is defined here 924 | error("%d %d bram_x %d higher than loaded bram size %lu\n",bit_x+i, bit_y, bram_x, this->bram[bram_bank].size()); | ~~^ | | | long unsigned int | %u icepack.cc:53:41: warning: format '%lu' expects argument of type 'long unsigned int', but argument 4 has type 'std::vector::size_type' {aka 'unsigned int'} [-Wformat=] 53 | #define error(...) do { fprintf(stderr, "Error: " __VA_ARGS__); exit(1); } while (0) | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 54 | #define panic(fmt, ...) do { fprintf(stderr, "Internal Error at %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__); abort(); } while (0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 55 | | 56 | string vstringf(const char *fmt, va_list ap) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 57 | { | ~ 58 | string string; | ~~~~~~~~~~~~~~ 59 | char *str = NULL; | ~~~~~~~~~~~~~~~~~ 60 | | 61 | #ifdef _WIN32 | ~~~~~~~~~~~~~ 62 | int sz = 64, rc; | ~~~~~~~~~~~~~~~~ 63 | while (1) { | ~~~~~~~~~~~ 64 | va_list apc; | ~~~~~~~~~~~~ 65 | va_copy(apc, ap); | ~~~~~~~~~~~~~~~~~ 66 | str = (char*)realloc(str, sz); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 67 | rc = vsnprintf(str, sz, fmt, apc); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | va_end(apc); | ~~~~~~~~~~~~ 69 | if (rc >= 0 && rc < sz) | ~~~~~~~~~~~~~~~~~~~~~~~ 70 | break; | ~~~~~~ 71 | sz *= 2; | ~~~~~~~~ 72 | } | ~ 73 | #else | ~~~~~ 74 | if (vasprintf(&str, fmt, ap) < 0) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 75 | str = NULL; | ~~~~~~~~~~~ 76 | #endif | ~~~~~~ 77 | | 78 | if (str != NULL) { | ~~~~~~~~~~~~~~~~~~ 79 | string = str; | ~~~~~~~~~~~~~ 80 | free(str); | ~~~~~~~~~~ 81 | } | ~ 82 | | 83 | return string; | ~~~~~~~~~~~~~~ 84 | } | ~ 85 | | 86 | string stringf(const char *fmt, ...) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 87 | { | ~ 88 | string string; | ~~~~~~~~~~~~~~ 89 | va_list ap; | ~~~~~~~~~~~ 90 | | 91 | va_start(ap, fmt); | ~~~~~~~~~~~~~~~~~~ 92 | string = vstringf(fmt, ap); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 93 | va_end(ap); | ~~~~~~~~~~~ 94 | | 95 | return string; | ~~~~~~~~~~~~~~ 96 | } | ~ 97 | | 98 | // ================================================================== | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 99 | // FpgaConfig stuff | ~~~~~~~~~~~~~~~~~~~ 100 | | 101 | struct FpgaConfig | ~~~~~~~~~~~~~~~~~ 102 | { | ~ 103 | string device; | ~~~~~~~~~~~~~~ 104 | string freqrange; | ~~~~~~~~~~~~~~~~~ 105 | string nosleep; | ~~~~~~~~~~~~~~~ 106 | string warmboot; | ~~~~~~~~~~~~~~~~ 107 | | 108 | // cram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 109 | int cram_width, cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 110 | vector>> cram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 111 | | 112 | // bram[BANK][X][Y] | ~~~~~~~~~~~~~~~~~~~ 113 | int bram_width, bram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 114 | vector>> bram; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 115 | | 116 | // data before preamble | ~~~~~~~~~~~~~~~~~~~~~~~ 117 | vector initblop; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 118 | | 119 | // bitstream i/o | ~~~~~~~~~~~~~~~~ 120 | void read_bits(std::istream &ifs); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 121 | void write_bits(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 122 | | 123 | // icebox i/o | ~~~~~~~~~~~~~ 124 | void read_ascii(std::istream &ifs, bool nosleep); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 125 | void write_ascii(std::ostream &ofs) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 126 | | 127 | // netpbm i/o | ~~~~~~~~~~~~~ 128 | void write_cram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 129 | void write_bram_pbm(std::ostream &ofs, int bank_num = -1) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 130 | | 131 | // query chip type metadata | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 132 | int chip_width() const; | ~~~~~~~~~~~~~~~~~~~~~~~ 133 | int chip_height() const; | ~~~~~~~~~~~~~~~~~~~~~~~~ 134 | vector chip_cols() const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 135 | | 136 | // query tile metadata | ~~~~~~~~~~~~~~~~~~~~~~ 137 | string tile_type(int x, int y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 138 | int tile_width(const string &type) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 139 | | 140 | // cram bit manipulation | ~~~~~~~~~~~~~~~~~~~~~~~~ 141 | void cram_clear(); | ~~~~~~~~~~~~~~~~~~ 142 | void cram_fill_tiles(); | ~~~~~~~~~~~~~~~~~~~~~~~ 143 | void cram_checkerboard(int m = 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 144 | }; | ~~ 145 | | 146 | struct CramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 147 | { | ~ 148 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 149 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 150 | | 151 | string tile_type; | ~~~~~~~~~~~~~~~~~ 152 | int tile_width; | ~~~~~~~~~~~~~~~ 153 | int column_width; | ~~~~~~~~~~~~~~~~~ 154 | | 155 | bool left_right_io; | ~~~~~~~~~~~~~~~~~~~ 156 | bool right_half; | ~~~~~~~~~~~~~~~~ 157 | bool top_half; | ~~~~~~~~~~~~~~ 158 | | 159 | int bank_num; | ~~~~~~~~~~~~~ 160 | int bank_tx; | ~~~~~~~~~~~~ 161 | int bank_ty; | ~~~~~~~~~~~~ 162 | int bank_xoff; | ~~~~~~~~~~~~~~ 163 | int bank_yoff; | ~~~~~~~~~~~~~~ 164 | | 165 | CramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 166 | void get_cram_index(int bit_x, int bit_y, int &cram_bank, int &cram_x, int &cram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 167 | }; | ~~ 168 | | 169 | struct BramIndexConverter | ~~~~~~~~~~~~~~~~~~~~~~~~~ 170 | { | ~ 171 | const FpgaConfig *fpga; | ~~~~~~~~~~~~~~~~~~~~~~~ 172 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 173 | | 174 | int bank_num; | ~~~~~~~~~~~~~ 175 | int bank_off; | ~~~~~~~~~~~~~ 176 | | 177 | BramIndexConverter(const FpgaConfig *fpga, int tile_x, int tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 178 | void get_bram_index(int bit_x, int bit_y, int &bram_bank, int &bram_x, int &bram_y) const; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 179 | }; | ~~ 180 | | 181 | static void update_crc16(uint16_t &crc, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 182 | { | ~ 183 | // CRC-16-CCITT, Initialize to 0xFFFF, No zero padding | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 184 | for (int i = 7; i >= 0; i--) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 185 | uint16_t xor_value = ((crc >> 15) ^ ((byte >> i) & 1)) ? 0x1021 : 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 186 | crc = (crc << 1) ^ xor_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 187 | } | ~ 188 | } | ~ 189 | | 190 | static uint8_t read_byte(std::istream &ifs, uint16_t &crc_value, int &file_offset) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 191 | { | ~ 192 | int byte = ifs.get(); | ~~~~~~~~~~~~~~~~~~~~~ 193 | | 194 | if (byte < 0) | ~~~~~~~~~~~~~ 195 | error("Unexpected end of file.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 196 | | 197 | file_offset++; | ~~~~~~~~~~~~~~ 198 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 199 | | 200 | return byte; | ~~~~~~~~~~~~ 201 | } | ~ 202 | | 203 | static void write_byte(std::ostream &ofs, uint16_t &crc_value, int &file_offset, uint8_t byte) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 204 | { | ~ 205 | ofs << byte; | ~~~~~~~~~~~~ 206 | file_offset++; | ~~~~~~~~~~~~~~ 207 | update_crc16(crc_value, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 208 | } | ~ 209 | | 210 | void FpgaConfig::read_bits(std::istream &ifs) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 211 | { | ~ 212 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 213 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 214 | | 215 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 216 | info("Parsing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 217 | | 218 | // skip initial comments until preamble is found | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 219 | | 220 | uint32_t preamble = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 221 | | 222 | while (1) | ~~~~~~~~~ 223 | { | ~ 224 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 225 | preamble = (preamble << 8) | byte; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 226 | if (preamble == 0xffffffff) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 227 | error("No preamble found in bitstream.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 228 | if (preamble == 0x7EAA997E) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 229 | info("Found preamble at offset %d.\n", file_offset-4); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 230 | break; | ~~~~~~ 231 | } | ~ 232 | initblop.push_back(byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 233 | } | ~ 234 | | 235 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 236 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 237 | initblop.pop_back(); | ~~~~~~~~~~~~~~~~~~~~ 238 | | 239 | // main parser loop | ~~~~~~~~~~~~~~~~~~~ 240 | | 241 | int current_bank = 0; | ~~~~~~~~~~~~~~~~~~~~~ 242 | int current_width = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 243 | int current_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 244 | int current_offset = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 245 | bool wakeup = false; | ~~~~~~~~~~~~~~~~~~~~ 246 | | 247 | this->cram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 248 | this->cram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 249 | | 250 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 251 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 252 | | 253 | while (!wakeup) | ~~~~~~~~~~~~~~~ 254 | { | ~ 255 | // one command byte. the lower 4 bits of the command byte specify | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 256 | // the length of the command payload. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 257 | | 258 | uint8_t command = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 259 | uint32_t payload = 0; | ~~~~~~~~~~~~~~~~~~~~~ 260 | | 261 | for (int i = 0; i < (command & 0x0f); i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 262 | payload = (payload << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 263 | | 264 | debug("Next command at offset %d: 0x%02x 0x%0*x\n", file_offset - 1 - (command & 0x0f), | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 265 | command, 2*(command & 0x0f), payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 266 | | 267 | uint16_t end_token; | ~~~~~~~~~~~~~~~~~~~ 268 | | 269 | switch (command & 0xf0) | ~~~~~~~~~~~~~~~~~~~~~~~ 270 | { | ~ 271 | case 0x00: | ~~~~~~~~~~ 272 | switch (payload) | ~~~~~~~~~~~~~~~~ 273 | { | ~ 274 | case 0x01: | ~~~~~~~~~~ 275 | info("CRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 276 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 277 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 278 | | 279 | this->cram_width = std::max(this->cram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 280 | this->cram_height = std::max(this->cram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 281 | | 282 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 283 | this->cram[current_bank].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 284 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 285 | this->cram[current_bank][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 286 | | 287 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 288 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 289 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 290 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 291 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 292 | this->cram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 293 | } | ~ 294 | } | ~ 295 | | 296 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 297 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 298 | if (end_token) | ~~~~~~~~~~~~~~ 299 | error("Expeded 0x0000 after CRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 300 | break; | ~~~~~~ 301 | | 302 | case 0x03: | ~~~~~~~~~~ 303 | info("BRAM Data [%d]: %d x %d bits = %d bits = %d bytes\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 304 | current_bank, current_width, current_height, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 305 | current_height*current_width, (current_height*current_width)/8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 306 | | 307 | this->bram_width = std::max(this->bram_width, current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 308 | this->bram_height = std::max(this->bram_height, current_offset + current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 309 | | 310 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 311 | this->bram[current_bank].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 312 | for (int x = 0; x < current_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 313 | this->bram[current_bank][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 314 | | 315 | for (int i = 0; i < (current_height*current_width)/8; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 316 | uint8_t byte = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 317 | for (int j = 0; j < 8; j++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 318 | int x = (i*8 + j) % current_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 319 | int y = (i*8 + j) / current_width + current_offset; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 320 | this->bram[current_bank][x][y] = ((byte << j) & 0x80) != 0; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 321 | } | ~ 322 | } | ~ 323 | | 324 | end_token = read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 325 | end_token = (end_token << 8) | read_byte(ifs, crc_value, file_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 326 | if (end_token) | ~~~~~~~~~~~~~~ 327 | error("Expeded 0x0000 after BRAM data, got 0x%04x\n", end_token); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 328 | break; | ~~~~~~ 329 | | 330 | case 0x05: | ~~~~~~~~~~ 331 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 332 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 333 | break; | ~~~~~~ 334 | | 335 | case 0x06: | ~~~~~~~~~~ 336 | info("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~ 337 | wakeup = true; | ~~~~~~~~~~~~~~ 338 | break; | ~~~~~~ 339 | | 340 | default: | ~~~~~~~~ 341 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 342 | } | ~ 343 | break; | ~~~~~~ 344 | | 345 | case 0x10: | ~~~~~~~~~~ 346 | current_bank = payload; | ~~~~~~~~~~~~~~~~~~~~~~~ 347 | debug("Set bank to %d.\n", current_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 348 | break; | ~~~~~~ 349 | | 350 | case 0x20: | ~~~~~~~~~~ 351 | if (crc_value != 0) | ~~~~~~~~~~~~~~~~~~~ 352 | error("CRC Check FAILED.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 353 | info("CRC Check OK.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~ 354 | break; | ~~~~~~ 355 | | 356 | case 0x50: | ~~~~~~~~~~ 357 | if (payload == 0) | ~~~~~~~~~~~~~~~~~ 358 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 359 | else if (payload == 1) | ~~~~~~~~~~~~~~~~~~~~~~ 360 | this->freqrange = "medium"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 361 | else if (payload == 2) | ~~~~~~~~~~~~~~~~~~~~~~ 362 | this->freqrange = "high"; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 363 | else | ~~~~ 364 | error("Unknown freqrange payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 365 | info("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 366 | break; | ~~~~~~ 367 | | 368 | case 0x60: | ~~~~~~~~~~ 369 | current_width = payload + 1; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 370 | debug("Setting bank width to %d.\n", current_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 371 | break; | ~~~~~~ 372 | | 373 | case 0x70: | ~~~~~~~~~~ 374 | current_height = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 375 | debug("Setting bank height to %d.\n", current_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 376 | break; | ~~~~~~ 377 | | 378 | case 0x80: | ~~~~~~~~~~ 379 | current_offset = payload; | ~~~~~~~~~~~~~~~~~~~~~~~~~ 380 | debug("Setting bank offset to %d.\n", current_offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 381 | break; | ~~~~~~ 382 | | 383 | case 0x90: | ~~~~~~~~~~ 384 | switch(payload) | ~~~~~~~~~~~~~~~ 385 | { | ~ 386 | case 0: | ~~~~~~~ 387 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 388 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 389 | break; | ~~~~~~ 390 | case 1: | ~~~~~~~ 391 | this->warmboot = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 392 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 393 | break; | ~~~~~~ 394 | case 32: | ~~~~~~~~ 395 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 396 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 397 | break; | ~~~~~~ 398 | case 33: | ~~~~~~~~ 399 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 400 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 401 | break; | ~~~~~~ 402 | default: | ~~~~~~~~ 403 | error("Unknown warmboot/nosleep payload 0x%02x\n", payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 404 | } | ~ 405 | info("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 406 | break; | ~~~~~~ 407 | | 408 | default: | ~~~~~~~~ 409 | error("Unknown command: 0x%02x 0x%02x\n", command, payload); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 410 | } | ~ 411 | } | ~ 412 | | 413 | if (this->cram_width == 182 && this->cram_height == 80) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 414 | this->device = "384"; | ~~~~~~~~~~~~~~~~~~~~~ 415 | else if (this->cram_width == 332 && this->cram_height == 144) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 416 | this->device = "1k"; | ~~~~~~~~~~~~~~~~~~~~ 417 | else if (this->cram_width == 872 && this->cram_height == 272) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 418 | this->device = "8k"; | ~~~~~~~~~~~~~~~~~~~~ 419 | else if (this->cram_width == 692 && this->cram_height == 336) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 420 | this->device = "5k"; | ~~~~~~~~~~~~~~~~~~~~ 421 | else if (this->cram_width == 692 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 422 | this->device = "u4k"; | ~~~~~~~~~~~~~~~~~~~~~ 423 | else if (this->cram_width == 656 && this->cram_height == 176) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 424 | this->device = "lm4k"; | ~~~~~~~~~~~~~~~~~~~~~~ 425 | else | ~~~~ 426 | error("Failed to detect chip type.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 427 | | 428 | info("Chip type is '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 429 | } | ~ 430 | | 431 | void FpgaConfig::write_bits(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 432 | { | ~ 433 | int file_offset = 0; | ~~~~~~~~~~~~~~~~~~~~ 434 | uint16_t crc_value = 0; | ~~~~~~~~~~~~~~~~~~~~~~~ 435 | | 436 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 437 | info("Writing bitstream file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 438 | | 439 | for (auto byte : this->initblop) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 440 | ofs << byte; | ~~~~~~~~~~~~ 441 | | 442 | debug("Writing preamble.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 443 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 444 | write_byte(ofs, crc_value, file_offset, 0xAA); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 445 | write_byte(ofs, crc_value, file_offset, 0x99); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 446 | write_byte(ofs, crc_value, file_offset, 0x7E); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 447 | | 448 | debug("Setting freqrange to '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 449 | write_byte(ofs, crc_value, file_offset, 0x51); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 450 | if (this->freqrange == "low") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 451 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 452 | else if (this->freqrange == "medium") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 453 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 454 | else if (this->freqrange == "high") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 455 | write_byte(ofs, crc_value, file_offset, 0x02); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 456 | else | ~~~~ 457 | error("Unknown freqrange '%s'.\n", this->freqrange.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 458 | | 459 | debug("Resetting CRC.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 460 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 461 | write_byte(ofs, crc_value, file_offset, 0x05); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 462 | crc_value = 0xffff; | ~~~~~~~~~~~~~~~~~~~ 463 | | 464 | { | ~ 465 | uint8_t nosleep_flag; | ~~~~~~~~~~~~~~~~~~~~~ 466 | debug("Setting warmboot to '%s', nosleep to '%s'.\n", this->warmboot.c_str(), this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 467 | write_byte(ofs, crc_value, file_offset, 0x92); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 468 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 469 | | 470 | if (this->nosleep == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 471 | nosleep_flag = 0; | ~~~~~~~~~~~~~~~~~ 472 | else if (this->nosleep == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 473 | nosleep_flag = 1; | ~~~~~~~~~~~~~~~~~ 474 | else | ~~~~ 475 | error("Unknown nosleep setting '%s'.\n", this->nosleep.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 476 | | 477 | if (this->warmboot == "disabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 478 | write_byte(ofs, crc_value, file_offset, 0x00 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 479 | else if (this->warmboot == "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 480 | write_byte(ofs, crc_value, file_offset, 0x20 | nosleep_flag); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 481 | else | ~~~~ 482 | error("Unknown warmboot setting '%s'.\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 483 | } | ~ 484 | | 485 | debug("CRAM: Setting bank width to %d.\n", this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 486 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 487 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 488 | write_byte(ofs, crc_value, file_offset, (this->cram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 489 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 490 | debug("CRAM: Setting bank height to %d.\n", this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 491 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 492 | write_byte(ofs, crc_value, file_offset, this->cram_height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 493 | write_byte(ofs, crc_value, file_offset, this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 494 | } | ~ 495 | | 496 | debug("CRAM: Setting bank offset to 0.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 497 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 498 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 499 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 500 | | 501 | for (int cram_bank = 0; cram_bank < 4; cram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 502 | { | ~ 503 | vector cram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 504 | int height = this->cram_height; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 505 | if(this->device == "5k" && ((cram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 506 | height = height / 2 + 8; | ~~~~~~~~~~~~~~~~~~~~~~~~ 507 | for (int cram_y = 0; cram_y < height; cram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 508 | for (int cram_x = 0; cram_x < this->cram_width; cram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 509 | cram_bits.push_back(this->cram[cram_bank][cram_x][cram_y]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 510 | | 511 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 512 | debug("CRAM: Setting bank height to %d.\n", height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 513 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 514 | write_byte(ofs, crc_value, file_offset, height >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 515 | write_byte(ofs, crc_value, file_offset, height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 516 | } | ~ 517 | | 518 | debug("CRAM: Setting bank %d.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 519 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 520 | write_byte(ofs, crc_value, file_offset, cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 521 | | 522 | debug("CRAM: Writing bank %d data.\n", cram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 523 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 524 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 525 | for (int i = 0; i < int(cram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 526 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 527 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 528 | byte = (byte << 1) | (cram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 529 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 530 | } | ~ 531 | | 532 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 533 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 534 | } | ~ 535 | | 536 | int bram_chunk_size = 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 537 | | 538 | if (this->bram_width && this->bram_height) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 539 | { | ~ 540 | if(this->device != "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 541 | debug("BRAM: Setting bank width to %d.\n", this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 542 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 543 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 544 | write_byte(ofs, crc_value, file_offset, (this->bram_width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 545 | } | ~ 546 | | 547 | | 548 | debug("BRAM: Setting bank height to %d.\n", this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 549 | write_byte(ofs, crc_value, file_offset, 0x72); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 550 | write_byte(ofs, crc_value, file_offset, bram_chunk_size >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 551 | write_byte(ofs, crc_value, file_offset, bram_chunk_size); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 552 | | 553 | for (int bram_bank = 0; bram_bank < 4; bram_bank++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 554 | { | ~ 555 | debug("BRAM: Setting bank %d.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 556 | write_byte(ofs, crc_value, file_offset, 0x11); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 557 | write_byte(ofs, crc_value, file_offset, bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 558 | | 559 | for (int offset = 0; offset < this->bram_height; offset += bram_chunk_size) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 560 | { | ~ 561 | vector bram_bits; | ~~~~~~~~~~~~~~~~~~~~~~~ 562 | int width = this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 563 | if(this->device == "5k" && ((bram_bank % 2) == 1)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 564 | width = width / 2; | ~~~~~~~~~~~~~~~~~~ 565 | for (int bram_y = 0; bram_y < bram_chunk_size; bram_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 566 | for (int bram_x = 0; bram_x < width; bram_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 567 | bram_bits.push_back(this->bram[bram_bank][bram_x][bram_y+offset]); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 568 | | 569 | debug("BRAM: Setting bank offset to %d.\n", offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 570 | write_byte(ofs, crc_value, file_offset, 0x82); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 571 | write_byte(ofs, crc_value, file_offset, offset >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 572 | write_byte(ofs, crc_value, file_offset, offset); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 573 | | 574 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 575 | debug("BRAM: Setting bank width to %d.\n", width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 576 | write_byte(ofs, crc_value, file_offset, 0x62); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 577 | write_byte(ofs, crc_value, file_offset, (width-1) >> 8); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 578 | write_byte(ofs, crc_value, file_offset, (width-1)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 579 | } | ~ 580 | | 581 | | 582 | debug("BRAM: Writing bank %d data.\n", bram_bank); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 583 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 584 | write_byte(ofs, crc_value, file_offset, 0x03); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 585 | for (int i = 0; i < int(bram_bits.size()); i += 8) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 586 | uint8_t byte = 0; | ~~~~~~~~~~~~~~~~~ 587 | for (int j = 0; j < 8; j++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 588 | byte = (byte << 1) | (bram_bits[i+j] ? 1 : 0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 589 | write_byte(ofs, crc_value, file_offset, byte); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 590 | } | ~ 591 | | 592 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 593 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 594 | } | ~ 595 | } | ~ 596 | } | ~ 597 | | 598 | debug("Writing CRC value.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 599 | write_byte(ofs, crc_value, file_offset, 0x22); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 600 | uint8_t crc_hi = crc_value >> 8, crc_lo = crc_value; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 601 | write_byte(ofs, crc_value, file_offset, crc_hi); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 602 | write_byte(ofs, crc_value, file_offset, crc_lo); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 603 | | 604 | debug("Wakeup.\n"); | ~~~~~~~~~~~~~~~~~~~ 605 | write_byte(ofs, crc_value, file_offset, 0x01); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 606 | write_byte(ofs, crc_value, file_offset, 0x06); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 607 | | 608 | debug("Padding byte.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~ 609 | write_byte(ofs, crc_value, file_offset, 0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 610 | } | ~ 611 | | 612 | void FpgaConfig::read_ascii(std::istream &ifs, bool nosleep) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 613 | { | ~ 614 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 615 | info("Parsing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 616 | | 617 | bool got_device = false; | ~~~~~~~~~~~~~~~~~~~~~~~~ 618 | this->cram.clear(); | ~~~~~~~~~~~~~~~~~~~ 619 | this->bram.clear(); | ~~~~~~~~~~~~~~~~~~~ 620 | this->freqrange = "low"; | ~~~~~~~~~~~~~~~~~~~~~~~~ 621 | this->warmboot = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 622 | | 623 | bool reuse_line = true; | ~~~~~~~~~~~~~~~~~~~~~~~ 624 | string line, command; | ~~~~~~~~~~~~~~~~~~~~~ 625 | | 626 | while (reuse_line || getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 627 | { | ~ 628 | reuse_line = false; | ~~~~~~~~~~~~~~~~~~~ 629 | | 630 | std::istringstream is(line); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 631 | is >> command; | ~~~~~~~~~~~~~~ 632 | | 633 | if (command.empty()) | ~~~~~~~~~~~~~~~~~~~~ 634 | continue; | ~~~~~~~~~ 635 | | 636 | debug("Next command: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 637 | | 638 | if (command == ".comment") | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 639 | { | ~ 640 | this->initblop.clear(); | ~~~~~~~~~~~~~~~~~~~~~~~ 641 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 642 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 643 | | 644 | while (getline(ifs, line)) | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 645 | { | ~ 646 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 647 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 648 | break; | ~~~~~~ 649 | } | ~ 650 | | 651 | for (auto ch : line) | ~~~~~~~~~~~~~~~~~~~~ 652 | this->initblop.push_back(ch); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 653 | this->initblop.push_back(0); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 654 | } | ~ 655 | | 656 | this->initblop.push_back(0x00); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 657 | this->initblop.push_back(0xff); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 658 | continue; | ~~~~~~~~~ 659 | } | ~ 660 | | 661 | if (command == ".device") | ~~~~~~~~~~~~~~~~~~~~~~~~~ 662 | { | ~ 663 | if (got_device) | ~~~~~~~~~~~~~~~ 664 | error("More than one .device statement.\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 665 | | 666 | is >> this->device; | ~~~~~~~~~~~~~~~~~~~ 667 | | 668 | if (this->device == "384") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 669 | this->cram_width = 182; | ~~~~~~~~~~~~~~~~~~~~~~~ 670 | this->cram_height = 80; | ~~~~~~~~~~~~~~~~~~~~~~~ 671 | this->bram_width = 0; | ~~~~~~~~~~~~~~~~~~~~~ 672 | this->bram_height = 0; | ~~~~~~~~~~~~~~~~~~~~~~ 673 | } else | ~~~~~~ 674 | if (this->device == "1k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 675 | this->cram_width = 332; | ~~~~~~~~~~~~~~~~~~~~~~~ 676 | this->cram_height = 144; | ~~~~~~~~~~~~~~~~~~~~~~~~ 677 | this->bram_width = 64; | ~~~~~~~~~~~~~~~~~~~~~~ 678 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 679 | } else | ~~~~~~ 680 | if (this->device == "8k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 681 | this->cram_width = 872; | ~~~~~~~~~~~~~~~~~~~~~~~ 682 | this->cram_height = 272; | ~~~~~~~~~~~~~~~~~~~~~~~~ 683 | this->bram_width = 128; | ~~~~~~~~~~~~~~~~~~~~~~~ 684 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 685 | } else | ~~~~~~ 686 | if (this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 687 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 688 | this->cram_height = 336; | ~~~~~~~~~~~~~~~~~~~~~~~~ 689 | this->bram_width = 160; | ~~~~~~~~~~~~~~~~~~~~~~~ 690 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 691 | } else | ~~~~~~ 692 | if (this->device == "u4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 693 | this->cram_width = 692; | ~~~~~~~~~~~~~~~~~~~~~~~ 694 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 695 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 696 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 697 | } else | ~~~~~~ 698 | if (this->device == "lm4k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 699 | this->cram_width = 656; | ~~~~~~~~~~~~~~~~~~~~~~~ 700 | this->cram_height = 176; | ~~~~~~~~~~~~~~~~~~~~~~~~ 701 | this->bram_width = 80; | ~~~~~~~~~~~~~~~~~~~~~~ 702 | this->bram_height = 2 * 128; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 703 | } else | ~~~~~~ 704 | error("Unsupported chip type '%s'.\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 705 | | 706 | this->cram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 707 | if(this->device == "5k") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 708 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 709 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 710 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 711 | this->cram[i][x].resize(((i % 2) == 1) ? (this->cram_height / 2 + 8) : this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 712 | } | ~ 713 | | 714 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 715 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 716 | int width = ((i % 2) == 1) ? (this->bram_width / 2) : this->bram_width; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 717 | this->bram[i].resize(width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 718 | for (int x = 0; x < width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 719 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 720 | } | ~ 721 | } else { | ~~~~~~~~ 722 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 723 | this->cram[i].resize(this->cram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 724 | for (int x = 0; x < this->cram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 725 | this->cram[i][x].resize(this->cram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 726 | } | ~ 727 | | 728 | this->bram.resize(4); | ~~~~~~~~~~~~~~~~~~~~~ 729 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 730 | this->bram[i].resize(this->bram_width); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 731 | for (int x = 0; x < this->bram_width; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 732 | this->bram[i][x].resize(this->bram_height); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 733 | } | ~ 734 | } | ~ 735 | | 736 | | 737 | got_device = true; | ~~~~~~~~~~~~~~~~~~ 738 | continue; | ~~~~~~~~~ 739 | } | ~ 740 | | 741 | if (command == ".warmboot") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 742 | { | ~ 743 | is >> this->warmboot; | ~~~~~~~~~~~~~~~~~~~~~ 744 | | 745 | if (this->warmboot != "disabled" && | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 746 | this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 747 | error("Unknown warmboot setting '%s'.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 748 | this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~ 749 | | 750 | continue; | ~~~~~~~~~ 751 | } | ~ 752 | | 753 | // No ".nosleep" section despite sharing the same byte as .warmboot. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 754 | // ".nosleep" is specified when icepack is invoked, which is too late. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 755 | // So we inject the section based on command line argument. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 756 | if (nosleep) | ~~~~~~~~~~~~ 757 | this->nosleep = "enabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~ 758 | else | ~~~~ 759 | this->nosleep = "disabled"; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 760 | | 761 | if (command == ".io_tile" || command == ".logic_tile" || command == ".ramb_tile" || command == ".ramt_tile" || command.substr(0, 4) == ".dsp" || command == ".ipcon_tile") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 762 | { | ~ 763 | if (!got_device) | ~~~~~~~~~~~~~~~~ 764 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 765 | | 766 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 767 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 768 | | 769 | CramIndexConverter cic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 770 | | 771 | if (("." + cic.tile_type + "_tile") != command) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 772 | error("Got %s statement for %s tile %d %d.\n", | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 773 | command.c_str(), cic.tile_type.c_str(), tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 774 | | 775 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 776 | { | ~ 777 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 778 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 779 | break; | ~~~~~~ 780 | } | ~ 781 | | 782 | for (int bit_x = 0; bit_x < int(line.size()) && bit_x < cic.tile_width; bit_x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 783 | if (line[bit_x] == '1') { | ~~~~~~~~~~~~~~~~~~~~~~~~~ 784 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 785 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 786 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 787 | } | ~ 788 | } | ~ 789 | | 790 | continue; | ~~~~~~~~~ 791 | } | ~ 792 | | 793 | if (command == ".ram_data") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 794 | { | ~ 795 | if (!got_device) | ~~~~~~~~~~~~~~~~ 796 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 797 | | 798 | int tile_x, tile_y; | ~~~~~~~~~~~~~~~~~~~ 799 | is >> tile_x >> tile_y; | ~~~~~~~~~~~~~~~~~~~~~~~ 800 | | 801 | BramIndexConverter bic(this, tile_x, tile_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 802 | | 803 | for (int bit_y = 0; bit_y < 16 && getline(ifs, line); bit_y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 804 | { | ~ 805 | if (line.substr(0, 1) == ".") { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 806 | reuse_line = true; | ~~~~~~~~~~~~~~~~~~ 807 | break; | ~~~~~~ 808 | } | ~ 809 | | 810 | for (int bit_x = 256-4, ch_idx = 0; ch_idx < int(line.size()) && bit_x >= 0; bit_x -= 4, ch_idx++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 811 | { | ~ 812 | int value = -1; | ~~~~~~~~~~~~~~~ 813 | if ('0' <= line[ch_idx] && line[ch_idx] <= '9') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 814 | value = line[ch_idx] - '0'; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 815 | if ('a' <= line[ch_idx] && line[ch_idx] <= 'f') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 816 | value = line[ch_idx] - 'a' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 817 | if ('A' <= line[ch_idx] && line[ch_idx] <= 'F') | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 818 | value = line[ch_idx] - 'A' + 10; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 819 | if (value < 0) | ~~~~~~~~~~~~~~ 820 | error("Not a hex character: '%c' (in line '%s')\n", line[ch_idx], line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 821 | | 822 | for (int i = 0; i < 4; i++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 823 | if ((value & (1 << i)) != 0) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 824 | int bram_bank, bram_x, bram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 825 | bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 826 | this->bram[bram_bank][bram_x][bram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 827 | } | ~ 828 | } | ~ 829 | } | ~ 830 | | 831 | continue; | ~~~~~~~~~ 832 | } | ~ 833 | | 834 | if (command == ".extra_bit") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 835 | { | ~ 836 | if (!got_device) | ~~~~~~~~~~~~~~~~ 837 | error("Missing .device statement before %s.\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 838 | | 839 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 840 | is >> cram_bank >> cram_x >> cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 841 | this->cram[cram_bank][cram_x][cram_y] = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 842 | | 843 | continue; | ~~~~~~~~~ 844 | } | ~ 845 | | 846 | if (command == ".sym") | ~~~~~~~~~~~~~~~~~~~~~~ 847 | continue; | ~~~~~~~~~ 848 | | 849 | if (command.substr(0, 1) == ".") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 850 | error("Unknown statement: %s\n", command.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 851 | error("Unexpected data line: %s\n", line.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 852 | } | ~ 853 | } | ~ 854 | | 855 | void FpgaConfig::write_ascii(std::ostream &ofs) const | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 856 | { | ~ 857 | debug("## %s\n", __PRETTY_FUNCTION__); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 858 | info("Writing ascii file..\n"); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 859 | | 860 | ofs << ".comment"; | ~~~~~~~~~~~~~~~~~~ 861 | bool insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 862 | for (auto ch : this->initblop) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 863 | if (ch == 0) { | ~~~~~~~~~~~~~~ 864 | insert_newline = true; | ~~~~~~~~~~~~~~~~~~~~~~ 865 | } else if (ch == 0xff) { | ~~~~~~~~~~~~~~~~~~~~~~~~ 866 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 867 | } else { | ~~~~~~~~ 868 | if (insert_newline) | ~~~~~~~~~~~~~~~~~~~ 869 | ofs << '\n'; | ~~~~~~~~~~~~ 870 | ofs << ch; | ~~~~~~~~~~ 871 | insert_newline = false; | ~~~~~~~~~~~~~~~~~~~~~~~ 872 | } | ~ 873 | } | ~ 874 | | 875 | ofs << stringf("\n.device %s\n", this->device.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 876 | if (this->warmboot != "enabled") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 877 | ofs << stringf(".warmboot %s\n", this->warmboot.c_str()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 878 | | 879 | // As "nosleep" is an icepack command, we do not write out a ".nosleep" | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 880 | // section. However, we parse it in read_bits() and notify the user in | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 881 | // info. | ~~~~~~~~ 882 | | 883 | typedef std::tuple tile_bit_t; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 884 | std::set tile_bits; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 885 | | 886 | for (int y = 0; y <= this->chip_height()+1; y++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 887 | for (int x = 0; x <= this->chip_width()+1; x++) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 888 | { | ~ 889 | CramIndexConverter cic(this, x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 890 | | 891 | if (cic.tile_type == "corner" || cic.tile_type == "unsupported") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 892 | continue; | ~~~~~~~~~ 893 | | 894 | ofs << stringf(".%s_tile %d %d\n", cic.tile_type.c_str(), x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 895 | | 896 | for (int bit_y = 0; bit_y < 16; bit_y++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 897 | for (int bit_x = 0; bit_x < cic.tile_width; bit_x++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 898 | int cram_bank, cram_x, cram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 899 | cic.get_cram_index(bit_x, bit_y, cram_bank, cram_x, cram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 900 | tile_bits.insert(tile_bit_t(cram_bank, cram_x, cram_y)); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 901 | if (cram_x > int(this->cram[cram_bank].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 902 | error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 903 | } | ~ 904 | if (cram_y > int(this->cram[cram_bank][cram_x].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 905 | error("cram_y %d (bit %d, %d) larger than bank %d size %lu\n", cram_y, bit_x, bit_y, cram_bank, this->cram[cram_bank][cram_x].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 906 | } | ~ 907 | ofs << (this->cram[cram_bank][cram_x][cram_y] ? '1' : '0'); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 908 | } | ~ 909 | ofs << '\n'; | ~~~~~~~~~~~~ 910 | } | ~ 911 | | 912 | if (cic.tile_type == "ramb") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 913 | { | ~ 914 | BramIndexConverter bic(this, x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 915 | ofs << stringf(".ram_data %d %d\n", x, y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 916 | | 917 | for (int bit_y = 0; bit_y < 16; bit_y++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 918 | for (int bit_x = 256-4; bit_x >= 0; bit_x -= 4) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 919 | int value = 0; | ~~~~~~~~~~~~~~ 920 | for (int i = 0; i < 4; i++) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 921 | int bram_bank, bram_x, bram_y; | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 922 | bic.get_bram_index(bit_x+i, bit_y, bram_bank, bram_x, bram_y); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 923 | if (bram_x >= int(this->bram[bram_bank].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 924 | error("%d %d bram_x %d higher than loaded bram size %lu\n",bit_x+i, bit_y, bram_x, this->bram[bram_bank].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 925 | break; | ~~~~~~ 926 | } | ~ 927 | if (bram_y >= int(this->bram[bram_bank][bram_x].size())) { | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 928 | error("bram_y %d higher than loaded bram size %lu\n", bram_y, this->bram[bram_bank][bram_x].size()); | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | | | std::vector::size_type {aka unsigned int} icepack.cc:928:8: note: in expansion of macro 'error' 928 | error("bram_y %d higher than loaded bram size %lu\n", bram_y, this->bram[bram_bank][bram_x].size()); | ^~~~~ icepack.cc:928:56: note: format string is defined here 928 | error("bram_y %d higher than loaded bram size %lu\n", bram_y, this->bram[bram_bank][bram_x].size()); | ~~^ | | | long unsigned int | %u make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icepack' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icepack' g++ -o icepack icepack.o -lftdi1 -lusb-1.0 -lm make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icepack' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icepack' ln -sf icepack iceunpack make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icepack' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/iceprog' gcc -pipe -frecord-gcc-switches -Wall -g -O2 -march=i586 -mtune=generic -Wextra -I/usr/include/libftdi1 -I/usr/include/libusb-1.0 -c -o iceprog.o iceprog.c make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/iceprog' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/iceprog' gcc -o iceprog iceprog.o -lftdi1 -lusb-1.0 -lm make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/iceprog' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icemulti' g++ -pipe -frecord-gcc-switches -Wall -g -O2 -march=i586 -mtune=generic -Wextra -c -o icemulti.o icemulti.cc make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icemulti' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icemulti' g++ -o icemulti icemulti.o -lftdi1 -lusb-1.0 -lm make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icemulti' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icepll' g++ -pipe -frecord-gcc-switches -Wall -g -O2 -march=i586 -mtune=generic -Wextra -c -o icepll.o icepll.cc make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icepll' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icepll' g++ -o icepll icepll.o -lftdi1 -lusb-1.0 -lm make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icepll' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icetime' python3 timings.py > timings.inc.new mv timings.inc.new timings.inc make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icetime' make[1]: Entering directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icetime' g++ -pipe -frecord-gcc-switches -Wall -g -O2 -march=i586 -mtune=generic -Wextra -DPREFIX='"/usr/local"' -DCHIPDB_SUBDIR='"icebox"' -c -o icetime.o icetime.cc icetime.cc: In function 'std::string ecnetname_to_vlog(std::string)': icetime.cc:1318:15: error: 'invalid_argument' in namespace 'std' does not name a type 1318 | } catch(std::invalid_argument e) { // Not numeric and stoi throws exception | ^~~~~~~~~~~~~~~~ make[1]: *** [: icetime.o] Error 1 make[1]: Leaving directory '/usr/src/RPM/BUILD/icestorm-0.0.0.618.gf029975/icetime' make: *** [Makefile:6: all] Error 2 error: Bad exit status from /usr/src/tmp/rpm-tmp.79100 (%build) RPM build errors: Bad exit status from /usr/src/tmp/rpm-tmp.79100 (%build) Command exited with non-zero status 1 228.61user 0.75system 1:54.26elapsed 200%CPU (0avgtext+0avgdata 234772maxresident)k 0inputs+0outputs (0major+288573minor)pagefaults 0swaps hsh-rebuild: rebuild of `icestorm-0.0.0.618.gf029975-alt2.src.rpm' failed. Command exited with non-zero status 1 235.69user 3.22system 2:09.10elapsed 185%CPU (0avgtext+0avgdata 234772maxresident)k 144inputs+0outputs (0major+628293minor)pagefaults 0swaps