cemu
载入中...
搜索中...
未找到
cpu.c 文件参考

中央处理器实现 更多...

#include "csr.h"
#include "opcode.h"
#include "utils.h"

宏定义

#define ADDR_MISALIGNED(addr)   (addr & 0x3)
 
#define MAX_CPU_STEP   10
 

函数

static u64 cpu_load (CPU *cpu, u64 addr, u64 size)
 *处理器加载数据
 
static void cpu_store (CPU *cpu, u64 addr, u64 size, u64 value)
 *处理器存储数据
 
static void print_op (char *s)
 打印操作码
 
static int cpu_step_one (CPU *cpu)
 处理器执行一条指令
 
static u64 rd (u32 inst)
 
static u64 rs1 (u32 inst)
 
static u64 rs2 (u32 inst)
 
static u64 imm_I (u32 inst)
 
static u64 imm_S (u32 inst)
 
static u64 imm_B (u32 inst)
 
static u64 imm_U (u32 inst)
 
static u64 imm_J (u32 inst)
 
static u32 shamt (u32 inst)
 
static u64 csr (u32 inst)
 
void exec_LUI (CPU *cpu, u32 inst)
 
void exec_AUIPC (CPU *cpu, u32 inst)
 
void exec_JAL (CPU *cpu, u32 inst)
 
void exec_JALR (CPU *cpu, u32 inst)
 
void exec_BEQ (CPU *cpu, u32 inst)
 
void exec_BNE (CPU *cpu, u32 inst)
 
void exec_BLT (CPU *cpu, u32 inst)
 
void exec_BGE (CPU *cpu, u32 inst)
 
void exec_BLTU (CPU *cpu, u32 inst)
 
void exec_BGEU (CPU *cpu, u32 inst)
 
void exec_LB (CPU *cpu, u32 inst)
 
void exec_LH (CPU *cpu, u32 inst)
 
void exec_LW (CPU *cpu, u32 inst)
 
void exec_LD (CPU *cpu, u32 inst)
 
void exec_LBU (CPU *cpu, u32 inst)
 
void exec_LHU (CPU *cpu, u32 inst)
 
void exec_LWU (CPU *cpu, u32 inst)
 
void exec_SB (CPU *cpu, u32 inst)
 
void exec_SH (CPU *cpu, u32 inst)
 
void exec_SW (CPU *cpu, u32 inst)
 
void exec_SD (CPU *cpu, u32 inst)
 
void exec_ADDI (CPU *cpu, u32 inst)
 立即数相加
 
void exec_SLLI (CPU *cpu, u32 inst)
 
void exec_SLTI (CPU *cpu, u32 inst)
 
void exec_SLTIU (CPU *cpu, u32 inst)
 
void exec_XORI (CPU *cpu, u32 inst)
 
void exec_SRLI (CPU *cpu, u32 inst)
 
void exec_SRAI (CPU *cpu, u32 inst)
 
void exec_ORI (CPU *cpu, u32 inst)
 
void exec_ANDI (CPU *cpu, u32 inst)
 
void exec_ADD (CPU *cpu, u32 inst)
 
void exec_SUB (CPU *cpu, u32 inst)
 
void exec_SLL (CPU *cpu, u32 inst)
 
void exec_SLT (CPU *cpu, u32 inst)
 
void exec_SLTU (CPU *cpu, u32 inst)
 
void exec_XOR (CPU *cpu, u32 inst)
 
void exec_SRL (CPU *cpu, u32 inst)
 
void exec_SRA (CPU *cpu, u32 inst)
 
void exec_OR (CPU *cpu, u32 inst)
 
void exec_AND (CPU *cpu, u32 inst)
 
void exec_FENCE (CPU *cpu, u32 inst)
 
void exec_ECALL (CPU *cpu, u32 inst)
 
void exec_EBREAK (CPU *cpu, u32 inst)
 
void exec_ECALLBREAK (CPU *cpu, u32 inst)
 
void exec_ADDIW (CPU *cpu, u32 inst)
 
void exec_SLLIW (CPU *cpu, u32 inst)
 
void exec_SRLIW (CPU *cpu, u32 inst)
 
void exec_SRAIW (CPU *cpu, u32 inst)
 
void exec_ADDW (CPU *cpu, u32 inst)
 
void exec_MULW (CPU *cpu, u32 inst)
 
void exec_SUBW (CPU *cpu, u32 inst)
 
void exec_DIVW (CPU *cpu, u32 inst)
 
void exec_SLLW (CPU *cpu, u32 inst)
 
void exec_SRLW (CPU *cpu, u32 inst)
 
void exec_DIVUW (CPU *cpu, u32 inst)
 
void exec_SRAW (CPU *cpu, u32 inst)
 
void exec_REMW (CPU *cpu, u32 inst)
 
void exec_REMUW (CPU *cpu, u32 inst)
 
void exec_CSRRW (CPU *cpu, u32 inst)
 
void exec_CSRRS (CPU *cpu, u32 inst)
 
void exec_CSRRC (CPU *cpu, u32 inst)
 
void exec_CSRRWI (CPU *cpu, u32 inst)
 
void exec_CSRRSI (CPU *cpu, u32 inst)
 
void exec_CSRRCI (CPU *cpu, u32 inst)
 
void exec_LR_W (CPU *cpu, u32 inst)
 
void exec_SC_W (CPU *cpu, u32 inst)
 
