diff --git a/library/axi_ad9361/altera/axi_ad9361_cmos_if.v b/library/axi_ad9361/altera/axi_ad9361_cmos_if.v index ff96bedfd..3337cf97a 100644 --- a/library/axi_ad9361/altera/axi_ad9361_cmos_if.v +++ b/library/axi_ad9361/altera/axi_ad9361_cmos_if.v @@ -54,9 +54,9 @@ module axi_ad9361_cmos_if #( // receive data path interface - output reg adc_valid, - output reg [47:0] adc_data, - output reg adc_status, + output adc_valid, + output [47:0] adc_data, + output adc_status, input adc_r1_mode, input adc_ddr_edgesel, @@ -89,408 +89,20 @@ module axi_ad9361_cmos_if #( input delay_rst, output delay_locked); + // cmos is not supported on altera platforms yet. - // internal registers - - reg [ 1:0] rx_frame = 0; - reg [11:0] rx_data_p = 0; - reg rx_error_r1 = 'd0; - reg rx_valid_r1 = 'd0; - reg [23:0] rx_data_r1 = 'd0; - reg rx_error_r2 = 'd0; - reg rx_valid_r2 = 'd0; - reg [47:0] rx_data_r2 = 'd0; - reg adc_p_valid = 'd0; - reg [47:0] adc_p_data = 'd0; - reg adc_p_status = 'd0; - reg adc_n_valid = 'd0; - reg [47:0] adc_n_data = 'd0; - reg adc_n_status = 'd0; - reg adc_valid_int = 'd0; - reg [47:0] adc_data_int = 'd0; - reg adc_status_int = 'd0; - reg [ 1:0] tx_data_cnt = 'd0; - reg [47:0] tx_data = 'd0; - reg tx_frame_p = 'd0; - reg tx_frame_n = 'd0; - reg [11:0] tx_data_p = 'd0; - reg [11:0] tx_data_n = 'd0; - reg tx_n_frame_p = 'd0; - reg tx_n_frame_n = 'd0; - reg [11:0] tx_n_data_p = 'd0; - reg [11:0] tx_n_data_n = 'd0; - reg tx_p_frame_p = 'd0; - reg tx_p_frame_n = 'd0; - reg [11:0] tx_p_data_p = 'd0; - reg [11:0] tx_p_data_n = 'd0; - reg up_enable_int = 'd0; - reg up_txnrx_int = 'd0; - reg enable_up_m1 = 'd0; - reg txnrx_up_m1 = 'd0; - reg enable_up = 'd0; - reg txnrx_up = 'd0; - reg enable_int = 'd0; - reg txnrx_int = 'd0; - reg enable_n_int = 'd0; - reg txnrx_n_int = 'd0; - reg enable_p_int = 'd0; - reg txnrx_p_int = 'd0; - reg dac_clkdata_p = 'd0; - reg dac_clkdata_n = 'd0; - reg locked_m1 = 'd0; - reg locked = 'd0; - - // internal signals - - wire [ 1:0] rx_frame_s; - wire [ 3:0] rx_frame_4_s; - wire [ 2:0] tx_data_sel_s; - wire [11:0] rx_data_p_s; - wire [11:0] rx_data_n_s; - wire rx_frame_p_s; - wire rx_frame_n_s; - wire locked_s; - - genvar l_inst; - - // receive data path interface - - assign rx_frame_s = {rx_frame_p_s, rx_frame_n_s}; - assign rx_frame_4_s = {rx_frame_s, rx_frame}; - - always @(posedge l_clk) begin - rx_frame <= rx_frame_s; - rx_data_p <= rx_data_p_s; - end - - // receive data path for single rf, frame is expected to qualify i only - - always @(posedge l_clk) begin - rx_error_r1 <= ~^ rx_frame_s; - rx_valid_r1 <= ^ rx_frame_s; - case (rx_frame_s) - 2'b01: rx_data_r1 <= {rx_data_p_s, rx_data_n_s}; - 2'b10: rx_data_r1 <= {rx_data_n_s, rx_data_p}; - default: rx_data_r1 <= 24'd0; - endcase - end - - // receive data path for dual rf, frame is expected to qualify iq for rf-1 only - - always @(posedge l_clk) begin - rx_error_r2 <= ((rx_frame_4_s == 4'b0011) || (rx_frame_4_s == 4'b1100) || - (rx_frame_4_s == 4'b1001) || (rx_frame_4_s == 4'b0110)) ? 1'b0 : 1'b1; - rx_valid_r2 <= ((rx_frame_4_s == 4'b0011) || - (rx_frame_4_s == 4'b1001)) ? 1'b1 : 1'b0; - case (rx_frame_s) - 2'b11: rx_data_r2[23: 0] <= {rx_data_p_s, rx_data_n_s}; - 2'b01: rx_data_r2[23: 0] <= {rx_data_n_s, rx_data_p}; - default: rx_data_r2[23: 0] <= rx_data_r2[23: 0]; - endcase - case (rx_frame_s) - 2'b00: rx_data_r2[47:24] <= {rx_data_p_s, rx_data_n_s}; - 2'b10: rx_data_r2[47:24] <= {rx_data_n_s, rx_data_p}; - default: rx_data_r2[47:24] <= rx_data_r2[47:24]; - endcase - end - - // receive data path mux - - always @(posedge l_clk) begin - if (adc_r1_mode == 1'b1) begin - adc_p_valid <= rx_valid_r1; - adc_p_data <= {24'd0, rx_data_r1}; - adc_p_status <= ~rx_error_r1; - end else begin - adc_p_valid <= rx_valid_r2; - adc_p_data <= rx_data_r2; - adc_p_status <= ~rx_error_r2; - end - end - - // transfer to a synchronous common clock - - always @(negedge l_clk) begin - adc_n_valid <= adc_p_valid; - adc_n_data <= adc_p_data; - adc_n_status <= adc_p_status; - end - - always @(posedge clk) begin - adc_valid_int <= adc_n_valid; - adc_data_int <= adc_n_data; - adc_status_int <= adc_n_status; - adc_valid <= adc_valid_int; - if (adc_valid_int == 1'b1) begin - adc_data <= adc_data_int; - end - adc_status <= adc_status_int & locked; - 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[1], dac_r1_mode, tx_data_cnt[0]}; - - always @(posedge clk) begin - if (dac_valid == 1'b1) begin - tx_data_cnt <= 2'b10; - end else if (tx_data_cnt[1] == 1'b1) begin - tx_data_cnt <= tx_data_cnt + 1'b1; - end - if (dac_valid == 1'b1) begin - tx_data <= dac_data; - end - case (tx_data_sel_s) - 3'b101: begin - tx_frame_p <= 1'b0; - tx_frame_n <= 1'b0; - tx_data_p <= tx_data[35:24]; - tx_data_n <= tx_data[47:36]; - end - 3'b100: begin - tx_frame_p <= 1'b1; - tx_frame_n <= 1'b1; - tx_data_p <= tx_data[11: 0]; - tx_data_n <= tx_data[23:12]; - end - 3'b110: begin - tx_frame_p <= 1'b1; - tx_frame_n <= 1'b0; - tx_data_p <= tx_data[11: 0]; - tx_data_n <= tx_data[23:12]; - end - default: begin - tx_frame_p <= 1'd0; - tx_frame_n <= 1'd0; - tx_data_p <= 12'd0; - tx_data_n <= 12'd0; - end - endcase - end - - // transfer data from a synchronous clock (skew less than 2ns) - - always @(negedge clk) begin - tx_n_frame_p <= tx_frame_p; - tx_n_frame_n <= tx_frame_n; - tx_n_data_p <= tx_data_p; - tx_n_data_n <= tx_data_n; - end - - always @(posedge l_clk) begin - tx_p_frame_p <= tx_n_frame_p; - tx_p_frame_n <= tx_n_frame_n; - tx_p_data_p <= tx_n_data_p; - tx_p_data_n <= tx_n_data_n; - end - - // tdd/ensm control - - always @(posedge up_clk) begin - up_enable_int <= up_enable; - up_txnrx_int <= up_txnrx; - end - - always @(posedge clk or posedge rst) begin - if (rst == 1'b1) begin - enable_up_m1 <= 1'b0; - txnrx_up_m1 <= 1'b0; - enable_up <= 1'b0; - txnrx_up <= 1'b0; - end else begin - enable_up_m1 <= up_enable_int; - txnrx_up_m1 <= up_txnrx_int; - enable_up <= enable_up_m1; - txnrx_up <= txnrx_up_m1; - end - end - - always @(posedge clk) begin - if (tdd_mode == 1'b1) begin - enable_int <= tdd_enable; - txnrx_int <= tdd_txnrx; - end else begin - enable_int <= enable_up; - txnrx_int <= txnrx_up; - end - end - - always @(negedge clk) begin - enable_n_int <= enable_int; - txnrx_n_int <= txnrx_int; - end - - always @(posedge l_clk) begin - enable_p_int <= enable_n_int; - txnrx_p_int <= txnrx_n_int; - end - - always @(posedge l_clk) begin - dac_clkdata_p <= dac_clksel; - dac_clkdata_n <= ~dac_clksel; - end - - // receive data interface, ibuf -> idelay -> iddr - - generate - for (l_inst = 0; l_inst <= 11; l_inst = l_inst + 1) begin: g_rx_data - ad_cmos_in #( - .DEVICE_TYPE (DEVICE_TYPE), - .IODELAY_CTRL (0), - .IODELAY_GROUP (IO_DELAY_GROUP)) - i_rx_data ( - .rx_clk (l_clk), - .rx_data_in (rx_data_in[l_inst]), - .rx_data_p (rx_data_p_s[l_inst]), - .rx_data_n (rx_data_n_s[l_inst]), - .up_clk (up_clk), - .up_dld (up_adc_dld[l_inst]), - .up_dwdata (up_adc_dwdata[((l_inst*5)+4):(l_inst*5)]), - .up_drdata (up_adc_drdata[((l_inst*5)+4):(l_inst*5)]), - .delay_clk (delay_clk), - .delay_rst (delay_rst), - .delay_locked ()); - end - endgenerate - - // receive frame interface, ibuf -> idelay -> iddr - - ad_cmos_in #( - .DEVICE_TYPE (DEVICE_TYPE), - .IODELAY_CTRL (1), - .IODELAY_GROUP (IO_DELAY_GROUP)) - i_rx_frame ( - .rx_clk (l_clk), - .rx_data_in (rx_frame_in), - .rx_data_p (rx_frame_p_s), - .rx_data_n (rx_frame_n_s), - .up_clk (up_clk), - .up_dld (up_adc_dld[12]), - .up_dwdata (up_adc_dwdata[64:60]), - .up_drdata (up_adc_drdata[64:60]), - .delay_clk (delay_clk), - .delay_rst (delay_rst), - .delay_locked (delay_locked)); - - // transmit data interface, oddr -> obuf - - generate - for (l_inst = 0; l_inst <= 11; l_inst = l_inst + 1) begin: g_tx_data - ad_cmos_out #( - .DEVICE_TYPE (DEVICE_TYPE), - .IODELAY_ENABLE (DAC_IODELAY_ENABLE), - .IODELAY_CTRL (0), - .IODELAY_GROUP (IO_DELAY_GROUP)) - i_tx_data ( - .tx_clk (l_clk), - .tx_data_p (tx_p_data_p[l_inst]), - .tx_data_n (tx_p_data_n[l_inst]), - .tx_data_out (tx_data_out[l_inst]), - .up_clk (up_clk), - .up_dld (up_dac_dld[l_inst]), - .up_dwdata (up_dac_dwdata[((l_inst*5)+4):(l_inst*5)]), - .up_drdata (up_dac_drdata[((l_inst*5)+4):(l_inst*5)]), - .delay_clk (delay_clk), - .delay_rst (delay_rst), - .delay_locked ()); - end - endgenerate - - // transmit frame interface, oddr -> obuf - - ad_cmos_out #( - .DEVICE_TYPE (DEVICE_TYPE), - .IODELAY_ENABLE (DAC_IODELAY_ENABLE), - .IODELAY_CTRL (0), - .IODELAY_GROUP (IO_DELAY_GROUP)) - i_tx_frame ( - .tx_clk (l_clk), - .tx_data_p (tx_p_frame_p), - .tx_data_n (tx_p_frame_n), - .tx_data_out (tx_frame_out), - .up_clk (up_clk), - .up_dld (up_dac_dld[12]), - .up_dwdata (up_dac_dwdata[64:60]), - .up_drdata (up_dac_drdata[64:60]), - .delay_clk (delay_clk), - .delay_rst (delay_rst), - .delay_locked ()); - - // transmit clock interface, oddr -> obuf - - ad_cmos_out #( - .DEVICE_TYPE (DEVICE_TYPE), - .IODELAY_ENABLE (DAC_IODELAY_ENABLE), - .IODELAY_CTRL (0), - .IODELAY_GROUP (IO_DELAY_GROUP)) - i_tx_clk ( - .tx_clk (l_clk), - .tx_data_p (dac_clkdata_p), - .tx_data_n (dac_clkdata_n), - .tx_data_out (tx_clk_out), - .up_clk (up_clk), - .up_dld (up_dac_dld[13]), - .up_dwdata (up_dac_dwdata[69:65]), - .up_drdata (up_dac_drdata[69:65]), - .delay_clk (delay_clk), - .delay_rst (delay_rst), - .delay_locked ()); - - // enable, oddr -> obuf - - ad_cmos_out #( - .DEVICE_TYPE (DEVICE_TYPE), - .IODELAY_ENABLE (DAC_IODELAY_ENABLE), - .IODELAY_CTRL (0), - .IODELAY_GROUP (IO_DELAY_GROUP)) - i_enable ( - .tx_clk (l_clk), - .tx_data_p (enable_p_int), - .tx_data_n (enable_p_int), - .tx_data_out (enable), - .up_clk (up_clk), - .up_dld (up_dac_dld[14]), - .up_dwdata (up_dac_dwdata[74:70]), - .up_drdata (up_dac_drdata[74:70]), - .delay_clk (delay_clk), - .delay_rst (delay_rst), - .delay_locked ()); - - // txnrx, oddr -> obuf - - ad_cmos_out #( - .DEVICE_TYPE (DEVICE_TYPE), - .IODELAY_ENABLE (DAC_IODELAY_ENABLE), - .IODELAY_CTRL (0), - .IODELAY_GROUP (IO_DELAY_GROUP)) - i_txnrx ( - .tx_clk (l_clk), - .tx_data_p (txnrx_p_int), - .tx_data_n (txnrx_p_int), - .tx_data_out (txnrx), - .up_clk (up_clk), - .up_dld (up_dac_dld[15]), - .up_dwdata (up_dac_dwdata[79:75]), - .up_drdata (up_dac_drdata[79:75]), - .delay_clk (delay_clk), - .delay_rst (delay_rst), - .delay_locked ()); - - // device clock interface (receive clock) - - always @(posedge clk) begin - locked_m1 <= locked_s; - locked <= locked_m1; - end - - ad_cmos_clk #( - .DEVICE_TYPE (DEVICE_TYPE)) - i_clk ( - .rst (mmcm_rst), - .locked (locked_s), - .clk_in (rx_clk_in), - .clk (l_clk)); + assign tx_clk_out = 'd0; + assign tx_frame_out = 'd0; + assign tx_data_out = 'd0; + assign enable = 'd0; + assign txnrx = 'd0; + assign l_clk = 'd0; + assign adc_valid = 'd0; + assign adc_data = 'd0; + assign adc_status = 'd0; + assign up_adc_drdata = 'd0; + assign up_dac_drdata = 'd0; + assign delay_locked = 'd0; endmodule diff --git a/library/axi_ad9361/altera/axi_ad9361_cmos_out.v b/library/axi_ad9361/altera/axi_ad9361_cmos_out.v new file mode 100644 index 000000000..5babc8813 --- /dev/null +++ b/library/axi_ad9361/altera/axi_ad9361_cmos_out.v @@ -0,0 +1,76 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// Each core or library found in this collection may have its own licensing terms. +// The user should keep this in in mind while exploring these cores. +// +// Redistribution and use in source and binary forms, +// with or without modification of this file, are permitted under the terms of either +// (at the option of the user): +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory, or at: +// https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html +// +// OR +// +// 2. An ADI specific BSD license as noted in the top level directory, or on-line at: +// https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ns/100ps + +module axi_ad9361_cmos_out #( + + parameter DEVICE_TYPE = 0) ( + + // data interface + + input tx_clk, + input tx_data_p, + input tx_data_n, + output tx_data_out); + + // local parameter + + localparam ARRIA10 = 0; + localparam CYCLONE5 = 1; + + // instantiations + + generate + + if (DEVICE_TYPE == ARRIA10) begin + axi_ad9361_cmos_out_core i_tx_data_oddr ( + .clk_export (tx_clk), + .din_export ({tx_data_p, tx_data_n}), + .pad_out_export (tx_data_out)); + end + + if (DEVICE_TYPE == CYCLONE5) begin + altddio_out #( + .width (1), + .lpm_hint ("UNUSED")) + i_altddio_out ( + .outclock (tx_clk), + .datain_h (tx_data_p), + .datain_l (tx_data_n), + .dataout (tx_data_out), + .outclocken (1'b1), + .oe_out (), + .oe (1'b1), + .aclr (1'b0), + .aset (1'b0), + .sclr (1'b0), + .sset (1'b0)); + end + + endgenerate + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/library/axi_ad9361/altera/axi_ad9361_lvds_if.v b/library/axi_ad9361/altera/axi_ad9361_lvds_if.v index 888fe751c..71305d6af 100644 --- a/library/axi_ad9361/altera/axi_ad9361_lvds_if.v +++ b/library/axi_ad9361/altera/axi_ad9361_lvds_if.v @@ -108,60 +108,60 @@ module axi_ad9361_lvds_if #( // internal registers - reg [ 3:0] rx_frame = 'd0; - reg rx_error = 'd0; - reg rx_valid = 'd0; - reg [ 5:0] rx_data_3 = 'd0; - reg [ 5:0] rx_data_2 = 'd0; - reg [ 5:0] rx_data_1 = 'd0; - reg [ 5:0] rx_data_0 = 'd0; - reg [23:0] rx_data = 'd0; - reg [ 3:0] tx_frame = 'd0; - reg [ 3:0] tx_p_frame = 'd0; - reg [ 3:0] tx_n_frame = 'd0; - reg [ 5:0] tx_data_d_0 = 'd0; - reg [ 5:0] tx_data_d_1 = 'd0; - reg [ 5:0] tx_data_d_2 = 'd0; - reg [ 5:0] tx_data_d_3 = 'd0; - reg tx_data_sel = 'd0; - reg up_enable_int = 'd0; - reg up_txnrx_int = 'd0; - reg enable_up_m1 = 'd0; - reg txnrx_up_m1 = 'd0; - reg enable_up = 'd0; - reg txnrx_up = 'd0; - reg enable_int = 'd0; - reg txnrx_int = 'd0; - reg enable_n_int = 'd0; - reg txnrx_n_int = 'd0; - reg enable_p_int = 'd0; - reg txnrx_p_int = 'd0; - reg [ 5:0] tx_p_data_d_0 = 'd0; - reg [ 5:0] tx_p_data_d_1 = 'd0; - reg [ 5:0] tx_p_data_d_2 = 'd0; - reg [ 5:0] tx_p_data_d_3 = 'd0; - reg [ 5:0] tx_n_data_d_0 = 'd0; - reg [ 5:0] tx_n_data_d_1 = 'd0; - reg [ 5:0] tx_n_data_d_2 = 'd0; - reg [ 5:0] tx_n_data_d_3 = 'd0; - reg adc_n_valid = 'd0; - reg adc_p_valid = 'd0; - reg adc_n_status = 'd0; - reg adc_p_status = 'd0; - reg [47:0] adc_n_data = 'd0; - reg [47:0] adc_p_data = 'd0; + reg [ 3:0] rx_frame = 'd0; + reg rx_error = 'd0; + reg rx_valid = 'd0; + reg [ 5:0] rx_data_3 = 'd0; + reg [ 5:0] rx_data_2 = 'd0; + reg [ 5:0] rx_data_1 = 'd0; + reg [ 5:0] rx_data_0 = 'd0; + reg [23:0] rx_data = 'd0; + reg [ 3:0] tx_frame = 'd0; + reg [ 3:0] tx_p_frame = 'd0; + reg [ 3:0] tx_n_frame = 'd0; + reg [ 5:0] tx_data_d_0 = 'd0; + reg [ 5:0] tx_data_d_1 = 'd0; + reg [ 5:0] tx_data_d_2 = 'd0; + reg [ 5:0] tx_data_d_3 = 'd0; + reg tx_data_sel = 'd0; + reg up_enable_int = 'd0; + reg up_txnrx_int = 'd0; + reg enable_up_m1 = 'd0; + reg txnrx_up_m1 = 'd0; + reg enable_up = 'd0; + reg txnrx_up = 'd0; + reg enable_int = 'd0; + reg txnrx_int = 'd0; + reg enable_n_int = 'd0; + reg txnrx_n_int = 'd0; + reg enable_p_int = 'd0; + reg txnrx_p_int = 'd0; + reg [ 5:0] tx_p_data_d_0 = 'd0; + reg [ 5:0] tx_p_data_d_1 = 'd0; + reg [ 5:0] tx_p_data_d_2 = 'd0; + reg [ 5:0] tx_p_data_d_3 = 'd0; + reg [ 5:0] tx_n_data_d_0 = 'd0; + reg [ 5:0] tx_n_data_d_1 = 'd0; + reg [ 5:0] tx_n_data_d_2 = 'd0; + reg [ 5:0] tx_n_data_d_3 = 'd0; + reg adc_n_valid = 'd0; + reg adc_p_valid = 'd0; + reg adc_n_status = 'd0; + reg adc_p_status = 'd0; + reg [47:0] adc_n_data = 'd0; + reg [47:0] adc_p_data = 'd0; // internal signals - wire s_clk; - wire loaden; - wire [ 7:0] phase_s; - wire [ 3:0] rx_frame_s; - wire [ 5:0] rx_data_s_3; - wire [ 5:0] rx_data_s_2; - wire [ 5:0] rx_data_s_1; - wire [ 5:0] rx_data_s_0; - wire [ 3:0] rx_frame_inv_s; + wire s_clk; + wire loaden; + wire [ 7:0] phase_s; + wire [ 3:0] rx_frame_s; + wire [ 5:0] rx_data_s_3; + wire [ 5:0] rx_data_s_2; + wire [ 5:0] rx_data_s_1; + wire [ 5:0] rx_data_s_0; + wire [ 3:0] rx_frame_inv_s; // unused interface signals @@ -369,74 +369,48 @@ module axi_ad9361_lvds_if #( // receive data path interface - ad_serdes_in #( - .DATA_WIDTH (6), - .SERDES_FACTOR (4), - .DEVICE_TYPE (DEVICE_TYPE)) + axi_ad9361_serdes_in #( + .DEVICE_TYPE (DEVICE_TYPE), + .DATA_WIDTH (6)) ad_serdes_data_in ( - .rst (mmcm_rst), .clk (s_clk), .div_clk (l_clk), .loaden (loaden), - .locked (up_drp_locked), .phase (phase_s), + .locked (up_drp_locked), .data_s0 (rx_data_s_0), .data_s1 (rx_data_s_1), .data_s2 (rx_data_s_2), .data_s3 (rx_data_s_3), - .data_s4 (), - .data_s5 (), - .data_s6 (), - .data_s7 (), .data_in_p (rx_data_in_p), .data_in_n (rx_data_in_n), - .up_clk (1'd0), - .up_dld (6'd0), - .up_dwdata (30'd0), - .up_drdata (), - .delay_clk (1'd0), - .delay_rst (1'd0), .delay_locked ()); // receive frame interface - ad_serdes_in #( - .DATA_WIDTH (1), - .SERDES_FACTOR (4), - .DEVICE_TYPE (DEVICE_TYPE)) + axi_ad9361_serdes_in #( + .DEVICE_TYPE (DEVICE_TYPE), + .DATA_WIDTH (1)) ad_serdes_frame_in ( - .rst (mmcm_rst), .clk (s_clk), .div_clk (l_clk), .loaden (loaden), - .locked (up_drp_locked), .phase (phase_s), + .locked (up_drp_locked), .data_s0 (rx_frame_s[0]), .data_s1 (rx_frame_s[1]), .data_s2 (rx_frame_s[2]), .data_s3 (rx_frame_s[3]), - .data_s4 (), - .data_s5 (), - .data_s6 (), - .data_s7 (), .data_in_p (rx_frame_in_p), .data_in_n (rx_frame_in_n), - .up_clk (1'd0), - .up_dld (1'd0), - .up_dwdata (5'd0), - .up_drdata (), - .delay_clk (1'd0), - .delay_rst (1'd0), .delay_locked ()); // transmit data interface - ad_serdes_out #( - .DATA_WIDTH (6), - .SERDES_FACTOR (4), - .DEVICE_TYPE (DEVICE_TYPE)) + axi_ad9361_serdes_out #( + .DEVICE_TYPE (DEVICE_TYPE), + .DATA_WIDTH (6)) ad_serdes_data_out ( - .rst (mmcm_rst), .clk (s_clk), .div_clk (l_clk), .loaden (loaden), @@ -444,21 +418,15 @@ module axi_ad9361_lvds_if #( .data_s1 (tx_p_data_d_1), .data_s2 (tx_p_data_d_2), .data_s3 (tx_p_data_d_3), - .data_s4 (6'd0), - .data_s5 (6'd0), - .data_s6 (6'd0), - .data_s7 (6'd0), .data_out_p (tx_data_out_p), .data_out_n (tx_data_out_n)); // transmit frame interface - ad_serdes_out #( - .DATA_WIDTH (1), - .SERDES_FACTOR (4), - .DEVICE_TYPE (DEVICE_TYPE)) + axi_ad9361_serdes_out #( + .DEVICE_TYPE (DEVICE_TYPE), + .DATA_WIDTH (1)) ad_serdes_frame_out ( - .rst (mmcm_rst), .clk (s_clk), .div_clk (l_clk), .loaden (loaden), @@ -466,21 +434,15 @@ module axi_ad9361_lvds_if #( .data_s1 (tx_p_frame[1]), .data_s2 (tx_p_frame[2]), .data_s3 (tx_p_frame[3]), - .data_s4 (1'd0), - .data_s5 (1'd0), - .data_s6 (1'd0), - .data_s7 (1'd0), .data_out_p (tx_frame_out_p), .data_out_n (tx_frame_out_n)); // transmit clock interface - ad_serdes_out #( - .DATA_WIDTH(1), - .SERDES_FACTOR(4), - .DEVICE_TYPE(DEVICE_TYPE)) + axi_ad9361_serdes_out #( + .DEVICE_TYPE (DEVICE_TYPE), + .DATA_WIDTH (1)) ad_serdes_tx_clock_out( - .rst (mmcm_rst), .clk (s_clk), .div_clk (l_clk), .loaden (loaden), @@ -488,16 +450,12 @@ module axi_ad9361_lvds_if #( .data_s1 (~dac_clksel), .data_s2 (dac_clksel), .data_s3 (~dac_clksel), - .data_s4 (1'd0), - .data_s5 (1'd0), - .data_s6 (1'd0), - .data_s7 (1'd0), .data_out_p (tx_clk_out_p), .data_out_n (tx_clk_out_n)); // serdes clock interface - ad_serdes_clk #( + axi_ad9361_serdes_clk #( .DEVICE_TYPE (DEVICE_TYPE)) ad_serdes_clk ( .rst (mmcm_rst), @@ -520,9 +478,9 @@ module axi_ad9361_lvds_if #( // enable - ad_cmos_out #( + axi_ad9361_cmos_out #( .DEVICE_TYPE (DEVICE_TYPE)) - i_enable ( + ad_serdes_enable ( .tx_clk (l_clk), .tx_data_p (enable_p_int), .tx_data_n (enable_p_int), @@ -530,9 +488,9 @@ module axi_ad9361_lvds_if #( // txnrx - ad_cmos_out #( + axi_ad9361_cmos_out #( .DEVICE_TYPE (DEVICE_TYPE)) - i_txnrx ( + ad_serdes_txnrx ( .tx_clk (l_clk), .tx_data_p (txnrx_p_int), .tx_data_n (txnrx_p_int), diff --git a/library/axi_ad9361/altera/axi_ad9361_serdes_clk.v b/library/axi_ad9361/altera/axi_ad9361_serdes_clk.v new file mode 100644 index 000000000..6e21f54d0 --- /dev/null +++ b/library/axi_ad9361/altera/axi_ad9361_serdes_clk.v @@ -0,0 +1,178 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// Each core or library found in this collection may have its own licensing terms. +// The user should keep this in in mind while exploring these cores. +// +// Redistribution and use in source and binary forms, +// with or without modification of this file, are permitted under the terms of either +// (at the option of the user): +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory, or at: +// https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html +// +// OR +// +// 2. An ADI specific BSD license as noted in the top level directory, or on-line at: +// https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ps/1ps + +module axi_ad9361_serdes_clk #( + + // parameters + + parameter DEVICE_TYPE = 0) ( + + // clock and divided clock + + input rst, + input clk_in_p, + input clk_in_n, + output clk, + output div_clk, + output out_clk, + output loaden, + output [ 7:0] phase, + + // drp interface + + input up_clk, + input up_rstn, + input up_drp_sel, + input up_drp_wr, + input [11:0] up_drp_addr, + input [31:0] up_drp_wdata, + output [31:0] up_drp_rdata, + output up_drp_ready, + output up_drp_locked); + + // local parameter + + localparam ARRIA10 = 0; + localparam CYCLONE5 = 1; + + // internal registers + + reg up_drp_sel_int = 'd0; + reg up_drp_rd_int = 'd0; + reg up_drp_wr_int = 'd0; + reg [ 8:0] up_drp_addr_int = 'd0; + reg [31:0] up_drp_wdata_int = 'd0; + reg [31:0] up_drp_rdata_int = 'd0; + reg up_drp_ready_int = 'd0; + reg up_drp_locked_int_m = 'd0; + reg up_drp_locked_int = 'd0; + + // internal signals + + wire up_drp_reset; + wire [31:0] up_drp_rdata_int_s; + wire up_drp_busy_int_s; + wire up_drp_locked_int_s; + wire loaden_s; + wire clk_s; + + // defaults + + assign up_drp_reset = ~up_rstn; + assign out_clk = div_clk; + assign up_drp_rdata = up_drp_rdata_int; + assign up_drp_ready = up_drp_ready_int; + assign up_drp_locked = up_drp_locked_int; + + always @(negedge up_rstn or posedge up_clk) begin + if (up_rstn == 1'b0) begin + up_drp_sel_int <= 1'b0; + up_drp_rd_int <= 1'b0; + up_drp_wr_int <= 1'b0; + up_drp_addr_int <= 9'd0; + up_drp_wdata_int <= 32'd0; + up_drp_rdata_int <= 32'd0; + up_drp_ready_int <= 1'b0; + up_drp_locked_int_m <= 1'd0; + up_drp_locked_int <= 1'd0; + end else begin + if (up_drp_sel_int == 1'b1) begin + if (up_drp_busy_int_s == 1'b0) begin + up_drp_sel_int <= 1'b0; + up_drp_rd_int <= 1'b0; + up_drp_wr_int <= 1'b0; + up_drp_addr_int <= 9'd0; + up_drp_wdata_int <= 32'd0; + up_drp_rdata_int <= up_drp_rdata_int_s; + up_drp_ready_int <= 1'b1; + end + end else if (up_drp_sel == 1'b1) begin + up_drp_sel_int <= 1'b1; + up_drp_rd_int <= ~up_drp_wr; + up_drp_wr_int <= up_drp_wr; + up_drp_addr_int <= up_drp_addr[8:0]; + up_drp_wdata_int <= up_drp_wdata; + up_drp_rdata_int <= 32'd0; + up_drp_ready_int <= 1'b0; + end else begin + up_drp_sel_int <= 1'b0; + up_drp_rd_int <= 1'b0; + up_drp_wr_int <= 1'b0; + up_drp_addr_int <= 9'd0; + up_drp_wdata_int <= 32'd0; + up_drp_rdata_int <= 32'd0; + up_drp_ready_int <= 1'b0; + end + up_drp_locked_int_m <= up_drp_locked_int_s; + up_drp_locked_int <= up_drp_locked_int_m; + end + end + + generate + + if (DEVICE_TYPE == ARRIA10) begin + axi_ad9361_serdes_clk_core i_core ( + .rst_reset (rst), + .ref_clk_clk (clk_in_p), + .locked_export (up_drp_locked_int_s), + .hs_phase_phout (phase), + .hs_clk_lvds_clk (clk), + .loaden_loaden (loaden), + .ls_clk_clk (div_clk)); + end + + if (DEVICE_TYPE == CYCLONE5) begin + assign phase = 8'd0; + axi_ad9361_serdes_clk_pll i_core ( + .rst_reset (rst), + .ref_clk_clk (clk_in_p), + .locked_export (up_drp_locked_int_s), + .hs_clk_clk (clk_s), + .loaden_clk (loaden_s), + .ls_clk_clk (div_clk), + .drp_clk_clk (up_clk), + .drp_rst_reset (up_drp_reset), + .pll_reconfig_waitrequest (up_drp_busy_int_s), + .pll_reconfig_read (up_drp_rd_int), + .pll_reconfig_write (up_drp_wr_int), + .pll_reconfig_readdata (up_drp_rdata_int_s), + .pll_reconfig_address (up_drp_addr_int[5:0]), + .pll_reconfig_writedata (up_drp_wdata_int)); + + cyclonev_pll_lvds_output #( + .pll_loaden_enable_disable ("true"), + .pll_lvdsclk_enable_disable ("true")) + i_clk_buf ( + .ccout ({loaden_s, clk_s}), + .loaden (loaden), + .lvdsclk (clk)); + end + + endgenerate + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/library/axi_ad9361/altera/axi_ad9361_serdes_in.v b/library/axi_ad9361/altera/axi_ad9361_serdes_in.v new file mode 100644 index 000000000..54af3627e --- /dev/null +++ b/library/axi_ad9361/altera/axi_ad9361_serdes_in.v @@ -0,0 +1,187 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// Each core or library found in this collection may have its own licensing terms. +// The user should keep this in in mind while exploring these cores. +// +// Redistribution and use in source and binary forms, +// with or without modification of this file, are permitted under the terms of either +// (at the option of the user): +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory, or at: +// https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html +// +// OR +// +// 2. An ADI specific BSD license as noted in the top level directory, or on-line at: +// https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ps/1ps + +module axi_ad9361_serdes_in #( + + // parameters + + parameter DEVICE_TYPE = 0, + parameter DATA_WIDTH = 16) ( + + // reset and clocks + + input clk, + input div_clk, + input loaden, + input [ 7:0] phase, + input locked, + + // data interface + + output [(DATA_WIDTH-1):0] data_s0, + output [(DATA_WIDTH-1):0] data_s1, + output [(DATA_WIDTH-1):0] data_s2, + output [(DATA_WIDTH-1):0] data_s3, + input [(DATA_WIDTH-1):0] data_in_p, + input [(DATA_WIDTH-1):0] data_in_n, + + // delay-control interface + + output delay_locked); + + // local parameter + + localparam ARRIA10 = 0; + localparam CYCLONE5 = 1; + + // internal signals + + wire [(DATA_WIDTH-1):0] delay_locked_s; + wire [(DATA_WIDTH-1):0] data_samples_s[0:3]; + wire [ 3:0] data_out_s[0:(DATA_WIDTH-1)]; + + // assignments + + assign delay_locked = & delay_locked_s; + assign data_s3 = data_samples_s[3]; + assign data_s2 = data_samples_s[2]; + assign data_s1 = data_samples_s[1]; + assign data_s0 = data_samples_s[0]; + + genvar n; + generate + for (n = 0; n < DATA_WIDTH; n = n + 1) begin: g_data + + assign data_samples_s[0][n] = data_out_s[n][0]; + assign data_samples_s[1][n] = data_out_s[n][1]; + assign data_samples_s[2][n] = data_out_s[n][2]; + assign data_samples_s[3][n] = data_out_s[n][3]; + + if (DEVICE_TYPE == CYCLONE5) begin + assign delay_locked_s[n] = 1'b1; + altlvds_rx #( + .buffer_implementation ("RAM"), + .cds_mode ("UNUSED"), + .common_rx_tx_pll ("OFF"), + .data_align_rollover (4), + .data_rate ("800.0 Mbps"), + .deserialization_factor (4), + .dpa_initial_phase_value (0), + .dpll_lock_count (0), + .dpll_lock_window (0), + .enable_clock_pin_mode ("UNUSED"), + .enable_dpa_align_to_rising_edge_only ("OFF"), + .enable_dpa_calibration ("ON"), + .enable_dpa_fifo ("UNUSED"), + .enable_dpa_initial_phase_selection ("OFF"), + .enable_dpa_mode ("OFF"), + .enable_dpa_pll_calibration ("OFF"), + .enable_soft_cdr_mode ("OFF"), + .implement_in_les ("OFF"), + .inclock_boost (0), + .inclock_data_alignment ("EDGE_ALIGNED"), + .inclock_period (50000), + .inclock_phase_shift (0), + .input_data_rate (800), + .intended_device_family ("Cyclone V"), + .lose_lock_on_one_change ("UNUSED"), + .lpm_hint ("CBX_MODULE_PREFIX=axi_ad9361_serdes_in"), + .lpm_type ("altlvds_rx"), + .number_of_channels (1), + .outclock_resource ("Dual-Regional clock"), + .pll_operation_mode ("NORMAL"), + .pll_self_reset_on_loss_lock ("UNUSED"), + .port_rx_channel_data_align ("PORT_UNUSED"), + .port_rx_data_align ("PORT_UNUSED"), + .refclk_frequency ("20.000000 MHz"), + .registered_data_align_input ("UNUSED"), + .registered_output ("OFF"), + .reset_fifo_at_first_lock ("UNUSED"), + .rx_align_data_reg ("RISING_EDGE"), + .sim_dpa_is_negative_ppm_drift ("OFF"), + .sim_dpa_net_ppm_variation (0), + .sim_dpa_output_clock_phase_shift (0), + .use_coreclock_input ("OFF"), + .use_dpll_rawperror ("OFF"), + .use_external_pll ("ON"), + .use_no_phase_shift ("ON"), + .x_on_bitslip ("ON"), + .clk_src_is_pll ("off")) + i_altlvds_rx ( + .rx_enable (loaden), + .rx_in (data_in_p[n]), + .rx_inclock (clk), + .rx_out (data_out_s[n]), + .dpa_pll_cal_busy (), + .dpa_pll_recal (1'b0), + .pll_areset (1'b0), + .pll_phasecounterselect (), + .pll_phasedone (1'b1), + .pll_phasestep (), + .pll_phaseupdown (), + .pll_scanclk (), + .rx_cda_max (), + .rx_cda_reset (1'b0), + .rx_channel_data_align (1'b0), + .rx_coreclk (1'b1), + .rx_data_align (1'b0), + .rx_data_align_reset (1'b0), + .rx_data_reset (1'b0), + .rx_deskew (1'b0), + .rx_divfwdclk (), + .rx_dpa_lock_reset (1'b0), + .rx_dpa_locked (), + .rx_dpaclock (1'b0), + .rx_dpll_enable (1'b1), + .rx_dpll_hold (1'b0), + .rx_dpll_reset (1'b0), + .rx_fifo_reset (1'b0), + .rx_locked (), + .rx_outclock (), + .rx_pll_enable (1'b1), + .rx_readclock (1'b0), + .rx_reset (1'b0), + .rx_syncclock (1'b0)); + end + + if (DEVICE_TYPE == ARRIA10) begin + axi_ad9361_serdes_in_core i_core ( + .clk_export (clk), + .div_clk_export (div_clk), + .hs_phase_export (phase), + .loaden_export (loaden), + .locked_export (locked), + .data_in_export (data_in_p[n]), + .data_s_export (data_out_s[n]), + .delay_locked_export (delay_locked_s[n])); + end + + end + endgenerate + +endmodule + +// *************************************************************************** +// *************************************************************************** diff --git a/library/axi_ad9361/altera/axi_ad9361_serdes_out.v b/library/axi_ad9361/altera/axi_ad9361_serdes_out.v new file mode 100644 index 000000000..7e271083f --- /dev/null +++ b/library/axi_ad9361/altera/axi_ad9361_serdes_out.v @@ -0,0 +1,137 @@ +// *************************************************************************** +// *************************************************************************** +// Copyright 2014 - 2017 (c) Analog Devices, Inc. All rights reserved. +// +// Each core or library found in this collection may have its own licensing terms. +// The user should keep this in in mind while exploring these cores. +// +// Redistribution and use in source and binary forms, +// with or without modification of this file, are permitted under the terms of either +// (at the option of the user): +// +// 1. The GNU General Public License version 2 as published by the +// Free Software Foundation, which can be found in the top level directory, or at: +// https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html +// +// OR +// +// 2. An ADI specific BSD license as noted in the top level directory, or on-line at: +// https://github.com/analogdevicesinc/hdl/blob/dev/LICENSE +// +// *************************************************************************** +// *************************************************************************** + +`timescale 1ps/1ps + +module axi_ad9361_serdes_out #( + + parameter DEVICE_TYPE = 0, + parameter DATA_WIDTH = 16) ( + + // reset and clocks + + input clk, + input div_clk, + input loaden, + + // data interface + + input [(DATA_WIDTH-1):0] data_s0, + input [(DATA_WIDTH-1):0] data_s1, + input [(DATA_WIDTH-1):0] data_s2, + input [(DATA_WIDTH-1):0] data_s3, + output [(DATA_WIDTH-1):0] data_out_p, + output [(DATA_WIDTH-1):0] data_out_n); + + // local parameter + + localparam ARRIA10 = 0; + localparam CYCLONE5 = 1; + + // internal signals + + wire [ 3:0] data_in_s[0:(DATA_WIDTH-1)]; + + // defaults + + assign data_out_n = 'd0; + + // instantiations + + genvar n; + + generate + for (n = 0; n < DATA_WIDTH; n = n + 1) begin: g_data + + assign data_in_s[n][3] = data_s0[n]; + assign data_in_s[n][2] = data_s1[n]; + assign data_in_s[n][1] = data_s2[n]; + assign data_in_s[n][0] = data_s3[n]; + + if (DEVICE_TYPE == CYCLONE5) begin + altlvds_tx #( + .center_align_msb ("UNUSED"), + .common_rx_tx_pll ("OFF"), + .coreclock_divide_by (1), + .data_rate ("800.0 Mbps"), + .deserialization_factor (4), + .differential_drive (0), + .enable_clock_pin_mode ("UNUSED"), + .implement_in_les ("OFF"), + .inclock_boost (0), + .inclock_data_alignment ("EDGE_ALIGNED"), + .inclock_period (50000), + .inclock_phase_shift (0), + .intended_device_family ("Cyclone V"), + .lpm_hint ("CBX_MODULE_PREFIX=axi_ad9361_serdes_out"), + .lpm_type ("altlvds_tx"), + .multi_clock ("OFF"), + .number_of_channels (1), + .outclock_alignment ("EDGE_ALIGNED"), + .outclock_divide_by (1), + .outclock_duty_cycle (50), + .outclock_multiply_by (1), + .outclock_phase_shift (0), + .outclock_resource ("Dual-Regional clock"), + .output_data_rate (800), + .pll_compensation_mode ("AUTO"), + .pll_self_reset_on_loss_lock ("OFF"), + .preemphasis_setting (0), + .refclk_frequency ("20.000000 MHz"), + .registered_input ("OFF"), + .use_external_pll ("ON"), + .use_no_phase_shift ("ON"), + .vod_setting (0), + .clk_src_is_pll ("off")) + i_altlvds_tx ( + .tx_enable (loaden), + .tx_in (data_in_s[n]), + .tx_inclock (clk), + .tx_out (data_out_p[n]), + .pll_areset (1'b0), + .sync_inclock (1'b0), + .tx_coreclock (), + .tx_data_reset (1'b0), + .tx_locked (), + .tx_outclock (), + .tx_pll_enable (1'b1), + .tx_syncclock (1'b0)); + end + + if (DEVICE_TYPE == ARRIA10) begin + axi_ad9361_serdes_out_core i_core ( + .clk_export (clk), + .div_clk_export (div_clk), + .loaden_export (loaden), + .data_out_export (data_out_p[n]), + .data_s_export (data_in_s[n])); + end + + end + endgenerate + +endmodule + +// *************************************************************************** +// *************************************************************************** +