无题
blog_makedownstore myblog md file
无题
RISC-V汇编语言入门一个完整的RISC-V汇编程序是多条语句组成。
一条典型的RISC-V汇编语句由三部分组成:[label:] [operation] [comment]
12_start:#可以将_start这个label理解为地址 li x6 ,5
汇编指令编码格式
指令长度:ILEN1 = 32bits(RV32I)
指令对齐:IALIGN=32bits(RV32I)
指令在内存中按照小端序排列
机器源码和汇编指令的对应关系
比如机器源码0110011,每个机器源码是7位,最后2位都是11,[6:5]的是纵坐标,[4:2]的是横坐标,所以对应关系是OP指令

补码/反码、零扩展和符号位扩展(Zero extension and Sign extension)-CSDN博客
符号扩展(Sign Extension)
符号扩展用于扩展有符号数(例如,有符号的整数)。在扩展时会保持原数值的符号位。
方法:在扩展位上填充原数值 ...
无题
RISC-V Vector Extension
RISC-V 向量扩展(RVV, RISC-V Vector Extension)中的指令可以大致分为三大类:设置向量长度(setvl)、加载/存储(load/store)、和 数学运算(mathematical operations)。以下是这三类指令的详细描述:
setvl 指令
setvl 指令用于设置向量长度,并返回当前向量长度。它是 RVV 中的核心指令,用于动态地控制每条指令处理的向量元素数量。通过设置向量长度寄存器(vl),可以使得后续的指令在处理数据时,按照给定的向量长度来处理。
指令格式:
1setvl xlen, rs1
功能:
设置向量长度(vl)。
rs1 寄存器的值决定了目标向量长度(vl)。
返回的向量长度会被存储在 vlen 寄存器中。
示例:
1setvl x0, x1 // 设置向量长度
加载/存储指令(Load/Store)
加载和存储指令用于将数据从内存加载到向量寄存器中,或者将向量寄存器中的数据存储回内存。这些指令的操作对象是向量寄存器,可以处理 ...
MLIR
方言 DialectMLIR 是一个设计完全可扩展的基础设施,它的可扩展性体现在 IR 的各个元素,包括 operations、types 和 attributes 等都是可以进行扩展的。这种可扩展性是通过方言(dialect)来实现的,方言为 IR 提供了一种通过 namespace 分组的机制,可以赋予操作(operation)新的语义,实现自定义的行为。
在 IR 中,如果想要为操作赋予新的语义以实现自定义行为,通常需要添加新的属性或者重新定义输入输出。这时,IR 的可扩展性就变得非常重要。
举例来说,考虑一个 matmul 算子,如果想要为它添加一个属性以进行后端图优化,就需要查看该算子的 attributes 字段是否可扩展,以及 op builder 是否允许传入该属性。只有两者都支持,才能满足需求。否则,通常需要创建一个自定义的 matmul 算子,并将原有的 matmul 算子替换为自定义算子。
而在 MLIR 中,你可以定义一个特定的方言,比如 toy dialect,然后在该方言中定义一个 matmul 算子,这样就可以获得 toy.matmul 算子。在图优化过程 ...
RISC-V汇编语言入门
一个完整的RISC-V汇编程序是多条语句组成。
一条典型的RISC-V汇编语句由三部分组成:[label:] [operation] [comment]
12_start:#可以将_start这个label理解为地址 li x6 ,5
汇编指令编码格式
指令长度:ILEN1 = 32bits(RV32I)
指令对齐:IALIGN=32bits(RV32I)
指令在内存中按照小端序排列
机器源码和汇编指令的对应关系
比如机器源码0110011,每个机器源码是7位,最后2位都是11,[6:5]的是纵坐标,[4:2]的是横坐标,所以对应关系是OP指令

