timvideos / litex-buildenv

An environment for building LiteX based FPGA designs. Makes it easy to get everything you need!
BSD 2-Clause "Simplified" License
214 stars 79 forks source link

Ice40 HX8K EVB issues #277

Open niklasnisbeth opened 4 years ago

niklasnisbeth commented 4 years ago

The BIOS does not compare up on the Lattice ice40 HX8K EVB. There are several issues.

I have gotten some of the way here:

https://github.com/niklasnisbeth/litex-buildenv/commit/846fc6193972692f9de8d99146f29702d6ff80e3

I have been trying to use litex-buildenv to make a vertexriscv image for the HX8K. I am using the stub firmware. The built firmware does not come up.

We tried adding the UARTWishboneBridge, but wishbone-tool cannot connect to it (as if the Wishbone bus is locking up).

Moving the SRAM to address 0 makes it possible to inspect the wishbone bus with the tool.

The CPU was not running code correctly, changing the SPIFlash to little endian corrects this.

At this point, with UARTWishboneBridge still in, the CPU starts running the BIOS but is stuck in an infinite loop apparently in a call to vsnprintf in the BIOS that I cannot locate.

Removing the UARTWishboneBridge does not make the BIOS come up.

litex-buildenv revision 96ab220b0f60e3d509ca0a66dcfb81676ef294d9 results in a working Micropython environment.

niklasnisbeth commented 4 years ago

Had a little time to dig a bit further into this, I can build a working LM32 firmware until commit da7488c2ab5e3d496ba4ecb5e482458302fb1c15.

From 3a9127d08d8d0be9a68331bd71bf43fc216dbb26, builds are broken due to memory region stuff that gets fixed in 053ec4d21a378cc65bb293c5e900ba210cd0ecf6, but at this point the LM32 BIOS does not start.

VexRiscV and Picorv are broken for me even in da7488c - I don't know if that's a separate error to the one that gets introduced in 3a9127d, nor if these builds were ever working on this board. I will focus on LM32 for the the time being since there's a working version to compare to.

3a9127d is rather large, unfortunately. I'll attach debuggers and keep at it as time permits and make notes here.

ewenmcneill commented 4 years ago

FTR, it seems like this same issue affects the TinyFPGA BX as well, which has the same iCE40 FPGA chip on it, and the same reliance on execute-in-place from the SPI flash. I've closed https://github.com/timvideos/litex-buildenv/issues/282 in favour of consolidating the discussion here as this issue was opened first (although FTR there's some possibly useful speculation in #282 comments which might be useful for reference).

Ewen

ewenmcneill commented 4 years ago

On the TinyFPGA BX front, a month or so back, at the "TimVideos" hackfest, @futaris suggested that one possible reason that the iCE40 8K boards weren't working with newer LiteX is that maybe LiteX had switched to defaulting to Quad-SPI mode, and maybe the TinyFPGA BX (and perhaps the HX8K EVB?) don't support Quad SPI mode.

Tracing tags on the TinyFPGA BX schematic shows that all 6 (non power/ground) pins on the SPI flash are connected to both the iCE40 LP8K and to the underside (inner) "additional pins" connector. These are SCK, SDO, SDI, SS, 82 and 109 on the schematic.

SDO seems to be connected to the iCE40 in two places (H5 / IOB_104_CBSEL1; and G6 / IOB_105_SDO), as is SS connected twice (F8 / IOR_113; and F7 / IOB_108_SS which has a pullup). At a guess SDO is connected twice for dual/quad SPI usage (so one pin can be used in either direction); I'm not sure why SS (chip select for the SPI) is connected twice, possibly it just made the circuit board routing easier?

82 is connected to the FPGA on H4 / IOB_82_GBIN4, and 109 is connected to the FPGA on J8 / IOR_109. Based on the labeling on the TinyFPGA BX back card, 82 is !WP / IO2and 109 is !HOLD / IO3.

So in theory there are enough pins connected between the iCE40 and the SPI flash to to do Quad SPI. The SPI flash seems to be an AT25SF081 which seems to support Quad SPI read. So in theory it'd be possible to make Quad SPI work.

Ewen

ewenmcneill commented 4 years ago

The TinyFPGA BX Platform file: https://github.com/timvideos/litex-buildenv/blob/e9a1550820dbdf543c62f2f24dd163d12eb403eb/platforms/tinyfpga_bx.py#L15-L28

shows both a spiflash and a spiflash4x config. The spiflash4x dq() line:

https://github.com/timvideos/litex-buildenv/blob/e9a1550820dbdf543c62f2f24dd163d12eb403eb/platforms/tinyfpga_bx.py#L27

is presumably IO0, IO1, IO2, IO3, for which G6, H7, H4, J8 as listed does seem plausible.

The FIXME around the SPI model/size information is a wee bit concerning:

https://github.com/timvideos/litex-buildenv/blob/e9a1550820dbdf543c62f2f24dd163d12eb403eb/platforms/tinyfpga_bx.py#L53-L59

but it looks like it's been like that for ages, and the information for the iCEBreaker (working) is also similar:

https://github.com/timvideos/litex-buildenv/blob/e9a1550820dbdf543c62f2f24dd163d12eb403eb/platforms/icebreaker.py#L84-L91

and also unchanged for ages.

Ewen

ETA: FWIW, the LiteX platform definition doesn't have any of the FIXME SPI additional values:

https://github.com/enjoy-digital/litex/blob/master/litex/boards/platforms/tinyfpga_bx.py

but otherwise looks basically the same, other than adding a serial port.

Also FWIW, as best I can tell the spiflash_model is only used for determining what to build into the QEMU emulation, at:

https://github.com/timvideos/litex-buildenv/blob/e9a1550820dbdf543c62f2f24dd163d12eb403eb/scripts/build-qemu.sh#L120

ewenmcneill commented 4 years ago

Possibly of note, it looks like the HX8K platform does not have a spiflash4x defined; see https://github.com/timvideos/litex-buildenv/blob/master/platforms/ice40_hx8k_b_evn.py. It only has a single speed SPI interface defined: https://github.com/timvideos/litex-buildenv/blob/e9a1550820dbdf543c62f2f24dd163d12eb403eb/platforms/ice40_hx8k_b_evn.py#L27-L32

(without even !WP or !HOLD). That's also unchanged for years. Presumably if there's no spiflash4x then LiteX just does regular single speed SPI? (Or maybe dual speed SPI?)

Ewen

GitHub
timvideos/litex-buildenv
An environment for building LiteX based FPGA designs. Makes it easy to get everything you need! - timvideos/litex-buildenv
ewenmcneill commented 4 years ago

For future reference, these seem to be the changes in the LiteX SPI Master / SPI Flash support that were pulled in by https://github.com/timvideos/litex-buildenv/commit/3a9127d08d8d0be9a68331bd71bf43fc216dbb26 (roughly July 2019 to October 2019), where the relevant commits were found from https://github.com/enjoy-digital/litex/compare/e637aa657b7c1163c7c21c4b972f4aa947406272...a54b80b9b4eaa6defca99b0749da8426535bbb62 (linked as third_party/litex 111 files).

(cd third_party/litex && git diff e637aa65...a54b80b -- litex/soc/cores/spi.py)
(cd third_party/litex && git diff e637aa65...a54b80b -- litex/soc/cores/spi_flash.py)

don't seem to show anything particularly obviously different (including, eg, any default to spiflash4x, so if that changed maybe it's somewhere else).

Ewen

ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ git log e637aa65...a54b80b -- litex/soc/cores/spi_flash.py
commit 1a6dddd57cf793e09754c11f91acfbb92ce812b6
Author: Sean Cross <sean@xobs.io>
Date:   Fri Sep 20 12:11:59 2019 +0800

    spi_flash: document register fields

    Document the various fields present in the SPI flash bitbang interface.
    This adds documentation for the Single and DualQuad modules.

    Signed-off-by: Sean Cross <sean@xobs.io>

commit 6d5fddc160ac5778eefe1216f78dc3aa6d526f93
Author: Florent Kermarrec <florent@enjoy-digital.fr>
Date:   Wed Aug 14 07:35:45 2019 +0200

    cores/spi_flash/S7SPIFlash: make cs_n optional in pads (when driven externally)
ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ git log e637aa65...a54b80b -- litex/soc/cores/spi.py
commit cca0478a5e57281224fd605078c9f2944ce9ef16
Author: Florent Kermarrec <florent@enjoy-digital.fr>
Date:   Mon Sep 16 17:02:55 2019 +0200

    soc/cores/spi: use new CSRField (no functional change)

commit 41fe7cae0b5341531f609943d5f70afd6256cfc8
Author: Florent Kermarrec <florent@enjoy-digital.fr>
Date:   Thu Aug 29 09:46:20 2019 +0200

    core/spi: add minimal SPISlave

