add: half-baked reflectometer TB
fix: constraints port names; ready: reflectometer top module
This commit is contained in:
@ -1,75 +1,91 @@
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module tb_reflectometer;
|
||||
|
||||
// parameters
|
||||
//------------------------------------------------------------
|
||||
// Параметры
|
||||
//------------------------------------------------------------
|
||||
localparam int unsigned DAC_DATA_WIDTH = 14;
|
||||
localparam int unsigned ADC_DATA_WIDTH = 12;
|
||||
localparam LOGIC_ZERO_LEVEL = 0; // DAC -5V for logic zero
|
||||
localparam VOLTAGE_ZERO_LEVEL = 2**(DAC_DATA_WIDTH-1); // DAC 0V for logic zero
|
||||
localparam PACK_FACTOR = 1; // not used in TB
|
||||
localparam PROCESS_MODE = 0; // 0 - uint, 1 - int
|
||||
localparam ZERO_LEVEL = 8192; // DAC zero voltage representation (2^14 / 2)
|
||||
localparam ACCUM_WIDTH = 32; // accumulator number bit witdth
|
||||
localparam N_MAX = 4096; // max value of windows to average by experiments
|
||||
localparam WINDOW_SIZE = 65; // fixed subwindow size to average by time
|
||||
localparam PACKET_SIZE = 1024; // bytes per UDP packet
|
||||
|
||||
localparam int unsigned ADC_CLK_MHZ = 65;
|
||||
localparam int unsigned DAC_CLK_MHZ = 125;
|
||||
localparam ZERO_LEVEL = LOGIC_ZERO_LEVEL; // "logic" VS "true"
|
||||
|
||||
// may be changed for test purposes
|
||||
localparam int unsigned PULSE_WIDTH = 2**6;
|
||||
localparam int unsigned PULSE_PERIOD = 2**8;
|
||||
localparam int unsigned PULSE_NUM = 10;
|
||||
localparam int unsigned PULSE_HEIGHT = 2**12;
|
||||
localparam int unsigned PULSE_PERIOD_ADC = (int'(real'(ADC_CLK_MHZ) / real'(DAC_CLK_MHZ) * real'(PULSE_PERIOD)) / int'(WINDOW_SIZE)) * int'(WINDOW_SIZE);
|
||||
localparam CLK_ETH_PHY_PERIOD = 8.000; // 125 MHz
|
||||
localparam CLK_REF_PERIOD = 5.000; // 200 MHz
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Тактовые сигналы и сброс
|
||||
//------------------------------------------------------------
|
||||
logic clk_ref = 1'b0; // 200 MHz
|
||||
logic clk_eth_phy = 1'b0; // common for RX & TX
|
||||
logic rst_n = 1'b0;
|
||||
//------------------------------------------------------------
|
||||
// Управление и конфиг
|
||||
//------------------------------------------------------------
|
||||
|
||||
initial begin
|
||||
if (PULSE_WIDTH <= 0)
|
||||
$fatal(1, "PULSE_WIDTH should be positive");
|
||||
if (PULSE_PERIOD <= 0)
|
||||
$fatal(1, "PULSE_PERIOD should be positive");
|
||||
if (PULSE_NUM <= 0)
|
||||
$fatal(1, "PULSE_NUM should be positive");
|
||||
if (PULSE_HEIGHT <= 0)
|
||||
$fatal(1, "PULSE_HEIGHT should be positive");
|
||||
if (PULSE_WIDTH >= 2**32-1)
|
||||
$fatal(1, "PULSE_WIDTH too high");
|
||||
if (PULSE_PERIOD >= 2**32-1)
|
||||
$fatal(1, "PULSE_PERIOD too high");
|
||||
if (PULSE_NUM >= 2**16-1)
|
||||
$fatal(1, "PULSE_NUM too high");
|
||||
if (PULSE_HEIGHT >= 2**DAC_DATA_WIDTH-1)
|
||||
$fatal(1, "PULSE_HEIGHT too high");
|
||||
if (PULSE_PERIOD_ADC % WINDOW_SIZE == 0)
|
||||
$fatal(1, "PULSE_PERIOD_ADC isn't multiple of WINDOW_SIZE");
|
||||
end
|
||||
//------------------------------------------------------------
|
||||
// Входы
|
||||
//------------------------------------------------------------
|
||||
|
||||
// DUT signals
|
||||
logic clk200, clk_eth_phy_tx, clk_eth_phy_rx; // GMII clocks
|
||||
logic rst_n;
|
||||
wire [3:0] status_leds; // [ None, dac_start, m_axis_valid, clk_wiz_locked ]
|
||||
|
||||
wire dac_clk, dac_en;
|
||||
wire [DAC_DATA_WIDTH-1:0] dac_data;
|
||||
wire adc_clk;
|
||||
logic adc_otr;
|
||||
logic [ADC_DATA_WIDTH-1:0] adc_data;
|
||||
|
||||
wire [7:0] s_axis_tx_tdata;
|
||||
wire s_axis_tx_tvalid;
|
||||
logic s_axis_tx_tready;
|
||||
wire s_axis_tx_tlast;
|
||||
//------------------------------------------------------------
|
||||
// Выходы
|
||||
//------------------------------------------------------------
|
||||
wire mmcm_locked;
|
||||
//------------------------------------------------------------
|
||||
// Внутренние сигналы тестбенча
|
||||
//------------------------------------------------------------
|
||||
// AXI-S интерфейс для управления
|
||||
logic [7:0] m_axis_control_tdata = 8'b0;
|
||||
logic m_axis_control_tvalid = 1'b0;
|
||||
wire m_axis_control_tready;
|
||||
logic m_axis_control_tlast = 1'b0;
|
||||
// AXI-S интерфейс для данных
|
||||
wire [7:0] s_axis_accumulator_tdata;
|
||||
wire s_axis_accumulator_tvalid;
|
||||
logic s_axis_accumulator_tready = 1'b0;
|
||||
wire s_axis_accumulator_tlast;
|
||||
// DAC интерфейс
|
||||
wire clk_dac;
|
||||
wire dac_wrt;
|
||||
wire [DAC_DATA_WIDTH-1:0] dac_data;
|
||||
// ADC интерфейс
|
||||
wire clk_adc;
|
||||
logic adc_otr = 1'b0;
|
||||
logic [ADC_DATA_WIDTH-1:0] adc_data = '0;
|
||||
// Интерфейс хендшейка с MAC-PHY
|
||||
wire send_request;
|
||||
logic request_ready = 1'b0;
|
||||
|
||||
logic phy_ready;
|
||||
wire accum_tx_start;
|
||||
logic [7:0] m_axis_rx_tdata;
|
||||
logic m_axis_rx_tvalid;
|
||||
logic m_axis_rx_tlast;
|
||||
logic m_axis_rx_tready;
|
||||
//------------------------------------------------------------
|
||||
// Virtual DAC
|
||||
//------------------------------------------------------------
|
||||
|
||||
logic [127:0] dut_config = 0;
|
||||
//------------------------------------------------------------
|
||||
// Virtual ADC
|
||||
//------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Virtual conductor
|
||||
//------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Statistics monitor
|
||||
//------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------
|
||||
// Config handler
|
||||
//------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------
|
||||
// DUT
|
||||
//------------------------------------------------------------
|
||||
reflectometer_top #(
|
||||
.DAC_DATA_WIDTH(DAC_DATA_WIDTH),
|
||||
.ADC_DATA_WIDTH(ADC_DATA_WIDTH),
|
||||
@ -81,105 +97,96 @@ module tb_reflectometer;
|
||||
.WINDOW_SIZE(WINDOW_SIZE),
|
||||
.PACKET_SIZE(PACKET_SIZE)
|
||||
) DUT (
|
||||
.sys_clk(clk200), // main clk 200 mhz
|
||||
.rst_n(rst_n), // rst_n
|
||||
.led(status_leds), // indication [3:0]
|
||||
.gmii_rx_clk(clk_eth_phy_rx), // ext. clk from PHY
|
||||
.gmii_tx_clk(clk_eth_phy_tx), // ext. clk from PHY
|
||||
// accumulated data stream
|
||||
.s_axis_tx_tdata(s_axis_tx_tdata),
|
||||
.s_axis_tx_tvalid(s_axis_tx_tvalid),
|
||||
.s_axis_tx_tready(s_axis_tx_tready),
|
||||
.s_axis_tx_tlast(s_axis_tx_tlast),
|
||||
// controller data stream
|
||||
.m_axis_rx_tdata(m_axis_rx_tdata),
|
||||
.m_axis_rx_tvalid(m_axis_rx_tvalid),
|
||||
.m_axis_rx_tlast(m_axis_rx_tlast),
|
||||
.m_axis_rx_tready(m_axis_rx_tready),
|
||||
|
||||
.req_ready(phy_ready), // AXI-stream requester ready
|
||||
.send_req(accum_tx_start), // AXI-stream start transmit
|
||||
.p2_clk(dac_clk), // DAC clk
|
||||
.p2_data(dac_data), // DAC [DAC_DATA_WIDTH-1:0] data
|
||||
.p2_wrt(dac_en), // DAC write enable
|
||||
.ch2_clk(adc_clk), // ADC clk
|
||||
.ch2_data(adc_data), // ADC [ADC_DATA_WIDTH-1:0] data
|
||||
.ch2_otr(adc_otr) // ADC signal out-of-range
|
||||
.clk_in(clk_ref),
|
||||
.rst_n(rst_n),
|
||||
.locked(mmcm_locked),
|
||||
|
||||
// Accumulator AXI-S bus
|
||||
.clk_m_axis(clk_eth_phy), // GMII PHY RX clock
|
||||
.m_axis_tdata(s_axis_accumulator_tdata),
|
||||
.m_axis_tvalid(s_axis_accumulator_tvalid),
|
||||
.m_axis_tready(s_axis_accumulator_tready),
|
||||
.m_axis_tlast(s_axis_accumulator_tlast),
|
||||
|
||||
// Control AXI-S bus
|
||||
.clk_s_axis(clk_eth_phy), // GMII PHY TX clock
|
||||
.s_axis__tdata(maxis_control_tdata),
|
||||
.s_axis_tvalid(maxis_control_tvalid),
|
||||
.s_axis_tlast(maxis_control_tlast),
|
||||
.s_axis_tready(maxis_control_tready),
|
||||
|
||||
// RTL-MAC handshake
|
||||
.request_ready(request_ready),
|
||||
.send_request(send_request),
|
||||
|
||||
// DAC
|
||||
.dac_clk_o(clk_dac),
|
||||
.dac_data(dac_data),
|
||||
.dac_wrt(dac_wrt),
|
||||
|
||||
// ADC
|
||||
.adc_clk_o(clk_adc),
|
||||
.adc_data(adc_data),
|
||||
.adc_otr(adc_otr)
|
||||
);
|
||||
|
||||
// clocks
|
||||
//------------------------------------------------------------
|
||||
// Тактовые сигналы
|
||||
//------------------------------------------------------------
|
||||
initial begin
|
||||
// 200 MHz
|
||||
clk200 = 1'b0;
|
||||
forever #2.5 clk200 = ~clk200;
|
||||
forever #(CLK_REF_PERIOD/2) clk_ref = ~clk_ref;
|
||||
end
|
||||
initial begin
|
||||
// 125 MHz
|
||||
clk_eth_phy_tx = 1'b0;
|
||||
forever #4 clk_eth_phy_tx = ~clk_eth_phy_tx;
|
||||
end
|
||||
initial begin
|
||||
// 125 MHz
|
||||
clk_eth_phy_rx = 1'b0;
|
||||
forever #4 clk_eth_phy_rx = ~clk_eth_phy_rx;
|
||||
forever #(CLK_ETH_PHY_PERIOD/2) clk_eth_phy = ~clk_eth_phy;
|
||||
end
|
||||
//------------------------------------------------------------
|
||||
// Таски для тестирования
|
||||
//------------------------------------------------------------
|
||||
|
||||
// task automatic axis_send_byte(
|
||||
// ref logic clk,
|
||||
// input logic [7:0] data,
|
||||
// input logic last,
|
||||
// ref logic tvalid,
|
||||
// ref logic [7:0] tdata,
|
||||
// ref logic tlast,
|
||||
// input logic tready
|
||||
// );
|
||||
// @(posedge clk);
|
||||
// tdata <= data;
|
||||
// tlast <= last;
|
||||
// tvalid <= 1'b1;
|
||||
|
||||
// ADC input noise simulation
|
||||
always @(posedge adc_clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
adc_data <= '0;
|
||||
end else begin
|
||||
adc_data <= $urandom() & ((1 << ADC_DATA_WIDTH) - 1);
|
||||
end
|
||||
end
|
||||
assign adc_otr = 1'b0;
|
||||
// // Ждем готовности приемника
|
||||
// wait(tready === 1'b1);
|
||||
|
||||
// AXIS tasks
|
||||
task automatic axis_send_byte(
|
||||
ref logic clk,
|
||||
input logic [7:0] data,
|
||||
input logic last,
|
||||
ref logic tvalid,
|
||||
ref logic [7:0] tdata,
|
||||
ref logic tlast,
|
||||
input logic tready
|
||||
);
|
||||
@(posedge clk);
|
||||
tdata <= data;
|
||||
tlast <= last;
|
||||
tvalid <= 1'b1;
|
||||
// @(posedge clk);
|
||||
// tvalid <= 1'b0;
|
||||
// tlast <= 1'b0;
|
||||
// endtask
|
||||
|
||||
// Ждем готовности приемника
|
||||
wait(tready === 1'b1);
|
||||
// task automatic dut_soft_reset();
|
||||
// axis_send_byte(
|
||||
// .clk(clk_eth_phy_rx),
|
||||
// .data(8'b00001111),
|
||||
// .last(1'b1),
|
||||
// .tvalid(m_axis_rx_tvalid),
|
||||
// .tdata(m_axis_rx_tdata),
|
||||
// .tlast(m_axis_rx_tlast),
|
||||
// .tready(m_axis_rx_tready)
|
||||
// );
|
||||
// endtask
|
||||
|
||||
@(posedge clk);
|
||||
tvalid <= 1'b0;
|
||||
tlast <= 1'b0;
|
||||
endtask
|
||||
|
||||
task automatic dut_soft_reset();
|
||||
axis_send_byte(
|
||||
.clk(clk_eth_phy_rx),
|
||||
.data(8'b00001111),
|
||||
.last(1'b1),
|
||||
.tvalid(m_axis_rx_tvalid),
|
||||
.tdata(m_axis_rx_tdata),
|
||||
.tlast(m_axis_rx_tlast),
|
||||
.tready(m_axis_rx_tready)
|
||||
);
|
||||
endtask
|
||||
|
||||
task automatic dut_start();
|
||||
axis_send_byte(
|
||||
.clk(clk_eth_phy_rx),
|
||||
.data(8'b11110000),
|
||||
.last(1'b1),
|
||||
.tvalid(m_axis_rx_tvalid),
|
||||
.tdata(m_axis_rx_tdata),
|
||||
.tlast(m_axis_rx_tlast),
|
||||
.tready(m_axis_rx_tready)
|
||||
);
|
||||
endtask
|
||||
// task automatic dut_start();
|
||||
// axis_send_byte(
|
||||
// .clk(clk_eth_phy_rx),
|
||||
// .data(8'b11110000),
|
||||
// .last(1'b1),
|
||||
// .tvalid(m_axis_rx_tvalid),
|
||||
// .tdata(m_axis_rx_tdata),
|
||||
// .tlast(m_axis_rx_tlast),
|
||||
// .tready(m_axis_rx_tready)
|
||||
// );
|
||||
// endtask
|
||||
|
||||
// task automatic dut_send_config(
|
||||
// input logic [127:0] ctrl_config
|
||||
@ -217,51 +224,16 @@ module tb_reflectometer;
|
||||
// endtask
|
||||
|
||||
|
||||
|
||||
// some helpers for controller axis
|
||||
|
||||
// GAME PLAN
|
||||
// 1. setup reflectometer
|
||||
// 2. create some reference signal with noise + virtual ADC
|
||||
// 3. setup m_axis endpoint for controller to start reflectometer (create multiple tasks)
|
||||
// 4. setup s_axis endpoint for data gathering and plotting
|
||||
// 5. check standalone reflectometer
|
||||
// 6. add reference signal averaging loop throw generator pulse posedge detection
|
||||
// 7. visual comparision of reference VS reflectometer
|
||||
// 8. add statistics for signal comparision (MSE/RMSE)
|
||||
|
||||
// main TB
|
||||
//------------------------------------------------------------
|
||||
// ОСНОВНОЙ ПРОЦЕСС ТЕСТИРОВАНИЯ
|
||||
//------------------------------------------------------------
|
||||
initial begin
|
||||
// setup
|
||||
rst_n = 1'b0;
|
||||
s_axis_tx_tready = 1'b0;
|
||||
m_axis_rx_tdata = 1'b0;
|
||||
m_axis_rx_tvalid = 1'b0;
|
||||
m_axis_rx_tlast = 1'b0;
|
||||
phy_ready = 1'b0;
|
||||
|
||||
// startup
|
||||
#100;
|
||||
rst_n = 1'b1;
|
||||
wait(DUT.clk_wiz_ctrl_inst.locked == 1'b1);
|
||||
#20;
|
||||
$display("=== clocks ready / wiz. locked ===");
|
||||
#40;
|
||||
// ready to work
|
||||
|
||||
dut_config[31:0] = PULSE_WIDTH;
|
||||
dut_config[63:32] = PULSE_PERIOD;
|
||||
dut_config[79:64] = PULSE_NUM;
|
||||
dut_config[79+DAC_DATA_WIDTH:80] = PULSE_HEIGHT;
|
||||
dut_config[127:96] = PULSE_PERIOD_ADC;
|
||||
|
||||
// dut_send_config(dut_config);
|
||||
dut_start();
|
||||
// dut_start();
|
||||
#1000;
|
||||
// dut_soft_reset();
|
||||
$display("[TB] Tests start");
|
||||
|
||||
$display("=== ALL BASIC TESTS PASSED ===");
|
||||
wait(mmcm_locked === 1'b1);
|
||||
#10000;
|
||||
|
||||
$display("[TB] ALL PASSED");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
endmodule
|
||||
|
||||
Reference in New Issue
Block a user