紫光盘古FPGA开发板入门与RGB彩灯控制实战

1. 紫光盘古系列2K开发板初探

第一次拿到紫光盘古系列MES2KG开发板时,我注意到它比常见的STM32开发板略大一圈,但布局非常工整。这块板子的核心是紫光同创Compa系列PGC2KG-LPG100 FPGA芯片,属于国产FPGA中性价比极高的入门选择。板载资源包括:

  • 256Mb SDRAM
  • 64Mb SPI Flash
  • 8位拨码开关
  • 4个独立按键
  • 6个用户LED(含RGB彩灯)
  • 40Pin扩展接口

特别值得一提的是板载的RGB彩灯,它通过PWM驱动,可以实现1600万色的显示效果。这个设计在教学中非常实用,我们可以用它来直观演示数字电路的各种概念。

注意:初次使用前建议先检查板载稳压芯片的输出电压,部分批次可能存在3.3V电压偏高的问题,可通过调节板载电位器校准。

2. 开发环境搭建实战

2.1 软件工具链配置

紫光FPGA官方推荐使用PDS(Pango Design Suite)开发环境,最新版本是2023.1。安装时需要注意:

  1. 必须关闭所有杀毒软件(会误删关键组件)
  2. 安装路径不要有中文或空格
  3. 安装完成后需要手动添加license文件

我习惯用VSCode作为辅助编辑器,通过以下配置可以优化Verilog开发体验:

{ "verilog.linting.linter": "iverilog", "verilog.formatting.style": "indent", "files.associations": { "*.v": "verilog" } }

2.2 硬件连接要点

使用Type-C线连接开发板时,Windows设备管理器应该出现两个串口:

  • 一个用于FPGA配置(CP2102)
  • 一个用于调试输出(CH340)

如果只识别到一个,可能需要手动安装CH340驱动。Linux系统下通常能自动识别,但需要将用户加入dialout组:

sudo usermod -a -G dialout $USER

3. 键控彩灯项目实现

3.1 工程创建与引脚约束

在PDS中新建工程时,器件选择PGC2KG-LPG100,速度等级选-6。关键约束文件(.pdc)需要包含以下内容:

# 按键引脚定义 set_pin_assignment {key[0]} {LOCATION=P15; IOSTANDARD=LVCMOS33} set_pin_assignment {key[1]} {LOCATION=P16; IOSTANDARD=LVCMOS33} # RGB LED引脚定义 set_pin_assignment {led_r} {LOCATION=E15; IOSTANDARD=LVCMOS33} set_pin_assignment {led_g} {LOCATION=E16; IOSTANDARD=LVCMOS33} set_pin_assignment {led_b} {LOCATION=D15; IOSTANDARD=LVCMOS33}

3.2 Verilog核心代码解析

以下是带按键消抖的RGB控制器实现:

module rgb_controller( input clk_50m, input [1:0] key, output reg [7:0] r, output reg [7:0] g, output reg [7:0] b ); // 按键消抖模块 reg [19:0] cnt_key; reg [1:0] key_stable; always @(posedge clk_50m) begin if(cnt_key == 20'd999_999) begin cnt_key <= 0; key_stable <= key; end else begin cnt_key <= cnt_key + 1; end end // 颜色状态机 parameter RED = 2'b00, GREEN = 2'b01, BLUE = 2'b10; reg [1:0] state; always @(posedge clk_50m) begin case(state) RED: begin r <= 8'hFF; g <= 0; b <= 0; if(key_stable[0]) state <= GREEN; end GREEN: begin r <= 0; g <= 8'hFF; b <= 0; if(key_stable[0]) state <= BLUE; end BLUE: begin r <= 0; g <= 0; b <= 8'hFF; if(key_stable[0]) state <= RED; end endcase // 亮度调节 if(key_stable[1]) begin r <= r >> 1; g <= g >> 1; b <= b >> 1; end end endmodule

