`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 27.05.2022 17:35:23 // Design Name: // Module Name: ltm9011_zynq // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module ltm9011_zynq( input LTM9011_DCOA_P, // 400 MHz from top input LTM9011_DCOA_N, // 400 MHz from top input LTM9011_DCOB_P, // 400 MHz from top input LTM9011_DCOB_N, // 400 MHz from top output wire clk_adc_a_o, // 100 MHz main clock to fabric output wire clk_adc_b_o, // 100 MHz main clock to fabric input LTM9011_FRA_P, input LTM9011_FRA_N, input LTM9011_FRB_P, input LTM9011_FRB_N, input [7:0] ltm9011_data_a_p, input [7:0] ltm9011_data_a_n, input [7:0] ltm9011_data_b_p, input [7:0] ltm9011_data_b_n, input reset, output wire LTM9011_CSA, // LTM9011 SPI /CS A output wire LTM9011_CSB, // LTM9011 SPI /CS_B output wire LTM9011_MOSI, // LTM9011 SPI MOSI output wire LTM9011_SCK, // LTM9011 SPI SCLK output [13: 0] adc_data_1, output [13: 0] adc_data_2, output [13: 0] adc_data_3, output [13: 0] adc_data_4, output [13: 0] adc_data_5, output [13: 0] adc_data_6, output [13: 0] adc_data_7, output [13: 0] adc_data_8, output setup_done ); /** ___ ________ ______ * / \ |_ __ \ / ___ \ * / /\ \ | | \ | | / \__\ * / /__\ \ | | | | | | __ * / ____ \ _| |__/ | | \___/ / * /__/ \___\ |________/ \________/ */ /** * local parameters */ localparam ADC_CH = 8; // number of ADC channels in use (no generate yet, difficult because of two DCOs of ADC) localparam DELAY_DCO_CLK = 0; localparam DELAY_DATA_LINES = 256; localparam DELAY_FRAME = 511; /** * clocking signals */ /** * channel specific lvds signals */ // wire [13: 0] adc_data [ADC_CH-1: 0];// data output from the ADC channels wire [ADC_CH-1: 0] adc_start_tp_on; // start testpattern ON signal from ADC channels wire [ADC_CH-1: 0] adc_start_tp_off;// start testpattern OFF signal from ADC channels /** * diff clk -> IBUFDS -> BUFMR -> clk_buf */ wire clk_dco_a_p_buf; // 400 MHz from ADC wire clk_dco_a_n_buf; // 400 MHz from ADC wire clk_dco_b_buf; // 400 MHz from ADC wire clk_200; // SPI wire clk_adc_a_pll; // ADC main clock adc_data_clk_path dco_a_buffer( .clk_p (LTM9011_DCOA_P), // input 400 MHz .clk_n (LTM9011_DCOA_N), // input 400 MHz .clk_buf_p (clk_dco_a_p_buf) // output 400 MHz // .clk_buf_n (clk_dco_a_n_buf) // output 400 MHz ); // hier besser einen div buffer verwenden??? wire adc_pll_locked; wire rst_in; clk_adc_a clk_a( .clk_in1 (clk_dco_a_p_buf), // 400 MHz .clk_global_100MHz (clk_adc_a_pll), // 100 MHz derived from 400 MHz. Used to drive all PL .clk_spi (clk_200), // 200 MHz (SPI) .locked (adc_pll_locked), .reset (1'b0) ); assign clk_adc_a_o = clk_adc_a_pll; //adc_data_clk_path dco_b_buffer( // .clk_p (LTM9011_DCOB_P), // .clk_n (LTM9011_DCOB_N), // .clk_buf (clk_dco_b_buf) //); //wire clk_adc_b_pll; //clk_adc_b clk_b( //.clk_in1 (clk_dco_b_buf), //.clk_out1 (clk_adc_b_pll) //); //assign clk_adc_b_o = clk_adc_b_pll; wire clk_fr_a_buf_in; adc_frame_clk_path frame_a_buffer( .clk_p (LTM9011_FRA_P), .clk_n (LTM9011_FRA_N), .clk_buf (clk_fr_a_buf) ); //adc_frame_clk_path frame_b_buffer( // .clk_p (LTM9011_FRB_P), // .clk_n (LTM9011_FRB_N), // .clk_buf (clk_fr_b_buf) //); /** * ADC data signal buffers. * This module contains the differential IO buffers * As an update to 44CH_SW0017a and for later use, * this module contains differential input, * differential output buffers. With a local parameter * inside this module, the non-inverted or the inverted * output of the buffer can be selected and the polarisation * of the differential signal lines can be inverted, * if this is necessary due to the hardware design. */ wire [8-1: 0] ltm9011_data_a; wire [8-1: 0] ltm9011_data_b; adc_data_buffer adc_data_buf_inst( .ltm9011_data_a_p (ltm9011_data_a_p), // differential input .ltm9011_data_a_n (ltm9011_data_a_n), .ltm9011_data_b_p (ltm9011_data_b_p), .ltm9011_data_b_n (ltm9011_data_b_n), .ltm9011_data_a (ltm9011_data_a), // single ended output .ltm9011_data_b (ltm9011_data_b) ); /** * This module contains a SPI communication state machine * to configure the ADC LTM9011 to output a known test data * pattern (start) or to output the converted analog data. */ reg reg_start_tp_on; reg reg_start_tp_off; reg reg_rst_in; reg [28: 0] counter; always @(posedge clk_adc_a_pll) begin counter <= counter + 1; // https://docs.xilinx.com/r/en-US/ug908-vivado-programming-debugging/Trigger-At-Startup // if(counter < 28'd100)begin // reg_start_tp_on <= 1'b0; // reg_start_tp_off <= 1'b0; // reg_rst_in <= 1'b1; // end else begin // reg_start_tp_on <= 1'b1; // reg_rst_in <= 1'b0; // end // if(counter > 28'd120)begin // start_spi <= 1; // spi_data <= 8'b00000000; // write to address 0 // cs <= 0; // end // if(counter > 28'd121)begin // start_spi <= 0; // end // if(counter > 28'd200)begin // start_spi <= 1; // spi_data <= 8'b10000000; // reset... // end // if(counter > 28'd201)begin // start_spi <= 0; // end // if(counter > 28'd250)begin // reg_start_tp_on <= 1'b0; // end // if(counter > 28'd350)begin // reg_start_tp_off <= 1'b1; // end // if(counter > 28'd400)begin // reg_start_tp_off <= 1'b0; // end end assign rst_in = reg_rst_in; assign start_tp_on = reg_start_tp_on; assign start_tp_off = reg_start_tp_off; ltm9011_testpattern#( .CLK_DIV () ) LTM9011_startstop_testpattern( .clk (clk_200), .reset (reset), // high activ .testdata (14'h0333), .start (start_tp_on), .stop (start_tp_off), .busy (testpattern_busy), .done (testpattern_done), .spi_clk (LTM9011_SCK), .spi_mosi_a (LTM9011_MOSI), .spi_mosi_b (), .spi_cs_a (LTM9011_CSA), .spi_cs_b (LTM9011_CSB) ); wire clk_fr_a_buf_delayed; wire clk_dco_a_p_buf_delayed; //++++++++++++++++++++++++++++++++++++++++++++++++ // Delay darf man nicht fuer clock benutzen !!! // DCO clock ist direkt verbunden //++++++++++++++++++++++++++++++++++++++++++++++++ //octopus_delay# // (.DELAY_COUNT (0) // Input delay value setting (0-1100 ps time mode)(0-511 count mode) // ) //delay_dco( //.clk (clk_fr_a_buf_delayed), // 1-bit input: Clock input //.data_in (clk_dco_a_p_buf), // 1-bit input: Data input from the IOBUF //.data_out (clk_dco_a_p_buf_delayed), // 1-bit output: Delayed data output //.rst (rst_in) // 1-bit input: Asynchronous Reset to the DELAY_VALUE //); assign clk_dco_a_p_buf_delayed = clk_dco_a_p_buf; //++++++++++++++++++++++++++++++++++++++++++++++++ // Delay darf man nicht fuer clock benutzen !!! // Frame clock ist direkt verbunden //++++++++++++++++++++++++++++++++++++++++++++++++ //octopus_delay# // (.DELAY_COUNT (511) // Input delay value setting (0-1100 ps time mode)(0-511 count mode) // ) //delay_frame( //.clk (clk_fr_a_buf_delayed), // 1-bit input: Clock input //.data_in (clk_fr_a_buf), // 1-bit input: Data input from the IOBUF //.data_out (clk_fr_a_buf_delayed), // 1-bit output: Delayed data output //.rst (rst_in) // 1-bit input: Asynchronous Reset to the DELAY_VALUE //); assign clk_fr_a_buf_delayed = clk_fr_a_buf; //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Delay darf man nicht fuer clock benutzen !!! // Der Versuch mit einen clkwiz hat nicht funktioniert. Kleinster Winkel in der Phase ist 26° deg. // //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //clk_frame_a_delay frame_a_delay // clock wiz // ( // // Clock out ports // .clk_frame_out(clk_fr_a_buf_delayed), // output clk_frame_out // // Clock in ports // .clk_frame_in(clk_fr_a_buf)); // input clk_frame_in wire [8-1: 0] data_a; // for debug only wire [8-1: 0] data_b; // for debug only octopus_iserdes# (.DELAY_DATA_LINES (256) ) adc_1( .clk_frame (clk_fr_a_buf_delayed), .clk_highspeed (clk_dco_a_p_buf_delayed), .clk_adc (clk_adc_a_pll), .data_in_a (ltm9011_data_a[0]), .data_in_b (ltm9011_data_b[0]), .data_out (adc_data_1), .data_a (data_a), .data_b (data_b) ); octopus_iserdes# (.DELAY_DATA_LINES (256) ) adc_2( .clk_frame (clk_fr_a_buf_delayed), .clk_highspeed (clk_dco_a_p_buf_delayed), .clk_adc (clk_adc_a_pll), .data_in_a (ltm9011_data_a[1]), .data_in_b (ltm9011_data_b[1]), .data_out (adc_data_2) ); octopus_iserdes# (.DELAY_DATA_LINES (256) ) adc_3( .clk_frame (clk_fr_a_buf_delayed), .clk_highspeed (clk_dco_a_p_buf_delayed), .clk_adc (clk_adc_a_pll), .data_in_a (ltm9011_data_a[2]), .data_in_b (ltm9011_data_b[2]), .data_out (adc_data_3) ); octopus_iserdes# (.DELAY_DATA_LINES (256) ) adc_4( .clk_frame (clk_fr_a_buf_delayed), .clk_highspeed (clk_dco_a_p_buf_delayed), .clk_adc (clk_adc_a_pll), .data_in_a (ltm9011_data_a[3]), .data_in_b (ltm9011_data_b[3]), .data_out (adc_data_4) ); octopus_iserdes# (.DELAY_DATA_LINES (256) ) adc_5( .clk_frame (clk_fr_a_buf_delayed), .clk_highspeed (clk_dco_a_p_buf_delayed), .clk_adc (clk_adc_a_pll), .data_in_a (ltm9011_data_a[4]), .data_in_b (ltm9011_data_b[4]), .data_out (adc_data_5) ); octopus_iserdes# (.DELAY_DATA_LINES (256) ) adc_6( .clk_frame (clk_fr_a_buf_delayed), .clk_highspeed (clk_dco_a_p_buf_delayed), .clk_adc (clk_adc_a_pll), .data_in_a (ltm9011_data_a[5]), .data_in_b (ltm9011_data_b[5]), .data_out (adc_data_6) ); octopus_iserdes# (.DELAY_DATA_LINES (256) ) adc_7( .clk_frame (clk_fr_a_buf_delayed), .clk_highspeed (clk_dco_a_p_buf_delayed), .clk_adc (clk_adc_a_pll), .data_in_a (ltm9011_data_a[6]), .data_in_b (ltm9011_data_b[6]), .data_out (adc_data_7) ); octopus_iserdes# (.DELAY_DATA_LINES (256) ) adc_8( .clk_frame (clk_fr_a_buf_delayed), .clk_highspeed (clk_dco_a_p_buf_delayed), .clk_adc (clk_adc_a_pll), .data_in_a (ltm9011_data_a[7]), .data_in_b (ltm9011_data_b[7]), .data_out (adc_data_8) ); //wire ila; //clk_ila clk_ila_inst( //.clk_in1 (clk_dco_a_p_buf_delayed), // 400 MHz //.clk_out1 (ila) // 400 (650)MHz //); //ila_top debug_ltm9011( //.clk (ila), //.probe0 ({ //// clk_adc_a_pll, // 100 MHz derived from 400 MHz. Used to drive all PL //// LTM9011_MOSI, // LTM9011 SPI MOSI //// LTM9011_SCK, // LTM9011 SPI SCLK //// ltm9011_data_a, //// ltm9011_data_b, //// rst_in, // data_a, // data_b, //// adc_data, // adc_data_1, // adc_data_2, // adc_data_3, // adc_data_4, // adc_data_5, // adc_data_6, // adc_data_7, // adc_data_8, // start_tp_on //// start_tp_off // }) //); endmodule // delay cascade: https://support.xilinx.com/s/question/0D52E00006hpsVXSAY/ultrascale-idelaye3odelaye3-cascade-implement-issue?language=en_US // https://github.com/analogdevicesinc/hdl/tree/master/library/xilinx/common // Xapp1208 bitslip logic // UG571 select io