`timescale 1ns / 1ps module mipi_link_test ( //系统输入 input wire sys_clk_p, // 板载 200MHz 差分时钟 (P) AL8 input wire sys_clk_n, // 板载 200MHz 差分时钟 (N) AL7 input wire sys_reset_in_n, // 板载复位 (低电平有效) F16 PL key1 //MIPI D-PHY 物理引脚 (来自AWR2243) input wire mipi_clk_p, input wire mipi_clk_n, input wire [3:0] mipi_data_p, // 4-lane 数据 (P) input wire [3:0] mipi_data_n, // 4-lane 数据 (N) //调试输出 (连接到Zynq PL的LED) 均为低点亮 output wire led_pll_lock_out, // MIPI物理层锁定指示 output wire led_clk_wiz_locked, // 时钟IP锁定指示 低 output wire led_video_tvalid // MIPI IP 正在输出数据 低 ); //wire 内部信号 wire dphy_clk_200M; // clk_wiz 的 200MHz D-PHY 参考时钟 wire clk_wiz_locked; wire mipi_ip_reset_n; // MIPI IP的最终复位信号 wire pll_lock_out; //IP核输出的恢复时钟 wire mipi_video_clk_raw; // 即 接rxbyteclkhs // (AXI-Stream 信号) //wire video_out_tvalid; //wire [15:0] video_out_tdata; // pixel =1 , 16位, pixel =4 , 64位 4-lane //wire [95:0] video_out_tuser;// 默认 // (AXI-Stream 信号) wire video_out_clk; // MIPI IP输出的视频时钟 wire video_out_tvalid; // MIPI IP输出的有效信号 wire [15:0] video_out_tdata; // 假设数据宽度为64, 以IP生成为准 wire [95:0] video_out_tuser; // 假设用户信号宽度为96, 以IP生成为准 wire [9:0] video_out_tdest; wire video_out_tlast; //wire video_out_tready_in; //assign video_out_tready_in = 1'b1; //其他 AXI-Stream 信号 // (其他IP输出信号,悬空) wire clkoutphy_out; wire system_rst_out; wire csirxss_csi_irq; // 例化时钟IP (clk_wiz_0) // (必须在IP Catalog中生成此IP, 并确保例化名称 'clk_wiz_0' 匹配) // (端口名称 .clk_in1 修改为 .clk_in1_p 和 .clk_in1_n) clk_wiz_0 u_clk_wiz ( .clk_in1_p(sys_clk_p), // 输入: 200MHz 差分时钟 (P) .clk_in1_n(sys_clk_n), // 输入: 200MHz 差分时钟 (N) .clk_out1(dphy_clk_200M), // 输出: 200MHz .resetn(sys_reset_in_n), // 输入: 系统 低电平复位 .locked(clk_wiz_locked) // 输出: clk_wiz 锁定 锁定输出高电平 ); // 生成MIPI IP的复位信号:必须在系统复位解除 且 clk_wiz 锁定后 assign mipi_ip_reset_n = sys_reset_in_n & clk_wiz_locked; assign led_clk_wiz_locked = ~clk_wiz_locked; // LED 低电平点亮 assign led_pll_lock_out = ~pll_lock_out; // --- 2. 例化MIPI CSI-2 RX IP (mipi_rx_ip) --- mipi_rx_ip u_mipi_rx ( // // AXI-Lite 控制接口 (必须被时钟和复位, 并束缚) .lite_aclk(dphy_clk_200M), // 使用 200MHz 系统时钟 .lite_aresetn(mipi_ip_reset_n), // 使用系统复位 .csirxss_s_axi_araddr(8'b0), .csirxss_s_axi_arvalid(1'b0), .csirxss_s_axi_awaddr(8'b0), .csirxss_s_axi_awvalid(1'b0), .csirxss_s_axi_bready(1'b1), // 始终准备好接收B-channel .csirxss_s_axi_rready(1'b1), // 始终准备好接收R-channel .csirxss_s_axi_wdata(32'b0), .csirxss_s_axi_wstrb(4'b0), .csirxss_s_axi_wvalid(1'b0), // (AXI-Lite 输出端口悬空) .csirxss_s_axi_arready(), .csirxss_s_axi_awready(), .csirxss_s_axi_bresp(), .csirxss_s_axi_bvalid(), .csirxss_s_axi_rdata(), .csirxss_s_axi_rresp(), .csirxss_s_axi_rvalid(), .csirxss_s_axi_wready(), // D-PHY 参考时钟 .dphy_clk_200M(dphy_clk_200M), // AXI-Stream 视频接口时钟 (关键修正!) .video_aclk(mipi_video_clk_raw), // **输入**:使用下面输出的恢复时钟 .video_aresetn(mipi_ip_reset_n), // 使用系统复位 // AXI-Stream 视频输出 .video_out_tdata(video_out_tdata), .video_out_tdest(video_out_tdest),// .video_out_tlast(video_out_tlast), .video_out_tready(1'b1), // 强制 TREADY 为高, 允许IP自由发送数据 .video_out_tuser(video_out_tuser), .video_out_tvalid(video_out_tvalid), // 物理层引脚 .mipi_phy_if_clk_n(mipi_clk_n), .mipi_phy_if_clk_p(mipi_clk_p), .mipi_phy_if_data_n(mipi_data_n), .mipi_phy_if_data_p(mipi_data_p), // 状态和时钟输出 .rxbyteclkhs(mipi_video_clk_raw), // **输出**:这是恢复的时钟 .pll_lock_out(pll_lock_out), // **连接到LED** pll_lock_out 锁定后高电平 .clkoutphy_out(clkoutphy_out), // 悬空 .system_rst_out(system_rst_out), // 悬空 .csirxss_csi_irq(csirxss_csi_irq) // 悬空 ); ila_0 u_ila_0 ( .clk(mipi_video_clk_raw), // **关键:使用MIPI的恢复时钟** // 将探针连接到AXI-Stream总线 .probe0(video_out_tdata), // [15:0] .probe1(video_out_tuser), // [95:0] .probe2(video_out_tvalid), // [0:0] .probe3(video_out_tlast), // [0:0] .probe4(video_out_tdest) // [9:0] ); ila_1 u_ila_1 ( .clk(dphy_clk_200M), // **时钟:永远在线的200MHz时钟** .probe0(pll_lock_out), // 探针0: MIPI PLL是否锁定? .probe1(clk_wiz_locked), // 探针1: 200MHz时钟是否稳定? .probe2(mipi_ip_reset_n) // 探针2: IP核是否已解除复位? ); // --- 3. 调试 tvalid 信号 --- // (这部分代码保持不变) // 使用 mipi_ip_reset_n 作为异步复位 // 使用 mipi_video_clk_raw 作为时钟 reg tvalid_latch = 1'b0; always @(posedge mipi_video_clk_raw or negedge mipi_ip_reset_n) begin if (!mipi_ip_reset_n) tvalid_latch <= 1'b0; else if (video_out_tvalid) tvalid_latch <= 1'b1; // 一旦tvalid为高, 就锁存 end assign led_video_tvalid = ~tvalid_latch; endmodule //`timescale 1ns / 1ps // //module mipi_link_test ( // // 1. 系统输入 // input wire sys_clk_p, // 您的板载 200MHz 差分时钟 (P) // input wire sys_clk_n, // 您的板载 200MHz 差分时钟 (N) // input wire sys_reset_in_n, // 您的板载复位 (低电平有效) // // // 2. MIPI D-PHY 物理引脚 (来自AWR2243) // input wire mipi_clk_p, // input wire mipi_clk_n, // input wire [3:0] mipi_data_p, // 4-lane 数据 (P) // input wire [3:0] mipi_data_n, // 4-lane 数据 (N) // // // 3. 调试输出 (连接到您Zynq板上的LED) // output wire led_pll_lock, // 关键!MIPI物理层锁定指示 // output wire led_clk_wiz_locked, // 时钟IP锁定指示 // output wire led_video_tvalid // MIPI IP 正在输出数据 //); // // // --- 内部信号 --- // wire dphy_clk_200M; // 来自 clk_wiz 的 200MHz D-PHY 参考时钟 // wire clk_wiz_locked; // wire mipi_ip_reset_n; // 用于MIPI IP的最终复位信号 // // // **已修正:这是从IP核输出的恢复时钟** // wire mipi_video_clk_raw; // 即 rxbyteclkhs // // // (AXI-Stream 信号) // wire video_out_tvalid; // wire [15:0] video_out_tdata; // **请检查:** 模板显示 16位, 但4-lane RAW14 应该是 64位。请在IP配置中确认 AXI-Stream 宽度 // wire [95:0] video_out_tuser; // // // (其他IP输出信号,悬空) // wire clkoutphy_out; // wire system_rst_out; // wire csirxss_csi_irq; // // // --- 1. 例化时钟IP (clk_wiz_0) --- // clk_wiz_0 u_clk_wiz ( // .clk_in1_p(sys_clk_p), // .clk_in1_n(sys_clk_n), // .clk_out1(dphy_clk_200M), // .resetn(sys_reset_in_n), // .locked(clk_wiz_locked) // ); // // // 生成MIPI IP的复位信号 // assign mipi_ip_reset_n = sys_reset_in_n & clk_wiz_locked; // assign led_clk_wiz_locked = clk_wiz_locked; // // // // --- 2. 例化MIPI CSI-2 RX IP (mipi_rx_ip) --- // // (已根据您的模板完全修正) // mipi_rx_ip u_mipi_rx ( // // AXI-Lite 控制接口 (必须被时钟和复位, 并束缚) // .lite_aclk(dphy_clk_200M), // 使用 200MHz 系统时钟 // .lite_aresetn(mipi_ip_reset_n), // 使用系统复位 // .csirxss_s_axi_araddr(8'b0), // .csirxss_s_axi_arvalid(1'b0), // .csirxss_s_axi_awaddr(8'b0), // .csirxss_s_axi_awvalid(1'b0), // .csirxss_s_axi_bready(1'b1), // 始终准备好接收B-channel // .csirxss_s_axi_rready(1'b1), // 始终准备好接收R-channel // .csirxss_s_axi_wdata(32'b0), // .csirxss_s_axi_wstrb(4'b0), // .csirxss_s_axi_wvalid(1'b0), // // (AXI-Lite 输出端口悬空) // .csirxss_s_axi_arready(), // .csirxss_s_axi_awready(), // .csirxss_s_axi_bresp(), // .csirxss_s_axi_bvalid(), // .csirxss_s_axi_rdata(), // .csirxss_s_axi_rresp(), // .csirxss_s_axi_rvalid(), // .csirxss_s_axi_wready(), // // // D-PHY 参考时钟 // .dphy_clk_200M(dphy_clk_200M), // // // AXI-Stream 视频接口时钟 (关键的修正!) // .video_aclk(mipi_video_clk_raw), // **输入**:使用下面输出的恢复时钟 // .video_aresetn(mipi_ip_reset_n), // 使用系统复位 // // // AXI-Stream 视频输出 // .video_out_tdata(video_out_tdata), // .video_out_tdest(), // .video_out_tlast(), // .video_out_tready(1'b1), // 强制 TREADY 为高, 允许IP自由发送数据 // .video_out_tuser(video_out_tuser), // .video_out_tvalid(video_out_tvalid), // // // 物理层引脚 (名称来自您的模板) // .mipi_phy_if_clk_n(mipi_clk_n), // .mipi_phy_if_clk_p(mipi_clk_p), // .mipi_phy_if_data_n(mipi_data_n), // .mipi_phy_if_data_p(mipi_data_p), // // // 状态和时钟输出 // .rxbyteclkhs(mipi_video_clk_raw), // **输出**:这是恢复的时钟 // .clkoutphy_out(clkoutphy_out), // 悬空 // .system_rst_out(system_rst_out), // 悬空 // .pll_lock_out(led_pll_lock), // **连接到LED** // .csirxss_csi_irq(csirxss_csi_irq) // 悬空 // ); // // // --- 3. 调试 tvalid 信号 --- // // (已修正:时钟改为 mipi_video_clk_raw) // reg tvalid_latch = 1'b0; // // 使用 mipi_ip_reset_n 作为异步复位 // // 使用 mipi_video_clk_raw 作为时钟 // always @(posedge mipi_video_clk_raw or negedge mipi_ip_reset_n) begin // if (!mipi_ip_reset_n) // tvalid_latch <= 1'b0; // else if (video_out_tvalid) // tvalid_latch <= 1'b1; // 一旦tvalid为高, 就锁存 // end // assign led_video_tvalid = tvalid_latch; // //endmodule