ad9467: register map changes

main
Rejeesh Kutty 2014-07-30 15:31:09 -04:00
parent c215eab696
commit dfd11cb809
5 changed files with 489 additions and 678 deletions

View File

@ -37,7 +37,7 @@
// *************************************************************************** // ***************************************************************************
// *************************************************************************** // ***************************************************************************
`timescale 1ns/1ns `timescale 1ns/100ps
module axi_ad9467( module axi_ad9467(
@ -47,8 +47,8 @@ module axi_ad9467(
adc_clk_in_n, adc_clk_in_n,
adc_data_in_p, adc_data_in_p,
adc_data_in_n, adc_data_in_n,
adc_data_or_p, adc_or_in_p,
adc_data_or_n, adc_or_in_n,
// delay_clock // delay_clock
@ -57,9 +57,11 @@ module axi_ad9467(
// dma interface // dma interface
adc_clk, adc_clk,
adc_dwr, adc_valid,
adc_ddata, adc_enable,
adc_doverflow, adc_data,
adc_dovf,
adc_dunf,
// axi interface // axi interface
@ -81,8 +83,7 @@ module axi_ad9467(
s_axi_rvalid, s_axi_rvalid,
s_axi_rresp, s_axi_rresp,
s_axi_rdata, s_axi_rdata,
s_axi_rready s_axi_rready);
);
// parameters // parameters
@ -90,8 +91,8 @@ module axi_ad9467(
parameter PCORE_BUFTYPE = 0; parameter PCORE_BUFTYPE = 0;
parameter PCORE_IODELAY_GROUP = "dev_if_delay_group"; parameter PCORE_IODELAY_GROUP = "dev_if_delay_group";
parameter C_S_AXI_MIN_SIZE = 32'hffff; parameter C_S_AXI_MIN_SIZE = 32'hffff;
parameter C_BASEADDR = 32'hffffffff; parameter C_HIGHADDR = 32'hffffffff;
parameter C_HIGHADDR = 32'h00000000; parameter C_BASEADDR = 32'h00000000;
// physical interface // physical interface
@ -99,8 +100,8 @@ module axi_ad9467(
input adc_clk_in_n; input adc_clk_in_n;
input [ 7:0] adc_data_in_p; input [ 7:0] adc_data_in_p;
input [ 7:0] adc_data_in_n; input [ 7:0] adc_data_in_n;
input adc_data_or_p; input adc_or_in_p;
input adc_data_or_n; input adc_or_in_n;
// delay clk // delay clk
@ -109,9 +110,11 @@ module axi_ad9467(
// dma interface // dma interface
output adc_clk; output adc_clk;
output adc_dwr; output adc_valid;
output [15:0] adc_ddata; output adc_enable;
input adc_doverflow; output [15:0] adc_data;
input adc_dovf;
input adc_dunf;
// axi interface // axi interface
@ -136,59 +139,59 @@ module axi_ad9467(
input s_axi_rready; input s_axi_rready;
// internal registers // internal registers
reg [31:0] up_rdata = 32'b0;
reg up_ack = 1'b0;
// internal clock and resets reg [31:0] up_rdata = 'd0;
reg up_ack = 'd0;
// internal clocks & resets
wire adc_rst;
wire up_clk; wire up_clk;
wire up_rstn; wire up_rstn;
wire adc_rst;
wire adc_clk;
// internal signals // internal signals
wire up_sel_s;
wire up_wr_s; wire [15:0] adc_data_s;
wire [13:0] up_addr_s;
wire [31:0] up_wdata_s;
wire [15:0] adc_data_if_s;
wire adc_or_s; wire adc_or_s;
wire up_adc_or_s;
wire adc_ddr_edgesel_s; wire adc_ddr_edgesel_s;
wire delay_rst_s;
wire delay_sel_s; wire delay_sel_s;
wire delay_rwn_s; wire delay_rwn_s;
wire [ 7:0] delay_addr_s; wire [ 7:0] delay_addr_s;
wire [ 4:0] delay_wdata_s; wire [ 4:0] delay_wdata_s;
wire delay_rst;
wire delay_ack_s;
wire [ 4:0] delay_rdata_s; wire [ 4:0] delay_rdata_s;
wire delay_ack_t_s;
wire delay_locked_s; wire delay_locked_s;
wire adc_pn_oos_s; wire up_status_pn_err_s;
wire adc_pn_err_s; wire up_status_pn_oos_s;
wire [31:0] up_rdata_common; wire up_status_or_s;
wire [31:0] up_rdata_channel; wire [31:0] up_rdata_s[0:1];
wire up_ack_common; wire up_ack_s[0:1];
wire up_ack_channel; wire up_sel_s;
wire adc_pn_type_s; wire up_wr_s;
wire [15:0] adc_channel_data_s; wire [13:0] up_addr_s;
wire adc_enable_s; wire [31:0] up_wdata_s;
//defaults
assign up_clk = s_axi_aclk; assign up_clk = s_axi_aclk;
assign up_rstn = s_axi_aresetn; assign up_rstn = s_axi_aresetn;
assign adc_dwr = 1'b1; assign adc_valid = 1'b1;
assign adc_ddata = adc_data_if_s;
// processor read interface // processor read interface
always @(negedge up_rstn or posedge up_clk) begin always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin if (up_rstn == 0) begin
up_rdata <= 32'd0; up_rdata <= 32'd0;
up_ack <= 1'd0; up_ack <= 1'd0;
end else begin end else begin
up_rdata <= up_rdata_channel | up_rdata_common; up_rdata <= up_rdata_s[0] | up_rdata_s[1];
up_ack <= up_ack_channel | up_ack_common; up_ack <= up_ack_s[0] | up_ack_s[1];
end end
end end
// ADC data interface // main (device interface)
axi_ad9467_if #( axi_ad9467_if #(
.PCORE_BUFTYPE (PCORE_BUFTYPE), .PCORE_BUFTYPE (PCORE_BUFTYPE),
.PCORE_IODELAY_GROUP (PCORE_IODELAY_GROUP)) .PCORE_IODELAY_GROUP (PCORE_IODELAY_GROUP))
@ -197,88 +200,92 @@ module axi_ad9467(
.adc_clk_in_n (adc_clk_in_n), .adc_clk_in_n (adc_clk_in_n),
.adc_data_in_p (adc_data_in_p), .adc_data_in_p (adc_data_in_p),
.adc_data_in_n (adc_data_in_n), .adc_data_in_n (adc_data_in_n),
.adc_data_or_p (adc_data_or_p), .adc_or_in_p (adc_or_in_p),
.adc_data_or_n (adc_data_or_n), .adc_or_in_n (adc_or_in_n),
.adc_clk (adc_clk), .adc_clk (adc_clk),
.adc_data (adc_data_if_s), .adc_data (adc_data_s),
.adc_or (adc_or_s), .adc_or (adc_or_s),
.adc_ddr_edgesel (adc_ddr_edgesel_s), .adc_ddr_edgesel (adc_ddr_edgesel_s),
.delay_clk (delay_clk),
.delay_rst (delay_rst_s),
.delay_sel (delay_sel_s), .delay_sel (delay_sel_s),
.delay_rwn (delay_rwn_s), .delay_rwn (delay_rwn_s),
.delay_addr (delay_addr_s), .delay_addr (delay_addr_s),
.delay_wdata (delay_wdata_s), .delay_wdata (delay_wdata_s),
.delay_clk (delay_clk),
.delay_ack (delay_ack_s),
.delay_rst (delay_rst),
.delay_rdata (delay_rdata_s), .delay_rdata (delay_rdata_s),
.delay_ack_t (delay_ack_t),
.delay_locked (delay_locked_s)); .delay_locked (delay_locked_s));
// channel // channel
axi_ad9467_channel #(.CHID(0)) i_channel ( axi_ad9467_channel #(.CHID(0)) i_channel (
.adc_clk (adc_clk), .adc_clk (adc_clk),
.adc_rst (adc_rst), .adc_rst (adc_rst),
.adc_data(adc_data_if_s), .adc_data (adc_data_s),
.adc_or (adc_or_s), .adc_or (adc_or_s),
.adc_dfmt_data(adc_channel_data_s), .adc_dfmt_data (adc_data),
.adc_enable(adc_enable_s), .adc_enable (adc_enable),
.up_adc_pn_err(adc_pn_err_s), .up_adc_pn_err (up_status_pn_err_s),
.up_adc_pn_oos(adc_pn_oos_s), .up_adc_pn_oos (up_status_pn_oos_s),
.up_adc_or(up_adc_or_s), .up_adc_or (up_status_or_s),
.up_rstn (up_rstn), .up_rstn (up_rstn),
.up_clk (up_clk), .up_clk (up_clk),
.up_sel (up_sel_s), .up_sel (up_sel_s),
.up_wr (up_wr_s), .up_wr (up_wr_s),
.up_addr (up_addr_s), .up_addr (up_addr_s),
.up_wdata (up_wdata_s), .up_wdata (up_wdata_s),
.up_rdata(up_rdata_channel), .up_rdata (up_rdata_s[0]),
.up_ack(up_ack_channel)); .up_ack (up_ack_s[0]));
// common processor control // common processor control
up_adc_common #(.PCORE_ID(PCORE_ID))
i_up_adc_common( up_adc_common #(.PCORE_ID(PCORE_ID)) i_up_adc_common (
.mmcm_rst (), .mmcm_rst (),
.delay_clk(delay_clk),
.delay_ack_t(delay_ack_s),
.delay_locked(delay_locked_s),
.delay_rst(delay_rst),
.delay_sel(delay_sel_s),
.delay_rwn(delay_rwn_s),
.delay_addr(delay_addr_s),
.delay_wdata(delay_wdata_s),
.delay_rdata(delay_rdata_s),
.adc_clk (adc_clk), .adc_clk (adc_clk),
.adc_rst (adc_rst), .adc_rst (adc_rst),
.adc_r1_mode (), .adc_r1_mode (),
.adc_ddr_edgesel (adc_ddr_edgesel_s), .adc_ddr_edgesel (adc_ddr_edgesel_s),
.adc_pin_mode (), .adc_pin_mode (),
.adc_status (1'b1), .adc_status (1'b1),
.adc_status_pn_err(adc_pn_err_s), .adc_status_ovf (adc_dovf),
.adc_status_pn_oos(adc_pn_oos_s), .adc_status_unf (adc_dunf),
.adc_status_or(up_adc_or_s),
.adc_clk_ratio (32'b1), .adc_clk_ratio (32'b1),
.adc_status_ovf(adc_doverflow), .up_status_pn_err (up_status_pn_err_s),
.adc_status_unf(1'b0), .up_status_pn_oos (up_status_pn_oos_s),
.up_status_or (up_status_or_s),
.delay_clk (delay_clk),
.delay_rst (delay_rst_s),
.delay_sel (delay_sel_s),
.delay_rwn (delay_rwn_s),
.delay_addr (delay_addr_s),
.delay_wdata (delay_wdata_s),
.delay_rdata (delay_rdata_s),
.delay_ack_t (delay_ack_t),
.delay_locked (delay_locked_s),
.drp_clk (1'b0), .drp_clk (1'b0),
.drp_rdata(16'b0),
.drp_rst (), .drp_rst (),
.drp_sel (), .drp_sel (),
.drp_wr (), .drp_wr (),
.drp_addr (), .drp_addr (),
.drp_wdata (), .drp_wdata (),
.drp_rdata (16'b0),
.drp_ready (1'b0), .drp_ready (1'b0),
.drp_locked (1'b1), .drp_locked (1'b1),
.up_usr_chanmax (),
.adc_usr_chanmax (8'd1),
.up_adc_gpio_in (32'd0),
.up_adc_gpio_out (),
.up_rstn (up_rstn), .up_rstn (up_rstn),
.up_clk (up_clk), .up_clk (up_clk),
.up_sel (up_sel_s), .up_sel (up_sel_s),
.up_wr (up_wr_s), .up_wr (up_wr_s),
.up_addr (up_addr_s), .up_addr (up_addr_s),
.up_wdata (up_wdata_s), .up_wdata (up_wdata_s),
.up_rdata(up_rdata_common), .up_rdata (up_rdata_s[1]),
.up_ack(up_ack_common), .up_ack (up_ack_s[1]));
.up_usr_chanmax(),
.adc_usr_chanmax(8'b0)); // up bus interface
// axi interface
up_axi #( up_axi #(
.PCORE_BASEADDR (C_BASEADDR), .PCORE_BASEADDR (C_BASEADDR),
.PCORE_HIGHADDR (C_HIGHADDR)) .PCORE_HIGHADDR (C_HIGHADDR))
@ -310,3 +317,6 @@ module axi_ad9467(
.up_ack (up_ack)); .up_ack (up_ack));
endmodule endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -34,23 +34,20 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *************************************************************************** // ***************************************************************************
// *************************************************************************** // ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/1ns `timescale 1ns/100ps
//------------------------------------------------------------------------------
//----------- Module Declaration -----------------------------------------------
//------------------------------------------------------------------------------
module axi_ad9467_channel( module axi_ad9467_channel(
// adc interface // adc interface
adc_clk, adc_clk,
adc_rst, adc_rst,
adc_data, adc_data,
adc_or, adc_or,
// channel interface // channel interface
adc_dfmt_data, adc_dfmt_data,
adc_enable, adc_enable,
up_adc_pn_err, up_adc_pn_err,
@ -58,6 +55,7 @@ module axi_ad9467_channel(
up_adc_or, up_adc_or,
// processor interface // processor interface
up_rstn, up_rstn,
up_clk, up_clk,
up_sel, up_sel,
@ -67,16 +65,19 @@ module axi_ad9467_channel(
up_rdata, up_rdata,
up_ack); up_ack);
// core parameter // parameters
parameter CHID = 0; parameter CHID = 0;
// adc interface // adc interface
input adc_clk; input adc_clk;
input adc_rst; input adc_rst;
input [15:0] adc_data; input [15:0] adc_data;
input adc_or; input adc_or;
// channel interface // channel interface
output [15:0] adc_dfmt_data; output [15:0] adc_dfmt_data;
output adc_enable; output adc_enable;
output up_adc_pn_err; output up_adc_pn_err;
@ -84,6 +85,7 @@ module axi_ad9467_channel(
output up_adc_or; output up_adc_or;
// processor interface // processor interface
input up_rstn; input up_rstn;
input up_clk; input up_clk;
input up_sel; input up_sel;
@ -93,20 +95,23 @@ module axi_ad9467_channel(
output [31:0] up_rdata; output [31:0] up_rdata;
output up_ack; output up_ack;
wire adc_pn_err_s; // internal signals
wire adc_pn_oos_s; wire adc_pn_oos_s;
wire adc_pn_type_s; wire adc_pn_err_s;
wire [ 3:0] adc_pnseq_sel_s;
wire adc_dfmt_enable_s; wire adc_dfmt_enable_s;
wire adc_dfmt_type_s; wire adc_dfmt_type_s;
wire adc_dfmt_se_s; wire adc_dfmt_se_s;
// PN sequence monitor // instantiations
axi_ad9467_pnmon i_axi_ad9467_pnmon ( axi_ad9467_pnmon i_axi_ad9467_pnmon (
.adc_clk (adc_clk), .adc_clk (adc_clk),
.adc_data (adc_data), .adc_data (adc_data),
.adc_pn_oos (adc_pn_oos_s), .adc_pn_oos (adc_pn_oos_s),
.adc_pn_err (adc_pn_err_s), .adc_pn_err (adc_pn_err_s),
.up_pn_type (adc_pn_type_s)); .adc_pnseq_sel (adc_pnseq_sel_s));
ad_datafmt #(.DATA_WIDTH(16)) i_datafmt ( ad_datafmt #(.DATA_WIDTH(16)) i_datafmt (
.clk(adc_clk), .clk(adc_clk),
@ -118,22 +123,21 @@ module axi_ad9467_channel(
.dfmt_type(adc_dfmt_type_s), .dfmt_type(adc_dfmt_type_s),
.dfmt_se(adc_dfmt_se_s)); .dfmt_se(adc_dfmt_se_s));
// adc channel control
up_adc_channel #(.PCORE_ADC_CHID(0)) i_up_adc_channel ( up_adc_channel #(.PCORE_ADC_CHID(0)) i_up_adc_channel (
.adc_clk (adc_clk), .adc_clk (adc_clk),
.adc_rst (adc_rst), .adc_rst (adc_rst),
.adc_enable (adc_enable), .adc_enable (adc_enable),
.adc_pn_sel (),
.adc_iqcor_enb (), .adc_iqcor_enb (),
.adc_dcfilt_enb (), .adc_dcfilt_enb (),
.adc_dfmt_se (adc_dfmt_se_s), .adc_dfmt_se (adc_dfmt_se_s),
.adc_dfmt_type (adc_dfmt_type_s), .adc_dfmt_type (adc_dfmt_type_s),
.adc_dfmt_enable (adc_dfmt_enable_s), .adc_dfmt_enable (adc_dfmt_enable_s),
.adc_pn_type (adc_pn_type_s),
.adc_dcfilt_offset (), .adc_dcfilt_offset (),
.adc_dcfilt_coeff (), .adc_dcfilt_coeff (),
.adc_iqcor_coeff_1 (), .adc_iqcor_coeff_1 (),
.adc_iqcor_coeff_2 (), .adc_iqcor_coeff_2 (),
.adc_pnseq_sel (adc_pnseq_sel_s),
.adc_data_sel (),
.adc_pn_err (adc_pn_err_s), .adc_pn_err (adc_pn_err_s),
.adc_pn_oos (adc_pn_oos_s), .adc_pn_oos (adc_pn_oos_s),
.adc_or (adc_or), .adc_or (adc_or),
@ -164,3 +168,6 @@ module axi_ad9467_channel(
.up_ack (up_ack)); .up_ack (up_ack));
endmodule endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -44,65 +44,74 @@
module axi_ad9467_if ( module axi_ad9467_if (
// adc interface (clk, data, over-range) // adc interface (clk, data, over-range)
adc_clk_in_p, adc_clk_in_p,
adc_clk_in_n, adc_clk_in_n,
adc_data_in_p, adc_data_in_p,
adc_data_in_n, adc_data_in_n,
adc_data_or_p, adc_or_in_p,
adc_data_or_n, adc_or_in_n,
// interface outputs // interface outputs
adc_clk, adc_clk,
adc_data, adc_data,
adc_or, adc_or,
// processor interface
adc_ddr_edgesel, adc_ddr_edgesel,
// delay control signals // delay control signals
delay_clk,
delay_rst,
delay_sel, delay_sel,
delay_rwn, delay_rwn,
delay_addr, delay_addr,
delay_wdata, delay_wdata,
delay_clk,
delay_ack,
delay_rst,
delay_rdata, delay_rdata,
delay_ack_t,
delay_locked); delay_locked);
// This parameter controls the buffer type based on the target device. // buffer type based on the target device.
parameter PCORE_BUFTYPE = 0; parameter PCORE_BUFTYPE = 0;
parameter C_DEVICE_7SERIES = 0;
parameter C_DEVICE_VIRTEX6 = 1;
parameter PCORE_IODELAY_GROUP = "dev_if_delay_group"; parameter PCORE_IODELAY_GROUP = "dev_if_delay_group";
// adc interface (clk, data, over-range) // adc interface (clk, data, over-range)
input adc_clk_in_p; input adc_clk_in_p;
input adc_clk_in_n; input adc_clk_in_n;
input [ 7:0] adc_data_in_p; input [ 7:0] adc_data_in_p;
input [ 7:0] adc_data_in_n; input [ 7:0] adc_data_in_n;
input adc_data_or_p; input adc_or_in_p;
input adc_data_or_n; input adc_or_in_n;
// interface outputs // interface outputs
output adc_clk; output adc_clk;
output [15:0] adc_data; output [15:0] adc_data;
output adc_or; output adc_or;
// processor interface
input adc_ddr_edgesel; input adc_ddr_edgesel;
// delay control signals // delay control signals
input delay_clk;
input delay_rst;
input delay_sel; input delay_sel;
input delay_rwn; input delay_rwn;
input [ 7:0] delay_addr; input [ 7:0] delay_addr;
input [ 4:0] delay_wdata; input [ 4:0] delay_wdata;
input delay_clk;
input delay_rst;
output delay_ack;
output [ 4:0] delay_rdata; output [ 4:0] delay_rdata;
output delay_ack_t;
output delay_locked; output delay_locked;
// internal registers
reg [ 7:0] adc_data_p = 'd0; reg [ 7:0] adc_data_p = 'd0;
reg [ 7:0] adc_data_n = 'd0; reg [ 7:0] adc_data_n = 'd0;
reg [ 7:0] adc_data_n_d = 'd0; reg [ 7:0] adc_data_n_d = 'd0;
@ -113,25 +122,20 @@ module axi_ad9467_if (
reg adc_or_n = 'd0; reg adc_or_n = 'd0;
reg adc_or = 'd0; reg adc_or = 'd0;
reg [ 8:0] delay_ld = 'd0; reg [ 8:0] delay_ld = 'd0;
reg delay_ack = 'd0; reg delay_ack_t = 'd0;
reg [ 4:0] delay_rdata = 'd0; reg [ 4:0] delay_rdata = 'd0;
// internal signals
wire [ 4:0] delay_rdata_s[8:0]; wire [ 4:0] delay_rdata_s[8:0];
wire [ 7:0] adc_data_ibuf_s;
wire [ 7:0] adc_data_idelay_s;
wire [ 7:0] adc_data_p_s; wire [ 7:0] adc_data_p_s;
wire [ 7:0] adc_data_n_s; wire [ 7:0] adc_data_n_s;
wire adc_or_ibuf_s;
wire adc_or_idelay_s;
wire adc_or_p_s; wire adc_or_p_s;
wire adc_or_n_s; wire adc_or_n_s;
wire adc_clk_ibuf_s;
genvar l_inst; genvar l_inst;
// The adc data is 8bits ddr, and here it is demuxed to 16bits. // sample select (p/n) swap
// The samples may be selected to be either positive first,
// or negative first.
always @(posedge adc_clk) begin always @(posedge adc_clk) begin
adc_data_p <= adc_data_p_s; adc_data_p <= adc_data_p_s;
@ -164,8 +168,8 @@ module axi_ad9467_if (
end end
end end
// The delay write interface, each delay element can be individually // delay write interface, each delay element can be individually
// addressed, and a delay value can be directly loaded (no INC/DEC stuff) // addressed, and a delay value can be directly loaded (no inc/dec stuff)
always @(posedge delay_clk) begin always @(posedge delay_clk) begin
if ((delay_sel == 1'b1) && (delay_rwn == 1'b0)) begin if ((delay_sel == 1'b1) && (delay_rwn == 1'b0)) begin
@ -204,198 +208,60 @@ module axi_ad9467_if (
default: delay_rdata <= 5'd0; default: delay_rdata <= 5'd0;
endcase endcase
if (delay_sel == 1'b1) begin if (delay_sel == 1'b1) begin
delay_ack <= ~delay_ack; delay_ack_t <= ~delay_ack_t;
end end
end end
// The data interface, data signals goes through a LVDS input buffer, then // data interface
// a delay element (1/32th of a 200MHz clock) and finally an input DDR demux.
generate generate
for (l_inst = 0; l_inst <= 7; l_inst = l_inst + 1) begin : g_adc_if for (l_inst = 0; l_inst <= 7; l_inst = l_inst + 1) begin : g_adc_if
ad_lvds_in #(
IBUFDS i_data_ibuf ( .BUFTYPE (PCORE_BUFTYPE),
.I (adc_data_in_p[l_inst]), .IODELAY_CTRL (0),
.IB (adc_data_in_n[l_inst]), .IODELAY_GROUP (PCORE_IODELAY_GROUP))
.O (adc_data_ibuf_s[l_inst])); i_adc_data (
.rx_clk (adc_clk),
if (PCORE_BUFTYPE == C_DEVICE_VIRTEX6) begin .rx_data_in_p (adc_data_in_p[l_inst]),
(* IODELAY_GROUP = PCORE_IODELAY_GROUP *) .rx_data_in_n (adc_data_in_n[l_inst]),
IODELAYE1 #( .rx_data_p (adc_data_p_s[l_inst]),
.CINVCTRL_SEL ("FALSE"), .rx_data_n (adc_data_n_s[l_inst]),
.DELAY_SRC ("I"), .delay_clk (delay_clk),
.HIGH_PERFORMANCE_MODE ("TRUE"), .delay_rst (delay_rst),
.IDELAY_TYPE ("VAR_LOADABLE"), .delay_ld (delay_ld[l_inst]),
.IDELAY_VALUE (0), .delay_wdata (delay_wdata),
.ODELAY_TYPE ("FIXED"), .delay_rdata (delay_rdata_s[l_inst]),
.ODELAY_VALUE (0), .delay_locked ());
.REFCLK_FREQUENCY (200.0),
.SIGNAL_PATTERN ("DATA"))
i_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 (adc_data_ibuf_s[l_inst]),
.DATAOUT (adc_data_idelay_s[l_inst]),
.RST (delay_ld[l_inst]),
.CNTVALUEIN (delay_wdata),
.CNTVALUEOUT (delay_rdata_s[l_inst]));
end else begin
(* IODELAY_GROUP = PCORE_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_data_idelay (
.CE (1'b0),
.INC (1'b0),
.DATAIN (1'b0),
.LDPIPEEN (1'b0),
.CINVCTRL (1'b0),
.REGRST (1'b0),
.C (delay_clk),
.IDATAIN (adc_data_ibuf_s[l_inst]),
.DATAOUT (adc_data_idelay_s[l_inst]),
.LD (delay_ld[l_inst]),
.CNTVALUEIN (delay_wdata),
.CNTVALUEOUT (delay_rdata_s[l_inst]));
end
IDDR #(
.INIT_Q1 (1'b0),
.INIT_Q2 (1'b0),
.DDR_CLK_EDGE ("SAME_EDGE_PIPELINED"),
.SRTYPE ("ASYNC"))
i_data_ddr (
.CE (1'b1),
.R (1'b0),
.S (1'b0),
.C (adc_clk),
.D (adc_data_idelay_s[l_inst]),
.Q1 (adc_data_p_s[l_inst]),
.Q2 (adc_data_n_s[l_inst]));
end end
endgenerate endgenerate
// The over-range interface, it follows a similar path as the data signals. // over-range interface
IBUFDS i_or_ibuf ( ad_lvds_in #(
.I (adc_data_or_p), .BUFTYPE (PCORE_BUFTYPE),
.IB (adc_data_or_n), .IODELAY_CTRL (1),
.O (adc_or_ibuf_s)); .IODELAY_GROUP (PCORE_IODELAY_GROUP))
i_adc_or (
.rx_clk (adc_clk),
.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[8]),
.delay_wdata (delay_wdata),
.delay_rdata (delay_rdata_s[8]),
.delay_locked (delay_locked));
generate // clock
if (PCORE_BUFTYPE == C_DEVICE_VIRTEX6) begin
(* IODELAY_GROUP = PCORE_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_or_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 (adc_or_ibuf_s),
.DATAOUT (adc_or_idelay_s),
.RST (delay_ld[8]),
.CNTVALUEIN (delay_wdata),
.CNTVALUEOUT (delay_rdata_s[8]));
end else begin
(* IODELAY_GROUP = PCORE_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_or_idelay (
.CE (1'b0),
.INC (1'b0),
.DATAIN (1'b0),
.LDPIPEEN (1'b0),
.CINVCTRL (1'b0),
.REGRST (1'b0),
.C (delay_clk),
.IDATAIN (adc_or_ibuf_s),
.DATAOUT (adc_or_idelay_s),
.LD (delay_ld[8]),
.CNTVALUEIN (delay_wdata),
.CNTVALUEOUT (delay_rdata_s[8]));
end
endgenerate
IDDR #( ad_lvds_clk #(
.INIT_Q1 (1'b0), .BUFTYPE (PCORE_BUFTYPE))
.INIT_Q2 (1'b0), i_adc_clk (
.DDR_CLK_EDGE ("SAME_EDGE_PIPELINED"), .clk_in_p (adc_clk_in_p),
.SRTYPE ("ASYNC")) .clk_in_n (adc_clk_in_n),
i_or_ddr ( .clk (adc_clk));
.CE (1'b1),
.R (1'b0),
.S (1'b0),
.C (adc_clk),
.D (adc_or_idelay_s),
.Q1 (adc_or_p_s),
.Q2 (adc_or_n_s));
// The clock path is a simple clock buffer after a LVDS input buffer.
// It is possible for this logic to be replaced with a OSERDES based data capture.
// The reason for such a simple interface here is because this reference design
// is used for various boards (native fmc and/or evaluation boards). The pinouts
// of the FPGA - ADC interface is probably do not allow a OSERDES placement.
IBUFGDS i_clk_ibuf (
.I (adc_clk_in_p),
.IB (adc_clk_in_n),
.O (adc_clk_ibuf_s));
generate
if (PCORE_BUFTYPE == C_DEVICE_VIRTEX6) begin
BUFR #(.BUFR_DIVIDE ("BYPASS")) i_clk_gbuf (
.CLR (1'b0),
.CE (1'b1),
.I (adc_clk_ibuf_s),
.O (adc_clk));
end else begin
BUFG i_clk_gbuf (
.I (adc_clk_ibuf_s),
.O (adc_clk));
end
endgenerate
// The delay controller. Refer to Xilinx doc. for details.
// The GROUP directive controls which delay elements this is associated with.
(* IODELAY_GROUP = PCORE_IODELAY_GROUP *)
IDELAYCTRL i_delay_ctrl (
.RST (delay_rst),
.REFCLK (delay_clk),
.RDY (delay_locked));
endmodule endmodule

View File

@ -6,7 +6,10 @@ source $ad_hdl_dir/library/scripts/adi_ip.tcl
adi_ip_create axi_ad9467 adi_ip_create axi_ad9467
adi_ip_files axi_ad9467 [list \ adi_ip_files axi_ad9467 [list \
"$ad_hdl_dir/library/common/ad_rst.v" \ "$ad_hdl_dir/library/common/ad_rst.v" \
"$ad_hdl_dir/library/common/ad_lvds_clk.v" \
"$ad_hdl_dir/library/common/ad_lvds_in.v" \
"$ad_hdl_dir/library/common/ad_datafmt.v" \ "$ad_hdl_dir/library/common/ad_datafmt.v" \
"$ad_hdl_dir/library/common/ad_pnmon.v" \
"$ad_hdl_dir/library/common/up_xfer_status.v" \ "$ad_hdl_dir/library/common/up_xfer_status.v" \
"$ad_hdl_dir/library/common/up_xfer_cntrl.v" \ "$ad_hdl_dir/library/common/up_xfer_cntrl.v" \
"$ad_hdl_dir/library/common/up_clock_mon.v" \ "$ad_hdl_dir/library/common/up_clock_mon.v" \

View File

@ -43,47 +43,36 @@
module axi_ad9467_pnmon ( module axi_ad9467_pnmon (
// adc interface // adc interface
adc_clk, adc_clk,
adc_data, adc_data,
// pn out of sync and error // pn out of sync and error
adc_pn_oos, adc_pn_oos,
adc_pn_err, adc_pn_err,
adc_pnseq_sel);
// processor interface PN9 (0x0), PN23 (0x1)
up_pn_type);
// adc interface // adc interface
input adc_clk; input adc_clk;
input [15:0] adc_data; input [15:0] adc_data;
// pn out of sync and error // pn out of sync and error
output adc_pn_oos; output adc_pn_oos;
output adc_pn_err; output adc_pn_err;
input [ 3:0] adc_pnseq_sel;
// processor interface PN9 (0x0), PN23 (0x1) // internal registers
input up_pn_type;
reg adc_pn_type_m1 = 'd0; reg adc_valid_in = 'd0;
reg adc_pn_type_m2 = 'd0; reg [31:0] adc_pn_data_in = 'd0;
reg adc_pn_type = 'd0; reg [31:0] adc_pn_data_pn = 'd0;
reg adc_pn_en = 'd0;
reg [15:0] adc_data_d = 'd0; // internal signals
reg [31:0] adc_pn_data = 'd0;
reg adc_pn_en_d = 'd0;
reg adc_pn_match = 'd0;
reg [ 6:0] adc_pn_oos_count = 'd0;
reg adc_pn_oos = 'd0;
reg [ 4:0] adc_pn_err_count = 'd0;
reg adc_pn_err = 'd0;
wire [31:0] adc_pn_data_in_s; wire [31:0] adc_pn_data_in_s;
wire adc_pn_match0_s;
wire adc_pn_match1_s;
wire adc_pn_match2_s;
wire adc_pn_match_s;
wire [31:0] adc_pn_data_s;
wire adc_pn_err_s;
// PN23 function // PN23 function
@ -169,93 +158,29 @@ module axi_ad9467_pnmon (
end end
endfunction endfunction
// This PN sequence checking algorithm is commonly used is most applications. // pn sequence select
// It is a simple function generated based on the OOS status.
// If OOS is asserted (PN is OUT of sync):
// The next sequence is generated from the incoming data.
// If 16 sequences match CONSECUTIVELY, OOS is cleared (de-asserted).
// If OOS is de-asserted (PN is IN sync)
// The next sequence is generated from the current sequence.
// If 64 sequences mismatch CONSECUTIVELY, OOS is set (asserted).
// If OOS is de-asserted, any spurious mismatches sets the ERROR register.
// Ideally, processor should make sure both OOS == 0x0 AND ERR == 0x0.
assign adc_pn_data_in_s[31:16] = {~adc_data_d[15], adc_data_d[14:0]}; assign adc_pn_data_pn_s = (adc_pn_oos == 1'b1) ? adc_pn_data_in : adc_pn_data_pn;
assign adc_pn_data_in_s[15:0] = {~adc_data[15], adc_data[14:0]};
assign adc_pn_match0_s = (adc_pn_data_in_s[31:16] == adc_pn_data[31:16]) ? 1'b1 : 1'b0;
assign adc_pn_match1_s = (adc_pn_data_in_s[15:0] == adc_pn_data[15:0]) ? 1'b1 : 1'b0;
assign adc_pn_match2_s = ((adc_data == 16'd0) && (adc_data_d == 16'd0)) ? 1'b0 : 1'b1;
assign adc_pn_match_s = adc_pn_match0_s & adc_pn_match1_s & adc_pn_match2_s;
assign adc_pn_data_s = (adc_pn_oos == 1'b1) ? adc_pn_data_in_s : adc_pn_data;
assign adc_pn_err_s = ~(adc_pn_oos | adc_pn_match);
// PN running sequence
always @(posedge adc_clk) begin always @(posedge adc_clk) begin
adc_pn_type_m1 <= up_pn_type; adc_valid_in <= ~adc_valid_in;
adc_pn_type_m2 <= adc_pn_type_m1; adc_pn_data_in <= {adc_pn_data_in[15:0], ~adc_data[15], adc_data[14:0]};
adc_pn_type <= adc_pn_type_m2; if (adc_pnseq_sel == 4'd0) begin
adc_pn_en <= ~adc_pn_en; adc_pn_data_pn <= pn9(adc_pn_data_pn_s);
adc_data_d <= adc_data;
if (adc_pn_en == 1'b1) begin
if (adc_pn_type == 1'b0) begin
adc_pn_data <= pn9(adc_pn_data_s);
end else begin end else begin
adc_pn_data <= pn23(adc_pn_data_s); adc_pn_data_pn <= pn23(adc_pn_data_pn_s);
end
end end
end end
// PN OOS and counters (16 to clear, 64 to set). These numbers are actually determined // pn oos & pn err
// based on BER parameters set by the system (usually in network applications).
always @(posedge adc_clk) begin ad_pnmon #(.DATA_WIDTH(32)) i_pnmon (
adc_pn_en_d <= adc_pn_en; .adc_clk (adc_clk),
adc_pn_match <= adc_pn_match_s; .adc_valid_in (adc_valid_in),
if (adc_pn_en_d == 1'b1) begin .adc_data_in (adc_pn_data_in),
if (adc_pn_oos == 1'b1) begin .adc_data_pn (adc_pn_data_pn),
if (adc_pn_match == 1'b1) begin .adc_pn_oos (adc_pn_oos),
if (adc_pn_oos_count >= 16) begin .adc_pn_err (adc_pn_err));
adc_pn_oos_count <= 'd0;
adc_pn_oos <= 'd0;
end else begin
adc_pn_oos_count <= adc_pn_oos_count + 1'b1;
adc_pn_oos <= 'd1;
end
end else begin
adc_pn_oos_count <= 'd0;
adc_pn_oos <= 'd1;
end
end else begin
if (adc_pn_match == 1'b0) begin
if (adc_pn_oos_count >= 64) begin
adc_pn_oos_count <= 'd0;
adc_pn_oos <= 'd1;
end else begin
adc_pn_oos_count <= adc_pn_oos_count + 1'b1;
adc_pn_oos <= 'd0;
end
end else begin
adc_pn_oos_count <= 'd0;
adc_pn_oos <= 'd0;
end
end
end
end
// The error state is streched to multiple adc clocks such that processor
// has enough time to sample the error condition.
always @(posedge adc_clk) begin
if (adc_pn_en_d == 1'b1) begin
if (adc_pn_err_s == 1'b1) begin
adc_pn_err_count <= 5'h10;
end else if (adc_pn_err_count[4] == 1'b1) begin
adc_pn_err_count <= adc_pn_err_count + 1'b1;
end
end
adc_pn_err <= adc_pn_err_count[4];
end
endmodule endmodule