Xilinx IOserdes 原语使用 ---- 回环实验

Xilinx IOserdes 原语使用 ---- 回环实验

下面RTL 代码,仅供参考,参考手册 :xilinx UG471

首先需要调节 bitslip 对齐,可以自己自定义序列接收检测,方可传输数据。

注意:

bitslip 必须在clkdiv 的一个周期下作用,等待两个周期后采样的Q4到Q1数据才有效,serdes 的复位至少需要两个时钟周期

c 复制代码
`timescale 1ns / 1ps

module serdes(
    input	i_clk_p,
    input	i_clk_n

    // output	o_data,
    // input	i_data

	);

wire		clk_50MHZx1;
wire		clk_400MHZx8;

reg	[15:0]		r_rst_cnt;
reg				r_rst_d0;
reg				r_rst_d1;
		(*mark_debug = "true"*)  reg	[7:0]		r_tx_data;
		(*mark_debug = "true"*)  wire	[7:0]	r_rx_data;
		(*mark_debug = "true"*)  reg	[7:0]		r_send_data;
		(*mark_debug = "true"*)  reg				r_sync_done;
		(*mark_debug = "true"*)  reg				r_sync_done_d;
		(*mark_debug = "true"*)  reg	[15:0]		r_sync_cnt;
		(*mark_debug = "true"*)  reg	[4:0]		r_bitslip_gap;
		(*mark_debug = "true"*)  reg				BITSLIP;

wire	RST;
wire	vio;
wire a_50M;
wire a_400M;

  clk_wiz_0 clk_wiz_0_inst0
   (
    // Clock out ports
    .clk_out1(clk_50MHZx1),     // output clk_out1
    .clk_out2(clk_400MHZx8),     // output clk_out2
    .clk_out3(a_50M),     // output clk_out3
    .clk_out4(a_400M),     // output clk_out4
    // Status and control signals
    .locked(locked),       // output locked
   // Clock in ports
    .clk_in1_p(i_clk_p),    // input clk_in1_p
    .clk_in1_n(i_clk_n));    // input clk_in1_n
// INST_TAG_END ------ End INSTANTIATION Template ---------

vio_0 your_instance_name (
  .clk(clk_50MHZx1),                // input wire clk
  .probe_out0(vio)  // output wire [0 : 0] probe_out0
);


assign RST = r_rst_d1 || vio;

always @ (posedge clk_50MHZx1 or negedge locked)begin
	if (!locked) begin
		r_rst_cnt <= 0;
		r_rst_d0 <= 0;
        r_rst_d1 <= 0;
    end else begin
     	r_rst_cnt <= (r_rst_cnt == 1024)?r_rst_cnt:r_rst_cnt + 1;
		r_rst_d0  <=  (r_rst_cnt < 1024)?1:0;
        r_rst_d1  <=  r_rst_d0;
    end
end 

/*------------------------------------------*\
                    iodelay
\*------------------------------------------*/

   // (* IODELAY_GROUP = <iodelay_group_name> *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL

   // IDELAYCTRL IDELAYCTRL_inst (
   //    .RDY(RDY),       // 1-bit output: Ready output
   //    .REFCLK(REFCLK), // 1-bit input: Reference clock input
   //    .RST(RST)        // 1-bit input: Active high reset input
   // );

 //  (* IODELAY_GROUP = <iodelay_group_name> *) // Specifies group name for associated IDELAYs/ODELAYs and IDELAYCTRL

   // IDELAYE2 #(
   //    .CINVCTRL_SEL("FALSE"),          // Enable dynamic clock inversion (FALSE, TRUE)
   //    .DELAY_SRC("IDATAIN"),           // Delay input (IDATAIN, DATAIN)
   //    .HIGH_PERFORMANCE_MODE("FALSE"), // Reduced jitter ("TRUE"), Reduced power ("FALSE")
   //    .IDELAY_TYPE("FIXED"),           // FIXED, VARIABLE, VAR_LOAD, VAR_LOAD_PIPE
   //    .IDELAY_VALUE(0),                // Input delay tap setting (0-31)
   //    .PIPE_SEL("FALSE"),              // Select pipelined mode, FALSE, TRUE
   //    .REFCLK_FREQUENCY(200.0),        // IDELAYCTRL clock input frequency in MHz (190.0-210.0, 290.0-310.0).
   //    .SIGNAL_PATTERN("DATA")          // DATA, CLOCK input signal
   // )
   // IDELAYE2_inst (
   //    .CNTVALUEOUT(CNTVALUEOUT), // 5-bit output: Counter value output
   //    .DATAOUT(DATAOUT),         // 1-bit output: Delayed data output
   //    .C(C),                     // 1-bit input: Clock input
   //    .CE(CE),                   // 1-bit input: Active high enable increment/decrement input
   //    .CINVCTRL(CINVCTRL),       // 1-bit input: Dynamic clock inversion input
   //    .CNTVALUEIN(CNTVALUEIN),   // 5-bit input: Counter value input
   //    .DATAIN(DATAIN),           // 1-bit input: Internal delay data input
   //    .IDATAIN(IDATAIN),         // 1-bit input: Data input from the I/O
   //    .INC(INC),                 // 1-bit input: Increment / Decrement tap delay input
   //    .LD(LD),                   // 1-bit input: Load IDELAY_VALUE input
   //    .LDPIPEEN(LDPIPEEN),       // 1-bit input: Enable PIPELINE register to load data input
   //    .REGRST(REGRST)            // 1-bit input: Active-high reset tap-delay input
   // );


/*------------------------------------------*\
       			  serdes
\*------------------------------------------*/


   ISERDESE2 #(
      .DATA_RATE("SDR"),           // DDR, SDR
      .DATA_WIDTH(8),              // Parallel data width (2-8,10,14)
      .DYN_CLKDIV_INV_EN("FALSE"), // Enable DYNCLKDIVINVSEL inversion (FALSE, TRUE)
      .DYN_CLK_INV_EN("FALSE"),    // Enable DYNCLKINVSEL inversion (FALSE, TRUE)
      // INIT_Q1 - INIT_Q4: Initial value on the Q outputs (0/1)
      .INIT_Q1(1'b0),
      .INIT_Q2(1'b0),
      .INIT_Q3(1'b0),
      .INIT_Q4(1'b0),
      .INTERFACE_TYPE("NETWORKING"),   // MEMORY, MEMORY_DDR3, MEMORY_QDR, NETWORKING, OVERSAMPLE
      .IOBDELAY("NONE"),           // NONE, BOTH, IBUF, IFD
      .NUM_CE(2),                  // Number of clock enables (1,2)
      .OFB_USED("TRUE"),          // Select OFB path (FALSE, TRUE)
      .SERDES_MODE("MASTER"),      // MASTER, SLAVE
      // SRVAL_Q1 - SRVAL_Q4: Q output values when SR is used (0/1)
      .SRVAL_Q1(1'b0),
      .SRVAL_Q2(1'b0),
      .SRVAL_Q3(1'b0),
      .SRVAL_Q4(1'b0)
   )
   ISERDESE2_inst (
      .O(),                       // 1-bit output: Combinatorial output
      // Q1 - Q8: 1-bit (each) output: Registered data outputs
      .Q1(r_rx_data[7]),
      .Q2(r_rx_data[6]),
      .Q3(r_rx_data[5]),
      .Q4(r_rx_data[4]),
      .Q5(r_rx_data[3]),
      .Q6(r_rx_data[2]),
      .Q7(r_rx_data[1]),
      .Q8(r_rx_data[0]),
      // SHIFTOUT1, SHIFTOUT2: 1-bit (each) output: Data width expansion output ports
      .SHIFTOUT1(),
      .SHIFTOUT2(),
      .BITSLIP(BITSLIP),  //右ç§>>,桶型ç§>>ä½?         // 1-bit input: The BITSLIP pin performs a Bitslip operation synchronous to
                                   // CLKDIV when asserted (active High). Subsequently, the data seen on the Q1
                                   // to Q8 output ports will shift, as in a barrel-shifter operation, one
                                   // position every time Bitslip is invoked (DDR operation is different from
                                   // SDR).

      // CE1, CE2: 1-bit (each) input: Data register clock enable inputs
      .CE1(1),
      .CE2(1),
      .CLKDIVP(0),           // 1-bit input: TBD
      // Clocks: 1-bit (each) input: ISERDESE2 clock input ports
      .CLK(a_400M),                   // 1-bit input: High-speed clock
      .CLKB(~a_400M),                 // 1-bit input: High-speed secondary clock
      .CLKDIV(a_50M),             // 1-bit input: Divided clock
      .OCLK(0),                 // 1-bit input: High speed output clock used when INTERFACE_TYPE="MEMORY" 
      // Dynamic Clock Inversions: 1-bit (each) input: Dynamic clock inversion pins to switch clock polarity
      .DYNCLKDIVSEL(0), // 1-bit input: Dynamic CLKDIV inversion
      .DYNCLKSEL(0),       // 1-bit input: Dynamic CLK/CLKB inversion
      // Input Data: 1-bit (each) input: ISERDESE2 data input ports
      .D(),                       // 1-bit input: Data input
      .DDLY(),                 // 1-bit input: Serial data from IDELAYE2
      .OFB(OFB),                   // 1-bit input: Data feedback from OSERDESE2
      .OCLKB(),               // 1-bit input: High speed negative edge output clock
      .RST(RST),                   // 1-bit input: Active high asynchronous reset
      // SHIFTIN1, SHIFTIN2: 1-bit (each) input: Data width expansion input ports
      .SHIFTIN1(),
      .SHIFTIN2()
   );



 OSERDESE2 #(
      .DATA_RATE_OQ("SDR"),   // DDR, SDR
      .DATA_RATE_TQ("SDR"),   // DDR, BUF, SDR
      .DATA_WIDTH(8),         // Parallel data width (2-8,10,14)
      .INIT_OQ(1'b0),         // Initial value of OQ output (1'b0,1'b1)
      .INIT_TQ(1'b0),         // Initial value of TQ output (1'b0,1'b1)
      .SERDES_MODE("MASTER"), // MASTER, SLAVE
      .SRVAL_OQ(1'b0),        // OQ output value when SR is used (1'b0,1'b1)
      .SRVAL_TQ(1'b0),        // TQ output value when SR is used (1'b0,1'b1)
      .TBYTE_CTL("FALSE"),    // Enable tristate byte operation (FALSE, TRUE)
      .TBYTE_SRC("FALSE"),    // Tristate byte source (FALSE, TRUE)
      .TRISTATE_WIDTH(1)      // 3-state converter width (1,4)
   )
   OSERDESE2_inst (
      .OFB(OFB),             // 1-bit output: Feedback path for data
      .OQ(),               // 1-bit output: Data path output
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1(),
      .SHIFTOUT2(),
      .TBYTEOUT(),   // 1-bit output: Byte group tristate
      .TFB(),             // 1-bit output: 3-state control
      .TQ(),               // 1-bit output: 3-state control
      .CLK(a_400M),             // 1-bit input: High speed clock
      .CLKDIV(a_50M),       // 1-bit input: Divided clock
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1(r_tx_data[0]),
      .D2(r_tx_data[1]),
      .D3(r_tx_data[2]),
      .D4(r_tx_data[3]),
      .D5(r_tx_data[4]),
      .D6(r_tx_data[5]),
      .D7(r_tx_data[6]),
      .D8(r_tx_data[7]),
      .OCE(1),             // 1-bit input: Output data clock enable
      .RST(RST),             // 1-bit input: Reset
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1(),
      .SHIFTIN2(),
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1(0),
      .T2(0),
      .T3(0),
      .T4(0),
      .TBYTEIN(0),     // 1-bit input: Byte group tristate
      .TCE(0)              // 1-bit input: 3-state clock enable
   );


always @ (posedge clk_50MHZx1)begin
	if (RST) begin
		r_send_data <= 0;
    end else if (!r_sync_done) begin
		r_send_data <= 0;
    end else if (r_sync_done) begin
		r_send_data <= r_send_data + 1;  
	end else 
		r_send_data <= r_send_data ;  
end 

always @ (posedge clk_50MHZx1 )begin
	if (RST) begin
		r_tx_data <= 0;
    end else if (!r_sync_done) begin
		r_tx_data <= 8'hBC;
    end else if (r_sync_done) begin
		r_tx_data <= r_send_data;    
	end else 
		r_tx_data <= 0;	 
end 

always @ (posedge clk_50MHZx1) begin
	if (RST) begin
		r_sync_done_d <= 0;
		r_bitslip_gap <= 0;
	end else if ( !r_sync_done_d && r_rx_data == 8'hBC) begin
		r_sync_done_d <= 1;
	end else if (r_sync_cnt == 100) begin
		r_bitslip_gap <= 0;
	end else begin
		r_sync_done_d <= 0;	
		r_bitslip_gap <= r_bitslip_gap + 1;	
end 
end

always @ (posedge clk_50MHZx1) begin
	if (RST)
		r_sync_cnt <= 0;
	else if (r_sync_cnt == 100)
		r_sync_cnt <= r_sync_cnt;
	else if (r_sync_done_d)
		r_sync_cnt <= r_sync_cnt + 1;
	else 
		r_sync_cnt <= r_sync_cnt;		
end 

always @ (posedge clk_50MHZx1) begin
	if (RST)
		r_sync_done <= 0;
	else if (r_sync_cnt == 100)
		r_sync_done <= 1;
	else 
		r_sync_done <= r_sync_done;		
end 

always @ (posedge clk_50MHZx1) begin
	if (RST)
		BITSLIP <= 0;
	else if (!r_sync_done_d && r_bitslip_gap == 31 && r_rx_data!= 8'hBC)
		BITSLIP <= 1;
	else 
		BITSLIP <= 0;		
end 

endmodule
相关推荐
搬砖的小码农_Sky28 分钟前
FPGA:FPGA器件选型
fpga开发
北城笑笑30 分钟前
FPGA 17 ,FPGA 与 SR-IOV虚拟化技术,高性能计算与虚拟化技术的结合(FPGA 与 SR-IOV 和 PCI,高性能计算与虚拟化的完美融合)
fpga开发·fpga
北城笑笑30 分钟前
FPGA 16 ,Verilog中的位宽:深入理解与应用
fpga开发·fpga
热爱学习地派大星32 分钟前
FPGA在线升级 -- Multiboot
fpga开发·verilog·fpga·远程升级·升级程序
9527华安33 分钟前
FPGA实现GTP光口数据回环传输,基于Aurora 8b/10b编解码架构,提供2套工程源码和技术支持
fpga开发·gtp·8b/10b·高速接口
oioihoii5 小时前
XDMA与FPGA:高效数据传输的艺术
fpga开发
Anin蓝天(北京太速科技-陈)10 小时前
208-Base Camera Link 图像信号模拟器
嵌入式硬件·fpga开发·信号处理
北京太速科技股份有限公司1 天前
太速科技-721-基于TSI721的 PCIe转RapidIO高速数据传输卡
网络·fpga开发
北京太速科技股份有限公司1 天前
太速科技-622-基于ADRV9002 +ZYNQ7020 的软件无线电 SDR(升级AD9361)
fpga开发