三级页表虚拟地址翻译
SV39使用39位虚拟地址,通过三级页表翻译为56位物理地址:
| 级别 | 索引 | 页大小 | 表项数 |
|---|---|---|---|
| Level 1 | VPN[2] | — | 512 |
| Level 2 | VPN[1] | — | 512 |
| Level 3 | VPN[0] | 4KB | 512 |
| R W X | 类型 | 权限 |
|---|---|---|
| 0 0 0 | Non-leaf(指向下一级) | — |
| 1 0 0 | Read-only | 只读 |
| 1 1 0 | Read-Write | 读写 |
| 1 0 1 | Read-Execute | 只读+执行(代码段) |
| 1 1 1 | Read-Write-Execute | 全部权限 |
| 0 1 0 | Reserved | 非法 |
// Lesson 09: SV39 Virtual Memory — Three-Level Page Table
module sv39_mmu(
input wire clk, rst_n,
input wire enable,
input wire [38:0] vaddr,
input wire [55:0] ptbase,
output reg [55:0] paddr,
output reg valid,
output reg fault,
output reg [1:0] pte_perm
);
wire [8:0] vpn2 = vaddr[38:30], vpn1 = vaddr[29:21], vpn0 = vaddr[20:12];
wire [11:0] offset = vaddr[11:0];
reg [63:0] l1_pte[0:511], l2_pte[0:511], l3_pte[0:511];
integer i;
initial begin
for(i=0;i<512;i=i+1) begin l1_pte[i]=0; l2_pte[i]=0; l3_pte[i]=0; end
l1_pte[0] = {44'd1, 2'b00, 4'b0000, 1'b0, 1'b0, 1'b1, 11'd0};
l2_pte[0] = {44'd2, 2'b00, 4'b0000, 1'b0, 1'b0, 1'b1, 11'd0};
l3_pte[0] = {44'd3, 2'b00, 4'b0000, 1'b1, 1'b1, 1'b1, 11'd0};
end
reg [1:0] stage; reg [8:0] sv_vpn2,sv_vpn1,sv_vpn0; reg [11:0] sv_offset;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin paddr<=0; valid<=0; fault<=0; pte_perm<=0; stage<=0; end
else if(!enable) begin paddr<={17'd0,vaddr}; valid<=1; fault<=0; stage<=0; end
else begin
case(stage)
0: begin sv_vpn2<=vpn2; sv_vpn1<=vpn1; sv_vpn0<=vpn0; sv_offset<=offset;
if(!l1_pte[vpn2][0]) begin fault<=1; valid<=0; end
else if(l1_pte[vpn2][1]||l1_pte[vpn2][2]||l1_pte[vpn2][3]) begin
paddr<={l1_pte[vpn2][63:20],sv_vpn1,sv_vpn0,sv_offset};
pte_perm<={l1_pte[vpn2][1],l1_pte[vpn2][2]}; valid<=1; fault<=0; end
else stage<=1; end
1: begin if(!l2_pte[sv_vpn1][0]) begin fault<=1; valid<=0; stage<=0; end
else if(l2_pte[sv_vpn1][1]||l2_pte[sv_vpn1][2]||l2_pte[sv_vpn1][3]) begin
paddr<={l2_pte[sv_vpn1][63:20],sv_vpn0,sv_offset};
pte_perm<={l2_pte[sv_vpn1][1],l2_pte[sv_vpn1][2]}; valid<=1; fault<=0; stage<=0; end
else stage<=2; end
2: begin if(!l3_pte[sv_vpn0][0]) begin fault<=1; valid<=0; end
else begin paddr<={l3_pte[sv_vpn0][63:20],sv_offset};
pte_perm<={l3_pte[sv_vpn0][1],l3_pte[sv_vpn0][2]}; valid<=1; fault<=0; end
stage<=0; end
endcase
end
end
endmodule
Linux在RISC-V上的虚拟内存布局:
当TLB miss时,硬件页表遍历器(Page Table Walker)自动完成三级查找:
整个遍历需要3次内存访问。如果L2/L3页表不在Cache中,延迟可能高达100+个时钟周期。
| 资料 | 内容 | 链接 |
|---|---|---|
| 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→启动流程 |
建议使用以下环境进行实验:
| 模式 | 虚拟地址位宽 | 页表级数 | 虚拟空间 | 用途 |
|---|---|---|---|---|
| Sv32 | 32位 | 2级 | 4GB | RV32嵌入式 |
| Sv39 | 39位 | 3级 | 512GB | RV64标准 |
| Sv48 | 48位 | 4级 | 256TB | 大型服务器 |
| Sv57 | 57位 | 5级 | 128PB | 未来扩展 |
SV39覆盖512GB虚拟地址空间,对大多数应用足够。但大型数据库和AI训练框架可能需要更大的地址空间,这就是Sv48/Sv57存在的原因。
| 页面类型 | 大小 | TLB覆盖范围 | 用途 |
|---|---|---|---|
| 标准页 | 4KB | 4KB/TLB项 | 通用 |
| 大页(Mega) | 2MB | 2MB/TLB项 | 数据库、DPDK |
| 巨页(Giga) | 1GB | 1GB/TLB项 | 大内存虚拟机 |
大页显著减少TLB缺失:64项TLB + 2MB大页 = 128MB覆盖范围(vs 256KB with 4KB页)。Linux通过mmap(MAP_HUGETLB)或透明大页(THP)支持。