commit 236070fdcf9d9ef3fec45f046b312e278f2ebe11
Author: Florent Kermarrec <florent@enjoy-digital.fr>
Date:   Mon Aug 5 10:36:38 2019 +0200

    cores: -x on spi.py
ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ 
ewenmcneill commented 4 years ago

I've made an attempt to divide up the large https://github.com/timvideos/litex-buildenv/commit/3a9127d08d8d0be9a68331bd71bf43fc216dbb26 submodule update, to narrow down what's causing the issue with the iCE40 HX8K/TinyFPGA BX. Sort of manually bisecting the submodule updates.

If I check out https://github.com/timvideos/litex-buildenv/commit/3a9127d08d8d0be9a68331bd71bf43fc216dbb26, do git submodule update --init --recursive, and then do:

cd third_party/litex
git checkout e637aa657b7c1163c7c21c4b972f4aa947406272
git submodule update --init --recursive
cd ../../third_party/litedram
git checkout 6c53996a7042050def908882b36e92585b6ef138

then I can build a working MicroPython on the TinyFPGA BX, even with all the other direct submodules updated (they're mostly not used for MIcroPython on the TinyFPGA BX). Those commits for litex and litedram submodules are the ones from the previous commit, ie before the submodule updates. (It won't build without reverting both litex and litedram, due to Python API compatibility issues AFAICT, hence reverting both.)

So this seems to confirm my hunch that the changes in litex, ie https://github.com/enjoy-digital/litex/compare/e637aa657b7c1163c7c21c4b972f4aa947406272...a54b80b9b4eaa6defca99b0749da8426535bbb62, is what has broken things. (And I'm reminded by trying to build that commit directly, without reverting litex, that the main change in that range was the memory map handling, including the location of the spiflash / rom / etc changing defaults.)

I'm now going to see if I can narrow down that litex range of commits to less than 3 months worth (2019-07-26 to 2019-10-31) to try to get a closer hint to what might have changed to break things.

Ewen

(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) e
wen@parthenon:/src/fpga/litex-buildenv$ git log -1 | head -6
commit 3a9127d08d8d0be9a68331bd71bf43fc216dbb26
Author: Tim 'mithro' Ansell <me@mith.ro>
Date:   Wed Oct 30 11:39:10 2019 -0700

    Updating submodules.

(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) e
wen@parthenon:/src/fpga/litex-buildenv$ git submodule
 3a6108a75be356a3dc53760d22782f1323248b6b third_party/edid-decode (heads/master-21-g3a6108a)
 01d8f819f15baf9a8cc5d96945a51e4d267ff564 third_party/flash_proxies (heads/master-2-g01d8f81)
+6c53996a7042050def908882b36e92585b6ef138 third_party/litedram (heads/master-283-g6c53996)
 4d9e74f10a3fe7bf71ba9bde50f49689c6458dc5 third_party/liteeth (heads/master-25-g4d9e74f)
 47e76f447f6e3d97aac2638a98f967d44db5c349 third_party/litepcie (remotes/origin/reordering-36-g47e76f4)
 db5d2f7881161ce5b9a10a0ab42555f884b9d7c1 third_party/litesata (heads/master-28-gdb5d2f7)
 7a9fa9d3b18362bf707dff25a78661395ef9ee7a third_party/litescope (heads/master-18-g7a9fa9d)
 7457a29b1a47fe15e81fa37f3bbdd510788f1d53 third_party/liteusb (remotes/origin/HEAD)
 49bafa481075e0bfbaf067b63c351ec29e993894 third_party/litevideo (heads/master-8-g49bafa4)
+e637aa657b7c1163c7c21c4b972f4aa947406272 third_party/litex (heads/master-682-ge637aa65)
 742360f2ba4c400c6164908f03c6ca3d965f168b third_party/litex-renode (heads/master-25-g742360f)
 41922fde2a8c36cd0f99d4b7ebb3ba9c37ce1489 third_party/migen (0.6.dev-306-g41922fd)
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) e
wen@parthenon:/src/fpga/litex-buildenv$ 
ewenmcneill commented 4 years ago

With some experimentation i've been able to get up to litex at the end of 2019-09-29, with litedram at 2019-09-11, and that works okay on the TinyFPGA BX.

Very soon after that (by 2019-09-30 I think) there are some complicated litex / litedram interdependent changes, and I was struggling to even find a combination that would build in that range (because they're clearly interdependent, but there's no actual "this version works with this version" information being maintained for them, so I'm having to guess from dates :-( ).

Anyway, that's narrowed it down to litex/litedram changes between 2019-09-29 and 2019-10-30, a one month range, with about 95 commits in it. AFAICT there are no changes to soc/spi.py or soc/spi_flash.py in that commit range, so I think that rules out SPI being broken somehow.

The main thing that seems to have changed in that range is the entire soft CPU memory architecture... I'm particularly suspicious of the changes starting with https://github.com/enjoy-digital/litex/commit/2c3ad3f96d8be73859177d6b51a01fcda06b1f6e, and whatever is the equivalent in litedram (it's moving code from litex to litedram, with a new API, etc).

Ewen

(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ git log -1
commit 68ba1c60be6d630793541e355c7342c176d2bf08 (HEAD)
Author: Florent Kermarrec <florent@enjoy-digital.fr>
Date:   Sat Sep 28 19:04:38 2019 +0200

    soc_core: avoid manual listing of support CPUs, just use CPU.keys()
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ cd ../../third_party/litedram
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv/third_party/litedram$ git log -1
commit f586aada1c5bf00a6fd9e668d129bb36c4006acd (HEAD)
Author: Florent Kermarrec <florent@enjoy-digital.fr>
Date:   Wed Sep 11 09:50:46 2019 +0200

    phys: improve presentation (add separators, better indent)
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv/third_party/litedram$ 
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ git checkout 68ba1c6 
Previous HEAD position was 4d90058b soc/integration: move cpu_interface retro-compatibility to litex/__init__
HEAD is now at 68ba1c60 soc_core: avoid manual listing of support CPUs, just use CPU.keys()
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ git log -1
commit 68ba1c60be6d630793541e355c7342c176d2bf08 (HEAD)
Author: Florent Kermarrec <florent@enjoy-digital.fr>
Date:   Sat Sep 28 19:04:38 2019 +0200

    soc_core: avoid manual listing of support CPUs, just use CPU.keys()
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ git submodule update --init --recursive
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ cd ..
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv/third_party$ cd ..
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv$ make clean
rm -f build/cache.mk
rm -rf build/tinyfpga_bx_base_lm32.minimal/
py3clean . 2>/dev/null || rm -rf $(find -name __pycache__)
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv$ 

(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv$ git log -1 | head -5
commit 3a9127d08d8d0be9a68331bd71bf43fc216dbb26
Author: Tim 'mithro' Ansell <me@mith.ro>
Date:   Wed Oct 30 11:39:10 2019 -0700

    Updating submodules.
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv$ git submodule
 3a6108a75be356a3dc53760d22782f1323248b6b third_party/edid-decode (heads/master-21-g3a6108a)
 01d8f819f15baf9a8cc5d96945a51e4d267ff564 third_party/flash_proxies (heads/master-2-g01d8f81)
+f586aada1c5bf00a6fd9e668d129bb36c4006acd third_party/litedram (heads/master-319-gf586aad)
 4d9e74f10a3fe7bf71ba9bde50f49689c6458dc5 third_party/liteeth (heads/master-25-g4d9e74f)
 47e76f447f6e3d97aac2638a98f967d44db5c349 third_party/litepcie (remotes/origin/reordering-36-g47e76f4)
 db5d2f7881161ce5b9a10a0ab42555f884b9d7c1 third_party/litesata (heads/master-28-gdb5d2f7)
 7a9fa9d3b18362bf707dff25a78661395ef9ee7a third_party/litescope (heads/master-18-g7a9fa9d)
 7457a29b1a47fe15e81fa37f3bbdd510788f1d53 third_party/liteusb (remotes/origin/HEAD)
 49bafa481075e0bfbaf067b63c351ec29e993894 third_party/litevideo (heads/master-8-g49bafa4)
+68ba1c60be6d630793541e355c7342c176d2bf08 third_party/litex (tinyfpga-bx-works-2019-08-10-113-g68ba1c60)
 742360f2ba4c400c6164908f03c6ca3d965f168b third_party/litex-renode (heads/master-25-g742360f)
 41922fde2a8c36cd0f99d4b7ebb3ba9c37ce1489 third_party/migen (0.6.dev-306-g41922fd)
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv$ 

        __   _ __      _  __
       / /  (_) /____ | |/_/
      / /__/ / __/ -_)>  <
     /____/_/\__/\__/_/|_|

 (c) Copyright 2012-2019 Enjoy-Digital
 (c) Copyright 2007-2015 M-Labs Ltd

 BIOS built on Mar  6 2020 21:12:29
 BIOS CRC passed (5e89ec91)

 Migen git sha1: 41922fd
 LiteX git sha1: 68ba1c60

--============ SoC info ================--
CPU:       LM32 @ 16MHz
ROM:       32KB
SRAM:      10KB

--========= Peripherals init ===========--

--========== Boot sequence =============--
Booting from serial...
Press Q or ESC to abort boot completely.
sL5DdSMmkekro
Timeout
Booting from flash...
Executing booted program at 0x20058008
--============= Liftoff! ===============--
MicroPython v1.9.4-534-gd2bd40498-dirty on 2020-03-06; litex with lm32
>>> print("Hello World!")
Hello World!
>>> 
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ git log HEAD...a54b80b9b4eaa6defca99b0749da8426535bbb62 | grep "^commit" | wc -l
94
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ git log HEAD...a54b80b9b4eaa6defca99b0749da8426535bbb62 -- litex/soc/cores/spi.py
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ git log HEAD...a54b80b9b4eaa6defca99b0749da8426535bbb62 -- litex/soc/cores/spi_flash.py
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-first-broken) ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ 
ewenmcneill commented 4 years ago

