Xilinx FPGA MIPI CSI-2 Transmitter Subsystem 仿真笔记

MIPI——Mobile Industry Processor Interface

DSI用于显示屏,CSI用于摄像头。在某些场合想用FPGA模拟摄像头,可以用Xilinx FPGA MIPI CSI-2 Transmitter Subsystem0。

MIPI协议,网上资料很多,此处不做赘述,此处仅对Xilinx FPGA MIPI CSI-2 Transmitter Subsystem做主要说明。


配置

MIPI CSI-2 Transmitter Subsystem这个IP核,内部包括MIPI D-PHY和MIPI CSI-2 TX Controller。

 此处配置接口为AXI4S,CSI lane选择1,输入像素数目为1,Line buffer深度为2048。

如果整个工程仅用一个接口,那么此处选择inlcude shared logic in core。

管脚根据你的硬件设计进行指定,此处数据管脚和时钟管脚,仅HP BANK可以用,绘制原理图之前需要提前看一下某些管脚是否可以用。


仿真验证

由于IP不自动example工程,所以自己搭建测试。

里面有个DATA_TYPE特别恶心,Xilinx的文档没提各个对应关系,让查MIPI官方文档,MIPI官方又要注册账号。

我这里产生图像是128*32的RGB888图像数据,用于仿真。

它的s_axis_tuser对应的Line number和Frame number可以设置为0,内核会自动匹配检测,但是后级MIPI接收端可能不知道图像的行场大小。

module tb_mipi_core  ; 
//------------------------------------------------------------ 
parameter C_M_AXI_ADDR_WIDTH = 8;


  reg    dphy_clk_200M   ; 
//s_axi
  wire    s_axi_awready   ; 
  wire    s_axi_awvalid   ; 
  wire  [C_M_AXI_ADDR_WIDTH-1:0]  s_axi_awaddr   ;  
  wire    s_axi_arready   ; 
  wire    s_axi_arvalid   ; 
  wire  [C_M_AXI_ADDR_WIDTH-1:0]  s_axi_araddr   ; 
  wire    s_axi_wready   ; 
  wire    s_axi_wvalid   ; 
  wire  [31:0]  s_axi_wdata   ; 
  wire  [3:0]  s_axi_wstrb   ; 
  wire    s_axi_rready   ; 
  wire    s_axi_rvalid   ; 
  wire  [31:0]  s_axi_rdata   ; 
  wire  [1:0]  s_axi_rresp   ; 
  wire    s_axi_bready   ; 
  wire    s_axi_bvalid   ; 
  wire  [1:0]  s_axi_bresp   ; 
  
  
//s_axis  
  reg    s_axis_aclk   ; 
  reg    s_axis_aresetn   ; 
  // reg    s_axis_tvalid   ; 
  wire    s_axis_tvalid   ; 
  wire    s_axis_tready   ; 
  reg  [47:0]  s_axis_tdata   ; 
  // reg    s_axis_tlast   ; 
  wire    s_axis_tlast   ; 
  // reg  [95:0]  s_axis_tuser   ; 
  wire  [95:0]  s_axis_tuser   ; 
  reg  [5:0]  s_axis_tkeep   ; 
  reg  [1:0]  s_axis_tdest   ; 
  
  wire    txclkesc_out   ; 
  wire    mmcm_lock_out   ; 
  wire    clkoutphy_out   ; 
  wire  [0:0]  mipi_phy_if_data_p   ; 
  wire  [0:0]  mipi_phy_if_data_n   ; 
  wire    mipi_phy_if_clk_p   ; 
  wire    mipi_phy_if_clk_n   ; 
  wire    txbyteclkhs   ; 
  wire    interrupt   ; 
  wire    system_rst_out   ;
  wire    pll_lock_out   ; 
  
  wire  s_axi_init_rdy;
  
//------------------------------------------------------------ 
initial  begin
dphy_clk_200M = 0;

s_axis_aresetn = 0;
s_axis_tdest = 0;

// s_axi_awvalid = 0;
// s_axi_wdata = 0;
// s_axi_arvalid = 0;
// s_axi_araddr = 0;
// s_axi_rready = 0  ; 
// s_axi_bready = 0  ; 
// s_axi_wstrb  = 0  ; 
// s_axi_awaddr = 0;
// s_axi_wvalid = 0  ; 

s_axis_aclk = 0;
s_axis_tdata = 0;
// s_axis_tlast = 0;
// s_axis_tuser = 0;
// s_axis_tvalid = 0;
s_axis_tkeep = 5'h1f;

#200;
s_axis_aresetn = 1;


end 

always #2.5   dphy_clk_200M = ~dphy_clk_200M;
always #5  s_axis_aclk = ~s_axis_aclk;

reg [10:0]  cnt_h = 0;
reg [10:0]  cnt_v = 0;

// 128*32
always @(posedge s_axis_aclk)
	if(s_axis_aresetn && s_axi_init_rdy==1)
	begin
		if(s_axis_tready)
			if(cnt_h==200)
				cnt_h <= 40;
			else
				cnt_h <= cnt_h + 1;
			
		if(cnt_h==200)
			if(cnt_v >= 31)
				cnt_v <= 0;
			else
				cnt_v <= cnt_v + 1;
	end
