跟着逻辑先生学习FPGA-实战篇第二课 6-2 LED灯流水灯实验

** 硬件平台:征战Pro开发板
软件平台:Vivado2018.3
仿真软件:Modelsim10.6d
文本编译器:Notepad++**

征战Pro开发板资料
链接:https://pan.baidu.com/s/1AIcnaGBpNLgFT8GG1yC-cA?pwd=x3u8
提取码:x3u8

1 知识背景

我们在《LED 灯闪烁实验》中对 LED 灯作了详细的介绍,如果大家对这部分内容不是很熟悉的话, 请参考《LED 灯闪烁实验》中的简介部分。

2 实验任务

流水灯是指同一时刻只有一个灯处于点亮状态,其余的 LED 灯处于熄灭状态,然后每隔一段时间 LED 灯从左往右依次点亮,从而形成流水灯的效果。实验我们将实现 8 个 LED 灯依次点亮,每 100ms 点亮 1 个灯。

3 硬件设计

3.1 原理图分析

八个 LED 灯均连接到了 FPGA 的 IO。当 FPGA 输出 LED0~LED7 为高电平时,发光二极管的正负极有电压差,便会产生电流流过发光二极管,从而点亮 LED 灯;当 FPGA 输出 LED0~LED7 为低电平时,发光二极管正负级没有电压差,也不会产生电流,LED 灯熄灭。
在这里插入图片描述
图6-2- 1 发光二极管原理图

3.2 管脚映射表

表6-2- 1 管脚映射表
在这里插入图片描述
在这里插入图片描述
同学们可能会好奇,为什么原理图中的网络名不和程序中的信号名一致呢?这是因为一般有两个原因:
1. 在公司里面,设计硬件的工程师和设计软件的工程师并不是同一个人,每个人的命名习惯不同,所以就会命名不一样的情况。
2. 硬件上的器件功能和软件上的功能并不一样。比如我们的按键 SW1 ,在硬件上它就是一个按键,但是在软件设计中,我们可以认为它是复位管脚,也可以认为它是控制管脚,所以原理图中的网络名和程序中的信号名没办法统一。
这种情况是很常见的,只要同学们掌握了原理,这个命名随便怎么变我们都知道如何去约束 FPGA 管脚。

3.3 编写 XDC 约束文件

在这里插入图片描述

4 程序设计

4.1 模块框图

八个灯流水的间隔时间为 100ms,间隔时间的控制需要通过计数器来实现,即通过计数器来实现计时的功能,因此本次实验需要用到系统时钟;除此之外,系统复位在 FPGA 系统中也是必不可少的,当程序出现跑飞等异常情况时,可以使程序恢复至默认状态;由以上分析可知,本次实验需要两个输入的端口,分别为系统时钟和系统复位,输出为 8 位的 LED 端口,模块框图如下图所示:
在这里插入图片描述
图6-2- 2模块框图与端口

4.2 设计思路

在硬件设计部分中我们介绍过,当 IO 输出高电平 1 时,点亮 LED 灯;当 IO 输出低电平 0 时, LED灯熄灭,因此要想控制 LED3 到 LED10 实现流水灯效果,第一次的时候给 led 端口赋值为 8’b00000001;等待 0.1s 后,给 led 端口赋值为 8’b00000010; 等待 0.1s 后,给 led 端口赋值为 8’b00000100;等待 0.1s,给 led 端口赋值为 8’b00001000;再次等待 0.1s 后,给 led 端口赋值为 8’b00010000,后面依次类推,八个 LED 即可实现流水的效果。
LED 灯流水的间隔为 0.1s,因此接下来还需要做一个 0.1s 的延时,延时的功能可以通过计数器实现,每当计数器计时到 0.1s 后,切换一次 LED 灯的显示状态即可。当计时完成后,开始控制 LED 灯的状态。
LED 共八种状态:
8’b00000001:对应 LED3 点亮,其它熄灭;
8’b00000010:对应 LED4 点亮,其它熄灭;
8’b00000100:对应 LED5 点亮,其它熄灭;
8’b00001000:对应 LED6 点亮,其它熄灭;
8’b00010000:对应 LED7 点亮,其它熄灭;
8’b00100000:对应 LED8 点亮,其它熄灭;
8’b01000000:对应 LED9 点亮,其它熄灭;
8’b10000000:对应 LED10 点亮,其它熄灭;
从上面我们得知,总共8个状态,那不用状态机来实现,岂不是对不起这 8 种状态。
由此绘制出 led_flow 模块的波形图如下图所示:

在这里插入图片描述
图6-2- 3 led_flow模块波形图

系统时钟 clk 的时钟周期为 20ns(对应开发板板载的晶振频率为 50Mhz),计数器计时 0.1s 需要0.1s/20ns = 100000000ns/20ns = 5000000 个时钟周期,由于计数器是从 0 开始计数,所以计数器最大计数到 25000000-1。

4.3 代码编写

限于篇幅,仅贴出部份代码(详见 Source 文件夹下led_flow.v文件)
定义模块端口,代码如下所示:

在这里插入图片描述
代码中使用了状态机,定义了九种状态,如下所示:
在这里插入图片描述
通过判断计数器cnt计数值到达最大值进行状态跳转,依次为:IDLE–>S0–>S1–>S2–>S3–>S4–>S5–>S6–>S7–>S0–>S1…,代码如下所示:
在这里插入图片描述
当状态机设计好以后,就可以根据不同状态给 led 端口赋值,代码如下所示:
在这里插入图片描述

5 仿真验证

对 RTL 代码进行仿真之前,我们首先需要编写实验对应的仿真文件(TestBench)。 TestBench 是用于验证功能模块的设计是否符合预期,其内容主要分为以下三个步骤:
1、 向被测功能模块的输入接口添加激励
2、 对被测功能模块的顶层接口进行信号例化
3、 判断被测功能模块的输出是否满足设计预期

5.1 led流水灯模块(led_flow)仿真验证

5.1.1 仿真激励代码编写

流水灯模块的输入端口为系统时钟 clk 和系统复位 rst_n,输出端口为 led。 clk 对应开发板所板载的 50MHz 的晶振,周期为 20ns,所以 TB 模块产生 clk 时,可以控制该信号每隔 10ns 翻转一次。而系统复位信号对应输入的复位按键,按键在未按下时为高电平,按下后为低电平,所以 TB 模块可以将 rst_n 初始状态赋值为 0,使程序处于复位状态,在延时一段时间后拉高 rst_n 来结束复位。在正常运行之前,先使程序处于一段时间的复位状态,是为了给流水灯模块里的相关信号赋初始值。
TB 模块产生的系统时钟和复位信号通过例化被测模块,将信号传递至被测模块中。
由于在上一章我们已经把仿真脚本写好了,这一章我们只用将 Sim 这个文件夹拷贝到我们当前课程文件夹中,文件结构如下所示:

在这里插入图片描述
图6-2- 4 工程结构

打开Sim文件夹,将“tb_led_shark.v”文件改为“tb_led_flow.v”,然后使用“Notepad++”工具打开“tb_led_flow.v”文件,就可以开始编写仿真代码了。
在这里插入图片描述

程序中第一行代码定义的仿真单位和仿真精度都是 1ns,对应程序中第 15 行代码表示延时 200ns。程序中第 20 行代码用于产生系统时钟, clk 每隔 10ns 翻转一次,一个完整的时钟周期包含一个高电平和一个低电平,因此系统时钟为 20ns,对应系统时钟频率为 50MHz。
需要注意的是,由于流水灯模块定义的流水间隔较长,为 0.1s,虽然 0.1s 从时间上来说比较短暂,但是对于仿真来说,仿真 0.1s 需要的时间较长。尤其是对于复杂的程序来说,有时候仿真几十毫秒,就需要好几个小时,因此为了降低仿真的等待时间和提升效率,一般需要对程序中延时较长的参数在仿真代码中进行重定义,如仿真代码第 23 行将led_flow 模块中的TIME_0S1进行重新定义赋值。

5.1.2 批处理仿真

仿真代码编写好,就可以使用批处理仿真了,在该章节我们可以不用再更改 modelsim.bat 文件。sim.do 文件也仅仅只用修改一处地方,如下图所示:

在这里插入图片描述
此处改为我们当前的仿真代码模块名:tb_led_flow,改好以后,保存。
双击modelsim.bat,我们就不管了,先喝茶,等软件自已跑(具体步骤参考前一章节),细心的读者会发现,modelsim界面报错了,如下图所示:
在这里插入图片描述
图6-2- 5 Modelsim报错信息

报错提示clk在wave.do不能被发现,这是因为我们的wave.do文件还是上一章节的波形,所以此处报错我们不用理会。当我们保存波形文件再运行 sim.do 文件就不会再报该错误了。

5.1.3 仿真波形分析

我们将led_flow模块的信号加入波形窗口,并将波形文件保存,运行sim.do指令(具体步骤参考《6-1 LED灯闪烁实验》),仿真出的波形如下图所示:

在这里插入图片描述
图6-2- 6 led_flow模块仿真波形
在这里插入图片描述
图6-2- 7 led_flow模块仿真波形(局部放大)

由图可知,状态机(curr_st)跳转正确,led 赋值正确;由图可知,状态机在 cnt 等于 9 时跳转,波形和预期相符。

6 综合编译

在前面我们已经将Source里面的源码(led_flow.v)和约束文件(pin.xdc)通过notepad++软件编辑好了,并且通过Modelsim进行了功能仿真,接下来我们新建Vivado工程并生成bit文件。具体步骤见《6-1 LED灯闪烁实验》章节,此处不再赘述。

7 下载验证

具体步骤见《6-1 LED灯闪烁实验》章节,此处不再赘述。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/944852.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【已解决】Latex中高亮段内命令(如参考文献引用、图、表格)

速览:解决前后图片对比拟解决的问题问题描述Latex高亮的一般做法段内有命令时候的高亮报错 问题原因 解决方案——在导言区为 \cite 等命令“注册”解决方案简要描述详细解释其他情况 速览:解决前后图片对比 解决前: 解决后: …

CSS中的“display“

简单记录一下,看图理解~(图片来自于MDN Web)

数字图像处理

一 形态学处理 ①二值图像 PS:1(255)代表的是白 0代表的是黑(0就是什么都看不见,就是黑) ②灰度图像 ③彩色图像 ④数学形态学基础:是分析几何形状和结构的数学方法,它建立在…

【项目日记(7)】第三层:页缓存的具体实现(上)

目录 前言1. 页缓存的具体结构2. 页缓存分配内存的全过程3. 页缓存分配内存的代码实现4. 优化代码,并完全脱离malloc5. 总结以及代码拓展 前言 在页缓存这一层中,负责给中心缓存分配大块儿的内存,以及合并前后空闲的内存,这一层为…

Python + 深度学习从 0 到 1(03 / 99)

希望对你有帮助呀!!💜💜 如有更好理解的思路,欢迎大家留言补充 ~ 一起加油叭 💦 欢迎关注、订阅专栏 【深度学习从 0 到 1】谢谢你的支持! ⭐ 神经网络的数据表示 – 张量 你可能对矩阵很熟悉&a…

使用Docker-compose部署SpringCloud项目

docker编写dockfile遇到的问题: 需要在docker-compose.yml文件下执行命令 docker-compose.yml文件格式的问题 1和2处空2格,3处空1格,4为本地配置文件目录,5为docker容器的目录,version为自己安装的docker-compose版本 …

【机器学习】【朴素贝叶斯分类器】从理论到实践:朴素贝叶斯分类器在垃圾短信过滤中的应用

🌟 关于我 🌟 大家好呀!👋 我是一名大三在读学生,目前对人工智能领域充满了浓厚的兴趣,尤其是机器学习、深度学习和自然语言处理这些酷炫的技术!🤖💻 平时我喜欢动手做实…

Tonghttpserver6.0.1.3 使用整理(by lqw)

文章目录 1.声明2.关于单机版控制台和集中管理控制台3.单机版控制台3.1安装,启动和查看授权信息3.2一些常见的使用问题(单机控制台)3.3之前使用的是nginx,现在要配nginx.conf上的配置,在THS上如何配置3.4如何配置密码过…