https://github.com/enjoy-digital/litex/commit/101f1b1cef749aea7d4b1a4897d74868eb77e6c6 also builds okay, which is the first 2019-09-30 commit. After that I have to update litedram to 5d1a9847aa805034e58eabf376e2807bfed7b133 to pick up code moved from litex to litedram, and then, I run into AttributeError: 'BaseSoC' object has no attribute 'get_memory_regions', ie, https://github.com/enjoy-digital/litex/issues/290. (The function was apparently removed in https://github.com/enjoy-digital/litex/commit/8be5824e258b84df240d34636aaa539124b92c65#diff-5b5aa398d41ddd6086fbe51e97931f5c to "simplify the code".)

So to carry on testing I need to roll litex-buildenv forward to https://github.com/timvideos/litex-buildenv/commit/c9745dc49866e416814716efa41ff10a29819b35, which works around that API change.

With:

the combination builds, but I get no serial output any more. So I think that's approximately the first broken version, which seems to confirm that it's the litex/litedram rearrangements that broke things. Ie, the changes on 2019-09-30 seem to be what broke things. There's some other updates trying to fix things up on 2019-10-31 after these changes were merged -- https://github.com/timvideos/litex-buildenv/commits/master?after=e9a1550820dbdf543c62f2f24dd163d12eb403eb+139 -- but it seems like they weren't everything required.

Anyway I've got a strong hunch the issues relate to, eg, memory layout / memory type changes.

Ewen

(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-second-broken) ewen@parthenon:/src/fpga/litex-buildenv$ git log -1
commit c9745dc49866e416814716efa41ff10a29819b35 (HEAD -> tinyfpga-bx-2019-10-30-second-broken)
Author: Tim 'mithro' Ansell <me@mith.ro>
Date:   Wed Oct 30 12:19:35 2019 -0700

    make: Updating for new LiteX API.
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-second-broken) ewen@parthenon:/src/fpga/litex-buildenv$ git submodule
 3a6108a75be356a3dc53760d22782f1323248b6b third_party/edid-decode (heads/master-21-g3a6108a)
 01d8f819f15baf9a8cc5d96945a51e4d267ff564 third_party/flash_proxies (heads/master-2-g01d8f81)
+5d1a9847aa805034e58eabf376e2807bfed7b133 third_party/litedram (heads/master-328-g5d1a984)
 4d9e74f10a3fe7bf71ba9bde50f49689c6458dc5 third_party/liteeth (heads/master-25-g4d9e74f)
 47e76f447f6e3d97aac2638a98f967d44db5c349 third_party/litepcie (remotes/origin/reordering-36-g47e76f4)
 db5d2f7881161ce5b9a10a0ab42555f884b9d7c1 third_party/litesata (heads/master-28-gdb5d2f7)
 7a9fa9d3b18362bf707dff25a78661395ef9ee7a third_party/litescope (heads/master-18-g7a9fa9d)
 7457a29b1a47fe15e81fa37f3bbdd510788f1d53 third_party/liteusb (remotes/origin/HEAD)
 49bafa481075e0bfbaf067b63c351ec29e993894 third_party/litevideo (heads/master-8-g49bafa4)
+4d90058b180ff43856da47f03b7bc736f16b887d third_party/litex (tinyfpga-bx-works-2019-08-10-131-g4d90058b)
 742360f2ba4c400c6164908f03c6ca3d965f168b third_party/litex-renode (heads/master-25-g742360f)
 41922fde2a8c36cd0f99d4b7ebb3ba9c37ce1489 third_party/migen (0.6.dev-306-g41922fd)
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-second-broken) ewen@parthenon:/src/fpga/litex-buildenv$ 
ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ git log | grep "^commit" | grep -B 9999 101f1b
commit 4d90058b180ff43856da47f03b7bc736f16b887d
commit 8be5824e258b84df240d34636aaa539124b92c65
commit 7b72148c4ed6f518397780d77aafe6df70937f9c
commit 63a813af9c53895c9e08e71d132d4bb435ccf8c2
commit 3d257d72665da2ab71a1d651d33e70d76c02a4b8
commit e8e57b4f87b9fc1eb0021b4ab174148fbb112e5b
commit 334ae336bfb98c388d28bc0c03609bdebcf46197
commit 241c3c642bdd1792868a95cf5d8e2e59c8a3d575
commit 48e5a1d14008cb8b33107ce20e9c642be815082a
commit e9ed4761b53160e4f55319bfe7010b380e202e6b
commit 78cecbe36bf2a5d75f2af90d2b3f4d802900cb22
commit 7575ecc6adb07ece0072f609b1eea64b3036725f
commit c6fe3f3145ed77554cc41ce1d8d66df028b7d570
commit 6fcb12a98f6d9df67c5c0390194fc755a300d18f
commit b826c1705f600d0cce6a69ab3b58d9d6b3b2ce8b
commit 355072c285a89286d855d0692800c1ca0d4dd76b
commit 2c3ad3f96d8be73859177d6b51a01fcda06b1f6e
commit 101f1b1cef749aea7d4b1a4897d74868eb77e6c6
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-second-broken) ewen@parthenon:/src/fpga/litex-buildenv/third_party/litex$ 
GitHub
timvideos/litex-buildenv
An environment for building LiteX based FPGA designs. Makes it easy to get everything you need! - timvideos/litex-buildenv
ewenmcneill commented 4 years ago

Joy, it looks like https://github.com/enjoy-digital/litex/commit/8be5824e258b84df240d34636aaa539124b92c65 is the commit that removes get_mem_regions(), which means testing anything before that (eg, https://github.com/enjoy-digital/litex/commit/7b72148c4ed6f518397780d77aafe6df70937f9c) means that we have to revert litex-buildenv back to https://github.com/timvideos/litex-buildenv/commit/3a9127d08d8d0be9a68331bd71bf43fc216dbb26, without the change in https://github.com/timvideos/litex-buildenv/commit/c9745dc49866e416814716efa41ff10a29819b35. Unstable APIs are sooooo much fun when trying to bisect :-(

Looks like working:

and failing:

which are just a few commits apart.

Ewen

(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-third-broken) ewen@parthenon:/src/fpga/litex-buildenv$ git log -1 | head -5
commit 3a9127d08d8d0be9a68331bd71bf43fc216dbb26
Author: Tim 'mithro' Ansell <me@mith.ro>
Date:   Wed Oct 30 11:39:10 2019 -0700

    Updating submodules.
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-third-broken) ewen@parthenon:/src/fpga/litex-buildenv$ git submodule
 3a6108a75be356a3dc53760d22782f1323248b6b third_party/edid-decode (heads/master-21-g3a6108a)
 01d8f819f15baf9a8cc5d96945a51e4d267ff564 third_party/flash_proxies (heads/master-2-g01d8f81)
+5d1a9847aa805034e58eabf376e2807bfed7b133 third_party/litedram (heads/master-328-g5d1a984)
 4d9e74f10a3fe7bf71ba9bde50f49689c6458dc5 third_party/liteeth (heads/master-25-g4d9e74f)
 47e76f447f6e3d97aac2638a98f967d44db5c349 third_party/litepcie (remotes/origin/reordering-36-g47e76f4)
 db5d2f7881161ce5b9a10a0ab42555f884b9d7c1 third_party/litesata (heads/master-28-gdb5d2f7)
 7a9fa9d3b18362bf707dff25a78661395ef9ee7a third_party/litescope (heads/master-18-g7a9fa9d)
 7457a29b1a47fe15e81fa37f3bbdd510788f1d53 third_party/liteusb (remotes/origin/HEAD)
 49bafa481075e0bfbaf067b63c351ec29e993894 third_party/litevideo (heads/master-8-g49bafa4)
