基于FPGA的驾车辅助系统设计
0赞第一部分 设计概述
1.1设计目的
随着车辆的普及,出行安全已经成为人们热切关注的话题,每年因为不当的驾驶行为而造成的交通事故日益增加,在科学技术迅速发展的大环境下,科学保障人们的生命安全已经成为必不可少的社会要点。据统计,2001年中国交通事故死亡人数为10万人,而同年美国的数字为4万人,日本为1万人。
据全球各交通和警察部门的统计,2003年全世界交通事故死亡人数为50万人。其中,中国交通事故死亡人数为10.4万。我国交通事故的致死率也是世界最高的,为27.3%,因疲劳驾驶而造成的交通事故占总数的20%左右,重特大伤亡事故中约40%是由于疲劳驾驶造成的,高速路上20%的事故都是因为疲劳驾驶。据公安部交管局统计数据显示深夜、凌晨或午后为“疲劳驾驶”事故高发期。
基于当前的这些数据以及现状,在疲劳驾驶的问题中,我们应该尽量减少事故的发生概率,即在驾驶过程使驾驶人保持清醒,若遇到驾驶人疲劳时,我们需要采取一些方法来使驾驶人清醒或者提醒停车休息即“疲劳驾驶检测功能”同时辅助多样化全面的人性化行车辅助功能,以此高度保障人身安全,使行车更安全和智能,为驾驶者以及乘客提供一个更科学、可靠、便捷的辅助平台。
1.2应用领域
本作品所设计的智能行车辅助系统通过核心算法功能“疲劳驾驶检测”,通过对驾驶员眨眼、打哈欠等行为的分析,实时检测疲惫状况并及语音提示驾驶员保持清醒,多种辅助系统可使行车更便捷应用于私家、货车、大巴等多种辆以及经常需要夜间长途出行的特定群体。行车辅助系统不仅具有疲劳驾驶检测功能,同时还配备智的行车辅助系统的功能,如语音播报、超声波测距倒车影像座椅按摩等多种便捷的且贴心功能,语音播报、超声波测距倒车影像座椅按摩等多种便捷的且可以通过语音控制可达到真正解放双手的目,使驾驶更专心、方便。
1.3适用范围
本行车辅助系统不仅可用于个人的安全,也应用于车辆管理公司,如出租车、货运输等需要集体配备行车辅助系统的团体,更智能 、安全便捷的行车辅助效果会更加明显。
第二部分 系统组成及功能说明
2.1系统介绍
本作品的核心系统疲劳驾驶检测搭载于 XILINX Zynq-7000 系列 PYNQ-Z2 开发板,开发板如图 2.1 所示,其主芯片为 XC7Z020CLG400-1,该芯片为 FPGA+ARM 架构并且可用于 python 开发,同时提供了丰富的 python API 和完 善的硬件设计流程,为较复杂算法的编写及应用提供了新思路。同时使用 Artix-7 核心板为辅助功能模块显示控制中心,如图 2.2 所示。
系统主要包含:疲劳驾驶检测、倒车辅助、语音控制平台、安全车距检 测等部分组成,总体流程图如 2.3 所示。系统可实现开机自启,并实时检测 驾驶者的疲惫情况,辅助功能模块由语音控制功能协调控制,实现解放双手 安心驾驶的目的,同时语音播报提醒驾驶员疲惫状况以及车辆周围障碍物情 况并及时反馈给驾驶者,达到预防交通事故发生的目的。
2.2 各模块介绍
2.2.1.疲劳驾驶检测系统
(一)系统总体方案设计考虑到疲劳状态图像处理的实时性和疲劳状态检测的准确性。采用 PYNQ 开发板作为系统的嵌入式控制单元,用于运行图像采集和图像处理的程序,以及控制各个预警模块;使用 usb 摄像头 实时采集机动车驾驶员的人脸和眼部图像视频流。该视频流的每一帧图像作 为驾驶员疲劳状态监测的源数据; 采用 OpenCV 计算机视觉库、Dlib 机器 学习库和 Python 开发语言对驾驶员的人脸图像进行处理,通过计算 EAR 参 数来实时检测眼部张合度,判断驾驶员的疲劳状态。当检测到驾驶员处于疲 劳驾驶的状态时,通过语音预警及座椅震动按摩的方式提醒驾驶员注意安全行车。
(二)系统软硬件平台
(1)嵌式控制单元考虑到图像采集和图像处理算法的复杂性,以及疲劳驾驶检测的应用场 景对体积、安装与成本的要求,采用 PYNQ 开发板作为控制单元,PYNQ-Z2 开 发板支持 PYNQ 项目,这是一个新的开源框架,使嵌入式编程人员能够在无 需设计可编程逻辑电路的情况下即可充分发挥 Xilinx Zynq All Programmable SoC(APSoC) 的功能。与常规方式不同的是,通过 PYNQ,用户可以使用 Python 进行APSoC 编程,并且代码可直接在 PYNQ-Z2 上进 行开发和测试。通过 PYNQ,可编程逻辑电路将作为硬件库导入并通过其 API 进行编程,其方式与导入和编程软件库基本相同。PYNQ-Z2 开发板是 PYNQ 开源框架的硬件平台。在 ARM A9 CPU 上运行的 软件包括:• 载有 Jupyter Notebooks 设计环境的网络服务器• IPython 内核和程序包• Linux• FPGA 的基本硬件库和 API
(2)实时视频图像采集单元图像的采集使用的是 NUOXI ZL-008 型号USB 摄像头,该摄像头支持分辨率640*480,帧率 30 帧/秒,增强像素数1200 万,可以满足本文研究中对 图像的清晰度和实时性的要求。将摄像头连接到PYNQ 的USB 接口,并将摄像头放置在车子内部的仪表盘上方。在 PYNQ 上,使用 Python 的 imutils 包采集实时的视频流,进而获取视 频流的每一帧图像,用于后续的图像处理。
整个SoC的PRV332处理器核心如图5所示,PRV332SV0处理器内核是一款支持RISCV-32 I和A拓展指令集,完全实现RISCV定 义的所有功能的处理器,不仅具备机器模式(M)模式下运行,还支持虚拟内存MMU 和系统(S)用户(U)模式,理论上完全具备运行类linux系统的能力。这款处理器内核主要由BIU(总线接口单元),EXU(执行单元),INS-CSR-GPR(指 令-CSR-通用寄存器单元),中断控制器组成,简单原理框图如图6所示。
图6 CPU原理框图
整个CPU以状态机的方式运行,常规指令需要6T:
T0:BIU准备开始下一条指令的地址。
T1:BIU(总线接口单元)发出地址和总线控制信号。
T2:BIU(总线接口单元)根据总线上的信号(访问失败信号、准备好信号)选择是否存入总线上的数据,若总线访问失败,则跳转到T10,若准备好信号为0,则保持T2状态,若准备好为高,则寄存总线上的数据并进入下一状态。
T3:BIU发出准备好信号, 同时把指令通过BIU的指令输出总线输出给指令解码单元(INS_DEC)开始指令解码。
T4:EXU开始动作,常规的加减法和逻辑运算将在这个周期内完成,如果是移位指令等则需要多个周期才能完成。
T5:写回阶段,CPU内部的寄存器根据指令译码器译码结果进行寄存,同时PC(程序计数器)值在这个阶段被更改,指向下一条要被执行的指令的位置。如果在这个执行阶段中断控制器接受了某个外部中断,则跳到T10。当处理器遇到内存访问指令,需要增加额外的四个执行周期 T6-T9。
T6:BIU准备开始下一条指令的地址。
T7:BIU(总线接口单元)发出地址和总线控制信号。
T8:BIU(总线接口单元)根据总线上的信号(访问失败信号、准备好信号)选择是否存入总线上的数据,若总线访问失败,则跳转到T10,若准备好信号为0,则保持T2状态,若准备好为高,则寄存总线上的数据并进入下一状态。
T9:BIU发出准备好信号, 同时把数据放在内部数据总线上。当处理器遇到中断或者发生异常,需要增加一个执行周期T10,T10可以插入到以上执行周期的T2或T5或T8之后。在T10里处理器将根据错误类型将PC值自动拨到对应的中断向量上,同时储存当前发生异常的PC值和异常值到MEPC和MTVAL寄存器里。
*关于RISCV的中断和异常处理可参考《The RISC-V Instruction Set Manual Volume II : Privileged Architecture》 2.2.1.2 BOOTROM(程序只读储存器)
图7 BOOT-ROM
PVS332具有一个片上BOOT-ROM,如图7,在BOOT-ROM里面预置了开机启动代码,系统复位后处理器首先执行该ROM里面的程序,通过修改该BOOT-ROM里面程序的内容可以实现多种功能。
2.2.1.3 OCRAM(片上内存)
[url=]Center[/url]
图8 OCRAM
PVS332具备一个4K字节的片上RAM,如图8所示,该内存为同步SRAM,可以在2T周期内读写数据,工作频率和CPU同步。具备比较高的读写带宽。可以在系统没有拓展内存的情况下使用。
2.2.1.4 SPI收发器
图9 SPI收发器
PVS332具备一个硬件SPI收发器,如图9所示,可以使用额外的门电路可以同时管理八个从设备。以下截图来自于《PVS332处理器编程手册》,描述的是SPI收发器的地址和操作,分别如图10、图11所示。
2.2.1.5 EXT-SLOT(拓展插槽)
图12 拓展插槽适配器
PVS332通过该适配器,如图12所示,支持最多8个,每个2MB的多功能拓展插槽,这些插槽都支持等待状态,同时插槽的地址直接被映射在处理器外部地址里面,程序可以直接访问到这些插槽上面的设备。拓展槽使用32个双向IO作为数据总线(SRAM_Data),22条地址总线(SRAM_Add),4条字节选择线(SRAM_BSEL),外部设备准备好信号线(rdy),读写信号线(SRAM_OE,SRAM_WR)和外部片选信号线(SRAM_CS)。外部总线读写分四个周期。(a)读时序当PVS332处理器内置的PRV332SV0处理器访问的内存属于外部储存器时,PVS332自动将内存选择到外部,进入读周期。T1:SRAM_CS拉低,SRAM_OE拉低,SRAM_Add送出地址,SRAM_BSEL的某几个位拉低以指示是哪个字节被读写。在下一个时钟上升沿进入T2状态T2:保持T1状态,在下一个时钟上升沿进入T3状态。T3:保持T2状态,当rdy=1时候,在下一个时钟沿进入T4状态,否则等待在T3状态T4:保持T3状态,在T4周期结束的时候进行数据采样,同时回到等待状态TW。(b)写时序T1:SRAM_CS拉低,SRAM_Add送出地址 ,SRAM_Data送出数据,SRAM_BSEL某几个位拉低以指示要操作哪个字节,在下一个上升沿进入T2周期。T2:SRAM_WR拉低,其余参数保持和T1一致,在下一个时钟上升沿进入T3周期。T3:保持T2状态,等待rdy信号之后在下一个时钟上升沿进入T4周期T4: SRAM_WR拉高,其余参数保持和T1一致,在下一个时钟上升沿进入TW。
2.2.1.6 GPIO
图13 GPIO
PVS332处理器支持128个GPIO, 所设计的模块如图13所示,在目前系统里面因为FPGA引脚较少,实际只使用了GPIOC的22个GPIO。GPIO有关的控制寄存器如下图14所示。
图14 GPIO控制寄存器
*以上设备的汇编测试程序可见SIM-TESTCODE文件夹。
*以上设备的寄存器定义可以见附录中的PVS332编程手册。
2.2.1.7 UART16550
图 15 UART16550
如图15,PVS332支持一个带FIFO的UART收发器,具备16字节深度的FIFO,最高支持波特 率为9600。UART16550的控制寄存器如图16所示:
图16 UART16550控制寄存器
*详情可以参考附录中的PVS332编程手册
2.2.1.8 控制寄存器组
图17 控制寄存器组
PVS332 SoC中有一个控制寄存器(图17 控制寄存器组)控制整个SoC的各项功能。控制寄存器组里面包含了:(1)系统定时器PVS332 SoC支持RISCV架构定义的系统的定时器(MTIME、MTIMECMP)这两个寄存器在0x0ffc0000-0x0ffc000f的空间里。该定时器在MTIME计时到MTIMECMP之后会产生定时器中断,只有当程序更新了MTIME或者MTIMECMP寄存器之后中断才会被清除。(2)软件中断控制器软件中断控制器可以让程序使用置1的方式产生同步的软件中断。(3)中断控制器(SIC)SIC可以支持最多256个外部中断的管理,并可以配置它们的优先级,由这个寄存器管理的中断源最后都连接在PRV332处理器的ext_int中断上,触发中断之后PRV332的xcause寄存器将会被更新为外部中断,软件可以查询SIC里面的中断挂起寄存器而找到是哪个外部设备发起了中断。图18是SIC的寄存器列表,详情可见附录中的《PVS332编程手册》
图18 SIC控制寄存器
*详情可见附录中的《PVS332编程手册》。
2.2.2 系统主板
系统主板分为3大部分,分别为FPGA插座部分、拓展插槽部分、SPI和GPIO和flash部分。
2.2.2.1 FPGA插座部分
图19 FPGA核心板插座部分
如图19,在这个部分里的CPU位置,可以插入上述FPGA核心板作为系统主板的CPU,该核心板一共有96个可用IO,我们将IO分配为:拓展卡IO、通用输入输出(GPIO)、SPI收发器 三个部分。在旁边的稳压器部分,主要为板上的逻辑芯片供电。同时我们搭载了多个指示灯用于指示系统的运行状态。
2.2.2.2 拓展插槽部分
图20 拓展插槽部分
在拓展插槽上图20所示,我们使用32个IO作为双向数据总线,22个IO作为地址总线,4个IO作为字节选择线, 2个IO作为读写使能线,1个IO作为准备好信号输入线。总线工作频率为8MHz(FPGA工作频率33MHz时)。最大传输速度为32MB/s。为了实现多个外部设备,我们将A19-A21作为一个3-8译码器的输入信号,使用该3-8译码器获得8个译码器信号,这样外部就可以获得8个插槽的片选信号。其余的A0-A18作为地址线,配合四个字节选择线可以寻址8 * 512K * 4Byte的空间。
2.2.2.3 SPI、GPIO和flash部分
图21 SPI、IO和外部FLASH
SPI部分同样使用3-8译码器作为从设备选择信号,而后使用一片8-1数据选择器作为八个SPI从设备的MISO选择。FLASH部分使用额外的74系列逻辑芯片搭建了复用器,在调试器对系统进行复位时(/RESET为低),此时复用器将FLASH的引脚切换给调试器的MOSI、MISO、SCK、CS使用。当调试器烧录FLASH完成之后,/RESET被拉高,此时该复用器将FLASH切换给主系统的SPI收发器使用。
2.2.2.4 主板PCB图
图 22 主板PCB图
2.2.2.5 主板实物
PVS332可以搭配配套的PVS332-XC7MB主板,板上引出了七个SPI,16个GPIO和 烧录器用的插针。同时引出了四个可以直接使用的拓展槽接口和一个需要外接其它拓展电路的接口。主板实物如图23所示:
图23 主板实物图
2.2.3 调试器
调试器使用ESP32作为主控,使用ESP32通过蓝牙/WIFI等多种方式连接系统主板和电脑端软件。该调试器可以和电脑端配套软件联合使用,执行包括对系统主板进行复位、烧录外部FLASH、监视系统主板串口并回传数据等一系列任务。调试器通过自定义排线接口与系统主板相连接,自定义接口的引脚定义如图24所示:
图24 调试器电路
调试器通过上图中MISO,MOSI,SCK,/CS来完成对系统主板的复位和调试工作。在/RESET为0时(即系统复位), 调试器作为SPI从机,MOSI,MISO,SCK,CS引脚控制系统主板上的外部FLASH;在/RESET为高(即系统正常工作)时,MOSI,MISO,SCK为SoC的SPI收发器0引脚,此时调试器作为SPI 从机,可以监视串口数据。调试器实物如图25所示:
图25 调试实物图
2.2.4内存拓展卡
外置内存拓展卡是两片IS62WV51216构成的,一共2兆字节。可以插在主板上的拓展插槽内,可以让系统获得额外的2MB内存。拓展卡如图26所示:
图26 内存拓展卡
2.2.5 PC端IDE
软件部分我们完全自主研发了一个IDE-PRV332IDE,具备编辑RISCV汇编,生成多种机器码文件的能力,可以极大的方便程序验证和调试工作。IDE界面如图27所示:
图27 IDE界面
2.2.5.1 IDE各项功能介绍
图28 IDE功能
如图28所示,IDE功能从上到下依次为:复制文件、剪切文件、新建文件、生成二进制文件、生成Hex文件、生成coe文件、缩进、换行。其中生成二进制文件可以让汇编代码直接被仿真器仿真;生成的Hex文件可以直接烧录到flash里面,配合SoC内部的BOOTLOADER程序使用;生成的coe文件可以作为xilinx FPGA的ROM里面的内容。
2.2.5.2 IDE实现技术特点
Prv332ide使用pyqt编写图形界面同时重构了原有的riscv汇编工具链,是一个总代码约2000行的轻量级prv332定制的可以直接烧录的ide.汇编工具链上抛弃传统的两遍扫描算法使用高效的一遍扫描算法,同时利用散列算法进行加速使得汇编翻译和地址分配速度非常快。不仅在速度上进行了优化,同时利用python面向对象的优点预留多个接口,配合图形界面可以直接生成用于仿真的二进制文件(直接用于modelsim仿真),coe文件(用于直接烧录xilinx的BROM),hex文件(用于直接烧录到soc的片外flash)。大大方便了验证和调试工作。图形界面使用pyqt开发,除了汇编工具链生成的之外还可以利用socket直连jttag接收soc传来的数据以及烧录工作。
第三部分 完成情况及性能参数
3.1综合完成FPGA逻辑资源占用
图29 FPGA布线占用
图30 FPGA资源占用
图29和图30可看到,综合布线完成后共占用逻辑单元3628个,一共使用总逻辑单元数量的45.35%。片内RAM共使用8KB,占用总片内RAM资源的80%。在总的资源占用上较为良好的达到了对轻量的需求。
3.2 在MODELSIM里面进行汇编代码仿真(以SPI收发器为例)
首先我们在配套的汇编软件中写SPI收发器的汇编代码,图31所示:
图31 SPI收发器驱动
此程序写了一个使用SPI收发器完成发送一系列字符串的程序的程序。程序流程如下:设置SPI收发器的基地址、设置要发送的数据、使能SPI收发器、检查SPI收发器的TXOK位,若为1则继续发送下一个字节的数据。其次我们使用PRV332IDE生成给modelsim仿真使用的二进制文件,如图32所示:
图32 生成的二进制文件
然后我们打开modelsim,直接开始仿真,可以看到SoC的SPI有关引脚上出现了我们希望看到的数据,如图33所示。
图33 仿真波形
3.3 PVS332实机启动演示
首先我们将上述仿真过的汇编代码使用PRV332IDE生成COE文件,如图34所示;接着我们将该COE文件作为PVS332系统里面BOOTROM的内容烧录到FPGA里面。为了更好的观察SPI收发器的工作情况,我们搭建如图35所示的测试电路。在该测试电路里,系统主板的调试接口和调试器通过排线连接在一起,由于系统主板的SPI收发器0和调试器有硬件连接,调试器监视SPI0收发器的数据,故我们用示波器观察系统主板上SPI0的SCK和MOSI线上的数据。
图34 COE文件
图35测试电路
系统启动之后可以看到从BOOTROM启动的SPI程序发出的信息,如图36所示:
图36 启动信息
同时在示波器上也可以看到SPI收发器正常工作,图37所示:
图37 示波器观察到的波形
第四部分 总结
4.1主要创新点
(1)本系统完全自主研发了一个简单的SoC,主CPU同样为自主研发,抛弃了MCS51,X86等落后的指令集,采用了新型的RISCV指令集,
(2)本系统同时完全自主研发了一个汇编语言IDE,在保证简单易用的前提下,实现了生成多种文件的功能,极大的方便了调试。
(3)本系统的SoC不仅可以在仿真软件上运行,我们还制作了相应的系统主板,突破了目前国内同类教学用RISCV系统只有仿真文件的问题。
4.2可扩展之处
(1)目前只支持少量的通信设备(八个SPI一个UART),以及非常少的拓展卡设备可以用(只有一个2MB拓展内存卡,最多只能拓展16MB的外部储存空间)。
(2)目前的汇编器只支持汇编语言开发,以后可以移植GCC编译器让该系统可以用于C语言编程下的微机教学。
(3)目前本系统暂时不支持JTAG等调试机制,以后有望移植JTAG让调试更加简单。
第五部分 参考文献
[1]水头一寿,CPU自制入门[M].北京:人民邮电出版社,2014
[2]胡振波,手把手教你设计CPU-RISC-V处理器[M].武汉:人民邮电出版社,2018
[3]胡振波,RISC-V架构与嵌入式开发快速入门[M].武汉:人民邮电出版社,2018
[4]夏宇闻,Verilog数字系统设计教程(第四版)[M].北京:北京航空航天大学出版社,2017
[5]Andrew Waterman, Krste Asanovic, SiFive Inc.The RISC-V Instruction Set Manual Volume II rivileged Architecture[Z].Califorina:University of California, Berkeley,July 27,2019.
[6]Andrew Waterman, Krste Asanovic, SiFive Inc.The RISC-V Instruction Set Manual Volume I :Unprivileged Architecture[Z].Califorina:University of California, Berkeley,July 27,2019.