最简单的Cache:一个地址对应一个Cache行
直接映射是最简单的Cache组织方式:每个内存地址只能映射到Cache中的一个固定位置:
| 操作 | 条件 | 动作 |
|---|---|---|
| 读命中 | Tag匹配 & Valid=1 | 返回Data |
| 读缺失 | Tag不匹配 或 Valid=0 | 从内存取数据 |
| 写命中 | Tag匹配 & Valid=1 | 更新Data, 置Dirty |
| 写缺失 | Tag不匹配 | 分配新行, 写入数据 |
| 替换 | 新行需用此位置 | 若Dirty则写回内存 |
// Lesson 11: Direct-Mapped Cache (16 entries)
module cache_direct(
input wire clk, rst_n,
input wire cpu_req, cpu_we,
input wire [31:0] cpu_addr, cpu_wdata,
output reg [31:0] cpu_rdata,
output reg cpu_hit,
output reg [31:0] mem_addr, mem_wdata,
output reg mem_req, mem_we
);
parameter ENTRIES = 16;
reg [25:0] tags [0:ENTRIES-1]; reg [31:0] data [0:ENTRIES-1];
reg valid [0:ENTRIES-1], dirty [0:ENTRIES-1];
wire [3:0] idx = cpu_addr[5:2]; wire [25:0] tag = cpu_addr[31:6];
wire tag_match = (tags[idx]===tag) && valid[idx];
integer i;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
for(i=0;i<ENTRIES;i=i+1) begin valid[i]<=0; dirty[i]<=0; end
cpu_hit<=0; mem_req<=0;
end else if(cpu_req) begin
if(tag_match) begin
cpu_hit<=1; mem_req<=0;
if(cpu_we) begin data[idx]<=cpu_wdata; dirty[idx]<=1; end
else cpu_rdata<=data[idx];
end else begin
cpu_hit<=0;
if(dirty[idx]&&valid[idx]) begin
mem_addr<={tags[idx],idx,2'b00}; mem_wdata<=data[idx];
mem_we<=1; mem_req<=1;
end else begin mem_req<=0; mem_we<=0; end
tags[idx]<=tag; valid[idx]<=1; dirty[idx]<=0;
if(cpu_we) begin data[idx]<=cpu_wdata; dirty[idx]<=1; end
end
end else begin cpu_hit<=0; mem_req<=0; mem_we<=0; end
end
endmodule
| Cache类型 | 命中率 | 硬件复杂度 | 功耗 |
|---|---|---|---|
| 直接映射 | 较低(冲突多) | 最低 | 最低 |
| 2路组相联 | 中等 | 中等 | 中等 |
| 4路组相联 | 较高 | 较高 | 较高 |
| 全相联 | 最高 | 最高 | 最高 |
虽然直接映射Cache命中率低,但它有独特优势:
| 场景 | 直接映射优势 | 原因 |
|---|---|---|
| 嵌入式处理器 | 面积小、功耗低 | 无需多路比较器 |
| I-Cache预取 | 顺序访问命中率高 | 指令顺序性好 |
| Scratchpad RAM | 确定性延迟 | 无替换策略 |
| FIFO缓存 | 简单高效 | 流式数据无需相联 |
直接映射Cache的关键洞察:如果工作集远小于Cache容量,直接映射的命中率接近100%。只有当工作集接近Cache容量时,冲突失效才成为问题。
| 资料 | 内容 | 链接 |
|---|---|---|
| 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→启动流程 |
建议使用以下环境进行实验:
分析Cache行为是性能优化的关键:
| 工具 | 平台 | 功能 |
|---|---|---|
| perf stat | Linux | 统计Cache命中/缺失次数 |
| perf record | Linux | 采样Cache事件,定位热点 |
| cachegrind | Valgrind | 模拟Cache行为,生成报告 |
| SimPoints | 仿真 | 找出代表性执行片段 |
| DINERO IV | 仿真 | Cache模拟器,可配置参数 |
写策略是Cache设计中最复杂的部分: