`timescale 1 ns / 1 ns module reflectometer_top #( parameter int unsigned DAC_DATA_WIDTH = 14, parameter int unsigned ADC_DATA_WIDTH = 12, parameter PACK_FACTOR = 1, parameter PROCESS_MODE = 0, parameter ACCUM_WIDTH = 32, parameter N_MAX = 4096, parameter WINDOW_SIZE = 65, parameter PACKET_SIZE = 1024 )( input sys_clk, input rst_n, output [3:0] led, input gmii_rx_clk, input gmii_tx_clk, (* MARK_DEBUG="true" *) output logic [7:0] s_axis_tx_tdata, (* MARK_DEBUG="true" *) output logic s_axis_tx_tvalid, (* MARK_DEBUG="true" *) input logic s_axis_tx_tready, (* MARK_DEBUG="true" *) output logic s_axis_tx_tlast, (* MARK_DEBUG="true" *) input wire [7:0] m_axis_rx_tdata, (* MARK_DEBUG="true" *) input wire m_axis_rx_tvalid, (* MARK_DEBUG="true" *) input wire m_axis_rx_tlast, (* MARK_DEBUG="true" *) output wire m_axis_rx_tready, // axis_mac (* MARK_DEBUG="true" *) input logic req_ready, (* MARK_DEBUG="true" *) output logic send_req, // DAC output wire p2_clk, (* MARK_DEBUG="true" *) output wire [DAC_DATA_WIDTH-1:0] p2_data, (* MARK_DEBUG="true" *) output wire p2_wrt, // ADC output ch2_clk, (* MARK_DEBUG="true" *) input [ADC_DATA_WIDTH-1:0] ch2_data, input ch2_otr ); // ------------------------------------------------------------------------- // IDELAYCTRL // ------------------------------------------------------------------------- (* IODELAY_GROUP = "rgmii_idelay_group" *) IDELAYCTRL IDELAYCTRL_inst ( .RDY (), .REFCLK (sys_clk), .RST (1'b0) ); // ------------------------------------------------------------------------- // Generated clocks for controller // Need to create this IP in Vivado: // input : 200 MHz // output0: 130 MHz // output1: 65 MHz // ------------------------------------------------------------------------- wire dac_clk; wire adc_clk; wire clk_wiz_locked; clk_wiz_ctrl_inst clk_wiz_ctrl_inst ( .clk_in1 (sys_clk), .reset (~rst_n), .clk_out1 (dac_clk), // 130 MHz .clk_out2 (adc_clk), // 65 MHz .locked (clk_wiz_locked) ); // ------------------------------------------------------------------------- // axis_mac interface // RX stream from Ethernet goes into controller // TX stream is unused for now // ------------------------------------------------------------------------- // ------------------------------------------------------------------------- // Controller reset // Use both external reset and clk_wiz lock // ------------------------------------------------------------------------- wire ctrl_rst_n = rst_n & clk_wiz_locked; (* MARK_DEBUG="true" *) logic finish; // Controller outputs to debug (* MARK_DEBUG="true" *) wire [31:0] dac_pulse_width; (* MARK_DEBUG="true" *) wire [31:0] dac_pulse_period; (* MARK_DEBUG="true" *) wire [DAC_DATA_WIDTH-1:0] dac_pulse_height; (* MARK_DEBUG="true" *) wire [15:0] dac_pulse_num; (* MARK_DEBUG="true" *) wire [31:0] adc_pulse_period; (* MARK_DEBUG="true" *) wire [15:0] adc_pulse_num; (* MARK_DEBUG="true" *) wire dac_start; (* MARK_DEBUG="true" *) wire adc_start; (* MARK_DEBUG="true" *) wire dac_rst; (* MARK_DEBUG="true" *) wire adc_rst; // ------------------------------------------------------------------------- // Controller // ETH domain = gmii_rx_clk, because RX AXI master comes from axis_mac RX side // ------------------------------------------------------------------------- control #( .DAC_DATA_WIDTH(DAC_DATA_WIDTH) ) udp_ctrl_inst ( .eth_clk_in (gmii_rx_clk), .dac_clk_in (dac_clk), .adc_clk_in (adc_clk), .rst_n (ctrl_rst_n), .s_axis_tdata (m_axis_rx_tdata), .s_axis_tvalid (m_axis_rx_tvalid), .s_axis_tready (m_axis_rx_tready), .s_axis_tlast (m_axis_rx_tlast), .finish (finish), .dac_pulse_width (dac_pulse_width), .dac_pulse_period (dac_pulse_period), .dac_pulse_height (dac_pulse_height), .dac_pulse_num (dac_pulse_num), .adc_pulse_period (adc_pulse_period), .adc_pulse_num (adc_pulse_num), .dac_start (dac_start), .adc_start (adc_start), .dac_rst (dac_rst), .adc_rst (adc_rst) ); // ------------------------------------------------------------------------- // DAC // ------------------------------------------------------------------------- (* MARK_DEBUG="true" *) logic sample_req; (* MARK_DEBUG="true" *) logic sample_req_sync1; (* MARK_DEBUG="true" *) logic sample_req_sync2; (* MARK_DEBUG="true" *) logic sample_req_sync3; (* MARK_DEBUG="true" *) logic sample_done; (* MARK_DEBUG="true" *) logic sample_done_sync1; (* MARK_DEBUG="true" *) logic sample_done_sync2; (* MARK_DEBUG="true" *) logic sample_done_sync3; //------------------------------------------------------------ // DAC -> ADC CDC //------------------------------------------------------------ always_ff @(posedge adc_clk or posedge adc_rst) begin if (adc_rst) begin sample_req <= 1'b0; sample_req_sync2 <= 1'b0; sample_req_sync3 <= 1'b0; end else begin sample_req_sync2 <= sample_req_sync1; sample_req_sync3 <= sample_req_sync2; sample_req <= sample_req_sync3; end end //------------------------------------------------------------ // ADC -> DAC CDC //------------------------------------------------------------ always_ff @(posedge dac_clk or posedge dac_rst) begin if (dac_rst) begin sample_done <= 1'b0; sample_done_sync2 <= 1'b0; sample_done_sync3 <= 1'b0; end else begin sample_done_sync2 <= sample_done_sync1; sample_done_sync3 <= sample_done_sync2; sample_done <= sample_done_sync3; end end //------------------------------------------------------------ // Generator //------------------------------------------------------------ generator #( .DATA_WIDTH(DAC_DATA_WIDTH) ) generator_inst ( .clk_in(dac_clk), .rst(dac_rst), .start(dac_start), .pulse_width(dac_pulse_width), .pulse_period(dac_pulse_period), .pulse_height(dac_pulse_height), .pulse_num(dac_pulse_num), .pulse(p2_wrt), .pulse_height_out(p2_data), .sample_done(sample_done), .sample_req(sample_req_sync1) ); wire ch2_clk_oddr; ODDR #( .DDR_CLK_EDGE("SAME_EDGE"), .INIT(1'b0), .SRTYPE("SYNC") ) ODDR_ch2_clk ( .Q (ch2_clk_oddr), .C (adc_clk), .CE(1'b1), .D1(1'b1), .D2(1'b0), .R (1'b0), .S (1'b0) ); OBUF OBUF_ch2_clk ( .I(ch2_clk_oddr), .O(ch2_clk) ); wire p2_clk_oddr; ODDR #( .DDR_CLK_EDGE("SAME_EDGE"), .INIT(1'b0), .SRTYPE("SYNC") ) ODDR_p2_clk ( .Q (p2_clk_oddr), .C (dac_clk), .CE(1'b1), .D1(1'b1), .D2(1'b0), .R (1'b0), .S (1'b0) ); OBUF OBUF_p2_clk ( .I(p2_clk_oddr), .O(p2_clk) ); // ------------------------------------------------------------------------- // ADC // ------------------------------------------------------------------------- (* MARK_DEBUG="true" *) logic [ADC_DATA_WIDTH*PACK_FACTOR-1:0] accum_m_axis_tdata; (* MARK_DEBUG="true" *) logic acum_m_axis_tvalid; sampler #( .DATA_WIDTH(ADC_DATA_WIDTH), .PACK_FACTOR(PACK_FACTOR), .PROCESS_MODE(PROCESS_MODE) ) sampler_dut ( .clk_in(adc_clk), .rst(adc_rst), .data_in(ch2_data), .out_of_range(ch2_otr), .m_axis_tdata(accum_m_axis_tdata), .m_axis_tvalid(acum_m_axis_tvalid), .smp_num(adc_pulse_period), .sample_req(sample_req), .sample_done(sample_done_sync1) ); // ------------------------------------------------------------------------- // Accumulator // ------------------------------------------------------------------------- accumulator_top #( .DATA_WIDTH(ADC_DATA_WIDTH), .ACCUM_WIDTH(ACCUM_WIDTH), .N_MAX(N_MAX), .WINDOW_SIZE(WINDOW_SIZE), .PACKET_SIZE(PACKET_SIZE) ) accumulator_top_dut ( .clk_in(adc_clk), .rst(adc_rst), .s_axis_tdata(accum_m_axis_tdata), .s_axis_tvalid(acum_m_axis_tvalid), .start(adc_start), .smp_num(adc_pulse_period), .seq_num(adc_pulse_num), .eth_clk_in(gmii_tx_clk), .req_ready(req_ready), .send_req(send_req), .m_axis_tdata(s_axis_tx_tdata), .m_axis_tvalid(s_axis_tx_tvalid), .m_axis_tready(s_axis_tx_tready), .m_axis_tlast(s_axis_tx_tlast), .finish(finish) ); // ------------------------------------------------------------------------- // Simple LED status // ------------------------------------------------------------------------- assign led[0] = clk_wiz_locked; assign led[1] = m_axis_rx_tvalid; assign led[2] = dac_start; endmodule