Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >教你在RISCV中使用DSP指令!

教你在RISCV中使用DSP指令!

作者头像
bigmagic
发布于 2021-09-15 07:28:43
发布于 2021-09-15 07:28:43
2.2K00
代码可运行
举报
文章被收录于专栏:嵌入式iot嵌入式iot
运行总次数:0
代码可运行

教你在RISCV中使用DSP指令!

  • 1.概述
  • 2.RISCV P扩展编程实践(内联汇编)
    • ADD16 (SIMD 16-bit Addition)
  • 3.RISCV P扩展编程实践(库函数)
  • 4.总结

1.概述

DSP有相关的专业芯片,能够专门实现计算功能,相比于通用处理器,DSP芯片专门用于计算,可以在一个周期内执行多条计算。随着单片机对计算功能的需求越来越多,如果用传统的通用处理器去执行大数据的计算,将会消耗许多的机器周期,导致系统的实时性变低。于是,一些通用芯片上也开始集成DSP扩展,比如常见的ARM Cortex-RARM Cortex-M内核。

有了这些DSP扩展支持,其功能更加强大,使用上,许多的办法都可以进行。比如常用的CMSIS-DSP。就是arm提供的DSP的编程库。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://arm-software.github.io/CMSIS_5/DSP/html/deprecated.html

使用上可以只需要将lib库和头文件包含到项目中即可。这样就可以使用CMSIS里面的函数功能,比如求正余弦函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
arm_cos_f32(radians);

如果用标准的数学库中的cos函数,同样也能够达到目的,标准库函数则需要消耗更多的机器周期,而使用了DSP库,则更加方便高效的进行计算。

上述是ARM对DSP支持的使用,RISCV也支持DSP扩展,在RISCV的架构手册上,就对DSP扩展有着一些描述。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://github.com/riscv/riscv-p-spec

目前的支持riscv dsp的riscv core已经有了,但是实际的硬件芯片,市面上还没有见到。目前riscv 的 p扩展还是处于没有稳定的阶段,通过文档的阅读,也能够大致的描述最终的模型。

首先其特点如下:

RISCV DSP扩展是采用的通用寄存器进行数据的存储,这意味着SIMD的寄存器的单位是以通用寄存器的宽度作为标准,如果是RV32,寄存器的长度是32,如果是RV64,则寄存器的长度为64。

相比于RISCV 的RVV,DSP扩展其寄存器的长度有限,但是对于并不复杂的计算来说,已经足够,特别是简单的音频,图形编解码,电机控制等等,都是非常好用的。

下面来描述一下具体如何在RISCV上进行DSP的编程。

2.RISCV P扩展编程实践(内联汇编)

riscv-p-spec规定了P扩展的一些常用的函数功能。

ADD16 (SIMD 16-bit Addition)

Type: SIMD

Format:

31 25

24 20

19 15

14 12

11 7

6 0

ADD16 0100000

Rs2

Rs1

000

Rd

OP-P 1110111

Syntax:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ADD16 Rd, Rs1, Rs2

Purpose: Perform 16-bit integer element additions in parallel.

Description: This instruction adds the 16-bit integer elements in Rs1 with the 16-bit integer elements in Rs2, and then writes the 16-bit element results to Rd.

Operations:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Rd.H[x] = Rs1.H[x] + Rs2.H[x];
for RV32: x=1..0,
for RV64: x=3..0

Exceptions: None

Privilege level: All

Note: This instruction can be used for either signed or unsigned addition.

Intrinsic functions:

Required:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
uintXLEN_t __rv__add16(uintXLEN_t a, uintXLEN_t b);

Optional (e.g., GCC vector extensions):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
RV32:
 uint16x2_t __rv__v_uadd16(uint16x2_t a, uint16x2_t b);
 int16x2_t __rv__v_sadd16(int16x2_t a, int16x2_t b);
RV64:
 uint16x4_t __rv__v_uadd16(uint16x4_t a, uint16x4_t b);
 int16x4_t __rv__v_sadd16(int16x4_t a, int16x4_t b);

在上述的指令中,规定了add16的编码规则,对于RV32来说,一个寄存器的位宽是16,那么可以将一个寄存器拆分成两个单元,一个机器周期,同时执行两条加法。同样的指令,在RV64上,则可以拆分成四个单元,一个机器周期,可以执行四条加法。

