FPGA学习分享--01 led流水灯的实现

这篇具有很好参考价值的文章主要介绍了FPGA学习分享--01 led流水灯的实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


需求
  1. 博宸电子的ZYNQ7020DEV开发板
  2. Vivado 2018.3
  3. 一定的verilog语言基础

一.任务剖析

1.1 实验目的

在1s内实现开发板上四个led灯的轮流闪烁,每个灯亮起0.25s.

1.2原理图及其分析

博主目前学习的是博宸电子的ZYNQ7020DEV开发板,下面是关于本次分享led流水灯的原理图


图1 涉及本次led流水灯的电路
FPGA学习分享--01 led流水灯的实现,fpga开发,学习,fpga

首先,从图1来看,每个led端口都和一个阻值为4.7k的电阻和一个发光二极管相连,并且发光二极管负端接地。要使得led发光,那么就要令发光二极管导通,即led端口应拉高。在编写代码中,当led输入端口输入为“1”时,代表拉高。


图2 涉及本次led流水灯的引脚
FPGA学习分享--01 led流水灯的实现,fpga开发,学习,fpga
开发板上共有六个led灯。LED1,LED2上电即点亮,故不考虑。
对于剩下的四个led灯,其引脚分配如下:

灯号 引脚
LED3 Y14
LED4 AA13
LED5 AB14
LED6 AB15

清楚了上述背景知识,接下来我们就可以编写代码啦。

二.总代码

2.1 敲写代码

2.1.1 代码内容

module led_stream(
  input			     clk,
  input 		     rst_n,
  
  output reg [3:0]   led       //设置为寄存器类型,否则第二个always模块会报错
  );
 
//定义一个1s的计时器,时钟频率为50MHz
reg [25:0] cnt;