void exec_AMOSWAP_W (CPU *cpu, u32 inst)
 
void exec_AMOADD_W (CPU *cpu, u32 inst)
 
void exec_AMOXOR_W (CPU *cpu, u32 inst)
 
void exec_AMOAND_W (CPU *cpu, u32 inst)
 
void exec_AMOOR_W (CPU *cpu, u32 inst)
 
void exec_AMOMIN_W (CPU *cpu, u32 inst)
 
void exec_AMOMAX_W (CPU *cpu, u32 inst)
 
void exec_AMOMINU_W (CPU *cpu, u32 inst)
 
void exec_AMOMAXU_W (CPU *cpu, u32 inst)
 
void exec_LR_D (CPU *cpu, u32 inst)
 
void exec_SC_D (CPU *cpu, u32 inst)
 
void exec_AMOSWAP_D (CPU *cpu, u32 inst)
 
void exec_AMOADD_D (CPU *cpu, u32 inst)
 
void exec_AMOXOR_D (CPU *cpu, u32 inst)
 
void exec_AMOAND_D (CPU *cpu, u32 inst)
 
void exec_AMOOR_D (CPU *cpu, u32 inst)
 
void exec_AMOMIN_D (CPU *cpu, u32 inst)
 
void exec_AMOMAX_D (CPU *cpu, u32 inst)
 
void exec_AMOMINU_D (CPU *cpu, u32 inst)
 
void exec_AMOMAXU_D (CPU *cpu, u32 inst)
 
void cpu_init (CPU *cpu)
 处理器初始化给定的CPU, 将指针指向的CPU中的寄存器全部置 0, 并将程序寄存器pc的值设为内存的起始地址。
 
u32 cpu_fetch (CPU *cpu)
 处理器从内存(DRAM)中读取指令用于执行, 并将其存入指令变量inst中。
 
int cpu_execute (CPU *cpu, u32 inst)
 处理器将从DRAM中取得并存放 在inst变量中的指令解码并执行。本质上是 ALU 和指令译码器的组合。
 
int cpu_step (CPU *cpu, int step)
 处理器步进执行
 
int cpu_loop (CPU *cpu, char *filename)
 处理器循环执行
 
void cpu_dump_regs (CPU *cpu)
 处理器查看寄存器的值
 

详细描述

中央处理器实现

作者
lancer (lance.nosp@m.rsta.nosp@m.dium@.nosp@m.163..nosp@m.com)
版本
0.1
日期
2024-01-08
注解
当编写 exec 函数时,应当注意 0 扩展与符号扩展。 例如,立即数在与寄存器中的其它值一起被操作时, 通常是符号扩展到 64 位。我们可以在需要时通过 C 语言的类型转换(int32_t) > (int64_t) > (u64) 来实现符号位扩展。

函数说明

◆ cpu_dump_regs()

void cpu_dump_regs ( CPU * cpu)

处理器查看寄存器的值

参数
cpu中央处理器

◆ cpu_execute()

int cpu_execute ( CPU * cpu,
u32 inst )

处理器将从DRAM中取得并存放 在inst变量中的指令解码并执行。本质上是 ALU 和指令译码器的组合。

注解
操作码告诉我们要对给定的地址和寄存器进行什么操作。 具体要进行什么操作取决于 3 个值: 操作码 opcode,funct3 和 funct7。 根据指令映射, 我们用以下 cpu_execute 函数对这 3 个部分进行译码。

◆ cpu_fetch()

u32 cpu_fetch ( CPU * cpu)

处理器从内存(DRAM)中读取指令用于执行, 并将其存入指令变量inst中。

参数
cpu中央处理器
返回
u32 32-bit 指令数据

◆ cpu_init()

void cpu_init ( CPU * cpu)

处理器初始化给定的CPU, 将指针指向的CPU中的寄存器全部置 0, 并将程序寄存器pc的值设为内存的起始地址。

参数
cpu中央处理器

◆ cpu_load()

static u64 cpu_load ( CPU * cpu,
u64 addr,
u64 size )
inlinestatic

*处理器加载数据

参数
cpu中央处理器
addr地址
size数据大小
返回
u64 数据

◆ cpu_loop()

int cpu_loop ( CPU * cpu,
char * filename )

处理器循环执行

注解
三级流水线CPU
  • 第 1 级流水线由函数cpu_fetch()处理。
  • 第 2、3 级流水线由定义在cpu.h中的函数cpu_execute()一并处理。
  • 程序计数器pc在每次循环后增加 4 个字节(32 位,因为每个 RISC-V 指令长度都为 32 位), 以获取下一条指令。因此 CPU 执行循环可以被写为下面这样:

◆ cpu_step()

int cpu_step ( CPU * cpu,
int step )

处理器步进执行

参数
cpu中央处理器
step步数
返回
int 错误代码

◆ cpu_step_one()

static int cpu_step_one ( CPU * cpu)
static

处理器执行一条指令

参数
cpu中央处理器
返回
int 错误代码

◆ cpu_store()

static void cpu_store ( CPU * cpu,
u64 addr,
u64 size,
u64 value )
inlinestatic

*处理器存储数据

参数
cpu中央处理器
addr地址
size数据大小
value数据

◆ exec_ADDI()

void exec_ADDI ( CPU * cpu,
u32 inst )

立即数相加

参数
cpu处理器
inst指令

◆ print_op()

static void print_op ( char * s)
static

打印操作码

参数
s操作码字符串