亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> VHDL

在 Linux VPS 上使用 Jenkins、Vivado 和 GitHub 自动化 FPGA 开发

* 本文包含 UpCloud VPS 的广告链接

持续交付和持续集成是敏捷的软件开发方法,可以缩短代码更改和部署之间的周期时间。通过使用自动化来验证代码更改并构建发布文件,团队可以变得更加高效。

软件公司长期以来一直实行持续开发,但您也可以将这些方法用于您的 FPGA 项目。本教程将教您如何使用 Jenkins、Xilinx Vivado 和 Git / GitHub 源代码控制管理 (SCM) 系统在虚拟专用服务器 (VPS) 上设置自动化服务器。

什么是詹金斯?

Jenkins 自动化服务器是一个用 Java 编写的免费开源程序。它在 Windows 或 Linux 上运行。我们将在本博文中使用 Linux,因为这是无头服务器最常见的平台。

Jenkins 在 Linux 中作为守护进程运行,在 Windows 中作为服务运行。 Jenkins 在启动时启动的内置 Web 服务器提供用户界面。大多数用户将使用 Web 界面与 Jenkins 进行交互。您可以通过 Web GUI 添加新的自动化项目并管理现有项目。

上图显示了我们今天要设置的 Jenkins 服务器的主页。默认情况下,只有登录的用户才能访问 Jenkins,但在本文中,我启用了对我的 *演示服务器的部分内容的公共访问。

* 更新:我于 2020 年 5 月 13 日关闭了演示服务器

您在主页上看到的是职位列表。这些作业可以包含任何任务,并且可以从 Web GUI 手动触发。或者它们可以通过脚本、网络钩子或其他作业完成时自动触发。因此术语自动化服务器 .

在我们的示例中,每个作业对应于保存在单独的 GitHub 存储库中的 VHDL 模块。每当开发人员将代码推送到受监控的 Git 存储库之一时,我们都会让 Jenkins 运行模拟并构建项目。如果测试平台失败或构建中断,Jenkins 会在 Web 界面中将作业标记为失败,并自动向提交错误代码的人发送电子邮件。

示例项目

自动化服务器对于处理大型项目的团队最有用。因此,我构建了一个由八个 Git 存储库组成的示例 FPGA 项目。该项目是从 Fast-Track 课程移植到 Xilinx ZedBoard 的 7 段显示计数器。

GitHub 上八个存储库的链接:

每个存储库都包含一个 VHDL 模块及其测试平台。一个例外是 repo,其中仅包含三个定义常量和类型的 VHDL 包。此外,seg7 顶部模块包含一个约束文件,定义物理实现的时钟速度和引脚分配。

大多数大型 VHDL 项目都使用多个存储库中的模块。公司通常拥有一个在许多设计中重复使用的包和模块库。这就是我通过将这个相当简单的设计分成许多模块来模拟的。

在我们的示例中,所有模块都依赖于包存储库,并且顶层模块也依赖于所有子模块。我通过使用标准 Git 子模块根据需要导入它们解决了这个问题。上图展示了该项目中所有repos的内容和依赖关系。

Git 存储库还包含多个非设计文件,例如 Jenkins 配置和构建脚本。我们将在本文接下来的部分中讨论它们。

虚拟专用服务器 (VPS)

虽然 Jenkins 可以在任何 Windows 或 Linux 计算机上运行,但出于所有实际目的,您可能希望在专用服务器上运行它。自动化服务器必须始终启动并运行,并且所有团队成员都可以访问。如果您有一台容量足够的物理服务器,那就太好了。但对于我们大多数人来说,更快、更便宜的解决方案是使用虚拟专用服务器 (VPS)。

VPS 是您通过互联网从托管公司租用的虚拟计算机。它看起来就像一台真正的 Windows 或 Linux 计算机,您可以与它交互并安装您想要的任何软件。我们将使用 Linux 计算机,因为这对我们的用例来说最有意义。

VHDLwhiz 网站在 VPS 上运行,过去两年一直如此。我已经费尽心思找到了最快、最好的 VPS 提供商,那就是 UpCloud。当然,我们将使用 UpCloud 为我们的自动化服务器设置 VPS。

获得 25 美元的 UpCloud 奖金

如果您想尝试 UpCloud,我有一个推荐代码,可以为您提供价值 25 美元的积分 报名时。

>> 点击此处获取 25 美元的 UpCloud 奖金 <<

或者在结账时使用我的促销代码:NV78V6

通过使用该代码,您将获得奖金并同时支持VHDLwhiz。对于每位使用 UpCloud 的客户,我可能会收到一些资金存入我的 UpCloud 帐户。

好的,销售谈话就够了。让我们继续设置服务器。

部署UpCloud VPS

登录到新的 UpCloud 帐户后,您可以通过导航到服务器 → 部署服务器来开始创建新 VPS 实例的过程 .

UpCloud在全球拥有多个数据中心。选择离您最近的位置来托管新服务器。然后,您必须选择为虚拟机提供多少资源的计划。 Jenkins 并不使用太多资源,但 Xilinx Vivado 却是真正的 RAM 霸主。因此,您应该至少选择具有 4 GB RAM 的套餐,如下图所示。

我建议查看 Xilinx 的内存建议页面,因为内存使用与目标 FPGA 的复杂性密切相关。该页面列出了我使用的 Zynq-7000 XC7Z045 FPGA 的峰值内存使用量为 1.9 GB。我发现 2 GB 规划对于设计布线来说太小了。 Vivado 崩溃,dmesg 中出现以下消息 日志:

[807816.678940]内存不足:杀死进程 22605 (vivado) Total-vm:2046684kB、anon-rss:782916kB、file-rss:308kB、shmem-rss:0kB