+7b72148c4ed6f518397780d77aafe6df70937f9c third_party/litex (tinyfpga-bx-works-2019-08-10-129-g7b72148c)
 742360f2ba4c400c6164908f03c6ca3d965f168b third_party/litex-renode (heads/master-25-g742360f)
 41922fde2a8c36cd0f99d4b7ebb3ba9c37ce1489 third_party/migen (0.6.dev-306-g41922fd)
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-third-broken) ewen@parthenon:/src/fpga/litex-buildenv$ 
        __   _ __      _  __
       / /  (_) /____ | |/_/
      / /__/ / __/ -_)>  <
     /____/_/\__/\__/_/|_|

 (c) Copyright 2012-2019 Enjoy-Digital
 (c) Copyright 2007-2015 M-Labs Ltd

 BIOS built on Mar  6 2020 22:18:06
 BIOS CRC passed (83015cad)

 Migen git sha1: 41922fd
 LiteX git sha1: 7b72148c

--============ SoC info ================--
CPU:       LM32 @ 16MHz
ROM:       32KB
SRAM:      10KB

--========= Peripherals init ===========--

--========== Boot sequence =============--
Booting from serial...
Press Q or ESC to abort boot completely.
sL5DdSMmkekro
Timeout
Booting from flash...
Executing booted program at 0x20058008
--============= Liftoff! ===============--
MicroPython v1.9.4-534-gd2bd40498-dirty on 2020-03-06; litex with lm32
>>> print("Hello World!")
Hello World!
>>> 
ewenmcneill commented 4 years ago

In the interests of science, I've tested the litex commit in the middle -- https://github.com/enjoy-digital/litex/commit/8be5824e258b84df240d34636aaa539124b92c65. As expected, the first failing combination (builds okay, but no output in serial after it is told to boot) is:

(The litex commit and litex-buildenv commit immediately before that do boot the litex BIOS and MiicroPython just fine; and both of those commits have to be updated together because of an API breakage in litex, as noted in https://github.com/enjoy-digital/litex/issues/290; see https://github.com/timvideos/litex-buildenv/issues/277#issuecomment-595683203 for testing the commits immediately before and after this one.)

Naturally the breaking commit is a huge structural commit in litex that completely rearranges how the memory mapping is handled. My guess is that even with the changes in litex-buildenv (eg, https://github.com/timvideos/litex-buildenv/commit/e4c6ffa96f6ac4048181363f9a9be2dbea4b19c3) that's still not sufficient to get actual XIP (execute in place) from Flash ROM working again :-( And/or it's in a different place now, so it's no longer being compiled to execute in the right location.

@mithro, looks like this is when it failed. But it's going to take more digging (and/or assistance from Florent) to figure out how to make it work again. If you've got any further ideas, they'd be welcomed :-)

Ewen

(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-middle-commit) ewen@parthenon:/src/fpga/litex-buildenv$ git log -1 
commit c9745dc49866e416814716efa41ff10a29819b35 (HEAD -> tinyfpga-bx-2019-10-30-middle-commit, tinyfpga-bx-2019-10-30-second-broken, tinyfpga-bx-2019-10-30-broken-here)
Author: Tim 'mithro' Ansell <me@mith.ro>
Date:   Wed Oct 30 12:19:35 2019 -0700

    make: Updating for new LiteX API.
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-middle-commit) ewen@parthenon:/src/fpga/litex-buildenv$ git submodule
 3a6108a75be356a3dc53760d22782f1323248b6b third_party/edid-decode (heads/master-21-g3a6108a)
 01d8f819f15baf9a8cc5d96945a51e4d267ff564 third_party/flash_proxies (heads/master-2-g01d8f81)
+5d1a9847aa805034e58eabf376e2807bfed7b133 third_party/litedram (heads/master-328-g5d1a984)
 4d9e74f10a3fe7bf71ba9bde50f49689c6458dc5 third_party/liteeth (heads/master-25-g4d9e74f)
 47e76f447f6e3d97aac2638a98f967d44db5c349 third_party/litepcie (remotes/origin/reordering-36-g47e76f4)
 db5d2f7881161ce5b9a10a0ab42555f884b9d7c1 third_party/litesata (heads/master-28-gdb5d2f7)
 7a9fa9d3b18362bf707dff25a78661395ef9ee7a third_party/litescope (heads/master-18-g7a9fa9d)
 7457a29b1a47fe15e81fa37f3bbdd510788f1d53 third_party/liteusb (remotes/origin/HEAD)
 49bafa481075e0bfbaf067b63c351ec29e993894 third_party/litevideo (heads/master-8-g49bafa4)
+8be5824e258b84df240d34636aaa539124b92c65 third_party/litex (tinyfpga-bx-works-2019-08-10-130-g8be5824e)
 742360f2ba4c400c6164908f03c6ca3d965f168b third_party/litex-renode (heads/master-25-g742360f)
 41922fde2a8c36cd0f99d4b7ebb3ba9c37ce1489 third_party/migen (0.6.dev-306-g41922fd)
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-middle-commit) ewen@parthenon:/src/fpga/litex-buildenv$ 
ewenmcneill commented 4 years ago

In case it is useful for reference later, this is the difference in the generated directories between the last working revision combination and the first broken combination. In particular it seems that the SRAM_SIZE has changed, and the FLASH_BOOT_ADDRESS has disappeared from the generated output. The latter is potentially relevant because the TinyFPGA BX target relies on updating the cpu_reset_address so that it can start executing from an address covered by the spiflash memory region; but the generated output may possibly just be an output artifact. (SHADOW_BASE also disappears, but I'm not sure if that's relevant.)

https://github.com/timvideos/litex-buildenv/blob/d6cffe26a17af015821142a8b199fc6460f149d8/targets/tinyfpga_bx/base.py#L77

Also of note, the TinyFPGA BX target is explicitly using single SPI not QuadSPI, so it shouldn't be affected by any QuadSPI default changes anyway:

https://github.com/timvideos/litex-buildenv/blob/d6cffe26a17af015821142a8b199fc6460f149d8/targets/tinyfpga_bx/base.py#L87

Ewen

(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-just-before-broken) ewen@parthenon:/src/fpga/litex-buildenv$ cp -pr "build/${PLATFORM}_${TARGET}_${CPU}.${CPU_VARIANT}/software/include/generated/" /tmp/tinyfpga-bx-last-working
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-just-before-broken) ewen@parthenon:/src/fpga/litex-buildenv$ diff -r /tmp/tinyfpga-bx-last-working/ /tmp/tinyfpga-bx-first-broken/
diff -r /tmp/tinyfpga-bx-last-working/csr.h /tmp/tinyfpga-bx-first-broken/csr.h
2c2
< // Auto-generated by Migen (41922fd) & LiteX (7b72148c) on 2020-03-08 16:21:45
---
> // Auto-generated by Migen (41922fd) & LiteX (8be5824e) on 2020-03-08 16:18:06
271,278d270
< #define TIMER0_INTERRUPT 1
< static inline int timer0_interrupt_read(void) {
<   return 1;
< }
< #define UART_INTERRUPT 0
< static inline int uart_interrupt_read(void) {
<   return 0;
< }
291c283
< #define CAS_LEDS_COUNT 1
---
> #define cas_leds_count 1
295c287
< #define CAS_SWITCHES_COUNT 0
---
> #define cas_switches_count 0
299c291
< #define CAS_BUTTONS_COUNT 0
---
> #define cas_buttons_count 0
315,318c307
< #define CONFIG_CPU_TYPE_LM32 1
< static inline int config_cpu_type_lm32_read(void) {
<   return 1;
< }
---
> #define CONFIG_CPU_TYPE_LM32
323,326c312
< #define CONFIG_CPU_VARIANT_MINIMAL 1
< static inline int config_cpu_variant_minimal_read(void) {
<   return 1;
< }
---
> #define CONFIG_CPU_VARIANT_MINIMAL
333a320,331
> }
> #define CONFIG_SHADOW_BASE 2147483648
> static inline int config_shadow_base_read(void) {
>   return 2147483648;
> }
> #define TIMER0_INTERRUPT 1
> static inline int timer0_interrupt_read(void) {
>   return 1;
> }
> #define UART_INTERRUPT 0
> static inline int uart_interrupt_read(void) {
>   return 0;
diff -r /tmp/tinyfpga-bx-last-working/git.h /tmp/tinyfpga-bx-first-broken/git.h
2c2
< // Auto-generated by Migen (41922fd) & LiteX (7b72148c) on 2020-03-08 16:21:45
---
> // Auto-generated by Migen (41922fd) & LiteX (8be5824e) on 2020-03-08 16:18:06
8c8
< #define LITEX_GIT_SHA1 "7b72148c"
---
> #define LITEX_GIT_SHA1 "8be5824e"
diff -r /tmp/tinyfpga-bx-last-working/mem.h /tmp/tinyfpga-bx-first-broken/mem.h
2c2
< // Auto-generated by Migen (41922fd) & LiteX (7b72148c) on 2020-03-08 16:21:45
---
> // Auto-generated by Migen (41922fd) & LiteX (8be5824e) on 2020-03-08 16:18:06
8c8
< #define SRAM_SIZE 0x00002800
---
> #define SRAM_SIZE 0x00004000
21,24d20
< 
< #define FLASH_BOOT_ADDRESS 0x20058000L
< 
< #define SHADOW_BASE 0x80000000L
diff -r /tmp/tinyfpga-bx-last-working/regions.ld /tmp/tinyfpga-bx-first-broken/regions.ld
2c2
<   sram : ORIGIN = 0x01000000, LENGTH = 0x00002800
---
>   sram : ORIGIN = 0x01000000, LENGTH = 0x00004000
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-just-before-broken) ewen@parthenon:/src/fpga/litex-buildenv$ 
ewenmcneill commented 4 years ago

