使用LiteX快速创建FPGA SoC工程(7)一-LiteX社区-FPGA CPLD-ChipDebug

使用LiteX快速创建FPGA SoC工程(7)一

本章介绍烧写上一章编译生成的bit文件,并运行linux系统

一、烧写FPGA

LiteX默认的UART串口速度为115200,可以先通过PC上的串口软件打开该串口,方便观察烧写后的启动打印字符。

前面的文章说过,在PL端我使用了两个用户可扩展的IO引脚作为串口,并且在Platform文件中的进行了定义。以下为该引脚的实物连接图:

图片[1]-使用LiteX快速创建FPGA SoC工程(7)一-LiteX社区-FPGA CPLD-ChipDebug

图1 UART串口连接

我是通过执行以下命令来烧写FPGA:

./alinx_ax7z100_target.py --load

烧写成功后,可以在串口工具中看到如下图的打印,由于未加载系统镜像,因此会启动失败,如下图所示:

图片[2]-使用LiteX快速创建FPGA SoC工程(7)一-LiteX社区-FPGA CPLD-ChipDebug

图2 启动打印

此外,我们在SoC中还使用了一个流水灯,在FPGA中可以看到该流水灯的运行情况,如下图所示:

图片[3]-使用LiteX快速创建FPGA SoC工程(7)一-LiteX社区-FPGA CPLD-ChipDebug

图3 流水灯

二、使用操作系统启动

2.1 编译新的bit文件

由于之前编译的cpu不支持linux系统,因此需要重新编译,本次编译启用了PL端的DDR,Target文件内容如下(platform文件不变):

#!/usr/bin/env python3

#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2022 Yonggang Liu <ggang.liu@gmail.com>,
# SPDX-License-Identifier: BSD-2-Clause

from migen import *

from litex_boards.platforms import alinx_ax7z100
from litex.build.xilinx.vivado import vivado_build_args, vivado_build_argdict

from litex.soc.interconnect import axi
from litex.soc.interconnect import wishbone

from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from litex.soc.cores.led import LedChaser

from litex.gen import LiteXModule

from litex.soc.integration.soc import SoCRegion

from litex.soc.cores import cpu
from litedram.modules import MT8JTF12864, MT41J256M16
from litedram.phy import s7ddrphy
from liteeth.phy import LiteEthPHY
from liteeth.phy.s7rgmii import LiteEthPHYRGMII
from liteeth.phy.a7_gtp import QPLLSettings, QPLL
from liteeth.phy.a7_1000basex import A7_1000BASEX

# CRG ----------------------------------------------------------------------------------------------

class _CRG(LiteXModule):
    def __init__(self, platform, sys_clk_freq):
        self.rst       = Signal()
        self.cd_sys    = ClockDomain()
        self.cd_sys4x  = ClockDomain()
        self.cd_idelay = ClockDomain()

        # # #

        self.pll = pll = S7MMCM(speedgrade=-2)
        self.comb += pll.reset.eq(~platform.request("cpu_reset") | self.rst)#注意取反
        pll.register_clkin(platform.request("clk200"), 200e6)
        pll.create_clkout(self.cd_sys,    sys_clk_freq)
        pll.create_clkout(self.cd_sys4x,  4*sys_clk_freq)
        pll.create_clkout(self.cd_idelay, 200e6)
        platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin) # Ignore sys_clk to pll.clkin path created by SoC's rst.

        self.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
        
# BaseSoC ------------------------------------------------------------------------------------------

class BaseSoC(SoCCore):
    #kwargs指代了继承自SoCCore类的__init__方法的除了sys_clk_freq 和 with_led_chaser之外的所有所有参数,是一个字典
    def __init__(self, sys_clk_freq=int(100e6), 
        with_ethernet = False,
        eth_phy = "rgmii",
        with_led_chaser = True, **kwargs):
        platform = alinx_ax7z100.Platform()

        # CRG --------------------------------------------------------------------------------------
        # 创建一个子模块,即PLL
        self.submodules.crg = _CRG(platform, sys_clk_freq)#platform的clk200会连接到pll,pll会生成sys_clk_freq的输出时钟

        # SoCCore ----------------------------------------------------------------------------------
        #if kwargs["uart_name"] == "serial": kwargs["uart_name"] = "usb_uart" # Use USB-UART Pmod on JB.
        kwargs["uart_name"] = "serial"#强制把SoCCore的uar_name成员变量设置为serial,以和7100的platform文件中的定义对应
        SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Alinx AX7Z100", **kwargs)
        
        # DDR3 SDRAM -------------------------------------------------------------------------------
        if not self.integrated_main_ram_size:#该选项默认是None
            self.ddrphy = s7ddrphy.K7DDRPHY(platform.request("ddram"),
                memtype      = "DDR3",
                nphases      = 4,
                sys_clk_freq = sys_clk_freq)
            self.add_sdram("sdram",
                phy           = self.ddrphy,
                module        = MT41J256M16(sys_clk_freq, "1:4"),
                # module        = MT41J256M16(sys_clk_freq, "1:4","800"),
                l2_cache_size = kwargs.get("l2_size", 8192)
            )
        # Ethernet ---------------------------------------------------------------------------------
        if with_ethernet:
            # RGMII Ethernet PHY -------------------------------------------------------------------
            if eth_phy == "rgmii":
                # phy
                self.ethphy = LiteEthPHYRGMII(
                    clock_pads = self.platform.request("eth_clocks"),
                    pads       = self.platform.request("eth"))
            self.add_ethernet(phy=self.ethphy)
        # Leds -------------------------------------------------------------------------------------
        if with_led_chaser:
            self.submodules.leds = LedChaser(
                pads         = platform.request_all("user_led"),
                sys_clk_freq = sys_clk_freq)