通过对编译出来的程序进行反汇编,可以得到对应的汇编代码。

当然,如果要实现dsp指令的扩展,目前官方的编译器还没有完全支持riscv的dsp扩展。如果要完成带有dsp指令的支持的gcc编译器,需要对编译器进行一定的定制。因为目前riscv的p扩展,并未完全定稿,如果完善后,应该会被合并到主线主线。

其中编程的方式采用gcc内部的内联函数的方式进行,在《P-ext-proposal.adoc》中,规定了Intrinsic functions的形式,比如add16

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
uintXLEN_t __rv__add16(uintXLEN_t a, uintXLEN_t b);

RV32:
 uint16x2_t __rv__v_uadd16(uint16x2_t a, uint16x2_t b);
 int16x2_t __rv__v_sadd16(int16x2_t a, int16x2_t b);
RV64:
 uint16x4_t __rv__v_uadd16(uint16x4_t a, uint16x4_t b);
 int16x4_t __rv__v_sadd16(int16x4_t a, int16x4_t b);

那么有上述函数可以供调用,不需要任何的库文件的支持,因为在gcc编译器中,内部自己可以根据这些内联函数进行汇编实现。

使用时,只需要包含gcc自带的dsp相关的头文件即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <riscv_dsp.h>

static __attribute__ ((noinline))
unsigned long add16 (unsigned long ra, unsigned long rb)
{
  return __rv__add16 (ra, rb);
}

使用技巧上并未特殊方法,但是目前,这基本上是比直接写汇编更加高效的dsp编程方式了。

3.RISCV P扩展编程实践(库函数)

在很多情况下,底层的DSP指令虽然可以完成很多功能,不同的组合方式将能够带来不同效果,但是这些基础库的使用,在很多方面也需要编程人员有很强的数学基础,并不能提供通用的math计算方法,这时使用库函数将能够在很大程度上解决这个问题。类似ARM的CMSIS-DSP。RISCV生态上也有一个NMSIS

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
https://github.com/Nuclei-Software/NMSIS

可以将riscv的标准的dsp指令通过组合,形成更加通用的数学库,比如sin或者cosfft,matrix等等,一些常用的标准库函数,都可以在里面找到。对于做嵌入式AI来说,已经十分完善。

使用方法上,首先需要添加NMSIS的的lib文件,然后包含头文件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "riscv_math.h"

直接调用NMSIS库中暴露出来的函数即可。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
float32_t xx = riscv_cos_f32(float32_t cos);

这种方式更加直接,也能减少编程人员对DSP函数的使用不熟悉,带来的一些人为的错误,所以NMSIS可以说是DSP指令的上层软件。使用该库可以很容易的进行高效的数据运算。

4.总结

