trial SV test

This commit is contained in:
otroubi
2026-09-07 12:50:51 +03:00
parent 7c94cbca56
commit 4a092a0ece
3 changed files with 1183 additions and 373 deletions
@@ -1,373 +0,0 @@
`timescale 1ns / 1ps
`include "interfaces.svh"
module reflectometer_tb;
//------------------------------------------------------------
// Параметры
//------------------------------------------------------------
localparam int unsigned DAC_DATA_WIDTH = 14;
localparam int unsigned ADC_DATA_WIDTH = 12;
localparam LOGIC_ZERO_LEVEL = 0; // DAC -5V for logic zero
localparam VOLTAGE_ZERO_LEVEL = 2**(DAC_DATA_WIDTH-1); // DAC 0V for logic zero
localparam PACK_FACTOR = 1; // not used in TB
localparam PROCESS_MODE = 0; // 0 - uint, 1 - int. Current accumulator don't support signed sum
localparam ACCUM_WIDTH = 32; // accumulator number bit witdth
localparam N_MAX = 4096; // max value of windows to average by experiments
localparam PACKET_SIZE = 1024; // bytes per UDP packet
localparam int REQUEST_TIMEOUT = 3 * PACKET_SIZE; // timeout for packet receiving from accumulator
localparam ZERO_LEVEL = LOGIC_ZERO_LEVEL; // "logic" VS "voltage"
localparam CLK_ETH_PHY_PERIOD = 8.000; // 125 MHz
localparam CLK_REF_PERIOD = 5.000; // 200 MHz
//------------------------------------------------------------
// Глобальные перменные
//------------------------------------------------------------
int unsigned WINDOW_SIZE = 65; // fixed subwindow size to average by time
//------------------------------------------------------------
// Тактовые сигналы и сброс
//------------------------------------------------------------
logic clk_ref = 1'b0; // 200 MHz
logic clk_eth_phy = 1'b0; // common for RX & TX
logic rst_n = 1'b0;
//------------------------------------------------------------
// Управление и конфиг DUT
//------------------------------------------------------------
logic [31:0] window_size;
// AXI-S интерфейс для управления
axis_if axis_control_if (
.clk(clk_eth_phy),
.rst_n(rst_n)
);
//------------------------------------------------------------
// Входы DUT
//------------------------------------------------------------
// ADC интерфейс
wire clk_adc;
wire adc_otr;
wire [ADC_DATA_WIDTH-1:0] adc_data;
//------------------------------------------------------------
// Выходы
//------------------------------------------------------------
// Статусы
wire mmcm_locked;
wire workflow_done;
wire processing_done;
// DAC интерфейс
wire clk_dac;
wire dac_wrt;
wire [DAC_DATA_WIDTH-1:0] dac_data;
// AXI-S интерфейс для данных
axis_if axis_accumulator_if (
.clk(clk_eth_phy),
.rst_n(rst_n)
);
//------------------------------------------------------------
// Внутренние сигналы тестбенча
//------------------------------------------------------------
// Интерфейс хендшейка с MAC-PHY
wire send_request;
logic request_ready;
// Сигнал между ЦАП и АЦП
real signal_voltage;
//------------------------------------------------------------
// Virtual DAC
//------------------------------------------------------------
virtual_dac_model #( // default voltage range is +/- 5V
.DAC_DATA_WIDTH(DAC_DATA_WIDTH)
// ,.VOLTAGE_GAIN(2)
) virtual_dac (
.clk_i(clk_dac),
.wrt_i(dac_wrt),
.data_i(dac_data),
.voltage_o(signal_voltage)
);
//------------------------------------------------------------
// Virtual ADC
//------------------------------------------------------------
virtual_adc_model #( // default voltage range is +/- 5V
.ADC_DATA_WIDTH(ADC_DATA_WIDTH)
) virtual_adc (
.clk_i(clk_adc),
.voltage_i(signal_voltage),
.otr_o(adc_otr),
.data_o(adc_data)
);
//------------------------------------------------------------
// Statistics processing
//------------------------------------------------------------
//------------------------------------------------------------
// Config handler
//------------------------------------------------------------
//------------------------------------------------------------
// 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),
.PACKET_SIZE(PACKET_SIZE)
) DUT (
.clk_in(clk_ref),
.rst_n(rst_n),
// Status
.locked(mmcm_locked),
.workflow_done(workflow_done),
.processing_done(processing_done),
// Accumulator AXI-S bus
.clk_axis_accumulator(clk_eth_phy), // GMII PHY RX clock
.axis_accumulator(axis_accumulator_if.master),
// Control AXI-S bus
.clk_axis_control(clk_eth_phy), // GMII PHY TX clock
.axis_control(axis_control_if.slave),
.window_size(window_size), // direct signal crutch (old controller)
// RTL-MAC handshake
.request_ready(request_ready),
.send_request(send_request),
// DAC
.dac_clk_o(clk_dac),
.dac_data(dac_data),
.dac_wrt(dac_wrt),
// ADC
.adc_clk_o(clk_adc),
.adc_data(adc_data),
.adc_otr(adc_otr)
);
assign window_size = WINDOW_SIZE;
//------------------------------------------------------------
// Тактовые сигналы
//------------------------------------------------------------
initial begin
forever #(CLK_REF_PERIOD/2) clk_ref = ~clk_ref;
end
initial begin
forever #(CLK_ETH_PHY_PERIOD/2) clk_eth_phy = ~clk_eth_phy;
end
//------------------------------------------------------------
// Таски для тестирования
//------------------------------------------------------------
// Таски работы с AXI-Stream
task automatic dut_soft_reset(virtual axis_if#(8).tb vif);
logic [7:0] tx_packet[];
tx_packet = '{8'h0f};
vif.master_send(tx_packet);
endtask
task automatic dut_start(virtual axis_if#(8).tb vif);
logic [7:0] tx_packet[];
tx_packet = '{8'hf0};
vif.master_send(tx_packet);
endtask
task automatic dut_send_system_config(
virtual axis_if#(8).tb vif,
input logic [31:0] pulse_width,
input logic [31:0] pulse_period,
input logic [15:0] pulse_num,
input logic [13:0] pulse_height, // achtung! p_height strictly must have 14 bits of width
input logic [31:0] pulse_period_adc,
input logic [31:0] window_size
);
// Создаем временный фиксированный массив и упаковываем всё одной строкой
logic [7:0] tx_packet[];
// Ахтунг, 14-битный ЦАП захардкожен
if (DAC_DATA_WIDTH != 14)
$display("[WARNING] -dut_send_system_config- Default pulse height (DAC bitwidth) is equal to 14. Be aware, controller packet structure is coded for 14 bits");
tx_packet = '{
8'h88, // Команда
pulse_width[7:0], pulse_width[15:8], pulse_width[23:16], pulse_width[31:24],
pulse_period[7:0], pulse_period[15:8], pulse_period[23:16], pulse_period[31:24],
pulse_num[7:0], pulse_num[15:8], pulse_height[7:0], 8'({2'b00, pulse_height[13:8]}),
pulse_period_adc[7:0], pulse_period_adc[15:8], pulse_period_adc[23:16], pulse_period_adc[31:24]
};
vif.master_send(tx_packet);
// TODO remove for new controller
WINDOW_SIZE = window_size;
endtask
// Таски сбора статистики
task automatic dut_read_output(
virtual axis_if#(8).tb vif,
input int sample_num,
input bit randomize_recv_delays,
output int output_data[]
);
logic [7:0] rx_packet[];
logic [ACCUM_WIDTH-1:0] data_packet[];
int numbers_per_packet = PACKET_SIZE/(ACCUM_WIDTH/8);
int packet_num = $ceil(real'(sample_num / WINDOW_SIZE) / real'(numbers_per_packet));
int timeout_flag = 0;
int packet_counter = 0;
if (sample_num % WINDOW_SIZE) begin
$display("[ERROR] -dut_read_output- Sample_num must be multiple of WINDOW_SIZE: %0d %% %0d = %0d", sample_num, WINDOW_SIZE, sample_num % WINDOW_SIZE);
$finish;
end
data_packet = new[numbers_per_packet];
output_data = new[numbers_per_packet * packet_num];
// count send_request pulses (equal to number of packets)
fork
begin : packet_counter_proc
forever begin
@(posedge clk_eth_phy);
if(send_request === 1)
packet_counter++;
end
end
join_none
// Wait until reflectometer done sampling and averaging
wait(processing_done == 1);
// recv loop
// если число пакетов превышает заложенное предрассчитанное значение -- ошибка
fork : recv_loop_proc
begin
// packet recv loop
forever begin
if (packet_counter > packet_num) begin
$display("[ERROR] -dut_read_output- Packet overflow detected. Number of data packets exceeds expected amount of packets");
$finish;
end
if (randomize_recv_delays)
repeat($urandom_range(0, 500)) @(posedge clk_eth_phy);
timeout_flag = 0;
fork : receive_packet_timeout
begin
request_ready = 1;
vif.slave_recv(rx_packet);
request_ready = 0;
end
begin
repeat(REQUEST_TIMEOUT) @(posedge clk_eth_phy);
timeout_flag = 1;
end
join_any
disable receive_packet_timeout;
if (timeout_flag) begin
$display("[ERROR] -dut_read_output- Timeout detected when receiving packet");
$finish;
end
if (rx_packet.size() != PACKET_SIZE) begin
$display("[ERROR] -dut_read_output- Wrong packet size received: %0d bytes received, %0d bytes expected", rx_packet.size(), PACKET_SIZE);
$finish;
end
// unpack values
data_packet = {<< byte {rx_packet}};
data_packet = {<< ACCUM_WIDTH {data_packet}};
// copy and convert values
for (int j = 0; j < data_packet.size(); j++) begin
output_data[(packet_counter-1) * data_packet.size() + j] = int'(data_packet[j]);
end
end
end
begin
// IP workflow completion event
wait(workflow_done == 1);
end
join_any
disable recv_loop_proc;
disable packet_counter_proc;
if (packet_counter != packet_num) begin
$display("[ERROR] -dut_read_output- Wrong number of packets received: %0d received, %0d expected", packet_counter, packet_num);
$finish;
end
endtask
// Основная таска типового теста
// todo
//------------------------------------------------------------
// ОСНОВНОЙ ПРОЦЕСС ТЕСТИРОВАНИЯ
//------------------------------------------------------------
initial begin
int output_data[];
automatic virtual axis_if.tb control_vif = axis_control_if.tb;
automatic virtual axis_if.tb accumulator_vif = axis_accumulator_if.tb;
$display("[TB] DUT initializaton");
// Инициализация
request_ready = 0;
rst_n = 0;
#100;
rst_n = 1;
wait(mmcm_locked === 1'b1);
#150;
$display("[TB] MMCM locked");
dut_soft_reset(control_vif);
#100;
// Тесты
$display("[TB] Tests start");
dut_send_system_config(
.vif(control_vif),
.pulse_width(32'd123),
.pulse_period(32'd5000),
.pulse_num(16'd1),
.pulse_height(14'd15000), // 0V
.pulse_period_adc(32'd2600),
.window_size(1)
);
#100;
dut_start(control_vif);
dut_read_output(
.vif(accumulator_vif),
.sample_num(2600),
.randomize_recv_delays(0),
.output_data(output_data)
);
#1000;
$display("Received %0d numbers", output_data.size());
for (int i = 0; i < output_data.size(); i++) begin
$write("%0d ", output_data[i]);
end
$display("");
$display("[TB] ALL PASSED");
$finish;
end
endmodule
@@ -0,0 +1,861 @@
`timescale 1ns / 1ps
`define MEASURE_CLK(clk, period) \
begin \
realtime t1, t2; \
@(posedge clk); \
t1 = $realtime; \
@(posedge clk); \
t2 = $realtime; \
period = t2 - t1; \
end
`define ERR_CHECK \
total_tests++; \
if (result_flag) begin \
total_failed_tests++; \
$error("Test #%0d failed. Err code: %0d", total_tests, result_flag); \
end \
module reflectometer_tb;
//------------------------------------------------------------
// Параметры
//------------------------------------------------------------
localparam int unsigned DAC_DATA_WIDTH = 14;
localparam int unsigned ADC_DATA_WIDTH = 12;
localparam LOGIC_ZERO_LEVEL = 0; // DAC -5V for logic zero
localparam VOLTAGE_ZERO_LEVEL = 2**(DAC_DATA_WIDTH-1); // DAC 0V for logic zero
localparam PACK_FACTOR = 1; // not used in TB
localparam PROCESS_MODE = 0; // 0 - uint, 1 - int. Current accumulator don't support signed sum
localparam ACCUM_WIDTH = 32; // accumulator number bit witdth
localparam N_MAX = 4096; // max value of windows to average by experiments
localparam PACKET_SIZE = 1024; // bytes per UDP packet
localparam int unsigned RD_FIFO_WIDTH = 32;
localparam int REQUEST_TIMEOUT = 3 * PACKET_SIZE; // timeout for packet receiving from accumulator
localparam ZERO_LEVEL = LOGIC_ZERO_LEVEL; // "logic" VS "voltage"
localparam CLK_ETH_PHY_PERIOD = 8.000; // 125 MHz
localparam CLK_REF_PERIOD = 5.000; // 200 MHz
localparam int unsigned AXI_DATA_WIDTH = 32;
localparam int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8;
localparam int unsigned AXI_USER_WIDTH = 1;
localparam int unsigned AXI_ID_WIDTH = 8;
localparam int unsigned AXI_MAX_BURST_LEN = 16;
localparam int unsigned AXIS_DATA_WIDTH = AXI_DATA_WIDTH;
localparam int unsigned AXIS_LAST_ENABLE = 1;
localparam int unsigned AXIS_ID_ENABLE = 1;
localparam int unsigned AXIS_DEST_ENABLE = 0;
localparam int unsigned AXIS_USER_ENABLE = 1;
localparam int unsigned ENABLE_SG = 0;
localparam int unsigned ENABLE_UNALIGNED = 0;
localparam int unsigned PIPELINE_OUTPUT = 0;
realtime CLK_ADC_PERIOD;
realtime CLK_DAC_PERIOD;
//------------------------------------------------------------
// Тактовые Ñигналы и ÑброÑ
//------------------------------------------------------------
logic clk_ref = 1'b0; // 200 MHz
logic rst_n = 1'b0;
//------------------------------------------------------------
// Входы DUT
//------------------------------------------------------------
// ADC интерфейÑ
wire clk_adc;
wire adc_otr;
wire [ADC_DATA_WIDTH-1:0] adc_data;
//------------------------------------------------------------
// Выходы
//------------------------------------------------------------
// СтатуÑÑ‹
wire mmcm_locked;
// DAC интерфейÑ
wire clk_dac;
wire dac_wrt;
wire [DAC_DATA_WIDTH-1:0] dac_data;
//------------------------------------------------------------
// Внутренние Ñигналы теÑтбенча
//------------------------------------------------------------
// Сигнал между ЦÐП и ÐЦП
real signal_voltage;
//------------------------------------------------------------
// Virtual DAC
//------------------------------------------------------------
virtual_dac_model #( // default voltage range is +/- 5V
.DAC_DATA_WIDTH(DAC_DATA_WIDTH)
// ,.VOLTAGE_GAIN(2)
) virtual_dac (
.clk_i(clk_dac),
.wrt_i(dac_wrt),
.data_i(dac_data),
.voltage_o(signal_voltage)
);
//------------------------------------------------------------
// Virtual ADC
//------------------------------------------------------------
virtual_adc_model #( // default voltage range is +/- 5V
.ADC_DATA_WIDTH(ADC_DATA_WIDTH)
) virtual_adc (
.clk_i(clk_adc),
.voltage_i(signal_voltage),
.otr_o(adc_otr),
.data_o(adc_data)
);
//------------------------------------------------------------
// DUT
//------------------------------------------------------------
tb_full_reflectometer #(
.AXI_DATA_WIDTH(AXI_DATA_WIDTH),
.AXI_STRB_WIDTH(AXI_STRB_WIDTH),
.AXI_USER_WIDTH(AXI_USER_WIDTH),
.AXI_ID_WIDTH(AXI_ID_WIDTH),
.AXI_MAX_BURST_LEN(AXI_MAX_BURST_LEN),
.AXIS_DATA_WIDTH(AXIS_DATA_WIDTH),
.AXIS_LAST_ENABLE(AXIS_LAST_ENABLE),
.AXIS_ID_ENABLE(AXIS_ID_ENABLE),
.AXIS_DEST_ENABLE(AXIS_DEST_ENABLE),
.AXIS_USER_ENABLE(AXIS_USER_ENABLE),
.ENABLE_SG(ENABLE_SG),
.ENABLE_UNALIGNED(ENABLE_UNALIGNED),
.PIPELINE_OUTPUT(PIPELINE_OUTPUT),
.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),
.PACKET_SIZE(PACKET_SIZE),
.RD_FIFO_WIDTH(RD_FIFO_WIDTH)
) DUT (
.ctrl_clk(clk_ref),
.rst_n(rst_n),
// Status
.locked(mmcm_locked),
// m_axil config
.s_axil_awaddr (s_axil_awaddr),
.s_axil_awprot (s_axil_awprot),
.s_axil_awvalid(s_axil_awvalid),
.s_axil_awready(s_axil_awready),
.s_axil_wdata (s_axil_wdata),
.s_axil_wstrb (s_axil_wstrb),
.s_axil_wvalid (s_axil_wvalid),
.s_axil_wready (s_axil_wready),
.s_axil_bresp (s_axil_bresp),
.s_axil_bvalid (s_axil_bvalid),
.s_axil_bready (s_axil_bready),
.s_axil_araddr (s_axil_araddr),
.s_axil_arprot (s_axil_arprot),
.s_axil_arvalid(s_axil_arvalid),
.s_axil_arready(s_axil_arready),
.s_axil_rdata (s_axil_rdata),
.s_axil_rresp (s_axil_rresp),
.s_axil_rvalid (s_axil_rvalid),
.s_axil_rready (s_axil_rready),
// s_axis dma reader
.m_axis_tdata (),
.m_axis_tkeep (),
.m_axis_tstrb (),
.m_axis_tlast (),
.m_axis_tid (),
.m_axis_tdest (),
.m_axis_tuser (),
.m_axis_tvalid(),
.m_axis_tready(1'b0),
// m_axi read_res
.s_axi_awid(s_axi_awid),
.s_axi_awaddr(s_axi_awaddr),
.s_axi_awlen(s_axi_awlen),
.s_axi_awsize(s_axi_awsize),
.s_axi_awburst(s_axi_awburst),
.s_axi_awlock(s_axi_awlock),
.s_axi_awcache(s_axi_awcache),
.s_axi_awprot(s_axi_awprot),
.s_axi_awqos(s_axi_awqos),
.s_axi_awregion(s_axi_awregion),
.s_axi_awuser(s_axi_awuser),
.s_axi_awvalid(s_axi_awvalid),
.s_axi_awready(s_axi_awready),
.s_axi_wdata(s_axi_wdata),
.s_axi_wstrb(s_axi_wstrb),
.s_axi_wlast(s_axi_wlast),
.s_axi_wuser(s_axi_wuser),
.s_axi_wvalid(s_axi_wvalid),
.s_axi_wready(s_axi_wready),
.s_axi_bid(s_axi_bid),
.s_axi_bresp(s_axi_bresp),
.s_axi_buser(s_axi_buser),
.s_axi_bvalid(s_axi_bvalid),
.s_axi_bready(s_axi_bready),
.s_axi_arid(s_axi_arid),
.s_axi_araddr(s_axi_araddr),
.s_axi_arlen(s_axi_arlen),
.s_axi_arsize(s_axi_arsize),
.s_axi_arburst(s_axi_arburst),
.s_axi_arlock(s_axi_arlock),
.s_axi_arcache(s_axi_arcache),
.s_axi_arprot(s_axi_arprot),
.s_axi_arqos(s_axi_arqos),
.s_axi_arregion(s_axi_arregion),
.s_axi_aruser(s_axi_aruser),
.s_axi_arvalid(s_axi_arvalid),
.s_axi_arready(s_axi_arready),
.s_axi_rid(s_axi_rid),
.s_axi_rdata(s_axi_rdata),
.s_axi_rresp(s_axi_rresp),
.s_axi_rlast(s_axi_rlast),
.s_axi_ruser(s_axi_ruser),
.s_axi_rvalid(s_axi_rvalid),
.s_axi_rready(s_axi_rready),
// DAC
.dac_clk_o(clk_dac),
.dac_data(dac_data),
.dac_wrt(dac_wrt),
// ADC
.adc_clk_o(clk_adc),
.adc_data(adc_data),
.adc_otr(adc_otr)
);
//------------------------------------------------------------
// Òàêòîâûå ñèãíàëû
//------------------------------------------------------------
initial begin
forever #(CLK_REF_PERIOD/2) clk_ref = ~clk_ref;
end
//------------------------------------------------------------
// Òàñêè äëÿ òåñòèðîâàíèÿ
//------------------------------------------------------------
// Òàñêè ðàáîòû ñ AXI-Lite, AXI
// Òàñêè äëÿ ðàáîòû ñ DMA
// Òàñêà êîíôèãóðàöèîííàÿ
task automatic dut_soft_reset(virtual axis_if#(8).tb vif);
logic [7:0] tx_packet[];
tx_packet = '{8'h0f};
vif.master_send(tx_packet);
endtask
task automatic dut_start(virtual axis_if#(8).tb vif);
logic [7:0] tx_packet[];
tx_packet = '{8'hf0};
vif.master_send(tx_packet);
endtask
task automatic dut_send_system_config(
virtual axis_if#(8).tb vif,
input logic [31:0] pulse_width,
input logic [31:0] pulse_period,
input logic [15:0] pulse_num,
input logic [13:0] pulse_height, // achtung! p_height strictly must have 14 bits of width
input logic [31:0] pulse_period_adc,
input logic [31:0] window_size
);
// Ñîçäàåì âðåìåííûé ôèêñèðîâàííûé ìàññèâ è óïàêîâûâàåì âñ¸ îäíîé ñòðîêîé
logic [7:0] tx_packet[];
// Àõòóíã, 14-áèòíûé ÖÀÏ çàõàðäêîæåí
if (DAC_DATA_WIDTH != 14)
$warning("[WARNING] -dut_send_system_config- Default pulse height (DAC bitwidth) is equal to 14. Be aware, controller packet structure is coded for 14 bits");
tx_packet = '{
8'h88, // Êîìàíäà
pulse_width[7:0], pulse_width[15:8], pulse_width[23:16], pulse_width[31:24],
pulse_period[7:0], pulse_period[15:8], pulse_period[23:16], pulse_period[31:24],
pulse_num[7:0], pulse_num[15:8], pulse_height[7:0], 8'({2'b00, pulse_height[13:8]}),
pulse_period_adc[7:0], pulse_period_adc[15:8], pulse_period_adc[23:16], pulse_period_adc[31:24]
};
vif.master_send(tx_packet);
// TODO remove for new controller
window_size_port = window_size;
endtask
// Òàñêè ñáîðà ñòàòèñòèêè
task automatic dut_read_output(
virtual axis_if#(8).tb vif,
input int sample_num,
input int window_size,
input bit randomize_recv_delays,
output int output_data[]
);
logic [7:0] rx_packet[];
logic [ACCUM_WIDTH-1:0] data_packet[];
int numbers_per_packet = PACKET_SIZE/(ACCUM_WIDTH/8);
int packet_num = $ceil(real'(sample_num / window_size) / real'(numbers_per_packet));
int timeout_flag = 0;
int packet_counter = 0;
if (sample_num % window_size) begin
$error("-dut_read_output- Sample_num must be multiple of window_size: %0d %% %0d = %0d", sample_num, window_size, sample_num % window_size);
$finish;
end
data_packet = new[numbers_per_packet];
output_data = new[numbers_per_packet * packet_num];
// count send_request pulses (equal to number of packets)
fork
begin : packet_counter_proc
forever begin
@(posedge clk_eth_phy);
if(send_request === 1)
packet_counter++;
end
end
join_none
// Wait until reflectometer done sampling and averaging
wait(processing_done == 1);
// recv loop
// åñëè ÷èñëî ïàêåòîâ ïðåâûøàåò çàëîæåííîå ïðåäðàññ÷èòàííîå çíà÷åíèå -- îøèáêà
fork : recv_loop_proc
begin
// packet recv loop
forever begin
if (packet_counter > packet_num) begin
$error("-dut_read_output- Packet overflow detected. Number of data packets exceeds expected amount of packets");
$finish;
end
if (randomize_recv_delays)
repeat($urandom_range(0, 500)) @(posedge clk_eth_phy);
timeout_flag = 0;
fork : receive_packet_timeout
begin
request_ready = 1;
vif.slave_recv(rx_packet);
request_ready = 0;
end
begin
repeat(REQUEST_TIMEOUT) @(posedge clk_eth_phy);
timeout_flag = 1;
end
join_any
disable receive_packet_timeout;
if (timeout_flag) begin
$error("-dut_read_output- Timeout detected when receiving packet");
$finish;
end
if (rx_packet.size() != PACKET_SIZE) begin
$error("-dut_read_output- Wrong packet size received: %0d bytes received, %0d bytes expected", rx_packet.size(), PACKET_SIZE);
$finish;
end
// unpack values
data_packet = {<< byte {rx_packet}};
data_packet = {<< ACCUM_WIDTH {data_packet}};
// copy and convert values
for (int j = 0; j < data_packet.size(); j++) begin
output_data[(packet_counter-1) * data_packet.size() + j] = int'(data_packet[j]);
end
end
end
begin
// IP workflow completion event
wait(workflow_done == 1);
end
join_any
disable recv_loop_proc;
disable packet_counter_proc;
if (packet_counter != packet_num) begin
$error("-dut_read_output- Wrong number of packets received: %0d received, %0d expected", packet_counter, packet_num);
$finish;
end
wait(processing_done == 0);
endtask
//------------------------------------------------------------
// Ôóíêöèè è òàñêè äëÿ âåðèôèêàöèè ñèãíàëîâ
//------------------------------------------------------------
// Òàñêà ãåíåðàöèè èäåàëüíîãî òåñòîâîãî ñèãíàëà
task automatic reference_signal(
input int pulse_width,
input int pulse_height,
input int pulse_period_adc,
input int window_size,
output real result[]
);
/*
Globals:
ADC and DAC clock periods,
Virtual ADC and DAC voltage steps
Task developed with assumption that first discrete values of DAC and ADC
are syncrhonized at t==0 and started simultaneously.
Gains and biases of virtual ADC & DAC are default and ranges are [-5V;5V].
Bitwidths may be altered.
Returned result[] array is an array of sums of voltage potentials in discrete time points.
Discrete samples summed over a time window.
result[time] = (voltage)
*/
int sample_num = pulse_period_adc / window_size; // total averaged output samples from accumulator
real current_signal_sample, partial_sum;
real ref_signal_active_voltage = virtual_dac.code_to_voltage(pulse_height);
real ref_signal_zero_voltage = virtual_dac.code_to_voltage(ZERO_LEVEL);
if (pulse_period_adc % window_size) begin
$error("-reference_signal- pulse_period_adc must be multiple of window_size: %0d %% %0d = %0d", pulse_period_adc, window_size, pulse_period_adc % window_size);
$finish;
end
result = new[sample_num];
partial_sum = 0;
for (int i = 0; i < pulse_period_adc; i++) begin
// var i in ADC timespace
// i == 0 is a t0 of pulse generation and sampling
current_signal_sample = (i*CLK_ADC_PERIOD <= pulse_width*CLK_DAC_PERIOD) ? ref_signal_active_voltage : ref_signal_zero_voltage;
partial_sum += current_signal_sample;
if (i % window_size == (window_size-1)) begin
result[i / window_size] = partial_sum;
partial_sum = 0;
end
end
endtask
// Ôóíêöèÿ ïðîâåðêè ðàçìåðîâ âûáîðîê
function automatic void check_size(
input real a[],
input real b[]
);
if (a.size() != b.size())
$fatal(1, "Array size mismatch: %0d != %0d",
a.size(), b.size());
if (a.size() == 0)
$error(1, "Empty array");
endfunction
// Ñðåäíåå ïî âûáîðêå
function automatic real array_mean(
input real a[]
);
real sum = 0.0;
foreach (a[i])
sum += a[i];
return sum / a.size();
endfunction
// MSE äâóõ âûáîðîê
function automatic real calc_mse(
input real a[],
input real b[]
);
real sum = 0.0;
check_size(a, b);
foreach (a[i]) begin
real err;
err = a[i] - b[i];
sum += err * err;
end
return sum / a.size();
endfunction
// NRMSE äâóõ âûáîðîê (íîðìèðîâàíèå RMSE)
function automatic real calc_nrmse(
input real a[],
input real b[]
);
const real EPS = 1e-12;
real mse, ms = 0;
mse = calc_mse(a, b);
foreach (a[i]) begin
ms += a[i] * a[i];
end
ms /= a.size();
return $sqrt(mse / (ms + EPS));
endfunction
// Ôóíêöèÿ ìîäóëÿ
function automatic real abs_f(input real x);
return (x < 0.0) ? -x : x;
endfunction
// Ìàêñèìàëüíàÿ àáñîëþòíàÿ îøèáêà
function automatic real calc_max_error(
input real a[],
input real b[]
);
real max_err = 0.0;
check_size(a, b);
foreach (a[i]) begin
real err;
err = abs_f(a[i] - b[i]);
if (err > max_err)
max_err = err;
end
return max_err;
endfunction
// Êîýôôèöèåíò êîððåëÿöèè Ïèðñîíà
function automatic real calc_pearson(
input real a[],
input real b[]
);
real mean_a;
real mean_b;
real numerator = 0.0;
real denom_a = 0.0;
real denom_b = 0.0;
check_size(a, b);
mean_a = array_mean(a);
mean_b = array_mean(b);
foreach (a[i]) begin
real da;
real db;
da = a[i] - mean_a;
db = b[i] - mean_b;
numerator += da * db;
denom_a += da * da;
denom_b += db * db;
end
if ((denom_a == 0.0) || (denom_b == 0.0))
return 0.0;
return numerator / $sqrt(denom_a * denom_b);
endfunction
// Âñïîìîãàòåëüíàÿ ôóíêöèÿ äëÿ âûâîäà ìàññèâà
function automatic void display_array_f(input real a[]);
$write("\t");
foreach(a[i])
$write("%f ", a[i]);
$write("\n");
endfunction
// Âñïîìîãàòåëüíàÿ ôóíêöèÿ äëÿ âûâîäà ìàññèâà
function automatic void display_array(input int a[]);
$write("\t");
foreach(a[i])
$write("%0d ", a[i]);
$write("\n");
endfunction
// Îñíîâíàÿ òàñêà òèïîâîãî òåñòà
task automatic run_test_case(
virtual axis_if#(8).tb ctrl_vif,
virtual axis_if#(8).tb accum_vif,
input int pulse_width,
input int pulse_period,
input int pulse_num,
input int pulse_height,
input int pulse_period_adc,
input int window_size,
input bit rand_recv_delays,
input bit use_reset,
output int result
);
int output_data[]; // raw accum values
real output_signal_v[]; // accum values after voltage conversion
real reference_signal_v[]; // reference signal voltage values
real nrmse, pearson, max_err; // error and correlation metrics
if (use_reset) begin
dut_soft_reset(ctrl_vif);
#100;
end
dut_send_system_config(
.vif(ctrl_vif),
.pulse_width(pulse_width),
.pulse_period(pulse_period),
.pulse_num(pulse_num),
.pulse_height(pulse_height),
.pulse_period_adc(pulse_period_adc),
.window_size(window_size)
);
#100;
dut_start(ctrl_vif);
dut_read_output(
.vif(accum_vif),
.sample_num(pulse_period_adc),
.window_size(window_size),
.randomize_recv_delays(rand_recv_delays),
.output_data(output_data)
);
// actual size of payload is pulse_period_adc / window_size
output_signal_v = new[pulse_period_adc / window_size];
`ifdef DEBUG
$display("[TB] Output data stream");
display_array(output_data);
`endif
// voltage conversion
begin
// zero level for partial sum
real zero_level_bias = window_size * virtual_adc.ZERO_CODE;
// common voltage multiplier for step & amplifier
real voltage_multiplier = virtual_adc.VOLTAGE_STEP / virtual_adc.VOLTAGE_GAIN;
// array conversion
foreach (output_signal_v[i]) begin
real average_code_per_pulse = real'(output_data[i]) / pulse_num;
output_signal_v[i] = (average_code_per_pulse - zero_level_bias) * voltage_multiplier;
end
end
reference_signal(
.pulse_width(pulse_width),
.pulse_height(pulse_height),
.pulse_period_adc(pulse_period_adc),
.window_size(window_size),
.result(reference_signal_v)
);
`ifdef DEBUG
$display("[TB] Output signal");
display_array_f(output_signal_v);
$display("[TB] Reference signal");
display_array_f(reference_signal_v);
`endif
nrmse = calc_nrmse(output_signal_v, reference_signal_v);
pearson = calc_pearson(output_signal_v, reference_signal_v);
max_err = calc_max_error(output_signal_v, reference_signal_v);
`ifdef DEBUG
$display("[TB] Metrics:\n\tNRMSE = %0.4f\t|\tPearson = %0.4f\t|\tMax error = %0.4f", nrmse, pearson, max_err);
`endif
// check metrics
result = 0;
// if (pearson < PEARSON_THRESHOLD)
// result += 1;
if (nrmse > NRMSE_THRESHOLD)
result += 2;
/*
Max error not used in evaluation because of fast pulse edge falling
resulting in plain difference between active signal level and zero level
For ex.: zero_level = 0x00 = -5V. pulse_height = 2^14-1 = 0x3fff = 5V
In some cases like jitter this may cause max error = 5 - (-5) = 10(V)
This cases are hardly traceble, thus max error not used in eval.
Pearson not used in evaluation because it only shows correlation of changing signals. Tests broke on static signals.
Pearson and max err remain in test for info.
*/
endtask
//------------------------------------------------------------
// ÎÑÍÎÂÍÎÉ ÏÐÎÖÅÑÑ ÒÅÑÒÈÐÎÂÀÍÈß
//------------------------------------------------------------
initial begin
int result_flag;
int total_failed_tests = 0, total_tests = 0;
$info("[TB] DUT initializaton");
// Èíèöèàëèçàöèÿ
request_ready = 0;
rst_n = 0;
#100;
rst_n = 1;
wait(mmcm_locked === 1'b1);
#150;
$info("[TB] MMCM locked");
// Meause periods because actual values hardcoded in IP
fork
`MEASURE_CLK(DUT.clk_sampler, CLK_ADC_PERIOD);
`MEASURE_CLK(DUT.clk_generator, CLK_DAC_PERIOD);
join
$info("[TB] ADC & DAC clock periods measured: ADC_period = %0.3f, DAC_period = %0.3f", CLK_ADC_PERIOD, CLK_DAC_PERIOD);
// Òåñòû
$info("[TB] Tests start");
$info("[TB] Simple test run");
run_test_case(
.ctrl_vif(control_vif),
.accum_vif(accumulator_vif),
.pulse_width(4000),
.pulse_period(10000),
.pulse_num(5),
.pulse_height(12000),
.pulse_period_adc(6000),
.window_size(10),
.rand_recv_delays(1),
.use_reset(1),
.result(result_flag)
);
`ERR_CHECK
$info("[TB] Random test run");
for (int i = 0; i < TEST_NUM; i++) begin
int pulse_width, pulse_period, pulse_num, pulse_height, pulse_period_adc, window_size;
bit rand_recv_delays, use_reset;
// Ãåíåðèðóåìûå ïàðàìåòðû
pulse_period = $urandom_range(500, 5000);
pulse_width = $urandom_range(50, pulse_period);
pulse_num = $urandom_range(1, 10);
pulse_height = $urandom_range(0, 2**DAC_DATA_WIDTH-1);
window_size = $urandom_range(1, 11);
pulse_period_adc = $urandom_range(50, N_MAX-1) * window_size;
rand_recv_delays = 1;
use_reset = 1; // ($urandom_range(0, 10) >= 9);
$display("Test #%0d", total_tests);
`ifdef DEBUG
$display("Parameters:\n\tpulse_width=%0d\n\tpulse_period=%0d\n\tpulse_num=%0d\n\tpulse_height=%0d\n\tpulse_period_adc=%0d\n\twindow_size=%0d\n\trand_recv_delays=%0d\n\tuse_reset=%0d",
pulse_width, pulse_period, pulse_num, pulse_height, pulse_period_adc, window_size, rand_recv_delays, use_reset);
`endif
run_test_case(
.ctrl_vif(control_vif),
.accum_vif(accumulator_vif),
.pulse_width(pulse_width),
.pulse_period(pulse_period),
.pulse_num(pulse_num),
.pulse_height(pulse_height),
.pulse_period_adc(pulse_period_adc),
.window_size(window_size),
.rand_recv_delays(rand_recv_delays),
.use_reset(use_reset),
.result(result_flag)
);
`ERR_CHECK
if (result_flag) begin
$display("Parameters:\n\tpulse_width=%0d\n\tpulse_period=%0d\n\tpulse_num=%0d\n\tpulse_height=%0d\n\tpulse_period_adc=%0d\n\twindow_size=%0d\n\trand_recv_delays=%0d\n\tuse_reset=%0d",
pulse_width, pulse_period, pulse_num, pulse_height, pulse_period_adc, window_size, rand_recv_delays, use_reset);
end
end
$info("[TB] Corner case test run");
run_test_case(
.ctrl_vif(control_vif),
.accum_vif(accumulator_vif),
.pulse_width(0),
.pulse_period(1000),
.pulse_num(5),
.pulse_height(12000),
.pulse_period_adc(600),
.window_size(10),
.rand_recv_delays(0),
.use_reset(1),
.result(result_flag)
);
`ERR_CHECK
run_test_case(
.ctrl_vif(control_vif),
.accum_vif(accumulator_vif),
.pulse_width(1000),
.pulse_period(1000),
.pulse_num(5),
.pulse_height(12000),
.pulse_period_adc(600),
.window_size(10),
.rand_recv_delays(0),
.use_reset(1),
.result(result_flag)
);
`ERR_CHECK
run_test_case(
.ctrl_vif(control_vif),
.accum_vif(accumulator_vif),
.pulse_width(500),
.pulse_period(1000),
.pulse_num(5),
.pulse_height(2**(DAC_DATA_WIDTH-1)),
.pulse_period_adc(600),
.window_size(10),
.rand_recv_delays(0),
.use_reset(1),
.result(result_flag)
);
`ERR_CHECK
run_test_case(
.ctrl_vif(control_vif),
.accum_vif(accumulator_vif),
.pulse_width(500),
.pulse_period(1000),
.pulse_num(5),
.pulse_height(15000),
.pulse_period_adc(10),
.window_size(1),
.rand_recv_delays(0),
.use_reset(1),
.result(result_flag)
);
`ERR_CHECK
$display("[TB] Tests done. [%0d/%0d] tests passed, %0d failed", total_tests - total_failed_tests, total_tests, total_failed_tests);
if (!total_failed_tests)
$display("[TB] ALL PASSED");
$finish;
end
endmodule
@@ -0,0 +1,322 @@
import dma_reg_pkg::*;
module tb_full_reflectometer #(
// parameters for base reflectometer works
parameter int unsigned DAC_DATA_WIDTH = 14,
parameter int unsigned ADC_DATA_WIDTH = 12,
parameter int unsigned PACK_FACTOR = 1,
parameter int unsigned PROCESS_MODE = 0,
parameter int unsigned ZERO_LEVEL = 8192,
parameter int unsigned ACCUM_WIDTH = 32,
parameter int unsigned N_MAX = 4096,
parameter int unsigned PACKET_SIZE = 64,
parameter int unsigned RD_FIFO_WIDTH = 32,
parameter int unsigned AXI_DATA_WIDTH = 32,
parameter int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8,
parameter int unsigned AXI_USER_WIDTH = 1,
parameter int unsigned AXI_ID_WIDTH = 8,
parameter int unsigned AXI_MAX_BURST_LEN = 16,
parameter int unsigned AXIS_DATA_WIDTH = AXI_DATA_WIDTH,
parameter int unsigned AXIS_KEEP_ENABLE = AXIS_DATA_WIDTH > 8,
parameter int unsigned AXIS_KEEP_WIDTH = AXIS_DATA_WIDTH / 8,
parameter int unsigned AXIS_LAST_ENABLE = 1,
parameter int unsigned AXIS_ID_ENABLE = 1,
parameter int unsigned AXIS_DEST_ENABLE = 0,
parameter int unsigned AXIS_USER_ENABLE = 1,
parameter int unsigned ENABLE_SG = 0,
parameter int unsigned ENABLE_UNALIGNED = 0,
parameter int unsigned PIPELINE_OUTPUT = 0
)(
input logic ctrl_clk,
input logic rst_n,
output logic locked,
input logic [dma_reg_pkg::AXI_ADDR_WIDTH-1:0] s_axil_awaddr,
input logic [2:0] s_axil_awprot,
input logic s_axil_awvalid,
output logic s_axil_awready,
input logic [AXI_DATA_WIDTH-1:0] s_axil_wdata,
input logic [AXI_DATA_WIDTH/8-1:0] s_axil_wstrb,
input logic s_axil_wvalid,
output logic s_axil_wready,
output logic [1:0] s_axil_bresp,
output logic s_axil_bvalid,
input logic s_axil_bready,
input logic [dma_reg_pkg::AXI_ADDR_WIDTH-1:0] s_axil_araddr,
input logic [2:0] s_axil_arprot,
input logic s_axil_arvalid,
output logic s_axil_arready,
output logic [AXI_DATA_WIDTH-1:0] s_axil_rdata,
output logic [1:0] s_axil_rresp,
output logic s_axil_rvalid,
input logic s_axil_rready,
output wire [AXIS_DATA_WIDTH-1:0] m_axis_read_data_tdata,
output wire [AXIS_KEEP_WIDTH-1:0] m_axis_read_data_tkeep,
output wire m_axis_read_data_tvalid,
input wire m_axis_read_data_tready,
output wire m_axis_read_data_tlast,
output wire [dma_reg_pkg::AXIS_ID_WIDTH-1:0] m_axis_read_data_tid,
output wire [dma_reg_pkg::AXIS_DEST_WIDTH-1:0] m_axis_read_data_tdest,
output wire [dma_reg_pkg::AXIS_USER_WIDTH-1:0] m_axis_read_data_tuser,
input logic [AXI_ID_WIDTH-1:0] s_axi_awid,
input logic [dma_reg_pkg::AXI_ADDR_WIDTH-1:0] s_axi_awaddr,
input logic [7:0] s_axi_awlen,
input logic [2:0] s_axi_awsize,
input logic [1:0] s_axi_awburst,
input logic s_axi_awlock,
input logic [3:0] s_axi_awcache,
input logic [2:0] s_axi_awprot,
input logic [3:0] s_axi_awqos,
input logic [3:0] s_axi_awregion,
input logic [AXI_USER_WIDTH-1:0] s_axi_awuser,
input logic s_axi_awvalid,
output logic s_axi_awready,
input logic [AXI_DATA_WIDTH-1:0] s_axi_wdata,
input logic [AXI_DATA_WIDTH/8-1:0] s_axi_wstrb,
input logic s_axi_wlast,
input logic [AXI_USER_WIDTH-1:0] s_axi_wuser,
input logic s_axi_wvalid,
output logic s_axi_wready,
output logic [AXI_ID_WIDTH-1:0] s_axi_bid,
output logic [1:0] s_axi_bresp,
output logic [AXI_USER_WIDTH-1:0] s_axi_buser,
output logic s_axi_bvalid,
input logic s_axi_bready,
input logic [AXI_ID_WIDTH-1:0] s_axi_arid,
input logic [dma_reg_pkg::AXI_ADDR_WIDTH-1:0] s_axi_araddr,
input logic [7:0] s_axi_arlen,
input logic [2:0] s_axi_arsize,
input logic [1:0] s_axi_arburst,
input logic s_axi_arlock,
input logic [3:0] s_axi_arcache,
input logic [2:0] s_axi_arprot,
input logic [3:0] s_axi_arqos,
input logic [3:0] s_axi_arregion,
input logic [AXI_USER_WIDTH-1:0] s_axi_aruser,
input logic s_axi_arvalid,
output logic s_axi_arready,
output logic [AXI_ID_WIDTH-1:0] s_axi_rid,
output logic [AXI_DATA_WIDTH-1:0] s_axi_rdata,
output logic [1:0] s_axi_rresp,
output logic s_axi_rlast,
output logic [AXI_USER_WIDTH-1:0] s_axi_ruser,
output logic s_axi_rvalid,
input logic s_axi_rready,
// DAC
output wire dac_clk_o,
output wire [DAC_DATA_WIDTH-1:0] dac_data,
output wire dac_wrt,
// ADC
output wire adc_clk_o,
input wire [ADC_DATA_WIDTH-1:0] adc_data,
input wire adc_otr
);
// ---------------------------------------------------------------------------
// AXI-Lite flat -> axi4l_if
// ---------------------------------------------------------------------------
axi4l_if #(
.ADDR_W(dma_reg_pkg::AXI_ADDR_WIDTH),
.DATA_W(AXI_DATA_WIDTH),
.USER_W(AXI_USER_WIDTH)
) axil_bus (
.aclk(ctrl_clk),
.aresetn(rst_n)
);
axi4l_flat_to_if #(
.ADDR_W(g_pkg::AXI_ADDR_WIDTH),
.DATA_W(AXI_DATA_WIDTH),
.USER_W(AXI_USER_WIDTH)
) u_axil_flat_to_if (
.s_axil_awaddr (s_axil_awaddr),
.s_axil_awprot (s_axil_awprot),
.s_axil_awvalid(s_axil_awvalid),
.s_axil_awready(s_axil_awready),
.s_axil_wdata (s_axil_wdata),
.s_axil_wstrb (s_axil_wstrb),
.s_axil_wvalid (s_axil_wvalid),
.s_axil_wready (s_axil_wready),
.s_axil_bresp (s_axil_bresp),
.s_axil_bvalid (s_axil_bvalid),
.s_axil_bready (s_axil_bready),
.s_axil_araddr (s_axil_araddr),
.s_axil_arprot (s_axil_arprot),
.s_axil_arvalid(s_axil_arvalid),
.s_axil_arready(s_axil_arready),
.s_axil_rdata (s_axil_rdata),
.s_axil_rresp (s_axil_rresp),
.s_axil_rvalid (s_axil_rvalid),
.s_axil_rready (s_axil_rready),
.m_axil(axil_bus)
);
// ---------------------------------------------------------------------------
// AXIS interfaces for the updated controller_wrapper_axil
// ---------------------------------------------------------------------------
// AXIS READ DMA MASTER output
axis_if #(
.DATA_W (AXIS_DATA_WIDTH),
.KEEP_W (AXIS_KEEP_WIDTH),
.ID_W (AXIS_ID_WIDTH),
.DEST_W (dma_reg_pkg::AXIS_DEST_WIDTH),
.USER_W (dma_reg_pkg::AXIS_USER_WIDTH)
) dma_read_data (
.aclk(ctrl_clk),
.aresetn(rst_n)
);
logic [AXIS_KEEP_WIDTH-1:0] unused_read_tstrb;
axis_if_to_flat #(
.DATA_W (AXIS_DATA_WIDTH),
.KEEP_W (AXIS_KEEP_WIDTH),
.ID_W (AXIS_ID_WIDTH),
.DEST_W (dma_reg_pkg::AXIS_DEST_WIDTH),
.USER_W (dma_reg_pkg::AXIS_USER_WIDTH)
) u_read_data_if_to_flat (
.s_axis(dma_read_data),
.m_axis_tdata (m_axis_read_data_tdata),
.m_axis_tkeep (m_axis_read_data_tkeep),
.m_axis_tstrb (unused_read_tstrb),
.m_axis_tlast (m_axis_read_data_tlast),
.m_axis_tid (m_axis_read_data_tid),
.m_axis_tdest (m_axis_read_data_tdest),
.m_axis_tuser (m_axis_read_data_tuser),
.m_axis_tvalid(m_axis_read_data_tvalid),
.m_axis_tready(m_axis_read_data_tready)
);
axi4_if #(
.ADDR_W(dma_reg_pkg::AXI_ADDR_WIDTH),
.DATA_W(AXI_DATA_WIDTH),
.ID_W (AXI_ID_WIDTH),
.USER_W(AXI_USER_WIDTH)
) m_axi (
.aclk(ctrl_clk),
.aresetn(rst_n)
);
axi4_flat_to_if #(
.ADDR_W(dma_reg_pkg::AXI_ADDR_WIDTH),
.DATA_W(AXI_DATA_WIDTH),
.ID_W(AXI_ID_WIDTH),
.USER_W(AXI_USER_WIDTH)
) u_axi_flat_to_if
(
.s_axi_awid(s_axi_awid),
.s_axi_awaddr(s_axi_awaddr),
.s_axi_awlen(s_axi_awlen),
.s_axi_awsize(s_axi_awsize),
.s_axi_awburst(s_axi_awburst),
.s_axi_awlock(s_axi_awlock),
.s_axi_awcache(s_axi_awcache),
.s_axi_awprot(s_axi_awprot),
.s_axi_awqos(s_axi_awqos),
.s_axi_awregion(s_axi_awregion),
.s_axi_awuser(s_axi_awuser),
.s_axi_awvalid(s_axi_awvalid),
.s_axi_awready(s_axi_awready),
.s_axi_wdata(s_axi_wdata),
.s_axi_wstrb(s_axi_wstrb),
.s_axi_wlast(s_axi_wlast),
.s_axi_wuser(s_axi_wuser),
.s_axi_wvalid(s_axi_wvalid),
.s_axi_wready(s_axi_wready),
.s_axi_bid(s_axi_bid),
.s_axi_bresp(s_axi_bresp),
.s_axi_buser(s_axi_buser),
.s_axi_bvalid(s_axi_bvalid),
.s_axi_bready(s_axi_bready),
.s_axi_arid(s_axi_arid),
.s_axi_araddr(s_axi_araddr),
.s_axi_arlen(s_axi_arlen),
.s_axi_arsize(s_axi_arsize),
.s_axi_arburst(s_axi_arburst),
.s_axi_arlock(s_axi_arlock),
.s_axi_arcache(s_axi_arcache),
.s_axi_arprot(s_axi_arprot),
.s_axi_arqos(s_axi_arqos),
.s_axi_arregion(s_axi_arregion),
.s_axi_aruser(s_axi_aruser),
.s_axi_arvalid(s_axi_arvalid),
.s_axi_arready(s_axi_arready),
.s_axi_rid(s_axi_rid),
.s_axi_rdata(s_axi_rdata),
.s_axi_rresp(s_axi_rresp),
.s_axi_rlast(s_axi_rlast),
.s_axi_ruser(s_axi_ruser),
.s_axi_rvalid(s_axi_rvalid),
.s_axi_rready(s_axi_rready),
.m_axi(m_axi)
);
reflectometer_and_dma_wrapper #(
.AXI_DATA_WIDTH(AXI_DATA_WIDTH),
.AXI_STRB_WIDTH(AXI_STRB_WIDTH),
.AXI_USER_WIDTH(AXI_USER_WIDTH),
.AXI_MAX_BURST_LEN(AXI_MAX_BURST_LEN),
.AXIS_DATA_WIDTH(AXIS_DATA_WIDTH),
.AXIS_KEEP_ENABLE(AXIS_KEEP_ENABLE),
.AXIS_KEEP_WIDTH(AXIS_KEEP_WIDTH),
.AXIS_LAST_ENABLE(AXIS_LAST_ENABLE),
.AXIS_ID_ENABLE(AXIS_ID_ENABLE),
.AXIS_DEST_ENABLE(AXIS_DEST_ENABLE),
.AXIS_USER_ENABLE(AXIS_USER_ENABLE),
.ENABLE_SG(ENABLE_SG),
.ENABLE_UNALIGNED(ENABLE_UNALIGNED),
.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),
.PACKET_SIZE(PACKET_SIZE),
.RD_FIFO_WIDTH(RD_FIFO_WIDTH)
) dut (
.ctrl_clk(ctrl_clk),
.rst_n(rst_n),
.locked(locked),
.s_axil(axil_bus),
.m_axi(m_axi),
.m_axis_read_data(dma_read_data),
.dac_clk_o(clk_dac),
.dac_data(dac_data),
.dac_wrt(dac_wrt),
.adc_clk_o(clk_adc),
.adc_data(adc_data),
.adc_otr(adc_otr)
);
endmodule : tb_full_reflectometer