请注意,您始终可以从您的 UpCloud 帐户中轻松升级服务器的 RAM 和 CPU 资源。如果不重新分区 VPS 的文件系统,您不会自动获得更昂贵的软件包附带的额外硬盘空间,但它会运行。作为参考,我一开始计划使用 50 GB 存储,在完成整个自动化服务器后,我已经使用了其中的 61%。仅 Vivado 就占用 24 GB 空间。

我建议您选择最新的CentOS Linux发行版作为操作系统,如下图所示。 Xilinx Vivado 官方仅支持 Red Hat Linux,该 Linux 不是免费的。但 CentOS 是一个免费的、社区支持的 Linux 发行版,紧随 Red Hat。

然后还有一些有关网络的选项,您可以保留默认值。网页上还有一个部分,您可以在其中上传 SSH 密钥以进行无密码登录。您可以稍后使用传统的 Linux 方法上传 SSH 密钥来配置这些内容。

最后,您需要指定服务器的主机名和名称,如下图所示。主机名是用户在浏览器中输入以访问 Jenkins 服务器的公共域。如果您没有准备好域或子域,您始终可以使用服务器的 IP 地址访问服务器。当您对设置感到满意时,请按部署 按钮创建服务器。

创建服务器后,自动生成的密码将显示为通知。您可以稍后使用 Linux passwd 更改此设置 命令。如果您在部署服务器之前提供了 SSH 密钥,则根本不需要密码。如果您失去对服务器的访问权限,您可以随时通过点击打开控制台连接从您的 UpCloud 帐户中登录 ,如下图所示。

DNS 区域设置

新服务器将被分配永久 IPv4 和 IPv6 地址,可在您的 UpCloud 帐户中的服务器->网络中找到 。您可以通过 SSH 连接到公共 IPv4 地址的 root 帐户来访问服务器。

通过使用下图中的示例 IP 地址,在 Linux 家用计算机中输入的相应命令为:

如果您只是将其作为实验,则可以仅使用 IP 地址。但更实用的解决方案是为服务器分配一个永久域名。为此,您必须从众多在线注册商之一购买域名。

由于我已经拥有 vhdlwhiz.com 域,因此我决定为 Jenkins 服务器创建一个名为 jenkins.vhdlwhiz.com 的子域 。我们在部署UpCloud服务器时正确设置了域名。接下来我们需要做的是将子域指向公共 IPv4 地址。

下图显示了我在域名注册商的 DNS 区域文件中输入的设置。如果我希望服务器位于顶级域 (vhdlwhiz.com) 上,我会将主机名字段留空。但我希望它位于 vhdlwhiz.com 的“jenkins”子域上。因此,我输入子域的名称。

更改 DNS 设置后,需要一段时间才能使用域名访问您的网站。通常,更改不会超过 20 分钟,但在极端情况下,可能需要长达 48 小时的时间才能将更改传播到互联网的每个角落。

更改生效后,通过SSH登录服务器时可以使用域名代替IP地址:

<前>08

安装詹金斯

登录新 Linux 服务器上的 root 帐户后,您应该做的第一件事是更新所有已安装的软件包。在 CentOS Linux 中,yum 是默认的包管理器。我们将使用yum 用于安装大部分软件的命令。

发出以下命令将所有已安装的软件包更新到最新版本:

现在我们知道我们的系统是最新的,我们可以继续安装。但在发出yum之前 命令安装 Jenkins,我们将明确安装 Java 版本 11。这将为我们以后安装 Xilinx Vivado 时省去一些麻烦。

目前,我们的服务器上没有 Java 解释器,如果我们告诉 yum 要安装 Jenkins,它将安装 Java 版本 8。这对于 Jenkins 来说效果很好,但稍后会给我们带来问题,因为 Vivado 依赖于 Java 版本 11。

在安装 Jenkins 之前使用此命令安装 Java 11:

<前>18

CentOS 附带的默认软件存储库中不提供 Jenkins。幸运的是,我们可以使用以下命令从 Red Hat 导入 Jenkins 存储库:

<前>25

最后,我们可以继续安装 Jenkins:

Jenkins服务器将在下次启动后自动启动,但是您可以像这样启动服务器而无需重新启动:

您始终可以使用 systemctl 检查 Jenkins 服务器的状态 命令:

它将打印出服务器的状态以及任何错误消息:

Jenkins 通过不安全的 HTTP

此时,Jenkins 正在 VPS 上的端口 8080 上运行,但您无法使用 Web 浏览器连接到它。这是因为 CentOS 防火墙默认阻止端口 8080 和端口 80 (HTTP)。我们可以做的就是在防火墙中打开端口 80 并使用 iptables 将其重新路由到端口 8080 来解决此问题 .

但在此之前,您必须决定是否要使用 HTTPS 来保护您的网站。仅使用 HTTP 和端口 80 的问题是您的网站将不安全。如果您使用公共 Wi-Fi 访问它,则使用同一 Wi-Fi 的恶意人员可以使用笔记本电脑和现成的黑客软件窃听您的连接并窃取您的 Jenkins 登录凭据。

如果您想避免未加密 HTTP 的安全风险,请跳至下一节有关为 Jenkins 设置 HTTPS 的内容。否则,请继续阅读。

启用对 Jenkins 的不安全 HTTP 访问就像发出以下命令一样简单:

<前>39

然后您可以在您喜欢的浏览器中输入您的域名,然后 Jenkins 入门 页面应该出现。至少在Google Chrome中,地址栏中会显示“不安全”警告,如下图所示。

跳至设置 Jenkins 如果您对此感到满意,请参阅部分。

基于安全 HTTPS 的 Jenkins

拥有一个可供公众访问的不安全网站存在巨大的安全风险。 Jenkins 可以访问您的源代码,任何成功侵入服务器的黑客也可以访问您的源代码。幸运的是,只需复制粘贴几个命令即可保护网站。