补码/反码、零扩展和符号位扩展(Zero extension and Sign extension)-CSDN博客
符号扩展(Sign Extension)
符号扩展用于扩展有符号数(例如,有符号的整数)。在扩展时会保持原数值的符号位。
方法:在扩展位上填充原数值的符号位。例如,如果原数 ...
RVV Intrinsic
RVV向量扩展向量扩展
使用 Intrinsics 的 C 语言 RISC-V 向量编程
RVV 的灵活性体现在以下几个方面:
向量长度的可变性:RVV 提供了灵活的向量长度(VL)设置,使得同一指令可以处理不同数量的数据元素。例如,你可以在同一程序中为不同的操作指定不同的向量长度,以适应硬件的能力或特定的计算任务。一个寄存器可以包含多个数据元素(例如 32 位整数、64 位浮点数等),并根据当前的 vl 设置来决定每个寄存器要处理多少数据元素。因此,向量寄存器组有时可以半满或不满——取决于 vl 设置以及每个操作处理的数据量。
向量寄存器组的大小:RISC-V 向量寄存器组通常由多个寄存器组成,每个寄存器的大小是固定的。寄存器的大小和数据类型(如整数或浮点数)是固定的,但由于 vl 是动态可调整的,寄存器的填充率可能会小于其最大容量。例如,假设一个寄存器是 128 位宽,如果你只需要处理 64 位的数据元素,寄存器的 “半满” 情况就可能发生。
指令和掩码的作用:在 RVV 中,某些指令可以允许掩码操作(例如,vfmv_v_f_f64m1),这意味着某些元素可能会被忽略或处理为零, ...
RISCV内存管理单元
RISC-V 向量扩展(RVV, RISC-V Vector Extension)中的指令可以大致分为三大类:设置向量长度(setvl)、加载/存储(load/store)、和 数学运算(mathematical operations)。以下是这三类指令的详细描述:
setvl 指令
setvl 指令用于设置向量长度,并返回当前向量长度。它是 RVV 中的核心指令,用于动态地控制每条指令处理的向量元素数量。通过设置向量长度寄存器(vl),可以使得后续的指令在处理数据时,按照给定的向量长度来处理。
指令格式:
1setvl xlen, rs1
功能:
设置向量长度(vl)。
rs1 寄存器的值决定了目标向量长度(vl)。
返回的向量长度会被存储在 vlen 寄存器中。
示例:
1setvl x0, x1 // 设置向量长度
加载/存储指令(Load/Store)
加载和存储指令用于将数据从内存加载到向量寄存器中,或者将向量寄存器中的数据存储回内存。这些指令的操作对象是向量寄存器,可以处理多个数据元素。
加载指令(Vector Loa ...
RVOS系统
start.s文件(.s文件是汇编语言源代码文件的扩展,包含了汇编语言代码,直接对应目标处理器的ISA)
一个典型的.s文件文件包含了以下几个部分:
数据段:存储程序使用的常量、字符串、数组等数据。
代码段:存储实际程序指令。
全局符号和标签:定义程序中的使用的标识符和函数名,供汇编器和链接器使用
编写一个简单RISC-V的系统
需要以下几个文件部分:
platform.h(硬件信息)
start.s(
初始化堆栈:为每个 hart 分配堆栈空间,并初始化栈指针 sp。
挂起非 hart 0 的核心:通过 wfi 指令将非 hart 0 的核心挂起,直到 hart 0 启动内核。
设置堆栈对齐:确保堆栈空间的对齐,以便符合 RISC-V 的 16 字节对齐规则。
多核心初始化:通过 hart id 为每个核心分配独立的堆栈空间。)
uart.c(交互显示)
宏定义uart所需要的寄存器。
uart初始化(打开或者关闭中断,设置串口的数据位、停止位、校验位、禁止波特锁存器)
定义uart输出函数输入函数
Makefile(编译的构建规则)
types.h(记录数据类型)
kern ...
RISCV Vector test
进行数组上的数据相加合并12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182#include <stdio.h>#include <stdlib.h>#include <riscv_vector.h>#include <time.h>// 正常的数组相加函数void array_add_normal(size_t n, const float *a, const float *b, float *c) { for (size_t i = 0; i < n; i++) { c[i] = a[i] + b[i]; }}// 使用 RVV 向量化的数组相加函数void array_add_rvv(size_t n, co ...
RISCV Vector
注意:
首先硬件可能支持不同版本的向量扩展,这之间不同版本互不兼容。
qemu上虽然可以跑RVV程序,但是开销比标量运算还大,所以只能做程序验证,实际运行效率要上实际的riscvgv的机器上才行。
ubuntu22.04尽管使用qemu但是也不支持rvv,因为kernel内核中的mstatus寄存器(机器模式下的状态寄存器)未初始化,当mstatus.vs域值被写0时候,试图执行向量指令或访问向量寄存器均会引发非法指令异常。
自动向量化和手动向量化
关于向量化:
对GCC或者LLVM进行开发(自动向量化)
**前端编译扩展 Target Transform Info (TTI)**:
定义目标架构的向量化能力(RVV 支持可扩展向量)。
例如为 RISC-V 增强 getRegisterBitWidth 和 getTypeLegalizationCost 方法。
修改 Loop 和 SLP Vectorizer:
添加对 RVV 动态向量寄存器的支持。
修改默认的向量化策略以生成动态向量类型。
支持 RVV 的 IR 到目标代码映射:
在后 ...

