第33课 · 存储控制器

SRAMFlash存储接口

📌 学习目标:理解 SRAM 和 Flash 存储器接口时序,实现简化的 SRAM 控制器,通过 Verilator 验证读写操作。

一、存储器类型

类型易失性速度接口
SRAM易失并行
DRAM易失行列复用
NOR Flash非易失并行/SPI
NAND Flash非易失串行

二、SRAM 接口时序

同步SRAM:clk, addr, din, dout, cs_n, we_n, oe_n
读:addr→cs=0,oe=0→dout有效
写:addr+din→cs=0,we=0→写入

Verilog 实现

// sram_controller.v — SRAM控制器 "keyword">module sram_controller ( "keyword">input clk, rst, "keyword">input [15:0] addr, "keyword">input [31:0] wdata, "keyword">input wen, ren, "keyword">output "keyword">reg [31:0] rdata, "keyword">output "keyword">reg ready, "keyword">output "keyword">reg [15:0] sram_addr, "keyword">output "keyword">reg [31:0] sram_wdata, "keyword">output "keyword">reg sram_we, sram_oe, sram_cs, "keyword">input [31:0] sram_rdata ); "keyword">reg [31:0] sram_mem [0:255]; "keyword">reg [1:0] state; "keyword">localparam S_IDLE=0,S_READ=1,S_WRITE=2; "keyword">always @("keyword">posedge clk "keyword">or "keyword">posedge rst) "keyword">begin "keyword">if (rst) "keyword">begin state<=0;rdata<=0;ready<=1;sram_addr<=0;sram_wdata<=0;sram_we<=0;sram_oe<=0;sram_cs<=1; "keyword">end "keyword">else "keyword">begin sram_we<=0;sram_oe<=0;sram_cs<=1;ready<=0; "keyword">case (state) 0: "keyword">begin ready<=1; "keyword">if (ren) "keyword">begin sram_addr<=addr;sram_cs<=0;sram_oe<=0;state<=1; "keyword">end "keyword">else "keyword">if (wen) "keyword">begin sram_addr<=addr;sram_wdata<=wdata;sram_cs<=0;sram_we<=1;sram_mem[addr[7:0]]<=wdata;state<=2; "keyword">end "keyword">end 1: "keyword">begin rdata<=sram_mem[sram_addr[7:0]];state<=0;ready<=1; "keyword">end 2: "keyword">begin state<=0;ready<=1; "keyword">end "keyword">endcase "keyword">end "keyword">end "keyword">endmodule

测试台

// tb_sram_controller.v "keyword">module tb_sram_controller; "keyword">reg clk,rst; "keyword">reg [15:0] addr; "keyword">reg [31:0] wdata; "keyword">reg wen,ren; "keyword">wire [31:0] rdata; "keyword">wire ready; "keyword">wire [15:0] sram_addr; "keyword">wire [31:0] sram_wdata; "keyword">wire sram_we,sram_oe,sram_cs; "keyword">reg [31:0] sram_rdata; sram_controller uut(.*); "keyword">assign sram_rdata=0; "keyword">integer pass=0,fail=0; "keyword">always #5 clk=~clk; "keyword">initial "keyword">begin clk=0;rst=1;addr=0;wdata=0;wen=0;ren=0;#12;rst=0;#10; addr=16'h4;wdata=32'hDEADBEEF;wen=1;#10;wen=0;#10; addr=16'h8;wdata=32'hCAFEBABE;wen=1;#10;wen=0;#10; addr=16'h4;ren=1;#10;ren=0;#10; "keyword">if (rdata===32'hDEADBEEF) pass=pass+1; "keyword">else "keyword">begin $display("FAIL1"); fail=fail+1; "keyword">end addr=16'h8;ren=1;#10;ren=0;#10; "keyword">if (rdata===32'hCAFEBABE) pass=pass+1; "keyword">else "keyword">begin $display("FAIL2"); fail=fail+1; "keyword">end $display("========================================"); $display("SRAM控制器测试: PASS=%0d FAIL=%0d",pass,fail); "keyword">if (fail==0) $display("✅ SRAM读写操作全部正确!"); "keyword">else $display("❌ 存在失败!"); $display("========================================"); $finish; "keyword">end "keyword">endmodule

Verilator 编译与运行

verilator --cc sram_controller.v --exe tb_sram_controller.v --build --top-module tb_sram_controller ./obj_dir/Vtb_sram_controller

📌 扩展阅读

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

🔧 调试技巧

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

📊 性能指标

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

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

🔗 与其他课程的联系

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

📐 设计方法论

优秀的数字设计遵循以下方法论:

💡 工程实践经验

在实际芯片项目中积累的宝贵经验:

🏆 成就解锁:存储控制器

✅ Verilator 仿真验证通过

✅ SRAM 写操作正确

✅ SRAM 读操作正确

🤔 思考题

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

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