Files
c_soft/riscv_cpu/riscv.h

259 lines
7.4 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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