FPGA实战学习笔记(一):LED流水灯设计
创始人
2024-11-13 02:12:20
0

目录

一、LED硬件原理

二、设计输入

1.端口设计

2.波形图绘制

         3.流水灯代码实现

4.移位操作原理

三、RTL功能仿真

1.RTL原理图

2.仿真测试文件代码

3.仿真结果

三、下载验证

1.分析综合

​2.管脚分配

3.时序约束

4.上板验证

总结


实现了一个流水灯效果,每隔0.5秒 LED 的状态会向左移动一位


一、LED硬件原理

        发光二极管的原理图如图所示, LED0到LED3这4个发光二极管的阴极都连到地( GND)上,阳极分别与FPGA相应的管脚相连。原理图中LED与地之间的电阻起到限流作用。
        即LED0,LED1,LED2,LED3端口对应的FPGA管脚为高电平,则二极管发光。

二、设计输入

1.端口设计

        本次实验需要实现间隔时间为0.5s的4个led流水灯的操作,还有系统复位等操作。间隔时间的控制需要通过计数器来实现计时的功能,需要用到系统时钟。因此,模块的输入端口包含系统时钟sys_clk、复位信号sys_rst_n,输出为包含4bit的LED端口led[3:0]。

2.波形图绘制

        如波形图所示,初始状态给led端口赋值为4’b0001;等待0.5s后,即计数器计数25000000次(板载晶振为50MHz,周期为20ns),给 led 端口赋值为4’b0010;等待0.5s后,给led端口赋值为4’b0100;等待0.5s,给led端口赋值为 4’b1000;再次等待0.5s后,给led端口赋值为4’b0001,后面依次类推,四个LED即可实现流水的效果。

3.流水灯代码实现

根据波形图使用Verilog编写计数器(water_led.v)代码
代码如下:

// 流水灯(时间间隔0.5s) module water_led (     input sys_clk,       // 系统时钟输入     input sys_rst_n,     // 系统复位信号输入     output reg [3:0] led // LED 输出 );  parameter MCNT = 24999999; // 定义计数器最大值,相当于 0.5s 的计数值,20ns * 24999999 = 0.5s reg [24:0] cnt;            // 计数器,d24999999=b0001 0111 1101 0111 1000 0100 0000,25 位宽  // 主要代码 always @(posedge sys_clk or negedge sys_rst_n) begin     if (!sys_rst_n)            cnt <= 25'd0;       // 复位计数器清零     else if (cnt == MCNT)   // 如果计数器达到最大值         cnt <= 25'd0;       // 计数器清零     else         cnt <= cnt + 25'd1; // 计数器加1 end  always @(posedge sys_clk or negedge sys_rst_n) begin     if (!sys_rst_n)            led <= 4'b0001;             // 复位设置LED为初始状态 0001     else if (cnt >= MCNT)           // 如果计数器大于等于最大值         led <= {led[2:0], led[3]};  // 进行左移,更新LED状态为流水灯效果     else         led <= led;  // LED状态保持不变 end  endmodule

4.移位操作原理

        流水的功能适合使用移位的操作,移位操作行代码为:led <= {led[2:0], led[3]},实际上是通过拼接操作来实现向左移位;比如:
        假设LED初始状态为4'b0001,LED[2:0]为低三位001,LED[3]为最高位0,则进行一次移位操作实际上就是拼接位{001,0},led此时状态为4'b0010,实现向左移位;

三、RTL功能仿真

1.RTL原理图

RTL原理图打开步骤:   

RTL视图如下:

      RTL_ADD是加法器,实现计数器的累加操作;
      RTL_MUX是一个选择器,根据cnt是否等于25’b1011111010111100000111111(对应十进制 25’d24999999)的结果,选择输出0或者输出cnt累加的结果;      
      RTL_ROM是一 个存储电路,将cnt和25’d24999999进行对比,并输出对比的结果值;            RTL_REG_ASYNC是异步复位的寄存器,在时钟边沿的触发下,将输入D赋值给输出Q。

2.仿真测试文件代码

代码如下:

`timescale 1ns / 1ns  module tb_water_led(); reg sys_clk     ; reg sys_rst_n   ;  wire [3:0] led  ;  initial begin     sys_clk = 1'b1;     sys_rst_n <= 1'b0;     #201     sys_rst_n <=1'b1; end  always #10 sys_clk = ~sys_clk;// 时钟周期为 20ns,生成时钟信号  water_led  #(.MCNT(24999))//减少仿真时间,将计数器设置为0.5ms water_led_inst(     .sys_clk    (sys_clk)     ,     .sys_rst_n  (sys_rst_n)   ,          .led        (led)     );  endmodule 

3.仿真结果

        仿真波形与之前所绘制的波形图一致,这里为了减少仿真耗时在仿真文件里将间隔时间设置为0.5ms。

四、下载验证

1.分析综合


2.管脚分配

管脚配置完成之后保存约束文件。

管脚参考小梅哥芯路恒XC7A35TFGG484-2开发板引脚进行分配,如下图:

3.时序约束

        对时钟的约束最简单的理解就是,设计者需要告诉EDA工具设计中所使用的时钟的频率是多少;然后工具才能按照所要求的时钟频率去优化布局布线,使设计能够在要求的时钟频率下正常工作。
        本次实验 sys_clk 的时钟频率为50MHz,周期为20ns,在做约束时可以等于这个值或者略低于这个值,不建议周期设置的太小,否则软件在布局布线时很难满足这个要求。
        对于比较简单的设计,即使不对工程做时序约束,可能也不影响最终的功能。但是当设计变得复杂起来,或者输入的时钟频率比较高的时候,如果不添加时序约束,那么就有可能在验证设计结果的时候出现一些意料之外的情况。所以这里推荐大家无论简单或者复杂的实验,都对工程做时序约束。
        (具体参考正点原子开发指南)

        具体操作如下:

4.上板验证

最后经过上图所示步骤生成bit流文件,Open Target,Program Device,实现结果如下所示:

water_led

总结

注意引脚分配很重要,一定要是对应的50MHz晶振的对应管脚,复位的随机选择一个按键引脚。

相关内容

热门资讯

一分钟内幕!科乐吉林麻将系统发... 一分钟内幕!科乐吉林麻将系统发牌规律,福建大玩家确实真的是有挂,技巧教程(有挂ai代打);所有人都在...
一分钟揭秘!微扑克辅助软件(透... 一分钟揭秘!微扑克辅助软件(透视辅助)确实是有挂(2024已更新)(哔哩哔哩);1、用户打开应用后不...
五分钟发现!广东雀神麻雀怎么赢... 五分钟发现!广东雀神麻雀怎么赢,朋朋棋牌都是是真的有挂,高科技教程(有挂方法)1、广东雀神麻雀怎么赢...
每日必看!人皇大厅吗(透明挂)... 每日必看!人皇大厅吗(透明挂)好像存在有挂(2026已更新)(哔哩哔哩);人皇大厅吗辅助器中分为三种...
重大科普!新华棋牌有挂吗(透视... 重大科普!新华棋牌有挂吗(透视)一直是有挂(2021已更新)(哔哩哔哩)1、完成新华棋牌有挂吗的残局...
二分钟内幕!微信小程序途游辅助... 二分钟内幕!微信小程序途游辅助器,掌中乐游戏中心其实存在有挂,微扑克教程(有挂规律)二分钟内幕!微信...
科技揭秘!jj斗地主系统控牌吗... 科技揭秘!jj斗地主系统控牌吗(透视)本来真的是有挂(2025已更新)(哔哩哔哩)1、科技揭秘!jj...
1分钟普及!哈灵麻将攻略小,微... 1分钟普及!哈灵麻将攻略小,微信小程序十三张好像存在有挂,规律教程(有挂技巧)哈灵麻将攻略小是一种具...
9分钟教程!科乐麻将有挂吗,传... 9分钟教程!科乐麻将有挂吗,传送屋高防版辅助(总是存在有挂)1、完成传送屋高防版辅助透视辅助安装,帮...
每日必看教程!兴动游戏辅助器下... 每日必看教程!兴动游戏辅助器下载(辅助)真是真的有挂(2025已更新)(哔哩哔哩)1、打开软件启动之...