enjoy-digital / litex

Build your hardware, easily!
Other
2.99k stars 569 forks source link

ulx3s ecp5 soc not working when using Lattice Diamond #1965

Open dwalton65 opened 5 months ago

dwalton65 commented 5 months ago

If I perform the following steps, everything builds ok using trellis, and I get the BIOS prompt.

cd litex-boards/litex_boards/targets
./radiona_ulx3s.py --build --device=LFE5U-85F --cpu-type=vexriscv --cpu-variant=minimal --csr-csv=build/csr.csv
fujprog build/radiona_ulx3s/gateware/radiona_ulx3s.bit
litex_term /dev/ttyUSB0

If I try using diamond 3.13, it builds without errors, but I don't get the BIOS prompt

cd litex-boards/litex_boards/targets
rm -rf build
./radiona_ulx3s.py --build --toolchain=diamond --device=LFE5U-85F --cpu-type=vexriscv --cpu-variant=minimal --csr-csv=build/csr.csv
fujprog build/radiona_ulx3s/gateware/radiona_ulx3s.bit
litex_term /dev/ttyUSB0

If you are using the jtag module, you need to make some other changes as discussed here and here

https://github.com/enjoy-digital/litex/blob/10083f4d87aae73599a7d929bd57cda70f8b0371/litex/soc/cores/jtag.py#L382 Change from p_INIT = 2 to p_init = 2

I also possibly found some .lpf configuration issues. If I open the generated project "build/radiona_ulx3s/gateware/radiona_ulx3s.ldf" in the Diamond GUI, it shows "CONFIG_IOVOLTAGE 2.5" in Global Preferences. I believe this should be 3.3. Adding the following to "build/radiona_ulx3s/gateware/radiona_ulx3s.lpf" fixes that and also sets the bank voltages: SYSCONFIG CONFIG_IOVOLTAGE=3.3; BANK 0 VCCIO 3.3 V; BANK 1 VCCIO 3.3 V; BANK 2 VCCIO 3.3 V; BANK 3 VCCIO 3.3 V; BANK 6 VCCIO 3.3 V; BANK 7 VCCIO 3.3 V; BANK 8 VCCIO 3.3 V;

Lattice Diamond 3.13 builds the project without errors, but I don't still don't get the BIOS prompt. There are a lot of warnings though. Most are along the lines of logic being pruned because no output depends on it. The ones I have checked seem valid.

The LED chaser is working though.

Any ideas where I should look next, and has anyone managed to build a LiteX project for the ulx3s with Lattice Diamond?

dwalton65 commented 5 months ago

I tried using LiteScope as described on this page Use LiteScope To Debug A SoC This worked well when using trellis, however when using Diamond litescope_cli --csr-csv=build/csr.csv just timed out.

I then tried just capturing the 25MHz clock. analyzer_signals was changed to:

        analyzer_signals = [
            self.crg.clk25,
            # # IBus (could also just added as self.cpu.ibus)
            # self.cpu.ibus.stb,
            # self.cpu.ibus.cyc,
            # self.cpu.ibus.adr,
            # self.cpu.ibus.we,
            # self.cpu.ibus.ack,
            # self.cpu.ibus.sel,
            # self.cpu.ibus.dat_w,
            # self.cpu.ibus.dat_r,

            # # DBus (could also just added as self.cpu.dbus)
            # self.cpu.dbus.stb,
            # self.cpu.dbus.cyc,
            # self.cpu.dbus.adr,
            # self.cpu.dbus.we,
            # self.cpu.dbus.ack,
            # self.cpu.dbus.sel,
            # self.cpu.dbus.dat_w,
            # self.cpu.dbus.dat_r,
        ]

This works for both trellis and Diamond. I will see if LiteScope can be used to monitor anything else when my project is built using Diamond.

dwalton65 commented 5 months ago

I just ran LiteScope with the SOC bus again, and this time it worked. diamond_soc_bus ibus.adr is looping over the addresses 0, 1, 2 The beginning of radiona_ulx3s_platform_rom.init contains the following:

