ad_serdes_in: Update the serdes_in module

Add additional IDELAY block before the ISERDES. Delet the IDDR blocks. Be aware, the ISERDES block are running in DDR mode. If the interface is SDR the maximum parallel data width is 4.
main
Istvan Csomortani 2014-09-25 16:40:29 +03:00
parent 27ffff827a
commit 079ed0ffb3
2 changed files with 270 additions and 277 deletions

View File

@ -158,12 +158,10 @@ module axi_ad9434_if (
reg adc_status_m1 = 'd0;
// internal signals
wire [11:0] adc_data_p_s;
wire [11:0] adc_data_n_s;
wire adc_or_p_s;
wire adc_or_n_s;
wire [ 4:0] delay_rdata_s[12:0];
wire [3:0] adc_or_s;
wire adc_clk_in;
wire adc_div_clk;
@ -224,43 +222,58 @@ module axi_ad9434_if (
// data interface
generate
for (l_inst = 0; l_inst <= 11; l_inst = l_inst + 1) begin : g_adc_if
ad_lvds_in #(
.BUFTYPE (PCORE_BUFTYPE),
.IODELAY_CTRL (0),
.IODELAY_GROUP (PCORE_IODELAY_GROUP))
i_adc_data (
.rx_clk (adc_clk_in),
.rx_data_in_p (adc_data_in_p[l_inst]),
.rx_data_in_n (adc_data_in_n[l_inst]),
.rx_data_p (adc_data_p_s[l_inst]),
.rx_data_n (adc_data_n_s[l_inst]),
.delay_clk (delay_clk),
.delay_rst (delay_rst),
.delay_ld (delay_ld[l_inst]),
.delay_wdata (delay_wdata),
.delay_rdata (delay_rdata_s[l_inst]),
.delay_locked ());
end
ad_serdes_in #(
.DEVICE_TYPE(PCORE_DEVTYPE),
.IODELAY_CTRL(0),
.IODELAY_GROUP(PCORE_IODELAY_GROUP))
i_adc_data (
.rst(adc_rst),
.clk(adc_clk_in),
.div_clk(adc_div_clk),
.data_s0(adc_data[(0*12)+l_inst]),
.data_s1(adc_data[(1*12)+l_inst]),
.data_s2(adc_data[(2*12)+l_inst]),
.data_s3(adc_data[(3*12)+l_inst]),
.data_s4(),
.data_s5(),
.data_s6(),
.data_s7(),
.data_in_p(adc_data_in_p[l_inst]),
.data_in_n(adc_data_in_n[l_inst]),
.delay_clk(delay_clk),
.delay_rst(delay_rst),
.delay_ld(delay_ld[l_inst]),
.delay_wdata(delay_wdata),
.delay_rdata(delay_rdata_s[l_inst]),
.delay_locked());
end
endgenerate
// over-range interface
ad_lvds_in #(
.BUFTYPE (PCORE_BUFTYPE),
.IODELAY_CTRL (1),
.IODELAY_GROUP (PCORE_IODELAY_GROUP))
i_adc_or (
.rx_clk (adc_clk_in),
.rx_data_in_p (adc_or_in_p),
.rx_data_in_n (adc_or_in_n),
.rx_data_p (adc_or_p_s),
.rx_data_n (adc_or_n_s),
.delay_clk (delay_clk),
.delay_rst (delay_rst),
.delay_ld (delay_ld[12]),
.delay_wdata (delay_wdata),
.delay_rdata (delay_rdata_s[12]),
.delay_locked (delay_locked));
ad_serdes_in #(
.DEVICE_TYPE(PCORE_DEVTYPE),
.IODELAY_CTRL(1),
.IODELAY_GROUP(PCORE_IODELAY_GROUP))
i_adc_data (
.rst(adc_rst),
.clk(adc_clk_in),
.div_clk(adc_div_clk),
.data_s0(adc_or_s[0]),
.data_s1(adc_or_s[1]),
.data_s2(adc_or_s[2]),
.data_s3(adc_or_s[3]),
.data_s4(),
.data_s5(),
.data_s6(),
.data_s7(),
.data_in_p(adc_or_in_p),
.data_in_n(adc_or_in_n),
.delay_clk(delay_clk),
.delay_rst(delay_rst),
.delay_ld(delay_ld[12]),
.delay_wdata(delay_wdata),
.delay_rdata(delay_rdata_s[12]),
.delay_locked(delay_locked));
// clock input buffers and MMCM
ad_serdes_clk #(
@ -286,47 +299,8 @@ module axi_ad9434_if (
.drp_ready (drp_ready),
.drp_locked (drp_locked));
// input SERDES for data
ad_serdes_in #(
.DEVICE_TYPE(PCORE_DEVTYPE),
.SERDES(1),
.DATA_WIDTH(12),
.PARALLEL_DATA_WIDTH(4))
i_serdes_data (
.rst(adc_rst),
.clk(adc_clk_in),
.div_clk(adc_div_clk),
.data_s0(adc_data_s0),
.data_s1(adc_data_s1),
.data_s2(adc_data_s2),
.data_s3(adc_data_s3),
.data_s4(),
.data_s5(),
.data_s6(),
.data_s7(),
.data_in_p(adc_data_p_s),
.data_in_n(adc_data_n_s));
// input SERDES for overrange
ad_serdes_in #(
.DEVICE_TYPE(PCORE_DEVTYPE),
.SERDES(1),
.DATA_WIDTH(1),
.PARALLEL_DATA_WIDTH(4))
i_serdes_or (
.rst(adc_rst),
.clk(adc_clk_in),
.div_clk(adc_div_clk),
.data_s0(adc_or_s0),
.data_s1(adc_or_s1),
.data_s2(adc_or_s2),
.data_s3(adc_or_s3),
.data_s4(),
.data_s5(),
.data_s6(),
.data_s7(),
.data_in_p(adc_or_p_s),
.data_in_n(adc_or_n_s));
// adc overange
assign adc_or = adc_or_s[0] | adc_or_s[1] | adc_or_s[2] | adc_or_s[3];
// adc status: adc is up, if both the MMCM and DELAY blocks are up
always @(posedge adc_div_clk) begin