Jenkins 无法自行处理 HTTPS。因此,我们必须安装一个通用 Web 服务器,将通过安全通道到达的请求重新路由到不安全的 Jenkins 服务器。我将使用 Nginx,它是当今最流行的免费开源 Web 服务器之一。

发出以下命令来安装并启动 Nginx:

<前>48

然后我们需要在防火墙中打开HTTP和HTTPS端口。我们将只服务 HTTPS 请求,但我们还需要保持 HTTP 端口打开,因为我们将配置 Nginx 将所有不安全请求重定向到安全端口。

这些命令将为网络流量打开防火墙:

<前>56

下一步是安装一个证书,网络浏览器可以使用该证书来证明它们正在与之交互的是您的网站,而不是冒名顶替的网站。我们将使用免费的 Let’s Encrypt 证书颁发机构来保护我们的网站。各个步骤很复杂,但幸运的是,certbot 提供了一个可以自动为我们完成此操作的脚本。

使用以下命令下载并准备脚本:

<前>68

接下来,运行脚本,该脚本将安装证书并对 Nginx 配置文件进行必要的更改:

当脚本运行时,它会提示您输入信息。对所有问题都回答肯定(是,接受),直到系统要求您选择是否将 HTTP 流量重定向到 HTTPS。下面的列表显示了问题和我建议的答案 (2)。允许 Nginx 重定向不安全的请求可确保没有人可以显式输入 http:// yoursite.com 并获取 Jenkins 的不安全版本。 Nginx 会将它们重定向到安全版本。

<前>70

最后,您应该启用 cron 作业来定期更新证书。否则,它将过期,浏览器将根本拒绝打开您的网站。

发出以下一行命令来添加每日 cron 作业:

<前>87

cron 守护进程将在每天午夜运行更新脚本。您可以使用 crontab -l 列出 cron 作业 命令并使用 crontab -e 编辑它们 命令。如果您现在访问您的网站,您将看到 Nginx 测试页面,而不是 Jenkins。我们将很快修复此问题,但请确保 Chrome 地址栏中的“不安全”警告消失,如下图所示。

为了让Nginx服务Jenkins,你需要对/etc/nginx/nginx.conf进行一些更改 文件。此代码片段归功于 Kerren 在 Medium 上的博客。使用 nano 编辑器可能是编辑配置文件的最简单方法:

<前>97

找到列出您的域名的服务器块,并将下面列表中突出显示的行添加到您的 nginx.conf 文件中。请注意,三行新行中的第一行位于服务器块上方,其余行位于根位置块中。

更新配置文件后,需要重新加载 Nginx 才能使更改生效。或者,您可以在重新加载之前使用以下命令测试配置文件:

Nginx 将打印出 OK 或告诉您在 nginx.conf 中的哪一行 文件错误是。当您对更改感到满意时,您可以通过发出以下命令重新加载 Web 服务器:

现在,当您在浏览器中访问 Jenkins 站点时,您应该会看到 Jenkins 的入门页面,如下图所示。这次它是通过安全连接提供的,我们可以安全地继续从 Web GUI 界面中配置 Jenkins。

设置 Jenkins

第一次访问 Jenkins 网站时,它会提示您输入在 Linux 文件系统上的文件中找到的密码。通过 SSH 登录后,使用以下命令显示密码。将其复制粘贴到浏览器中以访问 Web GUI:

<前>105

在下一个屏幕上,Jenkins 将询问您是否要安装建议的插件,或者是否要指定安装哪个插件。只需使用安装建议的插件 暂时的选择。您稍后可以随时添加或删除插件。

在下一页上,您必须创建管理员用户。填写您的详细信息并创建一个强密码以用于您的新帐户。默认情况下,只有登录用户才能访问 Jenkins 服务器。匿名用户只有在冒险访问您的网站时才会看到登录对话框。您可以访问我的*演示网站的唯一原因jenkins.vhdlwhiz.com 是我对服务器进行了更改。我使用 Matrix 授权策略插件授予对某些视图的匿名访问权限。

* 更新:我于 2020 年 5 月 13 日关闭了演示网站

当 Jenkins 完成插件安装后,您将看到“Jenkins is ready!”消息,如上图所示。单击按钮,您将进入新安装的 Jenkins 的空白概述页面。

安装 Jenkins 插件

您需要做的第一件事是安装一堆插件。 Jenkins 有一个内置插件管理器,可用于安装、更新和删除扩展。您会发现可以满足您大部分需求的插件。当您需要向 Jenkins 添加功能时,只需使用插件管理器中的搜索功能即可。

让我们继续安装我在设置示例 Jenkins 服务器时使用的插件。从侧边栏中选择管理 Jenkins->管理插件->可用 。请注意,除非您在搜索字段中输入某些内容,否则不会列出任何插件。一旦你输入,它们就会出现。

蓝海

我建议安装的第一个插件名为 Blue Ocean。该插件是 Jenkins 工作流程和用户界面的现代化版本。它还引入了许多其他有用的插件,这样您就不必单独安装它们。在插件管理器中搜索“blue ocean”并选择安装,如下图。

在单击安装后出现的安装进度页面上,您可以选择安装完成且没有作业正在运行时重新启动 Jenkins 。如果您选中旁边的复选框,Jenkins 将在插件安装完成后重新启动。重新启动 Jenkins 的另一种方法是通过 SSH 登录服务器并运行以下命令:

<前>112

除了 Blue Ocean 安装的一长串其他插件外,乍一看并没有明显的变化。但侧边栏中将会出现一个新的菜单项,如下图所示。单击后,它将带您进入 Blue Ocean GUI,它看起来与普通 Jenkins 界面有很大不同。尝试一下!