0b00006f
00000013
00000013
00000013
00000013
00000013
00000013
00000013

So the captured values for dat_r are correct.

dwalton65 commented 5 months ago

For comparison, this is a capture showing boot from address 0 when the project was build using trellis trellis_soc_bus

dwalton65 commented 5 months ago

If I change from vexriscv to picorv32, the soft cpu works, and I get the bios prompt.

I am using the Windows GUI version of Diamond. The steps to reproduce this are as follows: python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=picorv32 --build --device LFE5U-85F

Edit build/radiona_ulx3s/gateware/radiona_ulx3s.lpf and add the follolwing lines:

SYSCONFIG CONFIG_IOVOLTAGE=3.3 COMPRESS_CONFIG=ON SLAVE_SPI_PORT=DISABLE MASTER_SPI_PORT=ENABLE SLAVE_PARALLEL_PORT=DISABLE;
BANK 0 VCCIO 3.3 V;
BANK 1 VCCIO 3.3 V;
BANK 2 VCCIO 3.3 V;
BANK 3 VCCIO 3.3 V;
BANK 6 VCCIO 3.3 V;
BANK 7 VCCIO 3.3 V;
BANK 8 VCCIO 3.3 V;

Edit build/radiona_ulx3s/gateware/radiona_ulx3s.tcl and comment out each line after "prj_project save" My radiona_ulx3s.tcl looked like:

prj_project new -name "radiona_ulx3s" -impl "impl" -dev LFE5U-85F-6BG381C -synthesis "synplify"
prj_impl option {include path} {""}
prj_src add "/home/david/workspace/litex_python/lib/python3.10/site-packages/pythondata_cpu_picorv32/verilog/picorv32.v" -work work
prj_src add "/home/david/workspace/ulx3s/litex_tests/picorv32_test1/build/radiona_ulx3s/gateware/radiona_ulx3s.v" -work work
prj_impl option top "radiona_ulx3s"
prj_project save
#prj_run Synthesis -impl impl -forceOne
#prj_run Translate -impl impl
#prj_run Map -impl impl
#prj_run PAR -impl impl
#prj_run Export -impl impl -task Bitgen
#prj_project close

Create the Diamond project by running pnmainc build/radiona_ulx3s/gateware/radiona_ulx3s.tcl. If using the linux version of Diamond diamondc build/radiona_ulx3s/gateware/radiona_ulx3s.tcl. Using the Diamond GUI open the project build/radiona_ulx3s/gateware/radiona_ulx3s.ldf Run "Synthesize Design", "Translate Design", "Plate & Route Design", "Export files->Bitstream File" Program the ulx3s with fujprog build/radiona_ulx3s/gateware/impl/radiona_ulx3s_impl.bit

litex_term /dev/ttyUSB0


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

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

 BIOS built on Jun  3 2024 09:54:12
 BIOS CRC passed (b9d5e69f)

 LiteX git sha1: 72854b8be

--=============== SoC ==================--
CPU:            PicoRV32 @ 50MHz
BUS:            wishbone 32-bit @ 4GiB
CSR:            32-bit data
ROM:            128.0KiB
SRAM:           8.0KiB
L2:             8.0KiB
SDRAM:          32.0MiB 16-bit @ 50MT/s (CL-2 CWL-2)
MAIN-RAM:       32.0MiB

--========== Initialization ============--
Initializing SDRAM @0x40000000...
Switching SDRAM to software control.
Switching SDRAM to hardware control.
Memtest at 0x40000000 (2.0MiB)...
  Write: 0x40000000-0x40200000 2.0MiB
   Read: 0x40000000-0x40200000 2.0MiB
Memtest OK
Memspeed at 0x40000000 (Sequential, 2.0MiB)...
  Write speed: 9.5MiB/s
   Read speed: 13.5MiB/s

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

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

litex>

If I repeat the above with: python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=vexriscv --cpu-variant=minimal --build --device LFE5U-85F I do not get the bios prompt.

The Diamond "Place & Route Trace" report shows:

