From ad21a3bb36ac46fd94b60a4a5901ace888a68f2d Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Sat, 30 Jan 2021 07:57:49 +0100 Subject: [PATCH] recast verbose to int8_t to have more level of verbosity (-1 quiet, 0 normal, 1 verbose), add --quiet option, display progress bar when verbosity level >= 0 --- README.md | 1 + src/altera.cpp | 4 ++-- src/altera.hpp | 2 +- src/anlogic.cpp | 4 ++-- src/anlogic.hpp | 2 +- src/device.cpp | 6 +++--- src/device.hpp | 3 ++- src/efinix.cpp | 2 +- src/efinix.hpp | 2 +- src/gowin.cpp | 6 +++--- src/gowin.hpp | 2 +- src/ice40.cpp | 4 ++-- src/ice40.hpp | 2 +- src/lattice.cpp | 15 ++++++++------ src/lattice.hpp | 2 +- src/main.cpp | 27 ++++++++++++++++++------- src/progressBar.cpp | 33 +++++++++++++++++++++---------- src/progressBar.hpp | 5 ++++- src/spiFlash.cpp | 48 ++++++++++++++++++++++++++++----------------- src/spiFlash.hpp | 4 ++-- src/xilinx.cpp | 6 +++--- src/xilinx.hpp | 2 +- 22 files changed, 114 insertions(+), 68 deletions(-) diff --git a/README.md b/README.md index fddd15f..1fb5f6d 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,7 @@ openFPGALoader -- a program to flash FPGA Gowin and ECP5 devices) -o, --offset arg start offset in EEPROM --pins arg pin config (only for ft232R) TDI:TDO:TCK:TMS + --quiet Produce quiet output (no progress bar) -r, --reset reset FPGA after operations --spi SPI mode (only for FTDI in serial mode) -v, --verbose Produce verbose output diff --git a/src/altera.cpp b/src/altera.cpp index 551a9bb..5061cc9 100644 --- a/src/altera.cpp +++ b/src/altera.cpp @@ -16,7 +16,7 @@ // DATA_DIR is defined at compile time. #define BIT_FOR_FLASH (DATA_DIR "/openFPGALoader/test_sfl.svf") -Altera::Altera(Jtag *jtag, const std::string &filename, bool verbose): +Altera::Altera(Jtag *jtag, const std::string &filename, int8_t verbose): Device(jtag, filename, verbose), _svf(_jtag, _verbose) { if (_filename != "") { @@ -60,7 +60,7 @@ void Altera::programMem() _jtag->set_state(Jtag::RUN_TEST_IDLE); _jtag->toggleClk(12000); /* write */ - ProgressBar progress("Flash SRAM", byte_length, 50); + ProgressBar progress("Flash SRAM", byte_length, 50, _quiet); /* 2.2.6.5 */ _jtag->set_state(Jtag::SHIFT_DR); diff --git a/src/altera.hpp b/src/altera.hpp index 55770fa..0a9aaaf 100644 --- a/src/altera.hpp +++ b/src/altera.hpp @@ -9,7 +9,7 @@ class Altera: public Device { public: - Altera(Jtag *jtag, const std::string &filename, bool verbose); + Altera(Jtag *jtag, const std::string &filename, int8_t verbose); ~Altera(); void programMem(); diff --git a/src/anlogic.cpp b/src/anlogic.cpp index 49d4961..ef97e26 100644 --- a/src/anlogic.cpp +++ b/src/anlogic.cpp @@ -34,7 +34,7 @@ #define IRLENGTH 8 Anlogic::Anlogic(Jtag *jtag, const std::string &filename, - bool flash_wr, bool sram_wr, bool verbose): + bool flash_wr, bool sram_wr, int8_t verbose): Device(jtag, filename, verbose), _svf(_jtag, _verbose) { (void)flash_wr; @@ -140,7 +140,7 @@ void Anlogic::program(unsigned int offset) _jtag->toggleClk(15); _jtag->set_state(Jtag::SHIFT_DR); - ProgressBar progress("Loading", len, 50); + ProgressBar progress("Loading", len, 50, _quiet); int pos = 0; uint8_t *ptr = data; while (len > 0) { diff --git a/src/anlogic.hpp b/src/anlogic.hpp index 25924ff..139845a 100644 --- a/src/anlogic.hpp +++ b/src/anlogic.hpp @@ -29,7 +29,7 @@ class Anlogic: public Device, SPIInterface { public: Anlogic(Jtag *jtag, const std::string &filename, - bool flash_wr, bool sram_wr, bool verbose); + bool flash_wr, bool sram_wr, int8_t verbose); ~Anlogic(); void program(unsigned int offset = 0) override; diff --git a/src/device.cpp b/src/device.cpp index 599c2d8..def41ee 100644 --- a/src/device.cpp +++ b/src/device.cpp @@ -5,13 +5,13 @@ using namespace std; -Device::Device(Jtag *jtag, string filename, bool verbose): +Device::Device(Jtag *jtag, string filename, int8_t verbose): _filename(filename), _file_extension(filename.substr(filename.find_last_of(".") +1)), - _mode(NONE_MODE), _verbose(verbose) + _mode(NONE_MODE), _verbose(verbose > 0), _quiet(verbose < 0) { _jtag = jtag; - if (_verbose) + if (verbose > 0) cout << "File type : " << _file_extension << endl; } diff --git a/src/device.hpp b/src/device.hpp index b76b474..f320ac6 100644 --- a/src/device.hpp +++ b/src/device.hpp @@ -18,7 +18,7 @@ class Device { FLASH_MODE = 1, MEM_MODE = 2 }; - Device(Jtag *jtag, std::string filename, bool verbose = false); + Device(Jtag *jtag, std::string filename, int8_t verbose = false); virtual ~Device(); virtual void program(unsigned int offset = 0) = 0; virtual int idCode() = 0; @@ -29,6 +29,7 @@ class Device { std::string _file_extension; enum prog_mode _mode; bool _verbose; + bool _quiet; }; #endif diff --git a/src/efinix.cpp b/src/efinix.cpp index 2e9adba..09f4d58 100644 --- a/src/efinix.cpp +++ b/src/efinix.cpp @@ -32,7 +32,7 @@ Efinix::Efinix(FtdiSpi* spi, const std::string &filename, uint16_t rst_pin, uint16_t done_pin, - bool verbose): + int8_t verbose): Device(NULL, filename, verbose), _rst_pin(rst_pin), _done_pin(done_pin) { diff --git a/src/efinix.hpp b/src/efinix.hpp index f0bd9cb..219f788 100644 --- a/src/efinix.hpp +++ b/src/efinix.hpp @@ -27,7 +27,7 @@ class Efinix: public Device { public: Efinix(FtdiSpi *spi, const std::string &filename, uint16_t rst_pin, uint16_t done_pin, - bool verbose); + int8_t verbose); ~Efinix(); void program(unsigned int offset = 0) override; diff --git a/src/gowin.cpp b/src/gowin.cpp index 0cf6ba6..1e13ad1 100644 --- a/src/gowin.cpp +++ b/src/gowin.cpp @@ -70,7 +70,7 @@ using namespace std; #define EFLASH_ERASE 0x75 Gowin::Gowin(Jtag *jtag, const string filename, bool flash_wr, bool sram_wr, - bool verbose): Device(jtag, filename, verbose), is_gw1n1(false) + int8_t verbose): Device(jtag, filename, verbose), is_gw1n1(false) { _fs = NULL; if (_filename != "") { @@ -376,7 +376,7 @@ bool Gowin::flashFLASH(uint8_t *data, int length) memcpy(buffer+6*4, data, byte_length); - ProgressBar progress("write Flash", buffer_length, 50); + ProgressBar progress("write Flash", buffer_length, 50, _quiet); for (int i=0, xpage=0; xpage < nb_xpage; i+=(nb_iter*4), xpage++) { wr_rd(CONFIG_ENABLE, NULL, 0, NULL, 0); @@ -427,7 +427,7 @@ bool Gowin::flashSRAM(uint8_t *data, int length) int tx_len, tx_end; int byte_length = length / 8; - ProgressBar progress("Flash SRAM", byte_length, 50); + ProgressBar progress("Flash SRAM", byte_length, 50, _quiet); /* 2.2.6.4 */ wr_rd(XFER_WRITE, NULL, 0, NULL, 0); diff --git a/src/gowin.hpp b/src/gowin.hpp index 585d377..0fdf10c 100644 --- a/src/gowin.hpp +++ b/src/gowin.hpp @@ -31,7 +31,7 @@ class Gowin: public Device { public: Gowin(Jtag *jtag, std::string filename, bool flash_wr, bool sram_wr, - bool verbose); + int8_t verbose); ~Gowin(); int idCode() override; void reset() override; diff --git a/src/ice40.cpp b/src/ice40.cpp index 1a1b379..4ebe39f 100644 --- a/src/ice40.cpp +++ b/src/ice40.cpp @@ -31,7 +31,7 @@ Ice40::Ice40(FtdiSpi* spi, const std::string &filename, uint16_t rst_pin, uint16_t done_pin, - bool verbose): + int8_t verbose): Device(NULL, filename, verbose), _rst_pin(rst_pin), _done_pin(done_pin) { @@ -79,7 +79,7 @@ void Ice40::program(unsigned int offset) _spi->gpio_clear(_rst_pin); - SPIFlash flash(reinterpret_cast(_spi), _verbose); + SPIFlash flash(reinterpret_cast(_spi), _quiet); flash.reset(); flash.power_up(); diff --git a/src/ice40.hpp b/src/ice40.hpp index 633369b..1f5b81a 100644 --- a/src/ice40.hpp +++ b/src/ice40.hpp @@ -27,7 +27,7 @@ class Ice40: public Device { public: Ice40(FtdiSpi *spi, const std::string &filename, uint16_t rst_pin, uint16_t done_pin, - bool verbose); + int8_t verbose); ~Ice40(); void program(unsigned int offset = 0) override; diff --git a/src/lattice.cpp b/src/lattice.cpp index b43175c..8f03365 100644 --- a/src/lattice.cpp +++ b/src/lattice.cpp @@ -68,7 +68,7 @@ using namespace std; # define REG_STATUS_EXEC_ERR (1 << 26) Lattice::Lattice(Jtag *jtag, const string filename, - bool flash_wr, bool sram_wr, bool verbose): + bool flash_wr, bool sram_wr, int8_t verbose): Device(jtag, filename, verbose), _fpga_family(UNKNOWN_FAMILY) { (void)sram_wr; @@ -225,7 +225,7 @@ bool Lattice::program_mem() uint8_t tmp[1024]; int size = 1024; - ProgressBar progress("Loading", length, 50); + ProgressBar progress("Loading", length, 50, _quiet); for (int i = 0; i < length; i += size) { progress.display(i); @@ -864,7 +864,7 @@ bool Lattice::flashErase(uint8_t mask) bool Lattice::flashProg(uint32_t start_addr, const string &name, vector data) { (void)start_addr; - ProgressBar progress("Writing " + name, data.size(), 50); + ProgressBar progress("Writing " + name, data.size(), 50, _quiet); for (uint32_t line = 0; line < data.size(); line++) { wr_rd(PROG_CFG_FLASH, (uint8_t *)data[line].c_str(), 16, NULL, 0); @@ -893,7 +893,7 @@ bool Lattice::Verify(std::vector data, bool unlock) memset(tx_buf, 0, 16); bool failure = false; - ProgressBar progress("Verifying", data.size(), 50); + ProgressBar progress("Verifying", data.size(), 50, _quiet); for (size_t line = 0; line< data.size(); line++) { _jtag->set_state(Jtag::RUN_TEST_IDLE); _jtag->toggleClk(2); @@ -914,9 +914,12 @@ bool Lattice::Verify(std::vector data, bool unlock) if (unlock) DisableISC(); - progress.done(); + if (failure) + progress.fail(); + else + progress.done(); - return true; + return !failure; } uint64_t Lattice::readFeaturesRow() diff --git a/src/lattice.hpp b/src/lattice.hpp index c277c2c..6e5041e 100644 --- a/src/lattice.hpp +++ b/src/lattice.hpp @@ -32,7 +32,7 @@ class Lattice: public Device, SPIInterface { public: Lattice(Jtag *jtag, std::string filename, bool flash_wr, bool sram_wr, - bool verbose); + int8_t verbose); int idCode() override; int userCode(); void reset() override {} diff --git a/src/main.cpp b/src/main.cpp index 4d011cc..f5da813 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,7 +44,8 @@ using namespace std; struct arguments { - bool verbose, reset, detect; + int8_t verbose; + bool reset, detect; unsigned int offset; string bit_file; string device; @@ -74,7 +75,7 @@ int main(int argc, char **argv) jtag_pins_conf_t pins_config = {0, 0, 0, 0}; /* command line args. */ - struct arguments args = {false, false, false, 0, "", "", "-", "", -1, 6000000, "-", + struct arguments args = {0, false, false, 0, "", "", "-", "", -1, 6000000, "-", false, false, false, false, false, true, false, false}; /* parse arguments */ try { @@ -119,7 +120,7 @@ int main(int argc, char **argv) } if (args.cable[0] == '-') { /* if no board and no cable */ - if (args.verbose) + if (args.verbose > 0) cout << "No cable or board specified: using direct ft2232 interface" << endl; args.cable = "ft2232"; } @@ -154,7 +155,7 @@ int main(int argc, char **argv) spi_pins_conf_t pins_config = board->spi_pins_config; try { - spi = new FtdiSpi(cable.config, pins_config, args.freq, args.verbose); + spi = new FtdiSpi(cable.config, pins_config, args.freq, args.verbose > 0); } catch (std::exception &e) { printError("Error: Failed to claim cable"); return EXIT_FAILURE; @@ -226,7 +227,7 @@ int main(int argc, char **argv) vector listDev; int found = jtag->detectChain(listDev, 5); - if (args.verbose) + if (args.verbose > 0) cout << "found " << std::to_string(found) << " devices" << endl; if (found > 1) { printError("Error: currently only one device is supported"); @@ -244,7 +245,7 @@ int main(int argc, char **argv) cerr << "Error: device " << hex << idcode << " not supported" << endl; delete(jtag); return EXIT_FAILURE; - } else if (args.verbose || args.detect) { + } else if (args.verbose > 0 || args.detect) { printf("idcode 0x%x\nmanufacturer %s\nmodel %s\nfamily %s\n", idcode, fpga_list[idcode].manufacturer.c_str(), @@ -338,6 +339,7 @@ int parse_opt(int argc, char **argv, struct arguments *args, jtag_pins_conf_t *p string freqo; vector pins; + bool verbose, quiet; try { cxxopts::Options options(argv[0], "openFPGALoader -- a program to flash FPGA", ""); @@ -375,11 +377,13 @@ int parse_opt(int argc, char **argv, struct arguments *args, jtag_pins_conf_t *p cxxopts::value(args->offset)) ("pins", "pin config (only for ft232R) TDI:TDO:TCK:TMS", cxxopts::value>(pins)) + ("quiet", "Produce quiet output (no progress bar)", + cxxopts::value(quiet)) ("r,reset", "reset FPGA after operations", cxxopts::value(args->reset)) ("spi", "SPI mode (only for FTDI in serial mode)", cxxopts::value(args->spi)) - ("v,verbose", "Produce verbose output", cxxopts::value(args->verbose)) + ("v,verbose", "Produce verbose output", cxxopts::value(verbose)) ("h,help", "Give this help list") ("V,Version", "Print program version"); @@ -391,6 +395,15 @@ int parse_opt(int argc, char **argv, struct arguments *args, jtag_pins_conf_t *p return 1; } + if (verbose && quiet) { + printError("Error: can't select quiet and verbose mode in same time"); + throw std::exception(); + } + if (verbose) + args->verbose = 1; + if (quiet) + args->verbose = -1; + if (result.count("Version")) { cout << "openFPGALoader " << VERSION << endl; return 1; diff --git a/src/progressBar.cpp b/src/progressBar.cpp index 43cd072..982e59c 100644 --- a/src/progressBar.cpp +++ b/src/progressBar.cpp @@ -20,13 +20,22 @@ #include "progressBar.hpp" #include "display.hpp" -ProgressBar::ProgressBar(std::string mess, int maxValue, int progressLen): - _mess(mess), _maxValue(maxValue), _progressLen(progressLen) +ProgressBar::ProgressBar(std::string mess, int maxValue, int progressLen, + bool quiet): _mess(mess), _maxValue(maxValue), + _progressLen(progressLen), _quiet(quiet), _first(true) { last_time = clock(); } void ProgressBar::display(int value, char force) { + if (_quiet) { + if (_first) { + printInfo(_mess + ": ", false); + _first = false; + } + return; + } + clock_t this_time = clock(); if (!force && ((((float)(this_time - last_time))/CLOCKS_PER_SEC) < 0.2)) { @@ -36,24 +45,28 @@ void ProgressBar::display(int value, char force) float percent = ((float)value * 100.0f)/(float)_maxValue; float nbEq = (percent * (float) _progressLen)/100.0f; - //fprintf(stderr, "\r%s: [", _mess.c_str()); printInfo("\r" + _mess + ": [", false); for (int z=0; z < nbEq; z++) { fputc('=', stderr); } fprintf(stderr, "%*s", (int)(_progressLen-nbEq), ""); - //fprintf(stderr, "] %3.2f%%", percent); printInfo("] " + std::to_string(percent) + "%", false); } void ProgressBar::done() { - display(_maxValue, true); - //fprintf(stderr, "\nDone\n"); - printSuccess("\nDone"); + if (_quiet) { + printSuccess("Done"); + } else { + display(_maxValue, true); + printSuccess("\nDone"); + } } void ProgressBar::fail() { - display(_maxValue, true); - //fprintf(stderr, "\nDone\n"); - printError("\nFail"); + if (_quiet) { + printError("\nFail"); + } else { + display(_maxValue, true); + printError("\nFail"); + } } diff --git a/src/progressBar.hpp b/src/progressBar.hpp index 9e54758..8ca4e10 100644 --- a/src/progressBar.hpp +++ b/src/progressBar.hpp @@ -22,7 +22,8 @@ class ProgressBar { public: - ProgressBar(std::string mess, int maxValue, int progressLen); + ProgressBar(std::string mess, int maxValue, int progressLen, + bool quiet = false); void display(int value, char force = 0); void done(); void fail(); @@ -31,6 +32,8 @@ class ProgressBar { int _maxValue; int _progressLen; clock_t last_time; //records the time of last progress bar update + bool _quiet; + bool _first; }; #endif diff --git a/src/spiFlash.cpp b/src/spiFlash.cpp index 0dbcccb..4a717a2 100644 --- a/src/spiFlash.cpp +++ b/src/spiFlash.cpp @@ -60,7 +60,7 @@ #define FLASH_WRVECR 0x61 #define FLASH_RDVECR 0x65 -SPIFlash::SPIFlash(SPIInterface *spi, bool verbose):_spi(spi), _verbose(verbose) +SPIFlash::SPIFlash(SPIInterface *spi, int8_t verbose):_spi(spi), _verbose(verbose) { } @@ -85,20 +85,32 @@ int SPIFlash::sector_erase(int addr) int SPIFlash::sectors_erase(int base_addr, int size) { + int ret = 0; int start_addr = base_addr; int end_addr = (base_addr + size + 0xffff) & ~0xffff; - ProgressBar progress("Erasing", end_addr, 50); + ProgressBar progress("Erasing", end_addr, 50, _verbose < 0); + for (int addr = start_addr; addr < end_addr; addr += 0x10000) { - if (write_enable() == -1) - return -1; - if (sector_erase(addr) == -1) - return -1; - if (_spi->spi_wait(FLASH_RDSR, FLASH_RDSR_WIP, 0x00, 100000, false) == -1) - return -1; + if (write_enable() == -1) { + ret = -1; + break; + } + if (sector_erase(addr) == -1) { + ret = -1; + break; + } + if (_spi->spi_wait(FLASH_RDSR, FLASH_RDSR_WIP, 0x00, 100000, false) == -1) { + ret = -1; + break; + } progress.display(addr); } - progress.done(); - return 0; + if (ret == 0) + progress.done(); + else + progress.fail(); + + return ret; } int SPIFlash::write_page(int addr, uint8_t *data, int len) @@ -143,7 +155,7 @@ int SPIFlash::erase_and_prog(int base_addr, uint8_t *data, int len) if (disable_protection() != 0) return -1; } - ProgressBar progress("Writing", len, 50); + ProgressBar progress("Writing", len, 50, _verbose < 0); if (sectors_erase(base_addr, len) == -1) return -1; @@ -177,11 +189,11 @@ void SPIFlash::read_id() for (int i=0; i < 4; i++) { d = d << 8; d |= (0x00ff & (int)rx[i]); - if (_verbose) + if (_verbose > 0) printf("%x ", rx[i]); } - if (_verbose) + if (_verbose > 0) printf("read %x\n", d); /* read extented */ @@ -201,7 +213,7 @@ void SPIFlash::read_id() printf("EDID + CFD length : %02x\n", rx[3]); printf("EDID : %02x%02x\n", rx[5], rx[4]); printf("CFD : "); - if (_verbose) { + if (_verbose > 0) { for (int i = 6; i < len; i++) printf("%02x ", rx[i]); printf("\n"); @@ -215,7 +227,7 @@ uint8_t SPIFlash::read_status_reg() { uint8_t rx; _spi->spi_put(FLASH_RDSR, NULL, &rx, 1); - if (_verbose) { + if (_verbose > 0) { printf("RDSR : %02x\n", rx); printf("WIP : %d\n", rx&0x01); printf("WEL : %d\n", (rx>>1)&0x01); @@ -230,7 +242,7 @@ uint16_t SPIFlash::readNonVolatileCfgReg() { uint8_t rx[2]; _spi->spi_put(FLASH_RDNVCR, NULL, rx, 2); - if (_verbose) + if (_verbose > 0) printf("Non Volatile %x %x\n", rx[0], rx[1]); return (rx[1] << 8) | rx[0]; } @@ -239,7 +251,7 @@ uint16_t SPIFlash::readVolatileCfgReg() { uint8_t rx[2]; _spi->spi_put(FLASH_RDVCR, NULL, rx, 2); - if (_verbose) + if (_verbose > 0) printf("Volatile %x %x\n", rx[0], rx[1]); return (rx[1] << 8) | rx[0]; } @@ -273,7 +285,7 @@ int SPIFlash::write_disable() int ret = _spi->spi_wait(FLASH_RDSR, FLASH_RDSR_WEL, 0x00, 1000); if (ret == -1) printf("write disable: Error\n"); - else if (_verbose) + else if (_verbose > 0) printf("write disable: Success\n"); return ret; } diff --git a/src/spiFlash.hpp b/src/spiFlash.hpp index 86b0ac5..3e5a0a0 100644 --- a/src/spiFlash.hpp +++ b/src/spiFlash.hpp @@ -22,7 +22,7 @@ class SPIFlash { public: - SPIFlash(SPIInterface *spi, bool verbose); + SPIFlash(SPIInterface *spi, int8_t verbose); /* power */ void power_up(); void power_down(); @@ -48,7 +48,7 @@ class SPIFlash { uint16_t readVolatileCfgReg(); private: SPIInterface *_spi; - bool _verbose; + int8_t _verbose; }; #endif diff --git a/src/xilinx.cpp b/src/xilinx.cpp index 7dc79c4..10ea08e 100644 --- a/src/xilinx.cpp +++ b/src/xilinx.cpp @@ -14,7 +14,7 @@ #include "progressBar.hpp" Xilinx::Xilinx(Jtag *jtag, const std::string &filename, - bool flash_wr, bool sram_wr, bool verbose): + bool flash_wr, bool sram_wr, int8_t verbose): Device(jtag, filename, verbose) { if (_filename != ""){ @@ -122,7 +122,7 @@ void Xilinx::program_spi(unsigned int offset) printSuccess("DONE"); } - SPIFlash spiFlash(this, _verbose); + SPIFlash spiFlash(this, (_verbose ? 1 : (_quiet ? -1 : 0))); spiFlash.reset(); spiFlash.read_id(); spiFlash.read_status_reg(); @@ -194,7 +194,7 @@ void Xilinx::program_mem(BitParser &bitfile) int tx_len, tx_end; int burst_len = byte_length / 100; - ProgressBar progress("Flash SRAM", byte_length, 50); + ProgressBar progress("Flash SRAM", byte_length, 50, _quiet); for (int i=0; i < byte_length; i+=burst_len) { if (i + burst_len > byte_length) { diff --git a/src/xilinx.hpp b/src/xilinx.hpp index 8e91d8b..73eafdd 100644 --- a/src/xilinx.hpp +++ b/src/xilinx.hpp @@ -11,7 +11,7 @@ class Xilinx: public Device, SPIInterface { public: Xilinx(Jtag *jtag, const std::string &filename, - bool flash_wr, bool sram_wr, bool verbose); + bool flash_wr, bool sram_wr, int8_t verbose); ~Xilinx(); void program(unsigned int offset = 0) override;