在通过RISC-V规范时,我注意到64位版本与32位版本的不同之处在于,
这使得RV32代码不兼容RV64。但是,如果64位版本已经实施方式:
ADD/SUB/SHL/..到ADDW/SUBW/SHLW/..与标志让他们只能在32位操作系统上延伸。ADD/SUB/SHL/..或ADDD/SUBD/SHLD/..在全部64位行为这样,RV32程序也可以在RV64上运行。为了实现CPU,工作量将保持不变,因为在两种情况下都必须实现64位和32位指令,而只有64位和32位版本的操作码将被交换。符合规范。(除了乘法指令。)
那么,为什么RISC-V为什么决定将新的操作码分配给RV64中的32位操作而不是64位操作?
我目前正在研究RISC-V的规范,规范版本为2.2,Privileged Architecture版本为1.10.在RISC-V规范的第2章中,提到"......虽然简单的实现可能会覆盖8个SCALL/SBREAK/CSRR*指令,并且只有一条SYSTEM硬件指令总是陷阱......"
但是,当我查看特权规范时,该指令MRET也是一条SYSTEM指令,需要从陷阱返回.现在我很困惑需要多少机器级ISA:是否可以省略所有M级CSR并使用软件处理程序来处理任何SYSTEM指令,如规范中所述?如果是这样,如何传递返回地址和陷阱等信息?它们是通过常规寄存器x1-x31完成的
或者,如果我的目标是仅具有M级特权的简单嵌入式核心,那么仅仅实现以下M级CSR就足够了吗?
mvendorid
marchid
mimpid
mhartid
misa
mscratch
mepc
mcause
Run Code Online (Sandbox Code Playgroud)
最后,这些CSR可以省略多少?
LUI(立即加载上限)用于构建32位常量,并使用U型格式。LUI将U中间值放在目标寄存器rd的高20位中,并用零填充最低12位。
我在手册中找到了这个,但是如果我想将0xffffffff移到寄存器中,我需要的所有代码是:
LUI x2, 0xfffff000
ADDI x2, x2, 0xfff
Run Code Online (Sandbox Code Playgroud)
但是发生了一个问题,ADDI将扩展符号以使立即数据成为带符号的数字,因此0xfff将扩展到0xffffffff。
这使x2以0xffffefff,但不0xffffffff
什么是立即移动32位进行注册的良好实现?
我最近正在处理RISC-V 32I指令。我有一个关于NOP指令的问题,规范说它等于ADDI x0, x0, 0。
但是,x0不是可以由程序员修改的通用寄存器。因此,为什么x0在这里用作NOP指令的目的地寄存器?
任何人都可以在这点上阐明一些观点吗?
我正在寻求有关我尝试添加的扩展的帮助 riscv。
我的工作基线是riscv-toolsrepo的克隆,包含常用工具,其中包括:
注意:我克隆的最后一次提交是c6d58cecb3862deb742e1a5cc9d1c682f2c50ba9(2018-04-24)。
我的工作基于一个riscv32-ima核心。我想向该处理器添加一条指令,该指令ISA将激活我的处理器中的特定组件。
从 proc 本身的行为来看,我没有问题:我修改了尖峰并且我的指令(以及我添加到处理器的组件)工作得很好。
在汇编程序中,指令如下所示:
addi a0, a0, 0
... // other code
setupcomp // activate my component ...
... // other code
Run Code Online (Sandbox Code Playgroud)
看到这条指令没有任何操作数。
我躲了一会儿,发现这个教程有点旧。
所以我:
riscv-tools/riscv-opcodes/将opcode及其掩码添加到riscv-tools/riscv-opcodes/opcodes. 我的看起来像这样:
setupcomp 31..28=ignore 27..20=ignore 19..15=ignore 14..12=0 11..7=ignore 6..2=0x1a 1..0=3
Run Code Online (Sandbox Code Playgroud)从那里,我重建必要的.h文件:
make install
Run Code Online (Sandbox Code Playgroud)现在,我将必要的添加stucts到riscv-tools/riscv-gnu-toolchain/riscv-binutils-gdb/include/opcode/riscv-opc.h,并且我还正式声明了指令:
#define MATCH_SETUPCOMP 0x6b
#define …Run Code Online (Sandbox Code Playgroud)我不明白 JAL 在 RISC-V 中是如何工作的,因为我看到了多个相互矛盾的定义。例如,如果我参考这个网站:https : //rv8.io/isa.html
它说:
JAL rd,offset将第三个参数作为偏移量,但在某些情况下会显示JAL rd, imm。有什么不同?
看来,JAL应该采取功能和RD返回其输出(我不知道为什么有些人士把它称为ra并且rd在同一时间)。但如果是这样,子程序或函数是什么?rd似乎被定义为寄存器目的地,imm似乎只是一个整数..
真的很困惑请帮忙。
我在Chisel3中编写了一个单周期CPU,该CPU实现了大多数RV32I指令(CSR,Fence,ECALL / BREAK,LB / SB除外,稍后可能会提供这些指令)。目前,指令已在指令存储器中进行了硬编码,但是我将对其进行更改,以便它从文件中读取指令。我在如何实际模拟设计方面遇到麻烦。这是我将所有组件“粘合”在一起的代码。
class Core extends Module {
val io = IO(new Bundle {
val dc = Input(Bool())
})
io := DontCare
val pc = RegInit(0.U)
val pcSelect = Module(new PcSelect())
val pcPlusFour = Module(new Adder())
val alu = Module(new ALU())
val aluControl = Module(new AluControl())
val control = Module(new Control())
val immGen = Module(new ImmGen())
val branchLogic = Module(new BranchLogic())
val branchUnit = Module(new Adder())
val jumpReg = Module(new JumpReg())
val regFile = Module(new RegFile())
val jumpAdder …Run Code Online (Sandbox Code Playgroud) 我编写并编译了一个RISC-V Linux 应用程序。
我想转储在运行时执行的所有指令(静态分析无法实现)。
是否可以从 QEMU(或其他工具)获取动态汇编指令执行直方图?
我目前正在将nacl库转换为risc-v。我已经有poly1305工作。我正在尝试使用risc-v核心指令集来执行此操作,因此我没有乘法器。Pol1305的算法正在使用ceil(m / 16)* 17 * 17 8位乘法,其中m是消息长度(以字节为单位)(两个2 ^ 130整数乘以2 ^ 8以2 ^ 130-5为基数) 。因此,我想使用快速乘法算法来保持快速。
目前,我有用于乘法的移位加法算法。但是,对于8位值,这需要63个周期,因为我需要避免分支(定时侧通道),因此涉及一些需要更多周期的屏蔽。
andi t2, t0, 1 //t0 is the multiplier
sub t2, zero, t2 //creating a mask
and t3, t1, t2 //applying the mask to the multiplicand
add a0, a0, t3 //doing the add
srli t0, t0, 1 //shifting the multiplier
slli t1, t1, 1 //shifting the multiplicand
Run Code Online (Sandbox Code Playgroud)
这给了我每次乘法63个周期的有效结果。问题在于,对于131字节的消息,程序的总执行时间为175219个周期。此时,将9 * 17 * 17 * 63 = 163863个周期用于乘法。我想改善。
assembly multiplication micro-optimization modular-arithmetic riscv
我想检测一个程序来访问硬件性能计数器。
我已经编译了一个基本的 Rocketchip ( freechips.rocketchip.system-DefaultConfig) 并riscv-pk用于运行二进制文件。我正在 Verilator 中运行内核的模拟,在 UCB Chipyard 项目中使用大部分默认值编译了它。
二进制文件的 C 如下:
#include <stdio.h>
#define CACHE_MISS 0x100
int loop(int n, int a) {
int b = 0;
for(int i=0; i<n; i++) {
b = a + b;
}
return b;
}
int main() {
int a = 1;
int n = 200;
int count = 0;
printf("Configuring event monitor ...\n");
/*
// initialize counters here
// should start tracking cache misses with 0x100
__asm__ volatile("csrw …Run Code Online (Sandbox Code Playgroud) riscv ×10
assembly ×4
32bit-64bit ×1
architecture ×1
binutils ×1
chisel ×1
hardware ×1
hdl ×1
interrupt ×1
linux ×1
nop ×1
opcode ×1
qemu ×1
simulation ×1
trace ×1