FREQUENCY NET "main_crg_clkout0" 50.000000 MHz (0 errors)
            4096 items scored, 0 timing errors detected.
Report:   60.979MHz is the maximum frequency for this preference.
Timing summary (Setup and Hold):
---------------

Timing errors: 0 (setup), 0 (hold)
Score: 0 (setup), 0 (hold)
Cumulative negative slack: 0 (0+0)
Dolu1990 commented 5 months ago

Hi,

One thing i noticed is that some synthesis tools aren't following 1 to 1 the verilog description when it is about ram block inferation (that include vivado or ISE if i remember well) In particular, when you use the uncached instruction VexRiscv config (minimal), there is a little 2-3 entry buffer implemented as an array sync write / combinatorial read, and some synthesis tools infer them as block ram, but that isn't true to the verilog as the write to read latency become 2 cycle instead of 1, creating buggy hardware.

Can you try with the cpu-variant lite instead ?

(to workaround the xilinx behaviour i had to add verilog attributes to the array)

dwalton65 commented 5 months ago

Hi Dolu1990 I have also tried the VexRiscv cpu-variants lite and full with the same result. These all work when using the trellis toolchain. The following shows the options I have tried and the SDRAM speed results as reported by the BIOS. Where I have indicated "failed", this usually means that Diamond has reported syntax errors.

#python3 -m litex_boards.targets.radiona_ulx3s --cpu-type=vexriscv --cpu-variant=minimal --build --device LFE5U-85F --ecppack-compress
#  Write speed: 10.7MiB/s
#   Read speed: 15.4MiB/s

#python3 -m litex_boards.targets.radiona_ulx3s --cpu-type=vexriscv --cpu-variant=lite --build --device LFE5U-85F --ecppack-compress
#  Write speed: 14.1MiB/s
#   Read speed: 24.2MiB/s

#python3 -m litex_boards.targets.radiona_ulx3s --cpu-type=vexriscv --cpu-variant=standard --build --device LFE5U-85F --ecppack-compress
#  Write speed: 15.5MiB/s
#   Read speed: 22.1MiB/s

#python3 -m litex_boards.targets.radiona_ulx3s --cpu-type=vexriscv --cpu-variant=full --build --device LFE5U-85F --ecppack-compress
#  Write speed: 15.5MiB/s
#   Read speed: 22.1MiB/s

#python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=vexriscv --cpu-variant=minimal --build --device LFE5U-85F
# Built ok. But no BIOS prompt.

#python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=vexriscv --cpu-variant=lite --build --device LFE5U-85F
# Built ok. But no BIOS prompt.

#python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=vexriscv --cpu-variant=standard --build --device LFE5U-85F
# Built ok. But no BIOS prompt.

#python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=picorv32 --cpu-variant=minimal --build --device LFE5U-85F
#  Write speed: 9.5MiB/s
#   Read speed: 13.5MiB/s

#python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=picorv32 --cpu-variant=standard --build --device LFE5U-85F
#  Write speed: 9.5MiB/s
#   Read speed: 13.5MiB/s

#python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=ibex --cpu-variant=standard --build --device LFE5U-85F
# Failed

#python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=neorv32 --cpu-variant=standard --build --device LFE5U-85F
#  Write speed: 6.4MiB/s
#   Read speed: 11.8MiB/s

#python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=serv --cpu-variant=standard --build --device LFE5U-85F
#  Write speed: 1.7MiB/s
#   Read speed: 1.8MiB/s

#python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=cva5 --cpu-variant=standard --build --device LFE5U-85F
# Failed

#python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=cva6 --cpu-variant=standard --build --device LFE5U-85F
# Failed

#python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=minerva --cpu-variant=standard --build --device LFE5U-85F
# Needs amaranth

#python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=cv32e41p --cpu-variant=standard --build --device LFE5U-85F
# Failed timing analysis