//----------------------------------------------------------------------------------

// assign s_axis_tvalid = 0;
assign s_axis_tvalid = (cnt_h >= 73) ? 1:0;
assign s_axis_tuser[0] = (cnt_v==0 && cnt_h==73)? 1 : 0 ;
assign s_axis_tlast = (cnt_h==200)? 1 : 0 ;
//-------------------------------------------------------
assign s_axis_tuser[95:64] = 0;  //reserved
assign s_axis_tuser[15:7] = 0;  //reserved

assign s_axis_tuser[63:48] = 128;  //Word count  ---- 128*32
assign s_axis_tuser[47:32] = 0;  //Line number
assign s_axis_tuser[31:16] = 0;  //Frame number
assign s_axis_tuser[6:1] = 6'h24;  //Data type  ---  RGB888
// s_axis_tuser[0] = 0;  //Frame start

always @(posedge s_axis_aclk)
	if(s_axis_tvalid && s_axis_tready) begin
		s_axis_tdata[41:34] <= s_axis_tdata[41:34] + 1;
		s_axis_tdata[27:20] <= s_axis_tdata[27:20] + 1;
		s_axis_tdata[13:6]  <= s_axis_tdata[13:6]  + 1;
	end
		
//------------------------------------------------------------
  mipi_csi2_tx_subsystem_0  
   DUT  ( 
       .s_axi_awready (s_axi_awready ) ,
      .s_axis_aresetn (s_axis_aresetn ) ,
      .txclkesc_out (txclkesc_out ) ,
      .mmcm_lock_out (mmcm_lock_out ) ,
      .s_axis_tdest (s_axis_tdest ) ,
      .clkoutphy_out (clkoutphy_out ) ,
      .mipi_phy_if_data_n (mipi_phy_if_data_n ) ,
      .mipi_phy_if_clk_n (mipi_phy_if_clk_n ) ,
      .s_axi_arready (s_axi_arready ) ,
//      .s_axi_arprot (0 ) ,
      .s_axi_awvalid (s_axi_awvalid ) ,
      .s_axis_tdata (s_axis_tdata ) ,
      .s_axi_wdata (s_axi_wdata ) ,
      .dphy_clk_200M (dphy_clk_200M ) ,
      .mipi_phy_if_data_p (mipi_phy_if_data_p ) ,
      .mipi_phy_if_clk_p (mipi_phy_if_clk_p ) ,
      .txbyteclkhs (txbyteclkhs ) ,
      .interrupt (interrupt ) ,
      .s_axis_tlast (s_axis_tlast ) ,
      .s_axi_arvalid (s_axi_arvalid ) ,
      .s_axis_tready (s_axis_tready ) ,
      .s_axi_rresp (s_axi_rresp ) ,
      .s_axi_bresp (s_axi_bresp ) ,
      .s_axi_wready (s_axi_wready ) ,
//      .s_axi_awprot (0 ) ,
      .s_axis_tuser (s_axis_tuser ) ,
      .s_axi_araddr (s_axi_araddr ) ,
      .s_axis_aclk (s_axis_aclk ) ,
      .s_axis_tvalid (s_axis_tvalid ) ,
      .s_axi_rready (s_axi_rready ) ,
      .s_axi_bready (s_axi_bready ) ,
      .s_axi_wvalid (s_axi_wvalid ) ,
      .system_rst_out (system_rst_out ) ,
      .s_axi_rvalid (s_axi_rvalid ) ,
      .s_axi_bvalid (s_axi_bvalid ) ,
      .s_axi_wstrb (s_axi_wstrb ) ,
      .s_axi_awaddr (s_axi_awaddr ) ,
      .s_axis_tkeep (s_axis_tkeep ) ,
      .s_axi_rdata (s_axi_rdata ) ,
      .pll_lock_out (pll_lock_out ) ); 
//-------------------------------------------------------------	  
//-------------------------------------------------------------	  
//-------------------------------------------------------------	   
axi_lite_sm  
	#(
	.C_M_AXI_ADDR_WIDTH (C_M_AXI_ADDR_WIDTH)
	)
lite_sm_u
   (
    // -- System Signals
    .s_axi_aclk (s_axis_aclk),
    .aresetn (s_axis_aresetn),

    // -- Master Interface Write Address
    .s_axi_awaddr (s_axi_awaddr),
    .s_axi_awvalid (s_axi_awvalid),
    .s_axi_awready (s_axi_awready),

    // -- Master Interface Write Data
    .s_axi_wdata (s_axi_wdata),
    .s_axi_wstrb (s_axi_wstrb),
    .s_axi_wvalid (s_axi_wvalid),
    .s_axi_wready (s_axi_wready),

    // -- Master Interface Write Response
    .s_axi_bresp (s_axi_bresp),
    .s_axi_bvalid (s_axi_bvalid),
    .s_axi_bready (s_axi_bready),

    // -- Master Interface Read Address
    .s_axi_araddr (s_axi_araddr),
    .s_axi_arvalid (s_axi_arvalid),
    .s_axi_arready (s_axi_arready),

    // -- Master Interface Read Data 
    .s_axi_rdata (s_axi_rdata),
    .s_axi_rresp (s_axi_rresp),
    .s_axi_rvalid (s_axi_rvalid),
    .s_axi_rready (s_axi_rready),
	
	.s_axi_init_rdy(s_axi_init_rdy)
    );

