axi_ad9361: added

main
Rejeesh Kutty 2014-03-11 20:01:55 -04:00
parent 380584c23b
commit 580808e146
11 changed files with 3663 additions and 0 deletions

463
library/axi_ad9361/axi_ad9361.v Executable file
View File

@ -0,0 +1,463 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module axi_ad9361 (
// physical interface (receive)
rx_clk_in_p,
rx_clk_in_n,
rx_frame_in_p,
rx_frame_in_n,
rx_data_in_p,
rx_data_in_n,
// physical interface (transmit)
tx_clk_out_p,
tx_clk_out_n,
tx_frame_out_p,
tx_frame_out_n,
tx_data_out_p,
tx_data_out_n,
// delay clock
delay_clk,
// dma interface
clk,
adc_dwr,
adc_ddata,
adc_dsync,
adc_dovf,
adc_dunf,
dac_drd,
dac_ddata,
dac_dovf,
dac_dunf,
// axi interface
s_axi_aclk,
s_axi_aresetn,
s_axi_awvalid,
s_axi_awaddr,
s_axi_awready,
s_axi_wvalid,
s_axi_wdata,
s_axi_wstrb,
s_axi_wready,
s_axi_bvalid,
s_axi_bresp,
s_axi_bready,
s_axi_arvalid,
s_axi_araddr,
s_axi_arready,
s_axi_rvalid,
s_axi_rdata,
s_axi_rresp,
s_axi_rready,
// monitor signals
adc_mon_valid,
adc_mon_data);
// parameters
parameter PCORE_ID = 0;
parameter PCORE_VERSION = 32'h00060061;
parameter PCORE_BUFTYPE = 0;
parameter PCORE_IODELAY_GROUP = "dev_if_delay_group";
parameter PCORE_DAC_DP_DISABLE = 0;
parameter PCORE_ADC_DP_DISABLE = 0;
parameter C_S_AXI_MIN_SIZE = 32'hffff;
parameter C_BASEADDR = 32'hffffffff;
parameter C_HIGHADDR = 32'h00000000;
// physical interface (receive)
input rx_clk_in_p;
input rx_clk_in_n;
input rx_frame_in_p;
input rx_frame_in_n;
input [ 5:0] rx_data_in_p;
input [ 5:0] rx_data_in_n;
// physical interface (transmit)
output tx_clk_out_p;
output tx_clk_out_n;
output tx_frame_out_p;
output tx_frame_out_n;
output [ 5:0] tx_data_out_p;
output [ 5:0] tx_data_out_n;
// delay clock
input delay_clk;
// dma interface
output clk;
output adc_dwr;
output [63:0] adc_ddata;
output adc_dsync;
input adc_dovf;
input adc_dunf;
output dac_drd;
input [63:0] dac_ddata;
input dac_dovf;
input dac_dunf;
// axi interface
input s_axi_aclk;
input s_axi_aresetn;
input s_axi_awvalid;
input [31:0] s_axi_awaddr;
output s_axi_awready;
input s_axi_wvalid;
input [31:0] s_axi_wdata;
input [ 3:0] s_axi_wstrb;
output s_axi_wready;
output s_axi_bvalid;
output [ 1:0] s_axi_bresp;
input s_axi_bready;
input s_axi_arvalid;
input [31:0] s_axi_araddr;
output s_axi_arready;
output s_axi_rvalid;
output [31:0] s_axi_rdata;
output [ 1:0] s_axi_rresp;
input s_axi_rready;
// monitor interface
output adc_mon_valid;
output [47:0] adc_mon_data;
// internal registers
reg [31:0] up_rdata = 'd0;
reg up_ack = 'd0;
// internal clocks and resets
wire up_clk;
wire up_rstn;
wire delay_rst;
// internal signals
wire adc_valid_s;
wire [11:0] adc_data_i1_s;
wire [11:0] adc_data_q1_s;
wire [11:0] adc_data_i2_s;
wire [11:0] adc_data_q2_s;
wire adc_status_s;
wire adc_r1_mode_s;
wire dac_valid_s;
wire [11:0] dac_data_i1_s;
wire [11:0] dac_data_q1_s;
wire [11:0] dac_data_i2_s;
wire [11:0] dac_data_q2_s;
wire dac_r1_mode_s;
wire delay_sel_s;
wire delay_rwn_s;
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 dac_valid_pl_s;
wire [11:0] dac_data_pl_i1_s;
wire [11:0] dac_data_pl_q1_s;
wire [11:0] dac_data_pl_i2_s;
wire [11:0] dac_data_pl_q2_s;
wire dac_lb_enb_i1_s;
wire dac_pn_enb_i1_s;
wire dac_lb_enb_q1_s;
wire dac_pn_enb_q1_s;
wire dac_lb_enb_i2_s;
wire dac_pn_enb_i2_s;
wire dac_lb_enb_q2_s;
wire dac_pn_enb_q2_s;
wire adc_pn_oos_i1_s;
wire adc_pn_err_i1_s;
wire adc_pn_oos_q1_s;
wire adc_pn_err_q1_s;
wire adc_pn_oos_i2_s;
wire adc_pn_err_i2_s;
wire adc_pn_oos_q2_s;
wire adc_pn_err_q2_s;
wire up_sel_s;
wire up_wr_s;
wire [13:0] up_addr_s;
wire [31:0] up_wdata_s;
wire [31:0] up_rdata_rx_s;
wire up_ack_rx_s;
wire [31:0] up_rdata_tx_s;
wire up_ack_tx_s;
// signal name changes
assign up_clk = s_axi_aclk;
assign up_rstn = s_axi_aresetn;
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_rdata <= 'd0;
up_ack <= 'd0;
end else begin
up_rdata <= up_rdata_rx_s | up_rdata_tx_s;
up_ack <= up_ack_rx_s | up_ack_tx_s;
end
end
// device interface
axi_ad9361_dev_if #(
.PCORE_BUFTYPE (PCORE_BUFTYPE),
.PCORE_IODELAY_GROUP (PCORE_IODELAY_GROUP))
i_dev_if (
.rx_clk_in_p (rx_clk_in_p),
.rx_clk_in_n (rx_clk_in_n),
.rx_frame_in_p (rx_frame_in_p),
.rx_frame_in_n (rx_frame_in_n),
.rx_data_in_p (rx_data_in_p),
.rx_data_in_n (rx_data_in_n),
.tx_clk_out_p (tx_clk_out_p),
.tx_clk_out_n (tx_clk_out_n),
.tx_frame_out_p (tx_frame_out_p),
.tx_frame_out_n (tx_frame_out_n),
.tx_data_out_p (tx_data_out_p),
.tx_data_out_n (tx_data_out_n),
.clk (clk),
.adc_valid (adc_valid_s),
.adc_data_i1 (adc_data_i1_s),
.adc_data_q1 (adc_data_q1_s),
.adc_data_i2 (adc_data_i2_s),
.adc_data_q2 (adc_data_q2_s),
.adc_status (adc_status_s),
.adc_r1_mode (adc_r1_mode_s),
.dac_valid (dac_valid_s),
.dac_data_i1 (dac_data_i1_s),
.dac_data_q1 (dac_data_q1_s),
.dac_data_i2 (dac_data_i2_s),
.dac_data_q2 (dac_data_q2_s),
.dac_r1_mode (dac_r1_mode_s),
.delay_clk (delay_clk),
.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),
.delay_ack_t (delay_ack_t_s),
.delay_locked (delay_locked_s),
.dev_dbg_trigger (),
.dev_dbg_data ());
// prbs/loopback interface
axi_ad9361_pnlb i_pnlb (
.clk (clk),
.adc_valid_in (adc_valid_s),
.adc_data_in_i1 (adc_data_i1_s),
.adc_data_in_q1 (adc_data_q1_s),
.adc_data_in_i2 (adc_data_i2_s),
.adc_data_in_q2 (adc_data_q2_s),
.dac_valid_in (dac_valid_pl_s),
.dac_data_in_i1 (dac_data_pl_i1_s),
.dac_data_in_q1 (dac_data_pl_q1_s),
.dac_data_in_i2 (dac_data_pl_i2_s),
.dac_data_in_q2 (dac_data_pl_q2_s),
.dac_valid (dac_valid_s),
.dac_data_i1 (dac_data_i1_s),
.dac_data_q1 (dac_data_q1_s),
.dac_data_i2 (dac_data_i2_s),
.dac_data_q2 (dac_data_q2_s),
.dac_lb_enb_i1 (dac_lb_enb_i1_s),
.dac_pn_enb_i1 (dac_pn_enb_i1_s),
.dac_lb_enb_q1 (dac_lb_enb_q1_s),
.dac_pn_enb_q1 (dac_pn_enb_q1_s),
.dac_lb_enb_i2 (dac_lb_enb_i2_s),
.dac_pn_enb_i2 (dac_pn_enb_i2_s),
.dac_lb_enb_q2 (dac_lb_enb_q2_s),
.dac_pn_enb_q2 (dac_pn_enb_q2_s),
.adc_pn_oos_i1 (adc_pn_oos_i1_s),
.adc_pn_err_i1 (adc_pn_err_i1_s),
.adc_pn_oos_q1 (adc_pn_oos_q1_s),
.adc_pn_err_q1 (adc_pn_err_q1_s),
.adc_pn_oos_i2 (adc_pn_oos_i2_s),
.adc_pn_err_i2 (adc_pn_err_i2_s),
.adc_pn_oos_q2 (adc_pn_oos_q2_s),
.adc_pn_err_q2 (adc_pn_err_q2_s));
// receive
axi_ad9361_rx #(
.PCORE_ID (PCORE_ID),
.PCORE_VERSION (PCORE_VERSION),
.DP_DISABLE (PCORE_ADC_DP_DISABLE))
i_rx (
.adc_clk (clk),
.adc_valid (adc_valid_s),
.adc_pn_oos_i1 (adc_pn_oos_i1_s),
.adc_pn_err_i1 (adc_pn_err_i1_s),
.adc_data_i1 (adc_data_i1_s),
.adc_pn_oos_q1 (adc_pn_oos_q1_s),
.adc_pn_err_q1 (adc_pn_err_q1_s),
.adc_data_q1 (adc_data_q1_s),
.adc_pn_oos_i2 (adc_pn_oos_i2_s),
.adc_pn_err_i2 (adc_pn_err_i2_s),
.adc_data_i2 (adc_data_i2_s),
.adc_pn_oos_q2 (adc_pn_oos_q2_s),
.adc_pn_err_q2 (adc_pn_err_q2_s),
.adc_data_q2 (adc_data_q2_s),
.adc_status (adc_status_s),
.adc_r1_mode (adc_r1_mode_s),
.delay_clk (delay_clk),
.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),
.delay_ack_t (delay_ack_t_s),
.delay_locked (delay_locked_s),
.adc_dwr (adc_dwr),
.adc_ddata (adc_ddata),
.adc_dsync (adc_dsync),
.adc_dovf (adc_dovf),
.adc_dunf (adc_dunf),
.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_rx_s),
.up_ack (up_ack_rx_s),
.adc_mon_valid (adc_mon_valid),
.adc_mon_data (adc_mon_data),
.adc_dbg_trigger (),
.adc_dbg_data ());
// transmit
axi_ad9361_tx #(
.PCORE_ID (PCORE_ID),
.PCORE_VERSION (PCORE_VERSION),
.DP_DISABLE (PCORE_DAC_DP_DISABLE))
i_tx (
.dac_clk (clk),
.dac_valid (dac_valid_pl_s),
.dac_lb_enb_i1 (dac_lb_enb_i1_s),
.dac_pn_enb_i1 (dac_pn_enb_i1_s),
.dac_data_i1 (dac_data_pl_i1_s),
.dac_lb_enb_q1 (dac_lb_enb_q1_s),
.dac_pn_enb_q1 (dac_pn_enb_q1_s),
.dac_data_q1 (dac_data_pl_q1_s),
.dac_lb_enb_i2 (dac_lb_enb_i2_s),
.dac_pn_enb_i2 (dac_pn_enb_i2_s),
.dac_data_i2 (dac_data_pl_i2_s),
.dac_lb_enb_q2 (dac_lb_enb_q2_s),
.dac_pn_enb_q2 (dac_pn_enb_q2_s),
.dac_data_q2 (dac_data_pl_q2_s),
.dac_r1_mode (dac_r1_mode_s),
.dac_drd (dac_drd),
.dac_ddata (dac_ddata),
.dac_dovf (dac_dovf),
.dac_dunf (dac_dunf),
.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_tx_s),
.up_ack (up_ack_tx_s));
// axi 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
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,683 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// This interface includes both the transmit and receive components -
// They both uses the same clock (sourced from the receiving side).
`timescale 1ns/100ps
module axi_ad9361_dev_if (
// physical interface (receive)
rx_clk_in_p,
rx_clk_in_n,
rx_frame_in_p,
rx_frame_in_n,
rx_data_in_p,
rx_data_in_n,
// physical interface (transmit)
tx_clk_out_p,
tx_clk_out_n,
tx_frame_out_p,
tx_frame_out_n,
tx_data_out_p,
tx_data_out_n,
// clock (common to both receive and transmit)
clk,
// receive data path interface
adc_valid,
adc_data_i1,
adc_data_q1,
adc_data_i2,
adc_data_q2,
adc_status,
adc_r1_mode,
// transmit data path interface
dac_valid,
dac_data_i1,
dac_data_q1,
dac_data_i2,
dac_data_q2,
dac_r1_mode,
// delay control signals
delay_clk,
delay_rst,
delay_sel,
delay_rwn,
delay_addr,
delay_wdata,
delay_rdata,
delay_ack_t,
delay_locked,
// chipscope signals
dev_dbg_trigger,
dev_dbg_data);
// this parameter controls the buffer type based on the target device.
parameter PCORE_BUFTYPE = 0;
parameter PCORE_IODELAY_GROUP = "dev_if_delay_group";
localparam PCORE_7SERIES = 0;
localparam PCORE_VIRTEX6 = 1;
// physical interface (receive)
input rx_clk_in_p;
input rx_clk_in_n;
input rx_frame_in_p;
input rx_frame_in_n;
input [ 5:0] rx_data_in_p;
input [ 5:0] rx_data_in_n;
// physical interface (transmit)
output tx_clk_out_p;
output tx_clk_out_n;
output tx_frame_out_p;
output tx_frame_out_n;
output [ 5:0] tx_data_out_p;
output [ 5:0] tx_data_out_n;
// clock (common to both receive and transmit)
output clk;
// receive data path interface
output adc_valid;
output [11:0] adc_data_i1;
output [11:0] adc_data_q1;
output [11:0] adc_data_i2;
output [11:0] adc_data_q2;
output adc_status;
input adc_r1_mode;
// transmit data path interface
input dac_valid;
input [11:0] dac_data_i1;
input [11:0] dac_data_q1;
input [11:0] dac_data_i2;
input [11:0] dac_data_q2;
input dac_r1_mode;
// delay control signals
input delay_clk;
input delay_rst;
input delay_sel;
input delay_rwn;
input [ 7:0] delay_addr;
input [ 4:0] delay_wdata;
output [ 4:0] delay_rdata;
output delay_ack_t;
output delay_locked;
// chipscope signals
output [ 3:0] dev_dbg_trigger;
output [297:0] dev_dbg_data;
// internal registers
reg [ 5:0] rx_data_n = 'd0;
reg rx_frame_n = 'd0;
reg [11:0] rx_data = 'd0;
reg [ 1:0] rx_frame = 'd0;
reg [11:0] rx_data_d = 'd0;
reg [ 1:0] rx_frame_d = 'd0;
reg rx_error_r1 = 'd0;
reg rx_valid_r1 = 'd0;
reg [11:0] rx_data_i_r1 = 'd0;
reg [11:0] rx_data_q_r1 = 'd0;
reg rx_error_r2 = 'd0;
reg rx_valid_r2 = 'd0;
reg [11:0] rx_data_i1_r2 = 'd0;
reg [11:0] rx_data_q1_r2 = 'd0;
reg [11:0] rx_data_i2_r2 = 'd0;
reg [11:0] rx_data_q2_r2 = 'd0;
reg adc_valid = 'd0;
reg [11:0] adc_data_i1 = 'd0;
reg [11:0] adc_data_q1 = 'd0;
reg [11:0] adc_data_i2 = 'd0;
reg [11:0] adc_data_q2 = 'd0;
reg adc_status = 'd0;
reg [ 2:0] tx_data_cnt = 'd0;
reg [11:0] tx_data_i1_d = 'd0;
reg [11:0] tx_data_q1_d = 'd0;
reg [11:0] tx_data_i2_d = 'd0;
reg [11:0] tx_data_q2_d = 'd0;
reg tx_frame = 'd0;
reg [ 5:0] tx_data_p = 'd0;
reg [ 5:0] tx_data_n = 'd0;
reg [ 6:0] delay_ld = 'd0;
reg [ 4:0] delay_rdata = 'd0;
reg delay_ack_t = 'd0;
// internal signals
wire [ 3:0] rx_frame_s;
wire [ 3:0] tx_data_sel_s;
wire [ 4:0] delay_rdata_s[6:0];
wire [ 5:0] rx_data_ibuf_s;
wire [ 5:0] rx_data_idelay_s;
wire [ 5:0] rx_data_p_s;
wire [ 5:0] rx_data_n_s;
wire rx_frame_ibuf_s;
wire rx_frame_idelay_s;
wire rx_frame_p_s;
wire rx_frame_n_s;
wire [ 5:0] tx_data_oddr_s;
wire tx_frame_oddr_s;
wire tx_clk_oddr_s;
wire clk_ibuf_s;
genvar l_inst;
// device debug signals
assign dev_dbg_trigger[0] = rx_frame[0];
assign dev_dbg_trigger[1] = rx_frame[1];
assign dev_dbg_trigger[2] = tx_frame;
assign dev_dbg_trigger[3] = adc_status;
assign dev_dbg_data[ 5: 0] = tx_data_n;
assign dev_dbg_data[ 11: 6] = tx_data_p;
assign dev_dbg_data[ 23: 12] = tx_data_i1_d;
assign dev_dbg_data[ 35: 24] = tx_data_q1_d;
assign dev_dbg_data[ 47: 36] = tx_data_i2_d;
assign dev_dbg_data[ 59: 48] = tx_data_q2_d;
assign dev_dbg_data[ 63: 60] = tx_data_sel_s;
assign dev_dbg_data[ 66: 64] = tx_data_cnt;
assign dev_dbg_data[ 67: 67] = tx_frame;
assign dev_dbg_data[ 68: 68] = dac_r1_mode;
assign dev_dbg_data[ 69: 69] = dac_valid;
assign dev_dbg_data[ 81: 70] = dac_data_i1;
assign dev_dbg_data[ 93: 82] = dac_data_q1;
assign dev_dbg_data[105: 94] = dac_data_i2;
assign dev_dbg_data[117:106] = dac_data_q2;
assign dev_dbg_data[118:118] = rx_frame_p_s;
assign dev_dbg_data[119:119] = rx_frame_n_s;
assign dev_dbg_data[120:120] = rx_frame_n;
assign dev_dbg_data[122:121] = rx_frame;
assign dev_dbg_data[124:123] = rx_frame_d;
assign dev_dbg_data[128:125] = rx_frame_s;
assign dev_dbg_data[134:129] = rx_data_p_s;
assign dev_dbg_data[140:135] = rx_data_n_s;
assign dev_dbg_data[146:141] = rx_data_n;
assign dev_dbg_data[158:147] = rx_data;
assign dev_dbg_data[170:159] = rx_data_d;
assign dev_dbg_data[171:171] = rx_error_r1;
assign dev_dbg_data[172:172] = rx_valid_r1;
assign dev_dbg_data[184:173] = rx_data_i_r1;
assign dev_dbg_data[196:185] = rx_data_q_r1;
assign dev_dbg_data[197:197] = rx_error_r2;
assign dev_dbg_data[198:198] = rx_valid_r2;
assign dev_dbg_data[210:199] = rx_data_i1_r2;
assign dev_dbg_data[222:211] = rx_data_q1_r2;
assign dev_dbg_data[234:223] = rx_data_i2_r2;
assign dev_dbg_data[246:235] = rx_data_q2_r2;
assign dev_dbg_data[247:247] = adc_r1_mode;
assign dev_dbg_data[248:248] = adc_status;
assign dev_dbg_data[249:249] = adc_valid;
assign dev_dbg_data[261:250] = adc_data_i1;
assign dev_dbg_data[273:262] = adc_data_q1;
assign dev_dbg_data[285:274] = adc_data_i2;
assign dev_dbg_data[297:286] = adc_data_q2;
// receive data path interface
assign rx_frame_s = {rx_frame_d, rx_frame};
always @(posedge clk) begin
rx_data_n <= rx_data_n_s;
rx_frame_n <= rx_frame_n_s;
rx_data <= {rx_data_n, rx_data_p_s};
rx_frame <= {rx_frame_n, rx_frame_p_s};
rx_data_d <= rx_data;
rx_frame_d <= rx_frame;
end
// receive data path for single rf, frame is expected to qualify i/q msb only
always @(posedge clk) begin
rx_error_r1 <= ((rx_frame_s == 4'b1100) || (rx_frame_s == 4'b0011)) ? 1'b0 : 1'b1;
rx_valid_r1 <= (rx_frame_s == 4'b1100) ? 1'b1 : 1'b0;
if (rx_frame_s == 4'b1100) begin
rx_data_i_r1 <= {rx_data_d[11:6], rx_data[11:6]};
rx_data_q_r1 <= {rx_data_d[ 5:0], rx_data[ 5:0]};
end
end
// receive data path for dual rf, frame is expected to qualify i/q msb and lsb for rf-1 only
always @(posedge clk) begin
rx_error_r2 <= ((rx_frame_s == 4'b1111) || (rx_frame_s == 4'b1100) ||
(rx_frame_s == 4'b0000) || (rx_frame_s == 4'b0011)) ? 1'b0 : 1'b1;
rx_valid_r2 <= (rx_frame_s == 4'b0000) ? 1'b1 : 1'b0;
if (rx_frame_s == 4'b1111) begin
rx_data_i1_r2 <= {rx_data_d[11:6], rx_data[11:6]};
rx_data_q1_r2 <= {rx_data_d[ 5:0], rx_data[ 5:0]};
end
if (rx_frame_s == 4'b0000) begin
rx_data_i2_r2 <= {rx_data_d[11:6], rx_data[11:6]};
rx_data_q2_r2 <= {rx_data_d[ 5:0], rx_data[ 5:0]};
end
end
// receive data path mux
always @(posedge clk) begin
if (adc_r1_mode == 1'b1) begin
adc_valid <= rx_valid_r1;
adc_data_i1 <= rx_data_i_r1;
adc_data_q1 <= rx_data_q_r1;
adc_data_i2 <= 12'd0;
adc_data_q2 <= 12'd0;
adc_status <= ~rx_error_r1;
end else begin
adc_valid <= rx_valid_r2;
adc_data_i1 <= rx_data_i1_r2;
adc_data_q1 <= rx_data_q1_r2;
adc_data_i2 <= rx_data_i2_r2;
adc_data_q2 <= rx_data_q2_r2;
adc_status <= ~rx_error_r2;
end
end
// transmit data path mux (reverse of what receive does above)
// the count simply selets the data muxing on the ddr outputs
assign tx_data_sel_s = {tx_data_cnt[2], dac_r1_mode, tx_data_cnt[1:0]};
always @(posedge clk) begin
if (dac_valid == 1'b1) begin
tx_data_cnt <= 3'b100;
end else if (tx_data_cnt[2] == 1'b1) begin
tx_data_cnt <= tx_data_cnt + 1'b1;
end
if (dac_valid == 1'b1) begin
tx_data_i1_d <= dac_data_i1;
tx_data_q1_d <= dac_data_q1;
tx_data_i2_d <= dac_data_i2;
tx_data_q2_d <= dac_data_q2;
end
case (tx_data_sel_s)
4'b1111: begin
tx_frame <= 1'b0;
tx_data_p <= tx_data_i1_d[ 5:0];
tx_data_n <= tx_data_q1_d[ 5:0];
end
4'b1110: begin
tx_frame <= 1'b1;
tx_data_p <= tx_data_i1_d[11:6];
tx_data_n <= tx_data_q1_d[11:6];
end
4'b1101: begin
tx_frame <= 1'b0;
tx_data_p <= tx_data_i1_d[ 5:0];
tx_data_n <= tx_data_q1_d[ 5:0];
end
4'b1100: begin
tx_frame <= 1'b1;
tx_data_p <= tx_data_i1_d[11:6];
tx_data_n <= tx_data_q1_d[11:6];
end
4'b1011: begin
tx_frame <= 1'b0;
tx_data_p <= tx_data_i2_d[ 5:0];
tx_data_n <= tx_data_q2_d[ 5:0];
end
4'b1010: begin
tx_frame <= 1'b0;
tx_data_p <= tx_data_i2_d[11:6];
tx_data_n <= tx_data_q2_d[11:6];
end
4'b1001: begin
tx_frame <= 1'b1;
tx_data_p <= tx_data_i1_d[ 5:0];
tx_data_n <= tx_data_q1_d[ 5:0];
end
4'b1000: begin
tx_frame <= 1'b1;
tx_data_p <= tx_data_i1_d[11:6];
tx_data_n <= tx_data_q1_d[11:6];
end
default: begin
tx_frame <= 1'b0;
tx_data_p <= 6'd0;
tx_data_n <= 6'd0;
end
endcase
end
// delay write interface, each delay element can be individually
// addressed, and a delay value can be directly loaded (no inc/dec stuff)
always @(posedge delay_clk) begin
if ((delay_sel == 1'b1) && (delay_rwn == 1'b0)) begin
case (delay_addr)
8'h06: delay_ld <= 7'h40;
8'h05: delay_ld <= 7'h20;
8'h04: delay_ld <= 7'h10;
8'h03: delay_ld <= 7'h08;
8'h02: delay_ld <= 7'h04;
8'h01: delay_ld <= 7'h02;
8'h00: delay_ld <= 7'h01;
default: delay_ld <= 7'h00;
endcase
end else begin
delay_ld <= 7'h00;
end
end
// delay read interface, a delay ack toggle is used to transfer data to the
// processor side- delay locked is independently transferred
always @(posedge delay_clk) begin
case (delay_addr)
8'h06: delay_rdata <= delay_rdata_s[6];
8'h05: delay_rdata <= delay_rdata_s[5];
8'h04: delay_rdata <= delay_rdata_s[4];
8'h03: delay_rdata <= delay_rdata_s[3];
8'h02: delay_rdata <= delay_rdata_s[2];
8'h01: delay_rdata <= delay_rdata_s[1];
8'h00: delay_rdata <= delay_rdata_s[0];
default: delay_rdata <= 5'd0;
endcase
if (delay_sel == 1'b1) begin
delay_ack_t <= ~delay_ack_t;
end
end
// delay controller
(* IODELAY_GROUP = PCORE_IODELAY_GROUP *)
IDELAYCTRL i_delay_ctrl (
.RST (delay_rst),
.REFCLK (delay_clk),
.RDY (delay_locked));
// receive data interface, ibuf -> idelay -> iddr
generate
for (l_inst = 0; l_inst <= 5; l_inst = l_inst + 1) begin: g_rx_data
IBUFDS i_rx_data_ibuf (
.I (rx_data_in_p[l_inst]),
.IB (rx_data_in_n[l_inst]),
.O (rx_data_ibuf_s[l_inst]));
if (PCORE_BUFTYPE == PCORE_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_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 (rx_data_ibuf_s[l_inst]),
.DATAOUT (rx_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_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 (rx_data_ibuf_s[l_inst]),
.DATAOUT (rx_data_idelay_s[l_inst]),
.LD (delay_ld[l_inst]),
.CNTVALUEIN (delay_wdata),
.CNTVALUEOUT (delay_rdata_s[l_inst]));
end
IDDR #(
.DDR_CLK_EDGE ("SAME_EDGE_PIPELINED"),
.INIT_Q1 (1'b0),
.INIT_Q2 (1'b0),
.SRTYPE ("ASYNC"))
i_rx_data_iddr (
.CE (1'b1),
.R (1'b0),
.S (1'b0),
.C (clk),
.D (rx_data_idelay_s[l_inst]),
.Q1 (rx_data_p_s[l_inst]),
.Q2 (rx_data_n_s[l_inst]));
end
endgenerate
// receive frame interface, ibuf -> idelay -> iddr
IBUFDS i_rx_frame_ibuf (
.I (rx_frame_in_p),
.IB (rx_frame_in_n),
.O (rx_frame_ibuf_s));
generate
if (PCORE_BUFTYPE == PCORE_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_rx_frame_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 (rx_frame_ibuf_s),
.DATAOUT (rx_frame_idelay_s),
.RST (delay_ld[6]),
.CNTVALUEIN (delay_wdata),
.CNTVALUEOUT (delay_rdata_s[6]));
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_rx_frame_idelay (
.CE (1'b0),
.INC (1'b0),
.DATAIN (1'b0),
.LDPIPEEN (1'b0),
.CINVCTRL (1'b0),
.REGRST (1'b0),
.C (delay_clk),
.IDATAIN (rx_frame_ibuf_s),
.DATAOUT (rx_frame_idelay_s),
.LD (delay_ld[6]),
.CNTVALUEIN (delay_wdata),
.CNTVALUEOUT (delay_rdata_s[6]));
end
endgenerate
IDDR #(
.DDR_CLK_EDGE ("SAME_EDGE_PIPELINED"),
.INIT_Q1 (1'b0),
.INIT_Q2 (1'b0),
.SRTYPE ("ASYNC"))
i_rx_frame_iddr (
.CE (1'b1),
.R (1'b0),
.S (1'b0),
.C (clk),
.D (rx_frame_idelay_s),
.Q1 (rx_frame_p_s),
.Q2 (rx_frame_n_s));
// transmit data interface, oddr -> obuf
generate
for (l_inst = 0; l_inst <= 5; l_inst = l_inst + 1) begin: g_tx_data
ODDR #(
.DDR_CLK_EDGE ("SAME_EDGE"),
.INIT (1'b0),
.SRTYPE ("ASYNC"))
i_tx_data_oddr (
.CE (1'b1),
.R (1'b0),
.S (1'b0),
.C (clk),
.D1 (tx_data_p[l_inst]),
.D2 (tx_data_n[l_inst]),
.Q (tx_data_oddr_s[l_inst]));
OBUFDS i_tx_data_obuf (
.I (tx_data_oddr_s[l_inst]),
.O (tx_data_out_p[l_inst]),
.OB (tx_data_out_n[l_inst]));
end
endgenerate
// transmit frame interface, oddr -> obuf
ODDR #(
.DDR_CLK_EDGE ("SAME_EDGE"),
.INIT (1'b0),
.SRTYPE ("ASYNC"))
i_tx_frame_oddr (
.CE (1'b1),
.R (1'b0),
.S (1'b0),
.C (clk),
.D1 (tx_frame),
.D2 (tx_frame),
.Q (tx_frame_oddr_s));
OBUFDS i_tx_frame_obuf (
.I (tx_frame_oddr_s),
.O (tx_frame_out_p),
.OB (tx_frame_out_n));
// transmit clock interface, oddr -> obuf
ODDR #(
.DDR_CLK_EDGE ("SAME_EDGE"),
.INIT (1'b0),
.SRTYPE ("ASYNC"))
i_tx_clk_oddr (
.CE (1'b1),
.R (1'b0),
.S (1'b0),
.C (clk),
.D1 (1'b0),
.D2 (1'b1),
.Q (tx_clk_oddr_s));
OBUFDS i_tx_clk_obuf (
.I (tx_clk_oddr_s),
.O (tx_clk_out_p),
.OB (tx_clk_out_n));
// device clock interface (receive clock)
IBUFGDS i_rx_clk_ibuf (
.I (rx_clk_in_p),
.IB (rx_clk_in_n),
.O (clk_ibuf_s));
BUFG i_clk_gbuf (
.I (clk_ibuf_s),
.O (clk));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,54 @@
# ila debug
proc adi_ila_probe {w_obj w_msb w_lsb w_name} {
add_wave_virtual_bus -radix hex $w_name
for {set b $w_lsb} {$b <= $w_msb} {incr b} {
add_wave -into $w_name "$w_obj[$b]"
}
}
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 5 0 tx_data_n
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 11 6 tx_data_p
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 23 12 tx_data_i1_d
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 35 24 tx_data_q1_d
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 47 36 tx_data_i2_d
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 59 48 tx_data_q2_d
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 63 60 tx_data_sel_s
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 66 64 tx_data_cnt
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 67 67 tx_frame
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 68 68 dac_r1_mode
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 69 69 dac_valid
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 81 70 dac_data_i1
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 93 82 dac_data_q1
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 105 94 dac_data_i2
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 117 106 dac_data_q2
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 118 118 rx_frame_p_s
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 119 119 rx_frame_n_s
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 120 120 rx_frame_n
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 122 121 rx_frame
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 124 123 rx_frame_d
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 128 125 rx_frame_s
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 134 129 rx_data_p_s
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 140 135 rx_data_n_s
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 146 141 rx_data_n
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 158 147 rx_data
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 170 159 rx_data_d
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 171 171 rx_error_r1
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 172 172 rx_valid_r1
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 184 173 rx_data_i_r1
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 196 185 rx_data_q_r1
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 197 197 rx_error_r2
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 198 198 rx_valid_r2
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 210 199 rx_data_i1_r2
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 222 211 rx_data_q1_r2
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 234 223 rx_data_i2_r2
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 246 235 rx_data_q2_r2
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 247 247 adc_r1_mode
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 248 248 adc_status
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 249 249 adc_valid
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 261 250 adc_data_i1
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 273 262 adc_data_q1
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 285 274 adc_data_i2
adi_ila_probe system_i/axi_ad9361_1_dev_dbg_data 297 286 adc_data_q2

View File

@ -0,0 +1,46 @@
# ip
source ../scripts/adi_env.tcl
source $ad_hdl_dir/library/scripts/adi_ip.tcl
adi_ip_create axi_ad9361
adi_ip_files axi_ad9361 [list \
"$ad_hdl_dir/library/common/ad_rst.v" \
"$ad_hdl_dir/library/common/ad_mul_u16.v" \
"$ad_hdl_dir/library/common/ad_dds_sine.v" \
"$ad_hdl_dir/library/common/ad_dds_1.v" \
"$ad_hdl_dir/library/common/ad_dds.v" \
"$ad_hdl_dir/library/common/ad_datafmt.v" \
"$ad_hdl_dir/library/common/ad_dcfilter.v" \
"$ad_hdl_dir/library/common/ad_iqcor.v" \
"$ad_hdl_dir/library/common/up_axi.v" \
"$ad_hdl_dir/library/common/up_xfer_cntrl.v" \
"$ad_hdl_dir/library/common/up_xfer_status.v" \
"$ad_hdl_dir/library/common/up_clock_mon.v" \
"$ad_hdl_dir/library/common/up_delay_cntrl.v" \
"$ad_hdl_dir/library/common/up_drp_cntrl.v" \
"$ad_hdl_dir/library/common/up_adc_common.v" \
"$ad_hdl_dir/library/common/up_adc_channel.v" \
"$ad_hdl_dir/library/common/up_dac_common.v" \
"$ad_hdl_dir/library/common/up_dac_channel.v" \
"axi_ad9361_dev_if.v" \
"axi_ad9361_pnlb.v" \
"axi_ad9361_rx_pnmon.v" \
"axi_ad9361_rx_channel.v" \
"axi_ad9361_rx.v" \
"axi_ad9361_tx_dds.v" \
"axi_ad9361_tx_channel.v" \
"axi_ad9361_tx.v" \
"axi_ad9361.v" ]
adi_ip_properties axi_ad9361
set_property physical_name {s_axi_aclk} [ipx::get_port_map CLK \
[ipx::get_bus_interface s_axi_signal_clock [ipx::current_core]]]
ipx::remove_bus_interface {signal_clock} [ipx::current_core]
ipx::save_core [ipx::current_core]

View File

@ -0,0 +1,533 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// This interface includes both the transmit and receive components -
// They both uses the same clock (sourced from the receiving side).
`timescale 1ns/100ps
module axi_ad9361_pnlb (
// device interface
clk,
adc_valid_in,
adc_data_in_i1,
adc_data_in_q1,
adc_data_in_i2,
adc_data_in_q2,
dac_valid_in,
dac_data_in_i1,
dac_data_in_q1,
dac_data_in_i2,
dac_data_in_q2,
// dac outputs
dac_valid,
dac_data_i1,
dac_data_q1,
dac_data_i2,
dac_data_q2,
// control signals
dac_lb_enb_i1,
dac_pn_enb_i1,
dac_lb_enb_q1,
dac_pn_enb_q1,
dac_lb_enb_i2,
dac_pn_enb_i2,
dac_lb_enb_q2,
dac_pn_enb_q2,
// status signals
adc_pn_oos_i1,
adc_pn_err_i1,
adc_pn_oos_q1,
adc_pn_err_q1,
adc_pn_oos_i2,
adc_pn_err_i2,
adc_pn_oos_q2,
adc_pn_err_q2);
// device interface
input clk;
input adc_valid_in;
input [11:0] adc_data_in_i1;
input [11:0] adc_data_in_q1;
input [11:0] adc_data_in_i2;
input [11:0] adc_data_in_q2;
input dac_valid_in;
input [11:0] dac_data_in_i1;
input [11:0] dac_data_in_q1;
input [11:0] dac_data_in_i2;
input [11:0] dac_data_in_q2;
// dac outputs
output dac_valid;
output [11:0] dac_data_i1;
output [11:0] dac_data_q1;
output [11:0] dac_data_i2;
output [11:0] dac_data_q2;
// control signals
input dac_lb_enb_i1;
input dac_pn_enb_i1;
input dac_lb_enb_q1;
input dac_pn_enb_q1;
input dac_lb_enb_i2;
input dac_pn_enb_i2;
input dac_lb_enb_q2;
input dac_pn_enb_q2;
// status signals
output adc_pn_oos_i1;
output adc_pn_err_i1;
output adc_pn_oos_q1;
output adc_pn_err_q1;
output adc_pn_oos_i2;
output adc_pn_err_i2;
output adc_pn_oos_q2;
output adc_pn_err_q2;
// internal registers
reg dac_valid_t = 'd0;
reg [23:0] dac_pn_i1 = 'd0;
reg [23:0] dac_pn_q1 = 'd0;
reg [23:0] dac_pn_i2 = 'd0;
reg [23:0] dac_pn_q2 = 'd0;
reg [11:0] dac_lb_i1 = 'd0;
reg [11:0] dac_lb_q1 = 'd0;
reg [11:0] dac_lb_i2 = 'd0;
reg [11:0] dac_lb_q2 = 'd0;
reg dac_valid = 'd0;
reg [11:0] dac_data_i1 = 'd0;
reg [11:0] dac_data_q1 = 'd0;
reg [11:0] dac_data_i2 = 'd0;
reg [11:0] dac_data_q2 = 'd0;
reg adc_valid_t = 'd0;
reg [11:0] adc_data_in_i1_d = 'd0;
reg [11:0] adc_data_in_q1_d = 'd0;
reg [11:0] adc_data_in_i2_d = 'd0;
reg [11:0] adc_data_in_q2_d = 'd0;
reg [23:0] adc_pn_data_i1 = 'd0;
reg [23:0] adc_pn_data_q1 = 'd0;
reg [23:0] adc_pn_data_i2 = 'd0;
reg [23:0] adc_pn_data_q2 = 'd0;
reg adc_pn_err_i1 = 'd0;
reg adc_pn_oos_i1 = 'd0;
reg [ 3:0] adc_pn_oos_count_i1 = 'd0;
reg adc_pn_err_q1 = 'd0;
reg adc_pn_oos_q1 = 'd0;
reg [ 3:0] adc_pn_oos_count_q1 = 'd0;
reg adc_pn_err_i2 = 'd0;
reg adc_pn_oos_i2 = 'd0;
reg [ 3:0] adc_pn_oos_count_i2 = 'd0;
reg adc_pn_err_q2 = 'd0;
reg adc_pn_oos_q2 = 'd0;
reg [ 3:0] adc_pn_oos_count_q2 = 'd0;
// internal signals
wire dac_valid_t_s;
wire adc_valid_t_s;
wire [23:0] adc_data_in_i1_s;
wire adc_pn_err_i1_s;
wire adc_pn_update_i1_s;
wire adc_pn_match_i1_s;
wire adc_pn_match_i1_z_s;
wire adc_pn_match_i1_d_s;
wire [23:0] adc_pn_data_i1_s;
wire [23:0] adc_data_in_q1_s;
wire adc_pn_err_q1_s;
wire adc_pn_update_q1_s;
wire adc_pn_match_q1_s;
wire adc_pn_match_q1_z_s;
wire adc_pn_match_q1_d_s;
wire [23:0] adc_pn_data_q1_s;
wire [23:0] adc_data_in_i2_s;
wire adc_pn_err_i2_s;
wire adc_pn_update_i2_s;
wire adc_pn_match_i2_s;
wire adc_pn_match_i2_z_s;
wire adc_pn_match_i2_d_s;
wire [23:0] adc_pn_data_i2_s;
wire [23:0] adc_data_in_q2_s;
wire adc_pn_err_q2_s;
wire adc_pn_update_q2_s;
wire adc_pn_match_q2_s;
wire adc_pn_match_q2_z_s;
wire adc_pn_match_q2_d_s;
wire [23:0] adc_pn_data_q2_s;
// prbs-9 function
function [23:0] pn09;
input [23:0] din;
reg [23:0] dout;
begin
dout[23] = din[ 8] ^ din[ 4];
dout[22] = din[ 7] ^ din[ 3];
dout[21] = din[ 6] ^ din[ 2];
dout[20] = din[ 5] ^ din[ 1];
dout[19] = din[ 4] ^ din[ 0];
dout[18] = din[ 3] ^ din[ 8] ^ din[ 4];
dout[17] = din[ 2] ^ din[ 7] ^ din[ 3];
dout[16] = din[ 1] ^ din[ 6] ^ din[ 2];
dout[15] = din[ 0] ^ din[ 5] ^ din[ 1];
dout[14] = din[ 8] ^ din[ 0];
dout[13] = din[ 7] ^ din[ 8] ^ din[ 4];
dout[12] = din[ 6] ^ din[ 7] ^ din[ 3];
dout[11] = din[ 5] ^ din[ 6] ^ din[ 2];
dout[10] = din[ 4] ^ din[ 5] ^ din[ 1];
dout[ 9] = din[ 3] ^ din[ 4] ^ din[ 0];
dout[ 8] = din[ 2] ^ din[ 3] ^ din[ 8] ^ din[ 4];
dout[ 7] = din[ 1] ^ din[ 2] ^ din[ 7] ^ din[ 3];
dout[ 6] = din[ 0] ^ din[ 1] ^ din[ 6] ^ din[ 2];
dout[ 5] = din[ 8] ^ din[ 0] ^ din[ 4] ^ din[ 5] ^ din[ 1];
dout[ 4] = din[ 7] ^ din[ 8] ^ din[ 3] ^ din[ 0];
dout[ 3] = din[ 6] ^ din[ 7] ^ din[ 2] ^ din[ 8] ^ din[ 4];
dout[ 2] = din[ 5] ^ din[ 6] ^ din[ 1] ^ din[ 7] ^ din[ 3];
dout[ 1] = din[ 4] ^ din[ 5] ^ din[ 0] ^ din[ 6] ^ din[ 2];
dout[ 0] = din[ 3] ^ din[ 8] ^ din[ 5] ^ din[ 1];
pn09 = dout;
end
endfunction
// prbs-11 function
function [23:0] pn11;
input [23:0] din;
reg [23:0] dout;
begin
dout[23] = din[10] ^ din[ 8];
dout[22] = din[ 9] ^ din[ 7];
dout[21] = din[ 8] ^ din[ 6];
dout[20] = din[ 7] ^ din[ 5];
dout[19] = din[ 6] ^ din[ 4];
dout[18] = din[ 5] ^ din[ 3];
dout[17] = din[ 4] ^ din[ 2];
dout[16] = din[ 3] ^ din[ 1];
dout[15] = din[ 2] ^ din[ 0];
dout[14] = din[ 1] ^ din[10] ^ din[ 8];
dout[13] = din[ 0] ^ din[ 9] ^ din[ 7];
dout[12] = din[10] ^ din[ 6];
dout[11] = din[ 9] ^ din[ 5];
dout[10] = din[ 8] ^ din[ 4];
dout[ 9] = din[ 7] ^ din[ 3];
dout[ 8] = din[ 6] ^ din[ 2];
dout[ 7] = din[ 5] ^ din[ 1];
dout[ 6] = din[ 4] ^ din[ 0];
dout[ 5] = din[ 3] ^ din[10] ^ din[ 8];
dout[ 4] = din[ 2] ^ din[ 9] ^ din[ 7];
dout[ 3] = din[ 1] ^ din[ 8] ^ din[ 6];
dout[ 2] = din[ 0] ^ din[ 7] ^ din[ 5];
dout[ 1] = din[10] ^ din[ 6] ^ din[ 8] ^ din[ 4];
dout[ 0] = din[ 9] ^ din[ 5] ^ din[ 7] ^ din[ 3];
pn11 = dout;
end
endfunction
// prbs-15 function
function [23:0] pn15;
input [23:0] din;
reg [23:0] dout;
begin
dout[23] = din[14] ^ din[13];
dout[22] = din[13] ^ din[12];
dout[21] = din[12] ^ din[11];
dout[20] = din[11] ^ din[10];
dout[19] = din[10] ^ din[ 9];
dout[18] = din[ 9] ^ din[ 8];
dout[17] = din[ 8] ^ din[ 7];
dout[16] = din[ 7] ^ din[ 6];
dout[15] = din[ 6] ^ din[ 5];
dout[14] = din[ 5] ^ din[ 4];
dout[13] = din[ 4] ^ din[ 3];
dout[12] = din[ 3] ^ din[ 2];
dout[11] = din[ 2] ^ din[ 1];
dout[10] = din[ 1] ^ din[ 0];
dout[ 9] = din[ 0] ^ din[14] ^ din[13];
dout[ 8] = din[14] ^ din[12];
dout[ 7] = din[13] ^ din[11];
dout[ 6] = din[12] ^ din[10];
dout[ 5] = din[11] ^ din[ 9];
dout[ 4] = din[10] ^ din[ 8];
dout[ 3] = din[ 9] ^ din[ 7];
dout[ 2] = din[ 8] ^ din[ 6];
dout[ 1] = din[ 7] ^ din[ 5];
dout[ 0] = din[ 6] ^ din[ 4];
pn15 = dout;
end
endfunction
// prbs-20 function
function [23:0] pn20;
input [23:0] din;
reg [23:0] dout;
begin
dout[23] = din[19] ^ din[ 2];
dout[22] = din[18] ^ din[ 1];
dout[21] = din[17] ^ din[ 0];
dout[20] = din[16] ^ din[19] ^ din[ 2];
dout[19] = din[15] ^ din[18] ^ din[ 1];
dout[18] = din[14] ^ din[17] ^ din[ 0];
dout[17] = din[13] ^ din[16] ^ din[19] ^ din[ 2];
dout[16] = din[12] ^ din[15] ^ din[18] ^ din[ 1];
dout[15] = din[11] ^ din[14] ^ din[17] ^ din[ 0];
dout[14] = din[10] ^ din[13] ^ din[16] ^ din[19] ^ din[ 2];
dout[13] = din[ 9] ^ din[12] ^ din[15] ^ din[18] ^ din[ 1];
dout[12] = din[ 8] ^ din[11] ^ din[14] ^ din[17] ^ din[ 0];
dout[11] = din[ 7] ^ din[10] ^ din[13] ^ din[16] ^ din[19] ^ din[ 2];
dout[10] = din[ 6] ^ din[ 9] ^ din[12] ^ din[15] ^ din[18] ^ din[ 1];
dout[ 9] = din[ 5] ^ din[ 8] ^ din[11] ^ din[14] ^ din[17] ^ din[ 0];
dout[ 8] = din[ 4] ^ din[ 7] ^ din[10] ^ din[13] ^ din[16] ^ din[19] ^ din[ 2];
dout[ 7] = din[ 3] ^ din[ 6] ^ din[ 9] ^ din[12] ^ din[15] ^ din[18] ^ din[ 1];
dout[ 6] = din[ 2] ^ din[ 5] ^ din[ 8] ^ din[11] ^ din[14] ^ din[17] ^ din[ 0];
dout[ 5] = din[ 1] ^ din[ 4] ^ din[ 7] ^ din[10] ^ din[13] ^ din[16] ^ din[19] ^ din[ 2];
dout[ 4] = din[ 0] ^ din[ 3] ^ din[ 6] ^ din[ 9] ^ din[12] ^ din[15] ^ din[18] ^ din[ 1];
dout[ 3] = din[19] ^ din[ 5] ^ din[ 8] ^ din[11] ^ din[14] ^ din[17] ^ din[ 0];
dout[ 2] = din[18] ^ din[ 4] ^ din[ 7] ^ din[10] ^ din[13] ^ din[16] ^ din[19] ^ din[ 2];
dout[ 1] = din[17] ^ din[ 3] ^ din[ 6] ^ din[ 9] ^ din[12] ^ din[15] ^ din[18] ^ din[ 1];
dout[ 0] = din[16] ^ din[ 2] ^ din[ 5] ^ din[ 8] ^ din[11] ^ din[14] ^ din[17] ^ din[ 0];
pn20 = dout;
end
endfunction
// prbs generators run at 24bits wide
assign dac_valid_t_s = dac_valid_in & dac_valid_t;
always @(posedge clk) begin
if (dac_valid_in == 1'b1) begin
dac_valid_t <= ~dac_valid_t;
end
if (dac_pn_enb_i1 == 1'b0) begin
dac_pn_i1 <= 24'hffffff;
end else if (dac_valid_t_s == 1'b1) begin
dac_pn_i1 <= pn09(dac_pn_i1);
end
if (dac_pn_enb_q1 == 1'b0) begin
dac_pn_q1 <= 24'hffffff;
end else if (dac_valid_t_s == 1'b1) begin
dac_pn_q1 <= pn11(dac_pn_q1);
end
if (dac_pn_enb_i2 == 1'b0) begin
dac_pn_i2 <= 24'hffffff;
end else if (dac_valid_t_s == 1'b1) begin
dac_pn_i2 <= pn15(dac_pn_i2);
end
if (dac_pn_enb_q2 == 1'b0) begin
dac_pn_q2 <= 24'hffffff;
end else if (dac_valid_t_s == 1'b1) begin
dac_pn_q2 <= pn20(dac_pn_q2);
end
end
// hold adc data for loopback, it is assumed that there is a one to one mapping
// of receive and transmit (the rates are the same).
always @(posedge clk) begin
if (adc_valid_in == 1'b1) begin
dac_lb_i1 <= adc_data_in_i1;
dac_lb_q1 <= adc_data_in_q1;
dac_lb_i2 <= adc_data_in_i2;
dac_lb_q2 <= adc_data_in_q2;
end
end
// dac outputs-
always @(posedge clk) begin
dac_valid <= dac_valid_in;
if (dac_pn_enb_i1 == 1'b1) begin
if (dac_valid_t == 1'b1) begin
dac_data_i1 <= dac_pn_i1[11:0];
end else begin
dac_data_i1 <= dac_pn_i1[23:12];
end
end else if (dac_lb_enb_i1 == 1'b1) begin
dac_data_i1 <= dac_lb_i1;
end else begin
dac_data_i1 <= dac_data_in_i1;
end
if (dac_pn_enb_q1 == 1'b1) begin
if (dac_valid_t == 1'b1) begin
dac_data_q1 <= dac_pn_q1[11:0];
end else begin
dac_data_q1 <= dac_pn_q1[23:12];
end
end else if (dac_lb_enb_q1 == 1'b1) begin
dac_data_q1 <= dac_lb_q1;
end else begin
dac_data_q1 <= dac_data_in_q1;
end
if (dac_pn_enb_i2 == 1'b1) begin
if (dac_valid_t == 1'b1) begin
dac_data_i2 <= dac_pn_i2[11:0];
end else begin
dac_data_i2 <= dac_pn_i2[23:12];
end
end else if (dac_lb_enb_i2 == 1'b1) begin
dac_data_i2 <= dac_lb_i2;
end else begin
dac_data_i2 <= dac_data_in_i2;
end
if (dac_pn_enb_q2 == 1'b1) begin
if (dac_valid_t == 1'b1) begin
dac_data_q2 <= dac_pn_q2[11:0];
end else begin
dac_data_q2 <= dac_pn_q2[23:12];
end
end else if (dac_lb_enb_q2 == 1'b1) begin
dac_data_q2 <= dac_lb_q2;
end else begin
dac_data_q2 <= dac_data_in_q2;
end
end
// adc pn monitoring
assign adc_valid_t_s = adc_valid_in & adc_valid_t;
assign adc_data_in_i1_s = {adc_data_in_i1_d, adc_data_in_i1};
assign adc_pn_err_i1_s = ~(adc_pn_oos_i1 | adc_pn_match_i1_s);
assign adc_pn_update_i1_s = ~(adc_pn_oos_i1 ^ adc_pn_match_i1_s);
assign adc_pn_match_i1_s = adc_pn_match_i1_d_s & adc_pn_match_i1_z_s;
assign adc_pn_match_i1_z_s = (adc_data_in_i1_s == 24'd0) ? 1'b0 : 1'b1;
assign adc_pn_match_i1_d_s = (adc_data_in_i1_s == adc_pn_data_i1) ? 1'b1 : 1'b0;
assign adc_pn_data_i1_s = (adc_pn_oos_i1 == 1'b1) ? adc_data_in_i1_s : adc_pn_data_i1;
assign adc_data_in_q1_s = {adc_data_in_q1_d, adc_data_in_q1};
assign adc_pn_err_q1_s = ~(adc_pn_oos_q1 | adc_pn_match_q1_s);
assign adc_pn_update_q1_s = ~(adc_pn_oos_q1 ^ adc_pn_match_q1_s);
assign adc_pn_match_q1_s = adc_pn_match_q1_d_s & adc_pn_match_q1_z_s;
assign adc_pn_match_q1_z_s = (adc_data_in_q1_s == 24'd0) ? 1'b0 : 1'b1;
assign adc_pn_match_q1_d_s = (adc_data_in_q1_s == adc_pn_data_q1) ? 1'b1 : 1'b0;
assign adc_pn_data_q1_s = (adc_pn_oos_q1 == 1'b1) ? adc_data_in_q1_s : adc_pn_data_q1;
assign adc_data_in_i2_s = {adc_data_in_i2_d, adc_data_in_i2};
assign adc_pn_err_i2_s = ~(adc_pn_oos_i2 | adc_pn_match_i2_s);
assign adc_pn_update_i2_s = ~(adc_pn_oos_i2 ^ adc_pn_match_i2_s);
assign adc_pn_match_i2_s = adc_pn_match_i2_d_s & adc_pn_match_i2_z_s;
assign adc_pn_match_i2_z_s = (adc_data_in_i2_s == 24'd0) ? 1'b0 : 1'b1;
assign adc_pn_match_i2_d_s = (adc_data_in_i2_s == adc_pn_data_i2) ? 1'b1 : 1'b0;
assign adc_pn_data_i2_s = (adc_pn_oos_i2 == 1'b1) ? adc_data_in_i2_s : adc_pn_data_i2;
assign adc_data_in_q2_s = {adc_data_in_q2_d, adc_data_in_q2};
assign adc_pn_err_q2_s = ~(adc_pn_oos_q2 | adc_pn_match_q2_s);
assign adc_pn_update_q2_s = ~(adc_pn_oos_q2 ^ adc_pn_match_q2_s);
assign adc_pn_match_q2_s = adc_pn_match_q2_d_s & adc_pn_match_q2_z_s;
assign adc_pn_match_q2_z_s = (adc_data_in_q2_s == 24'd0) ? 1'b0 : 1'b1;
assign adc_pn_match_q2_d_s = (adc_data_in_q2_s == adc_pn_data_q2) ? 1'b1 : 1'b0;
assign adc_pn_data_q2_s = (adc_pn_oos_q2 == 1'b1) ? adc_data_in_q2_s : adc_pn_data_q2;
// adc pn running sequence
always @(posedge clk) begin
if (adc_valid_in == 1'b1) begin
adc_valid_t <= ~adc_valid_t;
adc_data_in_i1_d <= adc_data_in_i1;
adc_data_in_q1_d <= adc_data_in_q1;
adc_data_in_i2_d <= adc_data_in_i2;
adc_data_in_q2_d <= adc_data_in_q2;
end
if (adc_valid_t_s == 1'b1) begin
adc_pn_data_i1 <= pn09(adc_pn_data_i1_s);
adc_pn_data_q1 <= pn11(adc_pn_data_q1_s);
adc_pn_data_i2 <= pn15(adc_pn_data_i2_s);
adc_pn_data_q2 <= pn20(adc_pn_data_q2_s);
end
end
// pn oos and counters (16 to clear and set).
always @(posedge clk) begin
if (adc_valid_t_s == 1'b1) begin
adc_pn_err_i1 <= adc_pn_err_i1_s;
if ((adc_pn_update_i1_s == 1'b1) && (adc_pn_oos_count_i1 >= 15)) begin
adc_pn_oos_i1 <= ~adc_pn_oos_i1;
end
if (adc_pn_update_i1_s == 1'b1) begin
adc_pn_oos_count_i1 <= adc_pn_oos_count_i1 + 1'b1;
end else begin
adc_pn_oos_count_i1 <= 'd0;
end
adc_pn_err_q1 <= adc_pn_err_q1_s;
if ((adc_pn_update_q1_s == 1'b1) && (adc_pn_oos_count_q1 >= 15)) begin
adc_pn_oos_q1 <= ~adc_pn_oos_q1;
end
if (adc_pn_update_q1_s == 1'b1) begin
adc_pn_oos_count_q1 <= adc_pn_oos_count_q1 + 1'b1;
end else begin
adc_pn_oos_count_q1 <= 'd0;
end
adc_pn_err_i2 <= adc_pn_err_i2_s;
if ((adc_pn_update_i2_s == 1'b1) && (adc_pn_oos_count_i2 >= 15)) begin
adc_pn_oos_i2 <= ~adc_pn_oos_i2;
end
if (adc_pn_update_i2_s == 1'b1) begin
adc_pn_oos_count_i2 <= adc_pn_oos_count_i2 + 1'b1;
end else begin
adc_pn_oos_count_i2 <= 'd0;
end
adc_pn_err_q2 <= adc_pn_err_q2_s;
if ((adc_pn_update_q2_s == 1'b1) && (adc_pn_oos_count_q2 >= 15)) begin
adc_pn_oos_q2 <= ~adc_pn_oos_q2;
end
if (adc_pn_update_q2_s == 1'b1) begin
adc_pn_oos_count_q2 <= adc_pn_oos_count_q2 + 1'b1;
end else begin
adc_pn_oos_count_q2 <= 'd0;
end
end
end
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,717 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ADC channel-need to work on dual mode for pn sequence
`timescale 1ns/100ps
module axi_ad9361_rx (
// adc interface
adc_clk,
adc_valid,
adc_pn_oos_i1,
adc_pn_err_i1,
adc_data_i1,
adc_pn_oos_q1,
adc_pn_err_q1,
adc_data_q1,
adc_pn_oos_i2,
adc_pn_err_i2,
adc_data_i2,
adc_pn_oos_q2,
adc_pn_err_q2,
adc_data_q2,
adc_status,
adc_r1_mode,
// delay interface
delay_clk,
delay_rst,
delay_sel,
delay_rwn,
delay_addr,
delay_wdata,
delay_rdata,
delay_ack_t,
delay_locked,
// dma interface
adc_dwr,
adc_ddata,
adc_dsync,
adc_dovf,
adc_dunf,
// processor interface
up_rstn,
up_clk,
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack,
// monitor signals
adc_mon_valid,
adc_mon_data,
// debug signals
adc_dbg_trigger,
adc_dbg_data);
// parameters
parameter DP_DISABLE = 0;
parameter PCORE_ID = 0;
parameter PCORE_VERSION = 32'h00060061;
// adc interface
input adc_clk;
input adc_valid;
input adc_pn_oos_i1;
input adc_pn_err_i1;
input [11:0] adc_data_i1;
input adc_pn_oos_q1;
input adc_pn_err_q1;
input [11:0] adc_data_q1;
input adc_pn_oos_i2;
input adc_pn_err_i2;
input [11:0] adc_data_i2;
input adc_pn_oos_q2;
input adc_pn_err_q2;
input [11:0] adc_data_q2;
input adc_status;
output adc_r1_mode;
// delay interface
input delay_clk;
output delay_rst;
output delay_sel;
output delay_rwn;
output [ 7:0] delay_addr;
output [ 4:0] delay_wdata;
input [ 4:0] delay_rdata;
input delay_ack_t;
input delay_locked;
// dma interface
output adc_dwr;
output [63:0] adc_ddata;
output adc_dsync;
input adc_dovf;
input adc_dunf;
// processor interface
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;
// monitor signals
output adc_mon_valid;
output [47:0] adc_mon_data;
// debug signals
output [ 1:0] adc_dbg_trigger;
output [116:0] adc_dbg_data;
// internal registers
reg [47:0] adc_iqcor_data_3_1110 = 'd0;
reg [47:0] adc_iqcor_data_3_1101 = 'd0;
reg [47:0] adc_iqcor_data_3_1011 = 'd0;
reg [47:0] adc_iqcor_data_3_0111 = 'd0;
reg adc_iqcor_valid = 'd0;
reg adc_iqcor_valid_3 = 'd0;
reg adc_iqcor_sync = 'd0;
reg adc_iqcor_sync_3 = 'd0;
reg [63:0] adc_iqcor_data = 'd0;
reg [63:0] adc_iqcor_data_1110 = 'd0;
reg [63:0] adc_iqcor_data_1101 = 'd0;
reg [63:0] adc_iqcor_data_1011 = 'd0;
reg [63:0] adc_iqcor_data_0111 = 'd0;
reg [ 1:0] adc_iqcor_data_cnt = 'd0;
reg up_adc_status_pn_err = 'd0;
reg up_adc_status_pn_oos = 'd0;
reg up_adc_status_or = 'd0;
reg [31:0] up_rdata = 'd0;
reg up_ack = 'd0;
// internal clocks and resets
wire adc_rst;
// internal signals
wire adc_iqcor_valid_s;
wire [15:0] adc_dcfilter_data_out_0_s;
wire adc_pn_oos_out_0_s;
wire adc_pn_err_out_0_s;
wire adc_iqcor_valid_0_s;
wire [15:0] adc_iqcor_data_0_s;
wire adc_enable_0_s;
wire up_adc_pn_err_0_s;
wire up_adc_pn_oos_0_s;
wire up_adc_or_0_s;
wire [31:0] up_rdata_0_s;
wire up_ack_0_s;
wire adc_iqcor_valid_1_s;
wire [15:0] adc_iqcor_data_1_s;
wire adc_enable_1_s;
wire up_adc_pn_err_1_s;
wire up_adc_pn_oos_1_s;
wire up_adc_or_1_s;
wire [31:0] up_rdata_1_s;
wire up_ack_1_s;
wire [15:0] adc_dcfilter_data_out_2_s;
wire adc_pn_oos_out_2_s;
wire adc_pn_err_out_2_s;
wire adc_iqcor_valid_2_s;
wire [15:0] adc_iqcor_data_2_s;
wire adc_enable_2_s;
wire up_adc_pn_err_2_s;
wire up_adc_pn_oos_2_s;
wire up_adc_or_2_s;
wire [31:0] up_rdata_2_s;
wire up_ack_2_s;
wire adc_iqcor_valid_3_s;
wire [15:0] adc_iqcor_data_3_s;
wire adc_enable_3_s;
wire up_adc_pn_err_3_s;
wire up_adc_pn_oos_3_s;
wire up_adc_or_3_s;
wire [31:0] up_rdata_3_s;
wire up_ack_3_s;
wire [31:0] up_rdata_s;
wire up_ack_s;
// monitor signals
assign adc_mon_valid = adc_valid;
assign adc_mon_data[11: 0] = adc_data_i1;
assign adc_mon_data[23:12] = adc_data_q1;
assign adc_mon_data[35:24] = adc_data_i2;
assign adc_mon_data[47:36] = adc_data_q2;
// debug signals
assign adc_dbg_trigger[0] = adc_iqcor_valid_s;
assign adc_dbg_trigger[1] = adc_valid;
assign adc_dbg_data[ 15: 0] = adc_iqcor_data_0_s;
assign adc_dbg_data[ 31: 16] = adc_iqcor_data_1_s;
assign adc_dbg_data[ 47: 32] = adc_iqcor_data_2_s;
assign adc_dbg_data[ 63: 48] = adc_iqcor_data_3_s;
assign adc_dbg_data[ 64: 64] = adc_iqcor_valid_0_s;
assign adc_dbg_data[ 65: 65] = adc_iqcor_valid_1_s;
assign adc_dbg_data[ 66: 66] = adc_iqcor_valid_2_s;
assign adc_dbg_data[ 67: 67] = adc_iqcor_valid_3_s;
assign adc_dbg_data[ 79: 68] = adc_data_i1;
assign adc_dbg_data[ 91: 80] = adc_data_q1;
assign adc_dbg_data[103: 92] = adc_data_i2;
assign adc_dbg_data[115:104] = adc_data_q2;
assign adc_dbg_data[116:116] = adc_valid;
// adc channels - dma interface
assign adc_dwr = adc_iqcor_valid;
assign adc_dsync = adc_iqcor_sync;
assign adc_ddata = adc_iqcor_data;
assign adc_iqcor_valid_s = adc_iqcor_valid_0_s & adc_iqcor_valid_1_s &
adc_iqcor_valid_2_s & adc_iqcor_valid_3_s;
always @(posedge adc_clk) begin
if (adc_iqcor_valid_s == 1'b1) begin
adc_iqcor_valid_3 <= adc_iqcor_data_cnt[0] | adc_iqcor_data_cnt[1];
adc_iqcor_sync_3 <= adc_iqcor_data_cnt[0] & ~adc_iqcor_data_cnt[1];
adc_iqcor_data_3_1110[47:32] <= adc_iqcor_data_3_s;
adc_iqcor_data_3_1110[31:16] <= adc_iqcor_data_2_s;
adc_iqcor_data_3_1110[15: 0] <= adc_iqcor_data_1_s;
adc_iqcor_data_3_1101[47:32] <= adc_iqcor_data_3_s;
adc_iqcor_data_3_1101[31:16] <= adc_iqcor_data_2_s;
adc_iqcor_data_3_1101[15: 0] <= adc_iqcor_data_0_s;
adc_iqcor_data_3_1011[47:32] <= adc_iqcor_data_3_s;
adc_iqcor_data_3_1011[31:16] <= adc_iqcor_data_1_s;
adc_iqcor_data_3_1011[15: 0] <= adc_iqcor_data_0_s;
adc_iqcor_data_3_0111[47:32] <= adc_iqcor_data_2_s;
adc_iqcor_data_3_0111[31:16] <= adc_iqcor_data_1_s;
adc_iqcor_data_3_0111[15: 0] <= adc_iqcor_data_0_s;
case (adc_iqcor_data_cnt)
2'b11: begin
adc_iqcor_data_1110[63:48] <= adc_iqcor_data_3_s;
adc_iqcor_data_1110[47:32] <= adc_iqcor_data_2_s;
adc_iqcor_data_1110[31:16] <= adc_iqcor_data_1_s;
adc_iqcor_data_1110[15: 0] <= adc_iqcor_data_3_1110[47:32];
adc_iqcor_data_1101[63:48] <= adc_iqcor_data_3_s;
adc_iqcor_data_1101[47:32] <= adc_iqcor_data_2_s;
adc_iqcor_data_1101[31:16] <= adc_iqcor_data_0_s;
adc_iqcor_data_1101[15: 0] <= adc_iqcor_data_3_1101[47:32];
adc_iqcor_data_1011[63:48] <= adc_iqcor_data_3_s;
adc_iqcor_data_1011[47:32] <= adc_iqcor_data_1_s;
adc_iqcor_data_1011[31:16] <= adc_iqcor_data_0_s;
adc_iqcor_data_1011[15: 0] <= adc_iqcor_data_3_1011[47:32];
adc_iqcor_data_0111[63:48] <= adc_iqcor_data_2_s;
adc_iqcor_data_0111[47:32] <= adc_iqcor_data_1_s;
adc_iqcor_data_0111[31:16] <= adc_iqcor_data_0_s;
adc_iqcor_data_0111[15: 0] <= adc_iqcor_data_3_0111[47:32];
end
2'b10: begin
adc_iqcor_data_1110[63:48] <= adc_iqcor_data_2_s;
adc_iqcor_data_1110[47:32] <= adc_iqcor_data_1_s;
adc_iqcor_data_1110[31:16] <= adc_iqcor_data_3_1110[47:32];
adc_iqcor_data_1110[15: 0] <= adc_iqcor_data_3_1110[31:16];
adc_iqcor_data_1101[63:48] <= adc_iqcor_data_2_s;
adc_iqcor_data_1101[47:32] <= adc_iqcor_data_0_s;
adc_iqcor_data_1101[31:16] <= adc_iqcor_data_3_1101[47:32];
adc_iqcor_data_1101[15: 0] <= adc_iqcor_data_3_1101[31:16];
adc_iqcor_data_1011[63:48] <= adc_iqcor_data_1_s;
adc_iqcor_data_1011[47:32] <= adc_iqcor_data_0_s;
adc_iqcor_data_1011[31:16] <= adc_iqcor_data_3_1011[47:32];
adc_iqcor_data_1011[15: 0] <= adc_iqcor_data_3_1011[31:16];
adc_iqcor_data_0111[63:48] <= adc_iqcor_data_1_s;
adc_iqcor_data_0111[47:32] <= adc_iqcor_data_0_s;
adc_iqcor_data_0111[31:16] <= adc_iqcor_data_3_0111[47:32];
adc_iqcor_data_0111[15: 0] <= adc_iqcor_data_3_0111[31:16];
end
2'b01: begin
adc_iqcor_data_1110[63:48] <= adc_iqcor_data_1_s;
adc_iqcor_data_1110[47:32] <= adc_iqcor_data_3_1110[47:32];
adc_iqcor_data_1110[31:16] <= adc_iqcor_data_3_1110[31:16];
adc_iqcor_data_1110[15: 0] <= adc_iqcor_data_3_1110[15: 0];
adc_iqcor_data_1101[63:48] <= adc_iqcor_data_0_s;
adc_iqcor_data_1101[47:32] <= adc_iqcor_data_3_1101[47:32];
adc_iqcor_data_1101[31:16] <= adc_iqcor_data_3_1101[31:16];
adc_iqcor_data_1101[15: 0] <= adc_iqcor_data_3_1101[15: 0];
adc_iqcor_data_1011[63:48] <= adc_iqcor_data_0_s;
adc_iqcor_data_1011[47:32] <= adc_iqcor_data_3_1011[47:32];
adc_iqcor_data_1011[31:16] <= adc_iqcor_data_3_1011[31:16];
adc_iqcor_data_1011[15: 0] <= adc_iqcor_data_3_1011[15: 0];
adc_iqcor_data_0111[63:48] <= adc_iqcor_data_0_s;
adc_iqcor_data_0111[47:32] <= adc_iqcor_data_3_0111[47:32];
adc_iqcor_data_0111[31:16] <= adc_iqcor_data_3_0111[31:16];
adc_iqcor_data_0111[15: 0] <= adc_iqcor_data_3_0111[15: 0];
end
default:begin
adc_iqcor_data_1110[63:48] <= 16'hdead;
adc_iqcor_data_1110[47:32] <= 16'hdead;
adc_iqcor_data_1110[31:16] <= 16'hdead;
adc_iqcor_data_1110[15: 0] <= 16'hdead;
adc_iqcor_data_1101[63:48] <= 16'hdead;
adc_iqcor_data_1101[47:32] <= 16'hdead;
adc_iqcor_data_1101[31:16] <= 16'hdead;
adc_iqcor_data_1101[15: 0] <= 16'hdead;
adc_iqcor_data_1011[63:48] <= 16'hdead;
adc_iqcor_data_1011[47:32] <= 16'hdead;
adc_iqcor_data_1011[31:16] <= 16'hdead;
adc_iqcor_data_1011[15: 0] <= 16'hdead;
adc_iqcor_data_0111[63:48] <= 16'hdead;
adc_iqcor_data_0111[47:32] <= 16'hdead;
adc_iqcor_data_0111[31:16] <= 16'hdead;
adc_iqcor_data_0111[15: 0] <= 16'hdead;
end
endcase
end
end
always @(posedge adc_clk) begin
if (adc_iqcor_valid_s == 1'b1) begin
case ({adc_enable_3_s, adc_enable_2_s, adc_enable_1_s, adc_enable_0_s})
4'b1111: begin
adc_iqcor_valid <= 1'b1;
adc_iqcor_sync <= 1'b1;
adc_iqcor_data[63:48] <= adc_iqcor_data_3_s;
adc_iqcor_data[47:32] <= adc_iqcor_data_2_s;
adc_iqcor_data[31:16] <= adc_iqcor_data_1_s;
adc_iqcor_data[15: 0] <= adc_iqcor_data_0_s;
end
4'b1110: begin
adc_iqcor_sync <= adc_iqcor_sync_3;
adc_iqcor_valid <= adc_iqcor_valid_3;
adc_iqcor_data <= adc_iqcor_data_1110;
end
4'b1101: begin
adc_iqcor_sync <= adc_iqcor_sync_3;
adc_iqcor_valid <= adc_iqcor_valid_3;
adc_iqcor_data <= adc_iqcor_data_1101;
end
4'b1100: begin
adc_iqcor_sync <= 1'b1;
adc_iqcor_valid <= adc_iqcor_data_cnt[0];
adc_iqcor_data[63:48] <= adc_iqcor_data_3_s;
adc_iqcor_data[47:32] <= adc_iqcor_data_2_s;
adc_iqcor_data[31:16] <= adc_iqcor_data[63:48];
adc_iqcor_data[15: 0] <= adc_iqcor_data[47:32];
end
4'b1011: begin
adc_iqcor_sync <= adc_iqcor_sync_3;
adc_iqcor_valid <= adc_iqcor_valid_3;
adc_iqcor_data <= adc_iqcor_data_1011;
end
4'b1010: begin
adc_iqcor_sync <= 1'b1;
adc_iqcor_valid <= adc_iqcor_data_cnt[0];
adc_iqcor_data[63:48] <= adc_iqcor_data_3_s;
adc_iqcor_data[47:32] <= adc_iqcor_data_1_s;
adc_iqcor_data[31:16] <= adc_iqcor_data[63:48];
adc_iqcor_data[15: 0] <= adc_iqcor_data[47:32];
end
4'b1001: begin
adc_iqcor_sync <= 1'b1;
adc_iqcor_valid <= adc_iqcor_data_cnt[0];
adc_iqcor_data[63:48] <= adc_iqcor_data_3_s;
adc_iqcor_data[47:32] <= adc_iqcor_data_0_s;
adc_iqcor_data[31:16] <= adc_iqcor_data[63:48];
adc_iqcor_data[15: 0] <= adc_iqcor_data[47:32];
end
4'b1000: begin
adc_iqcor_sync <= 1'b1;
adc_iqcor_valid <= adc_iqcor_data_cnt[1] & adc_iqcor_data_cnt[0];
adc_iqcor_data[63:48] <= adc_iqcor_data_3_s;
adc_iqcor_data[47:32] <= adc_iqcor_data[63:48];
adc_iqcor_data[31:16] <= adc_iqcor_data[47:32];
adc_iqcor_data[15: 0] <= adc_iqcor_data[31:16];
end
4'b0111: begin
adc_iqcor_sync <= adc_iqcor_sync_3;
adc_iqcor_valid <= adc_iqcor_valid_3;
adc_iqcor_data <= adc_iqcor_data_0111;
end
4'b0110: begin
adc_iqcor_sync <= 1'b1;
adc_iqcor_valid <= adc_iqcor_data_cnt[0];
adc_iqcor_data[63:48] <= adc_iqcor_data_2_s;
adc_iqcor_data[47:32] <= adc_iqcor_data_1_s;
adc_iqcor_data[31:16] <= adc_iqcor_data[63:48];
adc_iqcor_data[15: 0] <= adc_iqcor_data[47:32];
end
4'b0101: begin
adc_iqcor_sync <= 1'b1;
adc_iqcor_valid <= adc_iqcor_data_cnt[0];
adc_iqcor_data[63:48] <= adc_iqcor_data_2_s;
adc_iqcor_data[47:32] <= adc_iqcor_data_0_s;
adc_iqcor_data[31:16] <= adc_iqcor_data[63:48];
adc_iqcor_data[15: 0] <= adc_iqcor_data[47:32];
end
4'b0100: begin
adc_iqcor_sync <= 1'b1;
adc_iqcor_valid <= adc_iqcor_data_cnt[1] & adc_iqcor_data_cnt[0];
adc_iqcor_data[63:48] <= adc_iqcor_data_2_s;
adc_iqcor_data[47:32] <= adc_iqcor_data[63:48];
adc_iqcor_data[31:16] <= adc_iqcor_data[47:32];
adc_iqcor_data[15: 0] <= adc_iqcor_data[31:16];
end
4'b0011: begin
adc_iqcor_sync <= 1'b1;
adc_iqcor_valid <= adc_iqcor_data_cnt[0];
adc_iqcor_data[63:48] <= adc_iqcor_data_1_s;
adc_iqcor_data[47:32] <= adc_iqcor_data_0_s;
adc_iqcor_data[31:16] <= adc_iqcor_data[63:48];
adc_iqcor_data[15: 0] <= adc_iqcor_data[47:32];
end
4'b0010: begin
adc_iqcor_sync <= 1'b1;
adc_iqcor_valid <= adc_iqcor_data_cnt[1] & adc_iqcor_data_cnt[0];
adc_iqcor_data[63:48] <= adc_iqcor_data_1_s;
adc_iqcor_data[47:32] <= adc_iqcor_data[63:48];
adc_iqcor_data[31:16] <= adc_iqcor_data[47:32];
adc_iqcor_data[15: 0] <= adc_iqcor_data[31:16];
end
4'b0001: begin
adc_iqcor_sync <= 1'b1;
adc_iqcor_valid <= adc_iqcor_data_cnt[1] & adc_iqcor_data_cnt[0];
adc_iqcor_data[63:48] <= adc_iqcor_data_0_s;
adc_iqcor_data[47:32] <= adc_iqcor_data[63:48];
adc_iqcor_data[31:16] <= adc_iqcor_data[47:32];
adc_iqcor_data[15: 0] <= adc_iqcor_data[31:16];
end
default: begin
adc_iqcor_valid <= 1'b1;
adc_iqcor_data[63:48] <= 16'hdead;
adc_iqcor_data[47:32] <= 16'hdead;
adc_iqcor_data[31:16] <= 16'hdead;
adc_iqcor_data[15: 0] <= 16'hdead;
end
endcase
adc_iqcor_data_cnt <= adc_iqcor_data_cnt + 1'b1;
end else begin
adc_iqcor_valid <= 1'b0;
adc_iqcor_data <= adc_iqcor_data;
adc_iqcor_data_cnt <= adc_iqcor_data_cnt;
end
end
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_adc_status_pn_err <= 'd0;
up_adc_status_pn_oos <= 'd0;
up_adc_status_or <= 'd0;
up_rdata <= 'd0;
up_ack <= 'd0;
end else begin
up_adc_status_pn_err <= up_adc_pn_err_0_s | up_adc_pn_err_1_s |
up_adc_pn_err_2_s | up_adc_pn_err_3_s;
up_adc_status_pn_oos <= up_adc_pn_oos_0_s | up_adc_pn_oos_1_s |
up_adc_pn_oos_2_s | up_adc_pn_oos_3_s;
up_adc_status_or <= up_adc_or_0_s | up_adc_or_1_s |
up_adc_or_2_s | up_adc_or_3_s;
up_rdata <= up_rdata_s | up_rdata_0_s | up_rdata_1_s |
up_rdata_2_s | up_rdata_3_s;
up_ack <= up_ack_s | up_ack_0_s | up_ack_1_s |
up_ack_2_s | up_ack_3_s;
end
end
// channel 0 (i)
axi_ad9361_rx_channel #(
.IQSEL(0),
.CHID(0),
.DP_DISABLE (DP_DISABLE))
i_rx_channel_0 (
.adc_clk (adc_clk),
.adc_rst (adc_rst),
.adc_valid (adc_valid),
.adc_pn_oos_pl (adc_pn_oos_i1),
.adc_pn_err_pl (adc_pn_err_i1),
.adc_data (adc_data_i1),
.adc_data_q (adc_data_q1),
.adc_or (1'b0),
.adc_dcfilter_data_out (adc_dcfilter_data_out_0_s),
.adc_pn_oos_out (adc_pn_oos_out_0_s),
.adc_pn_err_out (adc_pn_err_out_0_s),
.adc_dcfilter_data_in (16'd0),
.adc_pn_oos_in (1'd0),
.adc_pn_err_in (1'd0),
.adc_iqcor_valid (adc_iqcor_valid_0_s),
.adc_iqcor_data (adc_iqcor_data_0_s),
.adc_enable (adc_enable_0_s),
.up_adc_pn_err (up_adc_pn_err_0_s),
.up_adc_pn_oos (up_adc_pn_oos_0_s),
.up_adc_or (up_adc_or_0_s),
.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_0_s),
.up_ack (up_ack_0_s));
// channel 1 (q)
axi_ad9361_rx_channel #(
.IQSEL(1),
.CHID(1),
.DP_DISABLE (DP_DISABLE))
i_rx_channel_1 (
.adc_clk (adc_clk),
.adc_rst (adc_rst),
.adc_valid (adc_valid),
.adc_pn_oos_pl (adc_pn_oos_q1),
.adc_pn_err_pl (adc_pn_err_q1),
.adc_data (adc_data_q1),
.adc_data_q (12'd0),
.adc_or (1'b0),
.adc_dcfilter_data_out (),
.adc_pn_oos_out (),
.adc_pn_err_out (),
.adc_dcfilter_data_in (adc_dcfilter_data_out_0_s),
.adc_pn_oos_in (adc_pn_oos_out_0_s),
.adc_pn_err_in (adc_pn_err_out_0_s),
.adc_iqcor_valid (adc_iqcor_valid_1_s),
.adc_iqcor_data (adc_iqcor_data_1_s),
.adc_enable (adc_enable_1_s),
.up_adc_pn_err (up_adc_pn_err_1_s),
.up_adc_pn_oos (up_adc_pn_oos_1_s),
.up_adc_or (up_adc_or_1_s),
.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_1_s),
.up_ack (up_ack_1_s));
// channel 2 (i)
axi_ad9361_rx_channel #(
.IQSEL(0),
.CHID(2),
.DP_DISABLE (DP_DISABLE))
i_rx_channel_2 (
.adc_clk (adc_clk),
.adc_rst (adc_rst),
.adc_valid (adc_valid),
.adc_pn_oos_pl (adc_pn_oos_i2),
.adc_pn_err_pl (adc_pn_err_i2),
.adc_data (adc_data_i2),
.adc_data_q (adc_data_q2),
.adc_or (1'b0),
.adc_dcfilter_data_out (adc_dcfilter_data_out_2_s),
.adc_pn_oos_out (adc_pn_oos_out_2_s),
.adc_pn_err_out (adc_pn_err_out_2_s),
.adc_dcfilter_data_in (16'd0),
.adc_pn_oos_in (1'd0),
.adc_pn_err_in (1'd0),
.adc_iqcor_valid (adc_iqcor_valid_2_s),
.adc_iqcor_data (adc_iqcor_data_2_s),
.adc_enable (adc_enable_2_s),
.up_adc_pn_err (up_adc_pn_err_2_s),
.up_adc_pn_oos (up_adc_pn_oos_2_s),
.up_adc_or (up_adc_or_2_s),
.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_2_s),
.up_ack (up_ack_2_s));
// channel 3 (q)
axi_ad9361_rx_channel #(
.IQSEL(1),
.CHID(3),
.DP_DISABLE (DP_DISABLE))
i_rx_channel_3 (
.adc_clk (adc_clk),
.adc_rst (adc_rst),
.adc_valid (adc_valid),
.adc_pn_oos_pl (adc_pn_oos_q2),
.adc_pn_err_pl (adc_pn_err_q2),
.adc_data (adc_data_q2),
.adc_data_q (12'd0),
.adc_or (1'b0),
.adc_dcfilter_data_out (),
.adc_pn_oos_out (),
.adc_pn_err_out (),
.adc_dcfilter_data_in (adc_dcfilter_data_out_2_s),
.adc_pn_oos_in (adc_pn_oos_out_2_s),
.adc_pn_err_in (adc_pn_err_out_2_s),
.adc_iqcor_valid (adc_iqcor_valid_3_s),
.adc_iqcor_data (adc_iqcor_data_3_s),
.adc_enable (adc_enable_3_s),
.up_adc_pn_err (up_adc_pn_err_3_s),
.up_adc_pn_oos (up_adc_pn_oos_3_s),
.up_adc_or (up_adc_or_3_s),
.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_3_s),
.up_ack (up_ack_3_s));
// common processor control
up_adc_common #(
.PCORE_ID (PCORE_ID),
.PCORE_VERSION (PCORE_VERSION)
) i_up_adc_common (
.mmcm_rst (),
.adc_clk (adc_clk),
.adc_rst (adc_rst),
.adc_r1_mode (adc_r1_mode),
.adc_ddr_edgesel (),
.adc_pin_mode (),
.adc_status (adc_status),
.adc_status_pn_err (up_adc_status_pn_err),
.adc_status_pn_oos (up_adc_status_pn_oos),
.adc_status_or (up_adc_status_or),
.adc_status_ovf (adc_dovf),
.adc_status_unf (adc_dunf),
.adc_clk_ratio (32'd1),
.delay_clk (delay_clk),
.delay_rst (delay_rst),
.delay_sel (delay_sel),
.delay_rwn (delay_rwn),
.delay_addr (delay_addr),
.delay_wdata (delay_wdata),
.delay_rdata (delay_rdata),
.delay_ack_t (delay_ack_t),
.delay_locked (delay_locked),
.drp_clk (1'd0),
.drp_rst (),
.drp_sel (),
.drp_wr (),
.drp_addr (),
.drp_wdata (),
.drp_rdata (16'd0),
.drp_ready (1'd0),
.drp_locked (1'd1),
.up_usr_chanmax (),
.adc_usr_chanmax (8'd3),
.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_s),
.up_ack (up_ack_s));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,267 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ADC channel-need to work on dual mode for pn sequence
`timescale 1ns/100ps
module axi_ad9361_rx_channel (
// adc interface
adc_clk,
adc_rst,
adc_valid,
adc_pn_oos_pl,
adc_pn_err_pl,
adc_data,
adc_data_q,
adc_or,
// channel interface
adc_dcfilter_data_out,
adc_pn_oos_out,
adc_pn_err_out,
adc_dcfilter_data_in,
adc_pn_oos_in,
adc_pn_err_in,
adc_iqcor_valid,
adc_iqcor_data,
adc_enable,
up_adc_pn_err,
up_adc_pn_oos,
up_adc_or,
// processor interface
up_rstn,
up_clk,
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack);
// parameters
parameter IQSEL = 0;
parameter CHID = 0;
parameter DP_DISABLE = 0;
// adc interface
input adc_clk;
input adc_rst;
input adc_valid;
input adc_pn_oos_pl;
input adc_pn_err_pl;
input [11:0] adc_data;
input [11:0] adc_data_q;
input adc_or;
// channel interface
output [15:0] adc_dcfilter_data_out;
output adc_pn_oos_out;
output adc_pn_err_out;
input [15:0] adc_dcfilter_data_in;
input adc_pn_oos_in;
input adc_pn_err_in;
output adc_iqcor_valid;
output [15:0] adc_iqcor_data;
output adc_enable;
output up_adc_pn_err;
output up_adc_pn_oos;
output up_adc_or;
// processor interface
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;
// internal signals
wire adc_dfmt_valid_s;
wire [15:0] adc_dfmt_data_s;
wire adc_dcfilter_valid_s;
wire [15:0] adc_dcfilter_data_i_s;
wire [15:0] adc_dcfilter_data_q_s;
wire adc_pn_sel_s;
wire adc_iqcor_enb_s;
wire adc_dcfilt_enb_s;
wire adc_dfmt_se_s;
wire adc_dfmt_type_s;
wire adc_dfmt_enable_s;
wire [15:0] adc_dcfilt_offset_s;
wire [15:0] adc_dcfilt_coeff_s;
wire [15:0] adc_iqcor_coeff_1_s;
wire [15:0] adc_iqcor_coeff_2_s;
wire adc_pn_err_s;
wire adc_pn_oos_s;
// iq correction inputs
assign adc_dcfilter_data_i_s = (IQSEL == 1) ? adc_dcfilter_data_in : adc_dcfilter_data_out;
assign adc_dcfilter_data_q_s = (IQSEL == 1) ? adc_dcfilter_data_out : adc_dcfilter_data_in;
assign adc_pn_oos_s = (adc_pn_sel_s == 1'b1) ? adc_pn_oos_pl : ((IQSEL == 1) ? adc_pn_oos_in : adc_pn_oos_out);
assign adc_pn_err_s = (adc_pn_sel_s == 1'b1) ? adc_pn_err_pl : ((IQSEL == 1) ? adc_pn_err_in : adc_pn_err_out);
generate
if (IQSEL == 1) begin
assign adc_pn_oos_out = 1'b1;
assign adc_pn_err_out = 1'b1;
end else begin
axi_ad9361_rx_pnmon i_rx_pnmon (
.adc_clk (adc_clk),
.adc_valid (adc_valid),
.adc_data_i (adc_data),
.adc_data_q (adc_data_q),
.adc_pn_oos (adc_pn_oos_out),
.adc_pn_err (adc_pn_err_out));
end
endgenerate
generate
if (DP_DISABLE == 1) begin
assign adc_dfmt_valid_s = adc_valid;
assign adc_dfmt_data_s = {4'd0, adc_data};
end else begin
ad_datafmt #(.DATA_WIDTH(12)) i_ad_datafmt (
.clk (adc_clk),
.valid (adc_valid),
.data (adc_data),
.valid_out (adc_dfmt_valid_s),
.data_out (adc_dfmt_data_s),
.dfmt_enable (adc_dfmt_enable_s),
.dfmt_type (adc_dfmt_type_s),
.dfmt_se (adc_dfmt_se_s));
end
endgenerate
generate
if (DP_DISABLE == 1) begin
assign adc_dcfilter_valid_s = adc_dfmt_valid_s;
assign adc_dcfilter_data_out = adc_dfmt_data_s;
end else begin
ad_dcfilter i_ad_dcfilter (
.clk (adc_clk),
.valid (adc_dfmt_valid_s),
.data (adc_dfmt_data_s),
.valid_out (adc_dcfilter_valid_s),
.data_out (adc_dcfilter_data_out),
.dcfilt_enb (adc_dcfilt_enb_s),
.dcfilt_coeff (adc_dcfilt_coeff_s),
.dcfilt_offset (adc_dcfilt_offset_s));
end
endgenerate
generate
if (DP_DISABLE == 1) begin
assign adc_iqcor_valid = adc_dcfilter_valid_s;
assign adc_iqcor_data = (IQSEL == 1) ? adc_dcfilter_data_q_s : adc_dcfilter_data_i_s;
end else begin
ad_iqcor #(.IQSEL(IQSEL)) i_ad_iqcor (
.clk (adc_clk),
.valid (adc_dcfilter_valid_s),
.data_i (adc_dcfilter_data_i_s),
.data_q (adc_dcfilter_data_q_s),
.valid_out (adc_iqcor_valid),
.data_out (adc_iqcor_data),
.iqcor_enable (adc_iqcor_enb_s),
.iqcor_coeff_1 (adc_iqcor_coeff_1_s),
.iqcor_coeff_2 (adc_iqcor_coeff_2_s));
end
endgenerate
up_adc_channel #(.PCORE_ADC_CHID(CHID)) i_up_adc_channel (
.adc_clk (adc_clk),
.adc_rst (adc_rst),
.adc_enable (adc_enable),
.adc_pn_sel (adc_pn_sel_s),
.adc_iqcor_enb (adc_iqcor_enb_s),
.adc_dcfilt_enb (adc_dcfilt_enb_s),
.adc_dfmt_se (adc_dfmt_se_s),
.adc_dfmt_type (adc_dfmt_type_s),
.adc_dfmt_enable (adc_dfmt_enable_s),
.adc_pn_type (),
.adc_dcfilt_offset (adc_dcfilt_offset_s),
.adc_dcfilt_coeff (adc_dcfilt_coeff_s),
.adc_iqcor_coeff_1 (adc_iqcor_coeff_1_s),
.adc_iqcor_coeff_2 (adc_iqcor_coeff_2_s),
.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
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,185 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// PN monitors
`timescale 1ns/100ps
module axi_ad9361_rx_pnmon (
// adc interface
adc_clk,
adc_valid,
adc_data_i,
adc_data_q,
// pn out of sync and error
adc_pn_oos,
adc_pn_err);
// adc interface
input adc_clk;
input adc_valid;
input [11:0] adc_data_i;
input [11:0] adc_data_q;
// pn out of sync and error
output adc_pn_oos;
output adc_pn_err;
// internal registers
reg [15:0] adc_data = 'd0;
reg [15:0] adc_pn_data = 'd0;
reg adc_valid_d = 'd0;
reg adc_iq_match = 'd0;
reg adc_pn_match_d = 'd0;
reg adc_pn_match_z = 'd0;
reg adc_pn_err = 'd0;
reg [ 6:0] adc_pn_oos_count = 'd0;
reg adc_pn_oos = 'd0;
// internal signals
wire [11:0] adc_data_i_s;
wire [11:0] adc_data_q_s;
wire [11:0] adc_data_q_rev_s;
wire [15:0] adc_data_s;
wire adc_iq_match_s;
wire [15:0] adc_pn_data_s;
wire adc_pn_match_d_s;
wire adc_pn_match_z_s;
wire adc_pn_match_s;
wire adc_pn_update_s;
wire adc_pn_err_s;
// prbs function
function [15:0] pnfn;
input [15:0] din;
reg [15:0] dout;
begin
dout = {din[14:0], ~((^din[15:4]) ^ (^din[2:1]))};
pnfn = dout;
end
endfunction
// bit reversal function
function [11:0] brfn;
input [11:0] din;
reg [11:0] dout;
begin
dout[11] = din[ 0];
dout[10] = din[ 1];
dout[ 9] = din[ 2];
dout[ 8] = din[ 3];
dout[ 7] = din[ 4];
dout[ 6] = din[ 5];
dout[ 5] = din[ 6];
dout[ 4] = din[ 7];
dout[ 3] = din[ 8];
dout[ 2] = din[ 9];
dout[ 1] = din[10];
dout[ 0] = din[11];
brfn = dout;
end
endfunction
// assuming lower nibble is lost-
assign adc_data_i_s = ~adc_data_i;
assign adc_data_q_s = ~adc_data_q;
assign adc_data_q_rev_s = brfn(adc_data_q_s);
assign adc_data_s = {adc_data_i_s, adc_data_q_rev_s[3:0]};
assign adc_iq_match_s = (adc_data_i_s[7:0] == adc_data_q_rev_s[11:4]) ? 1'b1 : 1'b0;
// pn sequence checking algorithm is commonly used in most applications.
// if oos is asserted (pn is out of sync):
// next sequence is generated from the incoming data.
// if 64 sequences match consecutively, oos is cleared (de-asserted).
// if oos is de-asserted (pn is in sync)
// 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_s = (adc_pn_oos == 1'b1) ? adc_data_s : adc_pn_data;
assign adc_pn_match_d_s = (adc_data_s == adc_pn_data) ? 1'b1 : 1'b0;
assign adc_pn_match_z_s = (adc_data_s == adc_data) ? 1'b0 : 1'b1;
assign adc_pn_match_s = adc_iq_match & adc_pn_match_d & adc_pn_match_z;
assign adc_pn_update_s = ~(adc_pn_oos ^ adc_pn_match_s);
assign adc_pn_err_s = ~(adc_pn_oos | adc_pn_match_s);
// pn oos and counters (64 to clear and set).
always @(posedge adc_clk) begin
if (adc_valid == 1'b1) begin
adc_data <= adc_data_s;
adc_pn_data <= pnfn(adc_pn_data_s);
end
adc_valid_d <= adc_valid;
adc_iq_match <= adc_iq_match_s;
adc_pn_match_d <= adc_pn_match_d_s;
adc_pn_match_z <= adc_pn_match_z_s;
if (adc_valid_d == 1'b1) begin
adc_pn_err <= adc_pn_err_s;
if (adc_pn_update_s == 1'b1) begin
if (adc_pn_oos_count >= 16) begin
adc_pn_oos_count <= 'd0;
adc_pn_oos <= ~adc_pn_oos;
end else begin
adc_pn_oos_count <= adc_pn_oos_count + 1'b1;
adc_pn_oos <= adc_pn_oos;
end
end else begin
adc_pn_oos_count <= 'd0;
adc_pn_oos <= adc_pn_oos;
end
end
end
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,394 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module axi_ad9361_tx (
// dac interface
dac_clk,
dac_valid,
dac_lb_enb_i1,
dac_pn_enb_i1,
dac_data_i1,
dac_lb_enb_q1,
dac_pn_enb_q1,
dac_data_q1,
dac_lb_enb_i2,
dac_pn_enb_i2,
dac_data_i2,
dac_lb_enb_q2,
dac_pn_enb_q2,
dac_data_q2,
dac_r1_mode,
// dma interface
dac_drd,
dac_ddata,
dac_dovf,
dac_dunf,
// processor interface
up_rstn,
up_clk,
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack);
// parameters
parameter DP_DISABLE = 0;
parameter PCORE_ID = 0;
parameter PCORE_VERSION = 32'h00060061;
// dac interface
input dac_clk;
output dac_valid;
output dac_lb_enb_i1;
output dac_pn_enb_i1;
output [11:0] dac_data_i1;
output dac_lb_enb_q1;
output dac_pn_enb_q1;
output [11:0] dac_data_q1;
output dac_lb_enb_i2;
output dac_pn_enb_i2;
output [11:0] dac_data_i2;
output dac_lb_enb_q2;
output dac_pn_enb_q2;
output [11:0] dac_data_q2;
output dac_r1_mode;
// dma interface
output dac_drd;
input [63:0] dac_ddata;
input dac_dovf;
input dac_dunf;
// processor interface
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;
// internal registers
reg [ 7:0] dac_rate_cnt = 'd0;
reg dac_dds_enable = 'd0;
reg dac_dds_data_enable = 'd0;
reg dac_dds_data_enable_toggle = 'd0;
reg dac_drd = 'd0;
reg [63:0] dac_dma_data = 'd0;
reg [15:0] dac_dma_data_0 = 'd0;
reg [15:0] dac_dma_data_1 = 'd0;
reg [15:0] dac_dma_data_2 = 'd0;
reg [15:0] dac_dma_data_3 = 'd0;
reg dac_valid = 'd0;
reg [11:0] dac_data_i1 = 'd0;
reg [11:0] dac_data_q1 = 'd0;
reg [11:0] dac_data_i2 = 'd0;
reg [11:0] dac_data_q2 = 'd0;
reg [31:0] up_rdata = 'd0;
reg up_ack = 'd0;
// internal clock and resets
wire dac_rst;
// internal signals
wire dac_enable_s;
wire dac_datafmt_s;
wire [ 3:0] dac_datasel_s;
wire [ 7:0] dac_datarate_s;
wire [15:0] dac_dds_data_0_s;
wire [15:0] dac_dds_data_1_s;
wire [15:0] dac_dds_data_2_s;
wire [15:0] dac_dds_data_3_s;
wire [31:0] up_rdata_0_s;
wire up_ack_0_s;
wire [31:0] up_rdata_1_s;
wire up_ack_1_s;
wire [31:0] up_rdata_2_s;
wire up_ack_2_s;
wire [31:0] up_rdata_3_s;
wire up_ack_3_s;
wire [31:0] up_rdata_s;
wire up_ack_s;
// dds rate counters, dds phases are updated using data enables
always @(posedge dac_clk) begin
if ((dac_enable_s == 1'b0) || (dac_rate_cnt == 8'd0)) begin
dac_rate_cnt <= dac_datarate_s;
end else begin
dac_rate_cnt <= dac_rate_cnt - 1'b1;
end
dac_dds_enable <= dac_enable_s;
if (dac_rate_cnt == 8'd0) begin
dac_dds_data_enable <= 1'b1;
end else begin
dac_dds_data_enable <= 1'b0;
end
end
// dma interface
always @(posedge dac_clk) begin
if (dac_dds_data_enable == 1'b1) begin
dac_dds_data_enable_toggle <= ~dac_dds_data_enable_toggle;
end
if (dac_r1_mode == 1'b1) begin
dac_drd <= dac_dds_data_enable & dac_dds_data_enable_toggle;
end else begin
dac_drd <= dac_dds_data_enable;
end
if (dac_drd == 1'b1) begin
dac_dma_data <= dac_ddata;
end
if (dac_dds_data_enable == 1'b1) begin
if (dac_r1_mode == 1'b0) begin
dac_dma_data_0 <= dac_dma_data[15: 0];
dac_dma_data_1 <= dac_dma_data[31:16];
dac_dma_data_2 <= dac_dma_data[47:32];
dac_dma_data_3 <= dac_dma_data[63:48];
end else if (dac_dds_data_enable_toggle == 1'b1) begin
dac_dma_data_0 <= dac_dma_data[47:32];
dac_dma_data_1 <= dac_dma_data[63:48];
dac_dma_data_2 <= 16'd0;
dac_dma_data_3 <= 16'd0;
end else begin
dac_dma_data_0 <= dac_dma_data[15: 0];
dac_dma_data_1 <= dac_dma_data[31:16];
dac_dma_data_2 <= 16'd0;
dac_dma_data_3 <= 16'd0;
end
end
end
// dac outputs
always @(posedge dac_clk) begin
dac_valid <= dac_dds_data_enable;
if (dac_datasel_s[3:1] == 3'd1) begin
dac_data_i1 <= dac_dma_data_0[15:4];
dac_data_q1 <= dac_dma_data_1[15:4];
dac_data_i2 <= dac_dma_data_2[15:4];
dac_data_q2 <= dac_dma_data_3[15:4];
end else begin
dac_data_i1 <= dac_dds_data_0_s[15:4];
dac_data_q1 <= dac_dds_data_1_s[15:4];
dac_data_i2 <= dac_dds_data_2_s[15:4];
dac_data_q2 <= dac_dds_data_3_s[15:4];
end
end
// processor read interface
always @(negedge up_rstn or posedge up_clk) begin
if (up_rstn == 0) begin
up_rdata <= 'd0;
up_ack <= 'd0;
end else begin
up_rdata <= up_rdata_s |
up_rdata_0_s |
up_rdata_1_s |
up_rdata_2_s |
up_rdata_3_s;
up_ack <= up_ack_s |
up_ack_0_s |
up_ack_1_s |
up_ack_2_s |
up_ack_3_s;
end
end
// dac channel
axi_ad9361_tx_channel #(
.CHID(0),
.DP_DISABLE (DP_DISABLE))
i_tx_channel_0 (
.dac_clk (dac_clk),
.dac_rst (dac_rst),
.dac_dds_data (dac_dds_data_0_s),
.dac_dds_enable (dac_dds_enable),
.dac_dds_data_enable (dac_dds_data_enable),
.dac_dds_format (dac_datafmt_s),
.dac_dds_pattenb (dac_datasel_s[0]),
.dac_lb_enb (dac_lb_enb_i1),
.dac_pn_enb (dac_pn_enb_i1),
.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_0_s),
.up_ack (up_ack_0_s));
// dac channel
axi_ad9361_tx_channel #(
.CHID(1),
.DP_DISABLE (DP_DISABLE))
i_tx_channel_1 (
.dac_clk (dac_clk),
.dac_rst (dac_rst),
.dac_dds_data (dac_dds_data_1_s),
.dac_dds_enable (dac_dds_enable),
.dac_dds_data_enable (dac_dds_data_enable),
.dac_dds_format (dac_datafmt_s),
.dac_dds_pattenb (dac_datasel_s[0]),
.dac_lb_enb (dac_lb_enb_q1),
.dac_pn_enb (dac_pn_enb_q1),
.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_1_s),
.up_ack (up_ack_1_s));
// dac channel
axi_ad9361_tx_channel #(
.CHID(2),
.DP_DISABLE (DP_DISABLE))
i_tx_channel_2 (
.dac_clk (dac_clk),
.dac_rst (dac_rst),
.dac_dds_data (dac_dds_data_2_s),
.dac_dds_enable (dac_dds_enable),
.dac_dds_data_enable (dac_dds_data_enable),
.dac_dds_format (dac_datafmt_s),
.dac_dds_pattenb (dac_datasel_s[0]),
.dac_lb_enb (dac_lb_enb_i2),
.dac_pn_enb (dac_pn_enb_i2),
.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_2_s),
.up_ack (up_ack_2_s));
// dac channel
axi_ad9361_tx_channel #(
.CHID(3),
.DP_DISABLE (DP_DISABLE))
i_tx_channel_3 (
.dac_clk (dac_clk),
.dac_rst (dac_rst),
.dac_dds_data (dac_dds_data_3_s),
.dac_dds_enable (dac_dds_enable),
.dac_dds_data_enable (dac_dds_data_enable),
.dac_dds_format (dac_datafmt_s),
.dac_dds_pattenb (dac_datasel_s[0]),
.dac_lb_enb (dac_lb_enb_q2),
.dac_pn_enb (dac_pn_enb_q2),
.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_3_s),
.up_ack (up_ack_3_s));
// dac common processor interface
up_dac_common #(
.PCORE_ID (PCORE_ID),
.PCORE_VERSION (PCORE_VERSION)
) i_up_dac_common (
.mmcm_rst (),
.dac_clk (dac_clk),
.dac_rst (dac_rst),
.dac_enable (dac_enable_s),
.dac_frame (),
.dac_par_type (),
.dac_par_enb (),
.dac_r1_mode (dac_r1_mode),
.dac_datafmt (dac_datafmt_s),
.dac_datasel (dac_datasel_s),
.dac_datarate (dac_datarate_s),
.dac_status (1'b1),
.dac_status_ovf (dac_dovf),
.dac_status_unf (dac_dunf),
.dac_clk_ratio (32'd1),
.drp_clk (1'b0),
.drp_rst (),
.drp_sel (),
.drp_wr (),
.drp_addr (),
.drp_wdata (),
.drp_rdata (16'd0),
.drp_ready (1'd0),
.drp_locked (1'd1),
.up_usr_chanmax (),
.dac_usr_chanmax (8'd3),
.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_s),
.up_ack (up_ack_s));
endmodule
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,173 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module axi_ad9361_tx_channel (
// dac interface
dac_clk,
dac_rst,
dac_dds_data,
// processor interface
dac_dds_enable,
dac_dds_data_enable,
dac_dds_format,
dac_dds_pattenb,
dac_lb_enb,
dac_pn_enb,
// bus interface
up_rstn,
up_clk,
up_sel,
up_wr,
up_addr,
up_wdata,
up_rdata,
up_ack);
// parameters
parameter CHID = 32'h0;
parameter DP_DISABLE = 0;
// dac interface
input dac_clk;
input dac_rst;
output [15:0] dac_dds_data;
// processor interface
input dac_dds_enable;
input dac_dds_data_enable;
input dac_dds_format;
input dac_dds_pattenb;
output dac_lb_enb;
output dac_pn_enb;
// bus interface
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;
// internal signals
wire [15:0] dac_dds_patt_1_s;
wire [15:0] dac_dds_init_1_s;
wire [15:0] dac_dds_incr_1_s;
wire [15:0] dac_dds_scale_1_s;
wire [15:0] dac_dds_patt_2_s;
wire [15:0] dac_dds_init_2_s;
wire [15:0] dac_dds_incr_2_s;
wire [15:0] dac_dds_scale_2_s;
// single channel dds
axi_ad9361_tx_dds #(.DP_DISABLE(DP_DISABLE)) i_tx_dds (
.dac_clk (dac_clk),
.dac_rst (dac_rst),
.dac_dds_data (dac_dds_data),
.dac_dds_enable (dac_dds_enable),
.dac_dds_data_enable (dac_dds_data_enable),
.dac_dds_format (dac_dds_format),
.dac_dds_pattenb (dac_dds_pattenb),
.dac_dds_patt_1 (dac_dds_patt_1_s),
.dac_dds_init_1 (dac_dds_init_1_s),
.dac_dds_incr_1 (dac_dds_incr_1_s),
.dac_dds_scale_1 (dac_dds_scale_1_s),
.dac_dds_patt_2 (dac_dds_patt_2_s),
.dac_dds_init_2 (dac_dds_init_2_s),
.dac_dds_incr_2 (dac_dds_incr_2_s),
.dac_dds_scale_2 (dac_dds_scale_2_s));
// single channel processor
up_dac_channel #(.PCORE_DAC_CHID(CHID)) i_up_dac_channel (
.dac_clk (dac_clk),
.dac_rst (dac_rst),
.dac_dds_scale_1 (dac_dds_scale_1_s),
.dac_dds_init_1 (dac_dds_init_1_s),
.dac_dds_incr_1 (dac_dds_incr_1_s),
.dac_dds_scale_2 (dac_dds_scale_2_s),
.dac_dds_init_2 (dac_dds_init_2_s),
.dac_dds_incr_2 (dac_dds_incr_2_s),
.dac_dds_patt_1 (dac_dds_patt_1_s),
.dac_dds_patt_2 (dac_dds_patt_2_s),
.dac_dds_sel (),
.dac_lb_enb (dac_lb_enb),
.dac_pn_enb (dac_pn_enb),
.up_usr_datatype_be (),
.up_usr_datatype_signed (),
.up_usr_datatype_shift (),
.up_usr_datatype_total_bits (),
.up_usr_datatype_bits (),
.up_usr_interpolation_m (),
.up_usr_interpolation_n (),
.dac_usr_datatype_be (1'b0),
.dac_usr_datatype_signed (1'b1),
.dac_usr_datatype_shift (8'd0),
.dac_usr_datatype_total_bits (8'd16),
.dac_usr_datatype_bits (8'd16),
.dac_usr_interpolation_m (16'd1),
.dac_usr_interpolation_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
// ***************************************************************************
// ***************************************************************************

View File

@ -0,0 +1,148 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2011(c) Analog Devices, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
// - Neither the name of Analog Devices, Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
// - The use of this software may or may not infringe the patent rights
// of one or more patent holders. This license does not release you
// from the requirement that you obtain separate licenses from these
// patent holders to use this software.
// - Use of the software either in source or binary form, must be run
// on or directly connected to an Analog Devices Inc. component.
//
// THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.
//
// IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, INTELLECTUAL PROPERTY
// RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
`timescale 1ns/100ps
module axi_ad9361_tx_dds (
// dac interface
dac_clk,
dac_rst,
dac_dds_data,
// processor interface
dac_dds_enable,
dac_dds_data_enable,
dac_dds_format,
dac_dds_pattenb,
dac_dds_patt_1,
dac_dds_init_1,
dac_dds_incr_1,
dac_dds_scale_1,
dac_dds_patt_2,
dac_dds_init_2,
dac_dds_incr_2,
dac_dds_scale_2);
// parameters
parameter DP_DISABLE = 0;
// dac interface
input dac_clk;
input dac_rst;
output [15:0] dac_dds_data;
// processor interface
input dac_dds_enable;
input dac_dds_data_enable;
input dac_dds_format;
input dac_dds_pattenb;
input [15:0] dac_dds_patt_1;
input [15:0] dac_dds_init_1;
input [15:0] dac_dds_incr_1;
input [15:0] dac_dds_scale_1;
input [15:0] dac_dds_patt_2;
input [15:0] dac_dds_init_2;
input [15:0] dac_dds_incr_2;
input [15:0] dac_dds_scale_2;
// internal registers
reg [15:0] dac_dds_phase_0 = 'd0;
reg [15:0] dac_dds_phase_1 = 'd0;
reg dac_dds_datasel = 'd0;
reg [15:0] dac_dds_data = 'd0;
// internal signals
wire [15:0] dac_dds_data_s;
// dds phase counters
always @(posedge dac_clk) begin
if (dac_dds_enable == 1'b0) begin
dac_dds_phase_0 <= dac_dds_init_1;
dac_dds_phase_1 <= dac_dds_init_2;
end else if (dac_dds_data_enable == 1'b1) begin
dac_dds_phase_0 <= dac_dds_phase_0 + dac_dds_incr_1;
dac_dds_phase_1 <= dac_dds_phase_1 + dac_dds_incr_2;
end
end
// output is either 2's complement or offset binary.
always @(posedge dac_clk) begin
if (dac_dds_data_enable == 1'b1) begin
dac_dds_datasel <= ~dac_dds_datasel;
if (dac_dds_pattenb == 1'b0) begin
dac_dds_data <= dac_dds_data_s;
end else if (dac_dds_datasel == 1'b1) begin
dac_dds_data <= dac_dds_patt_2;
end else begin
dac_dds_data <= dac_dds_patt_1;
end
end
end
// dds
generate
if (DP_DISABLE == 1) begin
assign dac_dds_data_s = 16'd0;
end else begin
ad_dds i_dds_0 (
.clk (dac_clk),
.dds_format (dac_dds_format),
.dds_phase_0 (dac_dds_phase_0),
.dds_scale_0 (dac_dds_scale_1),
.dds_phase_1 (dac_dds_phase_1),
.dds_scale_1 (dac_dds_scale_2),
.dds_data (dac_dds_data_s));
end
endgenerate
endmodule
// ***************************************************************************
// ***************************************************************************