Xilinx hijinx,第 2 部分: 构建和加载比特流和 PowerPC 代码

实践 Virtex4 平台的完整 VHDL 和 C 项目

本文将探索一个完整 Virtex4 项目的硬件和软件方面。在 Xilinx hijinx 系列 的第二部分(也是最后一部分)中,您将向项目中添加或从中删除设备核心、连接项目组件、构建比特流、把它与 C 代码集成,并把整个结果下载到 FPGA。

Lewin Edwards (sysadm@zws.com), 设计工程师, Freelance

Lewin A.R.W. Edwards 现任职于一家“财富 50 强”公司,是该公司的一名无线安全/防火安全设备设计工程师。在此之前,他用了五年时间在 Digi-Frame Inc 开发 x86、ARM 和基于 PA-RISC 的联网多媒体装置。他在加密和安全软件领域有着广泛的经验,并且是两本有关嵌入式系统开发的书的作者。您可通过 sysadm@zws.com 与他联系。



2007 年 2 月 22 日

前一篇文章 对 ML403 评估板和 FPGA 作了总体介绍,让读者略微了解了 Platform Studio 用户界面。在此结束部分中,将采取行动把实际的比特流和代码植入板内。本文将研究使用配送的 ML403 能实现什么和不能实现什么。

但是,在跑之前总需要先学会走,而第一步是理解如何构建和运行代码。完全从头开始配置一个系统是个相当复杂的过程。不管您相信与否,这实际上是个特性,而不是个 bug。在“硬件”级(或 HDL 代码)上,需要能够定义 FPGA 要包含多少个外围设备、它们要连接到哪个处理器(请记住在 Virtex4 内最多可以实例化两个 PowerPC®!)、它们要连接到哪个内部总线,以及它们在处理器地址空间中的位置。

因为从头开始构建一个系统相当复杂,所以我不打算在本文中对它做出解释。我只是修改了 EDK 附带的一个示例,演示初始的系统设置所必需的内容。如果想学习如何从头开始构建 FPGA 系统,我建议从一个非常简单的功能示例开始;例如,实现一个“AND”门或者同样微小的功能,并把它的信号映射到 I/O pin,然后从这一点上开始理解。您无需为此使用任何硬件或昂贵的软件,只需要下载 ISE 的免费 WebPACK 版本和 Modelsim 的免费 Xilinx 版本,并在模拟中试验即可。

但是,对于本文的小实践,先从制作 EDK CD-ROM 示例目录的一个本地可写副本开始。一个警告:EDK —— 或者更准确点说,底层 GNU 工具链 —— 不处理文件名中的空格。这意味着如果正在 Microsoft® Windows® 上运行,则不能把设计文件放在桌面上(因为默认情况下,桌面目录是 C:\Documents and Settings\<user name>\Desktop);同样的注意也适用于 My Documents。为了避免这个问题,请把整个 reference_systems 目录从 EDK CD-ROM 复制到 C:\。顺便说一下,空白问题不是 GNU 工具链的固有限制;它更多的是 EDK GUI 包装器的功能,是因为包装器在向包含 cygwin 的外部工具传递文件名时,不能识别并正确地转换文件名中包含的空白。

现在,启动 Xilinx Project Studio,在第一个对话框中,选择 Open A Recent Project,然后单击 OK。浏览到 c:\reference_systems\EDK_Projects\ml403_emb_ref_ppc 目录并打开其中的 system.xmp 文件。加载文件时,将连接到 ML403 板。我建议至少通过 nullmodem 将串行端口连接到计算机或其他终端(把终端配置为 9600、8 位数据位、无奇偶校验、一个终止位),把 VGA 端口连接到空闲的监视器。启动该板后,将看到欢迎菜单,不要做出任何选择 —— 加载那里的示例会改变 I/O 映射,导致后面的步骤无法进行。

项目载入 Project Studio 之后,在左侧面板中会看到硬件组件的树状浏览器,在右侧面板会看到设计流程的图形演示。(演示实际是个便利的图像映射,可以单击图片上的热区,查看相关主题的帮助文件。)

默认系统配置包括一组外围设备:一个中断控制器、一个 16550 兼容的 UART、一个双 PS/2 设备控制器(处理鼠标和键盘端口),等等。由于这或多或少是个配置完整的系统,所以我用它作为这个实验的基础。理想情况下,此时为构建和下载完整硬件描述所需的全部操作是从 Tools 菜单中选择 Download

不幸的是,执行此操作时,XPS 会检查依赖项,并试图在下载比特流之前构建它。在这个过程中,会看到几条与下面类似的消息,而且构建会失败,出现“MDT -- platgen failed with errors!”错误:

