`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_p, input sys_clk_n, input rst_n, output [3:0] led, output e_reset, output e_mdc, inout e_mdio, output [3:0] rgmii_txd, output rgmii_txctl, output rgmii_txc, input [3:0] rgmii_rxd, input rgmii_rxctl, input rgmii_rxc, // DAC (* MARK_DEBUG="true" *) output debug_dac // ADC input [ADC_DATA_WIDTH-1:0] adc_data_in; input adc_out_of_range; ); // temp wire p2_clk; wire p2_wrt; (* MARK_DEBUG="true" *) wire [13:0] p2_data; assign debug_dac = p2_data[13]; // ------------------------------------------------------------------------- // Internal GMII-side signals // ------------------------------------------------------------------------- wire [7:0] gmii_txd; wire gmii_tx_en; wire gmii_tx_er; wire gmii_tx_clk; wire gmii_crs; wire gmii_col; wire [7:0] gmii_rxd_i; wire gmii_rx_dv; wire gmii_rx_er; wire gmii_rx_clk; wire [31:0] pack_total_len; wire e_rx_dv; wire [7:0] e_rxd; wire e_tx_en; wire [7:0] e_txd; wire e_rst_n; wire sys_clk; wire duplex_mode; assign duplex_mode = 1'b1; // ------------------------------------------------------------------------- // System clock buffer (200 MHz differential input) // ------------------------------------------------------------------------- IBUFDS sys_clk_ibufgds ( .O (sys_clk), .I (sys_clk_p), .IB (sys_clk_n) ); // ------------------------------------------------------------------------- // 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) ); // ------------------------------------------------------------------------- // GMII <-> RGMII conversion // ------------------------------------------------------------------------- util_gmii_to_rgmii util_gmii_to_rgmii_m0 ( .reset (1'b0), .rgmii_td (rgmii_txd), .rgmii_tx_ctl (rgmii_txctl), .rgmii_txc (rgmii_txc), .rgmii_rd (rgmii_rxd), .rgmii_rx_ctl (rgmii_rxctl), .gmii_rx_clk (gmii_rx_clk), .gmii_txd (e_txd), .gmii_tx_en (e_tx_en), .gmii_tx_er (1'b0), .gmii_tx_clk (gmii_tx_clk), .gmii_crs (gmii_crs), .gmii_col (gmii_col), .gmii_rxd (gmii_rxd_i), .rgmii_rxc (rgmii_rxc), .gmii_rx_dv (gmii_rx_dv), .gmii_rx_er (gmii_rx_er), .speed_selection (2'b10), .duplex_mode (duplex_mode) ); // ------------------------------------------------------------------------- // GMII arbitration / adaptation // ------------------------------------------------------------------------- gmii_arbi arbi_inst ( .clk (gmii_tx_clk), .rst_n (rst_n), .speed (2'b10), .link (1'b1), .pack_total_len (pack_total_len), .e_rst_n (e_rst_n), .gmii_rx_dv (gmii_rx_dv), .gmii_rxd (gmii_rxd_i), .gmii_tx_en (gmii_tx_en), .gmii_txd (gmii_txd), .e_rx_dv (e_rx_dv), .e_rxd (e_rxd), .e_tx_en (e_tx_en), .e_txd (e_txd) ); // ------------------------------------------------------------------------- // axis_mac interface // RX stream from Ethernet goes into controller // TX stream is unused for now // ------------------------------------------------------------------------- wire req_ready; reg send_req; reg [15:0] data_length; reg [7:0] s_axis_tx_tdata; reg s_axis_tx_tvalid; wire s_axis_tx_tready; reg s_axis_tx_tlast; (* MARK_DEBUG="true" *) wire [7:0] m_axis_rx_tdata; (* MARK_DEBUG="true" *) wire m_axis_rx_tvalid; (* MARK_DEBUG="true" *) wire m_axis_rx_tlast; (* MARK_DEBUG="true" *) wire m_axis_rx_tready; // Always ready to accept RX payload bytes assign m_axis_rx_tready = 1'b1; // TX disabled always @(*) begin send_req = 1'b0; data_length = 16'd0; s_axis_tx_tdata = 8'd0; s_axis_tx_tvalid= 1'b0; s_axis_tx_tlast = 1'b0; end axis_mac axis_mac0 ( .gmii_tx_clk (gmii_tx_clk), .gmii_rx_clk (gmii_rx_clk), .rst_n (e_rst_n), .gmii_rx_dv (e_rx_dv), .gmii_rxd (e_rxd), .gmii_tx_en (gmii_tx_en), .gmii_txd (gmii_txd), .send_req (send_req), .data_length (data_length), .req_ready (req_ready), .s_axis_tx_tdata (s_axis_tx_tdata), .s_axis_tx_tvalid (s_axis_tx_tvalid), .s_axis_tx_tready (s_axis_tx_tready), .s_axis_tx_tlast (s_axis_tx_tlast), .m_axis_rx_tdata (m_axis_rx_tdata), .m_axis_rx_tvalid (m_axis_rx_tvalid), .m_axis_rx_tready (m_axis_rx_tready), .m_axis_rx_tlast (m_axis_rx_tlast) ); // PHY reset helper from your original example reset reset_m0 ( .clk (sys_clk), .key1 (rst_n), .rst_n (e_reset) ); // MDIO lines are not driven here yet assign e_mdc = 1'b0; assign e_mdio = 1'bz; // ------------------------------------------------------------------------- // Controller reset // Use both external reset and clk_wiz lock // ------------------------------------------------------------------------- wire ctrl_rst_n = rst_n & clk_wiz_locked; // ------------------------------------------------------------------------- // Debug finish generator (still used here, since generator doesn't have finish signal) // // After each adc_start pulse generates one finish pulse after some delay. // This is just for first bring-up so the controller can leave busy state // If you don't want this, replace with: // wire finish_dbg = 1'b0; // ------------------------------------------------------------------------- (* 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 (), // controller internally always ready in current version .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 // ------------------------------------------------------------------------- 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) ); // dac clk mgt 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 // ------------------------------------------------------------------------- logic [DATA_WIDTH*PACK_FACTOR-1:0] accum_m_axis_tdata; 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(adc_data_in), .out_of_range(adc_out_of_range), .m_axis_tdata(accum_m_axis_tdata), .m_axis_tvalid(acum_m_axis_tvalid) ); // ------------------------------------------------------------------------- // 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_rx_clk), .req_ready(req_ready), .send_req(send_req), .m_axis_tdata(m_axis_rx_tdata), .m_axis_tvalid(m_axis_rx_tvalid), .m_axis_tready(m_axis_rx_tready), .m_axis_tlast(m_axis_rx_tlast), .finish(finish) ); // ------------------------------------------------------------------------- // Simple LED status // ------------------------------------------------------------------------- assign led[0] = clk_wiz_locked; assign led[1] = m_axis_rx_tvalid; assign led[2] = dac_start; assign led[3] = debug_dac; endmodule