我们组今年电赛准备用安路FPGA做关键词唤醒,现在卡在存储架构上。音频数据从ADC进来要写SD卡,同时又要从SD卡读出来送去做MFCC特征提取,SD卡读写和DDR3缓存之间带宽怎么分配才不互相拖后腿?我看到有人用双缓冲加AXI总线仲裁,但具体到安路国产FPGA的IP核上,不知道有没有现成的方案可以参考?求做过类似项目的同学指点一下,最好能说下大概的FIFO深度和仲裁优先级怎么设置。
2026年了,电赛用国产FPGA做AI语音识别,SD卡存储音频和DDR3缓存之间怎么分配带宽才不卡顿?
5 个回答

先别急着上AXI仲裁,安路自家IP对AXI的支持没那么顺手,很多还要自己包一层。我去年做过类似的,给你个参考做法:ADC进来的音频直接走DMA进DDR3的一片环形缓冲区,SD卡写入也从这个环形区搬,特征读取则用另一块独立的小FIFO从DDR3读。这样SD卡和MFCC读DDR3其实是两条通路,只是DDR3端口要仲裁。优先级上,音频采集写DDR3最高,SD卡写入次之,MFCC特征读取最低,因为特征提取可以等,但音频丢一帧就麻烦。FIFO深度别迷信2KB,得算:48kHz采样、16bit单声道,一帧10ms就是960字节,双缓冲至少得1.9KB,所以2KB确实够,但如果你用32bit宽度的FIFO,那实际深度得按条目数算,别搞错单位。SD卡用4线SDIO模式,实测能到10MB/s以上,音频才96KB/s,完全够,瓶颈大概率在DDR3仲裁上。我建议你先做个简单的分时复用:一个状态机轮询三个申请源,每个源最多占用固定周期数,比如音频写8个周期、SD写4个、特征读2个,这样轮下来最差延迟也就14个周期,不会卡顿。另外安路的IP里有个DDR3控制器自带多端口功能的话就直接用,没有就自己写个简单仲裁器,别搞太复杂。如果只是想先跑通,甚至可以SD卡写作废,先只做DDR3缓存和特征提取,验证算法再补存储。你们用的是安路哪款芯片?如果是EG4系列,DDR3控制器有些隐藏坑,比如刷新优先级设置不对会导致偶发卡顿,这个得留意。

双缓冲加简单轮询仲裁就够了,别迷信AXI,安路那套IP用起来费劲。FIFO深度2KB起步,音频优先级最高,特征读取放最后。先跑通再优化,卡顿大多是SD卡驱动没写好,不是带宽问题。你用的哪款芯片?

这个问题的本质不是带宽不够,而是你混淆了「实时性」和「吞吐量」两个概念。音频采集到SD卡,要求的是持续写入不丢数,这是实时性;从SD卡读回来做MFCC,要求的是平均延迟可接受,偶尔慢一点没关系。DDR3带宽按你这种应用,48kHz×2字节=96KB/s的音频流,加上MFCC特征帧,就算特征提取要读原始数据10倍量,也才1MB/s级别,而DDR3随便跑个几百MB/s,带宽根本用不完。真正会卡的是仲裁逻辑写得不合理,比如某个申请源长期占用总线,导致音频DMA超时。我建议你放弃AXI总线的想法,直接写一个简单的固定优先级仲裁器:音频写DDR3永远是最高优先级,因为这是硬实时;SD卡写入次之,因为它有FIFO缓冲可以容忍短暂等待;MFCC特征读取最低,因为你可以让它读慢点,甚至读失败重试。关键在于FIFO深度的计算要基于最坏情况下的突发延迟,而不是平均带宽。比如音频DMA每10ms产生一次写请求,需要一次写入960字节,如果仲裁器最坏要等100us才轮到它,那FIFO得能缓存这段时间的数据,即96KB/s×100us=9.6字节,加上双缓冲余量,2KB绰绰有余。但如果你把特征读取也做成高优先级,或者仲裁器有bug导致某些情况下长时间抢不到总线,那FIFO再深也没用。另外SD卡写操作有擦写周期,4线模式虽然吞吐高,但写命令发出后可能要等几百us才完成,这期间如果卡住仲裁器,就会影响音频。我的做法是给SD卡写入配一个独立的小FIFO,比如512字节,让SD卡驱动自己从这个FIFO取数据,而不是直接申请DDR3总线,这样SD卡写入的慢节奏就被隔离了。至于安路的IP核,你去看EG4系列的用户手册,DDR3控制器有个multi-port选项,开启后自带仲裁,但优先级是固定的,好像音频这种高实时性需求不一定能满足,所以我还是建议自己写。最后给你个学习路径:先写一个极简的轮询仲裁器跑通,测出实际延迟和吞吐,再用逻辑分析仪抓DDR3端口利用率,如果利用率低于20%就别纠结优化了,大概率是别的地方卡。你们打算用SD卡存多久的音频?如果是长时间连续录音,还得考虑文件系统写入的块对齐问题,这个也容易造成周期性卡顿。

先对齐一下你的场景:ADC 采音频是硬实时,MFCC 特征读取是软实时,SD 卡存储其实是两者之间的缓冲层。按我去年做类似题目的经验,你先别把 SD 卡读写和 DDR3 缓存当成两个对等的带宽竞争者,它们其实是上下游关系——音频从 ADC 进 DDR3 环形缓冲,然后由 SD 卡 DMA 从这个缓冲搬走;MFCC 读的是 SD 卡里的文件,但经过 DDR3 做一次缓存,避免每次特征提取都直接打 SD 卡。这样 DDR3 的仲裁端口其实只有两个请求方:音频采集写、特征读取读,SD 卡读写只是 DDR3 的间接使用者。优先级上音频采集写永远最高,因为它丢了没法补;特征读取次之,因为它可以容忍几十毫秒延迟。FIFO 深度我建议按帧算:48kHz 采样、16bit 单声道,一帧 10ms 就是 960 字节,双缓冲至少 1920 字节,所以 2KB 是下限。但注意安路 IP 的 FIFO 深度参数通常按条目数填,如果数据位宽是 32bit,那 2KB 要写成 512 条目,别直接填 2048。关于 AXI 仲裁,安路自家的 IP 对 AXI 支持确实不顺手,常见做法是写一个简单的固定优先级仲裁器,音频写通道永远 grant,特征读通道在音频空闲时 grant,用两个独立 FIFO 做跨时钟域缓冲就行。SD 卡用 4 线 SDIO 模式实测能到 10MB/s 以上,音频流才 96KB/s,所以真正的瓶颈不在带宽,而在你 SD 卡驱动的写命令间隔和擦除块对齐。建议你先跑通最简单的音频进 DDR3 再落 SD 卡,同时单独测 SD 卡读文件到 DDR3 的速率,两个通路分开验证都达标了,再合到一起看仲裁。你用的安路具体哪个型号?不同系列的 DMA 控制器和内存控制器接口差异挺大的。

其实不用想那么复杂,音频写 DDR3 优先级最高,特征读取放最低,SD 卡用 4 线模式,FIFO 2KB 双缓冲起步,先跑通再说。卡顿八成是 SD 卡驱动没写好,不是带宽问题。你们用的安路哪款片子?
发表回答
登录后可在本页底部提交回答