# Build --------------------------------------------------------------------------------------------

def main():
    from litex.soc.integration.soc import LiteXSoCArgumentParser
    parser = LiteXSoCArgumentParser(description="LiteX SoC on zynq xc7z100")#打印帮助信息时,会显示该字符串
    target_group = parser.add_argument_group(title="Target options")
    target_group.add_argument("--build",        action="store_true", help="Build design")#如果使用了--build选项,则args.build的值会为True
    target_group.add_argument("--load",         action="store_true", help="Load bitstream")#同上
    #target_group.add_argument("--with-ethernet",  action="store_true",        help="Enable Ethernet support.")
    #target_group.add_argument("--eth-phy",        default="rgmii",            help="Select Ethernet PHY (rgmii or 1000basex).")
    target_group.add_argument("--sys-clk-freq", default=100e6,       help="System clock frequency (default: 200MHz)")#指定时钟频率
    builder_args(parser)#想parser中添加 BIOS options 和 Builder options 两组选项
    soc_core_args(parser)#来自SocCore类所在文件的辅助函数,添加 SoC options 一组选项
    vivado_build_args(parser)#添加 Vivado toolchain options 一组选项
    args = parser.parse_args()

    soc = BaseSoC(#生成一个soc对象
        sys_clk_freq = int(float(args.sys_clk_freq)),
        #这里的args.sys_clk_freq实际上就是上面的--sys-clk-freq指定的值,最终决定了pll的输出频率
        #with_ethernet = args.with_ethernet,
        #eth_phy = args.eth_phy,
        **soc_core_argdict(args)#传递SOC相关参数的字典给BaseSoc
    )

    builder = Builder(soc, **builder_argdict(args))
    
    if args.build:#如果使用了--build选项,则会进行编译
        builder.build(**vivado_build_argdict(args))

    if args.load:#如果使用了--load选项,则会下载程序
        prog = soc.platform.create_programmer()
        prog.load_bitstream(builder.get_bitstream_filename(mode="sram"), device=1)

if __name__ == "__main__":
    main()

可以看到启用了DDR(此处还添加了以太网,但是命令行参数并没有启用,后续再进行启用)。然后执行以下命令进行编译:

./alinx_ax7z100_target_linux.py --cpu-type vexriscv_smp --bus-standard axi --build

此处我们将CPU指定为vexriscv_smp,以支持linux系统,同时将系统总线从默认的wishbone指定为axi。等待bit文件编译生成。

经过上板测试,该方法编译生成的CPU类型为VexRiscv SMP-STANDARD,而不是图8中的VexRiscv SMP-LINUX,无法启动Linux,因此先记录在此。使用2.2节的方法生成的bit文件可以启动Linux

2.1 Linux系统镜像

目前我使用了别人预先制作好的image,下载链接为:https://github.com/litex-hub/linux-on-litex-vexriscv/issues/164 。如下图:

图片[4]-使用LiteX快速创建FPGA SoC工程(7)一-LiteX社区-FPGA CPLD-ChipDebug

图4 下载images

2.2 针对Linux系统编译新的bit文件

在此之前,我们需要编译能支持linux系统的bit文件。

1、下载仓库

git clone https://github.com/litex-hub/linux-on-litex-vexriscv.git
git clone http://github.com/buildroot/buildroot

linux-on-litex-vexriscv:用于生成支持linux系统的bit文件,本质上就是调用了LiteX的东西;

  • buildroot:用于生成自定义的image;由于目前使用的是prebuild image,所以暂时永不上;

2、添加板卡支持:

在linux-on-litex-vecriscv仓库的根目录中,有一个make.py文件,向其中添加自己的板卡支持类,如下图:

图片[5]-使用LiteX快速创建FPGA SoC工程(7)一-LiteX社区-FPGA CPLD-ChipDebug

图片[6]-使用LiteX快速创建FPGA SoC工程(7)一-LiteX社区-FPGA CPLD-ChipDebug

图5 添加板卡支持到make.py

添加完成之后,在linux-on-litex-vecriscv仓库的根目录下,使用如下命令编译生成bit文件,该bit文件将在仓库根目录的build文件夹中,可以使用find命令查找:

./make.py --board=alinx7100 --toolchain=vivado --build

 

2.3 启动Linux

首先切换到下载的images所在的目录,执行以下命令,如图6:

litex_term --images=riscv_linux_prebuild_image/boot.json /dev/ttyUSB0

该终端可能会卡住,也可能会显示”litex>”:

图片[7]-使用LiteX快速创建FPGA SoC工程(7)一-LiteX社区-FPGA CPLD-ChipDebug

图6 下载image命令

无所谓,我们继续,使用vivado烧写bit文件:bit文件加载完成之后,在litex_term的窗口可以发现系统正在启动,并且通过串口加载images,如下图,这一过程通常需要几十分钟图片[8]-使用LiteX快速创建FPGA SoC工程(7)一-LiteX社区-FPGA CPLD-ChipDebug

图7 串口加载images

注意,确保启动时打印的CPU类型为下图所示,CPU一项的类型为:VexRiscv SMP-LINUX,否则使用不支持Linux系统的CPU将无法启动,:

图片[9]-使用LiteX快速创建FPGA SoC工程(7)一-LiteX社区-FPGA CPLD-ChipDebug

图8 CPU类型

启动完成之后,输入默认密码root即可登陆,如下图:

图片[10]-使用LiteX快速创建FPGA SoC工程(7)一-LiteX社区-FPGA CPLD-ChipDebug

图9 登陆成功

请登录后发表评论

    没有回复内容