标签: riscv

为什么RV64为32位操作而不是64位操作引入了新的操作码

在通过RISC-V规范时,我注意到64位版本与32位版本的不同之处在于,

  1. 将寄存器扩展到64位
  2. 更改了指令以对整个64位范围执行操作。
  3. 添加了新指令以执行32位操作

这使得RV32代码不兼容RV64。但是,如果64位版本已经实施方式:

  1. 将寄存器扩展到64位
  2. 重命名ADD/SUB/SHL/..ADDW/SUBW/SHLW/..与标志让他们只能在32位操作系统上延伸。
  3. 添加新的指令ADD/SUB/SHL/..ADDD/SUBD/SHLD/..在全部64位行为

这样,RV32程序也可以在RV64上运行。为了实现CPU,工作量将保持不变,因为在两种情况下都必须实现64位和32位指令,而只有64位和32位版本的操作码将被交换。符合规范。(除了乘法指令。)

那么,为什么RISC-V为什么决定将新的操作码分配给RV64中的32位操作而不是64位操作?

assembly instruction-set opcode 32bit-64bit riscv

5
推荐指数
1
解决办法
453
查看次数

如何将RISC-V SYSTEM指令实现为陷阱?

我目前正在研究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可以省略多少?

exception-handling interrupt cpu-architecture riscv

5
推荐指数
1
解决办法
1058
查看次数

RISC-V使用LUI和ADDI构建32位常量

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

这使x20xffffefff,但不0xffffffff

什么是立即移动32位进行注册的良好实现?

riscv

5
推荐指数
3
解决办法
2929
查看次数

RISC-V NOP指令

我最近正在处理RISC-V 32I指令。我有一个关于NOP指令的问题,规范说它等于ADDI x0, x0, 0

但是,x0不是可以由程序员修改的通用寄存器。因此,为什么x0在这里用作NOP指令的目的地寄存器?

任何人都可以在这点上阐明一些观点吗?

assembly nop riscv

5
推荐指数
2
解决办法
1497
查看次数

向 RISCV-32ima 添加新指令:“错误的 RISCV 操作码”

我正在寻求有关我尝试添加的扩展的帮助 riscv

全局设置

我的工作基线是riscv-toolsrepo的克隆,包含常用工具,其中包括:

  • riscv-fesvr
  • riscv-gnu-工具链
  • riscv-isa-sim
  • riscv 操作码
  • RISCV-PK

注意:我克隆的最后一次提交是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)

看到这条指令没有任何操作数。

我所做的

我躲了一会儿,发现这个教程有点旧

所以我:

  1. riscv-tools/riscv-opcodes/
  2. 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)
  3. 从那里,我重建必要的.h文件:

    make install
    
    Run Code Online (Sandbox Code Playgroud)
  4. 现在,我将必要的添加stuctsriscv-tools/riscv-gnu-toolchain/riscv-binutils-gdb/include/opcode/riscv-opc.h,并且我还正式声明了指令:

    #define MATCH_SETUPCOMP 0x6b
    #define …
    Run Code Online (Sandbox Code Playgroud)

binutils riscv

5
推荐指数
1
解决办法
1200
查看次数

RISC-V 中 JAL 的定义是什么以及如何使用它?

我不明白 JAL 在 RISC-V 中是如何工作的,因为我看到了多个相互矛盾的定义。例如,如果我参考这个网站:https : //rv8.io/isa.html

它说: JAL rd,offset将第三个参数作为偏移量,但在某些情况下会显示JAL rd, imm。有什么不同?

看来,JAL应该采取功能和RD返回其输出(我不知道为什么有些人士把它称为ra并且rd在同一时间)。但如果是这样,子程序或函数是什么?rd似乎被定义为寄存器目的地,imm似乎只是一个整数..

真的很困惑请帮忙。

architecture hardware cpu-architecture riscv

5
推荐指数
2
解决办法
2万
查看次数

模拟用Chisel编写的CPU设计

我在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)

simulation hdl chisel riscv

5
推荐指数
1
解决办法
171
查看次数

在 QEMU 中记录动态指令跟踪或直方图?

  1. 我编写并编译了一个RISC-V Linux 应用程序

  2. 我想转储在运行时执行的所有指令(静态分析无法实现)。

是否可以从 QEMU(或其他工具)获取动态汇编指令执行直方图?

linux assembly trace qemu riscv

5
推荐指数
2
解决办法
1706
查看次数

在不使用乘法器的情况下,以2 ^ 8为基数加速大型模块化乘法

我目前正在将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

5
推荐指数
1
解决办法
458
查看次数

在 RISC-V 中访问硬件性能计数器

我想检测一个程序来访问硬件性能计数器。

我已经编译了一个基本的 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

5
推荐指数
1
解决办法
832
查看次数