3.3 常见问题排查

  1. LED不亮

    • 检查约束文件是否正确定义
    • 测量引脚电压(应为3.3V)
    • 确认未启用内部上拉电阻
  2. 按键响应异常

    • 调整消抖计数器阈值(20ms左右为宜)
    • 检查按键硬件是否正常(万用表测量通断)
  3. 颜色显示不准

    • RGB LED是共阳接法,PWM占空比与亮度成反比
    • 不同颜色LED的导通电压有差异,可能需要单独校准

4. 进阶功能扩展

4.1 PWM精度提升方案

默认实现使用8位PWM,对于平滑调光可能不够。可以通过以下方式改进:

reg [15:0] pwm_cnt; always @(posedge clk_50m) begin pwm_cnt <= pwm_cnt + 1; end // 12位PWM输出 assign led_r = (pwm_cnt[15:4] < r_extend) ? 1'b1 : 1'b0;

4.2 使用FSMC接口扩展

板载的40Pin接口支持FSMC总线,可以连接LCD等外设。关键信号包括:

  • FSMC_NBL[1:0]:字节使能
  • FSMC_NOE:输出使能
  • FSMC_NWE:写使能
  • FSMC_D[15:0]:数据总线

典型写时序实现:

always @(negedge fsmc_nwe) begin if(!fsmc_ne1) begin case(fsmc_a[10:0]) 11'h000: reg1 <= fsmc_d; 11'h004: reg2 <= fsmc_d; endcase end end

4.3 多周期CPU设计基础

利用开发板可以实践简单的CPU设计。一个最小化的数据通路包含:

  • 指令寄存器(IR)
  • 程序计数器(PC)
  • 算术逻辑单元(ALU)
  • 寄存器文件(RegFile)

典型取指周期实现:

always @(posedge clk) begin if(!reset) begin pc <= 32'h8000_0000; end else if(state == FETCH) begin ir <= imem[pc[15:2]]; pc <= pc + 4; end end

5. 调试技巧与性能优化

5.1 在线逻辑分析仪使用

PDS内置的Logic Analyzer工具非常实用,配置步骤:

  1. 在代码中插入调试信号标记:
(* MARK_DEBUG="true" *) reg [7:0] debug_data;
  1. 生成bitstream时勾选"Enable Debug"
  2. 连接板子后启动在线调试

5.2 时序约束编写要点

关键约束示例:

create_clock -period 20.000 -name clk [get_ports clk_50m] set_input_delay -clock clk 5.0 [get_ports {key[*]}] set_output_delay -clock clk 3.0 [get_ports {led_*}]

5.3 资源优化策略

当资源利用率超过80%时,可以考虑:

  1. 使用块RAM替代分布式RAM
  2. 共享运算符(如多个加法器合并为1个带多路选择的加法器)
  3. 状态机编码优化(如Gray码编码)

6. 项目实战:音乐频谱显示器

结合板载资源,我们可以扩展一个音频可视化项目:

6.1 硬件连接

  • 麦克风模块接ADC输入
  • RGB LED作为频谱显示
  • 按键控制灵敏度和模式

6.2 FFT实现要点

// 蝶形运算单元示例 module butterfly( input [15:0] ar, ai, input [15:0] br, bi, input [15:0] wr, wi, output [15:0] xr, xi, output [15:0] yr, yi ); assign xr = ar + (wr*br - wi*bi)>>>8; assign xi = ai + (wr*bi + wi*br)>>>8; assign yr = ar - (wr*br - wi*bi)>>>8; assign yi = ai - (wr*bi + wi*br)>>>8; endmodule

6.3 性能实测数据

点数时钟频率执行周期
3250MHz320
6450MHz768
12850MHz1792

在实现这个项目时,我发现在计算旋转因子时采用CORDIC算法比查找表节省约30%的LUT资源,但会增加约15%的时钟周期。这种取舍需要根据具体应用场景决定。