So FLASH_BOOT_ADDRESS was removed in the relevant change:

https://github.com/enjoy-digital/litex/commit/8be5824e258b84df240d34636aaa539124b92c65#diff-d35fa8f6bd2523ded61b8e55c30cf6c2L68-L74

There's a bunch of special case code in the litex BIOS boot.c when FLASH_BOOT_ADDRESS is defined:

https://github.com/enjoy-digital/litex/blob/e801dc0261d7101b148135933f441ed82ca61da8/litex/soc/software/bios/boot.c#L361-L371

to do XIP (execute in place) from the spiflash, instead of copying into RAM. So if FLASH_BOOT_ADDRESS is not defined, that special case handling presumably won't be triggered any more.

AFAICT this relates to the handling of the application (eg, MicroPython) rather than the BIOS itself. So I think we should still be getting BIOS messages on the serial before that, and we're getting nothing on the serial interface when it fails. Which implies not even the BIOS is running.

But noting this because even if we get the BIOS to run, there might still need to be more work done to be able to do XIP of MicroPython again....

Ewen

GitHub
enjoy-digital/litex
Build your hardware, easily! Contribute to enjoy-digital/litex development by creating an account on GitHub.
ewenmcneill commented 4 years ago

Of note, the lm32-crt0.S also has EXECUTE_IN_PLACE special cases:

https://github.com/enjoy-digital/litex/blob/e801dc0261d7101b148135933f441ed82ca61da8/litex/soc/software/libbase/crt0-lm32.S#L115-L131

which is triggered by using crt0-lm32-xip.o:

https://github.com/enjoy-digital/litex/blob/e801dc0261d7101b148135933f441ed82ca61da8/litex/soc/software/libbase/Makefile#L30-L31

And which one is used (lm32-crt0-xip.o / lm32-crt0-ctr.o) determines whether the BIOS will be executed in place (xip) or Copied to RAM (ctr). In litex-buildenv, this is controlled by the COPY_TO_RAM define:

https://github.com/timvideos/litex-buildenv/blob/d6cffe26a17af015821142a8b199fc6460f149d8/firmware/Makefile#L69-L75

which seems to come from the generated variables.mak:

https://github.com/timvideos/litex-buildenv/blob/d6cffe26a17af015821142a8b199fc6460f149d8/firmware/Makefile#L1

but those variables haven't actually changed between the working and broken versions:

ewen@parthenon:/tmp/tinyfpga-bx-last-working$ egrep "EXECUTE|COPY" variables.mak 
COPY_TO_MAIN_RAM=0
EXECUTE_IN_PLACE=1
ewen@parthenon:/tmp/tinyfpga-bx-last-working$ 
ewen@parthenon:/tmp/tinyfpga-bx-first-broken$ egrep "EXECUTE|COPY" variables.mak
COPY_TO_MAIN_RAM=0
EXECUTE_IN_PLACE=1
ewen@parthenon:/tmp/tinyfpga-bx-first-broken$ 

Anyway since crt0 runs before main() in the BIOS, if there's an issue here, then it'll prevent main() from even starting, which plausibly causes the symptoms experienced.

The main other thing which jumps out as before output in main() is the UART init, which depends on setting up interrupts, etc. So anything breaking the UART handling would also cause no output.

https://github.com/enjoy-digital/litex/blob/e801dc0261d7101b148135933f441ed82ca61da8/litex/soc/software/bios/main.c#L575-L589

Ewen

PS: AFAICT few other CPU start.S entries have special cases for EXECUTE_IN_PLACE so this might mean that the smaller iCE40 boards are limited to using the lm32 soft CPU to get this handling.

GitHub
enjoy-digital/litex
Build your hardware, easily! Contribute to enjoy-digital/litex development by creating an account on GitHub.
GitHub
enjoy-digital/litex
Build your hardware, easily! Contribute to enjoy-digital/litex development by creating an account on GitHub.
GitHub
enjoy-digital/litex
Build your hardware, easily! Contribute to enjoy-digital/litex development by creating an account on GitHub.
ewenmcneill commented 4 years ago

FTR, I've figured out where the sram size is being changed from 0x2800 to 0x4000, and I think it's probably a mistake. (Or at least if it's being done deliberately, it's the weirdest undocumented side effect.)

As a reminder this is the relevant difference in the memory map between the working commit and the broken commit:

ewen@parthenon:/tmp$ diff tinyfpga-bx-last-working/regions.ld tinyfpga-bx-first-broken/regions.ld 
2c2
<   sram : ORIGIN = 0x01000000, LENGTH = 0x00002800
---
>   sram : ORIGIN = 0x01000000, LENGTH = 0x00004000
ewen@parthenon:/tmp$ 

and I assume that the actual soft hardware space is 0x2800 in size (approx 10k) rather than 0x4000(16k) in size, because the iCE40 8k is pretty RAM constrained and the relevant platforms have no external ("main") RAM.

It happens at :

https://github.com/enjoy-digital/litex/blob/8be5824e258b84df240d34636aaa539124b92c65/litex/soc/integration/soc_core.py#L355

(which has been rearranged again in subsequent commits), where r.length, ie the SocMemRegion object's length value is maniuplated as part of calculating if there are overlapping memory ranges being defined.

FTR, I believe it's using the Migen log2_int definition:

https://github.com/m-labs/migen/blob/3f9809b0ea62b26f6c99f1b5221b22f8255bc1f6/migen/fhdl/bitcontainer.py#L7-L13

Given those length values end up in the linker map, it seems to me unsafe to go around updating the length after it's been defined, and my guess is that it wasn't intended to do so. The previous code did change the same variable, but it wasn't referencing into an object so I think it'd just have bound a local copy of that variable instead. See:

https://github.com/enjoy-digital/litex/commit/8be5824e258b84df240d34636aaa539124b92c65#diff-5b5aa398d41ddd6086fbe51e97931f5cL352-R358

for what changed.

My guess is that this "accidentally worked" before, and got broken by the refactoring, resulting in a new linker map, which potentially resulted in trying to reference RAM that doesn't exist.

And a bunch of the LM32 exception handlers are basically just "lock up":

https://github.com/enjoy-digital/litex/blob/e801dc0261d7101b148135933f441ed82ca61da8/litex/soc/software/libbase/crt0-lm32.S#L26-L108

