紫光FPGA设计:双通道HDMI显示屏实现音频信号,模拟信号ADC采集后FFT频谱图像显示(横...

发布时间:2026/5/27 23:55:34

紫光FPGA设计:双通道HDMI显示屏实现音频信号,模拟信号ADC采集后FFT频谱图像显示(横... 紫光FPGA设计双通道HDMI显示屏实现音频信号模拟信号ADC采集后FFT频谱图像显示横屏、双通道、色彩可调 双通道频谱显示可以支持显示音频处理前的音频频谱和音频处理后的音频频谱实现处理前后频谱效果可视化对比 本demo基于紫光同创PGL50H开发板设计分辨率1024×768可做国产FPGA学习、集创赛、嵌入式设计竞赛紫光同创杯备赛、模拟信号ADC采集后FFT快速傅里叶变换音频降噪滤波算法处理方面等使用集创赛紫光同创杯往年海选刷掉一堆空喊“国产FPGAFFT”的不是FFT IP调用错数据流就是HDMI画面抖成马赛克更别说横屏双通道色彩可调还要实时对比前后降噪的那种。上周啃了三天PGL50H的手册和官方ADCHDMI基础demo改出了这个跑通1024×76860Hz横屏音频输入接个耳机孔原始ADC左半屏爆蓝色条滤波后的滚降粉色随便切颜色换对比方式连实验室室友路过都凑过来问能不能给他们练琴看频谱——顺便说句练琴切竖屏更好但题目要横屏就不管这个了。先给硬件配个单PGL50H板卡是官方送的备赛练习板自带两块DAC和一块AD7606不对不对我这块mini简化版是PCM1863双路音频ADC和ADV7511 HDMI TX——刚好凑题目要的双通道音频采集PCM1863这货是个傻瓜集成ADC不用外接复杂的I2S解码电阻直接连I2C调增益和采样率就行。我采样率设的48kHzFFT点数用了1024刚好对应频谱从0到24kHz的范围人耳敏感的20Hz-20kHz完全覆盖。来掏掏PCM1863配置的I2C小代码——紫光的ISE Suite里的I2C Master IP比Xilinx的快上手多了不用写复杂的状态机分支新手状态机真的容易绕晕漏count直接丢指令数组就行。这段数组是我抠手册抠出来的先复位再设采样率48kHz再开双路采样增益都拉到6dBparameter [15:0] PCM1863_I2C_INSTR[0:7] { 16h001E, // 软复位寄存器写0x1E复位 16h0101, // 寄存器1选I2C从设备模式0x01采样模式自动 16h02C3, // 寄存器2采样率48kHz主时钟取外部PCM1863自己的晶振不对不对我取的PGL50H的24MHz板载时钟分频给ADV7511的同时给PCM1863的MCLK这里要对应手册的MCLK256*Fs刚好24MHz/520≈46kHz哦凑数凑过了改成512分频24MHz/51246.875kHzPCM1863的自动采样率检测能抓这个没问题 16h0300, // 通道1输入是单端线输入接开发板的LINE IN1 16h0400, // 通道2输入也是单端线输入LINE IN2——等下我这里通道2其实是通道1处理后的对哦题目要双通道对比所以我实际只用了LINE IN1的原始数据通道2在ADC层设成了通道1的镜像但在数字逻辑层用滤波IP把镜像给换了这样硬件只需要一根线插耳机方便 16h0506, // 通道1增益6dB 16h0606, // 通道2原始镜像暂时增益6dB 16h0700 // 结束寄存器 };指令数组里的地址和数据要注意PCM1863的I2C是先写8位寄存器地址再写8位数据合起来16位刚好存成数组。然后ISE Suite的I2C Master IP选“burst write”模式每个时钟推一个16位的指令推完7条不算软复位后的空等软复位要等20ms对吧新手容易漏这个我一开始漏了PCM1863一直输出0数据示波器抓I2C也没反应后来翻开发板配套的测试例程才发现有个计数器等复位。接下来是核心的FFT部分——紫光官方有免费的FFT IP叫“TGFFT”不用找license直接在IP Catalog里搜就行。新手最容易踩的坑是IP的数据流接口Xilinx的FFT有时候是AXI-Stream带tlast和tvalid同步但TGFFT是带“start”“busy”“done”三个握手信号输入是实部虚部分开的16位输出也是16位实部虚部还要自己算模长。紫光FPGA设计双通道HDMI显示屏实现音频信号模拟信号ADC采集后FFT频谱图像显示横屏、双通道、色彩可调 双通道频谱显示可以支持显示音频处理前的音频频谱和音频处理后的音频频谱实现处理前后频谱效果可视化对比 本demo基于紫光同创PGL50H开发板设计分辨率1024×768可做国产FPGA学习、集创赛、嵌入式设计竞赛紫光同创杯备赛、模拟信号ADC采集后FFT快速傅里叶变换音频降噪滤波算法处理方面等使用我PCM1863输出的是16位单端有符号整数PCM数据小端大端这里又抠了半天手册PCM1863的I2S输出是MSB在前对应FPGA的I2S接收IP的MSB在前模式所以直接把单端数据当实部虚部补0就行。模长计算我简化了用了“高位截取近似”因为16位FFT输出的模长是√(实²虚²)但开方IP在FPGA里太占资源而且横屏的频谱条只需要0到511的高度因为PGL50H这块HDMI demo的基础是扫线纵轴留了下面50行显示标题上面718行不对1024×768纵轴0到767我设了纵轴50-650是频谱区域总共600行实部虚部平方和的高位截取到10位刚好对应0-1023再除以1.7就差不多到600简单粗暴占的资源只有两个乘法器和一个加法器比开方省多了。// 简化模长计算高位截取近似 wire [31:0] re_sq {{16{re[15]}}, re} * {{16{re[15]}}, re}; // 实部平方补符号位防溢出 wire [31:0] im_sq {{16{im[15]}}, im} * {{16{im[15]}}, im}; // 虚部平方 wire [32:0] sq_sum re_sq im_sq; // 平方和 wire [9:0] approx_mag sq_sum[31:22]; // 截取平方和的第31到22位刚好10位约等于√(sq_sum)误差不大看不出来然后是滤波部分题目提了“音频降噪滤波算法处理”紫光也有免费的FIR滤波器IP对吧叫“TG_FIR”系数可以用MATLAB生成——这个真的比手写FIR状态机快100倍我生成的是一个低通滤波器截止频率2kHz专门滤掉实验室空调和电脑风扇的低频噪音室友练琴刚好是中高频这个滤波器挺实用。FIR系数设成32阶16位有符号整数MATLAB代码贴一下% 生成32阶低通FIR滤波器系数截止频率2kHz采样率46.875kHz Fs 46875; Fc 2000; N 32; b fir1(N, Fc/(Fs/2), low); % 把系数转换成16位有符号整数Q15格式 b_q15 round(b * 2^15); % 输出到coe文件方便ISE Suite的TG_FIR IP导入 fid fopen(lowpass_32tap_2khz.coe, w); fprintf(fid, radix 10;\n); fprintf(fid, coefdata \n); fprintf(fid, %d,\n, b_q15(1:end-1)); fprintf(fid, %d;\n, b_q15(end)); fclose(fid);FIR IP的握手信号和FFT差不多也是“start”“busy”“done”输入是16位单端PCM数据输出也是16位滤波后的PCM数据刚好可以直接喂给第二个FFT IP——没错我用了两个完全一样的TG_FFT IP一个处理原始数据一个处理滤波后的并行跑这样左右半屏的频谱条是完全同步的不会有延迟对比效果特别明显。最后是HDMI显示部分——这个我直接用了PGL50H官方的1024×76860Hz扫线demo稍微改了改显存和扫线逻辑。显存我用了两块BRAM一块存左半屏原始频谱的高度每个频率点对应10位高度512个频率点因为FFT是1024点对称的只取前512就行一块存右半屏滤波后的高度。扫线逻辑部分当扫到纵轴50-650、横轴0-511的时候就去读左半屏的BRAM如果当前扫线的y坐标比高度小就输出蓝色扫到横轴513-1023的时候去读右半屏的BRAMy坐标小就输出粉色其他地方输出黑色背景下面50行用简单的点阵字符输出“PGL50H 原始FFT左 滤波FFT右 48kHz 1024点”——点阵字符是我自己用画图软件画的然后存成coe文件导入到ROM里新手也可以找现成的。色彩可调部分我加了两个拨码开关SW0-SW1调左半屏的颜色SW2-SW3调右半屏的颜色有蓝、绿、红、粉四种拨码开关是PGL50H板载的不用外接硬件直接读IO口就行// 色彩可调逻辑 reg [2:0] color_left, color_right; always (*) begin case (SW[1:0]) 2b00: color_left 3b100; // 蓝色 2b01: color_left 3b010; // 绿色 2b10: color_left 3b001; // 红色 2b11: color_left 3b101; // 粉色 endcase case (SW[3:2]) 2b00: color_right 3b101; // 默认粉色 // 其他颜色同上 endcase end整个工程做完大概占了PGL50H的20%左右的逻辑单元两个FFT IP占了大部分乘法器剩下的还有很多资源可以加别的功能比如加个触摸按键切换对比方式左右并列改成上下重叠半透明加个SD卡存频谱图这些都是集创赛加分项。对了新手一定要注意PGL50H的ISE Suite版本要用官方提供的14.7紫光定制版别用普通的Xilinx 14.7不然很多IP找不到时序约束也会有问题。还有时序约束文件官方demo里有现成的直接复制过来改改引脚就行——引脚定义在PGL50H的用户手册里附录A有详细的表格别插错LINE IN的接口

相关新闻