From 033324b49e401848f3429de2a0b6c7ce9ac3eb4d Mon Sep 17 00:00:00 2001 From: otroubi Date: Tue, 8 Sep 2026 18:07:58 +0300 Subject: [PATCH] debugging sv test for new reflectometer --- .../reflectometer_tb.sv | 439 ++++++++++++------ 1 file changed, 306 insertions(+), 133 deletions(-) diff --git a/designs/full_new_reflectometer/tests/full_reflectometer_test/sv_full_reflectometer_test/reflectometer_tb.sv b/designs/full_new_reflectometer/tests/full_reflectometer_test/sv_full_reflectometer_test/reflectometer_tb.sv index 133a26c..86c4f56 100644 --- a/designs/full_new_reflectometer/tests/full_reflectometer_test/sv_full_reflectometer_test/reflectometer_tb.sv +++ b/designs/full_new_reflectometer/tests/full_reflectometer_test/sv_full_reflectometer_test/reflectometer_tb.sv @@ -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 //------------------------------------------------------------ // Функции и таски для верификации сигналов