diff --git a/library/axi_ad9361/axi_ad9361.v b/library/axi_ad9361/axi_ad9361.v index 4059f990b..e25044443 100755 --- a/library/axi_ad9361/axi_ad9361.v +++ b/library/axi_ad9361/axi_ad9361.v @@ -49,6 +49,10 @@ module axi_ad9361 ( rx_frame_in_n, rx_data_in_p, rx_data_in_n, + + // receive master/slave + adc_start_in, + adc_start_out, // physical interface (transmit) @@ -58,6 +62,11 @@ module axi_ad9361 ( tx_frame_out_n, tx_data_out_p, tx_data_out_n, + + // transmit master/slave + + dac_enable_in, + dac_enable_out, // delay clock @@ -124,6 +133,10 @@ module axi_ad9361 ( input rx_frame_in_n; input [ 5:0] rx_data_in_p; input [ 5:0] rx_data_in_n; + + // receive master/slave + input adc_start_in; + output adc_start_out; // physical interface (transmit) @@ -133,6 +146,10 @@ module axi_ad9361 ( output tx_frame_out_n; output [ 5:0] tx_data_out_p; output [ 5:0] tx_data_out_n; + + // transmit master/slave + input dac_enable_in; + output dac_enable_out; // delay clock @@ -263,7 +280,8 @@ module axi_ad9361 ( axi_ad9361_dev_if #( .PCORE_BUFTYPE (PCORE_BUFTYPE), - .PCORE_IODELAY_GROUP (PCORE_IODELAY_GROUP)) + .PCORE_IODELAY_GROUP (PCORE_IODELAY_GROUP), + .PCORE_ID(PCORE_ID)) i_dev_if ( .rx_clk_in_p (rx_clk_in_p), .rx_clk_in_n (rx_clk_in_n), @@ -278,6 +296,8 @@ module axi_ad9361 ( .tx_data_out_p (tx_data_out_p), .tx_data_out_n (tx_data_out_n), .clk (clk), + .adc_start_in (adc_start_in), + .adc_start_out (adc_start_out), .adc_valid (adc_valid_s), .adc_data_i1 (adc_data_i1_s), .adc_data_q1 (adc_data_q1_s), @@ -409,6 +429,8 @@ module axi_ad9361 ( .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_enable_in (dac_enable_in), + .dac_enable_out (dac_enable_out), .dac_drd (dac_drd), .dac_ddata (dac_ddata), .dac_dovf (dac_dovf), diff --git a/library/axi_ad9361/axi_ad9361_dev_if.v b/library/axi_ad9361/axi_ad9361_dev_if.v index 3aebdb9d5..f53c53636 100755 --- a/library/axi_ad9361/axi_ad9361_dev_if.v +++ b/library/axi_ad9361/axi_ad9361_dev_if.v @@ -74,6 +74,10 @@ module axi_ad9361_dev_if ( adc_data_q2, adc_status, adc_r1_mode, + + // receive master/slave + adc_start_in, + adc_start_out, // transmit data path interface @@ -105,6 +109,7 @@ module axi_ad9361_dev_if ( parameter PCORE_BUFTYPE = 0; parameter PCORE_IODELAY_GROUP = "dev_if_delay_group"; + parameter PCORE_ID = 0; localparam PCORE_7SERIES = 0; localparam PCORE_VIRTEX6 = 1; @@ -139,6 +144,10 @@ module axi_ad9361_dev_if ( output [11:0] adc_data_q2; output adc_status; input adc_r1_mode; + + // receive master/slave + input adc_start_in; + output adc_start_out; // transmit data path interface @@ -168,6 +177,7 @@ module axi_ad9361_dev_if ( // internal registers + reg adc_start_out; reg [ 5:0] rx_data_n = 'd0; reg rx_frame_n = 'd0; reg [11:0] rx_data = 'd0; @@ -204,6 +214,7 @@ module axi_ad9361_dev_if ( // internal signals + wire adc_start_s; wire [ 3:0] rx_frame_s; wire [ 3:0] tx_data_sel_s; wire [ 4:0] delay_rdata_s[6:0]; @@ -273,6 +284,13 @@ module axi_ad9361_dev_if ( assign dev_dbg_data[285:274] = adc_data_i2; assign dev_dbg_data[297:286] = adc_data_q2; + // multiple instances synchronization + assign adc_start_s = (PCORE_ID == 32'd0) ? adc_start_out : adc_start_in; + + always @(posedge clk) begin + adc_start_out <= 1'b1; + end + // receive data path interface assign rx_frame_s = {rx_frame_d, rx_frame}; @@ -317,14 +335,14 @@ module axi_ad9361_dev_if ( always @(posedge clk) begin if (adc_r1_mode == 1'b1) begin - adc_valid <= rx_valid_r1; + adc_valid <= rx_valid_r1 & adc_start_s; 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_valid <= rx_valid_r2 & adc_start_s; adc_data_i1 <= rx_data_i1_r2; adc_data_q1 <= rx_data_q1_r2; adc_data_i2 <= rx_data_i2_r2; diff --git a/library/axi_ad9361/axi_ad9361_tx.v b/library/axi_ad9361/axi_ad9361_tx.v index 5eea65761..0be0330ca 100755 --- a/library/axi_ad9361/axi_ad9361_tx.v +++ b/library/axi_ad9361/axi_ad9361_tx.v @@ -58,6 +58,10 @@ module axi_ad9361_tx ( dac_pn_enb_q2, dac_data_q2, dac_r1_mode, + + // transmit master/slave + dac_enable_in, + dac_enable_out, // dma interface @@ -99,6 +103,10 @@ module axi_ad9361_tx ( output dac_pn_enb_q2; output [11:0] dac_data_q2; output dac_r1_mode; + + // transmit master/slave + input dac_enable_in; + output dac_enable_out; // dma interface @@ -120,6 +128,7 @@ module axi_ad9361_tx ( // internal registers + reg dac_enable = 'd0; reg [ 7:0] dac_rate_cnt = 'd0; reg dac_dds_enable = 'd0; reg dac_dds_data_enable = 'd0; @@ -163,6 +172,13 @@ module axi_ad9361_tx ( wire [31:0] up_rdata_s; wire up_ack_s; + // master/slave + assign dac_enable_s = (PCORE_ID == 0) ? dac_enable_out : dac_enable_in; + + always @(posedge dac_clk) begin + dac_enable <= dac_enable_s; + end + // dds rate counters, dds phases are updated using data enables always @(posedge dac_clk) begin @@ -186,9 +202,9 @@ module axi_ad9361_tx ( 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; + dac_drd <= dac_dds_data_enable & dac_dds_data_enable_toggle & dac_enable; end else begin - dac_drd <= dac_dds_data_enable; + dac_drd <= dac_dds_data_enable & dac_enable; end if (dac_drd == 1'b1) begin dac_dma_data <= dac_ddata; @@ -352,7 +368,7 @@ module axi_ad9361_tx ( .mmcm_rst (), .dac_clk (dac_clk), .dac_rst (dac_rst), - .dac_enable (dac_enable_s), + .dac_enable (dac_enable_out), .dac_frame (), .dac_par_type (), .dac_par_enb (), diff --git a/projects/fmcomms2/common/fmcomms2_bd.tcl b/projects/fmcomms2/common/fmcomms2_bd.tcl index 8c04db27d..c6821c9da 100755 --- a/projects/fmcomms2/common/fmcomms2_bd.tcl +++ b/projects/fmcomms2/common/fmcomms2_bd.tcl @@ -32,6 +32,7 @@ # ad9361 core set axi_ad9361 [create_bd_cell -type ip -vlnv analog.com:user:axi_ad9361:1.0 axi_ad9361] + set_property -dict [list CONFIG.PCORE_ID {0}] $axi_ad9361 set axi_ad9361_dac_dma [create_bd_cell -type ip -vlnv analog.com:user:axi_dmac:1.0 axi_ad9361_dac_dma] set_property -dict [list CONFIG.C_DMA_TYPE_SRC {0}] $axi_ad9361_dac_dma