143 lines
6.4 KiB
Verilog
143 lines
6.4 KiB
Verilog
`timescale 1ns/1ps
|
||
|
||
module Top_Project (
|
||
// ==========================================
|
||
// 1. 系统全局时钟与复位输入
|
||
// ==========================================
|
||
input wire sys_clk_50m, // 开发板上的 50MHz 晶振输入
|
||
input wire sys_rst_n, // 开发板上的复位按键 (低电平有效,按下为0)
|
||
|
||
// ==========================================
|
||
// 2. 外部 SDRAM 物理芯片接口 (匹配 W9825G6JH-6)
|
||
// ==========================================
|
||
output wire [12:0] sdram_ADDR, // 13位行地址 / 9位列地址复用
|
||
output wire [1:0] sdram_BA, // 2位 Bank 地址
|
||
inout wire [15:0] sdram_DQ, // 16位数据总线 (必须是 inout 双向类型)
|
||
output wire [1:0] sdram_DQM, // 数据掩码
|
||
output wire sdram_CASn, // 列选通 (低有效)
|
||
output wire sdram_CKE, // 时钟使能
|
||
output wire sdram_CSn, // 片选 (低有效)
|
||
output wire sdram_RASn, // 行选通 (低有效)
|
||
output wire sdram_WEn, // 写使能 (低有效)
|
||
output wire sdram_CLK, // 输出给 SDRAM 芯片的时钟引脚 (带相位偏移)
|
||
|
||
// ==========================================
|
||
// 3. 测试状态指示灯 (新增)
|
||
// ==========================================
|
||
output wire led_test_pass, // 测试通过指示灯 (建议接绿色 LED)
|
||
output wire led_test_fail // 测试失败指示灯 (建议接红色 LED)
|
||
);
|
||
|
||
// ==========================================
|
||
// 内部信号声明
|
||
// ==========================================
|
||
wire clk_100m; // PLL 输出的 100MHz (0度相位,给 FPGA 内部逻辑用)
|
||
wire clk_100m_shift; // PLL 输出的 100MHz (-90度相位,给 SDRAM 芯片用)
|
||
wire pll_locked; // PLL 锁定指示信号 (高电平表示时钟已稳定输出)
|
||
|
||
wire [15:0] sdram_DQ_read; // 从双向引脚分离出的读数据
|
||
wire [15:0] sdram_DQ_write; // 准备输出到双向引脚的写数据
|
||
wire [15:0] sdram_DQ_writeEnable; // 控制总线方向的写使能信号
|
||
|
||
// --- 新增:用户逻辑交互总线连线 ---
|
||
wire user_cmd_valid;
|
||
wire user_cmd_ready;
|
||
wire user_is_write;
|
||
wire [23:0] user_address;
|
||
wire [15:0] user_write_data;
|
||
wire user_rsp_valid;
|
||
wire [15:0] user_rsp_data;
|
||
|
||
// ==========================================
|
||
// 模块 1:例化系统 PLL IP 核 (sys_pll)
|
||
// ==========================================
|
||
sys_pll u_sys_pll (
|
||
// ALTPLL 的 areset 是高电平有效。
|
||
// 因为板载按键 sys_rst_n 是低电平有效,所以这里必须加非逻辑 '~'
|
||
.areset (~sys_rst_n),
|
||
.inclk0 (sys_clk_50m),
|
||
.c0 (clk_100m), // 内部 100MHz 时钟
|
||
.c1 (clk_100m_shift),// 偏移 100MHz 时钟
|
||
.locked (pll_locked)
|
||
);
|
||
|
||
// 将带有 -90 度相位偏移的时钟直接连到顶层输出引脚,送给 SDRAM 物理芯片
|
||
assign sdram_CLK = clk_100m_shift;
|
||
|
||
// ==========================================
|
||
// 模块 2:复位信号反相与同步处理
|
||
// ==========================================
|
||
// SpinalHDL 生成的 MyCustomSdramTop 是【高电平复位】的。
|
||
// 我们在此生成一个全局的【高电平有效】复位信号 system_reset。
|
||
wire system_reset;
|
||
assign system_reset = (~sys_rst_n) | (~pll_locked);
|
||
|
||
// ==========================================
|
||
// 模块 3:处理 SDRAM 双向数据总线 (inout 三态门)
|
||
// ==========================================
|
||
// 读取通道:直接将外部管脚状态输入给控制器
|
||
assign sdram_DQ_read = sdram_DQ;
|
||
|
||
// 写入通道:通过三态门控制
|
||
// 当控制器拉高写使能 (16'hFFFF) 时,将写数据推送到总线上。
|
||
assign sdram_DQ = (sdram_DQ_writeEnable == 16'hFFFF) ? sdram_DQ_write : 16'hZZZZ;
|
||
|
||
// ==========================================
|
||
// 模块 4:例化由 SpinalHDL 生成的 SDRAM 控制器
|
||
// ==========================================
|
||
MyCustomSdramTop u_sdram_ctrl (
|
||
// --- 时钟与复位 ---
|
||
.clk (clk_100m), // 接入稳定的 100MHz 内部时钟
|
||
.reset (system_reset), // 接入经过处理的高有效复位信号
|
||
|
||
// --- 连接到底层的 SDRAM 物理接口信号 ---
|
||
.io_sdram_ADDR (sdram_ADDR),
|
||
.io_sdram_BA (sdram_BA),
|
||
.io_sdram_DQ_read (sdram_DQ_read),
|
||
.io_sdram_DQ_write (sdram_DQ_write),
|
||
.io_sdram_DQ_writeEnable (sdram_DQ_writeEnable),
|
||
.io_sdram_DQM (sdram_DQM),
|
||
.io_sdram_CASn (sdram_CASn),
|
||
.io_sdram_CKE (sdram_CKE),
|
||
.io_sdram_CSn (sdram_CSn),
|
||
.io_sdram_RASn (sdram_RASn),
|
||
.io_sdram_WEn (sdram_WEn),
|
||
|
||
// --- 连接到测试模块的用户逻辑接口 ---
|
||
.io_userCmdValid (user_cmd_valid),
|
||
.io_userCmdReady (user_cmd_ready),
|
||
.io_userIsWrite (user_is_write),
|
||
.io_userAddress (user_address),
|
||
.io_userWriteData (user_write_data),
|
||
.io_userWriteMask (2'b11), // 写数据掩码 (2'b00表示16位全部写入,不屏蔽)
|
||
|
||
.io_userRspValid (user_rsp_valid),
|
||
.io_userRspData (user_rsp_data)
|
||
);
|
||
|
||
// ==========================================
|
||
// 模块 5:例化读写校验测试模块 (新增)
|
||
// ==========================================
|
||
Sdram_Tester #(
|
||
.TEST_LENGTH(24'd4096) // 测试的地址长度,这里设置为测试前 4096 个地址
|
||
) u_tester (
|
||
.clk (clk_100m),
|
||
// 注意:Tester 内部是下降沿复位 (低有效),所以需要将高有效的 system_reset 取反
|
||
.rst_n (~system_reset),
|
||
|
||
// --- 挂载到 SDRAM 用户总线 ---
|
||
.cmd_valid (user_cmd_valid),
|
||
.cmd_ready (user_cmd_ready),
|
||
.is_write (user_is_write),
|
||
.address (user_address),
|
||
.write_data (user_write_data),
|
||
|
||
.rsp_valid (user_rsp_valid),
|
||
.rsp_data (user_rsp_data),
|
||
|
||
// --- 连接到顶层外部引脚 ---
|
||
.test_pass (led_test_pass),
|
||
.test_fail (led_test_fail)
|
||
);
|
||
|
||
endmodule |