endmodule

原来以为不对其做任何配置,直接输入AXIS的数据,这个IP应该就能够正常运行,但是仿真发现其根本没有反应。所以后面通过AXI-LITE总线对其做寄存器配置。

根据手册说明,仅对配置寄存器(Core Configuration options)做配置就可以了。

register_write(0,32'h12);  //reset Controller
register_write(0,32'h11);  // Enables the core to receive and process packets

// wait Controller ready
		while(s_axi_rdata_r[2]==0)
		begin
			register_read(32'h0);
			repeat(10) @(posedge s_axi_aclk);
		end

//----
send AXIS stream data to core

根据手册说明,物理层默认初始化时间是1ms,等内核就绪后,发送AXIS数据流,它就应该能正常工作,但是观察输出的时钟和数据,始终不变化。并且内核AXIS接口在接收几包数据后,内核的ready信号一直为0,不能再继续接收数据。

并且输出的差分时钟和数据信号一直不变。

后面折腾半天,最终找到问题原因。

register_write(0,32'h12);  //reset Controller

// wait Controller ready
		while(s_axi_rdata_r[2]==0)
		begin
			register_read(32'h0);
			repeat(10) @(posedge s_axi_aclk);
		end

register_write(0,32'h11);  // Enables the core to receive and process packets

//----
send AXIS stream data to core

将之前代码顺序进行调整,仿真竟然通过。也就是在使能内核之前,必须先等内核就绪。

### 回答1: MIPI CSI-2 RX子系统是一种用于接收MIPI CSI-2协议视频数据的子系统。它可以将从摄像头或其他视频源发送的数据流转换为可用于处理和显示的数字信号。该子系统通常用于嵌入式系统和移动设备中,以实现高质量的视频捕捉和处理。 ### 回答2: MIPI CSI-2 RX子系统是一种可以接收MIPI CSI-2协议视频数据的系统。MIPI CSI-2协议通常用于连接摄像头和处理器之间的视频信息传输。由于MIPI CSI-2协议具有高带宽、低功耗和可靠性等优点,因此它被广泛应用于移动设备、智能家居、汽车、医疗设备等领域。 MIPI CSI-2 RX子系统主要由两个部分组成:硬件和软件。硬件部分包括CSI-2接收器、像素处理模块、数据转换器、DMA控制器等。它们协同工作,完成对MIPI CSI-2数据的接收、解析、转换和存储等功能。而软件部分则由驱动程序和应用程序组成,它们充当了控制和管理硬件部件的角色。 MIPI CSI-2 RX子系统的优势在于它可以实现高清晰度的视频传输,并且消耗极少的电力。它还支持并行传输,可以同时传输多个数据流,从而提高了数据传输的效率。此外,它还可以通过软件控制来调整和优化像素处理等功能,以适应不同场景下的应用需求。 需要注意的是,MIPI CSI-2 RX子系统虽然可以接收MIPI CSI-2协议的视频数据,但是它并不具备对视频数据进行编码和解码的能力。如果需要对视频数据进行编码和解码,需要额外添加相应的模块或设备。 总之,MIPI CSI-2 RX子系统作为连接摄像头和处理器之间的重要接口,具有方便、高效、低功耗、高网络带宽等优势,将成为未来智能设备的重要技术支撑。 ### 回答3: MIPI CSI-2 RX子系统是一种数据传输接口,被广泛应用于移动设备、工业相机和医疗设备等领域。这种子系统主要是指在芯片上实现接收MIPI Camera Serial Interface 2 (CSI-2)协议的模块,它可以接收来自相机或其它视频设备的数据,然后将这些数据传递给后续的图像处理部分进行处理和分析。 MIPI CSI-2 RX子系统的主要功能是处理和解压缩从相机或其它视频设备传输过来的视频流数据。它可以接收来自相机的原始视频数据,通过内部的解码器和视频处理器对其进行分析和处理,然后转换成计算机可以理解的数码信号。这些数码信号可以被用于实现多种功能,例如图像处理、分析和计算机视觉。 在MIPI CSI-2 RX子系统中,还包括一个数据通道,用于传输通过MIPI CSI-2协议传输的相关数据,例如图像的分辨率和格式。这些数据可以被用于配置后续的图像处理器,以确保它们能够正确地处理和分析来自相机或其它视频设备的数据流。 总之,MIPI CSI-2 RX子系统是一种重要的数据传输接口,它能够接收和处理从相机或其它视频设备传输过来的数据流,为后续的图像处理和计算机视觉提供数据支持。
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值