so if the compiler happens to, eg, try to put the stack at the top of the (newly expanded) RAM range, which isn't backed by anything, I suspect it'll all go terribly wrong the first time the stack is used :-(

So current'y that's my strongest theory for what went wrong with this commit.

Ewen

time python -u ./make.py --platform=tinyfpga_bx --target=base --cpu-type=lm32 --iprange=192.168.100   --cpu-variant=minimal --cpu-variant=minimal  \
    2>&1 | tee -a /src/fpga/litex-buildenv/build/tinyfpga_bx_base_lm32.minimal//output.20200308-190704.log; (exit ${PIPESTATUS[0]})
Setting integrated RAM size: 00002800
> /src/fpga/litex-buildenv/targets/tinyfpga_bx/base.py(82)__init__()
-> SoCCore.__init__(self, platform, clk_freq, **kwargs)
(Pdb) b litex/soc/integration/soc_core.py:208
Breakpoint 1 at /src/fpga/litex-buildenv/third_party/litex/litex/soc/integration/soc_core.py:208
(Pdb) c
> /src/fpga/litex-buildenv/third_party/litex/litex/soc/integration/soc_core.py(208)__init__()
-> if integrated_sram_size:
(Pdb) print(integrated_sram_size)
10240
(Pdb) n
> /src/fpga/litex-buildenv/third_party/litex/litex/soc/integration/soc_core.py(209)__init__()
-> self.submodules.sram = wishbone.SRAM(integrated_sram_size, init=integrated_sram_init)
(Pdb) n
> /src/fpga/litex-buildenv/third_party/litex/litex/soc/integration/soc_core.py(210)__init__()
-> self.register_mem("sram", self.soc_mem_map["sram"], self.sram.bus, integrated_sram_size)
(Pdb) n
> /src/fpga/litex-buildenv/third_party/litex/litex/soc/integration/soc_core.py(213)__init__()
-> if integrated_main_ram_size:
(Pdb) print(integrated_sram_size)
10240
(Pdb) print(self.mem_regions['sram'].length)
10240
(Pdb) b litex/soc/integration/soc_core.py:354
Breakpoint 2 at /src/fpga/litex-buildenv/third_party/litex/litex/soc/integration/soc_core.py:354
(Pdb) c
> /src/fpga/litex-buildenv/third_party/litex/litex/soc/integration/soc_core.py(354)add_memory_region()
-> for n, r in self.mem_regions.items():
(Pdb) print(self.mem_regions['sram'].length)
10240
(Pdb) n
> /src/fpga/litex-buildenv/third_party/litex/litex/soc/integration/soc_core.py(355)add_memory_region()
-> r.length = 2**log2_int(r.length, False)
(Pdb) print(n)
sram
(Pdb) print(r.length)
10240
(Pdb) n
> /src/fpga/litex-buildenv/third_party/litex/litex/soc/integration/soc_core.py(356)add_memory_region()
-> if n == name or in_this_region(r.origin) or in_this_region(r.origin + r.length - 1):
(Pdb) print(r.length)
16384
(Pdb) ^C
real    2m49.107s
user    0m0.171s
sys 0m0.008s
Makefile:266: recipe for target 'gateware' failed
make: *** [gateware] Error 1

(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-second-broken) ewen@parthenon:/src/fpga/litex-buildenv$ 
GitHub
enjoy-digital/litex
Build your hardware, easily! Contribute to enjoy-digital/litex development by creating an account on GitHub.
GitHub
m-labs/migen
A Python toolbox for building complex digital hardware - m-labs/migen
GitHub
enjoy-digital/litex
Build your hardware, easily! Contribute to enjoy-digital/litex development by creating an account on GitHub.
ewenmcneill commented 4 years ago

The litex code got changed a couple of times on 2019-10-29:

https://github.com/enjoy-digital/litex/commit/4014fbffe135086e86020d6571832b0a8fd7d11f https://github.com/enjoy-digital/litex/commit/9fcf29738710f755ed45ad967eacd2287cd91a67

The first still adjusts other memory regions when checking, but it seems to me that the second one pre-adjusts the length when adding a region so won't adjust a region length later.

Unfortunately by the time we reach that commit, the sram is being added via add_memory_region, which means that it has its size adjusted up to the next power of 2 boundary before it is added (rather than after):

https://github.com/enjoy-digital/litex/blob/9fcf29738710f755ed45ad967eacd2287cd91a67/litex/soc/integration/soc_core.py#L392-L406

so the net effect is the same I think -- the sram size will be increased from 0x2800 to 0x4000.

By the next change to this function:

https://github.com/enjoy-digital/litex/commit/53bc18cc3f739ed02b95a9e9e530915e22b3e9d2

there's actually a comment explaining that it's rounding the size up to the next power of 2, but it's still rounding up.

Then there's another huge refactoring 2020-02-06:

https://github.com/enjoy-digital/litex/commit/6baa07a69bff59249e6e88e5a8ac2aca0bfa7b51

which makes tracing the changes even harder ;-( I think that address decoder then relies on sizes being powers of 2:

https://github.com/enjoy-digital/litex/commit/6baa07a69bff59249e6e88e5a8ac2aca0bfa7b51#diff-d0cf5288909863f45f2189bab58b6abeR38-R67

but it's not clear how that propagates out to generated linker/include files (at least from looking at the diff).

Possibly that later version actually does the correct thing: ie, retains the memory region size as it was requested, but arranges the memory map so that things are powers-of-2 separated (for easy address decoding). So that the compiler will only use the validly mapped ram, but the address decoding is also a simple bitmask. I'm not sure if we have a February 2020-ish version to test.

But anyway the other obvious thing to try testing is just reducing the sram size to 0x2000 (from 0x2800), ie to 8kB (from 10kB), so that it's a power of 2. I'm not actually sure if that's going to be enough RAM to boot anything, but it at least seems worth a try.

Ewen

GitHub
enjoy-digital/litex
Build your hardware, easily! Contribute to enjoy-digital/litex development by creating an account on GitHub.
ewenmcneill commented 4 years ago

\o/

8kB 0x2000 RAM works with the newer (first broken) commits. It doesn't boot to MicroPython, only to the BIOS, because it can't find anything to boot from, but that's a separate problem (https://github.com/timvideos/litex-buildenv/issues/277#issuecomment-596163911). At least we now know why it wasn't even booting into the BIOS at all.

I think at this point I file a litex issue to see whether any of this is even still supported any more, or if the entire TinyFPGA platform port (ie, XIP) has been deliberately thrown out.

Ewen

python -m litex.soc.software.mkmscimg -f build/tinyfpga_bx_base_lm32.minimal//software/micropython/firmware.bin -o build/tinyfpga_bx_base_lm32.minimal//software/micropython/firmware.fbi
python mkimage.py \
      --cpu-variant=minimal --cpu-variant=minimal \
    --override-gateware=build/tinyfpga_bx_base_lm32.minimal//gateware/top.bin \
    --override-bios=build/tinyfpga_bx_base_lm32.minimal//software/bios/bios.bin \
    --override-firmware=build/tinyfpga_bx_base_lm32.minimal//software/micropython/firmware.fbi \
    --output-file=build/tinyfpga_bx_base_lm32.minimal//image-gateware+bios+micropython.bin

Gateware @ 0x00000000 (    135100 bytes) build/tinyfpga_bx_base_lm32.minimal//gateware/top.bin        - Xilinx FPGA Bitstream
ff 00 00 ff 7e aa 99 7e 51 00 01 05 92 00 21 62 03 67 72 01 10 82 00 00 11 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    BIOS @ 0x00028000 (     16004 bytes) build/tinyfpga_bx_base_lm32.minimal//software/bios/bios.bin  - LiteX BIOS with CRC
98 00 00 00 d0 00 00 00 78 01 20 05 38 21 00 00 d0 e1 00 00 e0 00 00 3b 34 00 00 00 34 00 00 00 e0 00 00 00 34 00 00 00 34 00 00 00 34 00 00 00 34 00 00 00 34 00 00 00 34 00 00 00 34 00 00 00
Firmware @ 0x00030000 (    245076 bytes) build/tinyfpga_bx_base_lm32.minimal//software/micropython/firmware.fbi - HDMI2USB Firmware in FBI format (loaded into DRAM)
00 03 bd 4c 83 49 01 b2 98 00 00 00 d0 00 00 00 78 01 20 05 38 21 80 08 d0 e1 00 00 e0 00 00 3b 34 00 00 00 34 00 00 00 e0 00 00 00 34 00 00 00 34 00 00 00 34 00 00 00 34 00 00 00 34 00 00 00
----------------------------------------
       Remaining space     606892 bytes (4 Megabits, 0.58 Megabytes)
           Total space    1048576 bytes (8 Megabits, 1.00 Megabytes)

Flash image: build/tinyfpga_bx_base_lm32.minimal//image-gateware+bios+micropython.bin
ff 00 00 ff 7e aa 99 7e 51 00 01 05 92 00 21 62 03 67 72 01 10 82 00 00 11 00 01 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
tinyprog  --program-image build/tinyfpga_bx_base_lm32.minimal//image-gateware+bios+micropython.bin

    TinyProg CLI
    ------------
    Using device id 1d50:6130
    Only one board with active bootloader, using it.

    Programming /dev/ttyACM0 with build/tinyfpga_bx_base_lm32.minimal//image-gateware+bios+micropython.bin
    Programming at addr 028000
    Waking up SPI flash
    441684 bytes to program
    Programming and Verifying: 442kB [00:04, 98.9kB/s]                                                                                       
    Success!

(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-second-broken) ewen@parthenon:/src/fpga/litex-buildenv$ diff /tmp/tinyfpga-bx-last-working/ build/tinyfpga_bx_base_lm32.minimal/software/include/generated/
diff /tmp/tinyfpga-bx-last-working/csr.h build/tinyfpga_bx_base_lm32.minimal/software/include/generated/csr.h
2c2
< // Auto-generated by Migen (41922fd) & LiteX (7b72148c) on 2020-03-08 16:21:45
---
> // Auto-generated by Migen (41922fd) & LiteX (8be5824e) on 2020-03-08 20:16:49
271,278d270
< #define TIMER0_INTERRUPT 1
< static inline int timer0_interrupt_read(void) {
<   return 1;
< }
< #define UART_INTERRUPT 0
< static inline int uart_interrupt_read(void) {
<   return 0;
< }
291c283
< #define CAS_LEDS_COUNT 1
---
> #define cas_leds_count 1
295c287
< #define CAS_SWITCHES_COUNT 0
---
> #define cas_switches_count 0
299c291
< #define CAS_BUTTONS_COUNT 0
---
> #define cas_buttons_count 0
315,318c307
< #define CONFIG_CPU_TYPE_LM32 1
< static inline int config_cpu_type_lm32_read(void) {
<   return 1;
< }
---
> #define CONFIG_CPU_TYPE_LM32
323,326c312
< #define CONFIG_CPU_VARIANT_MINIMAL 1
< static inline int config_cpu_variant_minimal_read(void) {
<   return 1;
< }
---
> #define CONFIG_CPU_VARIANT_MINIMAL
333a320,331
> }
> #define CONFIG_SHADOW_BASE 2147483648
> static inline int config_shadow_base_read(void) {
>   return 2147483648;
> }
> #define TIMER0_INTERRUPT 1
> static inline int timer0_interrupt_read(void) {
>   return 1;
> }
> #define UART_INTERRUPT 0
> static inline int uart_interrupt_read(void) {
>   return 0;
diff /tmp/tinyfpga-bx-last-working/git.h build/tinyfpga_bx_base_lm32.minimal/software/include/generated/git.h
2c2
< // Auto-generated by Migen (41922fd) & LiteX (7b72148c) on 2020-03-08 16:21:45
---
> // Auto-generated by Migen (41922fd) & LiteX (8be5824e) on 2020-03-08 20:16:49
8c8
< #define LITEX_GIT_SHA1 "7b72148c"
---
> #define LITEX_GIT_SHA1 "8be5824e"
diff /tmp/tinyfpga-bx-last-working/mem.h build/tinyfpga_bx_base_lm32.minimal/software/include/generated/mem.h
2c2
< // Auto-generated by Migen (41922fd) & LiteX (7b72148c) on 2020-03-08 16:21:45
---
> // Auto-generated by Migen (41922fd) & LiteX (8be5824e) on 2020-03-08 20:16:49
8c8
< #define SRAM_SIZE 0x00002800
---
> #define SRAM_SIZE 0x00002000
21,24d20
< 
< #define FLASH_BOOT_ADDRESS 0x20058000L
< 
< #define SHADOW_BASE 0x80000000L
diff /tmp/tinyfpga-bx-last-working/regions.ld build/tinyfpga_bx_base_lm32.minimal/software/include/generated/regions.ld
2c2
<   sram : ORIGIN = 0x01000000, LENGTH = 0x00002800
---
>   sram : ORIGIN = 0x01000000, LENGTH = 0x00002000
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-second-broken) ewen@parthenon:/src/fpga/litex-buildenv$ git diff targets/
diff --git a/targets/tinyfpga_bx/base.py b/targets/tinyfpga_bx/base.py
index 9ab8bd2..cfeffdf 100755
--- a/targets/tinyfpga_bx/base.py
+++ b/targets/tinyfpga_bx/base.py
@@ -66,7 +66,9 @@ class BaseSoC(SoCCore):
         if 'integrated_rom_size' not in kwargs:
             kwargs['integrated_rom_size']=0
         if 'integrated_sram_size' not in kwargs:
-            kwargs['integrated_sram_size']=0x2800
+            # 2020-03-08 - Litex memory regions now need to be powers of 2
+            #kwargs['integrated_sram_size']=0x2800
+            kwargs['integrated_sram_size']=0x2000

         # FIXME: Force either lite or minimal variants of CPUs; full is too big.

(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-second-broken) ewen@parthenon:/src/fpga/litex-buildenv$ ^C
(LX P=tinyfpga_bx.minimal F=micropython R=tinyfpga-bx-2019-10-30-second-broken) ewen@parthenon:/src/fpga/litex-buildenv$ make firmware-connect
flterm --port=/dev/ttyUSB0 --speed=115200
[FLTERM] v2.4-29-g47d3b15 Starting...

        __   _ __      _  __
       / /  (_) /____ | |/_/
      / /__/ / __/ -_)>  <
     /____/_/\__/\__/_/|_|

 (c) Copyright 2012-2019 Enjoy-Digital
 (c) Copyright 2007-2015 M-Labs Ltd

 BIOS built on Mar  8 2020 20:16:49
 BIOS CRC passed (0109b767)

 Migen git sha1: 41922fd
 LiteX git sha1: 8be5824e

