Ultra96でMIPI信号をリードする(4)

結局、ISERDESE3でINTERNAL_DIVCLKが使えなかったのでFIFOインターフェースを使うことにしました。

Data LaneのRTLは次にようになりました。

module csi_rx_lane_phy(
  input RST_N,

  input CLK_P,
  input CLK_N,

  input CLK_DIV,

  input DIN_P,
  input DIN_N,

  input DOUT_CLK,
  output DOUT_VALID,
  output [7:0] DOUT
);

wire in_data;
wire [7:0] serdes_data;
IBUFDS
#(
  .DIFF_TERM("TRUE"),
  .IBUF_LOW_PWR("FALSE"),
  .IOSTANDARD("DEFAULT")
)
u_IBUFDS
(
  .I(DIN_P),
  .IB(DIN_N),
  .O(in_data)
);

IDELAYE3 #(
  .CASCADE("NONE"),
  .DELAY_FORMAT("TIME"),
  .DELAY_SRC("IDATAIN"),
  .DELAY_TYPE("FIXED"),
  .DELAY_VALUE(0),
  .IS_CLK_INVERTED(0),
  .IS_RST_INVERTED(0),
  .LOOPBACK("FALSE"),
  .REFCLK_FREQUENCY(500.0),
  .SIM_DEVICE("ULTRASCALE_PLUS"),
  .SIM_VERSION(2.0),
  .UPDATE_MODE("ASYNC")
)
u_IDELAYE3(
  .CASC_OUT(),
  .CNTVALUEOUT(),
  .DATAOUT(in_delayed),

  .CASC_IN(),
  .CASC_RETURN(),
  .CE(),
  .CLK(CLK_DIV),
  .CNTVALUEIN(),
  .DATAIN(),
  .EN_VTC(),
  .IDATAIN(in_data),
  .INC(),
  .LOAD(),
  .RST(~RST_N)
);

wire serdes_clk, fifo_empty;

ISERDESE3 #(
  .DATA_WIDTH(8),
  .DDR_CLK_EDGE("OPPOSITE_EDGE"),
  .FIFO_ENABLE("TRUE"),
  .FIFO_SYNC_MODE("FALSE"),
  .IDDR_MODE("FALSE"),
  .IS_CLK_B_INVERTED(0),
  .IS_CLK_INVERTED(0),
  .IS_RST_INVERTED(0),
  .SIM_DEVICE("ULTRASCALE_PLUS"),
  .SIM_VERSION(2.0)
)
u_ISERDESE3 (
  .FIFO_EMPTY(fifo_empty),
  .INTERNAL_DIVCLK(serdes_clk),
  .Q(serdes_data),

  .CLK(CLK_P),
  .CLKDIV(CLK_DIV),
  .CLK_B(CLK_N),
  .D(in_data),
  .FIFO_RD_CLK(DOUT_CLK),
  .FIFO_RD_EN(~fifo_empty),
  .RST(~RST_N)
);

assign DOUT_VALID = ~fifo_empty;

assign DOUT = serdes_data;
//assign DOUT_CLK = serdes_clk;

endmodule

CLK_P/NがMIPI_CLKと同等のクロック、CLK_DIVがMIPI_CLKの2分周、DOUT_CLKがMIPI_CLKの4分周になります。

これで、シミュレーションもインプリメンテーションも通すことが出来ました。

write: 2019/02/18/ 22:07:42