debugging sv test for new reflectometer
This commit is contained in:
+306
-133
@@ -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 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 );
|
||||
|
||||
end
|
||||
endtask
|
||||
|
||||
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
|
||||
logic [31:0] dma_received_data[$];
|
||||
|
||||
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 axi_write_slave();
|
||||
logic [31:0] addr;
|
||||
logic [7:0] len;
|
||||
logic [31:0] data;
|
||||
|
||||
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[];
|
||||
begin
|
||||
forever begin
|
||||
// WAIT AW
|
||||
@(posedge ctrl_clk);
|
||||
|
||||
// Àõòóíã, 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");
|
||||
if (s_axi_awvalid) begin
|
||||
addr = s_axi_awaddr;
|
||||
len = s_axi_awlen;
|
||||
s_axi_awready <= 1'b1;
|
||||
|
||||
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]
|
||||
};
|
||||
$display(
|
||||
"[AXI] AW: addr=0x%08X len=%0d", addr, len );
|
||||
|
||||
vif.master_send(tx_packet);
|
||||
@(posedge ctrl_clk);
|
||||
s_axi_awready <= 1'b0;
|
||||
|
||||
// TODO remove for new controller
|
||||
window_size_port = window_size;
|
||||
endtask
|
||||
// RECEIVE W DATA
|
||||
for (int i = 0; i <= len; i++) begin
|
||||
s_axi_wready <= 1'b1;
|
||||
|
||||
while (!s_axi_wvalid)
|
||||
@(posedge ctrl_clk);
|
||||
|
||||
data = s_axi_wdata;
|
||||
dma_received_data.push_back(data);
|
||||
|
||||
// Òàñêè ñáîðà ñòàòèñòèêè
|
||||
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;
|
||||
$display( "[AXI] W[%0d] = 0x%08X last=%b", i, data, s_axi_wlast );
|
||||
|
||||
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
|
||||
@(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
|
||||
|
||||
//------------------------------------------------------------
|
||||
// ������� � ����� ��� ����������� ��������
|
||||
|
||||
Reference in New Issue
Block a user