--============ SoC info ================--
CPU:       LM32 @ 16MHz
ROM:       32KB
SRAM:      8KB

--========= Peripherals init ===========--

--========== Boot sequence =============--
Booting from serial...
Press Q or ESC to abort boot completely.
sL5DdSMmkekro
Timeout
No boot medium found

--============= Console ================--
litex> 
ewenmcneill commented 4 years ago

@niklasnisbeth I've CC'd you (and @mithro) on https://github.com/enjoy-digital/litex/issues/417; hope that's okay.

@niklasnisbeth If you do have a way of trying the iCE40 HK8K with the sram size forced to 0x2000 (8kB) instead of 0x2800 (10kB) I think that'd be a useful thing to do. In theory it should at least show the Litex boot messages and confirm that serial output works for you too.

Ewen

ewenmcneill commented 4 years ago

FTR, the default integrated_sram_size is coming from litex soc_core.py:

https://github.com/enjoy-digital/litex/blob/b5bddc2332bc701fbcfe028faf0980a3e6641320/litex/soc/integration/soc_core.py#L266-L268

and is also repeated at:

https://github.com/enjoy-digital/litex/blob/b5bddc2332bc701fbcfe028faf0980a3e6641320/litex/soc/integration/soc_core.py#L71-L72

both with hard coded values (I'm not sure why it doesn't follow DRY).

These arguments are included via:

https://github.com/timvideos/litex-buildenv/blob/master/make.py#L15

and:

https://github.com/enjoy-digital/litex/blob/b5bddc2332bc701fbcfe028faf0980a3e6641320/litex/soc/integration/soc_sdram.py#L53-L54

And approximately the same for integrated_rom_size, but one of them is set to 0:

https://github.com/enjoy-digital/litex/blob/b5bddc2332bc701fbcfe028faf0980a3e6641320/litex/soc/integration/soc_core.py#L68-L70

and one of them is set to 32kB:

https://github.com/enjoy-digital/litex/blob/b5bddc2332bc701fbcfe028faf0980a3e6641320/litex/soc/integration/soc_core.py#L261-L265

for added confusion.

Anyway this means it's now harder to distinguish "user specified the default value explicitly" from "user allowed the value to default", than it was when the defaults were 0 so you could be pretty certain if they were specified they were from the user :-(

FWIW, for reasons I don't understand litex-buildenv make.py calls soc_sdram_args(parser) in two places:

https://github.com/timvideos/litex-buildenv/blob/d6cffe26a17af015821142a8b199fc6460f149d8/make.py#L15 https://github.com/timvideos/litex-buildenv/blob/d6cffe26a17af015821142a8b199fc6460f149d8/make.py#L117

and it seems like it'll be called both times every run :-(

It's not clear to me if that's just an oversight, or there's something trying to be done by readding the same arguments....

Ewen

GitHub
enjoy-digital/litex
Build your hardware, easily! Contribute to enjoy-digital/litex development by creating an account on GitHub.
GitHub
enjoy-digital/litex
Build your hardware, easily! Contribute to enjoy-digital/litex development by creating an account on GitHub.
GitHub
timvideos/litex-buildenv
An environment for building LiteX based FPGA designs. Makes it easy to get everything you need! - timvideos/litex-buildenv
GitHub
enjoy-digital/litex
Build your hardware, easily! Contribute to enjoy-digital/litex development by creating an account on GitHub.
GitHub
enjoy-digital/litex
Build your hardware, easily! Contribute to enjoy-digital/litex development by creating an account on GitHub.
GitHub
enjoy-digital/litex
Build your hardware, easily! Contribute to enjoy-digital/litex development by creating an account on GitHub.
ewenmcneill commented 4 years ago

both with hard coded values (I'm not sure why it doesn't follow DRY).

Ah, now I look at the locations, one is the __init__() default arguments, and one is the parser setup. I do still think it'd be a better idea to have a shared common table of "default defaults" both of those were set from... (and in that same comment I asked whether the integrated_rom_size difference was intentional).