绿球

我总是安装的下一个插件纯粹是为了美观。 Green Balls 插件不需要任何配置。只需在插件管理器中搜索“green ball”并安装它,如下图所示。

默认情况下,Jenkins 在概览页面中使用蓝色球来指示作业状态成功。原因与Jenkins的发明者是日本人有关。有趣的是,在日本,当表示“正常”状态时,蓝色可以与绿色互换。更多相关内容,请参阅本文,您可以听到作者亲自解释原因。

来自世界上大多数其他地区的用户可能更喜欢绿色状态球。这个问题可以通过 Green Balls 插件轻松解决,如下图所示。

区域设置插件

我安装的下一个插件名为 Locale。在可用下搜索“区域设置” 插件管理器中的选项卡。安装插件,如下图所示。

该插件允许您强制 Jenkins 在 GUI 中为所有用户使用相同的语言。默认情况下,Jenkins 会将用户界面翻译为您的 Web 浏览器正在使用的语言。我是挪威人,但我更喜欢英语版的詹金斯。翻译的有点不够到位。此外,如果您需要了解如何在 Jenkins 中执行某些操作,那么用 google 搜索英文答案会更容易。

当然,如果你想要这个插件,完全取决于你。如果安装它,您需要导航到管理 Jenkins->配置系统 并找到名为Locale的部分 。然后,您需要输入“en_US”(或您想要的任何语言)并选中下面的框以强制所有用户使用该语言,如下图所示。不要忘记滚动到页面底部并单击“保存” .

克隆我的设置所需的最后一个插件是侧边栏链接插件。它允许您将自定义链接添加到 Jenkins 侧边栏。稍后我们将使用它添加 FPGA 版本(位文件)的链接。在插件管理器中搜索“sidebar”并安装插件,如下图。

将 Jenkins 连接到 GitHub

无论您的存储库是公共的还是私有的,您都需要向 Jenkins 授予您的 GitHub 帐户的一些权限。至少如果你想以最简单的方式做到这一点,你应该让 Jenkins GitHub 插件为你管理与 GitHub 的接口。 Blue Ocean 已经安装了 GitHub 插件。这些是配置它的步骤。

首先,您应该在系统上安装 Git。 GitHub 插件并不严格需要它,但是当你开始使用 Jenkins 作业时,你必须拥有它。发出此命令在 CentOS Linux 中安装 Git:

GitHub 中的个人访问令牌

登录 GitHub,单击右上角的个人资料图片,选择设置,然后转到“开发者设置” 。然后,选择个人访问令牌 从左侧边栏菜单中,或单击此链接直接将您带到那里。

在这里,您需要点击生成新令牌 ,如下图所示。 GitHub 将再次询问您的密码。您现在所做的实质上是创建一个新的、特定于应用程序的密码。这比共享您的实际密码更好,因为您可以撤销它,并且可以限制授予令牌的权限。这就是我们将在打开的页面上执行的操作。

输入密码后,您需要为令牌命名。这个名字只适合你。它可以是任何东西,例如“Jenkins”。然后,您必须至少启用 admin:org_hook , admin:repo_hookrepo 权限,如下图所示。您可以不选中所有其他框。

最后,当您点击生成令牌 ,将出现访问代码。您需要在离开该页面之前复制它,因为不可能再次看到它。如果您忘记了,请删除该令牌并重新创建它。

在 Jenkins 中输入 GitHub 凭据

复制令牌后,转到 Jenkins,选择管理 Jenkins-> 配置系统 ,然后找到名为 GitHub 的部分 ,如下图所示。从下拉菜单中,选择“添加 GitHub 服务器->GitHub 服务器” .

在出现的新 GitHub Server 部分中,选中标记为管理挂钩的框 。当您执行此操作时,Jenkins 将在 GitHub 上为您正在监控的存储库安装 Webhook。稍后我们将看到这特别有用,因为当用户将代码推送到关联的 GitHub 存储库时,我们将使用它们在 Jenkins 中触发模拟或构建。

选择凭据(添加)->Jenkins 勾选该框后,如下图所示。

在打开的窗口中,更改种类 下拉至秘密文本 。然后,将您之前在 GitHub 中生成的个人访问令牌粘贴到 Secret 中 场。在 ID 字段中输入“GitHub”,然后按添加 .

最后,当您返回主配置菜单时,添加秘密文本后,选择新的 GitHub 来自凭证的密钥 菜单。然后,按测试连接 验证 Jenkins 是否可以使用访问令牌与 GitHub 进行通信。如果一切顺利,您应该会看到如下图所示的消息。

确保滚动到页面底部并点击保存 在离开配置页面之前。

如果您遇到麻烦并最终添加了多个凭据,您可以通过转到管理Jenkins->管理用户来删除它们 ,然后单击您的用户名。现在,在左侧边栏中,将有一个名为Credentials的菜单项 。从那里,您可以查看和编辑 Jenkins 存储的所有密钥。

从 Jenkins 发送电子邮件

我们将配置 Jenkins 在代码出现问题时自动发送电子邮件。为了实现这一点,我们需要在管理 Jenkins-> 配置系统中进行一些更改 菜单。

您应该做的第一件事是输入 Jenkins 在发送自动电子邮件时将使用的发件人地址。查找系统管理员电子邮件地址 配置页面上的字段,然后输入您希望 Jenkins 发送的地址。

请注意:最好输入以 Jenkins 域名结尾的地址。这可以最大限度地减少电子邮件进入垃圾邮件文件夹的可能性。 Jenkins 服务器无权代表其他域发送电子邮件,但大多数电子邮件服务接受与发送服务器具有相同域的发件人地址。在这篇维基百科文章中阅读更多相关内容。在下图中,我输入了一个以与 Jenkins 服务器相同的域结尾的发件人地址。

