Code Monkey home page Code Monkey logo

litespi's People

Contributors

danc86 avatar derekmulcahy avatar enjoy-digital avatar fjullien avatar fkokosinski avatar gregdavill avatar kgugala avatar kowalewskijan avatar mithro avatar shenki avatar suarezvictor avatar zyp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

litespi's Issues

litex.soc.doc generation error

I'm updating some older icebreaker litex examples to use more upstream LiteX features. One of which is LiteSPI
The SoC works, as expected, but it appears I'm no longer able to generate documentation...

I've been able to replicate this in the litex_boards.1bitsquared_icebreaker target.

diff --git a/litex_boards/targets/1bitsquared_icebreaker.py b/litex_boards/targets/1bitsquared_icebreaker.py
index 0ab0434..a2c0daf 100755
--- a/litex_boards/targets/1bitsquared_icebreaker.py
+++ b/litex_boards/targets/1bitsquared_icebreaker.py
@@ -160,6 +160,9 @@ def main():
     builder = Builder(soc, **builder_argdict(args))
     builder.build(run=args.build)
 
+    from litex.soc.doc import generate_docs
+    generate_docs(soc, "build/docs/")
+
     if args.load:
         prog = soc.platform.create_programmer()
         prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".bin"))

Then running creates the following error.

$ ./1bitsquared_icebreaker.py

--- snip ---

