控制状态寄存器:RISC-V处理器的控制面板
RISC-V的CSR采用12位地址空间(0x000-0xFFF),按特权级和功能分区:
| CSR | 地址 | 功能 | 关键位 |
|---|---|---|---|
| mstatus | 0x300 | 机器状态 | MIE, MPIE, MPP |
| mie | 0x304 | 中断使能 | MEIE, MSIE, MTIE |
| mip | 0x344 | 中断等待 | MEIP, MSIP, MTIP |
| mtvec | 0x005 | 中断向量基址 | BASE, MODE |
| mepc | 0x341 | 异常返回地址 | PC值 |
| mcause | 0x342 | 异常原因 | Interrupt, Exception Code |
RISC-V提供专用CSR指令,保证读-修改-写操作的原子性:
| 指令 | 操作 | 等价C | 用途 |
|---|---|---|---|
| CSRRW | rd = CSR; CSR = rs1 | swap | 整体替换 |
| CSRRS | rd = CSR; CSR |= rs1 | set bits | 设置标志位 |
| CSRRC | rd = CSR; CSR &= ~rs1 | clear bits | 清除标志位 |
| CSRRWI | rd = CSR; CSR = zimm | swap imm | 立即数替换 |
// Lesson 02: CSR Registers — Read/Write with RS/RC operations
module csr_registers(
input wire clk, rst_n,
input wire [11:0] csr_addr,
input wire csr_read_en, csr_write_en,
input wire [31:0] csr_wdata,
input wire [1:0] csr_op, // 00=RW, 01=RS(set), 10=RC(clear)
output reg [31:0] csr_rdata,
output reg csr_illegal
);
reg [31:0] mstatus, mie, mip, mepc, mcause, mtvec;
always @(*) begin
csr_rdata = 32'b0; csr_illegal = 1'b0;
case (csr_addr)
12'h300: csr_rdata = mstatus;
12'h304: csr_rdata = mie;
12'h344: csr_rdata = mip;
12'h341: csr_rdata = mepc;
12'h342: csr_rdata = mcause;
12'h005: csr_rdata = mtvec;
default: csr_illegal = 1'b1;
endcase
end
wire [31:0] new_val = (csr_op == 2'b00) ? csr_wdata :
(csr_op == 2'b01) ? (csr_rdata | csr_wdata) :
(csr_rdata & ~csr_wdata);
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
mstatus <= 0; mie <= 0; mip <= 0;
mepc <= 0; mcause <= 0; mtvec <= 32'h00000400;
end else if (csr_write_en && !csr_illegal) begin
case (csr_addr)
12'h300: mstatus <= new_val;
12'h304: mie <= new_val;
12'h344: mip <= new_val;
12'h341: mepc <= new_val;
12'h342: mcause <= new_val;
12'h005: mtvec <= new_val;
endcase
end
end
endmodule
以下是一些真实系统中CSR操作的例子:
CSR操作的效率直接影响系统性能。Linux在上下文切换时需要读写约20个CSR,每次切换开销约200个时钟周期。
| 资料 | 内容 | 链接 |
|---|---|---|
| RISC-V特权规范 | CSR、Trap、中断完整定义 | riscv.org/specifications |
| RISC-V手册 | 中文版免费教材 | crva.ict.ac.cn |
| OpenSBI源码 | M-mode固件参考实现 | github.com/riscv/opensbi |
| Linux RISC-V | 内核移植与驱动 | kernel.org |
| BOOM处理器 | UC Berkeley开源OoO核心 | github.com/riscv-boom/riscv-boom |
| 香山处理器 | 中科院开源高性能核心 | github.com/OpenXiangShan |
| 课程范围 | 课程号 | 主题 |
|---|---|---|
| 特权架构 | 01-06 | 特权级→CSR→ecall→mret→trap→中断 |
| 内存系统 | 07-12 | PLIC→CLINT→SV39→TLB→直接映射→组相联 |
| 算术单元 | 13-14 | Booth乘法器→恢复余数除法 |
| 乱序执行 | 15-19 | OoO→ROB→寄存器重命名→记分牌→Tomasulo |
| 分支预测 | 20-21 | 2位预测器→BTB |
| RISC-V扩展 | 22-26 | RVC→RVM→RVA→RVF→RVD |
| 系统集成 | 27-30 | PMP→解码器→SoC→启动流程 |
建议使用以下环境进行实验:
RISC-V定义了一组硬件性能计数器,可通过CSR访问:
| CSR | 地址 | 功能 |
|---|---|---|
| mcycle | 0xB00 | 已执行的时钟周期数 |
| minstret | 0xB02 | 已执行的指令数 |
| mhpmcounter3-31 | 0xB03-B1F | 可编程事件计数器 |
| mhpmevent3-31 | 0x323-33F | 事件选择寄存器 |
| mcountinhibit | 0x320 | 计数器使能/禁用 |
通过mcycle和minstret可以计算IPC(Instructions Per Cycle):
mcounteren CSR控制U-mode是否可以读取性能计数器。Linux默认使能CY、TM、IR三个位,允许用户态通过rdcycle、rdtime、rdinstret伪指令读取。