在riscv的芯片中,如果要使用DSP,首先需要该芯片的硬件设计实现了riscv的p扩展,硬件支持的情况下,再适配编译器,编译器也将DSP的支持添加进去。这样可以直接使用DSP扩展的指令了。然而直接使用DSP提供的指令进行计算,工作量还是很大,同时优化也不一定非常的好,此时使用NMSIS库提供的函数,直接利用优化好的数学函数进行数据计算,这样才是高效最简单的方式。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-08-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 嵌入式IoT 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
riscv实现自定义指令并用qemu运行
riscv支持指令集自定义扩展,这大大增加了riscv的可玩性,同时对于一些实际应用中,自己通过一条指令来实现特定的功能,效率非常高,当然,前提是硬件平台需要对该指令的支持。
bigmagic
2021/04/30
4.2K4
riscv gcc中添加custom自定义指令
在riscv的处理器开发过程中,各家处理器往往都会涉及到自定义指令功能的添加。在处理器设计上,添加一些特定功能的指令是十分正常的,一般处理办法本文会讲述,让其识别客户自定义的指令。从现有的解决办法上来看,第一种是可以利用Kito Cheng提供的.insn模板进行开发,第二种则是修改binutils的方法。本文主要介绍这两种办法进行riscv custom指令的添加。
bigmagic
2021/10/09
5.2K0
riscv64 裸机编程实践与分析
任何芯片在启动之前都需要有一段汇编代码,从这段汇编代码上就可以体现一些架构设计的特点。往往做嵌入式底层开发都需要关注这段汇编代码的含义,这样在使用的时候才能全面的了解启动时做了什么事情,在后续的程序中遇到问题也能复盘推演。
bigmagic
2021/01/08
3.3K0
从riscv底层原理分析gd32vf103的中断行为
对于向量中断,其中断发生后,pc指针会根据中断的类型跳转到基地址+中断号*4的地址处去执行中断处理程序,做过stm32的,应该比较清楚向量中断的大概样子。当然,riscv也是支持这种向量中断,这样每个地址处会安排一个特定的中断处理函数,当中断发生后,跳转到特定的函数去执行即可。
bigmagic
2021/04/16
2.5K0
用哪吒D1开发板体验riscv向量底层编程
RISCV V扩展即向量指令扩展(RVV),这部分作为研究AI加速计算领域有着非常关键的作用。既然的D1支持了rvv扩展(0.7.1,最新的版本已经0.10版本),那么就实际的从底层原理角度分析一下使用的流程。利用了多媒体加速指令集,可以让计算变得更加的高效,同时并行计算的特性使得同时多次计算一组数字成为可能,类似于arm的NEON等等,那么RISCV又该如何去开启和使用V扩展指令,让计算变得更加高效呢?
bigmagic
2021/07/01
1.7K0
RISC-V指令集讲解(4)R-Type 整数寄存器-寄存器指令
上文RISC-V指令集讲解(3)I-Type 移位指令和U-type指令介绍完了整数寄存器-立即数指令,本文开始进行整数寄存器-寄存器指令的讲解。
IC知识库
2021/07/30
6.5K0
RISC-V指令集讲解(4)R-Type 整数寄存器-寄存器指令
RISC-V指令集讲解(6)load/store指令
RV32I是一个加载-存储(load-store)架构。也是只有load和store指令才能访问存储器和外设(CPU 内的寄存器只能由算术指令操作) [1]。load和store指令将寄存器和存储器/外设的值相互交换。
IC知识库
2021/07/31
7.8K0
RISC-V指令集讲解(6)load/store指令
芯昇科技CM32M433R-START开箱评测
中国移动芯昇科技发布CM32M4xxR,该芯片基于RISC-V内核的MCU,性能主要对标Cortex-M4。如今RISC-V架构的通用MCU在市场上也并不少见,但是该芯片也有其自己的特点,在探索应用领域方面也有自己独特的设计。
bigmagic
2022/04/15
1.1K0
芯昇科技CM32M433R-START开箱评测
RISC-V指令集讲解(5)条件和无条件跳转指令
无条件跳转指令均使用PC相对寻址。无条件跳转主要包括两条指令:JAL 和 JALR。
IC知识库
2021/07/31
25.1K0
RISC-V指令集讲解(5)条件和无条件跳转指令
riscv gcc中添加自定义的csr支持
由于RISCV的模块化的指令集的定义,各家都有着自己的实现方式。从当前看来,除了标准的CSR外,很多都实现了自己的CSR指令扩展。如何自定义CSR并且让编译器能够识别,本文将进行一定的分析,同时从riscv gcc开发的角度出发,来分析编译器开发的流程。
bigmagic
2021/08/20
2.1K0
【计算机组成与设计】Chisel取指和指令译码设计
输入位32bit的一个机器字,按照课本MIPS 指令格式,完成add、sub、lw、sw指令译码,其他指令一律译码成nop指令。输入信号名为Instr_word,对上述四条指令义译码输出信号名为add_op、sub_op、lw_op和sw_op,其余指令一律译码为nop;
叶茂林
2023/11/07
6260
【计算机组成与设计】Chisel取指和指令译码设计
opensbi下的riscv64裸机编程2(中断与异常)
任何时候,中断和异常的产生都是十分值得关注的,这些将破坏程序原有的执行逻辑。按照芯片的设计来说,中断和异常大致上可以分为三类异常(Exception)、陷入(Trap)、外部中断(Interrupt)。
bigmagic
2021/01/08
2.5K0
国产RISCV MCU 沁恒CH32V103上手体验
最近由于stm32的价格疯涨以及stm32 mcu芯片的缺货,导致很多电子产品的方案慢慢会考虑一些国产替代方案,比如兆易创新的GD系列芯片等等。随着riscv在国内的发展壮大,许多riscv架构的mcu芯片也逐渐的成为可以供选择的方案。那么这款MCU的性能、体验、开发上手难度、实用性等等角度上,究竟体验如何,下面文章将做一个简单的概述,同时利用目前对RISCV的知识层面的理解,去分析这个芯片的使用。
bigmagic
2021/09/15
3.6K0
国产RISCV MCU 沁恒CH32V103上手体验
D1 riscv芯片上运行rt-thread进行RVV性能评估
D1 && D1s(f133)采用的是平头哥C906的core,上面已经支持了RVV 0.7.1版本,虽然目前RVV1.0已经frozen,这就意味着上游编译器或者一些相关的生态软件将支持RVV1.0,但是作为性能评估RVV0.7.1与RVV1.0影响并不大。下面的文章主要描述如何在D1 && D1s芯片上运行rt-thread,并且描述如何开启RVV,同时对RVV性能进行一个简单的评估,最后讨论RVV如何与RTOS使用的问题。
bigmagic
2022/03/04
1.6K0
D1 riscv芯片上运行rt-thread进行RVV性能评估
riscv gcc工具链是如何被编译的
gcc工具链是一个复杂而又巧妙的工程,随着riscv上层软件的逐渐完善,工具链和底层系统软件的开发也显得尤为重要。深入理解gcc的原理,能够更好的对计算机体系结构有一个完整的了解。
bigmagic
2022/01/10
2.3K0
riscv gcc工具链是如何被编译的
RISC-V指令集讲解(2)I-Type整数寄存器-立即数指令
上文RISC-V指令集讲解 (1) 通用寄存器和汇编指令分类介绍了通用寄存器,程序计数器和6种汇编指令,本文将先从I-type的整数寄存器指令开始,详细介绍每一种汇编指令包括的具体指令。
IC知识库
2021/07/30
2.5K1
RISC-V指令集讲解(2)I-Type整数寄存器-立即数指令
哪吒D1开发板RISC-V CLINT编程实践
当前riscv的中断控制器部分比较简单,不像arm那样复杂,设计的简单分析起来就比较容易理解清楚。相比于ARM的GIC,RISC-V这一套CLINT与PLINT简直太容易理解了。或许是因为ARM迭代的时间很长,积累了很多设计上的经验,RISCV还需要经过实际的市场的考验,才能真正的看到中断控制这一块的设计到底是否简洁并且设计合理。
bigmagic
2021/07/23
2.9K1
嵌入式编程中使用qemu能够做什么?
嵌入式开发的过程中,很多时间都是要和硬件设备打交道,通过程序控制硬件的具体行为,这些往往是单片机延续下来的开发模式,在目前复杂的嵌入式系统中,很多都需要借助设计模式来进行开发,比如文件系统,网络,图形,算法等等,这些如果能够利用软件模拟器进行开发,可以大大的减少上板调试的时间。减少硬件连接的烦恼,在家也能随时分析软件代码。
bigmagic
2021/07/01
1.8K0
RISC-V架构系列之1:指令集和特权模式
从2010年开始的RISC-V 项目,已经有10年的时间,RISC-V基金会先后批准了RISC-V Base ISA, Privileged Architecture,Processor Trace等规范。RISC-V对Linux的基本支持也已经完成。本文尝试通俗易懂的介绍RISC-V对于Linux的基本支持,包括指令集和异常处理。内存管理,迁移到RISC-V,UEFI,KVM等支持,欢迎继续关注本公众号。
Linux阅码场
2021/02/24
2.8K0
RISC-V架构系列之1:指令集和特权模式
用于ARM Cortex-M系列的芯片的神经网络推理库CMSIS-NN详解
论文题目:《CMSIS-NN: Effificient Neural Network Kernels for Arm Cortex-M CPUs》, 2018年
BBuf
2022/09/28
3.4K1
用于ARM Cortex-M系列的芯片的神经网络推理库CMSIS-NN详解
推荐阅读
相关推荐
riscv实现自定义指令并用qemu运行
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验