FPGA-流水灯

Quartus中使用Verilog实现

根据之前所学内容,打开Quartus 软件,新建FPGA项目文件,建立好空项目过后,选择Verilog HDL File,因为我们要使用Verilog代码实现仿真。

详细操作可参考往期博客:

FPGA 实验报告:四位全加器与三八译码器仿真实现_quartus 四位二进制全加器-CSDN博客

然后输入以下代码:

代码展示

module led_flow #(parameter TIME_1S = 50_000_000)(  input               sys_clk     ,input               sys_rst_n   ,output  reg [5:0]   led         );reg     [25:0]      cnt     ;  wire                add_cnt ;wire                end_cnt ;reg     [2:0]       cnt1;wire                add_cnt1;wire                end_cnt1;// 时间基准计数器模块always @(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n) begincnt <= 26'b0;  // 修改为26位清零endelse if(add_cnt) beginif(end_cnt) begincnt <= 26'b0;  // 26位清零endelse begincnt <= cnt+1'b1;endendelse begincnt <= cnt;endend// LED状态计数器模块always @(posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)begincnt1 <= 3'b0;endelse if(add_cnt1) beginif(end_cnt1)begincnt1 <= 3'b0;endelse begincnt1 <= cnt1 + 1'b1;endendend// LED控制逻辑模块always @(posedge sys_clk or negedge sys_rst_n)beginif(!sys_rst_n)beginled <= 6'b0;  // 6位LED清零endelse begincase (cnt1)3'b000 : led <= 6'b000001;  // 6位LED的点亮顺序3'b001 : led <= 6'b000010;3'b010 : led <= 6'b000100;3'b011 : led <= 6'b001000;3'b100 : led <= 6'b010000;3'b101 : led <= 6'b100000;3'b110 : led <= 6'b000001;  // 循环回到第一个LEDdefault: led <= led;endcaseendend// 信号赋值模块assign add_cnt = 1'b1;assign end_cnt = add_cnt && cnt == TIME_1S - 1;  // 1秒的时间基准assign add_cnt1 = (cnt == TIME_1S-1);  assign end_cnt1 = add_cnt1 && cnt1 == 3'b110;  // 6个LED的状态计数器最大值endmodule

模块讲解

在上述代码中共有四个显著的模块,分别为

时间基准计数器模块

这部分实现了一个计数器,用于产生1秒的时间基准。在代码中定义了一个26位的寄存器cnt,用于存储计数值。当系统复位信号sys_rst_n为低电平时,计数器cnt被清零。

在每个时钟上升沿,如果add_cnt信号有效(始终为高电平),计数器cnt会增加。当计数器cnt达到TIME_1S - 1(即49,999,999)时,end_cnt信号有效,表示1秒的时间基准已到,计数器会清零并重新开始计数。

LED状态计数器模块:

这部分实现了一个计数器,用于控制6个LED的点亮顺序。在代码中定义了一个3位的寄存器cnt1,用于存储LED的状态计数值。

当系统复位信号sys_rst_n为低电平时,计数器cnt1被清零。