Ewen

ewenmcneill commented 4 years ago

The arguments to the target come via:

https://github.com/timvideos/litex-buildenv/blob/d6cffe26a17af015821142a8b199fc6460f149d8/make.py#L55-L57

which filters out the command line parsed args via:

https://github.com/enjoy-digital/litex/blob/b5bddc2332bc701fbcfe028faf0980a3e6641320/litex/soc/integration/soc_sdram.py#L65-L72 https://github.com/enjoy-digital/litex/blob/b5bddc2332bc701fbcfe028faf0980a3e6641320/litex/soc/integration/soc_core.py#L300-L314

and turns it into a pair of dicts which are mashed into **kwargs that just contain the "relevant" arguments.

So by that point it's no longer possible to get at the argparse object and, eg, find out what the default values were for those potential options. Nor is it possible without changing a non-trivial amount of code to, eg, pass another set of values in that contain the "defaults", or indicate which ones were set on the command line and which ones were just allowed to default.

And the "default defaults" aren't anywhere particularly convenient either, so we (a) can't trivially have per-target defaults (the SoC target isn't known until after the command line arguments are parsed), and (b) we can't even compare the value we got with the known defaults to find out if it's at least different.

About the only thing I can think of to do is to try setting per target defaults via the target Makefile, and then do something like what is done with the CPU:

https://github.com/timvideos/litex-buildenv/blob/d6cffe26a17af015821142a8b199fc6460f149d8/make.py#L15-L17

which might actually be overwritten by the second call to soc_sdram_args(parser) later in main() anyway....

Otherwise we unconditionally force the sram / rom sizes for the targets in the target base.py and accept it can't be changed anywhere else.

Ewen

GitHub
enjoy-digital/litex
Build your hardware, easily! Contribute to enjoy-digital/litex development by creating an account on GitHub.
GitHub
enjoy-digital/litex
Build your hardware, easily! Contribute to enjoy-digital/litex development by creating an account on GitHub.
ewenmcneill commented 4 years ago

About the only thing I can think of to do is to try setting per target defaults via the target Makefile, and then do something like what is done with the CPU:

Setting the defaults via the Makefile seems to be the right approach. And we can actually inject them via the command line (which actually happens with the CPU anyway; not sure why it's being set again from the environment...).

I've got a working, relatively cleaned up, example with the latest litex at:

https://github.com/ewenmcneill/litex-buildenv/tree/refactor-tinyfpga-bx

but it's only been fixed up for the TinyFPGA BX.

However I do get a working BIOS boot, with 10kB of RAM. (I did briefly try to get Quad SPI working, but naively swapping from Single SPI to Quad SPI didn't both, so I gave up on that.)

Ewen

PS: There's still no firmware, just "none", so it doesn't boot anything after the BIOS. But I think if I had a firmware it'd work. (I did spend a while trying to get the default litex-buildenv firmware (ie, not the stub) to build for the TinyFPGA, without success; it keeps building the stub firmware, and then being surprised that it can't find software/firmware/firmware.bin. And MicroPython needs some CSR function porting...

        __   _ __      _  __
       / /  (_) /____ | |/_/
      / /__/ / __/ -_)>  <
     /____/_/\__/\__/_/|_|
   Build your hardware, easily!

 (c) Copyright 2012-2020 Enjoy-Digital
 (c) Copyright 2007-2015 M-Labs

 BIOS built on Mar 13 2020 21:38:53
 BIOS CRC passed (a7851729)

 Migen git sha1: d11565a
 LiteX git sha1: b5bddc23

--=============== SoC ==================--
CPU:       LM32 @ 16MHz
ROM:       32KB
SRAM:      10KB

--============== Boot ==================--
Booting from serial...
Press Q or ESC to abort boot completely.
sL5DdSMmkekro
Timeout
Booting from flash...
Executing booted program at 0x20058008

--============= Liftoff! ===============--
GitHub
ewenmcneill/litex-buildenv
An environment for building LiteX based FPGA designs. Makes it easy to get everything you need! - ewenmcneill/litex-buildenv
ewenmcneill commented 4 years ago

(I wrote most of this last night, but reaiised today that I hadn't actually added it to the ticket.)

\o/

I got MicroPython to boot. It needed one more tweak to link in the litex hw include directory, for the new CSR routines; plus moving third_party/ports/fupy/hw out of the way (which was a cached copy of those litex routines -- an old cached copy).

So after a lot of work, I'm now back where I was: able to build/run MicroPython on the TinyFPGA BX via litex-buildenv.

The WIP versions of changes I'm using are https://github.com/ewenmcneill/litex-buildenv/tree/refactor-tinyfpga-bx and https://github.com/ewenmcneill/fupy-micropython/tree/modern-litex (the latter of which has just one change). And since with a new enough litex all the unusual/small memory size issues and XIP issues are resolved, I've closed the litex issued I opened (ie, https://github.com/enjoy-digital/litex/issues/417).

I suspect the next step is to work on https://github.com/timvideos/litex-buildenv/issues/366 (ie, updating the litex dependency), which will probably require some manual porting/updates, so that it's at a new enough version that these unusual RAM size/XIP platforms work again. (It turns out there is an auto dependency updater for litex too, but it's not able to get a successful build so it's not updating litex. Ports like my refractor-tinyfpga-bx branch are possibly required to get good builds, since the main change is that the litex default ROM/SRAM is no longer zero.)

Ewen

        __   _ __      _  __
       / /  (_) /____ | |/_/
      / /__/ / __/ -_)>  <
     /____/_/\__/\__/_/|_|
   Build your hardware, easily!

 (c) Copyright 2012-2020 Enjoy-Digital
 (c) Copyright 2007-2015 M-Labs

 BIOS built on Mar 13 2020 22:35:21
 BIOS CRC passed (57d4b565)

 Migen git sha1: d11565a
 LiteX git sha1: b5bddc23

--=============== SoC ==================--
CPU:       LM32 @ 16MHz
ROM:       32KB
SRAM:      10KB

--============== Boot ==================--
Booting from serial...
Press Q or ESC to abort boot completely.
sL5DdSMmkekro
Timeout
Booting from flash...
Executing booted program at 0x20058008

--============= Liftoff! ===============--
MicroPython v1.9.4-1430-ge23216bf2 on 2020-03-13; litex with lm32
>>> print("Hello World")
Hello World
>>> 
GitHub
ewenmcneill/litex-buildenv
An environment for building LiteX based FPGA designs. Makes it easy to get everything you need! - ewenmcneill/litex-buildenv
GitHub
ewenmcneill/fupy-micropython
MicroPython port to litex FPGA platforms. Contribute to ewenmcneill/fupy-micropython development by creating an account on GitHub.
ewenmcneill commented 4 years ago

@niklasnisbeth Now that #348 is merged, which updates to a litex which has working non-power-of-2 memory and a working set of compile flags, I think the iCE40 HX8K EVB is likely to work again (and if it doesn't, it'll hopefully just need some minor tweaks as made to the other platforms).

Can you test again when you get a chance and let us know? (TinyFPGA BX is working again for me; that was tested before we merged #348.)

Ewen

niklasnisbeth commented 4 years ago

Hello. It has taken me a while to get litex-buildenv to work again, but tonight I have been able to try from rev. a3d3477a78ddfc856e87d5a3753f4baf8414cdf2.

Using TARGET=ice40_hx8k_b_evn and FIRMWARE=stub, neither CPU=lm32.minimal nor CPU=vexriscv.minimal produce any output on /dev/ttyUSB1 at 115200 baud. I do get a very slow binary counter on the LEDs, but I'm not sure where that's coming from. Anything else in FIRMWARE does not allow me to build an image - I thought micropython was supposed to work there?

ewenmcneill commented 4 years ago

Thanks for testing. lm32.minimal is basically what I was testing with on a TinyFPGA BX, so that's the most likely to work (I suspect vexriscv.minimal should work too, but I don't know when anyone last tested that on an iCE40 from litex-buildenv).

MicroPython should build now (at least it did a couple of weeks ago), but it needs to be built with a custom script, eg:

...
export FIRMWARE=micropython
make gateware
scripts/build-micropython.sh

(It'd be nice if FIRMWARE=micropython and "make image" or similar was sufficient, but that hasn't been set up in the Makefiles AFAIK.)

Assuming the image built and flashed okay, my guess is that the "slow binary counter on the LEDs" is something that's built into the gateware (ie, not reliant on the CPU), and maybe the CPU still isn't booting correctly.

Unfortunately I don't have a ice40_hx8k_b_evn to test myself. But my guess would be that maybe something's still needing to be converted in the target file to ensure that the CPU/RAM gets built with the correct memory layout.

Ewen