always @(posedge clk or negedge rst_n) begin
		if (!rst_n)
		cnt <= 26'd0;
		else if(cnt < 26'd5000_0000)
		cnt <= cnt + 1'b1;
		else cnt <= 26'd0;
end

//通过计时器控制led交替闪烁,1s内闪烁4个灯	
always @(cnt) begin
		if(cnt<26'd1250_0000) led <= 4'b0001;
		if(cnt<26'd2500_0000 && cnt >= 26'd1250_0000) led <= 4'b0010;
		if(cnt<26'd3750_0000 && cnt >= 26'd2500_0000) led <= 4'b0100;
		if(cnt<26'd5000_0000 && cnt >= 26'd3750_0000) led <= 4'b1000;
end

endmodule

2.1.2 代码分析

  1. 时间:
    开发板内部自带有一个50M赫兹的晶振,即系统时钟clk为50M赫兹,也就是1s内时钟clk有50*10的6次方个上升沿。为了能够实现计时1s(实验目的),所以需要定义一个计数器cnt。时钟clk每达到一次上升沿,计数器cnt计数一次。所以当计数器cnt等于50000000(50M)时,时间等于1s。
    0.25s也就是50000000(50M)的四分之一,即12500000.

  2. 计数:
    当系统复位时,cnt赋值为0,准备开始计数计时。
    clk每上升一次,cnt的数值加一。
    当cnt值等于50M时,cnt赋值为0,重新开始计数。

always @(posedge clk or negedge rst_n) begin
		if (!rst_n)
		cnt <= 26'd0;
		else if(cnt < 26'd5000_0000)
		cnt <= cnt + 1'b1;
		else cnt <= 26'd0;
end
  1. 点亮:
    本实验先令LED3亮起0.25s,再让LED4亮起0.25s,随后是LED5,最后是LED6。 所以:
    当cnt的值处于0~12500000时,LED3端口赋值1,其余端口赋值为0.
    当cnt的值处于12500000~25000000时,LED4端口赋值1,其余端口赋值为0.
    当cnt的值处于25000000~37500000时,LED5端口赋值1,其余端口赋值为0.
    当cnt的值处于37500000~5000000时,LED6端口赋值1,其余端口赋值为0.
always @(cnt) begin
		if(cnt<26'd1250_0000) led <= 4'b0001;
		if(cnt<26'd2500_0000 && cnt >= 26'd1250_0000) led <= 4'b0010;
		if(cnt<26'd3750_0000 && cnt >= 26'd2500_0000) led <= 4'b0100;
		if(cnt<26'd5000_0000 && cnt >= 26'd3750_0000) led <= 4'b1000;
end

  1. module:
    定义两个输入:clk,rst-n。
    定义一个的输出:reg [3:0] led
    因为有四个led灯,所以led应该有四位,即[3:0],从3数到0
    并且led在always语句进行赋值,所以应该是reg寄存器类型
module led_stream(
  input			     clk,
  input 		     rst_n,
  
  output reg [3:0]   led       //设置为寄存器类型,否则第二个always模块会报错
  );

2.2 引脚与电压分配

  1. 方式一

FPGA学习分享--01 led流水灯的实现,fpga开发,学习,fpga
按照上图箭头所指的四个部分,依次完成分配。最终结果应与上图一致。

  1. 方式二
    点任选两个个方框中任意一个,左键点击FPGA学习分享--01 led流水灯的实现,fpga开发,学习,fpga
    选择第一项,加入一个新的约束文档FPGA学习分享--01 led流水灯的实现,fpga开发,学习,fpga
    进行命名,这里与项目名保持一致
    FPGA学习分享--01 led流水灯的实现,fpga开发,学习,fpga
    点击方框,直到看见xdc文件,在右侧屏幕进行手动引脚即电压分配
    FPGA学习分享--01 led流水灯的实现,fpga开发,学习,fpga
    这里为了大家编写方便,我将代码复制到下边了
set_property PACKAGE_PIN Y14 [get_ports {led[0]}]
set_property PACKAGE_PIN AA13 [get_ports {led[1]}]
set_property PACKAGE_PIN AB14 [get_ports {led[2]}]
set_property PACKAGE_PIN AB15 [get_ports {led[3]}]
set_property PACKAGE_PIN W17 [get_ports clk]
set_property PACKAGE_PIN V4 [get_ports rst_n]

set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}]

当然大家也不必担心,代码这么多自己该如何编写。它的格式都很固定,只需要根据引脚及电压更改一些参数而已。并且,当你采用方式一进行引脚分配后,Vivado会自动为你生成你的分配代码。

三. 仿真

因为有的同学手上可能没有板子,不过没有关系,Vivado上自带有仿真系统,为了让大家不受板子限制,博主在此也是做出了本次实验的相应仿真部分,供大家参考。仿真所涉及到的知识点会在以后详细讲解,这里大家先看看最后效果就好。

3.1 建立仿真

老样子,二选一
FPGA学习分享--01 led流水灯的实现,fpga开发,学习,fpga
按照图片,选择第三个,建立仿真文件,下一步
FPGA学习分享--01 led流水灯的实现,fpga开发,学习,fpga
命名,这里多加入一个tb下划线,用来警醒自己这应该作为头部文件
FPGA学习分享--01 led流水灯的实现,fpga开发,学习,fpga
然后就可以开始编写代码啦
FPGA学习分享--01 led流水灯的实现,fpga开发,学习,fpga

3.2 仿真代码

大家直接复制粘贴到代码编写区域即可

`timescale 1ns / 1ps   

module tb_led_stream();

reg         sys_clk;       
reg         sys_rst_n;    

wire  [3:0] led;
              
initial begin         //初始化                        
	sys_clk = 1'b0;
	sys_rst_n = 1'b0;
	#1 sys_rst_n = 1'b1;
end 

always #10 sys_clk = ~sys_clk;    //定义一个50M赫兹的时钟

led_stream u_led_stream(      //例化
.clk                  (sys_clk),        
.rst_n                (sys_rst_n),      

.led                  (led)   
);

endmodule

然后点击下图


FPGA学习分享--01 led流水灯的实现,fpga开发,学习,fpga


进行仿真,仿真结果如下:
FPGA学习分享--01 led流水灯的实现,fpga开发,学习,fpga
可以看见,每隔0.25s(250ms)不同的led灯依次点亮,满足实验要求。所以本次实验成功!

四.知识点

4.1 Verilog语法

  1. 时序always模块
    此模块的代码框架基本如下:
always @(posedge clk or negedge rst_n) begin
		if (!rst_n) begin
		//初始化你的参数
		end
		else 
		//编写代码逻辑
end

并且大多数采用阻塞赋值,即“<=”

  1. 电平always模块
    此模块的代码框架基本如下:
always @(*) begin
		//代码逻辑部分	
end

并且大多数采用非阻塞赋值,即“=”文章来源地址https://www.toymoban.com/news/detail-767606.html

  1. 数值的定义
    对寄存器类型的变量而言,其赋值需要根据参数的位数进行。
reg [4:0] num;   //5位,所以num最大是 2*2*2*2*2 - 1 = 31
num = 5'd30;     //十进制d下赋值30;
num = 5'b01011;   //二进制b下赋值01011;

//同理,还有八进制,十六进制赋值,但最大不能超过十进制下的31;

到了这里,关于FPGA学习分享--01 led流水灯的实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 5.2 FPGA:基于verilog的LED流水灯设计(多种方法)

    目录 设计目标:8个LED灯以每0.5s的速率进行循环闪烁 方法1:移位法实现 设计模块 仿真代码 实验结果  方法2:循环移位方法  设计模块 方法3:使用三八译码器实现流水灯 顶层模块 底层模块 当仿真时时间长,可以减小设计代码的计数次数,对分析移位功能没有影响。 设计

    2024年02月06日
    浏览(44)
  • 【LabVIEW FPGA图形化】 ngc、edf网表文件的编写:LED流水灯

    【LabVIEW FPGA图形化】 ngc、edf网表文件的编写:LED流水灯 FPGA图形化可以提高FPGA的开发效率,为产品迭代、功能机验证,产品参数调试提供的便捷的编程方式。LabVIEW作为一款图形化开发软件可以为FPGA提供零代码开发,图形化界面可以非常直观的展示出FPGA的并行结构。LabVIEW的开

    2023年04月27日
    浏览(45)
  • 51单片机学习--LED流水灯

    延时代码可通过软件生成,系统频率要和开发板的晶振频率相对应。  

    2024年02月16日
    浏览(55)
  • ARM入门(实现LED流水灯)超简单

            实现效果将LDE2到LED5依次点亮再依次熄灭。点亮LED灯就像我们接触编程语言的第一天输出一个\\\"hello world\\\"一样,这是一个最基础的入门操作。这里我们以点亮LED2的过程进行详细讲解,因其他LED灯的点亮过程都是一样的,所以就不做一一介绍了。 1、首先第一步我们需

    2023年04月10日
    浏览(49)
  • FPGA学习——点亮流水灯

    在FPGA开发板中,一般板载LED默认高电平点亮,因此我们只需要将想要亮起的LED赋值为1即可。 本入门实验要求为每隔1s开发板上的LED轮流亮起,因此我们需要一个1s的计数器, 由于开发板晶振时钟为50MHz,因此我们计数50_000_000即为1s。 注意:为了后续方便仿真所以这里MAX设置

    2024年02月13日
    浏览(48)
  • STM32——led灯的点亮+闪烁+流水灯的实现

    1.原理 其方式有两种一种是寄存器方式一种是库函数方式,但其原理都是一样的。如原理图所示,与LED相连接的IO口置低电平即可点亮led灯 2.寄存器方式–代码 3.库函数–代码 (1)led.c:函数led_config() (2)main.c调用led_config 4.结果展示 原理:让连接的IO口先置零再置1可以使其先亮

    2024年02月08日
    浏览(57)
  • 【STM32】STM32学习笔记-LED闪烁 LED流水灯 蜂鸣器(06-2)

    电路图示例1 电路图示例2 main.c 接线图如下图所示: 点击下载,现象为LED闪烁。 main.c main.c stm32F103工程模板 01-LED闪烁.rar 02-LED流水灯.rar 03-蜂鸣器示例程序.rar 参考: 【STM32】江科大STM32学习笔记汇总

    2024年03月19日
    浏览(59)
  • (STM32基础)STM32实现LED闪烁&LED流水灯&蜂鸣器

    1、按照新建工程步骤创建工程,新建start、library、user三个文件夹,从固件库添加相应文件 2、keilkil小程序用来清理listings和objects文件夹中编译产生的中间文件,以后需要打包工程的话可以先用keilkill先清理,这样文件夹会大大缩小所占内存。 在library中可以查看外设函数库,

    2024年02月07日
    浏览(58)
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯

      前言:感谢您的关注哦,我会持续更新编程相关知识,愿您在这里有所收获。如果有任何问题,欢迎沟通交流!期待与您在学习编程的道路上共同进步。       目录 一.  延时函数的生成  1.通过延时计算器得到延时函数  2.可赋值改变的延时函数  二.  LED模块编写原理 

    2024年02月19日
    浏览(47)
  • 单片机Proteus软件仿真一(手把手教你实现LED流水灯)

    1 单片机8051系列 爬虫是不能发了,审核总是不通过,算了,发点其他的。 51单片机是对兼容英特尔8051指令系统的单片机的统称。51单片机广泛应用于家用电器、汽车、工业测控、通信设备中。因为51单片机的指令系统、内部结构相对简单,所以国内许多高校用其进行单片机入

    2024年02月01日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包