浅谈CPU和硬件加速器接口 2
对于软硬件交互不频繁的硬件加速器,接口工作在“单步”模式就可以满足软件需求;对于需要复杂软硬件接口设计才能满足系统需求的硬件加速器,依然需要“单步”模式用于模块功能测试和芯片回片调试。因此,对于任何一个需要和软件交互的硬件加速器,软硬件接口都会支持“单步”模式。
常见的“单步”模式硬件加速器如下图所示

-) 从control path的角度,HWA内部包括配置寄存器和中断(一般而言硬件加速器用线中断,但是系统中断里类似MSI这样的消息中断会占比更大)
-) 从data path的角度,HWA内部一般会有FIFO和RAM用于数据缓存
软件在“单步”模式下使用硬件加速器的流程一般如下:
1. 调用功耗管理程序打开HWA和通路上的相关时钟。如果条件允许,对HWA做一次软复位(不管是软件工程师还是硬件工程师,都相信“干净”的初始状态能避免各种奇奇怪怪的异常)
2. 读写HWA里的配置寄存器,完成对HWA的各项配置
3. 启动HWA,等待完成中断。对于实时性要求高的任务,由于软件进出中断的时间较长(不同的CPU和操作系统时间有区别,一般是us级),常常采用polling寄存器的方式替代
4. 中断到来后读取结果和状态,清除中断
5. 调用功耗管理程序关闭HWA和通路上的相关时钟
配置寄存器是硬件加速器软件接口设计的核心内容之一,一般包括如下内容:
1. 参数配置寄存器
2. 工作开关寄存器(譬如start和stop)
3. 中断寄存器
4. 异常恢复寄存器(实际上软件很少用,但是经验丰富的工程师都会加入)
5. 用于debug的各种状态寄存器
一般而言,CPU读写HWA的配置寄存器需要xx-xxx ns(取决于总线架构设计和HWA总线接口设计)。对于顺序执行的CPU,一次读写寄存器的操作可能带来几百个CPU周期的性能损失,大大降低了CPU的MIPS,因此在配置寄存器设计过程中需要特别关注软件读写配置寄存器的效率问题。一般而言,需要按照如下原则进行设计:
1. 关注配置寄存器的高效性,让CPU在一次任务中尽可能减少对HWA配置寄存器的访问次数
-) 让所有的bit赋值操作都在regfile上做,
-) 对于多CPU共同访问的寄存器,硬件自动实现mutex功能,一个最通常的例子是DMA通道寄存器和中断互发寄存器
-) 不论是读还是写,避免同一个task需要访问多次配置寄存器,当然这个和可扩展性往往是冲突的,需要根据实际情况trade off
2. 保持配置寄存器的可扩展性,没有经验的工程师,往往会把寄存器排列的过于紧密,等到想要升级的时候,常常会因为找不到空间而暗自神伤。在十几年前,由于地址空间有限,把寄存器排列的过于宽松也是一种缺点。不过现在一般来说地址空间都远大于实际需求(CPU地址已经在48bit,256TB),因此适当的宽松已经不是一种罪过,当然地址空洞依然会导致一系列很讨厌的工程小问题
不管做任何事情,透过纷繁复杂的现象看清事物的本质都是很重要的能力。所谓HWA,可以把它在软硬件上整体理解为一条专用的“加速指令”,CPU和HWA的交互,其实可以抽象为CPU执行了一条复杂的专用指令