Is there any way to use CFU Playground with Altera/Intel boards?
FelipeWcosta opened this issue · 31 comments
Usually CFU Playground is only supported for LiteX boards what exclude Altera/Intel boards, can I use other toolchains and frameworks to do this migration?
At the moment nobody has used the CFU Playground with Altera/Intel boards so it is likely to require a large amount of effort to make it work. It would not be impossible to do this but buying a Xilinx or Lattice boards is probably going to be a better ROI.
Thanks for the reply, this really seems like the right decision to make but we have only Altera/Intel boards available in the moment and looking at the documentation of CFU Playground I can see an option of setup that use Yosys and Nextprn with others tools case needed. Searching in the documentation of each of them, Nextprn is supported for Cyclone V (even in the testing phase) family from Altera and Yosys is too supported for some families from Altera like Cyclone IV and Cyclone V. Is this the way to use some of these boards? I think that is necessary an integration with CFU.
When I say "to use some of these boards" I want to say use Cyclone V.
Last I heard the Altera support in nextpnr was still not usable for real designs. The first step to understanding if this has changed would be to see if you can get a standard LiteX SoC running on these boards with these tools. Once that is working reliably you can explore if this will also work in the CFU Playground.
@mithro thanks, I will research more on the topic.
Usually CFU Playground is only supported for LiteX boards what exclude Altera/Intel boards, can I use other toolchains and frameworks to do this migration?
Correction: LiteX supports FPGAs like de0nano, de10nano and others.
@FelipeWcosta IF Litex supports the board you want to use, and supports the proprietary tool flow for that board, and you have those tools installed, and you're willing to use them, then there is an unknown but possibly small amount of additional work needed to get it to work in CFU Playground. For example, you can use Vivado with boards having Xilinx FPGAs, and it's also possible to use Radiant software when targeting boards with Lattice FPGAs.
In other words, CFU Playground doesn't need to have support for your specific proprietary tools as long as you have them installed and LiteX knows how to use them.
Hi @tcal-x thanks for your reply. Yes, the LiteX has support to the board that we have available de0nano. My professor came up the idea of using OpenFPGA together with Quartus and it worked to the case for syntesis of a riscv processor. Do you have any tips on what scripts I should pay attention to get this working? I saw some scripts about the supported boards write in Python.
Thank you.
Hi @FelipeWcosta first step is to just try it! Try running make TARGET=<litex name of board> bitstream
and see what happens.
Note, I see our continuous integration tests in Github actions do run a test with the terasic_de0nano
(edit: AND terasic_de10nano
) board, which means it worked at least in Renode (the CI tests don't try to build a bitstream). However, our tests seem to be broken currently -- test-projects (proj_template, common_soc, terasic_de0nano)
Hi @tcal-x, I just ran the command line make TARGET=terasic_de0nano bitstream
and everything went fine up to a point where it was impossible to find the Quartus toolchain. So the next step is to add Quartus to the PATH.
I will report everything here.
Hi, I bring news. I've installed the quartus II web edition 32-bit (Free) toolchain and a first moment it seems to compile normally but after it stopped. It has a bunch of warnings too.
Do you have any idea what's going on?
Hi @FelipeWcosta !
I have no experience with Altera tools. You may be able to find more information about the problem in the generated files under soc/build/<board>.<proj>/gateware/
.
It is probably useful to have an installation of just LiteX and try building the default target for your board.
If you're familiar with Python, it's recommended to do this in a virtual environment.
This is the quick start guide: https://github.com/enjoy-digital/litex
Then cd
to litex-boards/litex_boards/targets
and run something like ./terasic_de10nano.py --build
.
Then if you see the same error, open an issue on the LiteX repo :)
Hi @tcal-x, that makes sense. I will do some tests with LiteX and a more recent version of Quartus II (it was done with a 2013 version where many libs are obsolete). Thank you for your help!
I bring more updates @tcal-x. It was what I suspected, only the version of Quartus II (changed to version 22.1).
Running the command line make TARGET=terasic_de0nano bitstream
the compilation completed without any problems and when I look at the directory soc/build/terasic_de0nano.proj_template/gateware
I can see some files that normally generated for the Quartus II and the verilog file terasic_de0nano.v
. How it is shown in the printscreen below:
So, do you have any suggestions on how I can proceed?
Thanks for all the support here.
The terasic_de0nano.v
file is generated by LiteX and would be one of the inputs to Quartus. The other inputs would be the VexRiscv CPU and the user's CFU, although they would be directly referenced and not copied to this directory. I'm not sure which of the files would be the "bitstream" that is put onto the Intel FPGA, but you don't really need to know if everything works.
If you didn't see any errors, the next step would be make TARGET=terasic_de0nano prog
, and see what happens. If it is successful at programming the FPGA board, you will probably see the classic LiteX LED cycling pattern.
Hello @tcal-x, nice to see you again. So I will try to do that as soon as possible.
And in case the prog
step works, the next step will be:
make TARGET=terasic_de0nano load
which will:
- build the software (RISCV binary)
- connect to the board,
- show the LiteX banner from the BIOS running on the SoC,
- upload your binary,
- and put you in a terminal talking to the binary running on the FPGA SoC.
@FelipeWcosta have you been able to program the board by other means? If you have never programmed the board from this particular computer, you may have an UDEV permissions issue --- something you just need to address once.
Usually googling "UDEV <boardname>" turns up something. For example,
https://www.google.com/search?q=udev+terasic_de0nano&oq=udev+terasic_de0nano
has the link
https://www.local-guru.net/blog/2011/9/25/Using-the-terasic-DE0-Nano-on-ubuntu
Hi @tcal-x, I not did this. In the first moment I thought that could be any problem with USB Blaster installation. Thank you for the advise.
Hi @tcal-x, the tutorial that you showed was util but I had to followed the tutorial on Intel site to can load a design on the DE0Nano board.
So, I mentioned all the files that was generated by Quartus before and I find out an erro with the file terasic_de0nano.bit
(I am not sure but I think what is it about the bitstream file). If it is the bitstream file (Quartus use the .sof
file to load a design on the board) can we change to read .sof
file on the scripts or exists other ways to generate the .bit
file?
Thank you!
Greetings!
So, I've had searching about the problem trying to figure out any way to genarate the .bit
file because I thought that will be the best way to slove this problem the other way will be to create an specifc workflow for the board but we have some erros with the general workflow and it going to generate others erros with the others boards (probably). As it is known we have two differents file formats a .sof
file for programming Altera's boards and .bit
file for Xilinx's boards maybe others boards too.
I am assessing the possibility of conversion of the .sof
into .bit
file but I couldn't find an relationship between this files formats yet.
If someone has some information about this and wants share with us, I thank!
Hello everyone!
I bring more news. So, I was trying to prog the board using CFU directly instead to convert the files manually, to do this I just changed the file extension to .sof
(in the general.py
file) in the script and the erros that appearing in the other scripts were commented to avoid them because we are not using the othes boards. I am not sure if the board was really programmed because a could not see the LED's pattern (I can see the LED's pattern when I use Quartus to prog).
The image above is the command terminal and how we can see probably there is any error with the communication between the host and the board, some advice for this case?
Thaks!
Hi @FelipeWcosta , if the LEDs are not flashing, that's probably a bad sign.
In some cases it may look like there are two serial ports and you get the message above (the script is looking for exactly one that matches /dev/ttyUSB* or /dev/ttyACM*), but more likely in this case the SoC is not working correctly so there's no serial port showing up. Can you do an ls /dev/ttyUSB* /dev/ttyACM*
?
When you think it is working and there appears to be a serial port, then the other thing you can do is try to connect to the SoC BIOS without loading the CFU Playground software; you'd just be talking to the LiteX BIOS, but that itself is very useful.
Hi @tcal-x, when I do ls /dev/ttyUSB* /dev/ttyACM*
do not exist these particular paths in the /dev
folder but I can see many others tty
paths as it shown in the printscreen.
I installed the LiteX
and navigate to \litex-boards\litex_boards\targets
path, then I run the specific command line:
.\terasic_de0nano.py --uart-jtag-uart --buil --load
And then I could see the LED's pattern. I also could realize a difference to load the bitstream file:
def main():
from litex.build.parser import LiteXArgumentParser
parser = LiteXArgumentParser(platform=terasic_de0nano.Platform, description="LiteX SoC on DE0-Nano.")
parser.add_target_argument("--sys-clk-freq", default=50e6, type=float, help="System clock frequency.")
parser.add_target_argument("--sdram-rate", default="1:1", help="SDRAM Rate (1:1 Full Rate or 1:2 Half Rate).")
args = parser.parse_args()
soc = BaseSoC(
sys_clk_freq = args.sys_clk_freq,
sdram_rate = args.sdram_rate,
**parser.soc_argdict
)
builder = Builder(soc, **parser.builder_argdict)
if args.build:
builder.build(**parser.toolchain_argdict)
if args.load:
prog = soc.platform.create_programmer()
prog.load_bitstream(builder.get_bitstream_filename(mode="sram"))
Can I use the --uart
argument directly in CFU or is not possible?
Hi @FelipeWcosta , yes, there is a way to pass any LiteX argument to the LiteX layer. But I think we have a few things to figure out before we're at that point.
First, we should get to the point of loading a bitstream from CFU Playground to the board and see the cycling LEDs.
- Did the LiteX / litex-boards/target build have cycling LEDs when you didn't use the
--uart-jtag-uart
option? - Do you know what utility LiteX uses to load the bitstream on the board?
If you think the uart option is necessary to get the blinking LEDs, then try adding this to your CFU Playground make
line: EXTRA_LITEX_ARGS="--uart-xxx"
, so you'll end up with something like this:
make TARGET=terasic_de0nano EXTRA_LITEX_ARGS="--uart-xxx" prog
And I see your issue on the litex repo about connecting to the system once it's running --- that's the next step! The people there should be able to help.
Hi @tcal-x,
Answaering the first question: Yes, I could see the flashing LED's pattern when I use only the argument ./terasic_de0nano.py --build
. The command line which I've used before is in the terasic_de0nano.py
script.
Now, the second question, looking at litex-boards/litex_boards/targets/terasic_de0nano.py
file I can see some diferences between the functions used to load the bitstream in general.py
script like this:
if args.load:
prog = soc.platform.create_programmer()
prog.load_bitstream(builder.get_bitstream_filename(mode="sram"))
In the builder
function too and some other things.
Apparently, --uart-jtag-uart
is not a problem it is worked without it, I going to spend more time trying to fix the issue in LiteX
repo. Was I thinking if litex-boards/litex_boards/targets/terasic_de0nano.py
could be a base to edit the general.py
file? What do you think?
The command line make TARGET=terasic_de0nano EXTRA_LITEX_ARGS="--uart-jtag-uart" prog
do not have effect.
Here is the entire code of litex-boards/litex_boards/targets/terasic_de0nano.py
:
#!/usr/bin/env python3
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2015-2020 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
# Build/Use:
# ./terasic_de0nano.py --uart-name=jtag_uart --build --load
# litex_term --jtag-config ../prog/openocd_max10_blaster.cfg jtag
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from litex.gen import *
from litex.build.io import DDROutput
from litex_boards.platforms import terasic_de0nano
from litex.soc.cores.clock import CycloneIVPLL
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from litex.soc.cores.led import LedChaser
from litedram.modules import IS42S16160
from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY
# CRG ----------------------------------------------------------------------------------------------
class _CRG(LiteXModule):
def __init__(self, platform, sys_clk_freq, sdram_rate="1:1"):
self.rst = Signal()
self.cd_sys = ClockDomain()
if sdram_rate == "1:2":
self.cd_sys2x = ClockDomain()
self.cd_sys2x_ps = ClockDomain()
else:
self.cd_sys_ps = ClockDomain()
# # #
# Clk / Rst
clk50 = platform.request("clk50")
# PLL
self.pll = pll = CycloneIVPLL(speedgrade="-6")
self.comb += pll.reset.eq(self.rst)
pll.register_clkin(clk50, 50e6)
pll.create_clkout(self.cd_sys, sys_clk_freq)
if sdram_rate == "1:2":
pll.create_clkout(self.cd_sys2x, 2*sys_clk_freq)
pll.create_clkout(self.cd_sys2x_ps, 2*sys_clk_freq, phase=180) # Idealy 90° but needs to be increased.
else:
pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=90)
# SDRAM clock
sdram_clk = ClockSignal("sys2x_ps" if sdram_rate == "1:2" else "sys_ps")
self.specials += DDROutput(1, 0, platform.request("sdram_clock"), sdram_clk)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, sys_clk_freq=50e6, sdram_rate="1:1", with_led_chaser=True, **kwargs):
platform = terasic_de0nano.Platform()
# CRG --------------------------------------------------------------------------------------
self.crg = _CRG(platform, sys_clk_freq, sdram_rate=sdram_rate)
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on DE0-Nano", **kwargs)
# SDR SDRAM --------------------------------------------------------------------------------
if not self.integrated_main_ram_size:
sdrphy_cls = HalfRateGENSDRPHY if sdram_rate == "1:2" else GENSDRPHY
self.sdrphy = sdrphy_cls(platform.request("sdram"), sys_clk_freq)
self.add_sdram("sdram",
phy = self.sdrphy,
module = IS42S16160(sys_clk_freq, sdram_rate),
l2_cache_size = kwargs.get("l2_size", 8192)
)
# Leds -------------------------------------------------------------------------------------
if with_led_chaser:
self.leds = LedChaser(
pads = platform.request_all("user_led"),
sys_clk_freq = sys_clk_freq)
# Build --------------------------------------------------------------------------------------------
def main():
from litex.build.parser import LiteXArgumentParser
parser = LiteXArgumentParser(platform=terasic_de0nano.Platform, description="LiteX SoC on DE0-Nano.")
parser.add_target_argument("--sys-clk-freq", default=50e6, type=float, help="System clock frequency.")
parser.add_target_argument("--sdram-rate", default="1:1", help="SDRAM Rate (1:1 Full Rate or 1:2 Half Rate).")
args = parser.parse_args()
soc = BaseSoC(
sys_clk_freq = args.sys_clk_freq,
sdram_rate = args.sdram_rate,
**parser.soc_argdict
)
builder = Builder(soc, **parser.builder_argdict)
if args.build:
builder.build(**parser.toolchain_argdict)
if args.load:
prog = soc.platform.create_programmer()
prog.load_bitstream(builder.get_bitstream_filename(mode="sram"))
if __name__ == "__main__":
main()
Thanks for all the help so far!
Greetings!
Only bringing some informations about the issue on LiteX repo, I made some tests and finally I've could load the bitstream on the board and access the BIOS, I've could do tests using the command line leds <value>
through JTAG but after of some time comes this erro on BIOS terminal:
Error: ftdi_write_data: usb bulk write failed
Apparently, ftdi
is part (it's a drive) of OpenOCD then I updated using the linux-litex-on-vexriscv
repo without sucess because this new erro come out:
Error: No lowlevel driver available
But ftdi
is specified on the script (the error could be the conflict between the different paths of OpenOCD since that Quartus use it too). So, we have a drive problem to a estable communication between the host and board through the JTAG.