diff --git a/README.md b/README.md index cb7f2bd..a81d300 100644 --- a/README.md +++ b/README.md @@ -364,10 +364,24 @@ openFPGALoader -f -b littleBee impl/pnr/*.fs ### Sipeed Lichee Tang -Due to a lack of information about FPGA configuration using JTAG, it's not -possible to use directly the *.bit* file. -The current way is to convert *.bit* to *.svf* by using a tool provided by -[prjtang project](https://github.com/mmicko/prjtang) +Support is currently limited to SRAM write + +For this target, *openFPGALoader* support *svf* and *bit* + +__bit file load__ + +```bash +openFPGALoader -b licheeTang /somewhere/project/prj/*.bit +``` + +__svf file load__ + +It's possible to produce this file by using *TD*: +* Tools->Device Chain +* Add your bit file +* Option : Create svf + +or by using [prjtang project](https://github.com/mmicko/prjtang) ```bash mkdir build @@ -382,7 +396,6 @@ follow: tangbit --input /somewhere.bit --svf bitstream.svf ``` -__file load__: ```bash openFPGALoader -b licheeTang /somewhere/*.svf ``` diff --git a/src/anlogic.cpp b/src/anlogic.cpp index 8fc222c..aa94e30 100644 --- a/src/anlogic.cpp +++ b/src/anlogic.cpp @@ -17,17 +17,26 @@ #include #include "anlogic.hpp" +#include "anlogicBitParser.hpp" #include "jtag.hpp" #include "device.hpp" +#include "progressBar.hpp" + +#define REFRESH 0x01 +#define IDCODE 0x06 +#define JTAG_PROGRAM 0x30 +#define SPI_PROGRAM 0x39 +#define CFG_IN 0x3b +#define JTAG_START 0x3d +#define BYPASS 0xFF -#define IDCODE 6 #define IRLENGTH 8 Anlogic::Anlogic(Jtag *jtag, const std::string &filename, bool verbose): Device(jtag, filename, verbose), _svf(_jtag, _verbose) { if (_filename != "") { - if (_file_extension == "svf") + if (_file_extension == "svf" || _file_extension == "bit") _mode = Device::MEM_MODE; else throw std::exception(); @@ -35,29 +44,89 @@ Anlogic::Anlogic(Jtag *jtag, const std::string &filename, bool verbose): } Anlogic::~Anlogic() {} + void Anlogic::reset() { + _jtag->shiftIR(BYPASS, IRLENGTH); + _jtag->shiftIR(REFRESH, IRLENGTH); + _jtag->toggleClk(15); + _jtag->shiftIR(BYPASS, IRLENGTH); + _jtag->toggleClk(200000); } void Anlogic::program(unsigned int offset) { if (_mode == Device::NONE_MODE) return; - /* in all case we consider svf is mandatory - * MEM_MODE : svf file provided for constructor - * is the bitstream to use - * SPI_MODE : svf file provided is bridge to have - * access to the SPI flash - */ - /* mem mode -> svf */ if (_mode == Device::MEM_MODE) { - _svf.parse(_filename); + if (_file_extension == "svf") { + _svf.parse(_filename); + return; + } + AnlogicBitParser bit(_filename, _verbose); + bit.parse(); + + // Loading device with 'bypass' instruction. + _jtag->shiftIR(BYPASS, IRLENGTH); + _jtag->shiftIR(BYPASS, IRLENGTH); + // Verify Device id. + // SIR 8 TDI (06) ; + // SDR 32 TDI (00000000) TDO (0a014c35) MASK (ffffffff) ; + // Boundary Scan Chain Contents + // Position 1: BG256 + // Loading device with 'refresh' instruction. + _jtag->shiftIR(REFRESH, IRLENGTH); + // Loading device with 'bypass' & 'spi_program' instruction. + _jtag->shiftIR(BYPASS, IRLENGTH); + _jtag->shiftIR(SPI_PROGRAM, IRLENGTH); + _jtag->toggleClk(50000); + // Loading device with 'jtag program' instruction. + _jtag->shiftIR(JTAG_PROGRAM, IRLENGTH); + _jtag->toggleClk(15); + // Loading device with a `cfg_in` instruction. + _jtag->shiftIR(CFG_IN, IRLENGTH); + _jtag->toggleClk(15); + + uint8_t *data = bit.getData(); + int len = bit.getLength() / 8; + _jtag->set_state(Jtag::SHIFT_DR); + ProgressBar progress("Loading", len, 50); + int pos = 0; + uint8_t *ptr = data; + while (len > 0) { + int xfer_len = (len > 512)?512:len; + _jtag->read_write(ptr, NULL, xfer_len*8, (len - xfer_len == 0)); + len -= xfer_len; + progress.display(pos); + pos += xfer_len; + ptr+=xfer_len; + } + + _jtag->set_state(Jtag::RUN_TEST_IDLE); + progress.done(); + _jtag->toggleClk(100); + // Loading device with a `jtag start` instruction. + _jtag->shiftIR(JTAG_START, IRLENGTH); + _jtag->toggleClk(15); + // Loading device with 'bypass' instruction. + _jtag->shiftIR(BYPASS, IRLENGTH); + _jtag->toggleClk(1000); + // ?? + _jtag->shiftIR(0x31, IRLENGTH); + _jtag->toggleClk(100); + _jtag->shiftIR(JTAG_START, IRLENGTH); + _jtag->toggleClk(15); + _jtag->shiftIR(BYPASS, IRLENGTH); + _jtag->toggleClk(15); } } + int Anlogic::idCode() { - unsigned char tx_data[4] = {IDCODE}; + unsigned char tx_data[4]; unsigned char rx_data[4]; + + tx_data[0] = IDCODE; _jtag->go_test_logic_reset(); _jtag->shiftIR(tx_data, NULL, IRLENGTH); memset(tx_data, 0, 4);