Merge branch 'dev/design' into integration_new_controller

This commit is contained in:
otroubi
2026-07-29 17:26:41 +03:00
7 changed files with 1490 additions and 57 deletions
+14 -7
View File
@@ -10,7 +10,6 @@ module reflectometer_top #(
parameter int unsigned ZERO_LEVEL = 8192,
parameter int unsigned ACCUM_WIDTH = 32,
parameter int unsigned N_MAX = 4096,
parameter int unsigned WINDOW_SIZE = 65,
parameter int unsigned PACKET_SIZE = 1024
)(
input wire clk_in,
@@ -18,12 +17,17 @@ module reflectometer_top #(
output wire locked,
// Accumulator AXI-S bus
input wire clk_axis_accumulator, // GMII PHY RX clock
axis_if.master axis_accumulator,
input wire clk_axis_accumulator, // GMII PHY RX clock
axis_if.master axis_accumulator,
// Control AXI-S bus
input wire clk_axis_control, // GMII PHY TX clock
axis_if.slave axis_control,
input wire clk_axis_control, // GMII PHY TX clock
axis_if.slave axis_control,
input wire [31:0] window_size, // New accum & old controller crutch
// Status signals
output wire workflow_done,
output wire processing_done,
// RTL-MAC handshake
input wire request_ready,
@@ -216,11 +220,12 @@ module reflectometer_top #(
// -------------------------------------------------------------------------
// Accumulator
// -------------------------------------------------------------------------
assign workflow_done = finish;
accumulator_top #(
.DATA_WIDTH(ADC_DATA_WIDTH),
.ACCUM_WIDTH(ACCUM_WIDTH),
.N_MAX(N_MAX),
.WINDOW_SIZE(WINDOW_SIZE),
.PACKET_SIZE(PACKET_SIZE)
) accumulator_top_dut (
.clk_in(clk_sampler),
@@ -230,6 +235,7 @@ module reflectometer_top #(
.start(adc_start),
.smp_num(adc_pulse_period),
.seq_num(adc_pulse_num),
.window_size(window_size),
.req_ready(request_ready),
.send_req(send_request),
@@ -239,7 +245,8 @@ module reflectometer_top #(
.m_axis_tready(axis_accumulator.tready),
.m_axis_tlast(axis_accumulator.tlast),
.finish(finish)
.finish(finish), // full reflectometer workflow complete (with transaction)
.accum_done(processing_done) // signal generation, sampling and processing complete
);
endmodule
+137 -49
View File
@@ -11,16 +11,22 @@ module reflectometer_tb;
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 = 1; // 0 - uint, 1 - int
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 WINDOW_SIZE = 65; // fixed subwindow size to average by time
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
//------------------------------------------------------------
// Тактовые сигналы и сброс
@@ -28,43 +34,48 @@ module reflectometer_tb;
logic clk_ref = 1'b0; // 200 MHz
logic clk_eth_phy = 1'b0; // common for RX & TX
logic rst_n = 1'b0;
//------------------------------------------------------------
// Управление и конфиг
//------------------------------------------------------------
//------------------------------------------------------------
// Входы
//------------------------------------------------------------
//------------------------------------------------------------
// Выходы
//------------------------------------------------------------
wire mmcm_locked;
//------------------------------------------------------------
// Внутренние сигналы тестбенча
// Управление и конфиг 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)
);
// DAC интерфейс
wire clk_dac;
wire dac_wrt;
wire [DAC_DATA_WIDTH-1:0] dac_data;
// ADC интерфейс
wire clk_adc;
wire adc_otr;
wire [ADC_DATA_WIDTH-1:0] adc_data;
//------------------------------------------------------------
// Внутренние сигналы тестбенча
//------------------------------------------------------------
// Интерфейс хендшейка с MAC-PHY
wire send_request;
logic request_ready;
// Сигналы ЦАП и АЦП
// Сигнал между ЦАП и АЦП
real signal_voltage;
//------------------------------------------------------------
@@ -79,6 +90,7 @@ module reflectometer_tb;
.data_i(dac_data),
.voltage_o(signal_voltage)
);
//------------------------------------------------------------
// Virtual ADC
//------------------------------------------------------------
@@ -90,8 +102,9 @@ module reflectometer_tb;
.otr_o(adc_otr),
.data_o(adc_data)
);
//------------------------------------------------------------
// Statistics monitor
// Statistics processing
//------------------------------------------------------------
//------------------------------------------------------------
@@ -109,12 +122,15 @@ module reflectometer_tb;
.ZERO_LEVEL(ZERO_LEVEL),
.ACCUM_WIDTH(ACCUM_WIDTH),
.N_MAX(N_MAX),
.WINDOW_SIZE(WINDOW_SIZE),
.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
@@ -123,6 +139,7 @@ module reflectometer_tb;
// 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),
@@ -138,6 +155,8 @@ module reflectometer_tb;
.adc_data(adc_data),
.adc_otr(adc_otr)
);
assign window_size = WINDOW_SIZE;
//------------------------------------------------------------
// Тактовые сигналы
//------------------------------------------------------------
@@ -147,6 +166,7 @@ module reflectometer_tb;
initial begin
forever #(CLK_ETH_PHY_PERIOD/2) clk_eth_phy = ~clk_eth_phy;
end
//------------------------------------------------------------
// Таски для тестирования
//------------------------------------------------------------
@@ -169,11 +189,16 @@ module reflectometer_tb;
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] 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],
@@ -183,9 +208,12 @@ module reflectometer_tb;
};
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,
@@ -194,43 +222,101 @@ module reflectometer_tb;
);
logic [7:0] rx_packet[];
logic [ACCUM_WIDTH-1:0] data_packet[];
int packet_num = $ceil(real'(sample_num / WINDOW_SIZE) / real'(PACKET_SIZE));
int numbers_per_packet = PACKET_SIZE/(ACCUM_WIDTH/8);
int idx = 0;
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("[TB] -dut_read_output- Error, sample_num must be multiple of WINDOW_SIZE: %0d %% %0d = %0d", sample_num, WINDOW_SIZE, sample_num % WINDOW_SIZE);
$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 posedge todo
// timeout todo
// 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
for (int i = 0; i < packet_num; i++) begin
// randomize_recv_delays todo
request_ready = 1;
vif.slave_recv(rx_packet);
request_ready = 0;
// если число пакетов превышает заложенное предрассчитанное значение -- ошибка
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
// unpack values
data_packet = {<< byte {rx_packet}};
data_packet = {<< ACCUM_WIDTH {data_packet}};
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
// copy and convert values
for (int j = 0; j < data_packet.size(); j++) begin
output_data[i * data_packet.size() + j] = int'(data_packet[j]);
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
// wait for dut.finish posedge todo
// timeout todo
// error handling todo
endtask
// Основная таска типового теста
// todo
//------------------------------------------------------------
// ОСНОВНОЙ ПРОЦЕСС ТЕСТИРОВАНИЯ
//------------------------------------------------------------
@@ -261,7 +347,8 @@ module reflectometer_tb;
.pulse_period(32'd5000),
.pulse_num(16'd1),
.pulse_height(14'd15000), // 0V
.pulse_period_adc(32'd2600)
.pulse_period_adc(32'd2600),
.window_size(1)
);
#100;
dut_start(control_vif);
@@ -272,6 +359,7 @@ module reflectometer_tb;
.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