#python3 -m litex_boards.targets.radiona_ulx3s --no-compile-gateware --toolchain=diamond --cpu-type=vexriscv_smp --cpu-variant=standard --cpu-count=1 --build --device LFE5U-85F
# Built ok. But no BIOS prompt.
Dolu1990 commented 5 months ago

That is realy weird :/

I just ran LiteScope with the SOC bus again, and this time it worked.

Looking at that screen shot 0b00006f => j 0xb0

Which mean the CPU should have happily jumped to 0xb0 and at least try to fetch some. It starting all over to 0x00 again and again would mean it had a trap.

"Likely" a illegal instruction trap.

Could you check for : wire decodeExceptionPort_valid; wire [3:0] decodeExceptionPort_payload_code; wire [31:0] decodeExceptionPort_payload_badAddr; wire CsrPlugin_exceptionPendings_0; wire CsrPlugin_exceptionPendings_1; wire CsrPlugin_exceptionPendings_2; wire CsrPlugin_exceptionPendings_3; ?

Thanks ^^

dwalton65 commented 5 months ago

I was incorrect when I said the VexRiscv cpu-variants lite and full had the same result as minimal. They have the same result only as in I don't get the bios prompt, but the bus activity is very different.

This is a capture of the boot of a Litex SOC (VexRiscv CPU cpu-variant minimal) built using Diamond: vexriscv_min_diamond_boot

This is a capture of the boot of a Litex SOC (VexRiscv CPU cpu-variant lite) built using trellis: vexriscv_lite_trellis_boot

This is a capture of the boot of a Litex SOC (VexRiscv CPU cpu-variant lite) built using Diamond: vexriscv_lite_diamond_boot

After a short time, the Litex SOC (VexRiscv CPU cpu-variant lite) built using Diamond appears to lockup: vexriscv_lite_diamond_final

I have attached the LiteScope boot capture files for the cpu-variant lite when built using Diamond and trellis. vexriscv_lite_dump.zip

Dolu1990 commented 5 months ago

The VexRiscv CPU cpu-variant minimal trace (the first one) is quite interresting as we can see the decoding exception fireing again and again.

I don't know much about Diamond, do you ? Maybe the right way to go forward would by to try a netlist simulation ? Not sure how easy it is to setup with diamond.

dwalton65 commented 5 months ago

I don't know much about Diamond, do you ? Maybe the right way to go forward would by to try a netlist simulation ? Not sure how easy it is to setup with diamond.

I have only recently started looking at Diamond. I will look into simulation with Diamond.

Dolu1990 commented 3 days ago

@dwalton65 Hi,

I digged in more. So far, it seems like it is a diamond big !?

I used : python3 -m litex_boards.targets.radiona_ulx3s --device LFE5U-85F --cpu-type=vexiiriscv --cpu-variant=cached --update-repo=no --bus-standard axi-lite --toolchain=diamond --vexii-args="--with-boot-mem-init" --with-jtag-tap --sys-clk-freq=25000000 --build

Here is the "proof" i have so far from a litescope capture:

  always @(posedge litex_clk or posedge xxReset) begin
    if(xxReset) begin
      xxValid1 <= 1'b0;
    end else begin
      if(xxReady) begin
        xxValid1 <= xxValid0;
      end
    end 
  end 

In that wave, valid0 should have propagated to valid1 when ready is high the reset is low. But it doesn't happen. image

Here is the real verilog

  always @(posedge litex_clk or posedge cpuResetCtrl_reset) begin
    if(cpuResetCtrl_reset) begin
      toplevel_execute_ctrl1_up_LANE_SEL_lane0 <= 1'b0;
    end else begin
      if(toplevel_execute_ctrl0_down_isReady) begin
        toplevel_execute_ctrl1_up_LANE_SEL_lane0 <= toplevel_execute_ctrl0_down_LANE_SEL_lane0;
      end
    end 
  end 