接下来,我们需要为 Jenkins 提供一种发送电子邮件的方式。最直接的方法是在 VPS 上安装 SMTP(邮件)服务器。您可以通过登录并发出以下命令来做到这一点:

<前>127

安装sendmail后 ,回到Jenkins系统配置,在SMTP服务器中输入“localhost” 字段,如下图所示。

此时,您还可以选中该框以允许发送给未注册的用户。这意味着没有 Jenkins 用户帐户的用户。稍后,我们将配置 Jenkins 向任何将错误代码推送到 GitHub 的人发送电子邮件。 Jenkins 将从 GitHub 获取罪魁祸首的电子邮件地址,但这只有在该人拥有匹配的 Jenkins 帐户或者我们选中此框时才有效。

最后,您可以测试配置,如上图所示。按测试配置后 ,应出现消息“电子邮件已成功发送”,并且电子邮件应到达您的收件箱。如果您在五分钟内没有收到电子邮件,请检查您的垃圾邮件文件夹。

以批处理模式安装 Xilinx Vivado

我使用 Xilinx Vivado 来模拟、编译和实现此示例项目中的代码。目标设备是 ZebBoard 开发板上的 Xilinx Zynq-7000 FPGA。在本节中,我将向您展示如何使用免费的 WebPACK 许可证在 VPS 上安装 Vivado。

第一步是下载 Xilinx 统一安装程序:Linux 自解压 Web 安装程序,如下图所示。您需要登录或创建新的 Xilinx 帐户才能下载安装程序。

下载完成后,您必须将其从桌面计算机复制到 Jenkins 服务器。如果您可以访问桌面上的 Linux shell,我建议使用安全文件复制,如以下命令所示:

在运行安装程序之前,您需要安装一些软件包以满足 Vivado 的依赖关系。运行以下命令来执行此操作:

<前>132

然后,运行 Xilinx Unified 安装程序,如下所示:

<前>144

.bin 文件会将安装文件解压到名为 Xil_installer 的新目录 。如果您收到下面列出的错误,那是因为您尚未安装 tar .

<前>157

Xilinx Unified 安装程序可以在您的系统上安装许多不同的 Xilinx 工具。因此,我们必须运行xsetup Xil_installer 中的文件 目录来指定我们感兴趣的软件:

<前>163

xsetup 脚本会提示您想要使用哪些工具。输入“2”表示Vivado ,然后“1”表示 Vivado HL WebPACK ,如下面的清单所示。

<前>176

要安装 Xilinx WebPACK 版本,您必须在安装过程中登录您的 Xilinx 帐户。在台式计算机上,安装程序 GUI 会引导您完成此过程,但在服务器上,没有 GUI,因此我们必须使用 xsetup 进行身份验证 脚本。运行以下命令生成身份验证令牌:

我必须运行该命令几次才能起作用。起初,脚本停止并出现错误“互联网连接已验证,可以连接到互联网”。然而,经过几次尝试后,我成功了,并且能够登录。该脚本将询问您的用户 ID 和密码。这是您从 xilinx.com 下载安装程序时使用的电子邮件和密码。

最后,您就可以以批处理模式安装 Vivado。调用安装脚本时,您必须指定安装配置文件,以便xsetup 知道要下载哪些工具。配置文件位于.Xilinx中 root 用户的主目录中的文件夹。运行以下命令以使用配置文件开始安装:

<前>184

安装过程将需要很长时间才能完成。 Vivado 安装使用 24 GB 空间。所有这些现在都是从相对较慢的 Xilinx 服务器下载。对我来说,下载只花了两个多小时。

安装完成后,您应该测试 Vivado 是否以批处理模式成功启动。 Xilinx 提供了一个 shell 脚本来为您设置环境。在运行 Vivado 之前,您需要使用 将脚本内容加载到活动 shell 中的命令:

<前>195

然后,您就可以运行 Vivado 了。 But there’s no GUI environment installed on your server, so we have to start it in batch mode by using this command:

If Vivado starts and exists immediately without printing any errors, it’s an indication that Vivado has everything it needs, and you are ready to go. Note that if you are getting the error listed below, it’s because you haven’t installed the ncurses-compat-libs package, as we talked about at the start of this section.

200

Integrating Vivado in Jenkins

To prepare Jenkins for Vivado, we need to make some changes to the general settings. Head to Manage Jenkins->Configure System and check that all the default settings make sense for you.

As I mentioned earlier, Vivado uses a lot of RAM. The resource usage depends on your target FPGA, and you can get an indication of how much you need from the Xilinx Memory Recommendations page. Therefore, I recommend that you change the default number of parallel jobs that can run from 2 to 1. Unless you allocated vast RAM resources on your VPS, you probably want to set # of executors to 1, as shown in the image below.

Instead of defining the environment variables in every Jenkins job, we will specify the PATH globally for all jobs. That makes it easier for you to swap to a newer version of Vivado in the future. Then you can refer to the ‘vivado’ executable in your scripts, and it will always point to the latest version, or whichever you decide.

Scroll to the Global properties section and check Environment variables 。 Click Add to get a new entry. Make sure to include the standard Linux PATH 以及。 I used “PATH=/tools/Xilinx/Vivado/2019.2/bin:/sbin:/usr/sbin:/bin:/usr/bin”, as shown in the image below.

Don’t forget to scroll to the bottom of the page and click Save .

Vivado GUI projects in batch mode

I chose to manage the Vivado projects in GUI mode. For each repository, I created a new project from within the regular Vivado GUI, adding source files, setting libraries, and all of that. However, the .xpr project files are binary and depend on a lot of other temporary files in the project directory.