在每个时钟上升沿,如果add_cnt1信号有效(当时间基准计数器达到预设值时),计数器cnt1会增加。当计数器cnt1达到6(即3'b110)时,end_cnt1信号有效,表示LED状态计数器已到最大值,计数器会清零并重新开始计数。

LED控制逻辑模块:

这部分实现了控制6个LED灯的点亮顺序。当系统复位信号sys_rst_n为低电平时,所有LED被设置为熄灭状态。

根据LED状态计数器cnt1的值,控制6个LED灯的点亮顺序。使用case语句实现不同状态下的LED点亮模式。

当cnt1为3'b000时,点亮第一个LED(led[0])。

当cnt1为3'b001时,点亮第二个LED(led[1])。

依此类推,直到cnt1为3'b101时,点亮第六个LED(led[5])。

当cnt1为3'b110时,循环回到第一个LED,实现跑马灯效果。

信号赋值模块:

这部分实现了对控制信号进行赋值,用于协调计数器和LED控制逻辑的工作。

dd_cnt:始终为高电平(1'b1),表示时间基准计数器cnt始终在计数。

end_cnt:当时间基准计数器cnt达到TIME_1S - 1(即49,999,999)时,end_cnt信号有效,表示1秒的时间基准已到。

add_cnt1:当时间基准计数器cnt达到TIME_1S - 1时,add_cnt1信号有效,表示需要增加LED状态计数器cnt1的值。

end_cnt1:当LED状态计数器cnt1达到6(即3'b110)时,end_cnt1信号有效,表示LED状态计数器已到最大值,需要清零。

在这里要注意:module led_flow #(......)中,led_flow要和顶层模块名称相同,不然编译会出错。

运行与烧录

完成代码的copy过后,点击保存:

然后选择file文件,右键led.v将其设置为顶层文件;

点击Assignments',选择目录下的Pin Planner进行引脚分配;

随后进行烧录,详细烧录教程可以参考CSDN博客:

Nios实验入门——用Verilog编程方式完成LED流水灯显示并使用串口输出“Hello Nios-II”字符到笔记本电脑_verilog led灯-CSDN博客

运行效果截图:

VScode分模块化实现

vscode下载与汉化

首先下载VScode:code.visualstudio.com

在官网链接下载并成功安装过后,打开软件,根据操作,选择汉化扩展:

扩展下载

随后再下载两个扩展,实现FPGA的Verilog代码;

代码示例

随后根据我们的代码,用模块化设计实现,在这里分为top顶层模块(比如LedBlink.v)、分频模块(fenpin.v)、显示模块(display.v);

1、顶层模块 LedBlink.v

module LedBlink (input sys_clk,      // 系统时钟input sys_rst_n,    // 系统复位信号,低电平有效output reg [5:0] led // 6个LED输出);// 分频模块信号wire clk_1s; // 1秒时钟信号// 实例化分频模块fenpin #(.TIME_1S(50_000_000)) u_fenpin (.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.clk_out(clk_1s));// 实例化显示模块display u_display (.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.clk_1s(clk_1s),.led(led));endmodule

2、分频模块 fenpin.v

module fenpin #(parameter TIME_1S = 50_000_000 // 1秒的时间基准,假设系统时钟为50MHz)(input sys_clk,      // 系统时钟input sys_rst_n,    // 系统复位信号,低电平有效output reg clk_out  // 分频后的1秒时钟信号);reg [25:0] cnt; // 计数器,用于产生1秒的时间基准always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n) begincnt <= 26'b0; // 复位时计数器清零clk_out <= 1'b0; // 分频时钟信号初始化endelse beginif (cnt == TIME_1S - 1) begincnt <= 26'b0; // 计数器达到预设值时清零clk_out <= ~clk_out; // 翻转分频时钟信号endelse begincnt <= cnt + 1'b1; // 计数器加1endendendendmodule

3、显示模块 display.v

module display (input sys_clk,      // 系统时钟input sys_rst_n,    // 系统复位信号,低电平有效input clk_1s,       // 1秒时钟信号output reg [5:0] led // 6个LED输出);reg [2:0] cnt1; // LED状态计数器always @(posedge sys_clk or negedge sys_rst_n) beginif (!sys_rst_n) begincnt1 <= 3'b0; // 复位时计数器清零led <= 6'b0; // LED初始化为熄灭状态endelse if (clk_1s) begin // 在1秒时钟信号的上升沿更新LED状态case (cnt1)3'b000: led <= 6'b000001; // 点亮第一个LED3'b001: led <= 6'b000010; // 点亮第二个LED3'b010: led <= 6'b000100; // 点亮第三个LED3'b011: led <= 6'b001000; // 点亮第四个LED3'b100: led <= 6'b010000; // 点亮第五个LED3'b101: led <= 6'b100000; // 点亮第六个LED3'b110: beginled <= 6'b000001; // 循环回到第一个LEDcnt1 <= 3'b000; // 计数器清零enddefault: led <= led; // 默认情况保持当前状态endcaseif (cnt1 != 3'b110) begincnt1 <= cnt1 + 1'b1; // 计数器加1endendendendmodule

  分模块化设计能降低复杂度,让每个模块功能明确且简单,同时提高代码可读性和维护性,便于团队协作和后期功能扩展。它还能增强代码复用性,减少重复开发,通过清晰的模块接口和职责划分,使系统更灵活、更易调试和升级,从而提升整体设计质量和开发效率。

实验结果

fpga流水灯视频

总结与思考

  本次实验让我对FPGA开发有了更深入的理解和实践,不仅掌握了Verilog HDL编程的基本技巧,还学会了如何运用模块化设计思想将复杂系统分解为功能明确的模块,从而降低开发难度并提高代码的可维护性和复用性。在实验中遇到的问题,如顶层模块名称不匹配、信号连接错误以及时钟分频不准确等,通过仔细检查和逻辑分析得以解决,这个过程显著提升了我的问题解决能力。展望未来,我将继续深入学习FPGA的高级功能,探索其与物联网技术的结合点,并积极参与实际项目和竞赛,以积累更多经验,为未来的职业发展打下坚实基础。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React19源码系列之createRoot的执行流程是怎么的?

2024年12月5日&#xff0c;react发布了react19版本。后面一段时间都将学习它的源码&#xff0c;并着手记录。 react官网&#xff1a;react19新特性 https://react.dev/blog/2024/12/05/react-19 在用vite创建react项目的使用&#xff0c;main.tsx主文件都会有以下代码。 //i…

全网首创/纯Qt/C++实现国标GB28181服务/实时视频/云台控制/预置位/录像回放和下载/事件订阅/语音对讲

一、前言说明 用纯Qt来实现这个GB28181的想法很久了&#xff0c;具体可以追溯到2014年&#xff0c;一晃十年都过去了&#xff0c;总算是整体的框架和逻辑都打通了&#xff0c;总归还是杂七杂八的事情多&#xff0c;无法静下心来研究具体的协议&#xff0c;最开始初步了解协议后…

Qt 实操记录:打造自己的“ QQ 音乐播放器”

目录 一.界面设计1.成品界面分析2.head界面实现3.body界面实现4.主界面设置(1).设置无标题栏与阴影效果(2).重写鼠标事件实现拖拽 二.自定义控件1.BtFrom界面设计2.推荐页面设计3.recBox页面设计4.recBoxItem页面设计(1).eventFilter介绍和使用(2).QJsonObject介绍和使用(3).向…

如何打造安全稳定的亚马逊采购测评自养号下单系统?

在当今的电商领域&#xff0c;亚马逊作为全球领先的在线购物平台&#xff0c;其商品种类繁多&#xff0c;用户基数庞大&#xff0c;成为了众多商家和消费者的首选。而对于一些需要进行商品测评或市场调研的用户来说&#xff0c;拥有一个稳定、安全的亚马逊账号体系显得尤为重要…

Python文字识别OCR

一.引言 文字识别&#xff0c;也称为光学字符识别&#xff08;Optical Character Recognition, OCR&#xff09;&#xff0c;是一种将不同形式的文档&#xff08;如扫描的纸质文档、PDF文件或数字相机拍摄的图片&#xff09;中的文字转换成可编辑和可搜索的数据的技术。随着技…

如何在 Github 上获得 1000 star?

作为程序员&#xff0c;Github 是第一个绕不开的网站。我们每天都在上面享受着开源带来的便利&#xff0c;我相信很多同学也想自己做一个开源项目&#xff0c;从而获得大家的关注。然而&#xff0c;理想很丰满&#xff0c;现实却是开发了很久的项目仍然无人问津。 最近&#x…

汽车机械钥匙升级一键启动的优点

汽车机械钥匙升级一键启动的优点主要包括&#xff1a; 便捷性&#xff1a;一键启动功能的引入极大地提升了用车便捷性。车主无需翻找钥匙&#xff0c;只需在车辆感应范围内轻触启动键&#xff0c;即可轻松发动汽车。 安全性&#xff1a;移动管家专车专用一键启动系统配备了防…

[QT]深入理解Qt中的信号与槽机制

文章目录 信号与槽1. 信号和槽概述信号的本质槽的本质说明 2. 信号和槽的使用2.1 连接信号和槽2.2 查看内置信号和槽2.3 通过 Qt Creator 生成信号槽代码 3. 自定义信号和槽3.1 基本语法3.2 带参数的信号和槽**示例1&#xff1a;重载信号槽****示例2&#xff1a;信号槽参数列表…

Axure设计之下拉多选框制作教程C(中继器)

利用Axure制作下拉多选器组件可以极大地提升原型制作的效率和效果。以下是基于你提供的详细步骤的详细指导&#xff0c;帮助你在Axure中实现一个功能完善、高保真且可复用的下拉多选器组件。 一、案例预览 预览地址&#xff1a;https://pghy0i.axshare.com 实现效果包括&#…

STC89C52单片机学习——第25节: [11-1]蜂鸣器

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难&#xff0c;但我还是想去做&#xff01; 本文写于&#xff1a;2025.03.18 51单片机学习——第25节: [11-1]蜂鸣器 前言开发板说明引用解答和科普一、蜂鸣器…

Linux上的`i2c-tools`工具集的详细介绍;并利用它操作IMX6ULL的I2C控制器进而控制芯片AP3216C读取光照值和距离值

IC-Tools 工具集介绍 i2c-tools 是 Linux 下用于 IC 设备调试 的用户空间工具集(你也可以把它看成是一个库&#xff0c;类似于之前自己用过的触摸屏库tslib库、FreeType矢量字符库)&#xff0c;它提供了一系列命令行工具&#xff0c;可以扫描、读取、写入 IC 设备&#xff0c;…

《CircleCI:CircleCI:解锁软件开发持续集成(CI)和持续部署(CD)高效密码》:此文为AI自动生成

《CircleCI&#xff1a;CircleCI&#xff1a;解锁软件开发持续集成&#xff08;CI&#xff09;和持续部署&#xff08;CD&#xff09;高效密码》&#xff1a;此文为AI自动生成 一、CircleCI 初印象 在当今软件开发的快节奏赛道上&#xff0c;持续集成&#xff08;CI&#xff0…

LinuX---Shell脚本创建和执行

概述&#xff1a; 它是一个命令行解释器&#xff0c;接收应用程序/用户命令&#xff0c;然后调用操作系统内核。 Shell还是一个功能强大的编程语言&#xff0c;易编写、易调试、灵活性强。 Linux提供的Shell解析器有 atguiguubuntu:~$ cat /etc/shells # /etc/shells: valid …

再学:Solidity数据类型

目录 1.uint&#xff1a;无符号整型 2.引用类型 3.数组 4.注意gas的消耗 ​编辑 5.映射 1.uint&#xff1a;无符号整型 注意能容纳的最大值和最小值 2.引用类型 值类型赋值 相当于 拷贝 若拷贝开销过大&#xff0c;可以考虑引用类型。 memory&#xff1a;只存在于函数内部…

Docker Desktop配置国内镜像源教程

在使用 Docker 时&#xff0c;由于默认镜像源在国外&#xff0c;经常会遇到下载速度慢、连接超时等问题。本文将详细介绍如何在 Windows 系统中为 Docker 配置国内镜像源&#xff0c;以提升镜像拉取速度。 常用国内镜像源 https://docker.1ms.run清华镜像源 https://docker.m…

C#中SerialPort 的使用

最近在学习C#的SerialPort &#xff0c;关于SerialPort 的使用&#xff0c;做如下总结&#xff1a; 1.可以通过函数System.IO.Ports.SerialPort.GetPortNames() 将获得系统所有的串口名称。C#代码如下&#xff1a; string[] sPorts SerialPort.GetPortNames(); foreach(stri…

深度学习 Deep Learning 第2章 线性代数

深度学习 第2章 线性代数 线性代数是深度学习的语言。 张量操作是神经网络计算的基石&#xff0c;矩阵乘法是前向传播的核心&#xff0c;范数约束模型复杂度&#xff0c;而生成空间理论揭示模型表达能力的本质。 本章介绍线性代数的基本内容&#xff0c;为进一步学习深度学习做…

EDID读取学习

简介 Video BIOS可以被认为是一个具有独立硬件抽象层的操作系统。它不会阻止或监视操作系统、应用程序或设备驱动程序对硬件的直接访问。虽然不推荐,但一些DOS应用程序确实可以改变基本的硬件设置,而根本不需要通过视频BIOS。大多数现代应用程序和操作系统都避免直接使用硬件…

基于SpringBoot的在线拍卖系统

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…

Android audio(8)-native音频服务的启动与协作(audiopolicyservice和audioflinger)

音频策略的构建 1、概述 2、AudiopolicyService 2.1 任务 2.2 启动流程 2.2.1 加载audio_policy.conf&#xff08;xml&#xff09;配置文件 2.2.2 初始化各种音频流对应的音量调节点 2.2.3 加载audio policy硬件抽象库 2.2.4设置输出设备 ps:audiopatch流程简介 2.2.5打开输出设…