BUUCTF Pwn ciscn_2019_es_2 WP

1.下载 checksec 用IDA32打开 定位main函数 发现了个假的后门函数: 看看vul函数: 使用read读取 想到栈溢出 但是只有48个 只能覆盖EBP和返回地址 长度不够构造 所以使用栈迁移: 栈迁移需要用到leave ret 使用ROPgadget找地址: …

6.若依数据字典

数据字典 维护系统中常见的静态数据,例如:性别、状态等。 好处 不写死在页面上,而是通过数据库来维护,因为如果要修改,则只需要改数据库中的数据即可,不用每个地方都修改了。 字典类型的管理 字典数据的…

JVM学习-内存结构(二)

一、堆 1.定义 2.堆内存溢出问题 1.演示 -Xmx设置堆大小 3.堆内存的诊断 3.1介绍 1,2都是命令行工具(可直接在ideal运行时,在底下打开终端,输入命令) 1可以拿到Java进程的进程ID,2 jmap只能查询某一个时…

rust windwos 两个edit框

use winapi::shared::minwindef::LOWORD; use windows::{core::*,Win32::{Foundation::*,Graphics::Gdi::{BeginPaint, EndPaint, PAINTSTRUCT},System::LibraryLoader::GetModuleHandleA,UI::WindowsAndMessaging::*,}, };// 两个全局静态变量,用于保存 Edit 控件的…

PostgreSQL 数据库连接

title: PostgreSQL 数据库连接 date: 2024/12/29 updated: 2024/12/29 author: cmdragon excerpt: PostgreSQL是一款功能强大的开源关系数据库管理系统,在现代应用中广泛应用于数据存储和管理。连接到数据库是与PostgreSQL进行交互的第一步,这一过程涉及到多个方面,包括连…

【服务器项目部署】⭐️将本地项目部署到服务器!

目录 🍸前言 🍻一、服务器选择 🍹 二、服务器环境部署 2.1 java 环境部署 2.2 mysql 环境部署 🍸三、项目部署 3.1 静态页面调整 3.2 服务器端口开放 3.3 项目部署 ​ 🍹四、测试 🍸前言 小伙伴们大家好…

网络层知识点梳理

网络层的作用 实现点到点服务的数据透明传送,具体功能包括寻址和路由选择、连接的建立、保持和终止点等。它提供的服务使传输层不需要了解网络中的数据传输和交换技术 网络层单位是分组网际层协议IP ARP地址解析协议 根据IP地址获取物理地址 RARP反地址解析协议 根据…

Spring Boot教程之四十:使用 Jasypt 加密 Spring Boot 项目中的密码

如何使用 Jasypt 加密 Spring Boot 项目中的密码 在本文中,我们将学习如何加密 Spring Boot 应用程序配置文件(如 application.properties 或 application.yml)中的数据。在这些文件中,我们可以加密用户名、密码等。 您经常会遇到…

windows 上安装nginx , 启停脚本

windows 上安装nginx , 启停脚本 cmd win 查看进程 tasklist /fi "imagename eq nginx.exe" 杀死进程 taskkill -pid 16212 -f 访问 http://127.0.0.1:8081/# 用脚本管理, 创建文件 kill.txt echo off chcp 65001 setlocal enabledel…

【Rust自学】7.5. use关键字 Pt.2 :重导入与换国内镜像源教程

喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 7.5.1. 使用pub use重新导入名称 使用use将路径导入作用域内后。该名称在词作用域内是私有的。 以上一篇文章的代码为例: m…

vulnhub jangow靶机

1.扫描靶机IP arp-scan -l如果扫不到靶机的话根据以下配置 启动时点击第二个 按回车 继续选择第二个 按e进入编辑 删除"recovery nomodeset" 在末尾添加"quiet splash rw init/bin/bash" Ctrlx 启动进入如下界面 passwd修改root密码 重启电脑登录root修…

Redis Java 集成到 Spring Boot

Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 🌱🌱个人主页:奋斗的明志 🌱🌱所属专栏:Redis 📚本系列文章为个人学习笔…