Binary files are not suitable for SCMs like Git. Fortunately, Xilinx has thought of this and written a guideline (XAPP1165) for how to use Vivado with version control systems. What we do is to use the write_project_tcl command in Vivado to export the entire project into a Tcl script. The script contains human-readable Tcl code suitable for Git.

I’ve organized all of the Git repos so that all files that belong to the Vivado projects are in a subfolder named “vivado”, while the VHDL source files are in the parent directory. Check out the demo packages project on my GitHub to see what I mean. For each repo, we will put the Vivado Tcl scripts in the vivado 文件夹。 You will also find the create_vivado_proj.tcl file, which is the human-readable version of the Vivado project.

To create the create_vivado_proj.tcl file, start by setting up the Vivado project as you wish in the Vivado GUI. Make sure that the Vivado project resides within a vivado subfolder. When you’re happy with the project, export it by entering the following commands in the Vivado Tcl console:

217

Add the create_vivado_proj.tcl file to Git, and set up the gitignore to ignore the rest of the Vivado project. Here’s the content of my .gitignore file which ignores everything but Tcl scripts in the vivado folder:

Opening the Vivado project in batch mode

It’s a good idea to test the Vivado project manually on the VPS before you start creating Jenkins jobs. By default, the daemon runs from a user account named jenkins on the Linux server. Therefore, you should test the Vivado project using the jenkins user.

Make sure that you have Git installed on the Linux server before you start this experiment. Run this command to install Git after logging in as root:

You can’t log in to the jenkins user directly, but you can change to it from the root user like this:

If you now run a pwd command, you will see that you are at /var/lib/jenkins

227

That’s because this isn’t a regular user account that has the home directory under /home , as is the norm on Linux systems. It’s only for running the Jenkins daemon, but we can log in to perform a manual walkthrough of the build process in the Jenkins environment.

The home folder is full of all the dynamic data like logs, user settings, and plugins that you have downloaded. When we later start running jobs in the Jenkins GUI, they will appear in the jobs folder.

Let’s go to the jobs folder to perform our experiment:

236

You can clone your Git repository directly into the jobs 文件夹。 Your Git repo has to be accessible without using a password. Either because it’s public, or because you have set up passwordless login as described on the GitHub help pages.

If you don’t have a Git repository with the Vivado project ready, feel free to clone one of my repos like this:

249

Then, cd into the new directory of the Git repository, and further into the vivado folder:

259

If you downloaded my example, you would find two Tcl files:create_vivado_proj.tcl and check_syntax.tcl 。 The first one is the Vivado project converted to a Tcl file, and the second one is a script that we haven’t talked about yet. It’s for checking the syntax of VHDL files in the Vivado project.

Before we can run any Vivado command, we need to set the PATH environment variable in the current shell. In Jenkins, we solved this by using Global properties , but now we are not coming through Jenkins, so we have to source the setup script from Xilinx like this:

263

Now that the vivado executable is in our path, let’s start by recreating the project. This is the command for doing that when running Vivado in batch mode:

277

After you hit Enter, you should see a whole lot of Tcl code echoed to the console. It’s the code for recreating the Vivado project that’s executing. If you didn’t see any obvious errors, type the command “echo $?” in the terminal before you do anything else. The output should be 0 if everything went well, as we can see from the listing below.

282

The “echo $?” command shows you the exit status from the previous command that you executed in Linux. An exit status of 0 means that everything is OK, no error. Any other exit status than 0 is an indication of error. Those are old Unix conventions that you can read more about here. Anyway, the exit status is important for Jenkins because that’s how it decides if a job stage is a success or a failure.

If you now do a directory listing, you will see that Vivado has recreated the project’s binary files:

293

Let’s try another experiment with running Tcl scripts in Vivado batch mode. Create a one-liner Tcl script by using the following command:

Now, run the script in Vivado batch mode:

302

After Vivado closes, check the exit code once more using the “echo $?” command:

314

It’s 1, which means exit failure in Unix. If you change the content of the test.tcl script to “exit 0”, and run Vivado once again, you will see that the exit status is now 0, indicating success. Try it!

The exit keyword is standard Tcl. We are going to use it as the interface between Vivado and Jenkins. Jenkins runs whatever Tcl script we create in Vivado, and looks at the exit status to determine if it shall mark the job stage as success or failure.

Remember to delete our little test project from the jobs folder when you are happy with the experiment:

325

Tcl script for checking code syntax in Vivado

This Tcl script runs a syntax check of the VHDL files in the project. If you are going to simulate or implement the code, you won’t need this script because any syntax errors will break the compilation. But for my packages project, it doesn’t make any sense to create a testbench for it. The files just contain constant and types declarations. I still want to catch any coding errors pushed to this repo, and that’s where the syntax check comes in handy.

In the script that is listed below, we start by opening the project file. Then, we call the Vivado check_syntax command while telling it to save the output to a variable called msg 。 After the check has completed, we look at the output message to see if there were any errors reported. If check_syntax reported anything at all, we set the exit status to 1 (failure). If there were no errors, we exit 0 (success).

check_syntax.tcl:

338

Vivado supports all of the standard Tcl keywords, and there are also a lot of built-in commands like check_syntax. I recommend taking a look at these two Xilinx documents that cover the Tcl scripting capabilities in great detail:

Vivado Design Suite Tcl Command Reference Guide (UG835)

Vivado Design Suite User Guide Using Tcl Scripting (UG894)

Tcl script for simulating in Vivado

The next script that I created is for running the testbench in batch mode. For this to work, you have to configure the simulation sets in the Vivado GUI before you export the project to Tcl. Go ahead and recreate one of the simulation projects on your desktop computer using the create_vivado_proj.tcl script to see how I set it up beforehand. You can open the reconstructed projects in the Vivado GUI.