View File

@ -42,11 +42,13 @@
module ad_serdes_in (
// reset and clocks
rst,
clk,
div_clk,
// data interface
data_s0,
data_s1,
data_s2,
@ -56,65 +58,112 @@ module ad_serdes_in (
data_s6,
data_s7,
data_in_p,
data_in_n);
data_in_n,
// delay interface
delay_clk,
delay_rst,
delay_ld,
delay_wdata,
delay_rdata,
delay_locked);
// parameters
parameter DEVICE_TYPE = 0;
parameter SERDES = 1;
parameter DATA_WIDTH = 16;
parameter PARALLEL_DATA_WIDTH = 8;
localparam DEVICE_6SERIES = 1;
localparam DEVICE_7SERIES = 0;
localparam DW = DATA_WIDTH - 1;
parameter DEVICE_TYPE = 0;
parameter IODELAY_CTRL = 0;
parameter IODELAY_GROUP = "dev_if_delay_group";
localparam DEVICE_6SERIES = 1;
localparam DEVICE_7SERIES = 0;
// reset and clocks
input rst;
input clk;
input div_clk;
// data interface
output [DW:0] data_s0;
output [DW:0] data_s1;
output [DW:0] data_s2;
output [DW:0] data_s3;
output [DW:0] data_s4;
output [DW:0] data_s5;
output [DW:0] data_s6;
output [DW:0] data_s7;
input [DW:0] data_in_p;
input [DW:0] data_in_n;
output data_s0;
output data_s1;
output data_s2;
output data_s3;
output data_s4;
output data_s5;
output data_s6;
output data_s7;
input data_in_p;
input data_in_n;
// delay interface
input delay_clk;
input delay_rst;
input delay_ld;
input [ 4:0] delay_wdata;
output [ 4:0] delay_rdata;
output delay_locked;
// internal signals
wire [DW:0] data_in_s;
wire [DW:0] data_shift1_s;
wire [DW:0] data_shift2_s;
// instantiations
genvar l_inst;
wire data_in_ibuf_s;
wire data_in_idelay_s;
wire data_shift1_s;
wire data_shift2_s;
// delay controller
generate
for (l_inst = 0; l_inst <= DW; l_inst = l_inst + 1) begin
if (SERDES == 0) begin
IDDR #(
.DDR_CLK_EDGE("SAME_EDGE"),
.INIT_Q1(1'b0),
.INIT_Q2(1'b0),
.SRTYPE("ASYNC"))
i_iddr (
.Q1(data_s0[l_inst]),
.Q2(data_s1[l_inst]),
.C(clk),
.CE(1'b1),
.D(data_in_s[l_inst]),
.R(rst),
.S(1'b0)
);
end
if (IODELAY_CTRL == 1) begin
(* IODELAY_GROUP = IODELAY_GROUP *)
IDELAYCTRL i_delay_ctrl (
.RST (delay_rst),
.REFCLK (delay_clk),
.RDY (delay_locked));
end else begin
assign delay_locked = 1'b1;
end
endgenerate
// received data interface: ibuf -> idelay -> iserdes
IBUFDS i_ibuf (
.O(data_in_ibuf_s),
.I(data_in_p),
.IB(data_in_n)
);
if(DEVICE_TYPE == DEVICE_7SERIES) begin
(* IODELAY_GROUP = IODELAY_GROUP *)
IDELAYE2 #(
.CINVCTRL_SEL ("FALSE"),
.DELAY_SRC ("IDATAIN"),
.HIGH_PERFORMANCE_MODE ("FALSE"),
.IDELAY_TYPE ("VAR_LOAD"),
.IDELAY_VALUE (0),
.REFCLK_FREQUENCY (200.0),
.PIPE_SEL ("FALSE"),
.SIGNAL_PATTERN ("DATA"))
i_rx_data_idelay (
.CE (1'b0),
.INC (1'b0),
.DATAIN (1'b0),
.LDPIPEEN (1'b0),
.CINVCTRL (1'b0),
.REGRST (1'b0),
.C (delay_clk),
.IDATAIN (data_in_ibuf_s),
.DATAOUT (data_in_idelay_s),
.LD (delay_ld),
.CNTVALUEIN (delay_wdata),
.CNTVALUEOUT (delay_rdata));
if ((SERDES == 1) && (DEVICE_TYPE == DEVICE_7SERIES)) begin
ISERDESE2 #(
.DATA_RATE("SDR"),
.DATA_WIDTH(PARALLEL_DATA_WIDTH),
.DATA_RATE("DDR"),
.DATA_WIDTH(8),
.DYN_CLKDIV_INV_EN("FALSE"),
.DYN_CLK_INV_EN("FALSE"),
.INIT_Q1(1'b0),
@ -129,18 +178,17 @@ module ad_serdes_in (
.SRVAL_Q1(1'b0),
.SRVAL_Q2(1'b0),
.SRVAL_Q3(1'b0),
.SRVAL_Q4(1'b0)
)
.SRVAL_Q4(1'b0))
ISERDESE2_inst (
.O(),
.Q1(data_s0[l_inst]),
.Q2(data_s1[l_inst]),
.Q3(data_s2[l_inst]),
.Q4(data_s3[l_inst]),
.Q5(data_s4[l_inst]),
.Q6(data_s5[l_inst]),
.Q7(data_s6[l_inst]),
.Q8(data_s7[l_inst]),
.Q1(data_s0),
.Q2(data_s1),
.Q3(data_s2),
.Q4(data_s3),
.Q5(data_s4),
.Q6(data_s5),
.Q7(data_s6),
.Q8(data_s7),
.SHIFTOUT1(),
.SHIFTOUT2(),
.BITSLIP(1'b0),
@ -153,7 +201,7 @@ module ad_serdes_in (
.OCLK(1'b0),
.DYNCLKDIVSEL(1'b0),
.DYNCLKSEL(1'b0),
.D(data_in_s[l_inst]),
.D(data_in_idelay_s),
.DDLY(1'b0),
.OFB(1'b0),
.OCLKB(1'b0),
@ -161,153 +209,124 @@ module ad_serdes_in (
.SHIFTIN1(1'b0),
.SHIFTIN2(1'b0)
);
end
end
if ((SERDES == 1) && (DEVICE_TYPE == DEVICE_6SERIES)) begin
if (PARALLEL_DATA_WIDTH <= 6) begin
ISERDESE1 #(
.DATA_RATE("SDR"),
.DATA_WIDTH(PARALLEL_DATA_WIDTH),
.DYN_CLKDIV_INV_EN("FALSE"),
.DYN_CLK_INV_EN("FALSE"),
.INIT_Q1(1'b0),
.INIT_Q2(1'b0),
.INIT_Q3(1'b0),
.INIT_Q4(1'b0),
.INTERFACE_TYPE("NETWORKING"),
.IOBDELAY("NONE"),
.NUM_CE(1),
.OFB_USED("FALSE"),
.SERDES_MODE("MASTER"),
.SRVAL_Q1(1'b0),
.SRVAL_Q2(1'b0),
.SRVAL_Q3(1'b0),
.SRVAL_Q4(1'b0))
i_serdes (
.O(),
.Q1(data_s0[l_inst]),
.Q2(data_s1[l_inst]),
.Q3(data_s2[l_inst]),
.Q4(data_s3[l_inst]),
.Q5(data_s4[l_inst]),
.Q6(data_s5[l_inst]),
.SHIFTOUT1(data_shift1_s[l_inst]),
.SHIFTOUT2(data_shift2_s[l_inst]),
.BITSLIP(1'b0),
.CE1(1'b1),
.CE2(1'b1),
.CLK(clk),
.CLKB(1'b0),
.CLKDIV(div_clk),
.OCLK(1'b0),
.DYNCLKDIVSEL(1'b0),
.DYNCLKSEL(1'b0),
.D(data_in_s[l_inst]),
.DDLY(1'b0),
.OFB(1'b0),
.RST(rst),
.SHIFTIN1(1'b0),
.SHIFTIN2(1'b0)
);
end else begin
ISERDESE1 #(
.DATA_RATE("SDR"),
.DATA_WIDTH(PARALLEL_DATA_WIDTH),
.DYN_CLKDIV_INV_EN("FALSE"),
.DYN_CLK_INV_EN("FALSE"),
.INIT_Q1(1'b0),
.INIT_Q2(1'b0),
.INIT_Q3(1'b0),
.INIT_Q4(1'b0),
.INTERFACE_TYPE("NETWORKING"),
.IOBDELAY("NONE"),
.NUM_CE(1),
.OFB_USED("FALSE"),
.SERDES_MODE("MASTER"),
.SRVAL_Q1(1'b0),
.SRVAL_Q2(1'b0),
.SRVAL_Q3(1'b0),
.SRVAL_Q4(1'b0))
i_serdes_m (
.O(),
.Q1(data_s0[l_inst]),
.Q2(data_s1[l_inst]),
.Q3(data_s2[l_inst]),
.Q4(data_s3[l_inst]),
.Q5(data_s4[l_inst]),
.Q6(data_s5[l_inst]),
.SHIFTOUT1(data_shift1_s[l_inst]),
.SHIFTOUT2(data_shift2_s[l_inst]),
.BITSLIP(1'b0),
.CE1(1'b1),
.CE2(1'b1),
.CLK(clk),
.CLKB(1'b0),
.CLKDIV(div_clk),
.OCLK(1'b0),
.DYNCLKDIVSEL(1'b0),
.DYNCLKSEL(1'b0),
.D(data_in_s[l_inst]),
.DDLY(1'b0),
.OFB(1'b0),
.RST(rst),
.SHIFTIN1(1'b0),
.SHIFTIN2(1'b0)
);
if(DEVICE_TYPE == DEVICE_6SERIES) begin
(* IODELAY_GROUP = IODELAY_GROUP *)
IODELAYE1 #(
.CINVCTRL_SEL ("FALSE"),
.DELAY_SRC ("I"),
.HIGH_PERFORMANCE_MODE ("TRUE"),
.IDELAY_TYPE ("VAR_LOADABLE"),
.IDELAY_VALUE (0),
.ODELAY_TYPE ("FIXED"),
.ODELAY_VALUE (0),
.REFCLK_FREQUENCY (200.0),
.SIGNAL_PATTERN ("DATA"))
i_rx_data_idelay (
.T (1'b1),
.CE (1'b0),
.INC (1'b0),
.CLKIN (1'b0),
.DATAIN (1'b0),
.ODATAIN (1'b0),
.CINVCTRL (1'b0),
.C (delay_clk),
.IDATAIN (data_in_ibuf_s),
.DATAOUT (data_in_idelay_s),
.RST (delay_ld),
.CNTVALUEIN (delay_wdata),
.CNTVALUEOUT (delay_rdata));
ISERDESE1 #(
.DATA_RATE("SDR"),
.DATA_WIDTH(PARALLEL_DATA_WIDTH),
.DYN_CLKDIV_INV_EN("FALSE"),
.DYN_CLK_INV_EN("FALSE"),
.INIT_Q1(1'b0),
.INIT_Q2(1'b0),
.INIT_Q3(1'b0),
.INIT_Q4(1'b0),
.INTERFACE_TYPE("NETWORKING"),
.IOBDELAY("NONE"),
.NUM_CE(1),
.OFB_USED("FALSE"),
.SERDES_MODE("SLAVE"),
.SRVAL_Q1(1'b0),
.SRVAL_Q2(1'b0),
.SRVAL_Q3(1'b0),
.SRVAL_Q4(1'b0))
i_serdes_s (
.O(),
.Q1(),
.Q2(),
.Q3(data_s6),
.Q4(data_s7),
.Q5(),
.Q6(),
.SHIFTOUT1(),
.SHIFTOUT2(),
.BITSLIP(1'b0),
.CE1(1'b1),
.CE2(1'b1),
.CLK(clk),
.CLKB(1'b0),
.CLKDIV(div_clk),
.OCLK(1'b0),
.DYNCLKDIVSEL(1'b0),
.DYNCLKSEL(1'b0),
.D(1'b0),
.DDLY(1'b0),
.OFB(1'b0),
.RST(rst),
.SHIFTIN1(data_shift1_s[l_inst]),
.SHIFTIN2(data_shift2_s[l_inst]));
end
end
ISERDESE1 #(
.DATA_RATE("DDR"),
.DATA_WIDTH(8),
.DYN_CLKDIV_INV_EN("FALSE"),
.DYN_CLK_INV_EN("FALSE"),
.INIT_Q1(1'b0),
.INIT_Q2(1'b0),
.INIT_Q3(1'b0),
.INIT_Q4(1'b0),
.INTERFACE_TYPE("NETWORKING"),
.IOBDELAY("NONE"),
.NUM_CE(1),
.OFB_USED("FALSE"),
.SERDES_MODE("MASTER"),
.SRVAL_Q1(1'b0),
.SRVAL_Q2(1'b0),
.SRVAL_Q3(1'b0),
.SRVAL_Q4(1'b0))
i_serdes_m (
.O(),
.Q1(data_s0),
.Q2(data_s1),
.Q3(data_s2),
.Q4(data_s3),
.Q5(data_s4),
.Q6(data_s5),
.SHIFTOUT1(data_shift1_s),
.SHIFTOUT2(data_shift2_s),
.BITSLIP(1'b0),
.CE1(1'b1),
.CE2(1'b1),
.CLK(clk),
.CLKB(1'b0),
.CLKDIV(div_clk),
.OCLK(1'b0),
.DYNCLKDIVSEL(1'b0),
.DYNCLKSEL(1'b0),
.D(data_in_idelay_s),
.DDLY(1'b0),
.OFB(1'b0),
.RST(rst),
.SHIFTIN1(1'b0),
.SHIFTIN2(1'b0)
);
IBUFDS i_ibuf (
.O(data_in_s[l_inst]),
.I(data_in_p[l_inst]),
.IB(data_in_n[l_inst])
);
end
endgenerate
ISERDESE1 #(
.DATA_RATE("DDR"),
.DATA_WIDTH(8),
.DYN_CLKDIV_INV_EN("FALSE"),
.DYN_CLK_INV_EN("FALSE"),
.INIT_Q1(1'b0),
.INIT_Q2(1'b0),
.INIT_Q3(1'b0),
.INIT_Q4(1'b0),
.INTERFACE_TYPE("NETWORKING"),
.IOBDELAY("NONE"),
.NUM_CE(1),
.OFB_USED("FALSE"),
.SERDES_MODE("SLAVE"),
.SRVAL_Q1(1'b0),
.SRVAL_Q2(1'b0),
.SRVAL_Q3(1'b0),
.SRVAL_Q4(1'b0))
i_serdes_s (
.O(),
.Q1(),
.Q2(),
.Q3(data_s6),
.Q4(data_s7),
.Q5(),
.Q6(),
.SHIFTOUT1(),
.SHIFTOUT2(),
.BITSLIP(1'b0),
.CE1(1'b1),
.CE2(1'b1),
.CLK(clk),
.CLKB(1'b0),
.CLKDIV(div_clk),
.OCLK(1'b0),
.DYNCLKDIVSEL(1'b0),
.DYNCLKSEL(1'b0),
.D(1'b0),
.DDLY(1'b0),
.OFB(1'b0),
.RST(rst),
.SHIFTIN1(data_shift1_s),
.SHIFTIN2(data_shift2_s));
end
endmodule