`timescale 1ns / 1ps module tb_reflectometer; // parameters localparam int unsigned DAC_DATA_WIDTH = 14; localparam int unsigned ADC_DATA_WIDTH = 12; localparam PACK_FACTOR = 1; // not used in TB localparam PROCESS_MODE = 0; // 0 - uint, 1 - int localparam ZERO_LEVEL = 8192; // DAC zero voltage representation (2^14 / 2) localparam ACCUM_WIDTH = 32; // accumulator number bit witdth localparam N_MAX = 4096; // max value of windows to average by experiments localparam WINDOW_SIZE = 65; // fixed subwindow size to average by time localparam PACKET_SIZE = 1024; // bytes per UDP packet // DUT signals logic clk200, clk_eth_phy_tx, clk_eth_phy_rx; logic rst_n; wire [3:0] status_leds; // [ None, dac_start, m_axis_valid, clk_wiz_locked ] wire dac_clk, dac_en; wire [DAC_DATA_WIDTH-1:0] dac_data; wire adc_clk; logic adc_otr; logic [ADC_DATA_WIDTH-1:0] adc_data; wire [7:0] s_axis_tx_tdata; wire s_axis_tx_tvalid; logic s_axis_tx_tready; wire s_axis_tx_tlast; logic phy_ready; wire accum_tx_start; logic [7:0] m_axis_rx_tdata; logic m_axis_rx_tvalid; logic m_axis_rx_tlast; wire m_axis_rx_tready; // DUT reflectometer_top #( .DAC_DATA_WIDTH(DAC_DATA_WIDTH), .ADC_DATA_WIDTH(ADC_DATA_WIDTH), .PACK_FACTOR(PACK_FACTOR), .PROCESS_MODE(PROCESS_MODE), .ZERO_LEVEL(ZERO_LEVEL), .ACCUM_WIDTH(ACCUM_WIDTH), .N_MAX(N_MAX), .WINDOW_SIZE(WINDOW_SIZE), .PACKET_SIZE(PACKET_SIZE) ) DUT ( .sys_clk(clk200), // main clk 200 mhz .rst_n(rst_n), // rst_n .led(status_leds), // indication [3:0] .gmii_rx_clk(clk_eth_phy_rx), // ext. clk from PHY .gmii_tx_clk(clk_eth_phy_tx), // ext. clk from PHY // accumulated data stream .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), // controller data stream .m_axis_rx_tdata(m_axis_rx_tdata), .m_axis_rx_tvalid(m_axis_rx_tvalid), .m_axis_rx_tlast(m_axis_rx_tlast), .m_axis_rx_tready(m_axis_rx_tready), .req_ready(phy_ready), // AXI-stream requester ready .send_req(accum_tx_start), // AXI-stream start transmit .p2_clk(dac_clk), // DAC clk .p2_data(dac_data), // DAC [DAC_DATA_WIDTH-1:0] data .p2_wrt(dac_en), // DAC write enable .ch2_clk(adc_clk), // ADC clk .ch2_data(adc_data), // ADC [ADC_DATA_WIDTH-1:0] data .ch2_otr(adc_otr) // ADC signal out-of-range ); // clocks initial begin // 200 MHz clk200 = 1'b0; forever #2.5 clk200 = ~clk200; end initial begin // 125 MHz clk_eth_phy_tx = 1'b0; forever #4 clk_eth_phy_tx = ~clk_eth_phy_tx; end initial begin // 125 MHz clk_eth_phy_rx = 1'b0; forever #4 clk_eth_phy_rx = ~clk_eth_phy_rx; end // ADC input noise simulation always @(posedge adc_clk or negedge rst_n) begin if (!rst_n) begin adc_data <= '0; end else begin adc_data <= $urandom() & ((1 << ADC_DATA_WIDTH) - 1); end end assign adc_otr = 1'b0; // some helpers for controller axis // GAME PLAN // 1. setup reflectometer // 2. create some reference signal with noise + virtual ADC // 3. setup m_axis endpoint for controller to start reflectometer (create multiple tasks) // 4. setup s_axis endpoint for data gathering and plotting // 5. check standalone reflectometer // 6. add reference signal averaging loop throw generator pulse posedge detection // 7. visual comparision of reference VS reflectometer // 8. add statistics for signal comparision (MSE/RMSE) // main TB initial begin // setup rst_n = 1'b0; s_axis_tx_tready = 1'b0; m_axis_rx_tdata = 1'b0; m_axis_rx_tvalid = 1'b0; m_axis_rx_tlast = 1'b0; phy_ready = 1'b0; // startup #100; rst_n = 1'b1; wait(DUT.clk_wiz_ctrl_inst.locked == 1'b1); #20; $display("=== clocks ready / wiz. locked ==="); #40; $display("=== ALL BASIC TESTS PASSED ==="); $finish; end endmodule