ERROR:MDT - opb_uart16550 (opb_uart16550_0) -
C:\reference_systems\ml403_emb_ref_ppc\system.mhs:324 - invalid license or no license found!
INFO:coreutil - Valid license for feature opb_iic_v1 not found. You may use the customization GUI for this core but you will not be able to generate any implementation or simulation files. Contact Xilinx to obtain a full license for this LogiCORE. For more information please refer to www.xilinx.com/ipcenter/ipevaluation/ FLEXlm Error: No such feature exists (-5,21)

造成此困难的原因是 EDK 附带的许多内核是商品化的;它们要花钱。在图 1 的左侧可以看到三个受影响的核心 —— 它们在 System 树中以 $ 图标显示。

图 1
图 1

请注意,可以从 Xilinx 得到多数商业核心的评估版本,但是它们的功能非常有限。还可以从 opencores 这类来源寻求免费的第三方核心(请参阅 参考资料),但要把这些核心连接到 Xilinx 总线 IP ,肯定需要做些适配工作。

作为构建问题的直接工作区,可以删除三个恼人的核心:右击每个内核,并选择 Delete。这样就能成功构建系统,但是用起来相当麻烦。可以没有以太网和 IIC,但是 UART 对于调试来说是必需的。所以需要修正这个问题。

幸运的是,Xilinx 提供了免费的“uartlite”核心,可轻松地将其添加到系统中。只要在 System 面板中右击,并选择 Add/Edit Cores...,就会看到图 2 所示的对话框:

图 2
图 2

(提示一下,前缀“plb”表示 Processor Local Bus,“opb”表示 On-Chip Peripheral Bus) 。

要添加新外部设备,请在右侧的列表中向下滚动,找到 opb_uartlite,选中它并单击 Add。这就导入了外部设备,但此阶段它只是 FPGA 中一个没有实质的硬件(EDK 不允许像这样进行构建)。需要把外围设备连接到总线,以便处理器能与它对话,并为它分派一点 PowerPC 的地址空间,以便处理器知道在哪里能找到它;还需要告诉路由器如何将其信号与其他外围设备或物理芯片 pin 相连接。所有这些功能都在 Bus Connections 选项卡上进行指定,如图 3 所示:

图 3
图 3

从左到右的三个空白列分别表示 On-chip Peripheral Bus、Processor Local Bus 和 Device Control Register bus。请注意:在 Xilinx 的设计中还可能有其他几个总线;可以从此对话框右上角的列表中添加其他总线。

每个外围设备实例由表中的一行表示;外围设备实例名称右侧的三个单元格表示实例与相应总线的关系(主、从或主+从)。

如果向下滚动到刚刚添加的 opb_uartlite_0 sopb 条目,会看到它没有连接(所有三个总线方框都是空的)。用这个设备能实现的唯一连接就是在 OPB 上的从连接;请在最左侧的空总线框中单击,建立此连接(框内会出现一个小写的“s”)。

现在需要定义 UART 在 PowerPC 地址空间中的位置;在 Addresses 选项卡上执行此操作,如图 4 所示:

图 4
图 4

滚动到 UART 行,在 Base Address 字段中输入 0xA0000000(这是刚删除的 16550 UART 的默认地址,因此可知这是存储小 UART 的安全位置)。在 Size 下拉列表中,选择最小值 (256) —— 小 UART 实际上只有 4 个 32 位寄存器,因此只需要 16 字节的地址空间,所以 256 个字节绰绰有余。

顺便说一下,我没有使用什么神奇的方法预测第二个数字。如果单击图 4 中对话框的 Parameters 选项卡,从右上角的下拉列表中选择需要的外围设备(请注意:此列表只显示设计中已实例化的外围设备。),并单击 Open PDF Doc,就能读取正在讨论的 IP 核心的完整数据表。可以在 C:\EDK\hw\XilinxProcessorIPLib\pcores(假设把 EDK 安装在默认目标目录)找到这些 PDF 文档。

倒数第二步,需要把 UART 的端口 —— 在本例中,是传输和接收这两个数据行 —— 映射到外部端口和 FPGA 中的连接。这是在 Ports 选项卡中进行的,如图 5 所示:

图 5
图 5

要建立所需的映射,请在右侧的列表中向下滚动,找到 opb_uartlite_0 并单击 RX,然后单击 Add。在左侧的列表中将出现针对这个信号的新行。要做的就是从 Net Name 列的下拉列表中选择合适的连接;在本例中,选择 uart_RX。对 TX 行执行同样的操作,当然这次是映射到“uart_TX”网络。

外部设备的 Interrupt 行需要映射到信号“uart_intr”。这在下拉列表中不会显示(内部连接表中的下拉列表中只显示外部连接);将 Interrupt 添加到内部连接列表后,需要单击该行,然后单击 Connect 并手动输入 uart_intr。(此信号通过其他 interrupt 多路传输;查看 Connect 按钮中的下拉列表,可以看到以“uart_intr & ps2_1_intr & ... .”开始的行。)