// here are the path going to litescope
 cpuResetCtrl_reset_delay_1 <= cpuResetCtrl_reset;      
 xxReset <= cpuResetCtrl_reset_delay_1;      

   assign _zz_xxReady0 = toplevel_execute_ctrl0_down_isReady;
     ._zz_xxReady0                                                      (vexiis_0_logic_core__zz_xxReady0                                                          ), //o
    _zz_xxReady0 <= vexiis_0_logic_core__zz_xxReady0;
        xxReady0 <= _zz_xxReady0;

  assign _zz_executesDownValid = toplevel_execute_ctrl0_down_LANE_SEL_lane0;        
._zz_executesDownValid                                             (vexiis_0_logic_core__zz_executesDownValid  
  _zz_xxValid0 <= vexiis_0_logic_core__zz_executesDownValid;                                               ), //o
      xxValid0 <= _zz_xxValid0;

assign _zz_executesUpValid_1 = toplevel_execute_ctrl1_up_LANE_SEL_lane0;
    ._zz_executesUpValid_1                                             (vexiis_0_logic_core__zz_executesUpValid_1         
_zz_xxValid1 <= vexiis_0_logic_core__zz_executesUpValid_1;                                        ), //o
    xxValid1 <= _zz_xxValid1;

sooo, i dont know what to do XD

VexiiRiscvLitex_ebd826479cbf4045d068ccbff7c98217.txt

Dolu1990 commented 3 days ago

@dwalton65 Did you got questasim latice to work ? Got issues getting it to use the free license XD

dwalton65 commented 3 days ago

Sorry, I never got back to trying the simulator. I managed to get picorv32 to work, and this has sufficient performance for my current needs.

To get picorv32 to work, I had to add ( syn_preserve=1, syn_state_machine=0 ) on the line before the main picorv32 verilog module declaration "module picorv32 #(" After doing this, sometimes when the project was built, everything worked, sometimes not. It looked to me that the Litedram logic was getting messed up. Synplify was deciding that A14 was the same as RAS, and other strange optimisations. I added the same ( syn_preserve=1, syn_state_machine=0 ) on the line before the first module declaration in the verilog produced by LiteX, and everything is now working well. I have not had to add these directives to my own verilog code. Synplify converts my FSMs to one hot encoding, but so far seems to work ok.

On Thu, 7 Nov 2024 at 05:21, Dolu1990 @.***> wrote:

@dwalton65 https://github.com/dwalton65 Did you got questasim latice to work ? Got issues getting it to use the free license XD

— Reply to this email directly, view it on GitHub https://github.com/enjoy-digital/litex/issues/1965#issuecomment-2460588506, or unsubscribe https://github.com/notifications/unsubscribe-auth/AV64UA2QNMKK4HXFUHTM5W3Z7JT3FAVCNFSM6AAAAABIILKN46VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDINRQGU4DQNJQGY . You are receiving this because you were mentioned.Message ID: @.***>

Dolu1990 commented 2 days ago

Ahhhh cursed tools XD GG any way for figuring out those verilog attribute invocations ^^

Maybe a older version of diamond is bug free. I used 3.14 on linux, and you ?

trabucayre commented 2 days ago

Same issue with 3.12...

dwalton65 commented 2 days ago

I am running Lattice Diamond (64-bit) 3.13.0.56.2 on Windows. I tried the Linux version, but had problems with it crashing.

From the document "Synopsys Synplify Pro for Lattice Attribute Reference Manual" fpga_attribute_reference.pdf In the Windows default install, this document can be found here C:\lscc\diamond\3.13\synpbase\doc\fpga_attribute_reference.pdf

syn_preserve Prevents sequential optimizations such as constant propagation, inverter push-through, and FSM extraction.

syn_state_machine Enables/disables state-machine optimization on individual state registers in the design.

dwalton65 commented 2 days ago

It looks like I only need to add the line (* syn_preserve=1 *) to get picorv32 to work. Setting syn_state_machine=0 does not appear necessary. Definitely does not work without (* syn_preserve=1 *) on the line before the main picorv32 verilog module declaration "module picorv32 #("

I tried this with the vexriscv cpu, and it still did not work. Something else must be going wrong

Dolu1990 commented 2 days ago

Thanks, good to know that it also doesn't work on windows XD