litex-hub / litehyperbus

Small footprint and configurable HyperBus core
BSD 2-Clause "Simplified" License
10 stars 5 forks source link

Working example help #6

Closed giggiu16 closed 3 years ago

giggiu16 commented 3 years ago

Hi everyone! I am trying to use litehyperbus to access the HyperRAM of the ecp5-mini board. I successfully implemented the board in Litex ecosystem, creating target and platform files, to provide the BaseSOC class and I am able to use base things of Litex. Unfortunately, trying to add the onboard HyperRAM and enabling the required submodule, the mem_test always fails. I am struggling with that from months but I don't have the necessary expertise in Litex to correctly debug the issue.

This is the result of a mem_test I tried to execute:

litex> mem_test 0x4000000 1000
Memtest at 0x00000g (08B)...
  Write: 0x0g-0x0g 08B   
   Read: 0x0g-0x0g 08B   
  bus errors:  00/00
  addr errors: 0a/0a
  data errors: 0a/0a
Memtest KO

The HyperRAM is a 1.8v Cypress S27KS0641. As per datasheet, it supports only differential clocking when using 1.8v part. As the clock pin is not on a left nor a right IO, I have to use pseudo-differential output of the ECP5 LVCMOS18D and that should be easy because the two clock pins are on a pseudo-differential pair.

Unfortunately I do not have the required instruments to debug the hardware (no oscilloscope nor a decent logic analyzer), so I am blaming my wrong implementation for now. I have also taken reference from some other implementations of HyperRAM with ECP5 but I haven't noticed significant differences beside the IO side where the memory is connected, so this is why I am assuming that the hardware is correct.

This is the schematic of the HyperRAM part:

Schermata 2021-08-05 alle 22 00 57 Schermata 2021-08-05 alle 22 01 26

Some implementation bits of the board in Litex ecosystem follows:

Platform pads of HyperRAM:

    # HyperRAM
    ("hyperram", 0,
        Subsignal("clk",    Pins("A2"), IOStandard("LVCMOS18D"), Misc("SLEWRATE=FAST")),
        # Subsignal("clk_n",  Pins("B3"), IOStandard("LVCMOS18")),
        Subsignal("rst_n",  Pins("B4"), IOStandard("LVCMOS18")),
        Subsignal("dq",     Pins("A6 C4 A7 B7 A8 B6 D4 A5"), IOStandard("LVCMOS18")),
        Subsignal("cs_n",   Pins("A3"), IOStandard("LVCMOS18")),
        Subsignal("rwds",   Pins("A4"), IOStandard("LVCMOS18")),
    ),

Submodule instantiation:

        self.submodules.hyperram  = HyperRAM(platform.request("hyperram"))
        self.add_wb_slave(self.mem_map["hyperram"], self.hyperram.bus)
        self.add_memory_region("hyperram", self.mem_map["hyperram"], 8*1024*1024) #8MB HyperRAM

Memory map with hyperram entry:

    mem_map = {
        "hyperram": 0x04000000,
    }

What I am doing wrong? Can you suggest me how to investigate further that issue? I have no idea on how to identify the root cause of the issue as now, but maybe someone can point me toward the right way.

Thank you so much for the help in advance!

gregdavill commented 3 years ago

It sounds like you're doing everything right. I can take a closer look at this later tonight for you.

giggiu16 commented 3 years ago

It sounds like you're doing everything right.

I can take a closer look at this later tonight for you.

Thanks. Let me know if I need to share something other that can help you further!

joshajohnson commented 3 years ago

Thanks Greg and Luigi, I had planned to investigate this issue further but still haven't got around to it.

My Litex board def is here if that helps as a starting point.

I believe @giggiu16 and I independently ran into this issue, which is making me think it's a hardware problem, but hoping it's not the case.

gregdavill commented 3 years ago

There might be something wrong with using add_wb_slave + add_memory_region. I initially used register_mem like this to add in to the SoC, and it seems to be working.

# HyperRam ---------------------------------------------------------------------------------
        self.submodules.hyperram = HyperRAM(platform.request("hyperram"))
        self.register_mem("hyperram", self.mem_map["hyperram"], self.hyperram.bus, 8*1024*1024)
        __   _ __      _  __
       / /  (_) /____ | |/_/
      / /__/ / __/ -_)>  <
     /____/_/\__/\__/_/|_|
   Build your hardware, easily!

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

 BIOS built on Aug 10 2021 20:20:30
 BIOS CRC passed (36974954)

 Migen git sha1: 3ffd64c
 LiteX git sha1: fb8f45be

--=============== SoC ==================--
CPU:            VexRiscv @ 48MHz
BUS:            WISHBONE 32-bit @ 4GiB
CSR:            32-bit data
ROM:            128KiB
SRAM:           8KiB

-- snip --

--============= Console ================--

litex> mem_list
Available memory regions:
ROM       0x00000000 0x20000 
SRAM      0x10000000 0x2000 
HYPERRAM  0x20000000 0x800000 
CSR       0xf0000000 0x10000 

litex> mem_test 0x20000000 0x800000
Memtest at 0x20000000 (8MiB)...
  Write: 0x20000000-0x20800000 8MiB     
   Read: 0x20000000-0x20800000 8MiB     
Memtest OK

Here is the code you can try: https://github.com/gregdavill/ecp5-mini-examples/blob/main/litex/soc-hr/ecp5_mini.py

Attached is the compiled gateware that enumerates as a USB-ACM device. ecp5_mini.zip

gregdavill commented 3 years ago

Update

It also works when adding it like this.

        # HyperRam ---------------------------------------------------------------------------------
        self.submodules.hyperram = HyperRAM(platform.request("hyperram"))
        self.add_wb_slave(self.mem_map["hyperram"], self.hyperram.bus)
        self.add_memory_region("hyperram", self.mem_map["hyperram"], 8*1024*1024) #8MB HyperRAM
joshajohnson commented 3 years ago

Thanks Greg, reproduced and working great over here :)

giggiu16 commented 3 years ago

Thanks Greg, I started testing again using register_mem as you suggested but that didn't worked. I have fixed some other things around my Litex platform implementation (PLL generation) but no luck there also.

I have then flashed your bitstream and the mem_test still goes KO.

litex> mem_test 0x20000000 0x800000
Memtest at 0x20000000 (8MiB)...
  Write: 0x20000000-0x20800000 8MiB     
   Read: 0x20000000-0x20800000 8MiB     
  bus errors:  256/256
  addr errors: 8191/8192
  data errors: 2097152/2097152
Memtest KO

I have no choice apart from removing the HyperRAM from the board, reflow the chip and solder it again using the hot air.

Thank you so much for your help, I hope to do that soon and to resolve that annoying issue, at least I confirmed that my implementation in Litex is good.

giggiu16 commented 3 years ago

Hi, just a quick update: after removing the HyperRAM, reballing and soldering it again on the ecp5-mini, finally the issue has been resolved! Before soldering again the HyperRAM I wrote a small gateware that toggled all of its pins to verify electrical connection with the ECP5 (and of course to not reflow the ECP5 also), then after successful verification of all the HR pins I soldered it again and everything worked as expected!

Thank you so much for your help, I am going to close that issue now.