由于删除了一些外围设备,所以还需要删除其输出端口映射到的外部端口连接;否则就会得到信号没有驱动程序的错误。本例中要删除的端口的具体列表是:phy_rst_n、phy_tx_data、phy_tx_en、phy_tx_er、iic_scl_int_O、iic_scl_int_T、iic_sda_int_O、iic_sda_int_T、iic_intr、ethernet_intr。删除这些端口最简单的方法是编辑 system.mhs 文件;查看 System 树,在 Project Files 下面,双击 MHS 文件打开它。除最后两个端口外,其他全部都可以通过注释掉相应的 PORT 行来删除;要删除 interrupt,请找到以下行:

PORT Intr = uart_intr & ps2_1_intr & ps2_2_intr & iic_intr & ac97_play_intr & ac97_record_intr & sysace_intr & phy_mii_int & usb_hpi_int & ethernet_intr

并使用以下行替换该行:

PORT Intr = uart_intr & ps2_1_intr & ps2_2_intr & ac97_play_intr & ac97_record_intr & sysace_intr & usb_hpi_int

现在也可以体验一下 Parameters 选项卡;该选项卡允许您调整核心的每个实例的配置。对于 UART 来说,除了波特率和帧细节外没有太多属性要配置。

现在已经装配好了一个完整的设计;如果愿意,现在就可以构建和下载比特流。警告:这会花很长时间,而不构建任何比特流也能执行本文下一部分的步骤。如果坚持要试试,请注意构建过程会给出一个解析 synthesis.sh 的错误 —— 出现这个问题是因为与 cygwin 当前版本冲突。遇到这个错误时,请打开命令提示符,并运行以下命令:

cd C:\reference_systems\EDK_Projects\ml403_emb_ref_ppc\synthesis
xst -ifn system_xst.scr

然后重试构建操作,就会成功完成了。(这个问题在 Xilinx 的 Web 站点中没有说明,所以它可能是我使用的 EDK/ISE 和 Cygwin 特殊版本而特有的问题 —— 但是,我在两台不同的计算机上都遇到了这个问题,所以请当心!)

如何把软件放进这个结构呢?通常的方法是在 FPGA 比特流中的一段块 RAM(BRAM)内包含一个小程序。该小程序是一个 bootloader,可以初始化附带的内存控制器,可能从某些外部源载入主程序,然后跳入主程序。为简洁起见,我们不会实际地设计一个执行这些功能的程序,相反,我们要研究如何构建和载入此项目内的一个样例程序。

在主 XPS 窗口中,单击 Applications 选项卡,将看到图 6 所示的树:

图 6
图 6

请注意顶部的项目(ppc405_0_bootloop)。这是什么也不做的哑程序,在开发针对自己设计的软件时使用。该理念是在 BRAM 中包含此“halt and wait”代码,这样就能配置 FPGA,然后附上一个调试器并下载想要运行的代码。当软件工程师开发出可用的 bootloader,可以把它放入 XPS 项目,并选择它作为载入 BRAM 的默认内容。然后可以构建烧制到平台闪存的最终可发行的比特流,或者构建设计用来配置 FPGA 的任何方法。在开电启动的时候,FPGA 配置为内置的 bootstrap,CPU 核心开电重置过程会启动引导过程。

我们想试验一个简单良好的示例,所以在 button_led_test 上右击并选择 Make project active。再次右击它,选择 Build Project。会看到三个错误:前两个错误提示 stdin 和 stdout 最初被定向到 16550 UART,而它并不存在。回到 System 面板,编辑 system.mss 文件,这个文件定义了设计的操作系统环境。请找到这一段:

清单 1
BEGIN OS
  PARAMETER OS_NAME = standalone
  PARAMETER OS_VER = 1.00.a
  PARAMETER PROC_INSTANCE = ppc405_0
  PARAMETER stdin = opb_uart16550_0
  PARAMETER stdout = opb_uart16550_0
END

把 stdin 和 stdout 所在的行改成引用 opb_uartlite_0。还请找到下面这段,把它们全注释掉,因为在设计中没有以太网支持:

清单 2
BEGIN LIBRARY
  PARAMETER LIBRARY_NAME = xilnet
  PARAMETER LIBRARY_VER = 2.00.a
  PARAMETER emac_instname = opb_ethernet_0
  PARAMETER no_of_tcp_conns = 5
  PARAMETER no_of_udp_conns = 5
END

最后,希望装入小 UART 的驱动程序。为此,只需将下面这段添加到 system.mss 即可:

清单 3
BEGIN LIBRARY
  PARAMETER LIBRARY_NAME = uartlite
  PARAMETER LIBRARY_VER = 1.00.b
  PARAMETER HW_INSTANCE = opb_uartlite_0
END

可以在 C:\EDK\sw\XilinxProcessorIPLib\drivers 找到所有驱动程序和它们的 API 文档。不幸的是,uartlite 驱动程序有个问题:目录指定为 1.00b 版,但其中的文件却指定为 2.1.0 版。解决这个问题的最简单方法就是进入 1.00b 的数据目录,为其中的 .mpd 和 .pao 文件制作副本。把这些副本的文件名改成 opb_uartlite_v1_00_b.*,然后构建中的硬件依赖项检查就会 OK。这个环境问题可能是由于在使用 EDK 之前 Xilinx 要求安装的 IP 更新引起的;从这一点需要注意的是,可能还有其他核心也有同样的潜伏问题。幸运的是,可以轻松地推导出命名约定,只要查看文件名和版本号就能修正这个问题。

现在,构建应该可以编译 button_led_test.c 了,这时会遇到一堆错误。这些错误是因为这个源文件引用了 xuartns550_l.h,这个头文件是(被删除的)16550 驱动程序的一部分。如果查看 uartlite 的 API 文档,那么修补这个程序让它在小 UART 驱动程序上运行就相对简单,只要注释掉所有出错的行,就能把代码装入该板。(在处理代码时,请注意程序如何从 xgpio_l.h 导入 GPIO 的基地址 —— 如果变动了外部设备的基地址,EDK 会自动更新它。)

在注释掉所有出错的行并构建完可执行文件之后,在 C:\reference_systems\EDK_Projects\ml403_emb_ref_ppc\ppc405_0\code 中会得到 button_led_test.elf。几乎就要成功了!请确保附带了 JTAG 适配器,并从 Tools 菜单选择 XMD。由于这可能是您第一次运行它,所以会要求您对设置做些配置;在这里只需要修改 JTAG Cable Type —— 单击 USB 单选按钮,再单击 Save

XMD 会启动一个命令行会话,用项目的目录作为当前工作目录。键入 cd ppc405_0/code 并按下 Enter。现在键入 dow button_led_test.elf 下载程序,再键入 run 运行程序。会在调试器上看到以下输出:

清单 4
XMD% dow button_led_test.elf
         section, .text: 0xffff0000-0xffff038c
         section, .boot0: 0xffff26d0-0xffff26e0
         section, .boot: 0xfffffffc-0x00000000
         section, .rodata: 0xffff038c-0xffff03a6
         section, .sdata2: 0xffff03a8-0xffff03a8
         section, .data: 0xffff03a8-0xffff0698
         section, .fixup: 0xffff0698-0xffff06ac
         section, .got2: 0xffff06ac-0xffff06cc
         section, .sdata: 0xffff06cc-0xffff06d0
         section, .bss: 0xffff06d0-0xffff26d0
Downloaded Program button_led_test.elf
Setting PC with program start addr = 0xfffffffc
PC reset to 0xfffffffc, Clearing MSR Register
XMD% run
PC reset to 0xfffffffc, Clearing MSR Register
Processor started. Type "stop" to stop processor
RUNNING>

现在已经在 FPGA 内下载并启动了您的第一个 PowerPC 程序。在 5 路操纵杆区内按下任何一个按钮,都会使按钮附近的 LED 发光。

您初次看到详细写出的上述全部内容时,会觉得非常复杂。但是一旦理解了设计流程,并花上几天的实践去寻找工具链的特点,就会发现它真的是一个非常简单的系统,该系统操纵了高度复杂的 FPGA 结构。EDK 简洁地隐藏了令人心烦的大部分依赖项处理工作,虽然有些时候需要绕过 GUI,直接进入实际的源文件处理 FPGA 方面的操作。

参考资料

学习

  • 您可以参阅本文在 developerWorks 全球网站上的 英文原文
  • 请参阅 Xilinx ML403 Evaluation Platform Demos and Reference Designs 获得在 ML403 上运行的多个参考设计的直接下载链接。
  • Opencores 有大量用于各种功能的 免费 HDL 核心
  • cygwinminGW 都有助于使 Windows 环境更像 UNIX® 环境。cygwin 主要由 GPL 管理,而 minGW 主要是在公共域 —— 请注意这里用的 “主要” 这个词是为了警告您:这一概括并不适用于这些集合中的所有组件。
  • 随时关注所有适合打印的 Power 架构相关的新闻:订阅 IBM microNews

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Linux
ArticleID=202762
ArticleTitle=Xilinx hijinx,第 2 部分: 构建和加载比特流和 PowerPC 代码
publish-date=02222007