transferring base tests for new controller design
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
TOPLEVEL_LANG = verilog
|
||||||
|
SIM ?= verilator
|
||||||
|
|
||||||
|
PWD := $(shell pwd)
|
||||||
|
|
||||||
|
RTL_DIR = $(PWD)/../src
|
||||||
|
LIBS_DIR = $(PWD)/../../../external/rtl_libs
|
||||||
|
|
||||||
|
VERILOG_SOURCES += $(LIBS_DIR)/axi/rtl/axi_pkg.sv
|
||||||
|
VERILOG_SOURCES += $(LIBS_DIR)/axi/rtl/axi_if.sv
|
||||||
|
VERILOG_SOURCES += $(LIBS_DIR)/axi/rtl/axi4l_flat_to_if.sv
|
||||||
|
VERILOG_SOURCES += $(LIBS_DIR)/axi/rtl/axi4l_if_to_flat.sv
|
||||||
|
VERILOG_SOURCES += $(LIBS_DIR)/axi/axi_reg/axi4l_reg_map.sv
|
||||||
|
VERILOG_SOURCES += $(RTL_DIR)/controller.sv
|
||||||
|
VERILOG_SOURCES += $(RTL_DIR)/dma_controller.sv
|
||||||
|
VERILOG_SOURCES += $(RTL_DIR)/shaper_axis_desc.sv
|
||||||
|
VERILOG_SOURCES += $(RTL_DIR)/shaper_axis_status.sv
|
||||||
|
VERILOG_SOURCES += $(RTL_DIR)/controller_wrapper_axil.sv
|
||||||
|
VERILOG_SOURCES += $(RTL_DIR)/axi4l_reg_map_controller_pkg.sv
|
||||||
|
VERILOG_SOURCES += $(RTL_DIR)/axi4l_reg_map_controller.sv
|
||||||
|
VERILOG_SOURCES += $(PWD)/tb_controller_wrapper_axil.sv
|
||||||
|
|
||||||
|
TOPLEVEL = tb_controller_wrapper_axil
|
||||||
|
MODULE = test_controller
|
||||||
|
|
||||||
|
|
||||||
|
ifeq ($(SIM),verilator)
|
||||||
|
EXTRA_ARGS += --trace --trace-structs
|
||||||
|
EXTRA_ARGS += -I$(LIBS_DIR)/axi/rtl/
|
||||||
|
COMPILE_ARGS += -Wno-fatal
|
||||||
|
COMPILE_ARGS += -I$(LIBS_DIR)/axi/rtl/
|
||||||
|
EXTRA_ARGS += --trace
|
||||||
|
EXTRA_ARGS += --trace-structs
|
||||||
|
EXTRA_ARGS += --public-flat-rw
|
||||||
|
EXTRA_ARGS += -Wno-fatal
|
||||||
|
EXTRA_ARGS += --timing
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
include $(shell cocotb-config --makefiles)/Makefile.sim
|
||||||
@@ -0,0 +1,737 @@
|
|||||||
|
`timescale 1ns/1ps
|
||||||
|
|
||||||
|
module tb_control;
|
||||||
|
|
||||||
|
localparam int unsigned DAC_DATA_WIDTH = 12;
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Clocks / reset
|
||||||
|
//------------------------------------------------------------
|
||||||
|
logic ctrl_clk;
|
||||||
|
logic dac_clk_in;
|
||||||
|
logic adc_clk_in;
|
||||||
|
logic rst_n;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
ctrl_clk = 1'b0;
|
||||||
|
forever #(1 * 4.000) ctrl_clk = ~ctrl_clk; // 125 MHz
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
dac_clk_in = 1'b0;
|
||||||
|
forever #(1 * 3.846153846) dac_clk_in = ~dac_clk_in; // ~130 MHz
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
adc_clk_in = 1'b0;
|
||||||
|
forever #(1 * 7.692307692) adc_clk_in = ~adc_clk_in; // ~65 MHz
|
||||||
|
end
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// DUT inputs
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
logic rst_soft;
|
||||||
|
|
||||||
|
logic finish;
|
||||||
|
|
||||||
|
logic [159:0] cfg_bus_input;
|
||||||
|
logic cfg_bus_valid;
|
||||||
|
|
||||||
|
logic start;
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// DUT outputs
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
logic busy;
|
||||||
|
|
||||||
|
logic [31:0] dac_pulse_width;
|
||||||
|
logic [31:0] dac_pulse_period;
|
||||||
|
logic [DAC_DATA_WIDTH-1:0] dac_pulse_height;
|
||||||
|
logic [15:0] dac_pulse_num;
|
||||||
|
|
||||||
|
logic [31:0] adc_pulse_period;
|
||||||
|
logic [15:0] adc_pulse_num;
|
||||||
|
logic [31:0] adc_window_size;
|
||||||
|
|
||||||
|
logic dac_start;
|
||||||
|
logic adc_start;
|
||||||
|
logic dac_rst;
|
||||||
|
logic adc_rst;
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// DUT
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
control #(
|
||||||
|
.DAC_DATA_WIDTH(DAC_DATA_WIDTH)
|
||||||
|
) dut (
|
||||||
|
.ctrl_clk (ctrl_clk),
|
||||||
|
.dac_clk_in (dac_clk_in),
|
||||||
|
.adc_clk_in (adc_clk_in),
|
||||||
|
|
||||||
|
.rst_n (rst_n),
|
||||||
|
.rst_soft (rst_soft),
|
||||||
|
|
||||||
|
.finish (finish),
|
||||||
|
|
||||||
|
.cfg_bus_input (cfg_bus_input),
|
||||||
|
.cfg_bus_valid (cfg_bus_valid),
|
||||||
|
|
||||||
|
.start (start),
|
||||||
|
|
||||||
|
.busy (busy),
|
||||||
|
|
||||||
|
.dac_pulse_width (dac_pulse_width),
|
||||||
|
.dac_pulse_period (dac_pulse_period),
|
||||||
|
.dac_pulse_height (dac_pulse_height),
|
||||||
|
.dac_pulse_num (dac_pulse_num),
|
||||||
|
|
||||||
|
.adc_pulse_period (adc_pulse_period),
|
||||||
|
.adc_pulse_num (adc_pulse_num),
|
||||||
|
.adc_window_size (adc_window_size),
|
||||||
|
|
||||||
|
.dac_start (dac_start),
|
||||||
|
.adc_start (adc_start),
|
||||||
|
.dac_rst (dac_rst),
|
||||||
|
.adc_rst (adc_rst)
|
||||||
|
);
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// pulse counters and monitors for testing
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
int dac_rst_count;
|
||||||
|
int adc_rst_count;
|
||||||
|
int dac_start_count;
|
||||||
|
int adc_start_count;
|
||||||
|
|
||||||
|
always_ff @(posedge dac_clk_in) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
dac_rst_count <= 0;
|
||||||
|
dac_start_count <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (dac_rst)
|
||||||
|
dac_rst_count <= dac_rst_count + 1;
|
||||||
|
|
||||||
|
if (dac_start)
|
||||||
|
dac_start_count <= dac_start_count + 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge adc_clk_in) begin
|
||||||
|
if (!rst_n) begin
|
||||||
|
adc_rst_count <= 0;
|
||||||
|
adc_start_count <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (adc_rst)
|
||||||
|
adc_rst_count <= adc_rst_count + 1;
|
||||||
|
|
||||||
|
if (adc_start)
|
||||||
|
adc_start_count <= adc_start_count + 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// helpers
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
task automatic send_cmd(input logic [7:0] cmd);
|
||||||
|
begin
|
||||||
|
@(negedge ctrl_clk);
|
||||||
|
|
||||||
|
case (cmd)
|
||||||
|
|
||||||
|
8'h0F: begin
|
||||||
|
rst_soft <= 1'b1;
|
||||||
|
|
||||||
|
@(posedge ctrl_clk);
|
||||||
|
|
||||||
|
rst_soft <= 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
8'hF0: begin
|
||||||
|
start <= 1'b1;
|
||||||
|
|
||||||
|
@(posedge ctrl_clk);
|
||||||
|
|
||||||
|
start <= 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
default:
|
||||||
|
$fatal(1, "Unsupported command %h", cmd);
|
||||||
|
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task automatic send_set_data(
|
||||||
|
input logic [31:0] pulse_width,
|
||||||
|
input logic [31:0] pulse_period,
|
||||||
|
input logic [15:0] pulse_num,
|
||||||
|
input logic [15:0] pulse_height_raw,
|
||||||
|
input logic [31:0] pulse_period_adc,
|
||||||
|
input logic [31:0] window_size
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [159:0] payload;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
window_size,
|
||||||
|
pulse_period_adc,
|
||||||
|
pulse_height_raw,
|
||||||
|
pulse_num,
|
||||||
|
pulse_period,
|
||||||
|
pulse_width
|
||||||
|
};
|
||||||
|
|
||||||
|
@(negedge ctrl_clk);
|
||||||
|
|
||||||
|
cfg_bus_input <= payload;
|
||||||
|
cfg_bus_valid <= 1'b1;
|
||||||
|
|
||||||
|
@(posedge ctrl_clk);
|
||||||
|
|
||||||
|
cfg_bus_valid <= 1'b0;
|
||||||
|
cfg_bus_input <= '0;
|
||||||
|
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task automatic pulse_finish;
|
||||||
|
begin
|
||||||
|
@(posedge adc_clk_in);
|
||||||
|
finish <= 1'b1;
|
||||||
|
|
||||||
|
@(posedge adc_clk_in);
|
||||||
|
finish <= 1'b0;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// waiters
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
task automatic wait_dac_rst_count(input int expected, input int max_cycles = 100);
|
||||||
|
int i;
|
||||||
|
begin
|
||||||
|
for (i = 0; i < max_cycles; i++) begin
|
||||||
|
@(posedge dac_clk_in);
|
||||||
|
|
||||||
|
if (dac_rst_count >= expected)
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
$fatal(1,
|
||||||
|
"Timeout waiting for dac_rst_count >= %0d, current=%0d",
|
||||||
|
expected,
|
||||||
|
dac_rst_count
|
||||||
|
);
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task automatic wait_adc_rst_count(input int expected, input int max_cycles = 100);
|
||||||
|
int i;
|
||||||
|
begin
|
||||||
|
for (i = 0; i < max_cycles; i++) begin
|
||||||
|
@(posedge adc_clk_in);
|
||||||
|
|
||||||
|
if (adc_rst_count >= expected)
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
$fatal(1,
|
||||||
|
"Timeout waiting for adc_rst_count >= %0d, current=%0d",
|
||||||
|
expected,
|
||||||
|
adc_rst_count
|
||||||
|
);
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task automatic wait_dac_start_count(input int expected, input int max_cycles = 100);
|
||||||
|
int i;
|
||||||
|
begin
|
||||||
|
for (i = 0; i < max_cycles; i++) begin
|
||||||
|
@(posedge dac_clk_in);
|
||||||
|
|
||||||
|
if (dac_start_count >= expected)
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
$fatal(1,
|
||||||
|
"Timeout waiting for dac_start_count >= %0d, current=%0d",
|
||||||
|
expected,
|
||||||
|
dac_start_count
|
||||||
|
);
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task automatic wait_adc_start_count(input int expected, input int max_cycles = 100);
|
||||||
|
int i;
|
||||||
|
begin
|
||||||
|
for (i = 0; i < max_cycles; i++) begin
|
||||||
|
@(posedge adc_clk_in);
|
||||||
|
|
||||||
|
if (adc_start_count >= expected)
|
||||||
|
return;
|
||||||
|
end
|
||||||
|
|
||||||
|
$fatal(1,
|
||||||
|
"Timeout waiting for adc_start_count >= %0d, current=%0d",
|
||||||
|
expected,
|
||||||
|
adc_start_count
|
||||||
|
);
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task automatic wait_cfg_applied(
|
||||||
|
|
||||||
|
input logic [31:0] exp_pulse_width,
|
||||||
|
input logic [31:0] exp_pulse_period,
|
||||||
|
input logic [15:0] exp_pulse_num,
|
||||||
|
input logic [15:0] exp_pulse_height_raw,
|
||||||
|
input logic [31:0] exp_pulse_period_adc,
|
||||||
|
input logic [31:0] exp_window_size,
|
||||||
|
input int max_cycles = 200
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [DAC_DATA_WIDTH-1:0] exp_height;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
exp_height = exp_pulse_height_raw[DAC_DATA_WIDTH-1:0];
|
||||||
|
|
||||||
|
for(i=0;i<max_cycles;i++) begin
|
||||||
|
|
||||||
|
@(posedge ctrl_clk);
|
||||||
|
|
||||||
|
if(
|
||||||
|
|
||||||
|
dac_pulse_width == exp_pulse_width &&
|
||||||
|
dac_pulse_period == exp_pulse_period &&
|
||||||
|
dac_pulse_num == exp_pulse_num &&
|
||||||
|
dac_pulse_height == exp_height &&
|
||||||
|
|
||||||
|
adc_pulse_period == exp_pulse_period_adc &&
|
||||||
|
adc_pulse_num == exp_pulse_num &&
|
||||||
|
adc_window_size == exp_window_size
|
||||||
|
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
$fatal("Configuration timeout");
|
||||||
|
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Test sequence
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
logic [31:0] test_pulse_width;
|
||||||
|
logic [31:0] test_pulse_period;
|
||||||
|
logic [15:0] test_pulse_num;
|
||||||
|
logic [15:0] test_pulse_height_raw;
|
||||||
|
logic [31:0] test_pulse_period_adc;
|
||||||
|
logic [31:0] test_window_size;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
// defaults
|
||||||
|
rst_n = 1'b0;
|
||||||
|
rst_soft = 1'b0;
|
||||||
|
|
||||||
|
start = 1'b0;
|
||||||
|
finish = 1'b0;
|
||||||
|
|
||||||
|
cfg_bus_input = '0;
|
||||||
|
cfg_bus_valid = 1'b0;
|
||||||
|
|
||||||
|
test_pulse_width = 32'h11223344;
|
||||||
|
test_pulse_period = 32'h55667788;
|
||||||
|
test_pulse_num = 16'hA1B2;
|
||||||
|
test_pulse_height_raw = 16'h0CDE; // for DAC_DATA_WIDTH=12 => 12'hCDE
|
||||||
|
test_pulse_period_adc = 32'h50607080;
|
||||||
|
test_window_size = 32'hABCDEF55;
|
||||||
|
|
||||||
|
repeat (10) @(posedge ctrl_clk);
|
||||||
|
rst_n = 1'b1;
|
||||||
|
|
||||||
|
repeat (10) @(posedge ctrl_clk);
|
||||||
|
|
||||||
|
//--------------------------------------------------------
|
||||||
|
// TEST 1: soft_reset
|
||||||
|
//--------------------------------------------------------
|
||||||
|
|
||||||
|
$display("[%0t] TEST 1: soft_reset", $time);
|
||||||
|
|
||||||
|
send_cmd(8'h0F);
|
||||||
|
|
||||||
|
wait_dac_rst_count(1);
|
||||||
|
wait_adc_rst_count(1);
|
||||||
|
|
||||||
|
if (dac_rst_count != 1) begin
|
||||||
|
$fatal(1,
|
||||||
|
"Expected exactly one dac_rst pulse after first soft_reset, got %0d",
|
||||||
|
dac_rst_count
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (adc_rst_count != 1) begin
|
||||||
|
$fatal(1,
|
||||||
|
"Expected exactly one adc_rst pulse after first soft_reset, got %0d",
|
||||||
|
adc_rst_count
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
$display("[%0t] TEST 1 passed", $time);
|
||||||
|
|
||||||
|
//--------------------------------------------------------
|
||||||
|
// TEST 2: set_data
|
||||||
|
//--------------------------------------------------------
|
||||||
|
|
||||||
|
$display("[%0t] TEST 2: set_data", $time);
|
||||||
|
|
||||||
|
send_set_data(
|
||||||
|
|
||||||
|
test_pulse_width,
|
||||||
|
test_pulse_period,
|
||||||
|
test_pulse_num,
|
||||||
|
test_pulse_height_raw,
|
||||||
|
test_pulse_period_adc,
|
||||||
|
test_window_size
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
wait_cfg_applied(
|
||||||
|
|
||||||
|
test_pulse_width,
|
||||||
|
test_pulse_period,
|
||||||
|
test_pulse_num,
|
||||||
|
test_pulse_height_raw,
|
||||||
|
test_pulse_period_adc,
|
||||||
|
test_window_size
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
if (dac_pulse_width !== 32'h11223344) begin
|
||||||
|
$fatal(1,
|
||||||
|
"dac_pulse_width mismatch: got %h expected %h",
|
||||||
|
dac_pulse_width,
|
||||||
|
32'h11223344
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (dac_pulse_period !== 32'h55667788) begin
|
||||||
|
$fatal(1,
|
||||||
|
"dac_pulse_period mismatch: got %h expected %h",
|
||||||
|
dac_pulse_period,
|
||||||
|
32'h55667788
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (dac_pulse_num !== 16'hA1B2) begin
|
||||||
|
$fatal(1,
|
||||||
|
"dac_pulse_num mismatch: got %h expected %h",
|
||||||
|
dac_pulse_num,
|
||||||
|
16'hA1B2
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (dac_pulse_height !== 12'hCDE) begin
|
||||||
|
$fatal(1,
|
||||||
|
"dac_pulse_height mismatch: got %h expected %h",
|
||||||
|
dac_pulse_height,
|
||||||
|
12'hCDE
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (adc_pulse_period !== 32'h50607080) begin
|
||||||
|
$fatal(1,
|
||||||
|
"adc_pulse_period mismatch: got %h expected %h",
|
||||||
|
adc_pulse_period,
|
||||||
|
32'h50607080
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (adc_pulse_num !== 16'hA1B2) begin
|
||||||
|
$fatal(1,
|
||||||
|
"adc_pulse_num mismatch: got %h expected %h",
|
||||||
|
adc_pulse_num,
|
||||||
|
16'hA1B2
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if(adc_window_size != test_window_size)
|
||||||
|
|
||||||
|
$fatal(
|
||||||
|
"adc_window_size mismatch. got=%h expected=%h",
|
||||||
|
adc_window_size,
|
||||||
|
test_window_size
|
||||||
|
);
|
||||||
|
|
||||||
|
$display("[%0t] TEST 2 passed", $time);
|
||||||
|
|
||||||
|
repeat (20) @(posedge ctrl_clk);
|
||||||
|
|
||||||
|
//--------------------------------------------------------
|
||||||
|
// TEST 3: start
|
||||||
|
//--------------------------------------------------------
|
||||||
|
|
||||||
|
$display("[%0t] TEST 3: start", $time);
|
||||||
|
|
||||||
|
send_cmd(8'hF0);
|
||||||
|
|
||||||
|
wait_dac_start_count(1);
|
||||||
|
wait_adc_start_count(1);
|
||||||
|
|
||||||
|
if (dac_start_count != 1) begin
|
||||||
|
$fatal(1,
|
||||||
|
"Expected exactly one dac_start pulse after first start, got %0d",
|
||||||
|
dac_start_count
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (adc_start_count != 1) begin
|
||||||
|
$fatal(1,
|
||||||
|
"Expected exactly one adc_start pulse after first start, got %0d",
|
||||||
|
adc_start_count
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (!busy) begin
|
||||||
|
$fatal(1,
|
||||||
|
"busy must be asserted after start"
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
$display("[%0t] TEST 3 start pulses passed", $time);
|
||||||
|
|
||||||
|
//--------------------------------------------------------
|
||||||
|
// release busy by finish pulse from ADC domain
|
||||||
|
//--------------------------------------------------------
|
||||||
|
|
||||||
|
$display("[%0t] Sending finish pulse", $time);
|
||||||
|
|
||||||
|
pulse_finish();
|
||||||
|
|
||||||
|
repeat (20) @(posedge ctrl_clk);
|
||||||
|
|
||||||
|
if (busy) begin
|
||||||
|
$fatal(1,
|
||||||
|
"busy was not cleared after finish pulse"
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
//--------------------------------------------------------
|
||||||
|
// sanity check that commands are accepted again after finish
|
||||||
|
//--------------------------------------------------------
|
||||||
|
|
||||||
|
$display("[%0t] TEST 4: soft_reset after finish", $time);
|
||||||
|
|
||||||
|
send_cmd(8'h0F);
|
||||||
|
|
||||||
|
wait_dac_rst_count(2);
|
||||||
|
wait_adc_rst_count(2);
|
||||||
|
|
||||||
|
if (dac_rst_count != 2) begin
|
||||||
|
$fatal(1,
|
||||||
|
"Expected exactly two dac_rst pulses total, got %0d",
|
||||||
|
dac_rst_count
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (adc_rst_count != 2) begin
|
||||||
|
$fatal(1,
|
||||||
|
"Expected exactly two adc_rst pulses total, got %0d",
|
||||||
|
adc_rst_count
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
$display("[%0t] TEST 4 passed", $time);
|
||||||
|
|
||||||
|
//--------------------------------------------------------
|
||||||
|
|
||||||
|
$display("==============================================");
|
||||||
|
$display("ALL BASIC TESTS PASSED");
|
||||||
|
$display("dac_rst_count = %0d", dac_rst_count);
|
||||||
|
$display("adc_rst_count = %0d", adc_rst_count);
|
||||||
|
$display("dac_start_count = %0d", dac_start_count);
|
||||||
|
$display("adc_start_count = %0d", adc_start_count);
|
||||||
|
$display("==============================================");
|
||||||
|
|
||||||
|
#50;
|
||||||
|
|
||||||
|
//--------------------------------------------------------
|
||||||
|
// TEST 2.1: set_data
|
||||||
|
//--------------------------------------------------------
|
||||||
|
|
||||||
|
test_pulse_width = 32'h12121212;
|
||||||
|
test_pulse_period = 32'h34343434;
|
||||||
|
test_pulse_num = 16'h1A2B;
|
||||||
|
test_pulse_height_raw = 16'hC0ED; // for DAC_DATA_WIDTH=12 => 12'hCDE
|
||||||
|
test_pulse_period_adc = 32'h56565656;
|
||||||
|
test_window_size = 32'h01020304;
|
||||||
|
|
||||||
|
$display("[%0t] TEST 2.1: set_data", $time);
|
||||||
|
|
||||||
|
send_set_data(
|
||||||
|
test_pulse_width,
|
||||||
|
test_pulse_period,
|
||||||
|
test_pulse_num,
|
||||||
|
test_pulse_height_raw,
|
||||||
|
test_pulse_period_adc,
|
||||||
|
test_window_size
|
||||||
|
);
|
||||||
|
|
||||||
|
wait_cfg_applied(
|
||||||
|
test_pulse_width,
|
||||||
|
test_pulse_period,
|
||||||
|
test_pulse_num,
|
||||||
|
test_pulse_height_raw,
|
||||||
|
test_pulse_period_adc,
|
||||||
|
test_window_size
|
||||||
|
);
|
||||||
|
|
||||||
|
if (dac_pulse_width !== 32'h12121212) begin
|
||||||
|
$fatal(1,
|
||||||
|
"dac_pulse_width mismatch: got %h expected %h",
|
||||||
|
dac_pulse_width,
|
||||||
|
32'h12121212
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (dac_pulse_period !== 32'h34343434) begin
|
||||||
|
$fatal(1,
|
||||||
|
"dac_pulse_period mismatch: got %h expected %h",
|
||||||
|
dac_pulse_period,
|
||||||
|
32'h34343434
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (dac_pulse_num !== 16'h1A2B) begin
|
||||||
|
$fatal(1,
|
||||||
|
"dac_pulse_num mismatch: got %h expected %h",
|
||||||
|
dac_pulse_num,
|
||||||
|
16'h1A2B
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (dac_pulse_height !== 12'hC0ED) begin
|
||||||
|
$fatal(1,
|
||||||
|
"dac_pulse_height mismatch: got %h expected %h",
|
||||||
|
dac_pulse_height,
|
||||||
|
12'hC0ED
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (adc_pulse_period !== 32'h56565656) begin
|
||||||
|
$fatal(1,
|
||||||
|
"adc_pulse_period mismatch: got %h expected %h",
|
||||||
|
adc_pulse_period,
|
||||||
|
32'h56565656
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
$display("[%0t] TEST 2.1 passed", $time);
|
||||||
|
|
||||||
|
repeat (20) @(posedge ctrl_clk);
|
||||||
|
|
||||||
|
//--------------------------------------------------------
|
||||||
|
// TEST 3.1: start
|
||||||
|
//--------------------------------------------------------
|
||||||
|
|
||||||
|
$display("[%0t] TEST 3.1: start", $time);
|
||||||
|
|
||||||
|
send_cmd(8'hF0);
|
||||||
|
|
||||||
|
wait_dac_start_count(2);
|
||||||
|
wait_adc_start_count(2);
|
||||||
|
|
||||||
|
if (dac_start_count != 2) begin
|
||||||
|
$fatal(1,
|
||||||
|
"Expected exactly one dac_start pulse after first start, got %0d",
|
||||||
|
dac_start_count
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (adc_start_count != 2) begin
|
||||||
|
$fatal(1,
|
||||||
|
"Expected exactly one adc_start pulse after first start, got %0d",
|
||||||
|
adc_start_count
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (!busy) begin
|
||||||
|
$fatal(1,
|
||||||
|
"busy must be asserted after start"
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
$display("[%0t] TEST 3.1 start pulses passed", $time);
|
||||||
|
|
||||||
|
//--------------------------------------------------------
|
||||||
|
// release busy by finish pulse from ADC domain
|
||||||
|
//--------------------------------------------------------
|
||||||
|
|
||||||
|
$display("[%0t] Sending finish pulse", $time);
|
||||||
|
|
||||||
|
pulse_finish();
|
||||||
|
|
||||||
|
repeat (20) @(posedge ctrl_clk);
|
||||||
|
|
||||||
|
if (busy) begin
|
||||||
|
$fatal(1,
|
||||||
|
"busy was not cleared after finish pulse"
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
//--------------------------------------------------------
|
||||||
|
// sanity check that commands are accepted again after finish
|
||||||
|
//--------------------------------------------------------
|
||||||
|
|
||||||
|
$display("[%0t] TEST 4.1: soft_reset after finish", $time);
|
||||||
|
|
||||||
|
send_cmd(8'h0F);
|
||||||
|
|
||||||
|
wait_dac_rst_count(2);
|
||||||
|
wait_adc_rst_count(2);
|
||||||
|
|
||||||
|
if (dac_rst_count != 2) begin
|
||||||
|
$fatal(1,
|
||||||
|
"Expected exactly two dac_rst pulses total, got %0d",
|
||||||
|
dac_rst_count
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (adc_rst_count != 2) begin
|
||||||
|
$fatal(1,
|
||||||
|
"Expected exactly two adc_rst pulses total, got %0d",
|
||||||
|
adc_rst_count
|
||||||
|
);
|
||||||
|
end
|
||||||
|
|
||||||
|
$display("[%0t] TEST 4.1 passed", $time);
|
||||||
|
|
||||||
|
//--------------------------------------------------------
|
||||||
|
|
||||||
|
$display("==============================================");
|
||||||
|
$display("ALL BASIC TESTS PASSED");
|
||||||
|
$display("dac_rst_count = %0d", dac_rst_count);
|
||||||
|
$display("adc_rst_count = %0d", adc_rst_count);
|
||||||
|
$display("dac_start_count = %0d", dac_start_count);
|
||||||
|
$display("adc_start_count = %0d", adc_start_count);
|
||||||
|
$display("==============================================");
|
||||||
|
$finish;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
@@ -0,0 +1,236 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<wave_config>
|
||||||
|
<wave_state>
|
||||||
|
</wave_state>
|
||||||
|
<db_ref_list>
|
||||||
|
<db_ref path="tb_control_behav.wdb" id="1">
|
||||||
|
<top_modules>
|
||||||
|
<top_module name="glbl" />
|
||||||
|
<top_module name="tb_control" />
|
||||||
|
</top_modules>
|
||||||
|
</db_ref>
|
||||||
|
</db_ref_list>
|
||||||
|
<zoom_setting>
|
||||||
|
<ZoomStartTime time="160.614 ns"></ZoomStartTime>
|
||||||
|
<ZoomEndTime time="1,564.737 ns"></ZoomEndTime>
|
||||||
|
<Cursor1Time time="1,330.716 ns"></Cursor1Time>
|
||||||
|
</zoom_setting>
|
||||||
|
<column_width_setting>
|
||||||
|
<NameColumnWidth column_width="479"></NameColumnWidth>
|
||||||
|
<ValueColumnWidth column_width="116"></ValueColumnWidth>
|
||||||
|
</column_width_setting>
|
||||||
|
<WVObjectSize size="34" />
|
||||||
|
<wvobject fp_name="/tb_control/dac_clk_in" type="logic">
|
||||||
|
<obj_property name="ElementShortName">dac_clk_in</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">dac_clk_in</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/adc_clk_in" type="logic">
|
||||||
|
<obj_property name="ElementShortName">adc_clk_in</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">adc_clk_in</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/rst_n" type="logic">
|
||||||
|
<obj_property name="ElementShortName">rst_n</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">rst_n</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#800080</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/rst_soft" type="logic">
|
||||||
|
<obj_property name="ElementShortName">rst_soft</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">rst_soft</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#008080</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/start" type="logic">
|
||||||
|
<obj_property name="ElementShortName">start</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">start</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#E0FFFF</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dut/adc_start_pulse" type="logic">
|
||||||
|
<obj_property name="ElementShortName">adc_start_pulse</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">adc_start_pulse</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dut/dac_start_pulse" type="logic">
|
||||||
|
<obj_property name="ElementShortName">dac_start_pulse</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">dac_start_pulse</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/busy" type="logic">
|
||||||
|
<obj_property name="ElementShortName">busy</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">busy</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#E0FFFF</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/finish" type="logic">
|
||||||
|
<obj_property name="ElementShortName">finish</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">finish</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FAAFBE</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dut/finish_pulse" type="logic">
|
||||||
|
<obj_property name="ElementShortName">finish_pulse</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">finish_pulse</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/cfg_bus_valid" type="logic">
|
||||||
|
<obj_property name="ElementShortName">cfg_bus_valid</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">cfg_bus_valid</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FF0080</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/cfg_bus_input" type="array">
|
||||||
|
<obj_property name="ElementShortName">cfg_bus_input[159:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">cfg_bus_input[159:0]</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FF0080</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dac_pulse_width" type="array">
|
||||||
|
<obj_property name="ElementShortName">dac_pulse_width[31:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">dac_pulse_width[31:0]</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dac_pulse_period" type="array">
|
||||||
|
<obj_property name="ElementShortName">dac_pulse_period[31:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">dac_pulse_period[31:0]</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dac_pulse_height" type="array">
|
||||||
|
<obj_property name="ElementShortName">dac_pulse_height[11:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">dac_pulse_height[11:0]</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
<obj_property name="Radix">HEXRADIX</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dac_pulse_num" type="array">
|
||||||
|
<obj_property name="ElementShortName">dac_pulse_num[15:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">dac_pulse_num[15:0]</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/adc_pulse_period" type="array">
|
||||||
|
<obj_property name="ElementShortName">adc_pulse_period[31:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">adc_pulse_period[31:0]</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/adc_pulse_num" type="array">
|
||||||
|
<obj_property name="ElementShortName">adc_pulse_num[15:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">adc_pulse_num[15:0]</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/adc_window_size" type="array">
|
||||||
|
<obj_property name="ElementShortName">adc_window_size[31:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">adc_window_size[31:0]</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dac_start" type="logic">
|
||||||
|
<obj_property name="ElementShortName">dac_start</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">dac_start</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/adc_start" type="logic">
|
||||||
|
<obj_property name="ElementShortName">adc_start</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">adc_start</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dac_rst" type="logic">
|
||||||
|
<obj_property name="ElementShortName">dac_rst</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">dac_rst</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FFA500</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/adc_rst" type="logic">
|
||||||
|
<obj_property name="ElementShortName">adc_rst</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">adc_rst</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="group499" type="group">
|
||||||
|
<obj_property name="label">tb signals</obj_property>
|
||||||
|
<obj_property name="DisplayName">label</obj_property>
|
||||||
|
<wvobject fp_name="/tb_control/dac_rst_count" type="array">
|
||||||
|
<obj_property name="ElementShortName">dac_rst_count[31:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">dac_rst_count[31:0]</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/adc_rst_count" type="array">
|
||||||
|
<obj_property name="ElementShortName">adc_rst_count[31:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">adc_rst_count[31:0]</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dac_start_count" type="array">
|
||||||
|
<obj_property name="ElementShortName">dac_start_count[31:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">dac_start_count[31:0]</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/adc_start_count" type="array">
|
||||||
|
<obj_property name="ElementShortName">adc_start_count[31:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">adc_start_count[31:0]</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#F0E68C</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dut/cfg_req_toggle_adc" type="logic">
|
||||||
|
<obj_property name="ElementShortName">cfg_req_toggle_adc</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">cfg_req_toggle_adc</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dut/cfg_req_toggle_dac" type="logic">
|
||||||
|
<obj_property name="ElementShortName">cfg_req_toggle_dac</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">cfg_req_toggle_dac</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FFFF00</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dut/cfg_ack_toggle_adc" type="logic">
|
||||||
|
<obj_property name="ElementShortName">cfg_ack_toggle_adc</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">cfg_ack_toggle_adc</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FF00FF</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dut/cfg_ack_toggle_dac" type="logic">
|
||||||
|
<obj_property name="ElementShortName">cfg_ack_toggle_dac</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">cfg_ack_toggle_dac</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#FF00FF</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dut/cfg_wait_adc_ack" type="logic">
|
||||||
|
<obj_property name="ElementShortName">cfg_wait_adc_ack</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">cfg_wait_adc_ack</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#0000FF</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dut/cfg_wait_dac_ack" type="logic">
|
||||||
|
<obj_property name="ElementShortName">cfg_wait_dac_ack</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">cfg_wait_dac_ack</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#0000FF</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dut/cfg_req_pulse_adc" type="logic">
|
||||||
|
<obj_property name="ElementShortName">cfg_req_pulse_adc</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">cfg_req_pulse_adc</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#808000</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dut/cfg_req_pulse_dac" type="logic">
|
||||||
|
<obj_property name="ElementShortName">cfg_req_pulse_dac</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">cfg_req_pulse_dac</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#808000</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dut/cfg_ack_pulse_adc" type="logic">
|
||||||
|
<obj_property name="ElementShortName">cfg_ack_pulse_adc</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">cfg_ack_pulse_adc</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#DCDCDC</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject fp_name="/tb_control/dut/cfg_ack_pulse_dac" type="logic">
|
||||||
|
<obj_property name="ElementShortName">cfg_ack_pulse_dac</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">cfg_ack_pulse_dac</obj_property>
|
||||||
|
<obj_property name="CustomSignalColor">#DCDCDC</obj_property>
|
||||||
|
<obj_property name="UseCustomSignalColor">true</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
</wave_config>
|
||||||
@@ -0,0 +1,338 @@
|
|||||||
|
module tb_controller_wrapper_axil #(
|
||||||
|
parameter int unsigned ADDR_W = 16,
|
||||||
|
parameter int unsigned DATA_W = 32,
|
||||||
|
parameter int unsigned USER_W = 1,
|
||||||
|
|
||||||
|
parameter int unsigned DAC_DATA_WIDTH = 12,
|
||||||
|
|
||||||
|
parameter int unsigned AXI_ADDR_WIDTH = 16,
|
||||||
|
parameter int unsigned AXIS_ID_WIDTH = 8,
|
||||||
|
parameter int unsigned LEN_WIDTH = 20,
|
||||||
|
parameter int unsigned AXIS_USER_WIDTH = 1,
|
||||||
|
parameter int unsigned AXIS_DEST_WIDTH = 8,
|
||||||
|
parameter int unsigned TAG_WIDTH = 8,
|
||||||
|
|
||||||
|
parameter int unsigned READ_DESC_WIDTH = AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH + AXIS_ID_WIDTH + AXIS_DEST_WIDTH + AXIS_USER_WIDTH,
|
||||||
|
parameter int unsigned WRITE_DESC_WIDTH = AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH,
|
||||||
|
|
||||||
|
parameter int unsigned READ_STATUS_WIDTH = TAG_WIDTH + 4,
|
||||||
|
parameter int unsigned WRITE_STATUS_WIDTH = LEN_WIDTH + TAG_WIDTH + AXIS_ID_WIDTH + AXIS_DEST_WIDTH + AXIS_USER_WIDTH + 4,
|
||||||
|
|
||||||
|
// ceil(width / 8), чтобы keep/strb не стали слишком узкими для нестандартных ширин типа 12/49/61.
|
||||||
|
parameter int unsigned READ_DESC_KEEP_W = (READ_DESC_WIDTH + 7) / 8,
|
||||||
|
parameter int unsigned WRITE_DESC_KEEP_W = (WRITE_DESC_WIDTH + 7) / 8,
|
||||||
|
parameter int unsigned READ_STATUS_KEEP_W = (READ_STATUS_WIDTH + 7) / 8,
|
||||||
|
parameter int unsigned WRITE_STATUS_KEEP_W = (WRITE_STATUS_WIDTH + 7) / 8
|
||||||
|
)(
|
||||||
|
input logic ctrl_clk,
|
||||||
|
input logic rst,
|
||||||
|
|
||||||
|
input logic [ADDR_W-1:0] s_axil_awaddr,
|
||||||
|
input logic [2:0] s_axil_awprot,
|
||||||
|
input logic s_axil_awvalid,
|
||||||
|
output logic s_axil_awready,
|
||||||
|
|
||||||
|
input logic [DATA_W-1:0] s_axil_wdata,
|
||||||
|
input logic [DATA_W/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 [ADDR_W-1:0] s_axil_araddr,
|
||||||
|
input logic [2:0] s_axil_arprot,
|
||||||
|
input logic s_axil_arvalid,
|
||||||
|
output logic s_axil_arready,
|
||||||
|
|
||||||
|
output logic [DATA_W-1:0] s_axil_rdata,
|
||||||
|
output logic [1:0] s_axil_rresp,
|
||||||
|
output logic s_axil_rvalid,
|
||||||
|
input logic s_axil_rready,
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Минимальный flat-view для DMA AXIS портов.
|
||||||
|
// Наружу оставлены только tdata/tvalid/tready в старом стиле.
|
||||||
|
// Все остальные AXIS поля внутри обёртки завязаны на безопасные значения.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// DUT master -> testbench: descriptor commands.
|
||||||
|
output logic [READ_DESC_WIDTH-1:0] desc_read_cmd_out,
|
||||||
|
output logic valid_desc_read,
|
||||||
|
input logic ready_desc_read,
|
||||||
|
|
||||||
|
output logic [WRITE_DESC_WIDTH-1:0] desc_write_cmd_out,
|
||||||
|
output logic valid_desc_write,
|
||||||
|
input logic ready_desc_write,
|
||||||
|
|
||||||
|
// testbench -> DUT slave: status commands.
|
||||||
|
input logic [READ_STATUS_WIDTH-1:0] status_read_cmd_in,
|
||||||
|
input logic valid_status_read,
|
||||||
|
output logic ready_status_read,
|
||||||
|
|
||||||
|
input logic [WRITE_STATUS_WIDTH-1:0] status_write_cmd_in,
|
||||||
|
input logic valid_status_write,
|
||||||
|
output logic ready_status_write
|
||||||
|
);
|
||||||
|
|
||||||
|
logic rst_n;
|
||||||
|
assign rst_n = ~rst;
|
||||||
|
|
||||||
|
// Для минимального теста держим все clock domain-ы на одном clock.
|
||||||
|
logic dac_clk_in;
|
||||||
|
logic adc_clk_in;
|
||||||
|
assign dac_clk_in = ctrl_clk;
|
||||||
|
assign adc_clk_in = ctrl_clk;
|
||||||
|
|
||||||
|
logic finish;
|
||||||
|
assign finish = 1'b0;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// AXI-Lite flat -> axi4l_if
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
axi4l_if #(
|
||||||
|
.ADDR_W(ADDR_W),
|
||||||
|
.DATA_W(DATA_W),
|
||||||
|
.USER_W(USER_W)
|
||||||
|
) axil_bus (
|
||||||
|
.aclk(ctrl_clk),
|
||||||
|
.aresetn(rst_n)
|
||||||
|
);
|
||||||
|
|
||||||
|
axi4l_flat_to_if #(
|
||||||
|
.ADDR_W(ADDR_W),
|
||||||
|
.DATA_W(DATA_W),
|
||||||
|
.USER_W(USER_W)
|
||||||
|
) 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_if #(
|
||||||
|
.DATA_W(READ_STATUS_WIDTH),
|
||||||
|
.KEEP_W(READ_STATUS_KEEP_W),
|
||||||
|
.ID_W(AXIS_ID_WIDTH),
|
||||||
|
.DEST_W(AXIS_DEST_WIDTH),
|
||||||
|
.USER_W(AXIS_USER_WIDTH)
|
||||||
|
) axis_status_read (
|
||||||
|
.aclk(ctrl_clk),
|
||||||
|
.aresetn(rst_n)
|
||||||
|
);
|
||||||
|
|
||||||
|
axis_if #(
|
||||||
|
.DATA_W(WRITE_STATUS_WIDTH),
|
||||||
|
.KEEP_W(WRITE_STATUS_KEEP_W),
|
||||||
|
.ID_W(AXIS_ID_WIDTH),
|
||||||
|
.DEST_W(AXIS_DEST_WIDTH),
|
||||||
|
.USER_W(AXIS_USER_WIDTH)
|
||||||
|
) axis_status_write (
|
||||||
|
.aclk(ctrl_clk),
|
||||||
|
.aresetn(rst_n)
|
||||||
|
);
|
||||||
|
|
||||||
|
axis_if #(
|
||||||
|
.DATA_W(READ_DESC_WIDTH),
|
||||||
|
.KEEP_W(READ_DESC_KEEP_W),
|
||||||
|
.ID_W(AXIS_ID_WIDTH),
|
||||||
|
.DEST_W(AXIS_DEST_WIDTH),
|
||||||
|
.USER_W(AXIS_USER_WIDTH)
|
||||||
|
) axis_desc_read (
|
||||||
|
.aclk(ctrl_clk),
|
||||||
|
.aresetn(rst_n)
|
||||||
|
);
|
||||||
|
|
||||||
|
axis_if #(
|
||||||
|
.DATA_W(WRITE_DESC_WIDTH),
|
||||||
|
.KEEP_W(WRITE_DESC_KEEP_W),
|
||||||
|
.ID_W(AXIS_ID_WIDTH),
|
||||||
|
.DEST_W(AXIS_DEST_WIDTH),
|
||||||
|
.USER_W(AXIS_USER_WIDTH)
|
||||||
|
) axis_desc_write (
|
||||||
|
.aclk(ctrl_clk),
|
||||||
|
.aresetn(rst_n)
|
||||||
|
);
|
||||||
|
|
||||||
|
// testbench flat status -> DUT AXIS slave ports
|
||||||
|
axis_flat_to_if #(
|
||||||
|
.DATA_W(READ_STATUS_WIDTH),
|
||||||
|
.KEEP_W(READ_STATUS_KEEP_W),
|
||||||
|
.ID_W(AXIS_ID_WIDTH),
|
||||||
|
.DEST_W(AXIS_DEST_WIDTH),
|
||||||
|
.USER_W(AXIS_USER_WIDTH)
|
||||||
|
) u_status_read_flat_to_if (
|
||||||
|
.s_axis_tdata (status_read_cmd_in),
|
||||||
|
.s_axis_tkeep ({READ_STATUS_KEEP_W{1'b1}}),
|
||||||
|
.s_axis_tstrb ({READ_STATUS_KEEP_W{1'b1}}),
|
||||||
|
.s_axis_tlast (1'b1),
|
||||||
|
.s_axis_tid ('0),
|
||||||
|
.s_axis_tdest ('0),
|
||||||
|
.s_axis_tuser ('0),
|
||||||
|
.s_axis_tvalid(valid_status_read),
|
||||||
|
.s_axis_tready(ready_status_read),
|
||||||
|
|
||||||
|
.m_axis(axis_status_read)
|
||||||
|
);
|
||||||
|
|
||||||
|
axis_flat_to_if #(
|
||||||
|
.DATA_W(WRITE_STATUS_WIDTH),
|
||||||
|
.KEEP_W(WRITE_STATUS_KEEP_W),
|
||||||
|
.ID_W(AXIS_ID_WIDTH),
|
||||||
|
.DEST_W(AXIS_DEST_WIDTH),
|
||||||
|
.USER_W(AXIS_USER_WIDTH)
|
||||||
|
) u_status_write_flat_to_if (
|
||||||
|
.s_axis_tdata (status_write_cmd_in),
|
||||||
|
.s_axis_tkeep ({WRITE_STATUS_KEEP_W{1'b1}}),
|
||||||
|
.s_axis_tstrb ({WRITE_STATUS_KEEP_W{1'b1}}),
|
||||||
|
.s_axis_tlast (1'b1),
|
||||||
|
.s_axis_tid ('0),
|
||||||
|
.s_axis_tdest ('0),
|
||||||
|
.s_axis_tuser ('0),
|
||||||
|
.s_axis_tvalid(valid_status_write),
|
||||||
|
.s_axis_tready(ready_status_write),
|
||||||
|
|
||||||
|
.m_axis(axis_status_write)
|
||||||
|
);
|
||||||
|
|
||||||
|
// DUT AXIS master ports -> testbench flat descriptor outputs
|
||||||
|
logic [READ_DESC_KEEP_W-1:0] unused_desc_read_tkeep;
|
||||||
|
logic [READ_DESC_KEEP_W-1:0] unused_desc_read_tstrb;
|
||||||
|
logic unused_desc_read_tlast;
|
||||||
|
logic [AXIS_ID_WIDTH-1:0] unused_desc_read_tid;
|
||||||
|
logic [AXIS_DEST_WIDTH-1:0] unused_desc_read_tdest;
|
||||||
|
logic [AXIS_USER_WIDTH-1:0] unused_desc_read_tuser;
|
||||||
|
|
||||||
|
axis_if_to_flat #(
|
||||||
|
.DATA_W(READ_DESC_WIDTH),
|
||||||
|
.KEEP_W(READ_DESC_KEEP_W),
|
||||||
|
.ID_W(AXIS_ID_WIDTH),
|
||||||
|
.DEST_W(AXIS_DEST_WIDTH),
|
||||||
|
.USER_W(AXIS_USER_WIDTH)
|
||||||
|
) u_desc_read_if_to_flat (
|
||||||
|
.s_axis(axis_desc_read),
|
||||||
|
|
||||||
|
.m_axis_tdata (desc_read_cmd_out),
|
||||||
|
.m_axis_tkeep (unused_desc_read_tkeep),
|
||||||
|
.m_axis_tstrb (unused_desc_read_tstrb),
|
||||||
|
.m_axis_tlast (unused_desc_read_tlast),
|
||||||
|
.m_axis_tid (unused_desc_read_tid),
|
||||||
|
.m_axis_tdest (unused_desc_read_tdest),
|
||||||
|
.m_axis_tuser (unused_desc_read_tuser),
|
||||||
|
.m_axis_tvalid(valid_desc_read),
|
||||||
|
.m_axis_tready(ready_desc_read)
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [WRITE_DESC_KEEP_W-1:0] unused_desc_write_tkeep;
|
||||||
|
logic [WRITE_DESC_KEEP_W-1:0] unused_desc_write_tstrb;
|
||||||
|
logic unused_desc_write_tlast;
|
||||||
|
logic [AXIS_ID_WIDTH-1:0] unused_desc_write_tid;
|
||||||
|
logic [AXIS_DEST_WIDTH-1:0] unused_desc_write_tdest;
|
||||||
|
logic [AXIS_USER_WIDTH-1:0] unused_desc_write_tuser;
|
||||||
|
|
||||||
|
axis_if_to_flat #(
|
||||||
|
.DATA_W(WRITE_DESC_WIDTH),
|
||||||
|
.KEEP_W(WRITE_DESC_KEEP_W),
|
||||||
|
.ID_W(AXIS_ID_WIDTH),
|
||||||
|
.DEST_W(AXIS_DEST_WIDTH),
|
||||||
|
.USER_W(AXIS_USER_WIDTH)
|
||||||
|
) u_desc_write_if_to_flat (
|
||||||
|
.s_axis(axis_desc_write),
|
||||||
|
|
||||||
|
.m_axis_tdata (desc_write_cmd_out),
|
||||||
|
.m_axis_tkeep (unused_desc_write_tkeep),
|
||||||
|
.m_axis_tstrb (unused_desc_write_tstrb),
|
||||||
|
.m_axis_tlast (unused_desc_write_tlast),
|
||||||
|
.m_axis_tid (unused_desc_write_tid),
|
||||||
|
.m_axis_tdest (unused_desc_write_tdest),
|
||||||
|
.m_axis_tuser (unused_desc_write_tuser),
|
||||||
|
.m_axis_tvalid(valid_desc_write),
|
||||||
|
.m_axis_tready(ready_desc_write)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Controller ADC/DAC outputs.
|
||||||
|
logic [31:0] adc_window_size;
|
||||||
|
logic [31:0] dac_pulse_width;
|
||||||
|
logic [31:0] dac_pulse_period;
|
||||||
|
logic [DAC_DATA_WIDTH-1:0] dac_pulse_height;
|
||||||
|
logic [15:0] dac_pulse_num;
|
||||||
|
logic [31:0] adc_pulse_period;
|
||||||
|
logic [15:0] adc_pulse_num;
|
||||||
|
logic dac_start;
|
||||||
|
logic adc_start;
|
||||||
|
logic dac_rst;
|
||||||
|
logic adc_rst;
|
||||||
|
|
||||||
|
controller_wrapper_axil #(
|
||||||
|
.ADDR_W(ADDR_W),
|
||||||
|
.DATA_W(DATA_W),
|
||||||
|
.USER_W(USER_W),
|
||||||
|
.DAC_DATA_WIDTH(DAC_DATA_WIDTH),
|
||||||
|
.AXI_ADDR_WIDTH(AXI_ADDR_WIDTH),
|
||||||
|
.AXIS_ID_WIDTH(AXIS_ID_WIDTH),
|
||||||
|
.LEN_WIDTH(LEN_WIDTH),
|
||||||
|
.AXIS_USER_WIDTH(AXIS_USER_WIDTH),
|
||||||
|
.AXIS_DEST_WIDTH(AXIS_DEST_WIDTH),
|
||||||
|
.TAG_WIDTH(TAG_WIDTH),
|
||||||
|
.READ_DESC_WIDTH(READ_DESC_WIDTH),
|
||||||
|
.WRITE_DESC_WIDTH(WRITE_DESC_WIDTH),
|
||||||
|
.READ_STATUS_WIDTH(READ_STATUS_WIDTH),
|
||||||
|
.WRITE_STATUS_WIDTH(WRITE_STATUS_WIDTH)
|
||||||
|
) dut (
|
||||||
|
.ctrl_clk(ctrl_clk),
|
||||||
|
.dac_clk_in(dac_clk_in),
|
||||||
|
.adc_clk_in(adc_clk_in),
|
||||||
|
.rst_n(rst_n),
|
||||||
|
.s_axil(axil_bus),
|
||||||
|
|
||||||
|
.finish(finish),
|
||||||
|
.adc_window_size(adc_window_size),
|
||||||
|
|
||||||
|
.dac_pulse_width(dac_pulse_width),
|
||||||
|
.dac_pulse_period(dac_pulse_period),
|
||||||
|
.dac_pulse_height(dac_pulse_height),
|
||||||
|
.dac_pulse_num(dac_pulse_num),
|
||||||
|
|
||||||
|
.adc_pulse_period(adc_pulse_period),
|
||||||
|
.adc_pulse_num(adc_pulse_num),
|
||||||
|
|
||||||
|
.dac_start(dac_start),
|
||||||
|
.adc_start(adc_start),
|
||||||
|
.dac_rst(dac_rst),
|
||||||
|
.adc_rst(adc_rst),
|
||||||
|
|
||||||
|
.s_axis_status_read(axis_status_read),
|
||||||
|
.s_axis_status_write(axis_status_write),
|
||||||
|
|
||||||
|
.m_axis_desc_read(axis_desc_read),
|
||||||
|
.m_axis_desc_write(axis_desc_write)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule : tb_controller_wrapper_axil
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
import cocotb
|
||||||
|
from cocotb.clock import Clock
|
||||||
|
from cocotb.handle import Immediate
|
||||||
|
from cocotb.triggers import RisingEdge
|
||||||
|
from cocotbext.axi import AxiLiteBus, AxiLiteMaster
|
||||||
|
|
||||||
|
|
||||||
|
# Register indexes from axi4l_reg_map_controller_pkg.sv
|
||||||
|
REG_CONTROL = 0
|
||||||
|
REG_STATUS = 1
|
||||||
|
REG_DAC_WIDTH = 2
|
||||||
|
REG_DAC_PERIOD = 3
|
||||||
|
REG_DAC_PULSE_NUM = 4
|
||||||
|
REG_DAC_PULSE_HEIGHT = 5
|
||||||
|
REG_ADC_PERIOD = 6
|
||||||
|
REG_WINDOW_SIZE = 7
|
||||||
|
REG_ERROR = 8
|
||||||
|
REG_DESC_READ_ADDR = 9
|
||||||
|
REG_DESC_READ_LEN = 10
|
||||||
|
REG_DESC_READ_CONFIG = 11
|
||||||
|
REG_READ_STATUS = 12
|
||||||
|
REG_DESC_WRITE_ADDR = 13
|
||||||
|
REG_DESC_WRITE_LEN_AND_TAG = 14
|
||||||
|
REG_STATUS_WRITE_LEN = 15
|
||||||
|
REG_STATUS_WRITE_CONFIG = 16
|
||||||
|
|
||||||
|
|
||||||
|
# REG_CONTROL pulse bits
|
||||||
|
CTRL_START = 0
|
||||||
|
CTRL_RST_SOFT = 1
|
||||||
|
CTRL_CFG_BUS_VALID = 2
|
||||||
|
CTRL_SEND_DESC_READ = 3
|
||||||
|
CTRL_SEND_DESC_WRITE = 4
|
||||||
|
CTRL_TAKE_STATUS_READ = 5
|
||||||
|
CTRL_TAKE_STATUS_WRITE = 6
|
||||||
|
|
||||||
|
|
||||||
|
def reg_addr(reg_index: int) -> int:
|
||||||
|
# AXI-Lite uses byte addresses, 32-bit registers are spaced by 4 bytes.
|
||||||
|
return reg_index * 4
|
||||||
|
|
||||||
|
|
||||||
|
def u32(value: int) -> bytes:
|
||||||
|
return int(value & 0xFFFFFFFF).to_bytes(4, "little")
|
||||||
|
|
||||||
|
|
||||||
|
class TB:
|
||||||
|
def __init__(self, dut):
|
||||||
|
self.dut = dut
|
||||||
|
|
||||||
|
cocotb.start_soon(Clock(dut.ctrl_clk, 10, units="ns").start())
|
||||||
|
|
||||||
|
self.axil = AxiLiteMaster(
|
||||||
|
AxiLiteBus.from_prefix(dut, "s_axil"),
|
||||||
|
dut.ctrl_clk,
|
||||||
|
dut.rst,
|
||||||
|
)
|
||||||
|
|
||||||
|
async def reset(self):
|
||||||
|
self.dut.rst.value = 1
|
||||||
|
for _ in range(5):
|
||||||
|
await RisingEdge(self.dut.ctrl_clk)
|
||||||
|
|
||||||
|
self.dut.rst.value = 0
|
||||||
|
for _ in range(5):
|
||||||
|
await RisingEdge(self.dut.ctrl_clk)
|
||||||
|
|
||||||
|
async def write_reg(self, reg_index: int, value: int):
|
||||||
|
await self.axil.write(reg_addr(reg_index), u32(value))
|
||||||
|
|
||||||
|
async def read_reg(self, reg_index: int) -> int:
|
||||||
|
resp = await self.axil.read(reg_addr(reg_index), 4)
|
||||||
|
return int.from_bytes(bytes(resp.data), "little")
|
||||||
|
|
||||||
|
|
||||||
|
@cocotb.test()
|
||||||
|
async def simple_axil_write_read(dut):
|
||||||
|
tb = TB(dut)
|
||||||
|
await tb.reset()
|
||||||
|
|
||||||
|
await tb.write_reg(REG_DAC_WIDTH, 0x0000_0123)
|
||||||
|
|
||||||
|
value = await tb.read_reg(REG_DAC_WIDTH)
|
||||||
|
assert value == 0x0000_0123
|
||||||
|
|
||||||
|
|
||||||
|
@cocotb.test()
|
||||||
|
async def simple_controller_config_write(dut):
|
||||||
|
tb = TB(dut)
|
||||||
|
await tb.reset()
|
||||||
|
|
||||||
|
await tb.write_reg(REG_DAC_WIDTH, 0x10)
|
||||||
|
await tb.write_reg(REG_DAC_PERIOD, 0x40)
|
||||||
|
await tb.write_reg(REG_DAC_PULSE_NUM, 3)
|
||||||
|
await tb.write_reg(REG_DAC_PULSE_HEIGHT, 0x7FF)
|
||||||
|
await tb.write_reg(REG_ADC_PERIOD, 0x80)
|
||||||
|
await tb.write_reg(REG_WINDOW_SIZE, 16)
|
||||||
|
|
||||||
|
assert await tb.read_reg(REG_DAC_WIDTH) == 0x10
|
||||||
|
assert await tb.read_reg(REG_WINDOW_SIZE) == 16
|
||||||
|
|
||||||
|
# write data: set cfg_bus_valid signal
|
||||||
|
await tb.write_reg(REG_CONTROL, 1 << CTRL_CFG_BUS_VALID)
|
||||||
|
|
||||||
|
# wait
|
||||||
|
for _ in range(30):
|
||||||
|
await RisingEdge(dut.ctrl_clk)
|
||||||
|
|
||||||
|
# check config
|
||||||
|
assert int(dut.dac_pulse_width) == 0x10
|
||||||
|
assert int(dut.dac_pulse_period) == 0x40
|
||||||
|
assert int(dut.dac_pulse_num) == 3
|
||||||
|
assert int(dut.dac_pulse_height) == 0x7FF
|
||||||
|
assert int(dut.adc_pulse_period) == 0x80
|
||||||
|
assert int(dut.adc_window_size) == 16
|
||||||
|
|
||||||
|
await RisingEdge(dut.ctrl_clk)
|
||||||
|
|
||||||
|
|
||||||
|
@cocotb.test()
|
||||||
|
async def simple_controller_start_check(dut):
|
||||||
|
tb = TB(dut)
|
||||||
|
await tb.reset()
|
||||||
|
await tb.write_reg(REG_CONTROL, 1 << CTRL_START)
|
||||||
|
|
||||||
|
await RisingEdge(dut.dac_start)
|
||||||
|
|
||||||
|
|
||||||
|
@cocotb.test()
|
||||||
|
async def simple_dma_desc_status(dut):
|
||||||
|
tb = TB(dut)
|
||||||
|
await tb.reset()
|
||||||
|
|
||||||
|
await tb.write_reg(REG_DESC_READ_ADDR, 0xdead)
|
||||||
|
await tb.write_reg(REG_DESC_READ_LEN, 64)
|
||||||
|
await tb.write_reg(REG_DESC_READ_CONFIG, 0x0000_0001)
|
||||||
|
|
||||||
|
await tb.write_reg(REG_DESC_WRITE_ADDR, 0xbeef)
|
||||||
|
await tb.write_reg(REG_DESC_WRITE_LEN_AND_TAG, 0x0005555)
|
||||||
|
|
||||||
|
# W1S pulse: bit 3 = send_desc_read_o.
|
||||||
|
await tb.write_reg(REG_CONTROL, 1 << CTRL_SEND_DESC_READ)
|
||||||
|
|
||||||
|
await tb.write_reg(REG_CONTROL, 1 << CTRL_SEND_DESC_WRITE)
|
||||||
|
|
||||||
|
for _ in range(20):
|
||||||
|
await RisingEdge(dut.ctrl_clk)
|
||||||
|
|
||||||
|
assert int(dut.desc_read_cmd_out.value) == 0x000000100040DEAD
|
||||||
|
assert int(dut.desc_write_cmd_out.value) == 0x0005555BEEF
|
||||||
|
|
||||||
|
# test status
|
||||||
|
dut.status_read_cmd_in.value = Immediate(123)
|
||||||
|
dut.status_write_cmd_in.value = Immediate(0xabcd90012345)
|
||||||
|
dut.valid_status_read.value = Immediate(1)
|
||||||
|
dut.valid_status_write.value = Immediate(1)
|
||||||
|
|
||||||
|
for _ in range(10):
|
||||||
|
await RisingEdge(dut.ctrl_clk)
|
||||||
|
|
||||||
|
# read status
|
||||||
|
await tb.write_reg(REG_CONTROL, 1 << CTRL_TAKE_STATUS_READ)
|
||||||
|
await tb.write_reg(REG_CONTROL, 1 << CTRL_TAKE_STATUS_WRITE)
|
||||||
|
|
||||||
|
for _ in range(10):
|
||||||
|
await RisingEdge(dut.ctrl_clk)
|
||||||
|
|
||||||
|
assert await tb.read_reg(REG_READ_STATUS) == 123
|
||||||
|
assert await tb.read_reg(REG_STATUS_WRITE_CONFIG) == 0xABCD900
|
||||||
|
assert await tb.read_reg(REG_STATUS_WRITE_LEN) == 0x12345
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Primary clocks
|
||||||
|
create_clock -name eth_clk -period 8.000 [get_ports eth_clk_in]
|
||||||
|
create_clock -name dac_clk -period 7.692 [get_ports dac_clk_in]
|
||||||
|
create_clock -name adc_clk -period 15.385 [get_ports adc_clk_in]
|
||||||
|
|
||||||
|
|
||||||
|
# Asynchronous clock groups
|
||||||
|
# eth, dac, adc are independent domains
|
||||||
|
|
||||||
|
set_clock_groups -name ASYNC_ETH_DAC_ADC -asynchronous \
|
||||||
|
-group [get_clocks eth_clk] \
|
||||||
|
-group [get_clocks dac_clk] \
|
||||||
|
-group [get_clocks adc_clk]
|
||||||
Reference in New Issue
Block a user