From e0d763c4b584ae83537f4e7da2ccae2cf96a175c Mon Sep 17 00:00:00 2001 From: Gwenhael Goavec-Merou Date: Thu, 20 Aug 2020 16:58:20 +0200 Subject: [PATCH] add basic support for anlogic eagle s20 FPGA and lichee tang board --- CMakeLists.txt | 2 ++ README.md | 2 ++ src/anlogic.cpp | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ src/anlogic.hpp | 40 ++++++++++++++++++++++++++++ src/board.hpp | 1 + src/main.cpp | 4 +++ src/part.hpp | 2 ++ 7 files changed, 120 insertions(+) create mode 100644 src/anlogic.cpp create mode 100644 src/anlogic.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9dc2820..9df2896 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ if(USE_PKGCONFIG) endif() set(OPENFPGALOADER_SOURCE + src/anlogic.cpp src/anlogicCable.cpp src/dirtyJtag.cpp src/spiFlash.cpp @@ -69,6 +70,7 @@ set(OPENFPGALOADER_SOURCE set(OPENFPGALOADER_HEADERS src/altera.hpp + src/anlogic.hpp src/anlogicCable.hpp src/cxxopts.hpp src/dirtyJtag.hpp diff --git a/README.md b/README.md index 8f07c1e..cba003b 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,13 @@ __Current support kits:__ * [Saanlima Pipistrello LX45](http://pipistrello.saanlima.com/index.php?title=Welcome_to_Pipistrello) (memory) * [SeeedStudio Spartan Edge Accelerator Board](http://wiki.seeedstudio.com/Spartan-Edge-Accelerator-Board) (memory) * [Sipeed Tang Nano](https://tangnano.sipeed.com/en/) (memory) +* [Sipeed Lichee Tang](https://tang.sipeed.com/en/hardware-overview/lichee-tang/) (memory) * [Terasic de0nano](https://www.terasic.com.tw/cgi-bin/page/archive.pl?No=593) (memory) * LambdaConcept ECPIX-5 (memory and flash) __Supported (tested) FPGA:__ +* Anlogic [EG4S20](http://www.anlogic.com/prod_view.aspx?TypeId=10&Id=168&FId=t3:10:3) (SRAM) * Gowin [GW1N (GW1N-1, GW1N-4, GW1NR-9)](https://www.gowinsemi.com/en/product/detail/2/) (SRAM and Flash (flash mode only tested with GW1NR-9)) * Lattice [MachXO2](https://www.latticesemi.com/en/Products/FPGAandCPLD/MachXO2) (SRAM and Flash) * Lattice [MachXO3LF](http://www.latticesemi.com/en/Products/FPGAandCPLD/MachXO3.aspx) (SRAM and Flash) diff --git a/src/anlogic.cpp b/src/anlogic.cpp new file mode 100644 index 0000000..8fc222c --- /dev/null +++ b/src/anlogic.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2020 Gwenhael Goavec-Merou + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include "anlogic.hpp" +#include "jtag.hpp" +#include "device.hpp" + +#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") + _mode = Device::MEM_MODE; + else + throw std::exception(); + } +} +Anlogic::~Anlogic() +{} +void Anlogic::reset() +{ +} + +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); + } +} +int Anlogic::idCode() +{ + unsigned char tx_data[4] = {IDCODE}; + unsigned char rx_data[4]; + _jtag->go_test_logic_reset(); + _jtag->shiftIR(tx_data, NULL, IRLENGTH); + memset(tx_data, 0, 4); + _jtag->shiftDR(tx_data, rx_data, 32); + return ((rx_data[0] & 0x000000ff) | + ((rx_data[1] << 8) & 0x0000ff00) | + ((rx_data[2] << 16) & 0x00ff0000) | + ((rx_data[3] << 24) & 0xff000000)); +} diff --git a/src/anlogic.hpp b/src/anlogic.hpp new file mode 100644 index 0000000..753e8e4 --- /dev/null +++ b/src/anlogic.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 Gwenhael Goavec-Merou + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef SRC_ANLOGIC_HPP_ +#define SRC_ANLOGIC_HPP_ + +#include + +#include "bitparser.hpp" +#include "device.hpp" +#include "jtag.hpp" +#include "svf_jtag.hpp" + +class Anlogic: public Device { + public: + Anlogic(Jtag *jtag, const std::string &filename, bool verbose); + ~Anlogic(); + + void program(unsigned int offset = 0) override; + int idCode() override; + void reset() override; + private: + SVF_jtag _svf; +}; + +#endif // SRC_ANLOGIC_HPP_ diff --git a/src/board.hpp b/src/board.hpp index 943b835..e606a15 100644 --- a/src/board.hpp +++ b/src/board.hpp @@ -44,6 +44,7 @@ static std::map board_list = { {"ecp5_evn", {"ft2232", {}}}, {"machXO2EVN", {"ft2232", {}}}, {"machXO3SK", {"ft2232", {}}}, + {"licheeTang", {"anlogicCable", {}}}, {"littleBee", {"ft2232", {}}}, {"spartanEdgeAccelBoard", {"",{}}}, {"pipistrello", {"ft2232", {}}}, diff --git a/src/main.cpp b/src/main.cpp index e32e21a..1429556 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,6 +25,7 @@ #include #include "altera.hpp" +#include "anlogic.hpp" #include "board.hpp" #include "cable.hpp" #include "device.hpp" @@ -145,6 +146,7 @@ int main(int argc, char **argv) if (fpga_list.find(idcode) == fpga_list.end()) { cerr << "Error: device " << hex << idcode << " not supported" << endl; + delete(jtag); return EXIT_FAILURE; } else if (args.verbose || args.detect) { printf("idcode 0x%x\nmanufacturer %s\nmodel %s\nfamily %s\n", @@ -166,6 +168,8 @@ int main(int argc, char **argv) fpga = new Xilinx(jtag, args.bit_file, args.verbose); } else if (fab == "altera") { fpga = new Altera(jtag, args.bit_file, args.verbose); + } else if (fab == "anlogic") { + fpga = new Anlogic(jtag, args.bit_file, args.verbose); } else if (fab == "Gowin") { fpga = new Gowin(jtag, args.bit_file, args.write_flash, args.write_sram, args.verbose); diff --git a/src/part.hpp b/src/part.hpp index 08a004c..130c532 100644 --- a/src/part.hpp +++ b/src/part.hpp @@ -11,6 +11,8 @@ typedef struct { } fpga_model; static std::map fpga_list = { + {0x0a014c35, {"anlogic", "eagle s20", "EG4S20BG256"}}, + {0x0362D093, {"xilinx", "artix a7 35t", "xc7a35"}}, {0x13631093, {"xilinx", "artix a7 100t", "xc7a100"}},