YosysHQ / apicula

Project Apicula 🐝: bitstream documentation for Gowin FPGAs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

GW1NR-9 vs GW1N-9 bit-stream

chili-chips-ba opened this issue · comments

The only difference between these two devices is in the package add-ons. FPGA die is the same for both. While N package includes only FPGA die, the NR is a SIP with SDRAM, PSRAM, or double PSRAM packaging options along with FPGA die.

Since those are essentially "external components", by supporting the N, Apicula is also supporting the NR. So far, all is nice and dandy.

But, the problem is that current Apicula doesn't allow specifying NR for --family. Without it, the NR bit-stream is built with N ID. When we then try to download Apicula-generated bit-stream using Gowin programmer, it complains about incorrect target. It does not seem it would take much to allow building the NR bitstream with the proper NR ID, thus opening the path for mixing and matching Apicula with Gowin proprietary tools.

NR-vs-N

What quickly came to my mind without having to duplicate databases with and without R or store multiple ids in the database (which would require adding multiple IDE runs to get different ids at the fuzzing stage) was to add the --device-id parameter to gowin_pack.
This parameter will need to be specified very precisely and accurately, as expected by the vendor bootloader.
The solution is not brilliant and any other patches are welcome, especially in light of the fact that I do not have the opportunity to run vendor things that work directly with hardware.

The new --device-id option would indeed be a lightweight approach for developers, yet a flexible one for users.

However, we must note that your current classification is misaligned with Gowin's (https://www.gowinsemi.com/en/product/detail/46), hence confusing. It'd be more straightforward if you allowed specifying --family GW1NR-9C.

Such family could be virtual, essentially an alias to GW1N-9C in everything by the --device-id.

In that way, if the (ordinary) user does not explicitly specify the device-id, you can internally look it up based on --family and --device.

Should the (power) user specify device-id, you take it as-is, without trying to derive from the other passed options.

gowin-littlebee

I wrote this small script:

import json
import os
import subprocess
from collections import defaultdict

def build_family_aliases():
    db_hashes = defaultdict(list)

    md5_exec = subprocess.run("md5sum /usr/src/gowin/IDE/share/device/*/*.fse",
                              shell=True, check=True, capture_output=True,
                              encoding='utf-8')

    for line in md5_exec.stdout.splitlines():
        computed_hash, path = line.split("  ")
        family = os.path.split(path)[-1].replace(".fse", "")
        db_hashes[computed_hash].append(family)

    family_aliases = {}
    for computed_hash, families in db_hashes.items():
        # arbitrarily use the shortest family as the "true" family
        families.sort(key=lambda x: (len(x), x))
        family_aliases[families[0]] = families

    return family_aliases


if __name__ == "__main__":
    family_aliases = build_family_aliases()
    with open("family_alias.json", "w") as f:
        f.write(json.dumps(dict(family_aliases)))

and it outputs (when run in the docker container used in the CI):

{"GW1N-1": ["GW1N-1", "GW1NR-1"], "GW1N-2": ["GW1N-2", "GW1N-2B", "GW1NR-2", "GW1N-1P5", "GW1NR-2B", "GW1NZR-2", "GW1N-1P5B"], "GW1N-1S": ["GW1N-1S"], "GW1N-4": ["GW1N-4", "GW1N-4B", "GW1N-4D", "GW1NR-4", "GW1NR-4B", "GW1NR-4D", "GW1NRF-4B"], "GW1N-9": ["GW1N-9", "GW1NR-9"], "GW1N-9C": ["GW1N-9C", "GW1NR-9C"], "GW1NS-2": ["GW1NS-2", "GW1NS-2C", "GW1NSR-2", "GW1NSE-2C", "GW1NSR-2C"], "GW1NS-4": ["GW1NS-4", "GW1NS-4C", "GW1NSR-4", "GW1NSR-4C", "GW1NSER-4C"], "GW1NZ-1": ["GW1NZ-1", "GW1NZ-1C"], "GW2A-18": ["GW2A-18", "GW2AR-18"], "GW2A-18C": ["GW2A-18C", "GW2AR-18C", "GW2ANR-18C"], "GW2A-55": ["GW2A-55", "GW2A-55C", "GW2AN-55C"], "GW2AN-4X": ["GW2AN-4X", "GW2AN-9X", "GW2AN-18X"]}

So this should allow mapping any family back to the "true" family for nextpnr. However, I'm not quite sure where the bitstream ID gets set yet.

Also, it appears that nextpnr itself might need to have some changes, as it has some bits hardcoded: https://github.com/YosysHQ/nextpnr/blob/5bfe0dd1b137e43d8ed85485552e126a6b7ee978/gowin/main.cc#L80

I can assume that since the image is formed in gowun_pack, then from there you can start searching, which may end in some fuzzer, where the vendor IDE is launched to obtain a “clean” image.

Would @bl0x be the right developer to pull in for this?

(I will PR once I get this working, just adding the info here as a work log)

An updated script to also extract IDCODEs for families is below, I also inverted the dictionary format which is written to the JSON file: https://gist.github.com/jeremyherbert/d8863a6893f54f000af78024c8c7e0db

I just need to work on the bitstream IDCODE override now.

Also just for a bit of fun, the IDCODEs in this document have some which are wrong: https://cdn.gowinsemi.com.cn/TN653E.pdf ;)

Which ones are incorrect? How about bringing it to Gowin's attention? Have you followed up with them?

Well at least GW1NR-9 and 9C are swapped relative to what the IDE has in the programmer file, as confirmed by reading the IDCODE with JTAG/openFPGAloader out of a tang 9k. After I saw that just took the whole table as untrustworthy and moved on. Have a look in the gist at the IDCODEs and see how they are different for those two parts.

I don’t have any contacts at Gowin and I assume like most other semiconductor companies they don’t care about anyone not buying high volume. So I haven’t contacted them, but feel free to do so if you have a contact point.

@chili-chips-ba I know it's a lot to build, but you should be able to get this working now - please give it a go if you have time. I tested on both the tang nano 20k and tang nano 9k and they both worked fine with openFPGALoader (which rejects the flash if the IDCODE is wrong).

Thank you! @Juninho99 from our team shall provide feedback.
We have also contacted support@gowinsemi.com about the issue you found in their documentation. They are looking into it.

Gowin tech support has responded to our enquiry. Here is what they said:

This link is for an old out-of-date UG290 programming document, TN653-1.07E (https://cdn.gowinsemi.com.cn/TN653E.pdf). The latest UG290-2.7.3E is correct. The English version can be found here https://www.gowinsemi.com/en/support/database/?support_search=UG290
https://www.gowinsemi.com/upload/database_doc/1779/document/658e82dfb3d4e.pdf

image