As you can see from the listing below, I start by opening the project. Then, I set the name of the simulation fileset to a variable (usually sim_1 )。 After we launch the simulation, we also have to close it. Otherwise, the status of the simulation won’t get written to the log files.

run_simulation.tcl:

342

Now, I struggled to find a good way of getting the simulation status. My VHDL testbenches terminate on a VHDL finish keyword on success. Errors will result in a VHDL assertion failure. There’s no obvious way to find out why the simulator stopped by using Tcl commands in Vivado.

Fortunately, Tcl is a powerful scripting language. My workaround is to open the simulation log and look for the string “Failure:”, which indicates a VHDL assertion failure. Finally, we exit 1 if the word is in the log, or 0 if it isn’t.

Tcl script for synthesizing in Vivado

In the Tcl script for synthesizing in Vivado batch mode, we start by opening the project file. Then, We assign the run name to a variable. You must have added the design files to the Vivado project before you exported it to Tcl. If you didn’t change the name of the synthesis run in the GUI, it’s will probably be “synth_1”.

You should set the CPU count variable to the number of logical processors that your server has. This number controls the degree of multithreading that Vivado uses. I opted for the VPS with 4 CPUs on UpCloud, and therefore set the CPU count to 4.

run_synthesis.tcl

352

The launch_runs command is non-blocking, meaning that it will complete before the actual synthesis. If we try to read the status right after calling launch_run , it will be “Running”. To pause the script until the synthesis completes, we call the wait_on_run command.

Finally, we get the run status and exit 0 or 1, depending on the status message.

Tcl script for running the implementation in Vivado

The script for running Place and Route (PAR) in Vivado batch mode is similar to the synthesis script. The difference is that the run name is now “impl_1”, and that we are looking for another success message.

run_implementation.tcl

364

Tcl script for generating the bitstream in Vivado

Finally, after if the implementation completes successfully, we can generate a bitstream for programming the FPGA. The script is similar to the previous one, but the launch_runs command is slightly different. And of course, we are looking or a different status in the end.

generate_bitstream.tcl

376

Setting up the Jenkins jobs

A job in Jenkins refers to a set of grouped software tasks. Jenkins displays jobs and their current status as items listed on the overview page. You can start jobs manually from the web interface, or they can be triggered automatically, for example, when someone pushes code to a repo, or as a result of another job completing. We will do both.

Jenkins offers several ways of managing jobs. The traditional method is the Freestyle project , where you specify every action from within the Jenkins web GUI. The more modern way of managing Jenkins jobs is to use a pipeline script that stores all of the information about the execution flow. The pipeline scripts have the benefit that you can add them to your SCM.

To create a new pipeline script, select New item from the Jenkins sidebar. In the dialog that opens, select the Pipeline option and click OK, as shown in the image below.

The first thing we have to do in the job configuration is to add the GitHub repository that contains the source code. In this example, I am using the packages repo, but the procedure is the same for all the other jobs and repos. Check the GitHub project box and enter the address in the Project url field that appears, as shown in the image below.

After that, we can set up the build triggers for this job. I want this job to start when someone pushes code to the GitHub repo. To do that, we check the box that says GitHub hook trigger for GITScm polling , as shown in the image below. Note that this will only work if you have checked the Manage hooks box in the global settings, as we did earlier.

At the bottom of the job configuration page is the Pipeline 部分。 Here, you have to option to enter the pipeline script directly into the config page. But we want to version control the pipeline script. Therefore, we chose the Pipeline script from SCM 选项。 Make sure that Git is selected, as shown in the image below.

Paste in the URL of your GitHub repository, and select your credentials if it’s a private repo. Ours is public, so we will leave the credentials blank. We will also go with the default master branch selection.

Finally, we have to select the path to the Jenkins script within the Git repository. I have created a file named Jenkinsfile at the root of each repo. Don’t forget to click Save before you leave the page.

Jenkins pipeline scripts

Pipeline scripts follow the same syntax rules as the Apache Groovy programming language, which I must admit I had never heard of before. Nevertheless, you won’t have a hard time understanding pipeline scripts if you’ve done any kind of modern programming. At first glance, it looks like a JSON schema without the commas separating the data items.

The scripts are quite versatile, and there are many options for things like executing stages in parallel or running tasks on multiple Jenkins servers. I suggest that you take a look at the official Jenkins pipeline documentation if you want to dig deeper into the matter.

Fortunately, you don’t need to know everything about them to benefit from pipeline scripts. We will use the format below as a template for all of your scripts. We will add as many stages as we need to split the job into logical steps.

385

If somebody pushes faulty code to the repo, we want the culprit to receive an automated email with information about the failed job. To do that, we use a failure section within a post 部分。 This part of the script will only execute if any of the stages fail. Then, the job will stop. Jenkins won’t go to the next stage if one fails. Instead, it will jump into the failur e section. Jenkins then lifts the email addresses from the latest Git commits and sends them an email with a link to the broken build.

VHDL syntax checking job

The only repo in our design that doesn’t have a testbench is the packages repo—instead, we user our check_syntax.tcl script to verify that the code is at least valid VHDL.

In the first step of our pipeline script, we call deleteDir() 。 That’s one of the basic commands available in Jenkins pipeline scripts. It cleans the working directory by removing any leftover from previous builds.

On the next line, we call git 。 Note that this is not the git Linux command, but a command referencing the git Jenkins plugin. We tell it to clone the repository into the workspace.

Finally, on the third line of the Create project stage, we use the sh keyword to call a Linux shell command. Here, we change to the vivado directory and run the create_vivado_proj.tcl script in Vivado batch mode to recreate the Vivado project.

Jenkinsfile:

391

In the second stage, the one named Check VHDL syntax , the Vivado project already exists, so we can jump to running our Tcl script. We use the shell command again to run the check_syntax.tcl file, which will exit 0 on success, or 1 on error, causing Jenkins to mark the build as a failure.

