diff --git a/src/fsparser.cpp b/src/fsparser.cpp index 250c9bb..67ee9b3 100644 --- a/src/fsparser.cpp +++ b/src/fsparser.cpp @@ -180,6 +180,13 @@ int FsParser::parse() case 0x0000281b: /* GW2A-55 */ nb_line = 2038; break; + case 0x0001081b: /* GW5AST-138 */ + /* + * FIXME: Lack of information, + * so just accept everything. + */ + nb_line = 65535; + break; default: printWarn("Warning: Unknown IDCODE"); nb_line = 0; diff --git a/src/gowin.cpp b/src/gowin.cpp index 61b7cce..69c6dce 100644 --- a/src/gowin.cpp +++ b/src/gowin.cpp @@ -78,6 +78,7 @@ Gowin::Gowin(Jtag *jtag, const string filename, const string &file_type, std::st Device::prog_type_t prg_type, bool external_flash, bool verify, int8_t verbose): Device(jtag, filename, file_type, verify, verbose), is_gw1n1(false), is_gw2a(false), + is_gw5a(false), _external_flash(external_flash), _spi_sck(BSCAN_SPI_SCK), _spi_cs(BSCAN_SPI_CS), _spi_di(BSCAN_SPI_DI), _spi_do(BSCAN_SPI_DO), @@ -160,6 +161,15 @@ Gowin::Gowin(Jtag *jtag, const string filename, const string &file_type, std::st /* FIXME: implement GW2 checksum calculation */ skip_checksum = true; is_gw2a = true; + break; + case 0x0001081b: /* GW5AST-138 */ + case 0x0001181b: /* GW5AT-138 */ + case 0x0001281b: /* GW5A-25 */ + _external_flash = true; + /* FIXME: implement GW5 checksum calculation */ + skip_checksum = true; + is_gw5a = true; + break; }; if (mcufw.size() > 0) { @@ -256,6 +266,8 @@ void Gowin::program(unsigned int offset, bool unprotect_flash) length = _fs->getLength(); if (_mode == FLASH_MODE) { + if (is_gw5a) + throw std::runtime_error("Error: write to flash on GW5A is not yet supported"); if (!_external_flash) { /* write into internal flash */ programFlash(); } else { /* write bitstream into external flash */ @@ -302,6 +314,13 @@ void Gowin::program(unsigned int offset, bool unprotect_flash) wr_rd(READ_IDCODE, NULL, 0, NULL, 0); + /* Work around FPGA stuck in Bad Command status */ + if (is_gw5a) { + reset(); + _jtag->set_state(Jtag::RUN_TEST_IDLE); + _jtag->toggleClk(1000000); + } + /* erase SRAM */ if (!EnableCfg()) return; @@ -618,6 +637,11 @@ bool Gowin::flashSRAM(uint8_t *data, int length) ProgressBar progress("Flash SRAM", byte_length, 50, _quiet); + /* UG704 3.4.3 */ + if (is_gw5a) { + wr_rd(INIT_ADDR, NULL, 0, NULL, 0); + } + /* 2.2.6.4 */ wr_rd(XFER_WRITE, NULL, 0, NULL, 0); diff --git a/src/gowin.hpp b/src/gowin.hpp index 07b35ec..6cf1885 100644 --- a/src/gowin.hpp +++ b/src/gowin.hpp @@ -63,6 +63,7 @@ class Gowin: public Device, SPIInterface { ConfigBitstreamParser *_fs; bool is_gw1n1; bool is_gw2a; + bool is_gw5a; bool skip_checksum; /**< bypass checksum verification (GW2A) */ bool _external_flash; /**< select between int or ext flash */ uint8_t _spi_sck; /**< clk signal offset in bscan SPI */ diff --git a/src/part.hpp b/src/part.hpp index 855047e..059dc67 100644 --- a/src/part.hpp +++ b/src/part.hpp @@ -227,6 +227,11 @@ static std::map fpga_list = { /* Gowin GW2 */ {0x0000081b, {"Gowin", "GW2A", "GW2A(R)-18(C)", 8}}, + /* Gowin GW5 */ + {0x0001081b, {"Gowin", "GW5AST", "GW5AST-138", 8}}, + {0x0001181b, {"Gowin", "GW5AT", "GW5AT-138", 8}}, + {0x0001281b, {"Gowin", "GW5A", "GW5A-25", 8}}, + /**************************************************************************/ /* CologneChip */ /**************************************************************************/