基于RISC-V内核的生理信号加速SoC及FPGA的原型设计#第八届立创电赛#
随着瑞萨MCU杯第八届立创电子设计大赛报名和项目提交截止,项目评审和火力值冲刺正如火如荼进行中,谁将勇夺2万现金大奖敬请期待!目前火力值进入冲刺阶段,急需你的助阵。即日起-11月30日在第八届立创电子设计开源大赛任一参赛项目下进行评论等互动,将有机会得最高500元京东E卡!
图:点击前往大赛项目库
01、评论赢10元京东E卡
即日起至11月26日,在第八届立创电赛参赛项目下评论,我们将从评论区随机抽100人送10元京东E卡。
图:第八届立创电赛项目互动示范
获奖的留言将会收到官方回复,每周抽取20份,奖励以积分形式在每周一派发。
02、评论+点赞+收藏赢500元京东E卡
即日起至11月30日,如果你在第八届立创电赛参赛项目下同时进行评论+点赞+收藏,还有机会被抽到500元京东E卡大奖,我们将会在12月1日大赛官网首页进行公布该幸运锦鲤!
*以下涉及的作品推介,不代表最终评审结果。
医疗电子是很多参赛选手创作的方向,今年立创电赛也不例外,涌现了很多亮眼的医疗方向项目。其中就有参赛选手瞄准心脏骤停急救设备方向,尝试提高救治效率。本文作者:第八届立创电赛参赛选手@buck_boost,禁止商用,未经许可禁止转载,点击查看原文章。
1、项目功能介绍
本项目设计了一种应用于心脏骤停场合的智能生理信号分析加速SoC,采用基于卷积神经网络算法和近似熵算法的组合算法程序以实现心电分类诊断和减少室颤误判的效果。本项目自研了一套生理信号专用的MCU级别的SOC开发板,专门用于部署生理信号的分析。该开发板不仅仅能用于除颤仪,也可以用在绝大多数需要处理生理一维信号的医疗器械上。
本项目所设计的开发板包含的功能有:熵计算加速、CNN 计算加速、定点浮点乘法加速等。可以将原本在单片机上需要数秒乃至数小时计算完成的熵算法以及一维卷积神经网络算法加速到单片机算力可以接受的水平。
本项目设计的开发板采用 RISC-V 指令集的 CPU内核,其型号为 E203,并自主设计了生理信号处理专用协处理器。协处理器包含熵计算加速器、向量乘法计算加速器、定点乘法加速器、浮点乘法器等等生理信号加速专用电路。在本SOC配套的 SDK测试中,进行了250点的近似熵计算,对于纯软件计算,提速约 34 倍,利用加速器计算部分提速约 1700 倍。在一个典型的 CNN心电识别网络中,利用加速版本计算的程序提速约 33 倍。
2、硬件部分
为了验证SOC的相关功能,本文特别设计了功能完整的 FPGA 验证板。如图 3 所示,该验证板主要由电源模块、flash、DDR、晶振、通信串口等部分组成。能够与心电采集模块和电除颤电路通信并共同完成自动诊断和电除颤抢救任务。为了保证 FPGA 和 DDR 能正常工作,其电源模块可以提供 1V、1.5V、1.8V、3.3V 等电压,并严格按照 FPGA 上电顺序的要求上电。
实物图
原理图
3、软件部分
本项目利用熵和 CNN 设计了一种融合算法,其区别于传统心电分类程序,能在胸外按压过程中防止误判心电信号为室颤,以达到提高救治效率的效果。由于生理系统具有明显的非线性性质,因此非线性分析方法可能有助于更好地揭示其特性与机理。从工程技术上看,常常需要研究信号性质的动态变化,因而十分需要只要较短数据就能表现信号特点的动力学参数。从这一要求上看,Rncus 在1991 年提出的近似熵(Apporxiantte Entopy,简记ApEn)是一个值得注意的参数。故本文选用近似熵算法作为诊断手段之一。
此外,本项目还结合了卷积神经网络(CNN)算法,可以对心电信号做进一步地分类。本文所述的自动心电诊断模块区别于传统 CNN 方法,采用 CNN 与熵值判定相结合的方式,提升了在急救场合中对含有同频段伪迹噪声的心电分类准确率。
传统的心脏骤停急救设备往往在施救者在进行胸外按压的时候不进行 ECG 的自动诊断,且在自动诊断的时候要求施救者中断胸外按压,影响抢救效率。其原因在于胸外按压会产生严重的伪迹,该伪迹的频谱与正常心电的频谱大幅度重合,采用传统算法难以滤除。本文中的设计采用卷积神经网络算法和近似熵算法结合的方式,可利用二者的优势,规避二者的缺点。由于心肺复苏过程中的心电信号数据难以获取,因此难以找到足够的数据给神经网络训练。在缺少足够训练集的情况下,依靠人为加噪难以提高室颤的识别准确率,而单独通过熵来判断室颤只能进行二分类且抗干扰性能差。
该算法可以高效利用协处理器,本文基于该算法自主设计了一套 CNN 以及近似熵计算库,可以通过搭载本文所设计的协处理器的 CPU 运行。
本设计采用 E203 内核作为 SOC 的 CPU,利用 nice 接口扩展协处理器。协处理器由指令解码单元、执行状态机、熵计算加速单元、CNN 向量计算单元、单周期定点乘法器组成,设计框图如下图 所示:
协处理器总体设计框图
当程序调用协处理器时,CPU 会拉高 nice 接口的 nice_req_valid 信号线请求握手,协处理器在空闲的情况下会将 nice_req_ready 拉高完成握手,并从指令预取单元中获取指令,状态机会根据指令解码单元解码出的数据和指令调用相应的执行单元执行指令,指令执行完成后,状态机会把 nice 接口的 nice_rsp_valid 线拉高请求握手。
协处理器指令集以及指令解码单元的设计
E203处理器的nice指令编码如表所示:
nice指令编码
比特位 | 31-25 | 24-20 | 19-15 | 14 | 13 | 12 | 11-7 | 6-0 |
功能 | func7 | rs2 | rs1 | xd | xs1 | xs2 | rd | opcode |
其中,func7为指令编码空间,最多支持额外译码出128条指令;rs2和rs1为寄存器索引;xd指示该指令是否需要将结果写回至rd索引的寄存器;xs1和xs2分别指示是否需要读取rs1和rs2索引的寄存器;opcode是操作码。指令解码单元由组合逻辑电路和一个D触发器组成,其逻辑框图如图所示:
指令解码单元的设计框图
协处理器支持执行指令的同时预取一条指令,通过相等比较器判断指令的各部分是否有效,将判断信号送入与门获得某指令的预取信号。在协处理器成功握手后,通过D触发器输出该指令的执行信号。该逻辑可以保证协处理器可以在一条指令执行完成后立即执行下一条指令。
协处理器一共设有7条指令,如下表所示:
协处理器的指令集列表
指令 | 操作数1 | 操作数2 | 写回值 | 功能 |
custom_lbuf_apen | 地址 | 无 | 1 | 熵计算加速器写入原始数据 |
custom_lth_apen | 阈值 | 无 | 2 | 熵计算加速器写入阈值 |
custom_calu_apen | 写回首地址 | 无 | 3 | 熵计算加速器工作一次 |
custom_lker_cnn | 卷积核首地址 | 卷积核长度 | 4 | CNN向量计算单元加载卷积核 |
custom_calcu_cnn | 序列首地址 | 无 | 结果 | CNN向量计算单元计算一次 |
custom_multi | 变量1 | 变量2 | 积 | 进行一次定点乘法计算 |
custom_multi_f | 变量1 | 变量2 | 积 | 进行一次浮点乘法计算 |
其中,熵计算加速器具有三条操作指令,分别为custom_lbuf_apen、custom_lth_apen、custom_calu_apen。程序进行熵计算时,首先需要调用custom_lbuf_apen指令将待计算熵的序列的首地址写入熵计算加速器,然后调用custom_lth_apen指令设置熵计算中的阈值,随后不断调用custom_calu_apen指令获取计算结果。
CNN向量计算单元一共有两条指令,分别为custom_lker_cnn、custom_calcu_cnn。卷积神经网络推理程序在进行卷积乘法运算时,调用custom_lker_cnn将卷积核加载进单元,随后不断调用custom_calcu_cnn计算向量乘法以达到卷积计算的目的。
由于在绝大多数信号的处理算法中,需要大量的乘法运算,而本文使用的CPU内核属于低功耗CPU,没有单周期乘法器和浮点计算单元,为了防止乘法计算拖累算法整体计算速度,影响协处理器的加速效果,本文为协处理器添加了两条乘法指令用于定点和浮点计算:custom_multi、custom_multi_f。
执行状态机的设计
本文所设计的协处理器包含多项功能,虽然其功能差别巨大,但是每个功能的执行状态总可以分解为表3中8个状态的一个,因此,协处理器的所有指令通过指令执行信号复用8个状态。
执行状态机的8个状态
状态 | 执行功能 |
IDLE | 执行状态机处于空闲状态,此时状态机等待预取指令。 |
LOAD | 执行状态机Load地址操作数。 |
READ | 执行状态机通过ICB总线读取数据。 |
WREG | 执行状态机向子单元的寄存器写入数据。 |
CALU | 执行状态机操控子单元进行计算。 |
WAIT | 执行状态机等待子单元计算完成或者数据稳定。 |
WMEM | 执行状态机通过ICB总线写入数据。 |
RSP | 执行状态机拉高nice_rsp_valid请求握手。 |
状态机采用三段式编写,状态跳转采用组合逻辑电路实现,状态输出采用时序逻辑电路实现,状态机大致工作逻辑如下所述。
1、当状态机处于IDLE状态时,状态机会等待nice接口的nice_req_ready信号拉高,随后根据预取的指令类型跳转到下一个状态;
2、当状态机处于LOAD状态时,状态机会将地址预加载到DMA单元,同时拉高nice_mem_holdup,随后跳转到READ状态;
3、当状态机处于READ状态时,状态机会通过DMA从ICB读取指定长度的数据,随后根据指令寄存器的内容跳转到RSP或者WAIT状态。
4、当状态机处于WREG状态时,状态机会根据指令向子单元的寄存器写入数据,随后跳转到RSP状态。
5、当状态机处于CALU状态时,状态机会根据指令向子单元的寄存器写入数据,随后根据指令寄存器的内容跳转到WAIT或者RSP状态。
6、WAIT状态用于等待子单元计算完成或者数据稳定。该状态使用移位寄存器进行计数,通过判定某一位是否为1判断是否需要继续等待,随后根据指令寄存器的内容跳转到WMEM或者RSP状态。
7、当状态机处于WMEM状态时,状态机会通过DMA单元向ICB总线写入计算结果数据,随后跳转回到CALU状态进行下一条计算。
8、当状态机处于RSP状态时,状态机会向nice_icb_rsp_rdata寄存器写入指令写回值。随后跳转到IDLE状态结束一条指令的执行。
可裁剪熵计算加速单元的设计
熵计算加速单元的架构如图所示:
熵计算加速器的架构
熵计算加速单元包含向量计算单元阵列、并行计算控制器、向量重构器、寄存器组以及读写控制器。其对外接口如表所示:
熵计算加速器的对外接口
接口名称 | 位宽 | 接口功能 |
clk | 1 | 加速器模块的时钟端口 |
rst_n | 1 | 加速器模块的复位端口 |
reg_cs | 1 | 加速器模块寄存器读写使能端口 |
reg_wr | 1 | 加速器模块寄存器的写有效端口 |
reg_rd | 1 | 加速器模块寄存器的读有效端口 |
reg_wr_addr | 10 | 加速器模块寄存器的写地址端口 |
reg_rd_addr | 10 | 加速器模块寄存器的读地址端口 |
reg_data_in | 32 | 加速器模块寄存器的数据输入端口 |
reg_data_out | 32 | 加速器模块寄存器的数据输出端口 |
熵计算加速单元的控制完全通过读写寄存器完成,加速器内部寄存器组的寻址范围为0-(APEN_DATA_LEN+1),其中APEN_DATA_LEN是向量计算单元的个数,可以通过修改APEN_DATA_LEN这个参数裁剪熵计算加速器。数据寄存器组的地址范围为0-(APEN_DATA_LEN-1),这个寄存器组的作用是存储待计算的原始数据序列。由于这个寄存器组数量较多,为了保证运行效率,不可以采用CPU依次读写的方式,需要通过DMA写入。地址为APEN_DATA_LEN的寄存器是阈值寄存器。其寄存的是熵算法中的阈值。
控制寄存器和状态寄存器共用地址APEN_DATA_LEN+1,控制寄存器只写,状态寄存器只读。控制寄存器和状态寄存器的功能编码如表所示:
控制寄存器的功能编码
比特位 | 31-12 | 11 | 10-1 | 0 |
功能 | 保留 | 计算维度(0为2维,1为3维) | 计算编号 | 写1电路开始工作 |
状态寄存器的功能编码
比特位 | 31-23 | 22-13 | 12 | 11 | 10-1 | 0 |
功能 | 保留 | 向量距离大于阈值的个数 | 保留 | 计算维度 | 计算编号 | 是否空闲 |
外部电路在调用熵计算加速单元计算前,需要向控制寄存器对应位置写入必须要的计算信息,并在最低位写1。加速单元检测到控制寄存器的最低位为1后,会立即开始一次计算,同时将控制寄存器的最低位写0,状态寄存器的最低位写1。完成计算后,加速单元会重新把状态寄存器的最低位置0。
模块还自带一个由组合逻辑电路设计的向量重构路由器,其作用是将原始数据序列重构成2维或者3维的向量组。并根据控制寄存器中的计算编号,提供相应的数据给距离计算单元。
- 成交数 --
- 成交额 --
- 应答率