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,276 +37,286 @@
// *************************************************************************** // ***************************************************************************
// *************************************************************************** // ***************************************************************************
`timescale 1ns/1ns `timescale 1ns/100ps
module axi_ad9467( module axi_ad9467(
// physical interface // physical interface
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,
// delay_clock // delay_clock
delay_clk, delay_clk,
// 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
s_axi_aclk, s_axi_aclk,
s_axi_aresetn, s_axi_aresetn,
s_axi_awvalid, s_axi_awvalid,
s_axi_awaddr, s_axi_awaddr,
s_axi_awready, s_axi_awready,
s_axi_wvalid, s_axi_wvalid,
s_axi_wdata, s_axi_wdata,
s_axi_wstrb, s_axi_wstrb,
s_axi_wready, s_axi_wready,
s_axi_bvalid, s_axi_bvalid,
s_axi_bresp, s_axi_bresp,
s_axi_bready, s_axi_bready,
s_axi_arvalid, s_axi_arvalid,
s_axi_araddr, s_axi_araddr,
s_axi_arready, s_axi_arready,
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
parameter PCORE_ID = 0; parameter PCORE_ID = 0;
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
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;
// delay clk // delay clk
input delay_clk; input delay_clk;
// 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
input s_axi_aclk; input s_axi_aclk;
input s_axi_aresetn; input s_axi_aresetn;
input s_axi_awvalid; input s_axi_awvalid;
input [31:0] s_axi_awaddr; input [31:0] s_axi_awaddr;
output s_axi_awready; output s_axi_awready;
input s_axi_wvalid; input s_axi_wvalid;
input [31:0] s_axi_wdata; input [31:0] s_axi_wdata;
input [ 3:0] s_axi_wstrb; input [ 3:0] s_axi_wstrb;
output s_axi_wready; output s_axi_wready;
output s_axi_bvalid; output s_axi_bvalid;
output [ 1:0] s_axi_bresp; output [ 1:0] s_axi_bresp;
input s_axi_bready; input s_axi_bready;
input s_axi_arvalid; input s_axi_arvalid;
input [31:0] s_axi_araddr; input [31:0] s_axi_araddr;
output s_axi_arready; output s_axi_arready;
output s_axi_rvalid; output s_axi_rvalid;
output [ 1:0] s_axi_rresp; output [ 1:0] s_axi_rresp;
output [31:0] s_axi_rdata; output [31:0] s_axi_rdata;
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;
wire up_clk; reg up_ack = 'd0;
wire up_rstn;
wire adc_rst;
wire adc_clk;
// internal signals // internal clocks & resets
wire up_sel_s;
wire up_wr_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 up_adc_or_s;
wire adc_ddr_edgesel_s;
wire delay_sel_s;
wire delay_rwn_s;
wire [ 7:0] delay_addr_s;
wire [ 4:0] delay_wdata_s;
wire delay_rst;
wire delay_ack_s;
wire [ 4:0] delay_rdata_s;
wire delay_locked_s;
wire adc_pn_oos_s;
wire adc_pn_err_s;
wire [31:0] up_rdata_common;
wire [31:0] up_rdata_channel;
wire up_ack_common;
wire up_ack_channel;
wire adc_pn_type_s;
wire [15:0] adc_channel_data_s;
wire adc_enable_s;
assign up_clk = s_axi_aclk; wire adc_rst;
assign up_rstn = s_axi_aresetn; wire up_clk;
assign adc_dwr = 1'b1; wire up_rstn;
assign adc_ddata = adc_data_if_s;
// processor read interface // internal signals
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin wire [15:0] adc_data_s;
up_rdata <= 32'd0; wire adc_or_s;
up_ack <= 1'd0; wire adc_ddr_edgesel_s;
end else begin wire delay_rst_s;
up_rdata <= up_rdata_channel | up_rdata_common; wire delay_sel_s;
up_ack <= up_ack_channel | up_ack_common; wire delay_rwn_s;
end wire [ 7:0] delay_addr_s;
wire [ 4:0] delay_wdata_s;
wire [ 4:0] delay_rdata_s;
wire delay_ack_t_s;
wire delay_locked_s;
wire up_status_pn_err_s;
wire up_status_pn_oos_s;
wire up_status_or_s;
wire [31:0] up_rdata_s[0:1];
wire up_ack_s[0:1];
wire up_sel_s;
wire up_wr_s;
wire [13:0] up_addr_s;
wire [31:0] up_wdata_s;
//defaults
assign up_clk = s_axi_aclk;
assign up_rstn = s_axi_aresetn;
assign adc_valid = 1'b1;
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_rdata <= 32'd0;
up_ack <= 1'd0;
end else begin
up_rdata <= up_rdata_s[0] | up_rdata_s[1];
up_ack <= up_ack_s[0] | up_ack_s[1];
end end
end
// ADC data interface // main (device interface)
axi_ad9467_if #(
.PCORE_BUFTYPE (PCORE_BUFTYPE),
.PCORE_IODELAY_GROUP (PCORE_IODELAY_GROUP))
i_if (
.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_data_or_p),
.adc_data_or_n (adc_data_or_n),
.adc_clk (adc_clk),
.adc_data (adc_data_if_s),
.adc_or (adc_or_s),
.adc_ddr_edgesel (adc_ddr_edgesel_s),
.delay_sel (delay_sel_s),
.delay_rwn (delay_rwn_s),
.delay_addr (delay_addr_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_locked (delay_locked_s));
// channel axi_ad9467_if #(
axi_ad9467_channel #(.CHID(0)) i_channel ( .PCORE_BUFTYPE (PCORE_BUFTYPE),
.adc_clk(adc_clk), .PCORE_IODELAY_GROUP (PCORE_IODELAY_GROUP))
.adc_rst(adc_rst), i_if (
.adc_data(adc_data_if_s), .adc_clk_in_p (adc_clk_in_p),
.adc_or(adc_or_s), .adc_clk_in_n (adc_clk_in_n),
.adc_dfmt_data(adc_channel_data_s), .adc_data_in_p (adc_data_in_p),
.adc_enable(adc_enable_s), .adc_data_in_n (adc_data_in_n),
.up_adc_pn_err(adc_pn_err_s), .adc_or_in_p (adc_or_in_p),
.up_adc_pn_oos(adc_pn_oos_s), .adc_or_in_n (adc_or_in_n),
.up_adc_or(up_adc_or_s), .adc_clk (adc_clk),
.up_rstn(up_rstn), .adc_data (adc_data_s),
.up_clk(up_clk), .adc_or (adc_or_s),
.up_sel(up_sel_s), .adc_ddr_edgesel (adc_ddr_edgesel_s),
.up_wr(up_wr_s), .delay_clk (delay_clk),
.up_addr(up_addr_s), .delay_rst (delay_rst_s),
.up_wdata(up_wdata_s), .delay_sel (delay_sel_s),
.up_rdata(up_rdata_channel), .delay_rwn (delay_rwn_s),
.up_ack(up_ack_channel)); .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));
// common processor control // channel
up_adc_common #(.PCORE_ID(PCORE_ID))
i_up_adc_common(
.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_rst(adc_rst),
.adc_r1_mode(),
.adc_ddr_edgesel(adc_ddr_edgesel_s),
.adc_pin_mode(),
.adc_status(1'b1),
.adc_status_pn_err(adc_pn_err_s),
.adc_status_pn_oos(adc_pn_oos_s),
.adc_status_or(up_adc_or_s),
.adc_clk_ratio(32'b1),
.adc_status_ovf(adc_doverflow),
.adc_status_unf(1'b0),
.drp_clk(1'b0),
.drp_rdata(16'b0),
.drp_rst(),
.drp_sel(),
.drp_wr(),
.drp_addr(),
.drp_wdata(),
.drp_ready(1'b0),
.drp_locked(1'b1),
.up_rstn(up_rstn),
.up_clk(up_clk),
.up_sel(up_sel_s),
.up_wr(up_wr_s),
.up_addr(up_addr_s),
.up_wdata(up_wdata_s),
.up_rdata(up_rdata_common),
.up_ack(up_ack_common),
.up_usr_chanmax(),
.adc_usr_chanmax(8'b0));
// axi interface axi_ad9467_channel #(.CHID(0)) i_channel (
up_axi #( .adc_clk (adc_clk),
.PCORE_BASEADDR (C_BASEADDR), .adc_rst (adc_rst),
.PCORE_HIGHADDR (C_HIGHADDR)) .adc_data (adc_data_s),
i_up_axi ( .adc_or (adc_or_s),
.up_rstn (up_rstn), .adc_dfmt_data (adc_data),
.up_clk (up_clk), .adc_enable (adc_enable),
.up_axi_awvalid (s_axi_awvalid), .up_adc_pn_err (up_status_pn_err_s),
.up_axi_awaddr (s_axi_awaddr), .up_adc_pn_oos (up_status_pn_oos_s),
.up_axi_awready (s_axi_awready), .up_adc_or (up_status_or_s),
.up_axi_wvalid (s_axi_wvalid), .up_rstn (up_rstn),
.up_axi_wdata (s_axi_wdata), .up_clk (up_clk),
.up_axi_wstrb (s_axi_wstrb), .up_sel (up_sel_s),
.up_axi_wready (s_axi_wready), .up_wr (up_wr_s),
.up_axi_bvalid (s_axi_bvalid), .up_addr (up_addr_s),
.up_axi_bresp (s_axi_bresp), .up_wdata (up_wdata_s),
.up_axi_bready (s_axi_bready), .up_rdata (up_rdata_s[0]),
.up_axi_arvalid (s_axi_arvalid), .up_ack (up_ack_s[0]));
.up_axi_araddr (s_axi_araddr),
.up_axi_arready (s_axi_arready), // common processor control
.up_axi_rvalid (s_axi_rvalid),
.up_axi_rresp (s_axi_rresp), up_adc_common #(.PCORE_ID(PCORE_ID)) i_up_adc_common (
.up_axi_rdata (s_axi_rdata), .mmcm_rst (),
.up_axi_rready (s_axi_rready), .adc_clk (adc_clk),
.up_sel (up_sel_s), .adc_rst (adc_rst),
.up_wr (up_wr_s), .adc_r1_mode (),
.up_addr (up_addr_s), .adc_ddr_edgesel (adc_ddr_edgesel_s),
.up_wdata (up_wdata_s), .adc_pin_mode (),
.up_rdata (up_rdata), .adc_status (1'b1),
.up_ack (up_ack)); .adc_status_ovf (adc_dovf),
.adc_status_unf (adc_dunf),
.adc_clk_ratio (32'b1),
.up_status_pn_err (up_status_pn_err_s),
.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_rst (),
.drp_sel (),
.drp_wr (),
.drp_addr (),
.drp_wdata (),
.drp_rdata (16'b0),
.drp_ready (1'b0),
.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_clk (up_clk),
.up_sel (up_sel_s),
.up_wr (up_wr_s),
.up_addr (up_addr_s),
.up_wdata (up_wdata_s),
.up_rdata (up_rdata_s[1]),
.up_ack (up_ack_s[1]));
// up bus interface
up_axi #(
.PCORE_BASEADDR (C_BASEADDR),
.PCORE_HIGHADDR (C_HIGHADDR))
i_up_axi (
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_axi_awvalid (s_axi_awvalid),
.up_axi_awaddr (s_axi_awaddr),
.up_axi_awready (s_axi_awready),
.up_axi_wvalid (s_axi_wvalid),
.up_axi_wdata (s_axi_wdata),
.up_axi_wstrb (s_axi_wstrb),
.up_axi_wready (s_axi_wready),
.up_axi_bvalid (s_axi_bvalid),
.up_axi_bresp (s_axi_bresp),
.up_axi_bready (s_axi_bready),
.up_axi_arvalid (s_axi_arvalid),
.up_axi_araddr (s_axi_araddr),
.up_axi_arready (s_axi_arready),
.up_axi_rvalid (s_axi_rvalid),
.up_axi_rresp (s_axi_rresp),
.up_axi_rdata (s_axi_rdata),
.up_axi_rready (s_axi_rready),
.up_sel (up_sel_s),
.up_wr (up_wr_s),
.up_addr (up_addr_s),
.up_wdata (up_wdata_s),
.up_rdata (up_rdata),
.up_ack (up_ack));
endmodule endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -34,133 +34,140 @@
// 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_rst,
adc_data,
adc_or,
// channel interface adc_clk,
adc_dfmt_data, adc_rst,
adc_enable, adc_data,
up_adc_pn_err, adc_or,
up_adc_pn_oos,
up_adc_or,
// processor interface // channel interface
up_rstn,
up_clk,
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack);
// core parameter adc_dfmt_data,
parameter CHID = 0; adc_enable,
up_adc_pn_err,
up_adc_pn_oos,
up_adc_or,
// adc interface // processor interface
input adc_clk;
input adc_rst;
input [15:0] adc_data;
input adc_or;
// channel interface up_rstn,
output [15:0] adc_dfmt_data; up_clk,
output adc_enable; up_sel,
output up_adc_pn_err; up_wr,
output up_adc_pn_oos; up_addr,
output up_adc_or; up_wdata,
up_rdata,
up_ack);
// processor interface // parameters
input up_rstn;
input up_clk;
input up_sel;
input up_wr;
input [13:0] up_addr;
input [31:0] up_wdata;
output [31:0] up_rdata;
output up_ack;
wire adc_pn_err_s; parameter CHID = 0;
wire adc_pn_oos_s;
wire adc_pn_type_s;
wire adc_dfmt_enable_s;
wire adc_dfmt_type_s;
wire adc_dfmt_se_s;
// PN sequence monitor // adc interface
axi_ad9467_pnmon i_axi_ad9467_pnmon (
.adc_clk (adc_clk),
.adc_data (adc_data),
.adc_pn_oos (adc_pn_oos_s),
.adc_pn_err (adc_pn_err_s),
.up_pn_type (adc_pn_type_s));
ad_datafmt #(.DATA_WIDTH(16)) i_datafmt ( input adc_clk;
.clk(adc_clk), input adc_rst;
.valid(1'b1), input [15:0] adc_data;
.data(adc_data), input adc_or;
.valid_out(),
.data_out(adc_dfmt_data),
.dfmt_enable(adc_dfmt_enable_s),
.dfmt_type(adc_dfmt_type_s),
.dfmt_se(adc_dfmt_se_s));
// adc channel control // channel interface
up_adc_channel #(.PCORE_ADC_CHID(0)) i_up_adc_channel (
.adc_clk (adc_clk), output [15:0] adc_dfmt_data;
.adc_rst (adc_rst), output adc_enable;
.adc_enable (adc_enable), output up_adc_pn_err;
.adc_pn_sel (), output up_adc_pn_oos;
.adc_iqcor_enb (), output up_adc_or;
.adc_dcfilt_enb (),
.adc_dfmt_se (adc_dfmt_se_s), // processor interface
.adc_dfmt_type (adc_dfmt_type_s),
.adc_dfmt_enable (adc_dfmt_enable_s), input up_rstn;
.adc_pn_type (adc_pn_type_s), input up_clk;
.adc_dcfilt_offset (), input up_sel;
.adc_dcfilt_coeff (), input up_wr;
.adc_iqcor_coeff_1 (), input [13:0] up_addr;
.adc_iqcor_coeff_2 (), input [31:0] up_wdata;
.adc_pn_err (adc_pn_err_s), output [31:0] up_rdata;
.adc_pn_oos (adc_pn_oos_s), output up_ack;
.adc_or (adc_or),
.up_adc_pn_err (up_adc_pn_err), // internal signals
.up_adc_pn_oos (up_adc_pn_oos),
.up_adc_or (up_adc_or), wire adc_pn_oos_s;
.up_usr_datatype_be (), wire adc_pn_err_s;
.up_usr_datatype_signed (), wire [ 3:0] adc_pnseq_sel_s;
.up_usr_datatype_shift (), wire adc_dfmt_enable_s;
.up_usr_datatype_total_bits (), wire adc_dfmt_type_s;
.up_usr_datatype_bits (), wire adc_dfmt_se_s;
.up_usr_decimation_m (),
.up_usr_decimation_n (), // instantiations
.adc_usr_datatype_be (1'b0),
.adc_usr_datatype_signed (1'b1), axi_ad9467_pnmon i_axi_ad9467_pnmon (
.adc_usr_datatype_shift (8'd0), .adc_clk (adc_clk),
.adc_usr_datatype_total_bits (8'd16), .adc_data (adc_data),
.adc_usr_datatype_bits (8'd16), .adc_pn_oos (adc_pn_oos_s),
.adc_usr_decimation_m (16'd1), .adc_pn_err (adc_pn_err_s),
.adc_usr_decimation_n (16'd1), .adc_pnseq_sel (adc_pnseq_sel_s));
.up_rstn (up_rstn),
.up_clk (up_clk), ad_datafmt #(.DATA_WIDTH(16)) i_datafmt (
.up_sel (up_sel), .clk(adc_clk),
.up_wr (up_wr), .valid(1'b1),
.up_addr (up_addr), .data(adc_data),
.up_wdata (up_wdata), .valid_out(),
.up_rdata (up_rdata), .data_out(adc_dfmt_data),
.up_ack (up_ack)); .dfmt_enable(adc_dfmt_enable_s),
.dfmt_type(adc_dfmt_type_s),
.dfmt_se(adc_dfmt_se_s));
up_adc_channel #(.PCORE_ADC_CHID(0)) i_up_adc_channel (
.adc_clk (adc_clk),
.adc_rst (adc_rst),
.adc_enable (adc_enable),
.adc_iqcor_enb (),
.adc_dcfilt_enb (),
.adc_dfmt_se (adc_dfmt_se_s),
.adc_dfmt_type (adc_dfmt_type_s),
.adc_dfmt_enable (adc_dfmt_enable_s),
.adc_dcfilt_offset (),
.adc_dcfilt_coeff (),
.adc_iqcor_coeff_1 (),
.adc_iqcor_coeff_2 (),
.adc_pnseq_sel (adc_pnseq_sel_s),
.adc_data_sel (),
.adc_pn_err (adc_pn_err_s),
.adc_pn_oos (adc_pn_oos_s),
.adc_or (adc_or),
.up_adc_pn_err (up_adc_pn_err),
.up_adc_pn_oos (up_adc_pn_oos),
.up_adc_or (up_adc_or),
.up_usr_datatype_be (),
.up_usr_datatype_signed (),
.up_usr_datatype_shift (),
.up_usr_datatype_total_bits (),
.up_usr_datatype_bits (),
.up_usr_decimation_m (),
.up_usr_decimation_n (),
.adc_usr_datatype_be (1'b0),
.adc_usr_datatype_signed (1'b1),
.adc_usr_datatype_shift (8'd0),
.adc_usr_datatype_total_bits (8'd16),
.adc_usr_datatype_bits (8'd16),
.adc_usr_decimation_m (16'd1),
.adc_usr_decimation_n (16'd1),
.up_rstn (up_rstn),
.up_clk (up_clk),
.up_sel (up_sel),
.up_wr (up_wr),
.up_addr (up_addr),
.up_wdata (up_wdata),
.up_rdata (up_rdata),
.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

@ -5,20 +5,23 @@ 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_datafmt.v" \ "$ad_hdl_dir/library/common/ad_lvds_clk.v" \
"$ad_hdl_dir/library/common/up_xfer_status.v" \ "$ad_hdl_dir/library/common/ad_lvds_in.v" \
"$ad_hdl_dir/library/common/up_xfer_cntrl.v" \ "$ad_hdl_dir/library/common/ad_datafmt.v" \
"$ad_hdl_dir/library/common/up_clock_mon.v" \ "$ad_hdl_dir/library/common/ad_pnmon.v" \
"$ad_hdl_dir/library/common/up_delay_cntrl.v" \ "$ad_hdl_dir/library/common/up_xfer_status.v" \
"$ad_hdl_dir/library/common/up_drp_cntrl.v" \ "$ad_hdl_dir/library/common/up_xfer_cntrl.v" \
"$ad_hdl_dir/library/common/up_adc_common.v" \ "$ad_hdl_dir/library/common/up_clock_mon.v" \
"$ad_hdl_dir/library/common/up_adc_channel.v" \ "$ad_hdl_dir/library/common/up_delay_cntrl.v" \
"$ad_hdl_dir/library/common/up_axi.v" \ "$ad_hdl_dir/library/common/up_drp_cntrl.v" \
"axi_ad9467_pnmon.v" \ "$ad_hdl_dir/library/common/up_adc_common.v" \
"axi_ad9467_if.v" \ "$ad_hdl_dir/library/common/up_adc_channel.v" \
"axi_ad9467_channel.v" \ "$ad_hdl_dir/library/common/up_axi.v" \
"axi_ad9467.v"] "axi_ad9467_pnmon.v" \
"axi_ad9467_if.v" \
"axi_ad9467_channel.v" \
"axi_ad9467.v"]
adi_ip_properties axi_ad9467 adi_ip_properties axi_ad9467

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_valid_in = 'd0;
reg [31:0] adc_pn_data_in = 'd0;
reg [31:0] adc_pn_data_pn = 'd0;
reg adc_pn_type_m1 = 'd0; // internal signals
reg adc_pn_type_m2 = 'd0;
reg adc_pn_type = 'd0;
reg adc_pn_en = 'd0;
reg [15:0] adc_data_d = 'd0;
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; end else begin
if (adc_pn_en == 1'b1) begin adc_pn_data_pn <= pn23(adc_pn_data_pn_s);
if (adc_pn_type == 1'b0) begin
adc_pn_data <= pn9(adc_pn_data_s);
end else begin
adc_pn_data <= pn23(adc_pn_data_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