module w3_ad_bridge ( //Ref clk for IDELAYCTRL input clk200, //Input sampling clocks - User design must provide these clock signals // sys_samp_clk_Tx requirements: // -Synchronous to and valid for capturing user_RFx_TXD ports // -Frequency must match AD9963 input data rate configuration (DAC clock / interpolation rate) input sys_samp_clk_Tx, // sys_samp_clk_Tx_90 must be 90 degree phase shift of sys_samp_clk_Tx (used to generate TXCLK output) input sys_samp_clk_Tx_90, // sys_samp_clk_Rx requirements: // -Synchronous to AD9963 ADC clock // -Frequency must match AD9963 output data rate configuration (ADC clock / decimation rate) // user_RFx_RXD outputs are synchronous to sys_samp_clk_Rx input sys_samp_clk_Rx, //RF Path A User Ports output [0:11] user_RFA_RXD_I, output [0:11] user_RFA_RXD_Q, input [0:11] user_RFA_TXD_I, input [0:11] user_RFA_TXD_Q, input user_RFA_TXIQ, //RF Path B User Ports output [0:11] user_RFB_RXD_I, output [0:11] user_RFB_RXD_Q, input [0:11] user_RFB_TXD_I, input [0:11] user_RFB_TXD_Q, input user_RFB_TXIQ, //RF Path A AD ports output [0:11] ad_RFA_TXD, output ad_RFA_TXIQ, output ad_RFA_TXCLK, input [0:11] ad_RFA_TRXD, input ad_RFA_TRXIQ, input ad_RFA_TRXCLK, //RF Path B AD ports output [0:11] ad_RFB_TXD, output ad_RFB_TXIQ, output ad_RFB_TXCLK, input [0:11] ad_RFB_TRXD, input ad_RFB_TRXIQ, input ad_RFB_TRXCLK ); parameter C_FAMILY = "virtex6"; assign ad_RFA_TXIQ = user_RFA_TXIQ; assign ad_RFB_TXIQ = user_RFB_TXIQ; //Use DDR primitives for cleanest output clock ODDR #( .DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE" .INIT(1'b0), // Initial value of Q: 1'b0 or 1'b1 .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" ) OBUFDDR_RFA_TXCLK ( .Q(ad_RFA_TXCLK), // 1-bit DDR output .C(sys_samp_clk_Tx_90), // 1-bit clock input .CE(1'b1), // 1-bit clock enable input .D1(1'b1), // 1-bit data input (positive edge) .D2(1'b0), // 1-bit data input (negative edge) .R(1'b0), // 1-bit reset .S(1'b0) // 1-bit set ); ODDR #( .DDR_CLK_EDGE("OPPOSITE_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE" .INIT(1'b0), // Initial value of Q: 1'b0 or 1'b1 .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" ) OBUFDDR_RFB_TXCLK ( .Q(ad_RFB_TXCLK), // 1-bit DDR output .C(sys_samp_clk_Tx_90), // 1-bit clock input .CE(1'b1), // 1-bit clock enable input .D1(1'b1), // 1-bit data input (positive edge) .D2(1'b0), // 1-bit data input (negative edge) .R(1'b0), // 1-bit reset .S(1'b0) // 1-bit set ); wire ad_RFA_TRXCLK_buf, ad_RFB_TRXCLK_buf; BUFIO BUFIO_RFA_TRXCLK ( .O(ad_RFA_TRXCLK_buf), // Clock buffer output .I(ad_RFA_TRXCLK) // Clock buffer input ); BUFIO BUFIO_RFB_TRXCLK ( .O(ad_RFB_TRXCLK_buf), // Clock buffer output .I(ad_RFB_TRXCLK) // Clock buffer input ); wire [0:11] user_RFA_RXD_I_src; wire [0:11] user_RFA_RXD_Q_src; wire [0:11] user_RFB_RXD_I_src; wire [0:11] user_RFB_RXD_Q_src; //Instantiate all the DDR registers for TXD and TRXD I/O // Only selects bits [0:11] (12MSB) of 14-bit Tx I/Q samples provided by user logic genvar ii; generate for(ii=0; ii<12; ii=ii+1) begin: DDR_REGS_RFA_RFB ODDR #( .DDR_CLK_EDGE("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE" .INIT(1'b0), // Initial value of Q: 1'b0 or 1'b1 .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" ) ODDR_RFA_TXD ( .Q(ad_RFA_TXD[ii]), // 1-bit DDR output .C(sys_samp_clk_Tx), // 1-bit clock input .CE(1'b1), // 1-bit clock enable input .D1(user_RFA_TXD_I[ii]), // 1-bit data input (positive edge) .D2(user_RFA_TXD_Q[ii]), // 1-bit data input (negative edge) .R(1'b0), // 1-bit reset .S(1'b0) // 1-bit set ); ODDR #( .DDR_CLK_EDGE("SAME_EDGE"), // "OPPOSITE_EDGE" or "SAME_EDGE" .INIT(1'b0), // Initial value of Q: 1'b0 or 1'b1 .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" ) ODDR_RFB_TXD ( .Q(ad_RFB_TXD[ii]), // 1-bit DDR output .C(sys_samp_clk_Tx), // 1-bit clock input .CE(1'b1), // 1-bit clock enable input .D1(user_RFB_TXD_I[ii]), // 1-bit data input (positive edge) .D2(user_RFB_TXD_Q[ii]), // 1-bit data input (negative edge) .R(1'b0), // 1-bit reset .S(1'b0) // 1-bit set ); IDDR #( .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), // "OPPOSITE_EDGE", "SAME_EDGE" or "SAME_EDGE_PIPELINED" .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1 .INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1 .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" ) IDDR_RFA_TRXD ( .Q1(user_RFA_RXD_I_src[ii]), // 1-bit output for positive edge of clock .Q2(user_RFA_RXD_Q_src[ii]), // 1-bit output for negative edge of clock .C(ad_RFA_TRXCLK_buf), // 1-bit clock input .CE(1'b1), // 1-bit clock enable input .D(ad_RFA_TRXD[ii]), // 1-bit DDR data input .R(1'b0), // 1-bit reset .S(1'b0) // 1-bit set ); IDDR #( .DDR_CLK_EDGE("SAME_EDGE_PIPELINED"), // "OPPOSITE_EDGE", "SAME_EDGE" or "SAME_EDGE_PIPELINED" .INIT_Q1(1'b0), // Initial value of Q1: 1'b0 or 1'b1 .INIT_Q2(1'b0), // Initial value of Q2: 1'b0 or 1'b1 .SRTYPE("SYNC") // Set/Reset type: "SYNC" or "ASYNC" ) IDDR_RFB_TRXD ( .Q1(user_RFB_RXD_I_src[ii]), // 1-bit output for positive edge of clock .Q2(user_RFB_RXD_Q_src[ii]), // 1-bit output for negative edge of clock .C(ad_RFB_TRXCLK_buf), // 1-bit clock input .CE(1'b1), // 1-bit clock enable input .D(ad_RFB_TRXD[ii]), // 1-bit DDR data input .R(1'b0), // 1-bit reset .S(1'b0) // 1-bit set ); //D flip flops to connect source-syncronous inputs to samp_clk domain (TRXCLK and samp_clk have same rate, arbitrary phases) FDSE #(.INIT(1'b0)) DFF2_RFA_I (.D(user_RFA_RXD_I_src[ii]), .Q(user_RFA_RXD_I[ii]), .C(sys_samp_clk_Rx), .S(1'b0), .CE(1'b1)); FDSE #(.INIT(1'b0)) DFF2_RFA_Q (.D(user_RFA_RXD_Q_src[ii]), .Q(user_RFA_RXD_Q[ii]), .C(sys_samp_clk_Rx), .S(1'b0), .CE(1'b1)); FDSE #(.INIT(1'b0)) DFF2_RFB_I (.D(user_RFB_RXD_I_src[ii]), .Q(user_RFB_RXD_I[ii]), .C(sys_samp_clk_Rx), .S(1'b0), .CE(1'b1)); FDSE #(.INIT(1'b0)) DFF2_RFB_Q (.D(user_RFB_RXD_Q_src[ii]), .Q(user_RFB_RXD_Q[ii]), .C(sys_samp_clk_Rx), .S(1'b0), .CE(1'b1)); end endgenerate endmodule