英文商城网站,国外优秀个人网站欣赏,吴江开发区人才网,个人网站怎么写目录
前言
一. 设计流程
1.1 需求分析
1.2 方案设计
1.3 PWM解析
二. 实现流程
2.1 确定时间单位和精度
2.2 定义参数和寄存器
2.3 实现计数器逻辑
2.4 控制 LED 状态
三. 整体流程
3.1 全部代码
3.2 代码逻辑
1. 参数定义
2. 分级计数
3. 状态切换
4. LED 输…目录
前言
一. 设计流程
1.1 需求分析
1.2 方案设计
1.3 PWM解析
二. 实现流程
2.1 确定时间单位和精度
2.2 定义参数和寄存器
2.3 实现计数器逻辑
2.4 控制 LED 状态
三. 整体流程
3.1 全部代码
3.2 代码逻辑
1. 参数定义
2. 分级计数
3. 状态切换
4. LED 输出控制
四. 注意事项
五. 本文总结
六. 更多操作 前言
在数字电路设计领域呼吸灯是一个经典且有趣的项目它模拟人类呼吸的节奏使 LED 灯呈现出从暗到亮再从亮到暗的渐变效果常被用于电子产品的状态指示、氛围营造等场景。这里将详细介绍如何使用 Verilog 硬件描述语言实现一个呼吸灯效果并对实现过程中的关键知识点、设计流程、代码逻辑以及注意事项进行深入探讨。 实现的呼吸灯效果渐明渐暗、渐明渐暗循环往复 一. 设计流程
1.1 需求分析 呼吸灯的核心需求是让 LED 灯呈现出类似人类呼吸的渐变效果即亮度从暗到亮再从亮到暗循环变化。为了实现这一效果我们需要通过控制 LED 灯的驱动信号来改变其亮度而在数字电路中通常使用脉冲宽度调制PWM技术来模拟模拟电压从而控制 LED 灯的亮度。
1.2 方案设计 为了实现 PWM 控制我们将采用分级计数的方式来实现不同时间尺度的延时。具体来说我们会设计三个计数器微秒级计数器、毫秒级计数器和秒级计数器。通过这三个计数器的协同工作我们可以精确控制 PWM 信号的占空比从而实现 LED 灯亮度的渐变。
1.3 PWM解析 脉冲宽度调制(PWM)是英文“Pulse Width Modulation”的缩写简称脉宽调制是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术广泛应用在从测量、通信、功率控制等领域中。 二. 实现流程
2.1 确定时间单位和精度
在进行 Verilog 代码编写之前首先要明确时间单位和精度。这一步对于后续处理不同时间尺度的延时至关重要。在本例中我们使用timescale编译指令来声明时间单位和精度。
// 时间尺度声明仿真时间单位为1ns仿真精度为1ps
timescale 1ns / 1ps这里选择 1ns 作为时间单位1ps 作为时间精度意味着在仿真过程中时间的最小步进是 1ps能够满足处理微秒us、毫秒ms等较大时间尺度的需求。这样的设置可以让我们更精确地模拟时间流逝从而实现对呼吸灯渐变效果的精细控制。
2.2 定义参数和寄存器
确定好时间单位和精度后接下来要定义一些关键的参数和寄存器。这些参数和寄存器将用于控制计数器的行为进而影响 LED 灯的状态变化。
// 定义呼吸灯模块模块开始
module breath_led(input clk, // 时钟信号用于同步电路的操作input rst_n, // 复位信号低电平有效用于初始化电路状态output reg led // 输出信号控制LED灯的亮灭);
// 定义参数用于延时计数
parameter us_delay 50; // 定义微秒级延时的计数值
parameter ms_delay 1000; // 定义毫秒级延时的计数值
parameter s_delay 1000; // 定义秒级延时的计数值
// 定义计数器寄存器
reg [5:0] cnt_lus; // 微秒级计数器6位宽最大计数值为63
reg [9:0] cnt_lms; // 毫秒级计数器10位宽最大计数值为1023
reg [9:0] cnt_ls; // 秒级计数器10位宽最大计数值为1023
reg led_en; // LED使能信号用于控制LED的亮灭模式参数部分 us_delay用于设置微秒级延时的计数值。当微秒级计数器cnt_lus达到us_delay - 1时会触发一些操作如毫秒级计数器的递增。ms_delay定义毫秒级延时的计数值。毫秒级计数器cnt_lms达到ms_delay - 1时会影响秒级计数器的状态。s_delay表示秒级延时的计数值。秒级计数器cnt_ls达到s_delay - 1时会引发 LED 使能信号led_en的状态切换。 寄存器部分 cnt_lus微秒级计数器6 位宽其最大计数值为 63。在时钟信号的驱动下它会不断递增用于精确计时微秒级的时间间隔。cnt_lms毫秒级计数器10 位宽最大计数值为 1023。它依赖于微秒级计数器的状态进行递增用于计时毫秒级的时间。cnt_ls秒级计数器同样是 10 位宽最大计数值为 1023。它在微秒级和毫秒级计数器满足特定条件时才会递增用于计时秒级的时间。led_enLED 使能信号用于控制 LED 灯的亮灭模式。通过改变led_en的值可以实现 LED 灯亮度的渐变效果。
2.3 实现计数器逻辑
为了模拟时间的流逝我们需要实现三个层次的计数器微秒计数器、毫秒计数器和秒计数器。每个计数器根据不同的条件进行递增或重置从而实现精确的时间控制。
// 微秒级计数器逻辑
always(posedge clk)beginif(!rst_n) // 如果复位信号有效低电平cnt_lus 0; // 微秒级计数器清零else if(cnt_lus us_delay - 1) // 如果微秒级计数器达到设定的延时值减1cnt_lus 0; // 微秒级计数器清零elsecnt_lus cnt_lus 1; // 微秒级计数器加1
end// 毫秒级计数器逻辑
always(posedge clk)beginif(!rst_n) // 如果复位信号有效低电平cnt_lms 0; // 毫秒级计数器清零else if(cnt_lus us_delay - 1)begin // 当微秒级计数器达到设定的延时值减1if(cnt_lms ms_delay - 1) // 如果毫秒级计数器达到设定的延时值减1cnt_lms 0; // 毫秒级计数器清零elsecnt_lms cnt_lms 1; // 毫秒级计数器加1end// 其他情况保持不变由于时序逻辑不需要写
end// 秒级计数器逻辑
always(posedge clk)beginif(!rst_n) // 如果复位信号有效低电平cnt_ls 0; // 秒级计数器清零else if(cnt_lus us_delay - 1)begin // 当微秒级计数器达到设定的延时值减1if(cnt_lms ms_delay - 1)begin // 当毫秒级计数器达到设定的延时值减1if(cnt_ls s_delay - 1) // 如果秒级计数器达到设定的延时值减1cnt_ls 0; // 秒级计数器清零elsecnt_ls cnt_ls 1; // 秒级计数器加1endend
end微秒级计数器 cnt_lus在每个时钟信号的上升沿首先检查复位信号rst_n是否有效。如果有效将微秒级计数器清零以确保电路在复位时能够恢复到初始状态。如果复位信号无效接着检查计数器是否达到us_delay - 1。若达到该值说明已经完成了一次微秒级的延时将计数器清零重新开始计时若未达到则将计数器加 1继续计时。毫秒级计数器 cnt_lms同样在时钟信号的上升沿进行操作。当复位信号有效时将毫秒级计数器清零。当微秒级计数器达到us_delay - 1时说明已经经过了一个微秒级的时间间隔此时检查毫秒级计数器是否达到ms_delay - 1。若达到则将毫秒级计数器清零开始新的毫秒计时若未达到则将毫秒级计数器加 1。秒级计数器 cnt_ls在时钟上升沿当复位信号有效时秒级计数器清零。只有当微秒级计数器达到us_delay - 1且毫秒级计数器达到ms_delay - 1时才会进一步检查秒级计数器是否达到s_delay - 1。若达到则将秒级计数器清零重新开始秒计时若未达到则将秒级计数器加 1。
通过这三个计数器的协同工作我们可以实现从微秒到毫秒再到秒的精确计时为后续控制 LED 灯的状态变化提供时间基础。
2.4 控制 LED 状态
在完成计数器逻辑的实现后接下来要根据计数器的状态来控制 LED 灯的状态。这里我们通过一个 LED 使能信号led_en来切换 LED 灯的亮灭模式从而实现呼吸灯的渐变效果。
// LED使能信号逻辑
always(posedge clk)beginif(!rst_n) // 如果复位信号有效低电平led_en 0; // LED使能信号清零else if(cnt_lus us_delay - 1 cnt_lms ms_delay - 1 cnt_ls s_delay - 1)// 当微秒级、毫秒级和秒级计数器都达到设定的延时值减1时led_en ~led_en; // 取反LED使能信号
end
// LED输出逻辑
always(posedge clk)beginif(!rst_n) // 如果复位信号有效低电平led 0; // LED输出信号清零else if(led_en 0) // 如果LED使能信号为0// 如果秒级计数器大于毫秒级计数器LED输出高电平否则输出低电平led (cnt_ls cnt_lms)? 1 : 0; else if(led_en 1) // 如果LED使能信号为1// 如果秒级计数器大于毫秒级计数器LED输出低电平否则输出高电平led (cnt_ls cnt_lms)? 0 : 1;
end
//模块结束
endmoduleLED 使能信号逻辑在时钟信号的上升沿首先检查复位信号rst_n。若复位信号有效将 LED 使能信号led_en清零。当微秒级计数器cnt_lus、毫秒级计数器cnt_lms和秒级计数器cnt_ls都达到各自设定的延时值减 1 时说明已经经过了一个完整的计时周期此时将 LED 使能信号取反从而切换 LED 灯的亮灭模式。LED 输出逻辑同样在时钟上升沿进行操作。当复位信号有效时将 LED 输出信号led清零。当 LED 使能信号led_en为 0 时比较秒级计数器cnt_ls和毫秒级计数器cnt_lms的大小。如果cnt_ls cnt_lms则 LED 输出高电平使 LED 灯点亮否则输出低电平使 LED 灯熄灭。当 LED 使能信号led_en为 1 时逻辑相反即cnt_ls cnt_lms时 LED 输出低电平否则输出高电平。
随着时间的推移计数器的值不断变化LED 使能信号也会周期性地切换从而使 LED 灯的亮度呈现出从暗到亮再从亮到暗的渐变效果模拟出呼吸的节奏。 三. 整体流程
3.1 全部代码
// 时间尺度声明仿真时间单位为1ns仿真精度为1ps
timescale 1ns / 1ps// 定义呼吸灯模块
module breath_led(input clk, // 时钟信号用于同步电路的操作input rst_n, // 复位信号低电平有效用于初始化电路状态output reg led // 输出信号控制LED灯的亮灭);// 定义参数用于延时计数
parameter us_delay 50; // 定义微秒级延时的计数值
parameter ms_delay 1000; // 定义毫秒级延时的计数值
parameter s_delay 1000; // 定义秒级延时的计数值// 定义计数器寄存器
reg [5:0] cnt_lus; // 微秒级计数器6位宽最大计数值为63
reg [9:0] cnt_lms; // 毫秒级计数器10位宽最大计数值为1023
reg [9:0] cnt_ls; // 秒级计数器10位宽最大计数值为1023
reg led_en; // LED使能信号用于控制LED的亮灭模式// 微秒级计数器逻辑
always(posedge clk)beginif(!rst_n) // 如果复位信号有效低电平cnt_lus 0; // 微秒级计数器清零else if(cnt_lus us_delay - 1) // 如果微秒级计数器达到设定的延时值减1cnt_lus 0; // 微秒级计数器清零elsecnt_lus cnt_lus 1; // 微秒级计数器加1
end// 毫秒级计数器逻辑
always(posedge clk)beginif(!rst_n) // 如果复位信号有效低电平cnt_lms 0; // 毫秒级计数器清零else if(cnt_lus us_delay - 1)begin // 当微秒级计数器达到设定的延时值减1if(cnt_lms ms_delay - 1) // 如果毫秒级计数器达到设定的延时值减1cnt_lms 0; // 毫秒级计数器清零elsecnt_lms cnt_lms 1; // 毫秒级计数器加1end// 其他情况保持不变由于时序逻辑不需要写
end// 秒级计数器逻辑
always(posedge clk)beginif(!rst_n) // 如果复位信号有效低电平cnt_ls 0; // 秒级计数器清零else if(cnt_lus us_delay - 1)begin // 当微秒级计数器达到设定的延时值减1if(cnt_lms ms_delay - 1)begin // 当毫秒级计数器达到设定的延时值减1if(cnt_ls s_delay - 1) // 如果秒级计数器达到设定的延时值减1cnt_ls 0; // 秒级计数器清零elsecnt_ls cnt_ls 1; // 秒级计数器加1endend
end// LED使能信号逻辑
always(posedge clk)beginif(!rst_n) // 如果复位信号有效低电平led_en 0; // LED使能信号清零else if(cnt_lus us_delay - 1 cnt_lms ms_delay - 1 cnt_ls s_delay - 1)// 当微秒级、毫秒级和秒级计数器都达到设定的延时值减1时led_en ~led_en; // 取反LED使能信号
end// LED输出逻辑
always(posedge clk)beginif(!rst_n) // 如果复位信号有效低电平led 0; // LED输出信号清零else if(led_en 0) // 如果LED使能信号为0led (cnt_ls cnt_lms)? 1 : 0; // 如果秒级计数器大于毫秒级计数器LED输出高电平否则输出低电平else if(led_en 1) // 如果LED使能信号为1led (cnt_ls cnt_lms)? 0 : 1; // 如果秒级计数器大于毫秒级计数器LED输出低电平否则输出高电平
endendmodule
3.2 代码逻辑
1. 参数定义
us_delay微秒级延时计数值用于控制微秒级计数器重置条件。ms_delay毫秒级延时计数值用于控制毫秒级计数器重置条件。s_delay秒级延时计数值用于控制秒级计数器重置条件。
2. 分级计数
微秒级cnt_lus时钟上升沿复位信号 rst_n 有效则清零否则计到 us_delay - 1 清零未到则加 1。毫秒级cnt_lms时钟上升沿复位有效则清零cnt_lus 到 us_delay - 1 时计到 ms_delay - 1 清零未到则加 1。秒级cnt_ls时钟上升沿复位有效则清零cnt_lus 到 us_delay - 1 且 cnt_lms 到 ms_delay - 1 时计到 s_delay - 1 清零未到则加 1。
3. 状态切换
led_en 控制 LED 亮灭模式。三个计数器均达延时值led_en 取反依其值比较 cnt_ls 与 cnt_lms 控制 led 输出。
4. LED 输出控制
led_en 为 0cnt_ls cnt_lms 时 led 高电平反之低电平。led_en 为 1逻辑相反。 随时间推进cnt_ls 与 cnt_lms 大小关系变化使 LED 呈呼吸渐变效果。 四. 注意事项
参数设置代码中的参数 us_delay、ms_delay 和 s_delay 决定了呼吸灯渐变的速度。若参数设置不合理可能导致呼吸灯渐变速度过快或过慢甚至因计数值过大造成资源占用过多或仿真时间过长。例如若 us_delay、ms_delay 和 s_delay 设置过小呼吸灯渐变过程会极快人眼难以察觉反之设置过大则渐变过程缓慢影响用户体验。时钟频率代码依赖输入的时钟信号 clk 进行同步操作。时钟频率不合适会影响呼吸灯效果。若时钟频率过高计数器计数速度快呼吸灯渐变过程难以察觉若时钟频率过低呼吸灯渐变过程慢甚至可能出现闪烁不连贯的情况。因此实际设计中需根据具体需求和硬件条件选择合适的时钟频率。硬件实现若将代码烧录到实际硬件中需考虑硬件特性和限制。如硬件驱动能力、LED 灯特性等都可能影响呼吸灯实际效果。若硬件驱动能力不足可能无法正常驱动 LED 灯若 LED 灯响应速度慢也可能无法实现理想的渐变效果。进行硬件实现时需对硬件充分测试和调试确保呼吸灯正常工作。 五. 本文总结
通过本文的分享记录我们详细了解了如何使用 Verilog 硬件描述语言实现一个呼吸灯涵盖了相关时间单位知识、设计流程、代码逻辑以及注意事项。呼吸灯设计不仅是一个有趣的项目还涉及数字电路设计中的许多重要概念如分级计数、状态切换和 PWM 控制等。希望这里能帮助你更好地掌握数字电路设计相关知识和技能。 六. 更多操作
完整FPGA系列请看
FPGA系列文章目录https://blog.csdn.net/weixin_65793170/article/details/144185217?spm1001.2014.3001.5501https://blog.csdn.net/weixin_65793170/article/details/144185217?spm1001.2014.3001.5501