VHDL simulation jobs

For all other jobs than the packages repo, the git one-liner command won’t work for checking out the code from GitHub. The problem is that these repos have dependencies in the form of submodules. The submodules reference other Git repositories, which the simple git command doesn’t pull by default. But that’s OK; we can fix the issue by using the more versatile checkout call, also well-documented on the Git plugin page.

Jenkinsfile;

404

Finally, we run the run_simulation.tcl script in Vivado in the next stage.

The above listing shows the script used in the bcd_encoder repo. Identical scripts, only with different repo URLs, are used for the counter, digit_selector, output_mux, reset, and seg7_encoder repos as well.

FPGA implementation job

The seg7 repo contains the top module for our FPGA project. It pulls in all of the other repos as submodules. The pipeline script is similar to the one used for the simulation-only jobs, but with four added stages:Run simulation , Run implementation , Generate bitstream , and Release bitfile .

The first two stages create the project and run the simulation. I have already covered how they work in the previous sections of this article. The next three stages work the same way as the simulation stage, but with the Tcl script replaced with the ones that are relevant for the task.

Jenkinsfile:

417

The final stage of the implementation job is named Release bitfile 。 It contains a shell script that copies the newly generated FPGA programming file to a release folder. The shell command renames the file to include the name of the project and a timestamp.

To maintain traceability, we also generate a text file that contains the Git hash of the main repo (seg7 ) and all of the submodules. When working with Git submodules, it’s not enough to store the hash of the main repo. To generate a hash for the main repo that includes changes in all submodules, we would have to commit the main repo after pulling and updating all submodules. We don’t want to do that automatically from Jenkins.

Note that implementing the FPGA for every single push, like I am doing in the example, is probably not what you want for a real-life Jenkins project. It can take hours to build a large-scale FPGA project, and that wouldn’t work when you have a team of developers pushing multiple times per day. Instead of building after each push to the repo, you can configure Jenkins to route the FPGA only once a day. For example, at midnight, as shown by the screenshot below from the job configuration page.

Triggering builds after other jobs complete

Our example project consists of several Git repositories, but they are all tied together as Git submodules. Except for packages, all the other repos depend on at least one other repository. Most depend on the packages repository. Have a look at the dependency graph that I presented earlier in this article to see how it all fits together.

Therefore, we should trigger jobs not only by pushes to the repo in question but also after any of the submodules are touched. We can achieve this in Jenkins by visiting every job and setting the Build after other projects are built option accordingly.

The image below shows the trigger for the bcd_encoder project. It will start after the packages repo, which it depends on, completes a build successfully.

The top module depends on all other repos. I have added them as watch projects in a comma-separated list, as shown in the image below. Note that you may not want to do this for the FPGA implementation job if it takes a long time to route, as I mentioned in the previous section.

Serving the bitfiles using Nginx

Since we already have a web server running, we can use if for serving the release files over HTTP. I want all new bitfiles to appear on the URL jenkins.vhdlwhiz.com/releases 。 Let’s see how we can use Nginx for this.

Our implementation job already copies new bitfiles to a directory on the Nginx HTML root, but we haven’t created it yet. Create the release dir and give the Jenkins user write permissions by issuing the following commands:

421

Then we have to make a change to the /etc/nginx/nginx.conf 文件。 Find the server section in the config file with a name equal to your domain. Add the following location section inside of it, directly below the root (‘/’) location section:

435

Finally, after you have saved the file, test the configuration file, and reload the Nginx server:

444

If everything worked, you should be able to list the content of the release directory, as shown in the screenshot below from Google Chrome.

To tie the Jenkins web interface to the release dir, I want to create a link to if from the Jenkins sidebar. We have already installed the Sidebar Link plugin that enables custom links in the sidebar.

The next step is to go to Manage Jenkins->Configure System and scroll down to the Additional Sidebar Links 部分。 Here, we can specify the name and URL of the new link, as shown in the image below. The link icon field is optional. I reused one of the icons that came with the Jenkins server.

After completing the previous step, you should now have a custom link to the bitfile releases in the sidebar, complete with a nice-looking folder icon, as you can see from the image below.

摘要

Jenkins can be a valuable tool also for FPGA teams. Automating tasks can save your company time and improve the quality of your code. By using automatic build triggers and automated job pipelines, fewer coding errors will go unnoticed.

As we have seen from the example project presented in this article, Jenkins can implement a complete suite of regression tests for your VHDL code. It shows the current health of your project in a pleasant graphical web interface, suitable for even the most VHDL-illiterate project manager.

If you wish to try out Jenkins for FPGA development, I recommend following the steps in this article on an UpCloud VPS instance. I thoroughly researched all VPS providers a few years ago before moving VHDLwhiz to a VPS. I found that UpCloud was the fastest and best alternative. I’m still 100% pleased with the service.

If you decide to open an account on UpCloud, I kindly ask that you use my referral link or code:NV78V6 。 Not only do you support VHDLwhiz, but you also get $25 of credit on UpCloud when using the promo code.


VHDL

  1. 基本 VHDL 测验 - 第 2 部分
  2. 生成语句去抖动器示例
  3. 如何在 VHDL 中使用有符号和无符号
  4. 如何在 VHDL 中创建并发语句
  5. 如何将 Quartus Prime IP 库链接到 VUnit
  6. 如何创建自检测试平台
  7. 如何在 VHDL 中创建 PWM 控制器
  8. 使用 Tcl 的交互式测试平台
  9. 如何在 VHDL 中创建环形缓冲区 FIFO
  10. 记录 - VHDL 示例
  11. 如何使用就绪/有效握手在块 RAM 中创建 AXI FIFO
  12. 信号与 VHDL 中的变量有何不同