#ifndef riscv_h__ #define riscv_h__ #include "stdint.h" /* 每个指令长度为32bit,分为6个类型 |--------------+------------+-----------+-------------+--------------+---------------| | [31-25] | [24-20] | [19-15] | [14-12] | [11-7] | [6-0] | |--------------+------------+-----------+-------------+--------------+---------------| | funct7 | rs2 | rs1 | funct3 | rd | opcode | R-type 计算指令 |--------------+------------+-----------+-------------+--------------+---------------| | imm[11:0] | rs1 | funct3 | rd | opcode | I-type 加载指令 |--------------+------------+-----------+-------------+--------------+---------------| | imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode | S-type 存储指令 |--------------+------------+-----------+-------------+--------------+---------------| |imm[12] [10:5]| rs2 | rs1 | funct3 | imm[4:1][11] | opcode | B-type 分支指令 |--------------+------------+-----------+-------------+--------------+---------------| | imm[31:12] | rd | opcode | U-type 立即数指令 |-----------------------------------------------------+--------------+---------------| | imm[20] [10:1] [11] [19:12] | rd | opcode | J-type 跳转指令 |-----------------------------------------------------+--------------+---------------| */ // 定义opcode #define opcode_lui 0x37 // U-type #define opcode_auipc 0x17 // U-type #define opcode_jal 0x6f // J-type #define opcode_jalr 0x67 // I-type // B-type #define opcode_beq 0x63 #define opcode_bne 0x63 #define opcode_blt 0x63 #define opcode_bge 0x63 #define opcode_bltu 0x63 #define opcode_bgeu 0x63 // I-type #define opcode_lb 0x03 #define opcode_lh 0x03 #define opcode_lw 0x03 #define opcode_lbu 0x03 #define opcode_lhu 0x03 // S-type #define opcode_sb 0x23 #define opcode_sh 0x23 #define opcode_sw 0x23 // I-type #define opcode_addi 0x13 #define opcode_slti 0x13 #define opcode_sltiu 0x13 #define opcode_xori 0x13 #define opcode_ori 0x13 #define opcode_andi 0x13 #define opcode_slli 0x13 #define opcode_srli 0x13 #define opcode_srai 0x13 // R-type #define opcode_add 0x33 #define opcode_sub 0x33 #define opcode_sll 0x33 #define opcode_slt 0x33 #define opcode_sltu 0x33 #define opcode_xor 0x33 #define opcode_srl 0x33 #define opcode_sra 0x33 #define opcode_or 0x33 #define opcode_and 0x33 #define opcode_fence 0x0f #define opcode_fence_i 0x0f // 系统调用 #define opcode_ecall 0x73 #define opcode_ebreak 0x73 #define opcode_csrrw 0x73 #define opcode_csrrs 0x73 #define opcode_csrrc 0x73 #define opcode_csrrwi 0x73 #define opcode_csrrsi 0x73 #define opcode_csrrci 0x73 #define MEM_SIZE 1024*1024 #define MEM_ADDR_BASE 0x10000000 #define zero reg[0] #define ra reg[1] #define sp reg[2] #define gp reg[3] #define tp reg[4] #define t0 reg[5] #define t1 reg[6] #define t2 reg[7] #define s0 reg[8] #define s1 reg[9] #define a0 reg[10] #define a1 reg[11] #define a2 reg[12] #define a3 reg[13] #define a4 reg[14] #define a5 reg[15] #define a6 reg[16] #define a7 reg[17] #define s2 reg[18] #define s3 reg[19] #define s4 reg[20] #define s5 reg[21] #define s6 reg[22] #define s7 reg[23] #define s8 reg[24] #define s9 reg[25] #define s10 reg[26] #define s11 reg[27] #define t3 reg[28] #define t4 reg[29] #define t5 reg[30] #define t6 reg[31] #define fp reg[8] // 不需要做符号扩展 #define imm_u_type(_ins,_imm) {\ _imm = (_ins >> 12) << 12;\ } // 20位符号扩展 #define imm_j_type(_ins,_imm) {\ _imm = ((_ins >> 21) & 0x3ff) << 1;\ _imm |= ((_ins >> 20) & 1) << 11;\ _imm |= ((_ins >> 12) & 0xff) << 12;\ _imm |= ((_ins >> 31) & 1) << 20;\ if(_imm&(1<<20)){\ _imm|=0xfff00000;\ }\ } // 12位符号扩展 #define imm_i_type(_ins,_imm) {\ _imm = (_ins >> 20) & 0xfff;\ if(_imm&(1<<11)){\ _imm|=0xfffff000;\ }\ } // 13位符号扩展 #define imm_b_type(_ins,_imm) {\ _imm = ((_ins >> 31) & 1) << 12;\ _imm |= ((_ins >> 7) & 0x1) << 11;\ _imm |= ((_ins >> 8) & 0xf) << 1;\ _imm |= ((_ins >> 25) & 0x3f) << 5;\ if(_imm&(1<<12)){\ _imm|=0xfffff000;\ }\ } // 12位符号扩展 #define imm_s_type(_ins,_imm) {\ _imm = ((_ins >> 7) & 0x1f);\ _imm |= (_ins >> 25) << 5;\ if(_imm&(1<<11)){\ _imm|=0xfffff000;\ }\ } #define imm_csr(_ins,_imm) {\ _imm = (_ins >> 20) & 0xfff;\ } #define DEVICE_MAX_NUM 16 struct riscv_t; typedef struct device_t{ uint32_t addr; uint32_t size; uint32_t (*read)(uint32_t addr); void (*write)(uint32_t addr, uint32_t data); void (*run)(struct riscv_t *riscv,const struct device_t* device); void (*init)(const struct device_t* device); }device_t; typedef struct riscv_t{ uint32_t mem[MEM_SIZE]; const device_t* device_list[DEVICE_MAX_NUM]; uint32_t device_num; uint32_t* rom; uint32_t rom_size; uint32_t rom_addr_base; uint32_t pc; uint32_t pc_modify;// pc 指针已经被修改 不要自动递增 int32_t exc_code; uint32_t reg[32]; uint32_t csrs[4096]; }riscv_t; #define mem_wr(addr) riscv->mem[(addr-MEM_ADDR_BASE) >> 2] #define mem_wrb(addr) ((uint8_t *)riscv->mem)[(addr-MEM_ADDR_BASE)] #define mem_wrh(addr) ((uint16_t *)riscv->mem)[(addr-MEM_ADDR_BASE) >> 1] #define rom_wr(addr) riscv->rom[(addr-riscv->rom_addr_base) >> 2] #define rom_wrb(addr) ((uint8_t *)(riscv->rom))[(addr-riscv->rom_addr_base)] #define rom_wrh(addr) ((uint16_t *)(riscv->rom))[(addr-riscv->rom_addr_base) >> 1] // trap 相关定义 #define mstatus csrs[0x300] // 机器状态寄存器 #define misa csrs[0x301] // ISA扩展 #define medeleg csrs[0x302] // 异常委托寄存器 #define mideleg csrs[0x303] // 中断委托寄存器 #define mie csrs[0x304] // 中断使能寄存器 #define mtvec csrs[0x305] // 异常向量寄存器 #define mcounteren csrs[0x306] // 统计计数器使能寄存器 #define mstatush csrs[0x310] // 添加的状态寄存器高 #define mscratch csrs[0x340] // 存储器 软件中可用于暂时存放一个字大小的数据 #define mepc csrs[0x341] // 异常程序计数器 指向发生异常的指令 #define mcause csrs[0x342] // 异常原因寄存器 #define mtval csrs[0x343] // 异常值寄存器 地址例外出错的地址 非法指令本身 #define mip csrs[0x344] // 中断请求寄存器 它列出正在准备处理的中断 #define mtinst csrs[0x34a] // 存储器指令寄存器 当发生异常时,它包含异常指令 #define mtval2 csrs[0x34b] // 坏的物理地址 #define mcycle csrs[0xc00] // 循环计数器 #define minstret csrs[0xc02] // 执行指令计数器 // 只有机器模式的cpu只有这两个位起作用 清除这两个位表示禁用全局中断 #define MSTATUS_MIE 0x00000008 // 中断使能位 #define MSTATUS_MPIE 0x00000080 // 进异常时会自动清除MIE MPIE是清除之前的状态 #define MIP_MSIP (1 << IRQ_M_SOFT) #define MIP_MTIP (1 << IRQ_M_TIMER) #define MIP_MEIP (1 << IRQ_M_EXT) #define IRQ_M_SOFT 3 #define IRQ_M_TIMER 7 #define IRQ_M_EXT 11 int riscv_register_device(riscv_t* riscv, const device_t* device); int riscv_init(riscv_t* riscv, uint32_t* rom, uint32_t rom_addr_base, uint32_t rom_size); int riscv_device_init(riscv_t* riscv); int riscv_run(riscv_t* riscv); #endif