debugging sv test for new reflectometer

This commit is contained in:
otroubi
2026-09-08 18:07:58 +03:00
parent 255b46ffb2
commit 033324b49e
@@ -1,5 +1,7 @@
`timescale 1ns / 1ps
import dma_reg_pkg::*;
`define MEASURE_CLK(clk, period) \
begin \
realtime t1, t2; \
@@ -59,6 +61,76 @@ module reflectometer_tb;
realtime CLK_ADC_PERIOD;
realtime CLK_DAC_PERIOD;
// AXI
logic [AXI_ID_WIDTH-1:0] s_axi_awid;
logic [dma_reg_pkg::AXI_ADDR_WIDTH-1:0] s_axi_awaddr;
logic [7:0] s_axi_awlen;
logic [2:0] s_axi_awsize;
logic [1:0] s_axi_awburst;
logic s_axi_awlock;
logic [3:0] s_axi_awcache;
logic [2:0] s_axi_awprot;
logic [3:0] s_axi_awqos;
logic [3:0] s_axi_awregion;
logic [AXI_USER_WIDTH-1:0] s_axi_awuser;
logic s_axi_awvalid;
logic s_axi_awready;
logic [AXI_DATA_WIDTH-1:0] s_axi_wdata;
logic [AXI_DATA_WIDTH/8-1:0] s_axi_wstrb;
logic s_axi_wlast;
logic [AXI_USER_WIDTH-1:0] s_axi_wuser;
logic s_axi_wvalid;
logic s_axi_wready;
logic [AXI_ID_WIDTH-1:0] s_axi_bid;
logic [1:0] s_axi_bresp;
logic [AXI_USER_WIDTH-1:0] s_axi_buser;
logic s_axi_bvalid;
logic s_axi_bready;
logic [AXI_ID_WIDTH-1:0] s_axi_arid;
logic [dma_reg_pkg::AXI_ADDR_WIDTH-1:0] s_axi_araddr;
logic [7:0] s_axi_arlen;
logic [2:0] s_axi_arsize;
logic [1:0] s_axi_arburst;
logic s_axi_arlock;
logic [3:0] s_axi_arcache;
logic [2:0] s_axi_arprot;
logic [3:0] s_axi_arqos;
logic [3:0] s_axi_arregion;
logic [AXI_USER_WIDTH-1:0] s_axi_aruser;
logic s_axi_arvalid;
logic s_axi_arready;
logic [AXI_ID_WIDTH-1:0] s_axi_rid;
logic [AXI_DATA_WIDTH-1:0] s_axi_rdata;
logic [1:0] s_axi_rresp;
logic s_axi_rlast;
logic [AXI_USER_WIDTH-1:0] s_axi_ruser;
logic s_axi_rvalid;
logic s_axi_rready;
// AXIL
logic [dma_reg_pkg::AXI_ADDR_WIDTH-1:0] s_axil_awaddr;
logic [2:0] s_axil_awprot;
logic s_axil_awvalid;
logic s_axil_awready;
logic [AXI_DATA_WIDTH-1:0] s_axil_wdata;
logic [AXI_DATA_WIDTH/8-1:0] s_axil_wstrb;
logic s_axil_wvalid;
logic s_axil_wready;
logic [1:0] s_axil_bresp;
logic s_axil_bvalid;
logic s_axil_bready;
logic [dma_reg_pkg::AXI_ADDR_WIDTH-1:0] s_axil_araddr;
logic [2:0] s_axil_arprot;
logic s_axil_arvalid;
logic s_axil_arready;
logic [AXI_DATA_WIDTH-1:0] s_axil_rdata;
logic [1:0] s_axil_rresp;
logic s_axil_rvalid;
logic s_axil_rready;
//------------------------------------------------------------
@@ -257,158 +329,259 @@ module reflectometer_tb;
//------------------------------------------------------------
// AXI-Lite, AXI
localparam int REG_CONTROL = 0;
localparam int REG_STATUS = 1;
localparam int REG_DAC_WIDTH = 2;
localparam int REG_DAC_PERIOD = 3;
localparam int REG_DAC_PULSE_NUM = 4;
localparam int REG_DAC_PULSE_HEIGHT = 5;
localparam int REG_ADC_PERIOD = 6;
localparam int REG_WINDOW_SIZE = 7;
localparam int REG_DESC_WRITE_ADDR = 13;
localparam int REG_DESC_WRITE_LEN_TAG = 14;
localparam int REG_STATUS_WRITE_LEN = 15;
localparam int REG_STATUS_WRITE_CONFIG = 16;
// REG_CONTROL pulse bits
localparam int CTRL_START = 1 << 0;
localparam int CTRL_RST_SOFT = 1 << 1;
localparam int CTRL_CFG_BUS_VALID = 1 << 2;
localparam int CTRL_SEND_DESC_READ = 1 << 3;
localparam int CTRL_SEND_DESC_WRITE = 1 << 4;
localparam int CTRL_TAKE_STATUS_READ = 1 << 5;
localparam int CTRL_TAKE_STATUS_WRITE = 1 << 6;
// REG_STATUS bits
localparam int STATUS_BUSY = 1 << 0;
localparam int STATUS_PROCESSING_DONE = 1 << 1;
localparam int STATUS_DESC_READ_BUSY = 1 << 2;
localparam int STATUS_DESC_WRITE_BUSY = 1 << 3;
localparam int STATUS_STATUS_READ_BUSY = 1 << 4;
localparam int STATUS_STATUS_WRITE_BUSY = 1 << 5;
localparam int STATUS_DESC_READ_HS = 1 << 6;
localparam int STATUS_DESC_WRITE_HS = 1 << 7;
localparam int STATUS_STATUS_READ_HS = 1 << 8;
localparam int STATUS_STATUS_WRITE_HS = 1 << 9;
function automatic logic [31:0] reg_addr(input int index);
return index * 4;
endfunction
task automatic axil_write(
input logic [31:0] addr,
input logic [31:0] data
);
begin
// Write address channel
@(posedge ctrl_clk);
s_axil_awaddr <= addr;
s_axil_awprot <= 3'b000;
s_axil_awvalid <= 1'b1;
// Write data channel
s_axil_wdata <= data;
s_axil_wstrb <= 4'b1111;
s_axil_wvalid <= 1'b1;
// AXI-Lite: address handshake
while (!s_axil_awready)
@(posedge ctrl_clk);
// AXI-Lite: data handshake
while (!s_axil_wready)
@(posedge ctrl_clk);
@(posedge ctrl_clk);
s_axil_awvalid <= 1'b0;
s_axil_wvalid <= 1'b0;
// Write response
s_axil_bready <= 1'b1;
while (!s_axil_bvalid)
@(posedge ctrl_clk);
if (s_axil_bresp != 2'b00)
$error( "[AXIL] Write response error: BRESP=%b", s_axil_bresp);
@(posedge ctrl_clk);
s_axil_bready <= 1'b0;
$display( "[AXIL] WRITE addr=0x%08X data=0x%08X", addr, data);
end
endtask
task automatic axil_read(
input logic [31:0] addr,
output logic [31:0] data
);
begin
// Read address
@(posedge ctrl_clk);
s_axil_araddr <= addr;
s_axil_arprot <= 3'b000;
s_axil_arvalid <= 1'b1;
while (!s_axil_arready)
@(posedge ctrl_clk);
@(posedge ctrl_clk);
s_axil_arvalid <= 1'b0;
// Read response
s_axil_rready <= 1'b1;
while (!s_axil_rvalid)
@(posedge ctrl_clk);
data = s_axil_rdata;
if (s_axil_rresp != 2'b00)
$error( "[AXIL] Read response error: RRESP=%b", s_axil_rresp );
@(posedge ctrl_clk);
s_axil_rready <= 1'b0;
$display( "[AXIL] READ addr=0x%08X data=0x%08X", addr, data );
end
endtask
task automatic write_reg(
input int index,
input logic [31:0] data
);
axil_write( reg_addr(index), data );
endtask
task automatic read_reg(
input int index,
output logic [31:0] data
);
axil_read( reg_addr(index), data );
endtask
//
task automatic configure_reflectometer(
input int pulse_width,
input int pulse_period,
input int pulse_num,
input int pulse_height,
input int adc_period,
input int window_size
);
begin
$display("[TB] Configure reflectometer");
write_reg( REG_DAC_WIDTH, pulse_width );
write_reg( REG_DAC_PERIOD, pulse_period);
write_reg( REG_DAC_PULSE_NUM, pulse_num );
write_reg( REG_DAC_PULSE_HEIGHT, pulse_height );
write_reg( REG_ADC_PERIOD, adc_period );
write_reg( REG_WINDOW_SIZE, window_size );
// CTRL_CFG_BUS_VALID
write_reg(REG_CONTROL, CTRL_CFG_BUS_VALID);
$display("[TB] Configuration sent");
end
endtask
task automatic dut_start();
begin
write_reg( REG_CONTROL, CTRL_START);
$display("[TB] START sent");
end
endtask
task automatic dut_soft_reset();
begin
write_reg( REG_CONTROL, CTRL_RST_SOFT );
$display("[TB] SOFT RESET sent");
end
endtask
// 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 send_desc_write(
input logic [31:0] addr,
input logic [31:0] length_tag
);
begin
write_reg( REG_DESC_WRITE_ADDR, addr );
write_reg( REG_DESC_WRITE_LEN_TAG, length_tag);
write_reg( REG_CONTROL, CTRL_SEND_DESC_WRITE);
$display( "[TB] DMA WRITE descriptor: addr=0x%08X len_tag=%0d", addr, length_tag );
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[];
end
endtask
// Àõòóíã, 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");
logic [31:0] dma_received_data[$];
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);
task automatic axi_write_slave();
logic [31:0] addr;
logic [7:0] len;
logic [31:0] data;
// TODO remove for new controller
window_size_port = window_size;
endtask
begin
forever begin
// WAIT AW
@(posedge ctrl_clk);
if (s_axi_awvalid) begin
addr = s_axi_awaddr;
len = s_axi_awlen;
s_axi_awready <= 1'b1;
$display(
"[AXI] AW: addr=0x%08X len=%0d", addr, len );
// Òàñêè ñáîðà ñòàòèñòèêè
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;
@(posedge ctrl_clk);
s_axi_awready <= 1'b0;
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
// RECEIVE W DATA
for (int i = 0; i <= len; i++) begin
s_axi_wready <= 1'b1;
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
while (!s_axi_wvalid)
@(posedge ctrl_clk);
// Wait until reflectometer done sampling and averaging
wait(processing_done == 1);
data = s_axi_wdata;
dma_received_data.push_back(data);
// 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
$display( "[AXI] W[%0d] = 0x%08X last=%b", i, data, s_axi_wlast );
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
@(posedge ctrl_clk);
s_axi_wready <= 1'b0;
end
end
begin
// IP workflow completion event
wait(workflow_done == 1);
end
join_any
disable recv_loop_proc;
disable packet_counter_proc;
// WRITE RESPONSE
s_axi_bresp <= 2'b00;
s_axi_bvalid <= 1'b1;
if (packet_counter != packet_num) begin
$error("-dut_read_output- Wrong number of packets received: %0d received, %0d expected", packet_counter, packet_num);
$finish;
while (!s_axi_bready)
@(posedge ctrl_clk);
@(posedge ctrl_clk);
s_axi_bvalid <= 1'b0;
end
end
wait(processing_done == 0);
endtask
end
endtask
//------------------------------------------------------------
//