第23课 · 虚拟内存

页表TLB地址翻译

📌 学习目标:理解虚拟内存和页式地址翻译的原理,实现简化的 TLB,通过 Verilator 验证虚拟地址到物理地址的翻译。

一、为什么需要虚拟内存?

二、页式地址翻译

虚拟地址: [VPN(20bit)] [Offset(12bit)]
               ↓ 页表查找
物理地址: [PPN(20bit)] [Offset(12bit)]

页大小 = 4KB (2^12)
PTE: [Valid(1)] [PPN(20)] [R(1)] [W(1)] [X(1)]

三、TLB(Translation Lookaside Buffer)

TLB 是页表的 Cache:

TLB 命中 → 1 周期得到物理地址
TLB 缺失 → 查页表 → 填充 TLB → 重试
典型 TLB 命中率: >99%

四、简化设计参数

Verilog 实现

// tlb_simple.v — 简化TLB + 页表地址翻译 "keyword">module tlb_simple ( "keyword">input clk, rst, "keyword">input [15:0] vaddr, "keyword">input translate_en, "keyword">output "keyword">reg [15:0] paddr, "keyword">output "keyword">reg tlb_hit, tlb_miss, page_fault ); "keyword">parameter TLB_ENTRIES = 4; "keyword">parameter VPN_BITS = 8; "keyword">parameter PPN_BITS = 8; "keyword">parameter OFFSET_BITS = 8; "keyword">reg [VPN_BITS-1:0] tlb_vpn [0:TLB_ENTRIES-1]; "keyword">reg [PPN_BITS-1:0] tlb_ppn [0:TLB_ENTRIES-1]; "keyword">reg tlb_valid [0:TLB_ENTRIES-1]; "keyword">reg [29:0] page_table [0:255]; "keyword">reg [1:0] replace_ptr; "keyword">wire [VPN_BITS-1:0] vpn = vaddr[15:OFFSET_BITS]; "keyword">wire [OFFSET_BITS-1:0] offset = vaddr[OFFSET_BITS-1:0]; "keyword">integer i; "keyword">reg found; "keyword">reg [PPN_BITS-1:0] found_ppn; "keyword">always @(*) "keyword">begin found = 0; found_ppn = 0; "keyword">for (i = 0; i < TLB_ENTRIES; i = i + 1) "keyword">if (tlb_valid[i] && tlb_vpn[i] == vpn) "keyword">begin found = 1; found_ppn = tlb_ppn[i]; "keyword">end "keyword">end "keyword">wire pte_valid = page_table[vpn][29]; "keyword">wire [PPN_BITS-1:0] pte_ppn = page_table[vpn][28:21]; "keyword">always @("keyword">posedge clk "keyword">or "keyword">posedge rst) "keyword">begin "keyword">if (rst) "keyword">begin "keyword">for (i=0; i"keyword">begin tlb_valid[i]<=0; tlb_vpn[i]<=0; tlb_ppn[i]<=0; "keyword">end replace_ptr<=0; tlb_hit<=0; tlb_miss<=0; page_fault<=0; paddr<=0; "keyword">end "keyword">else "keyword">begin tlb_hit<=0; tlb_miss<=0; page_fault<=0; "keyword">if (translate_en) "keyword">begin "keyword">if (found) "keyword">begin paddr<={found_ppn,offset}; tlb_hit<=1; "keyword">end "keyword">else "keyword">begin tlb_miss<=1; "keyword">if (pte_valid) "keyword">begin tlb_vpn[replace_ptr]<=vpn; tlb_ppn[replace_ptr]<=pte_ppn; tlb_valid[replace_ptr]<=1; replace_ptr<=replace_ptr+1; paddr<={pte_ppn,offset}; "keyword">end "keyword">else page_fault<=1; "keyword">end "keyword">end "keyword">end "keyword">end "keyword">endmodule

测试台

// tb_tlb_simple.v "keyword">module tb_tlb_simple; "keyword">reg clk,rst; "keyword">reg [15:0] vaddr; "keyword">reg translate_en; "keyword">wire [15:0] paddr; "keyword">wire tlb_hit,tlb_miss,page_fault; tlb_simple uut(.*); "keyword">integer pass=0,fail=0; "keyword">always #5 clk=~clk; "keyword">initial "keyword">begin clk=0;rst=1;vaddr=0;translate_en=0; #12;rst=0; uut.page_table[0]=30'h20000005; // V=1,PPN=5 uut.page_table[1]=30'h20000003; // V=1,PPN=3 uut.page_table[2]=30'h0; // V=0 vaddr=16'h0000; translate_en=1; #10; "keyword">if (tlb_miss && paddr===16'h0500) pass=pass+1; "keyword">else "keyword">begin $display("FAIL1"); fail=fail+1; "keyword">end translate_en=0; #10; vaddr=16'h0000; translate_en=1; #10; "keyword">if (tlb_hit && paddr===16'h0500) pass=pass+1; "keyword">else "keyword">begin $display("FAIL2"); fail=fail+1; "keyword">end translate_en=0; #10; vaddr=16'h0200; translate_en=1; #10; "keyword">if (page_fault) pass=pass+1; "keyword">else "keyword">begin $display("FAIL3"); fail=fail+1; "keyword">end translate_en=0; #10; $display("========================================"); $display("TLB+页表测试: PASS=%0d FAIL=%0d",pass,fail); "keyword">if (fail==0) $display("✅ 虚拟内存地址翻译全部正确!"); "keyword">else $display("❌ 存在失败!"); $display("========================================"); $finish; "keyword">end "keyword">endmodule

Verilator 编译与运行

verilator --cc tlb_simple.v --exe tb_tlb_simple.v --build --top-module tb_tlb_simple ./obj_dir/Vtb_tlb_simple

📌 扩展阅读

本课的核心概念在实际工程中有广泛应用:

🔧 调试技巧

在开发本课模块时,常见问题和解决方法:

📊 性能指标

衡量本课模块性能的关键指标:

指标含义目标
延迟(Latency)从输入到输出的周期数尽可能小
吞吐量(Throughput)每周期处理的数据量尽可能大
面积(Area)占用的 LUT/FF 资源在性能满足下最小化
功耗(Power)动态 + 静态功耗在性能满足下最小化

🔗 与其他课程的联系

本课内容在整个 RISC-V 数字电路课程中的位置:

🏆 成就解锁:虚拟内存

✅ Verilator 仿真验证通过

✅ TLB 全相联查找逻辑正确

✅ 页表地址翻译正确

✅ TLB 缺失填充正确

✅ 页错误检测正确

🤔 思考题

1. 本课设计的模块如何与前面课程的内容结合?

2. 修改参数后,系统的行为会有什么变化?