FPGA实现呼吸灯效果与逻辑优化

需积分: 47 9 下载量 150 浏览量 更新于2024-07-15 2 收藏 1.22MB DOCX 举报
"EDA呼吸流水灯1.docx" 在本次实验任务中,我们需要设计一个FPGA逻辑,以实现一个呼吸式流水灯效果。这个效果会在DE0实验板上的LED9到LED0之间逐个点亮,并且每个LED的亮度会有明暗变化,模拟呼吸的节奏。该任务分为基本要求和扩展要求。 ### 基本要求 1. **频率设定**:FPGA逻辑应以10Hz的频率驱动LED灯。这意味着每秒周期性的亮暗切换需要发生10次。 2. **呼吸效果**:LED灯在亮起时应有亮度变化,即在亮与灭之间存在过渡,使得视觉上呈现出类似呼吸的柔和效果。 ### 扩展要求 1. **逻辑简化**:在实现基本功能的基础上,尝试通过使用存储器来简化逻辑设计,将LED显示样式预先存储,然后由FPGA读取执行,以此减少逻辑复杂度。 2. **更多样式**:增加更多的LED显示模式,丰富显示效果,提供多样化的视觉体验。 ### 设计过程 设计过程中主要涉及到两个关键模块:**分频器**和**计数器**。 #### 分频器 (FREQUENCY_DIVIDER) 分频器模块用于将系统时钟i_sys_clk进行分频,以得到10Hz的输出时钟o_div_clk。这里的代码使用了一个计数器r_div_count,当计数达到预设值i_div_count_value(即1000000/10=100000,因为1s内有100000个10Hz的周期)时,输出时钟翻转。`posedge`触发器确保在时钟上升沿或复位时更新状态。 ```verilog always @(posedge i_sys_rst or posedge i_sys_clk) begin if (i_sys_rst) begin r_div_count <= 32'd0; o_div_clk <= 1'b0; end else begin if (r_div_count == i_div_count_value) begin r_div_count <= 32'd0; o_div_clk <= ~o_div_clk; end else begin r_div_count <= r_div_count + 32'd1; } end end ``` #### 计数器 (LAMP_COUNTER) 计数器模块负责控制LED的点亮顺序。它接收分频器产生的时钟i_lamp_clk,当计数达到预设值i_cnt_mod_value(比如6,因为有6个LED)时,重置计数值,输出到LED的值o_lamp_val。这样LED就会按照设定的顺序依次亮起。 ```verilog always @(posedge i_sys_rst or posedge i_lamp_clk) begin if (i_sys_rst) begin o_lamp_val <= 6'd0; end else begin if (o_lamp_val == i_cnt_mod_value) begin o_lamp_val <= 6'd0; end else begin o_lamp_val <= o_lamp_val + 6'd1; } end end ``` ### 明暗变化实现 为了实现呼吸效果,可以使用PWM(脉宽调制)技术。PWM可以通过改变高电平的时间比例来调整输出的平均亮度。可以创建一个额外的计数器,其周期比o_div_clk短,根据计数器值与最大值的比例来调整当前LED的亮度,通过PWM信号控制亮度。 ### 存储器优化 扩展要求提到使用存储器保存显示样式,这可能涉及到使用RAM或者ROM来存储不同显示阶段的LED状态。例如,可以创建一个二维数组,其中每一行代表一种显示状态,每一列对应一个LED的亮度值。通过读取存储器中的数据,可以更灵活地控制LED显示样式。 总结来说,这个实验旨在锻炼FPGA设计能力,包括时序逻辑、分频、计数以及利用存储器简化设计。通过完成这个任务,学生不仅可以掌握Verilog语言的基本用法,还能了解FPGA在实现动态显示效果方面的应用。