当前位置: 首页 > news >正文

别只写计数器了!用紫光PGL50H实现流水灯的三种Verilog写法对比(状态机/移位/计数器)

别只写计数器了!用紫光PGL50H实现流水灯的三种Verilog写法对比(状态机/移位/计数器)

在FPGA开发中,流水灯实验就像编程界的"Hello World",但大多数教程止步于基础计数器实现。本文将带您突破常规,在紫光同创PGL50H平台上,用状态机、移位寄存器和传统计数器三种方法实现同样的流水灯效果,并深入分析每种方法的工程价值。

1. 实验环境与需求分析

紫光同创PGL50H采用40nm工艺,配备4路HSST高速收发器,核心板集成DDR3和Flash存储器。我们的目标是通过8个LED实现以下流水效果:

  • 每个LED点亮持续时间:0.5秒
  • 流水方向:从左到右循环
  • 时钟频率:50MHz(周期20ns)

传统计数器实现简单,但在复杂模式变更时显得笨拙。我们引入状态机和移位寄存器方案,对比三种方法的实际表现:

实现方式代码复杂度可扩展性时序性能资源占用
传统计数器★★☆★☆☆★★★★★★
移位寄存器★★☆★★☆★★★★★☆
状态机(FSM)★☆☆★★★★★☆★★☆

2. 传统计数器实现方案

最基础的实现方式使用25位计数器控制LED状态切换:

module led_counter( input clk_50m, input rst_n, output reg [7:0] led ); reg [24:0] counter; always @(posedge clk_50m or negedge rst_n) begin if(!rst_n) begin counter <= 25'd0; led <= 8'b0000_0001; end else if(counter == 25'd24_999_999) begin counter <= 25'd0; led <= {led[6:0], led[7]}; // 循环左移 end else begin counter <= counter + 1'b1; end end endmodule

关键点分析

  • 计数器位宽计算:0.5s/(20ns) = 25,000,000 → 需要25位(2^25=33,554,432)
  • 移位操作使用拼接运算符实现循环效果
  • 资源占用主要是25位计数器和8位寄存器

注意:实际开发中建议使用参数定义时间常量,如parameter DELAY_500MS = 25'd24_999_999

3. 移位寄存器实现方案

利用移位寄存器特性简化状态转移逻辑:

module led_shift( input clk_50m, input rst_n, output reg [7:0] led ); reg [24:0] counter; always @(posedge clk_50m or negedge rst_n) begin if(!rst_n) begin counter <= 25'd0; led <= 8'b0000_0001; end else begin counter <= (counter == 25'd24_999_999) ? 25'd0 : counter + 1'b1; if(counter == 25'd0) // 仅在计时满时移位 led <= {led[0], led[7:1]}; // 循环右移 end end endmodule

优化技巧

  1. 移位方向可通过修改拼接顺序灵活调整
  2. 初始模式可扩展为多模式:
    // 初始化时可选择不同模式 parameter INIT_PATTERN = 8'b0000_0001; initial led = INIT_PATTERN;
  3. 移位操作消耗的逻辑资源比计数器少

4. 状态机(FSM)实现方案

使用有限状态机实现更复杂的控制逻辑:

module led_fsm( input clk_50m, input rst_n, output reg [7:0] led ); reg [24:0] counter; typedef enum { S_LED0, S_LED1, S_LED2, S_LED3, S_LED4, S_LED5, S_LED6, S_LED7 } state_t; state_t current_state; always @(posedge clk_50m or negedge rst_n) begin if(!rst_n) begin counter <= 25'd0; current_state <= S_LED0; led <= 8'b0000_0001; end else begin counter <= (counter == 25'd24_999_999) ? 25'd0 : counter + 1'b1; if(counter == 25'd0) begin case(current_state) S_LED0: begin led <= 8'b0000_0010; current_state <= S_LED1; end S_LED1: begin led <= 8'b0000_0100; current_state <= S_LED2; end S_LED2: begin led <= 8'b0000_1000; current_state <= S_LED3; end S_LED3: begin led <= 8'b0001_0000; current_state <= S_LED4; end S_LED4: begin led <= 8'b0010_0000; current_state <= S_LED5; end S_LED5: begin led <= 8'b0100_0000; current_state <= S_LED6; end S_LED6: begin led <= 8'b1000_0000; current_state <= S_LED7; end S_LED7: begin led <= 8'b0000_0001; current_state <= S_LED0; end endcase end end end endmodule

状态机优势

  • 可轻松扩展复杂流水模式(如来回流动、随机模式)
  • 状态转换清晰可见,便于调试
  • 添加新状态不影响原有逻辑

5. 三种方案实测对比

在PGL50H开发板上综合实现后,资源占用对比如下:

实现方案LUT使用量寄存器使用量最大时钟频率
计数器3233150MHz
移位寄存器2833150MHz
状态机4133120MHz

工程选择建议

  • 简单流水效果:优先选择移位寄存器实现
  • 需要模式切换:采用状态机实现更易维护
  • 资源敏感型设计:传统计数器仍具优势

高级技巧:组合使用状态机和移位寄存器可以实现更复杂的效果:

// 在状态机中控制移位方向 case(current_state) S_FORWARD: led <= {led[6:0], 1'b0}; S_BACKWARD: led <= {1'b0, led[7:1]}; endcase

6. 调试与优化实践

在PDS开发环境中调试时,重点关注以下信号:

  1. 计数器溢出信号
    wire counter_overflow = (counter == 25'd24_999_999);
  2. 状态机当前状态(添加调试输出):
    output [2:0] debug_state = current_state;
  3. LED驱动能力检查:
    • 确保IO配置为推挽输出
    • 检查板级LED限流电阻值

常见问题解决

  • LED流水速度异常:检查时钟源是否正确接入
  • 部分LED不亮:验证管脚分配和硬件连接
  • 随机复位:确保复位信号去抖动处理

在PGL50H上实现时,推荐使用PDS工具的时序分析器检查设计是否满足50MHz时钟约束。对于更复杂的流水模式,可以考虑使用查找表(LUT)预存模式序列:

reg [7:0] pattern_table [0:7]; initial begin pattern_table[0] = 8'b0000_0001; pattern_table[1] = 8'b0000_0010; // ...初始化所有模式 end

通过这三种实现方式的对比,我们可以根据项目需求灵活选择最适合的方案。状态机提供了最好的可扩展性,移位寄存器在简单场景下更高效,而传统计数器仍然是快速验证的首选。

http://www.jsqmd.com/news/761959/

相关文章:

  • 【YOLOv11】097、YOLOv11学术研究:如何阅读论文、复现实验与发表工作
  • 如何理解 GPT-Image-2 的“文本生成图片”能力
  • 别再只会用DAC输出直流电压了!手把手教你用STM32CubeMX配置F407生成可调频率三角波
  • AI测试用例生成模板的设计与实践
  • STM32工业级Modbus协议栈:基于HAL与FreeRTOS的完整解决方案
  • 3步掌握量化交易:QuantConnect免费教程完全指南
  • 昆明办公专用眼镜配镜
  • Android驱动开发:聚焦蓝牙、WiFi与NFC技术详解
  • 【尘封 57 年的代码史诗】阿波罗登月程序代码全开源:人类第一次登月,全靠这 14.5 万行汇编代码撑起
  • R 4.5情感分析性能跃迁实录:对比4.4版本提速217%,词向量+BERT微调双路径详解(内部压测报告首曝)
  • DLSS Swapper终极指南:免费游戏性能优化神器
  • MineCursor:为开发者打造个性化光标主题,提升编码体验与效率
  • 扩散模型与流匹配:生成模型的数学本质与工程实践
  • 大模型微调研究
  • 2026年GEO排名优化公司哪家强?五大服务商深度盘点
  • ComfyUI Essentials:填补AI绘画工作流的核心空白
  • 河南彩印编织袋:工农业包装升级的关键选择
  • 2026直连式单螺杆泵推荐榜:轴承架式螺杆泵、进口螺杆泵配件、锂电池专用螺杆泵、食品级螺杆泵、高压螺杆泵、不锈钢螺杆泵选择指南 - 优质品牌商家
  • 构建认知动态AI Agent:解决长任务执行中的状态一致性问题
  • GEC6818开发板串口传感器实战:手把手教你用GY-39和C语言打造环境监测系统
  • 2026蜀绣蜀锦厂家TOP5推荐选购及价格指南:哪里有卖蜀绣蜀锦礼品的、四川蜀绣厂家、四川蜀绣蜀锦礼品、成都蜀绣厂家选择指南 - 优质品牌商家
  • 文档即测试 —— doctest模块
  • 射频工程师的AWR MWO入门:避开学生党常踩的坑,高效完成滤波器与功放仿真
  • Dify动态权限策略配置:支持实时生效、审计留痕、自动熔断的3步上线法
  • Agent Recall:为AI编程助手构建持久记忆系统的架构与实践
  • 15、OpenClaw 自定义插件开发完整指南(2026最新版)
  • 如何在macOS上原生运行Windows程序:Whisky快速入门指南
  • Rebuff框架:构建LLM应用的四层纵深防御体系,有效抵御提示词注入攻击
  • VLANeXt:现代混合云网络架构的12个设计原则
  • 别再死记硬背LLC波形了!用这个仿真工具(Simulink/PSIM)带你动态理解ZVS与谐振过程