trial SV test
This commit is contained in:
@@ -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
|
|
||||||
+861
@@ -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
|
||||||
+322
@@ -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
|
||||||
Reference in New Issue
Block a user