Traceback (most recent call last):
  File "/home/greg/Projects/icebreaker-litex-examples/soc/deps/litex-boards/litex_boards/targets/1bitsquared_icebreaker.py", line 174, in <module>
    main()
  File "/home/greg/Projects/icebreaker-litex-examples/soc/deps/litex-boards/litex_boards/targets/1bitsquared_icebreaker.py", line 164, in main
    generate_docs(soc, "build/docs/")
  File "/home/greg/Projects/icebreaker-litex-examples/soc/deps/litex/litex/soc/doc/__init__.py", line 99, in generate_docs
    documented_region = DocumentedCSRRegion(
  File "/home/greg/Projects/icebreaker-litex-examples/soc/deps/litex/litex/soc/doc/csr.py", line 80, in __init__
    docs = module.get_module_documentation()
  File "/home/greg/Projects/icebreaker-litex-examples/soc/deps/litex/litex/soc/integration/doc.py", line 141, in gatherer
    return sorted(r, key=lambda x: x.duid)
  File "/home/greg/Projects/icebreaker-litex-examples/soc/deps/litex/litex/soc/integration/doc.py", line 141, in <lambda>
    return sorted(r, key=lambda x: x.duid)
  File "/home/greg/Projects/icebreaker-litex-examples/soc/deps/migen/migen/fhdl/module.py", line 136, in __getattr__
    raise AttributeError("'"+self.__class__.__name__+"' object has no attribute '"+name+"'")
AttributeError: 'LiteSPISDRPHYCore' object has no attribute 'duid'

Fix the name of LiteSPI instance in example/arty.py

I see that in examples/arty.py we use spiflash_mmap name for LiteSPI instance (link). In my opinion it could be quite confusing since LiteSPI by default is configured to have both Master and MMAP mode (link). I think we should decide either we change the name to something more generic like spiflash_core or we should remove default master mode.

Verify that dummy bits are handled correctly in I/O modes

While looking at the generic PHY code I noticed that amount of actual dummy cycles depends on number of pins used by the command when sending an address (ie. if command sends address on 4 lanes then 8 dummy bits will result in only 2 dummy cycles).
I think we should check if those cases are currently handled correctly and if not then fix them.

Improve PHY MMAP/Master sharing?

The PHY is currently always shared between 2 Modules and when a Module is disabled, a dummy one is inserted. We could make things dynamic, like for example what is done in LiteEth for the UDP ports:
https://github.com/enjoy-digital/liteeth/blob/master/liteeth/core/udp.py#L32
or in LiteDRAM for the DRAM ports:
https://github.com/enjoy-digital/litedram/blob/master/litedram/core/crossbar.py

This way, when only 1 Module is used, it would have a direct connection to the PHY, and when several Modules are sharing the PHY the mux logic will be inserted to share it.

The current implementation will not prevent things to work and will not necessarily use more resources (since the dummy Modules will be simplified at synthesis), but improving it would make things closer to the others cores and will provide more flexibility for future features. (ex another type of Module that would be connected to the PHY).

Add DDR support for Fomu

I tried getting DDR SPI on Fomu by editing https://github.com/litex-hub/litex-boards/blob/master/litex_boards/targets/kosagi_fomu.py:

-        self.add_spi_flash(mode="4x", module=spi_flash_modules[spi_flash_module](), with_master=False)
+        self.add_spi_flash(mode="4x", module=spi_flash_modules[spi_flash_module](), with_master=False, rate='1:2')

The build attempt gave me the error

Info: Placed 14 cells based on constraints.
ERROR: Unable to find a placement location for cell 'SB_IO_13'
0 warnings, 1 error

Looking at the generated SoC rtl build/kosagi_fomu_pvt/gateware/kosagi_fomu_pvt.v I saw this pattern:

SB_IO #(
        .IO_STANDARD("SB_LVCMOS"),
        .PIN_TYPE(6'd0)
) SB_IO_13 (
        .CLOCK_ENABLE(1'd1),
        .INPUT_CLK(sys_clk),
        .PACKAGE_PIN(builder_inferedddrtristate2__i),
        .D_IN_0(main_basesoc_litespiddrphycore2[2]),
        .D_IN_1(main_basesoc_litespiddrphycore3[2])
);

SB_IO #(
        .PIN_TYPE(6'd41)
) SB_IO_14 (
        .D_OUT_0(builder_inferedddrtristate2__o),
        .OUTPUT_ENABLE(builder_inferedddrtristate2_oe),
        .PACKAGE_PIN(spiflash4x_dq[2]),
        .D_IN_0(builder_inferedddrtristate2__i)
);

These two IOs are connected by wire builder_inferedddrtristate2__i. I suspect this is not quite correct, in particular the connection to PACKAGE_PIN of the first IO.

Add travis CI

  • Should run the tests
  • Should check the style (might be problematic?)

Missing opcodes in auto-generated Modules.

The auto-generated modules seem to be missing some opcodes. When switch the different LiteX-Boards targets to LiteSPI, modifications have been made to be able to enable Quad SPI mode on some boards, for ex:

So it seems the script generating the modules is not listing all supported the opcodes.

x4 configuration: read flash config/status errors (x1 mode)

In d436b02 a small change was made to the sr_in source when operating in x1 mode. This works in x1 mode with the other changes. But unfortunately this breaks x1 CPU controlled commands when the core is configured in x2 or x4 modes

Here is the change:

diff --git a/litespi/phy/generic_sdr.py b/litespi/phy/generic_sdr.py
index c5446fe..a39ac23 100644
--- a/litespi/phy/generic_sdr.py
+++ b/litespi/phy/generic_sdr.py
@@ -158,7 +169,7 @@ def __init__(self, pads, flash, device, clock_domain, default_divisor, cs_delay)
         # Data In Shift.
         self.sync += If(sr_in_shift,
             Case(sink.width, {
-                1 : sr_in.eq(Cat(dq_i[1],  sr_in)), # 1: pads.miso
+                1 : sr_in.eq(Cat(dq_i[:1], sr_in)),
                 2 : sr_in.eq(Cat(dq_i[:2], sr_in)),
                 4 : sr_in.eq(Cat(dq_i[:4], sr_in)),
                 8 : sr_in.eq(Cat(dq_i[:8], sr_in)),

When configured for x4 mode with a CSR controller enabled most config/status commands operate in 1bit mode. The controller talks on DQ0 and they respond on DQ1.

This commit breaks this behavior, as the controller is now listening for a response on DQ0, which is simply the data it's just sent out.

Wrong data read from SPI flash on Arty

It appears that on NeTV2 board, data read from flash is the same as compared to hexdump output.
On Arty board it is not. It looks like there is a problem with sampling process. Example:
Binary data:
00000000 48 00 49 00 bb 00 11 |H.I....|
Data read using BIOS:
Memory dump: 0x80000000 24 00 24 80 dd 80 08 ff ff ff ff ff ff ff ff ff $.$.............

When we take for instance:
0x48 = 0b1001000
in flash it seems to be: 0x24 = 0b100100, so one bit is missing.

Comparison of whole binary (original vs. flash):
0b1001000000000000100100100000000101110110000000000010001
0b100100000000000010010010000000110111011000000000001000x

Overall:

  • 1 bit missing
  • 1 bit is wrong in the middle

Speed test fails at DIV=0, reverts to lower speed

Hi, I'm testing on the ECPIX-5 which has an IS25LP256D, configured to do READ_1_4_4 with 6 dummy cycles as per the flash datasheet. Everything appears to work fine except the speed test fails for DIV=0:

Initializing SPIFlash...
Testing against CRC32: feba9ad6
[DIV: 9] feba9ad6
[DIV: 8] feba9ad6
[DIV: 7] feba9ad6
[DIV: 6] feba9ad6
[DIV: 5] feba9ad6
[DIV: 4] feba9ad6
[DIV: 3] feba9ad6
[DIV: 2] feba9ad6
[DIV: 1] feba9ad6
[DIV: 0] 312f98e1
SPIFlash freq configured to 18 MHz

According to the datasheet, this mode should be good for 81 MHz:
image

My sysclk is 75 MHz, so DIV=0 should result in 37.5 MHz, which is nowhere close to the maximum. The calculated checksum for DIV=0 is also identical if I run it multiple times. This suggests that there's a deterministic logic error.

As an aside, I also doubt that a speed test like this is actually useful -- in a configuration where the flash is not rated for the max speed the core can do, it can still work well enough to pass the test, but fail later.

How to write to flash?

How to use litespi to perform flash write?
I am trying to integrate litespi and use bios to download images to flash.

Arty: Example for storing gateware on SPIflash

Hi,

has anyone accomplished to store the gateware on the SPIflash on an Arty A7 already? Do we have a documentation available for this? What is the most reasonable way to make it very easy to use (e.g. --store instead of --load after building the gateware?)

Looking forward to your ideas!

Adding more ports to crossbar, how to handle arbitration?

Hi, currently there can be two modules attached to the crossbar; one LiteSPIMMAP and one LiteSPIMaster. Arbitration between the two is handled by the mux_sel CSR bit. Software sets it to use the master interface, and clears it to allow the MMAP interface to be used.

I'm planning to add a couple more modules that needs to be hooked up to the crossbar:

  • A write interface that hooks up to a LUNA USBRequestHandler to implement DFU directly in gateware.
  • A reader for the flash unique ID, to derive a serial number for the USB device.

To allow this, we need to implement a better arbitration mechanism. Any thoughts on how to go about this?

I imagine there might be situations where one module needs to send multiple commands uninterrupted, so I figure the arbitration mechanism should be decoupled from both first/last flags on the streams and the chip select signal.

Rename XIP to MMAP?

XIP can be a bit confusing, we are in fact providing a MMAP interface to the SPI Flash and one if its usecase is indeed XIP when we are executing code directly from the Flash. But this will also be used to copy blocks of data from the SPI Flash to RAM, store a file system, etc... so MMAP would probably give a better description of the purpose of the core.

Improve resources usage.

LiteSPI is working correctly with good performance on the different boards it has been tested but uses more resources than the LiteX SPIFlash core that was used previously.

When testing different configurations on the iCEBreaker (with python3 -m litex_boards.targets.1bitsquared_icebreaker --cpu-type=serv --build) we get the following resource usage:

No SPIFlash LiteX's SPIFlash LiteSPI (no Master) LiteSPI (with Master (depth=1)))
1883 LCs 2036 LCs 2353 LCs 2921 LCs
Ref +153 LCs +470 LCs +1038 LCs
- Ref +317 LCs + 885 LCs

The LiteX's SPIFlash core was equivalent to LiteSPI with Master enabled, so we should reduce resource usage to be able to do efficient designs on small FPGAs.

Support for ECP5 boot flash in LiteSPI

Currently clkgen.py has support for xc7 devices using a Xilinx STARTUPE2 instance. Similar support could be added for ECP5 using the Lattice USRMCLK instance. From looking at other code, without understanding much about what is required, it looks like USRMCLK does a similar thing to STARTUPE2. I added the following in clkgen.py and it seems to work.

            elif device == "ecp5":
                self.specials += Instance("USRMCLK",
                    i_USRMCLKI  = clk,
                    i_USRMCLKTS = 0
                )

This code is selected by passing thedevice = "ecp5" parameter to LiteSPIPHY.

I can try the whole pull request process if required.

Make 10000 cycle timeout configurable

https://github.com/litex-hub/litespi/blob/master/litespi/core/mmap.py#L106

When used in https://github.com/litex-hub/litex-boards/blob/master/litex_boards/targets/digilent_arty.py, litespi has a 10000 cycle delay for each non-sequential load from flash. If flash is read sequentially, I don't see the delay.

For some reason, I don't see this large delay on the (internal) HPS board, even for non-sequential loads. I haven't had time to investigate why the behavior is different. Instantiation: https://github.com/google/CFU-Playground/blob/main/soc/hps_soc.py#L143-L150

@kgugala FYI

Support Auto-Initializing SPI Flashes to Quad Mode

This applies to my version of the icebreaker, and is a follow up of a conversation with @smunaut.

Some SPI flashes, like some part numbers in the W25Q128JV family, support 4x operation, but are not enabled for 4x on power-on. My icebreaker uses one of these flashes where the default is 1x on power on, and therefore 4x operation does not work out-of-the-box. This can be surprising behavior, and I think initializing to 4x mode if a user requested a 4x may be a user-invisible solution :D!

The PHY supports doing 1x reads even if you supply pads for 4x operation. I think the easiest way to add support for this is to add some init steps to the LiteSPIMMAP FSM, which does the following (based on W25Q128JV datasheet):

  1. Send command 50h (Write Enable for Volatile Status Register)
  2. Read SR2 (command 35h)
  3. Set QE bit (bit 1) in the read value
  4. Write SR2 (command 31h)
  5. Wait 50 nanoseconds (tSHSL2- part-specific?) before allowing any further accesses to take place.

After these 5 steps have occurred, your SPI flash will be in quad mode until power is cycled.

However, I haven't done this myself because I'm not sure the best way to represent "flash may need to be initialized into 4x mode" per SpiNorFlashModule. In the case of W25Q128JV, different part numbers have different defaults (although initializing a part that doesn't need to be initialized is harmless). There's plenty of ways to represent "needs 4x init", but which way is best? Can it be done without regenerating the entirity of generated_modules.py?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.