FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
登录
首页-所有问题-其他-正文

使用FPGA实现‘动态视觉传感器(DVS)’事件流处理,在硬件上处理异步稀疏事件数据有哪些独特的架构设计思路?

FPGA学号5FPGA学号5
其他
6小时前
0
0
3
我的毕业设计方向是类脑计算,打算用FPGA处理动态视觉传感器(DVS)输出的异步事件流。与传统帧式图像处理不同,事件数据是稀疏、异步的。在FPGA上设计处理架构时,感觉无从下手。请问有哪些针对这种异步稀疏数据流的独特硬件架构设计思路?比如是否需要特殊的FIFO或仲裁机制?如何高效地实现事件驱动的卷积或滤波操作?希望能得到一些启发。
FPGA学号5

FPGA学号5

这家伙真懒,几个字都不愿写!
13600
分享:
数字IC后端面试中,常被问到的‘时钟树综合(CTS)’相关问题有哪些?上一篇
数字IC笔试题中,关于‘异步FIFO’的设计,除了深度和指针计算,通常会考察哪些深度问题?下一篇
回答列表总数:9
  • 数字电路入门者

    数字电路入门者

    你好,我也在做类脑视觉相关的项目,分享一下我的经验。核心思路是抛弃传统的同步、帧式处理架构,拥抱‘事件驱动’和‘无时钟’或‘准异步’的设计。

    首先,数据入口是关键。DVS输出的是(x, y, pol, t)格式的地址事件,数据率变化剧烈。直接用传统同步FIFO可能会在事件爆发时溢出,或在空闲时浪费资源。一种思路是采用‘弹性FIFO’或基于寄存器链的小型缓冲池,配合背压信号(back-pressure)来控制数据流。更激进的做法是采用异步FIFO(使用握手协议,如req/ack),但设计复杂度高,作为毕业设计,我建议先用双缓冲(ping-pong buffer)结合流控信号来平滑数据流。

    对于处理架构,不要想着把事件攒成一帧再做卷积,那样就失去了事件流的低延迟优势。可以考虑‘基于地址映射的累加更新’架构。具体来说:
    1. 在FPGA的Block RAM里维护一个或多个‘表面’(Surface),比如当前时刻的卷积特征图。
    2. 每个到来的事件,根据其坐标(x, y),直接索引到BRAM中对应的一个或多个位置(取决于卷积核大小)。
    3. 根据事件的极性(pol)和可能携带的时间衰减信息,更新这些位置的值(做加法或减法)。这本质上是一个由事件触发的、稀疏的、随机的内存读写操作。
    4. 设计一个高效的仲裁器来处理可能同时到达的多个事件对同一内存区域的访问冲突。简单的轮询(round-robin)或固定优先级可能就够用。

    这样,特征图是随着事件流‘动态演化’的,你可以定期(比如每毫秒)或者当某个区域的累计值超过阈值时,输出一个处理结果,实现真正的异步处理。

    注意事项:这种随机访问模式对BRAM的带宽要求高,如果事件率很高,可以考虑将特征图拆分到多个双端口BRAM中,根据坐标低位进行分区,以并行处理多个事件。另外,时间信息的处理(比如衰减)很重要,需要在更新值时加入时间衰减因子,这可能需要一个全局的时间戳计数器。

    先从一个小型网络(比如一个5x5的滤波)开始验证这个架构,再慢慢扩展。希望对你有所帮助!

    2小时前
  • 硅农预备役2024

    硅农预备役2024

    同学你好,我博士课题就是FPGA上的神经形态视觉处理,分享点实战经验。

    处理DVS事件流,最大的特点是数据稀疏且时间连续,所以架构设计要避免传统图像处理中‘帧同步’和‘全局扫描’的思维。我给你两个具体思路:

    一是‘基于活跃事件列表的架构’。不要把所有像素状态都放在一个静态阵列里每个周期访问。相反,维护一个‘活跃事件列表’(比如用一个小型片上存储器或寄存器堆),只存储最近发生事件的像素地址和相关信息。当新事件到来时,处理器只对这个列表里的事件进行操作(例如进行时间相关性滤波,抑制孤立噪声事件)。这种架构非常节省资源和功耗,因为计算只发生在有事件的地方。实现时,可以用一个CAM(内容可寻地址存储器)或哈希表来快速查找和更新活跃列表。

    二是‘流式时空卷积架构’。对于事件驱动的卷积,比如要做边缘检测,传统卷积核需要周围像素。但事件是稀疏的,你可以预先定义好卷积核的坐标偏移。当一个事件到来时,根据其(x,y)坐标,直接计算出受该事件影响的输出像素位置,并更新那些位置的累加值(考虑事件极性)。这相当于把卷积操作‘推’(push)到输出空间,而不是从输入空间‘拉’(pull)数据。这需要为每个输出像素维护一个累加器阵列(存在分布式RAM或Block RAM中)。这种架构避免了为稀疏输入遍历整个卷积窗口,效率很高。

    关于FIFO和仲裁,如果事件速率很高,可以考虑多级FIFO和动态优先级仲裁。例如,给不同空间区域的事件分配不同优先级(比如中央视野优先级高),或者根据事件的时间戳给予‘新鲜’事件更高优先级。

    最后提醒一个坑:DVS事件可能有噪声,硬件架构里最好集成一个简单的在线滤波模块(比如基于时间-空间邻域的滤波),放在处理前端,否则后续处理会被噪声干扰。

    建议你先用高级综合(HLS)或SystemVerilog快速原型一个简单流水线,再逐步优化。加油!

    3小时前
  • FPGA学习笔记

    FPGA学习笔记

    你好!我也在做类脑视觉的项目,用FPGA处理DVS事件流确实和传统图像处理很不一样。核心思路是‘事件驱动’和‘无时钟域’设计。

    首先,数据接口上,DVS输出通常是AER(地址事件表示)格式,每个事件包含(x, y, polarity)和有效信号。FPGA端可以用一个‘事件接收模块’来解析。这里的关键是,事件是异步到达的,所以输入接口最好用异步FIFO(例如Xilinx的FIFO Generator里选Independent Clocks)来跨时钟域处理,将异步事件同步到你的系统主时钟域。但要注意,事件可能很密集,FIFO深度要足够,否则会丢失事件。

    架构上,一个很直接的思路是‘基于时间戳的流水线’。每个事件打上时间戳(可以用一个全局计数器),然后进入处理流水线。因为事件稀疏,你可以设计多个并行的处理单元(PE),每个PE负责处理一个空间区域(比如一块像素区域)的事件。需要一个仲裁器(比如Round-Robin或基于时间戳优先)把事件分发到对应的PE。PE内部可以实现事件驱动的卷积:不是每个时钟都计算,而是当事件到来时,才去读取周围像素的‘状态’(比如表面正负激活累加值),进行运算并更新状态。状态可以存在Block RAM里,按地址(x,y)索引。

    另外,也可以考虑‘无时钟’或‘握手协议’的设计,用valid/ready信号控制数据流,这样能更自然地匹配异步事件流。但这对设计习惯挑战较大。

    总之,先搭好事件接收和同步的架子,再设计事件分发和事件驱动的处理单元。建议先从简单的滤波(比如表面滤波)开始验证架构。

    3小时前
  • 电子工程学生

    电子工程学生

    同学你好,我也搞过类似的项目,分享一下我们踩过的坑和最终方案。

    最大的挑战确实是“异步”和“稀疏”。我们没用中央大缓存存整帧,而是用了分布式的小缓存,配合内容可寻址存储器(CAM)的思路。

    具体来说,我们设计了一个“活跃事件列表”。当事件到来时,系统不是立刻处理,而是先查询这个列表:看看同一个像素位置有没有还没处理完的旧事件?如果有,可能需要根据时间戳进行合并或抛弃。这个列表用CAM实现,可以快速并行查询所有位置。

    处理卷积或滤波时,传统卷积核是滑动窗口。对于事件流,我们实现了“稀疏卷积”。只有事件发生的坐标,才去读取其周围像素的“状态值”,然后只计算这些受影响点的卷积核权重贡献,更新输出点。这需要精心设计邻居访问的电路,因为事件是乱序来的,你访问周围像素时,它们的状态可能存储在慢速的DRAM里,所以最好有一层片上SRAM做局部状态缓存。

    我们的建议是,先明确你算法层要做什么,是识别还是跟踪?然后反向设计硬件。如果做滤波,可以看看脉冲神经网络(SNN)的硬件实现,很多思路是相通的,比如用积分-发放模型。

    仲裁机制方面,如果多个事件同时到达,简单轮询就行。重点保证处理是确定性的,即相同输入事件流,输出每次都一样,这对调试至关重要。

    4小时前
  • 嵌入式开发小白

    嵌入式开发小白

    毕业设计做这个方向挺有意思的,DVS数据确实和传统图像处理很不一样。核心思路是把“帧驱动”变成“事件驱动”。

    我的一个思路是设计一个“事件路由器”加“处理单元阵列”的架构。事件从传感器进来,带坐标和时间戳。先用一个路由器模块,根据事件的(x, y)坐标,把它路由到对应的处理单元(PE)里。每个PE负责处理固定一片像素区域的事件。

    关键点在于,PE不是一直在运算,而是被事件“唤醒”的。当路由器把一个事件丢给某个PE后,这个PE才启动,读取它本地存储的“状态”(比如之前的滤波结果或神经元膜电位),进行更新计算,算完再把状态存回去,然后休眠。这样功耗会低很多,因为只有有事件的区域才动。

    至于异步FIFO,肯定需要,用来跨时钟域和处理速度不匹配。但更重要的是事件之间的“因果”关系处理,如果后续操作依赖时间顺序,可能需要在时间戳上做文章,比如给事件排序。

    你可以先搭一个简单的仿真模型,用事件流文件做测试,验证路由和唤醒机制是否可行。

    4小时前
  • 硅农养成计划

    硅农养成计划

    同学你好,我也做过类似的FPGA项目。处理异步稀疏流,首先要解决‘数据怎么存和怎么取’的问题。传统帧缓存在这里效率极低。我的经验是,采用‘基于地址的事件映射’加‘时间戳队列’的混合结构。具体来说,用一块Block RAM或UltraRAM作为‘表面存储器’,每个像素地址对应一个存储单元,存放该像素最新的状态(比如激活值)。同时,维护一个按时间戳排序的小型优先队列(可以用堆实现),记录最近活跃的像素地址。当新事件到来,更新对应地址的存储器,并根据操作类型(比如卷积)将地址插入队列。然后,一个处理引擎从队列中取出地址,根据该地址从表面存储器读取数据,并读取其邻居地址的数据进行运算,更新结果再写回。这样,计算只发生在真正有事件的地方。FIFO方面,输入接口用一个简单的异步FIFO缓冲原始事件流即可,后续处理靠上述架构消化稀疏性。注意时间戳的同步和溢出处理。

    5小时前
  • 电子工程学生

    电子工程学生

    毕业设计做这个方向挺有意思的,DVS的数据确实和传统图像处理差别很大。核心思路就是别再用帧驱动的同步思维了,得转向事件驱动的异步架构。一个关键点是设计一个高效的事件路由网络,比如用基于AXI4-Stream的轻量级NoC(片上网络),每个处理单元(PE)作为独立节点。事件包带着坐标和时间戳进来,由路由逻辑根据坐标直接分发到对应的PE,而不是广播给所有人。这样能避免无效操作。对于卷积这类需要邻域信息的操作,可以在事件到达时,只激活其周围局部窗口内的PE,从片上缓存读取邻居的‘状态’(比如累积的脉冲)进行计算更新。FIFO可以用小深度、多通道的异步FIFO来缓冲不同通道的事件,避免拥堵。仲裁的话,如果事件冲突严重,可以按时间戳优先级处理。

    5小时前
  • 逻辑萌新实验室

    逻辑萌新实验室

    哈,我也搞过一阵子DVS在FPGA上的处理,分享一下我的踩坑经验。最大的痛点确实是‘异步’和‘稀疏’。架构设计上,别老想着把事件流攒成一帧再处理,那会丢失所有时间分辨率的优势。我给你一个很实用的思路:流水线+事件激活的计算单元。

    首先,把整个处理流程拆成几个独立的阶段(Stage),比如:事件接收与解析 -> 时间表面更新 -> 特征提取(如卷积)-> 决策输出。每个阶段之间用FIFO连接,但这个FIFO不是普通的FIFO,最好是能支持‘标签’或‘带地址’的数据。因为事件数据包本身很小,如果很多事件涌向同一个后续模块(比如卷积单元),就会堵车。所以,可以在FIFO前加一个分发器(Dispatcher),根据事件的坐标,把事件分发到多个并行的处理通道上,每个通道负责图像的一个区域。这样就把全局的稀疏流,变成了多个局部的、可能更密集的流,并行处理。

    对于卷积滤波的高效实现,如果卷积核不大(比如3x3),完全可以在事件到达时实时计算。你需要维护一个小的、围绕当前事件坐标的上下文窗口。具体实现:用一组寄存器或小型RAM,缓存该事件所在行及其上下几行最近的事件信息。当新事件到来时,更新这个上下文窗口,然后卷积核只在这个窗口有效的区域进行计算(因为很多位置是‘无事件’,值为0,乘法可以跳过)。这能节省大量计算。在硬件描述时,要设计成条件触发的模块,只有事件有效信号到来时,才启动卷积计算逻辑,否则该模块大部分时间处于静态低功耗状态。

    注意事项:时间戳的处理要小心。DVS事件的时间戳精度很高,但在FPGA内部可能不需要那么高的绝对精度,你可以用相对时间或简化的时间表示(比如计数器的计数值),重点是计算事件间的时间间隔。另外,资源利用方面,分布式RAM比Block RAM更适合实现大量像素的独立存储。先搭一个简单的仿真环境,用软件生成模拟事件流来测试你的架构,再上板调试,会顺利很多。

    6小时前
  • Verilog入门者

    Verilog入门者

    毕业设计做这个方向挺有意思的,DVS的数据确实和传统图像处理差别很大。核心思路是把‘帧驱动’变成‘事件驱动’。架构上,我建议先从数据接口和路由入手。DVS输出的是(x, y, timestamp, polarity)格式的事件包,通常是异步串行数据流(如AER协议)。FPGA这边,首先要一个高速串并转换和解析模块,把事件包解析成坐标和极性。关键点在于,后续处理模块不能被动等待,而应该被事件‘触发’。所以,一种经典思路是采用‘基于地址事件的路由网络’。简单说,就是把事件的(x, y)坐标作为地址,直接映射到后续处理单元(比如一个处理单元负责一片像素区域)。这样,事件来了就直接送到对应位置的处理单元,避免了全局的帧缓冲,延迟极低。

    对于卷积或滤波这种需要邻域信息的操作,传统卷积核是滑动窗口遍历整幅图像,这显然不适合稀疏事件。事件驱动的卷积,可以这样做:当一个事件到达某个坐标(x, y)时,才去计算以该坐标为中心的卷积核窗口。但这需要你能快速读取到该事件邻域内、在过去一段时间内发生的其他事件(因为事件是稀疏的,可能邻域内很多位置没有事件)。所以,你需要一个能按地址快速随机访问的‘时间表面’存储器,存储每个像素位置最近一次事件的时间戳(或一段时间内的事件历史)。当新事件触发计算时,从这个存储器里读出邻域像素的时间信息,结合衰减函数(模拟生物神经元膜电位衰减)来计算输出。FPGA上可以用分布式RAM或Block RAM阵列来实现这个‘时间表面’,每个RAM对应一小块像素区域。

    至于FIFO,在事件流入口可能需要一个异步FIFO来跨时钟域处理,但核心处理路径上,要尽量避免大的集中式FIFO造成排队延迟。仲裁机制在多个事件同时到达同一处理单元时可能需要,可以用简单的轮询或固定优先级。建议你先用一个小规模阵列(比如32x32)做原型验证,再逐步扩展。

    6小时前
我要回答answer.notCanPublish
回答被采纳奖励100个积分
FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训
请先登录