add: half-baked reflectometer TB
fix: constraints port names; ready: reflectometer top module
This commit is contained in:
@ -1,3 +1,3 @@
|
|||||||
# Primary clocks
|
# Primary clocks
|
||||||
create_clock -name eth_clk -period 8.000 [get_ports dac_clk_in]
|
create_clock -name eth_clk -period 8.000 [get_ports clk_dac]
|
||||||
create_clock -name acc_clk -period 15.385 [get_ports adc_clk_in]
|
create_clock -name acc_clk -period 15.385 [get_ports clk_adc]
|
||||||
@ -1 +1,4 @@
|
|||||||
set_clock_groups -name ASYNC_UDP_CTRL -asynchronous -group [get_clocks rgmii_rxc] -group [get_clocks clk_out1_clk_wiz_ctrl_inst] -group [get_clocks clk_out2_clk_wiz_ctrl_inst]
|
# Primary clocks
|
||||||
|
create_clock -name ref_clock -period 5.000 [get_ports clk_in]
|
||||||
|
create_clock -name phy_rx_clock -period 8.000 [get_ports clk_m_axis]
|
||||||
|
create_clock -name phy_tx_clock -period 8.000 [get_ports clk_s_axis]
|
||||||
@ -11,75 +11,68 @@ module reflectometer_top #(
|
|||||||
parameter int unsigned WINDOW_SIZE = 65,
|
parameter int unsigned WINDOW_SIZE = 65,
|
||||||
parameter int unsigned PACKET_SIZE = 1024
|
parameter int unsigned PACKET_SIZE = 1024
|
||||||
)(
|
)(
|
||||||
input sys_clk,
|
input wire clk_in,
|
||||||
input rst_n,
|
input wire rst_n,
|
||||||
|
output wire locked,
|
||||||
|
|
||||||
output [3:0] led,
|
// Accumulator AXI-S bus
|
||||||
|
input wire clk_m_axis, // GMII PHY RX clock
|
||||||
|
output wire [7:0] m_axis_tdata,
|
||||||
|
output wire m_axis_tvalid,
|
||||||
|
input wire m_axis_tready,
|
||||||
|
output wire m_axis_tlast,
|
||||||
|
|
||||||
input gmii_rx_clk,
|
// Control AXI-S bus
|
||||||
input gmii_tx_clk,
|
input wire clk_s_axis, // GMII PHY TX clock
|
||||||
|
input wire [7:0] s_axis__tdata,
|
||||||
|
input wire s_axis_tvalid,
|
||||||
|
input wire s_axis_tlast,
|
||||||
|
output wire s_axis_tready,
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) output logic [7:0] s_axis_tx_tdata,
|
// RTL-MAC handshake
|
||||||
(* MARK_DEBUG="true" *) output logic s_axis_tx_tvalid,
|
input wire request_ready,
|
||||||
(* MARK_DEBUG="true" *) input logic s_axis_tx_tready,
|
output wire send_request,
|
||||||
(* MARK_DEBUG="true" *) output logic s_axis_tx_tlast,
|
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) input wire [7:0] m_axis_rx_tdata,
|
|
||||||
(* MARK_DEBUG="true" *) input wire m_axis_rx_tvalid,
|
|
||||||
(* MARK_DEBUG="true" *) input wire m_axis_rx_tlast,
|
|
||||||
(* MARK_DEBUG="true" *) output wire m_axis_rx_tready,
|
|
||||||
|
|
||||||
// axis_mac
|
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) input logic req_ready,
|
|
||||||
(* MARK_DEBUG="true" *) output logic send_req,
|
|
||||||
|
|
||||||
// DAC
|
// DAC
|
||||||
output logic dac_clk_o,
|
output wire dac_clk_o,
|
||||||
output logic [DAC_DATA_WIDTH-1:0] dac_data,
|
output wire [DAC_DATA_WIDTH-1:0] dac_data,
|
||||||
output logic dac_wrt,
|
output wire dac_wrt,
|
||||||
|
|
||||||
// ADC
|
// ADC
|
||||||
output logic adc_clk_o,
|
output wire adc_clk_o,
|
||||||
input wire [ADC_DATA_WIDTH-1:0] adc_data,
|
input wire [ADC_DATA_WIDTH-1:0] adc_data,
|
||||||
input wire adc_otr
|
input wire adc_otr
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
wire [ADC_DATA_WIDTH*PACK_FACTOR-1:0] sampler_m_axis_tdata;
|
|
||||||
wire sampler_m_axis_tvalid;
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Generated clocks for controller
|
// Generated clocks for controller
|
||||||
// Need to create this IP in Vivado:
|
// Need to create this IP in Vivado:
|
||||||
// input : 200 MHz
|
// input resetn
|
||||||
// output0: 130 MHz
|
// input clk_200 : 200 MHz : Reference clock
|
||||||
// output1: 65 MHz
|
// output clk_adc_65 : 65 MHz : ADC RTL clock
|
||||||
|
// output clk_adc_65_180 : 65 MHz, phase 180 deg. : ADC PHY clock
|
||||||
|
// output clk_adc_125 : 125 MHz : DAC RTL clock
|
||||||
|
// output clk_adc_125_180 : 125 MHz, phase 180 deg. : DAC PHY clock
|
||||||
|
// output locked
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
wire dac_clk;
|
wire clk_sampler, clk_generator, clk_locked;
|
||||||
wire adc_clk;
|
|
||||||
wire clk_wiz_locked;
|
|
||||||
|
|
||||||
clk_wiz_ctrl_inst clock_wiz_inst
|
clk_wiz_ctrl_inst clk_wiz_inst
|
||||||
(
|
(
|
||||||
// Clock in ports
|
// Clock in ports
|
||||||
.clk_200(clk_in),
|
.clk_200(clk_in),
|
||||||
// Clock out ports
|
// Clock out ports
|
||||||
.clk_adc_65(clk_adc),
|
.clk_adc_65(clk_sampler),
|
||||||
.clk_adc_65_180(clk_sampler),
|
.clk_adc_65_180(adc_clk_o),
|
||||||
.clk_dac_125(clk_dac),
|
.clk_dac_125(clk_generator),
|
||||||
.clk_dac_125_180(clk_generator),
|
.clk_dac_125_180(dac_clk_o),
|
||||||
// Status and control signals
|
// Status and control signals
|
||||||
.resetn(rst_n),
|
.resetn(rst_n),
|
||||||
.locked(clk_locked)
|
.locked(clk_locked)
|
||||||
);
|
);
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
assign locked = clk_locked;
|
||||||
// axis_mac interface
|
|
||||||
// RX stream from Ethernet goes into controller
|
|
||||||
// TX stream is unused for now
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Controller reset
|
// Controller reset
|
||||||
@ -87,40 +80,36 @@ module reflectometer_top #(
|
|||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
wire ctrl_rst_n = rst_n & clk_locked;
|
wire ctrl_rst_n = rst_n & clk_locked;
|
||||||
|
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) logic finish;
|
|
||||||
|
|
||||||
// Controller outputs to debug
|
|
||||||
(* MARK_DEBUG="true" *) wire [31:0] dac_pulse_width;
|
|
||||||
(* MARK_DEBUG="true" *) wire [31:0] dac_pulse_period;
|
|
||||||
(* MARK_DEBUG="true" *) wire [DAC_DATA_WIDTH-1:0] dac_pulse_height;
|
|
||||||
(* MARK_DEBUG="true" *) wire [15:0] dac_pulse_num;
|
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) wire [31:0] adc_pulse_period;
|
|
||||||
(* MARK_DEBUG="true" *) wire [15:0] adc_pulse_num;
|
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) wire dac_start;
|
|
||||||
(* MARK_DEBUG="true" *) wire adc_start;
|
|
||||||
(* MARK_DEBUG="true" *) wire dac_rst;
|
|
||||||
(* MARK_DEBUG="true" *) wire adc_rst;
|
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Controller
|
// Controller
|
||||||
// ETH domain = gmii_rx_clk, because RX AXI master comes from axis_mac RX side
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
wire [31:0] dac_pulse_width;
|
||||||
|
wire [31:0] dac_pulse_period;
|
||||||
|
wire [DAC_DATA_WIDTH-1:0] dac_pulse_height;
|
||||||
|
wire [15:0] dac_pulse_num;
|
||||||
|
|
||||||
|
wire [31:0] adc_pulse_period;
|
||||||
|
wire [15:0] adc_pulse_num;
|
||||||
|
|
||||||
|
wire dac_start;
|
||||||
|
wire adc_start;
|
||||||
|
wire dac_rst;
|
||||||
|
wire adc_rst;
|
||||||
|
|
||||||
|
wire finish;
|
||||||
|
|
||||||
control #(
|
control #(
|
||||||
.DAC_DATA_WIDTH(DAC_DATA_WIDTH)
|
.DAC_DATA_WIDTH(DAC_DATA_WIDTH)
|
||||||
) udp_ctrl_inst (
|
) udp_ctrl_inst (
|
||||||
.eth_clk_in (gmii_rx_clk),
|
.eth_clk_in (clk_s_axis),
|
||||||
.dac_clk_in (dac_clk),
|
.dac_clk_in (clk_generator),
|
||||||
.adc_clk_in (adc_clk),
|
.adc_clk_in (clk_sampler),
|
||||||
.rst_n (ctrl_rst_n),
|
.rst_n (ctrl_rst_n),
|
||||||
|
|
||||||
.s_axis_tdata (m_axis_rx_tdata),
|
.s_axis_tdata (s_axis__tdata),
|
||||||
.s_axis_tvalid (m_axis_rx_tvalid),
|
.s_axis_tvalid (s_axis_tvalid),
|
||||||
.s_axis_tready (m_axis_rx_tready),
|
.s_axis_tready (s_axis_tready),
|
||||||
.s_axis_tlast (m_axis_rx_tlast),
|
.s_axis_tlast (s_axis_tlast),
|
||||||
|
|
||||||
.finish (finish),
|
.finish (finish),
|
||||||
|
|
||||||
@ -139,124 +128,80 @@ module reflectometer_top #(
|
|||||||
.adc_rst (adc_rst)
|
.adc_rst (adc_rst)
|
||||||
);
|
);
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// DAC
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) logic sample_req;
|
|
||||||
(* MARK_DEBUG="true" *) logic sample_req_sync1;
|
|
||||||
(* MARK_DEBUG="true" *) logic sample_req_sync2;
|
|
||||||
(* MARK_DEBUG="true" *) logic sample_req_sync3;
|
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) logic sample_done;
|
|
||||||
(* MARK_DEBUG="true" *) logic sample_done_sync1;
|
|
||||||
(* MARK_DEBUG="true" *) logic sample_done_sync2;
|
|
||||||
(* MARK_DEBUG="true" *) logic sample_done_sync3;
|
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// DAC -> ADC CDC
|
// DAC -> ADC CDC
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
always_ff @(posedge adc_clk or posedge adc_rst) begin
|
logic [2:0] stretch; // 125/65~=2. Чтобы поймать единичный импульс, растянем его во времени
|
||||||
if (adc_rst) begin
|
logic [1:0] sync_DA;
|
||||||
sample_req <= 1'b0;
|
wire dac_done_stretched;
|
||||||
sample_req_sync2 <= 1'b0;
|
|
||||||
sample_req_sync3 <= 1'b0;
|
wire generator_done, generator_request;
|
||||||
end
|
wire sampler_done, sampler_request;
|
||||||
|
|
||||||
|
always_ff @(posedge clk_generator or posedge dac_rst)
|
||||||
|
begin
|
||||||
|
if (dac_rst)
|
||||||
|
stretch <= 0;
|
||||||
else begin
|
else begin
|
||||||
sample_req_sync2 <= sample_req_sync1;
|
stretch[0] <= generator_done;
|
||||||
sample_req_sync3 <= sample_req_sync2;
|
stretch[1] <= stretch[0];
|
||||||
sample_req <= sample_req_sync3;
|
stretch[2] <= stretch[1];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
assign dac_done_stretched = |stretch;
|
||||||
|
|
||||||
|
always_ff @(posedge clk_sampler or posedge adc_rst) begin
|
||||||
|
if (adc_rst)
|
||||||
|
sync_DA <= 0;
|
||||||
|
else begin
|
||||||
|
sync_DA[0] <= dac_done_stretched;
|
||||||
|
sync_DA[1] <= sync_DA[0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assign sampler_request = sync_DA[1];
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// ADC -> DAC CDC
|
// ADC -> DAC CDC
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
always_ff @(posedge dac_clk or posedge dac_rst) begin
|
logic [1:0] sync_AD;
|
||||||
if (dac_rst) begin
|
|
||||||
sample_done <= 1'b0;
|
always_ff @(posedge clk_generator or posedge dac_rst) begin
|
||||||
sample_done_sync2 <= 1'b0;
|
if (dac_rst)
|
||||||
sample_done_sync3 <= 1'b0;
|
sync_AD <= 0;
|
||||||
end
|
|
||||||
else begin
|
else begin
|
||||||
sample_done_sync2 <= sample_done_sync1;
|
sync_AD[0] <= sampler_done;
|
||||||
sample_done_sync3 <= sample_done_sync2;
|
sync_AD[1] <= sync_AD[0];
|
||||||
sample_done <= sample_done_sync3;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
assign generator_request = sync_AD[1];
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// Generator
|
// Generator (DAC)
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
|
|
||||||
generator #(
|
generator #(
|
||||||
.DATA_WIDTH(DAC_DATA_WIDTH),
|
.DATA_WIDTH(DAC_DATA_WIDTH),
|
||||||
.ZERO_LEVEL(ZERO_LEVEL)
|
.ZERO_LEVEL(ZERO_LEVEL)
|
||||||
) generator_inst (
|
) generator_inst (
|
||||||
.clk_in(dac_clk),
|
.clk_dac(clk_generator),
|
||||||
.rst(dac_rst),
|
.rst(dac_rst),
|
||||||
.start(dac_start),
|
.start(dac_start),
|
||||||
.pulse_width(dac_pulse_width),
|
.pulse_width(dac_pulse_width),
|
||||||
.pulse_period(dac_pulse_period),
|
.pulse_period(dac_pulse_period),
|
||||||
.pulse_height(dac_pulse_height),
|
.pulse_height(dac_pulse_height),
|
||||||
.pulse_num(dac_pulse_num),
|
.pulse_num(dac_pulse_num),
|
||||||
.pulse(p2_wrt),
|
.dac_out(dac_data),
|
||||||
.pulse_height_out(p2_data),
|
.done(generator_done),
|
||||||
.sample_done(sample_done),
|
.request(generator_request)
|
||||||
.sample_req(sample_req_sync1)
|
|
||||||
);
|
);
|
||||||
|
assign dac_wrt = dac_clk_o;
|
||||||
|
|
||||||
wire ch2_clk_oddr;
|
|
||||||
|
|
||||||
ODDR #(
|
|
||||||
.DDR_CLK_EDGE("SAME_EDGE"),
|
|
||||||
.INIT(1'b0),
|
|
||||||
.SRTYPE("SYNC")
|
|
||||||
) ODDR_ch2_clk (
|
|
||||||
.Q (ch2_clk_oddr),
|
|
||||||
.C (adc_clk),
|
|
||||||
.CE(1'b1),
|
|
||||||
.D1(1'b1),
|
|
||||||
.D2(1'b0),
|
|
||||||
.R (1'b0),
|
|
||||||
.S (1'b0)
|
|
||||||
);
|
|
||||||
|
|
||||||
OBUF OBUF_ch2_clk (
|
|
||||||
.I(ch2_clk_oddr),
|
|
||||||
.O(ch2_clk)
|
|
||||||
);
|
|
||||||
|
|
||||||
wire p2_clk_oddr;
|
|
||||||
|
|
||||||
ODDR #(
|
|
||||||
.DDR_CLK_EDGE("SAME_EDGE"),
|
|
||||||
.INIT(1'b0),
|
|
||||||
.SRTYPE("SYNC")
|
|
||||||
) ODDR_p2_clk (
|
|
||||||
.Q (p2_clk_oddr),
|
|
||||||
.C (dac_clk),
|
|
||||||
.CE(1'b1),
|
|
||||||
.D1(1'b1),
|
|
||||||
.D2(1'b0),
|
|
||||||
.R (1'b0),
|
|
||||||
.S (1'b0)
|
|
||||||
);
|
|
||||||
|
|
||||||
OBUF OBUF_p2_clk (
|
|
||||||
.I(p2_clk_oddr),
|
|
||||||
.O(p2_clk)
|
|
||||||
);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// ADC
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
// Sampler (ADC)
|
||||||
|
// -------------------------------------------------------------------------
|
||||||
|
wire [ADC_DATA_WIDTH*PACK_FACTOR-1:0] sampler_m_axis_tdata;
|
||||||
|
wire sampler_m_axis_tvalid;
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) logic [ADC_DATA_WIDTH*PACK_FACTOR-1:0] accum_m_axis_tdata;
|
sampler #(
|
||||||
(* MARK_DEBUG="true" *) logic acum_m_axis_tvalid;
|
|
||||||
|
|
||||||
sampler
|
|
||||||
#(
|
|
||||||
.DATA_WIDTH(ADC_DATA_WIDTH),
|
.DATA_WIDTH(ADC_DATA_WIDTH),
|
||||||
.PACK_FACTOR(PACK_FACTOR),
|
.PACK_FACTOR(PACK_FACTOR),
|
||||||
.PROCESS_MODE(PROCESS_MODE)
|
.PROCESS_MODE(PROCESS_MODE)
|
||||||
@ -268,50 +213,37 @@ module reflectometer_top #(
|
|||||||
.m_axis_tdata(sampler_m_axis_tdata),
|
.m_axis_tdata(sampler_m_axis_tdata),
|
||||||
.m_axis_tvalid(sampler_m_axis_tvalid),
|
.m_axis_tvalid(sampler_m_axis_tvalid),
|
||||||
.smp_num(adc_pulse_period),
|
.smp_num(adc_pulse_period),
|
||||||
.sample_req(sample_req),
|
.done(sampler_done),
|
||||||
.sample_done(sample_done_sync1)
|
.request(sampler_request)
|
||||||
);
|
);
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// Accumulator
|
// Accumulator
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
accumulator_top #(
|
||||||
accumulator_top
|
|
||||||
#(
|
|
||||||
.DATA_WIDTH(ADC_DATA_WIDTH),
|
.DATA_WIDTH(ADC_DATA_WIDTH),
|
||||||
.ACCUM_WIDTH(ACCUM_WIDTH),
|
.ACCUM_WIDTH(ACCUM_WIDTH),
|
||||||
.N_MAX(N_MAX),
|
.N_MAX(N_MAX),
|
||||||
.WINDOW_SIZE(WINDOW_SIZE),
|
.WINDOW_SIZE(WINDOW_SIZE),
|
||||||
.PACKET_SIZE(PACKET_SIZE)
|
.PACKET_SIZE(PACKET_SIZE)
|
||||||
)
|
) accumulator_top_dut (
|
||||||
accumulator_top_dut
|
.clk_in(clk_sampler),
|
||||||
(
|
|
||||||
.clk_in(adc_clk),
|
|
||||||
.rst(adc_rst),
|
.rst(adc_rst),
|
||||||
.s_axis_tdata(accum_m_axis_tdata),
|
.s_axis_tdata(sampler_m_axis_tdata),
|
||||||
.s_axis_tvalid(acum_m_axis_tvalid),
|
.s_axis_tvalid(sampler_m_axis_tvalid),
|
||||||
.start(adc_start),
|
.start(adc_start),
|
||||||
.smp_num(adc_pulse_period),
|
.smp_num(adc_pulse_period),
|
||||||
.seq_num(adc_pulse_num),
|
.seq_num(adc_pulse_num),
|
||||||
|
|
||||||
.eth_clk_in(gmii_tx_clk),
|
.req_ready(request_ready),
|
||||||
.req_ready(req_ready),
|
.send_req(send_request),
|
||||||
.send_req(send_req),
|
.eth_clk_in(clk_m_axis),
|
||||||
.m_axis_tdata(s_axis_tx_tdata),
|
.m_axis_tdata(m_axis_tdata),
|
||||||
.m_axis_tvalid(s_axis_tx_tvalid),
|
.m_axis_tvalid(m_axis_tvalid),
|
||||||
.m_axis_tready(s_axis_tx_tready),
|
.m_axis_tready(m_axis_tready),
|
||||||
.m_axis_tlast(s_axis_tx_tlast),
|
.m_axis_tlast(m_axis_tlast),
|
||||||
|
|
||||||
.finish(finish)
|
.finish(finish)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Simple LED status
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
assign status_led[0] = rst_n;
|
|
||||||
assign status_led[1] = clk_locked;
|
|
||||||
// assign status_led[2] = ;
|
|
||||||
// assign status_led[3] = ;
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|||||||
@ -1,75 +1,91 @@
|
|||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
module tb_reflectometer;
|
module tb_reflectometer;
|
||||||
|
//------------------------------------------------------------
|
||||||
// parameters
|
// Параметры
|
||||||
|
//------------------------------------------------------------
|
||||||
localparam int unsigned DAC_DATA_WIDTH = 14;
|
localparam int unsigned DAC_DATA_WIDTH = 14;
|
||||||
localparam int unsigned ADC_DATA_WIDTH = 12;
|
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 PACK_FACTOR = 1; // not used in TB
|
||||||
localparam PROCESS_MODE = 0; // 0 - uint, 1 - int
|
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 ACCUM_WIDTH = 32; // accumulator number bit witdth
|
||||||
localparam N_MAX = 4096; // max value of windows to average by experiments
|
localparam N_MAX = 4096; // max value of windows to average by experiments
|
||||||
localparam WINDOW_SIZE = 65; // fixed subwindow size to average by time
|
localparam WINDOW_SIZE = 65; // fixed subwindow size to average by time
|
||||||
localparam PACKET_SIZE = 1024; // bytes per UDP packet
|
localparam PACKET_SIZE = 1024; // bytes per UDP packet
|
||||||
|
|
||||||
localparam int unsigned ADC_CLK_MHZ = 65;
|
localparam ZERO_LEVEL = LOGIC_ZERO_LEVEL; // "logic" VS "true"
|
||||||
localparam int unsigned DAC_CLK_MHZ = 125;
|
|
||||||
|
|
||||||
// may be changed for test purposes
|
localparam CLK_ETH_PHY_PERIOD = 8.000; // 125 MHz
|
||||||
localparam int unsigned PULSE_WIDTH = 2**6;
|
localparam CLK_REF_PERIOD = 5.000; // 200 MHz
|
||||||
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);
|
|
||||||
|
|
||||||
initial begin
|
//------------------------------------------------------------
|
||||||
if (PULSE_WIDTH <= 0)
|
// Тактовые сигналы и сброс
|
||||||
$fatal(1, "PULSE_WIDTH should be positive");
|
//------------------------------------------------------------
|
||||||
if (PULSE_PERIOD <= 0)
|
logic clk_ref = 1'b0; // 200 MHz
|
||||||
$fatal(1, "PULSE_PERIOD should be positive");
|
logic clk_eth_phy = 1'b0; // common for RX & TX
|
||||||
if (PULSE_NUM <= 0)
|
logic rst_n = 1'b0;
|
||||||
$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 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;
|
wire [DAC_DATA_WIDTH-1:0] dac_data;
|
||||||
wire adc_clk;
|
// ADC интерфейс
|
||||||
logic adc_otr;
|
wire clk_adc;
|
||||||
logic [ADC_DATA_WIDTH-1:0] adc_data;
|
logic adc_otr = 1'b0;
|
||||||
|
logic [ADC_DATA_WIDTH-1:0] adc_data = '0;
|
||||||
|
// Интерфейс хендшейка с MAC-PHY
|
||||||
|
wire send_request;
|
||||||
|
logic request_ready = 1'b0;
|
||||||
|
|
||||||
wire [7:0] s_axis_tx_tdata;
|
//------------------------------------------------------------
|
||||||
wire s_axis_tx_tvalid;
|
// Virtual DAC
|
||||||
logic s_axis_tx_tready;
|
//------------------------------------------------------------
|
||||||
wire s_axis_tx_tlast;
|
|
||||||
|
|
||||||
logic phy_ready;
|
//------------------------------------------------------------
|
||||||
wire accum_tx_start;
|
// Virtual ADC
|
||||||
logic [7:0] m_axis_rx_tdata;
|
//------------------------------------------------------------
|
||||||
logic m_axis_rx_tvalid;
|
|
||||||
logic m_axis_rx_tlast;
|
|
||||||
logic m_axis_rx_tready;
|
|
||||||
|
|
||||||
logic [127:0] dut_config = 0;
|
//------------------------------------------------------------
|
||||||
|
// Virtual conductor
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Statistics monitor
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Config handler
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
// DUT
|
// DUT
|
||||||
|
//------------------------------------------------------------
|
||||||
reflectometer_top #(
|
reflectometer_top #(
|
||||||
.DAC_DATA_WIDTH(DAC_DATA_WIDTH),
|
.DAC_DATA_WIDTH(DAC_DATA_WIDTH),
|
||||||
.ADC_DATA_WIDTH(ADC_DATA_WIDTH),
|
.ADC_DATA_WIDTH(ADC_DATA_WIDTH),
|
||||||
@ -81,105 +97,96 @@ module tb_reflectometer;
|
|||||||
.WINDOW_SIZE(WINDOW_SIZE),
|
.WINDOW_SIZE(WINDOW_SIZE),
|
||||||
.PACKET_SIZE(PACKET_SIZE)
|
.PACKET_SIZE(PACKET_SIZE)
|
||||||
) DUT (
|
) DUT (
|
||||||
.sys_clk(clk200), // main clk 200 mhz
|
.clk_in(clk_ref),
|
||||||
.rst_n(rst_n), // rst_n
|
.rst_n(rst_n),
|
||||||
.led(status_leds), // indication [3:0]
|
.locked(mmcm_locked),
|
||||||
.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
|
// Accumulator AXI-S bus
|
||||||
.send_req(accum_tx_start), // AXI-stream start transmit
|
.clk_m_axis(clk_eth_phy), // GMII PHY RX clock
|
||||||
.p2_clk(dac_clk), // DAC clk
|
.m_axis_tdata(s_axis_accumulator_tdata),
|
||||||
.p2_data(dac_data), // DAC [DAC_DATA_WIDTH-1:0] data
|
.m_axis_tvalid(s_axis_accumulator_tvalid),
|
||||||
.p2_wrt(dac_en), // DAC write enable
|
.m_axis_tready(s_axis_accumulator_tready),
|
||||||
.ch2_clk(adc_clk), // ADC clk
|
.m_axis_tlast(s_axis_accumulator_tlast),
|
||||||
.ch2_data(adc_data), // ADC [ADC_DATA_WIDTH-1:0] data
|
|
||||||
.ch2_otr(adc_otr) // ADC signal out-of-range
|
// 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
|
initial begin
|
||||||
// 200 MHz
|
forever #(CLK_REF_PERIOD/2) clk_ref = ~clk_ref;
|
||||||
clk200 = 1'b0;
|
|
||||||
forever #2.5 clk200 = ~clk200;
|
|
||||||
end
|
end
|
||||||
initial begin
|
initial begin
|
||||||
// 125 MHz
|
forever #(CLK_ETH_PHY_PERIOD/2) clk_eth_phy = ~clk_eth_phy;
|
||||||
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;
|
|
||||||
end
|
end
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Таски для тестирования
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
// ADC input noise simulation
|
// task automatic axis_send_byte(
|
||||||
always @(posedge adc_clk or negedge rst_n) begin
|
// ref logic clk,
|
||||||
if (!rst_n) begin
|
// input logic [7:0] data,
|
||||||
adc_data <= '0;
|
// input logic last,
|
||||||
end else begin
|
// ref logic tvalid,
|
||||||
adc_data <= $urandom() & ((1 << ADC_DATA_WIDTH) - 1);
|
// ref logic [7:0] tdata,
|
||||||
end
|
// ref logic tlast,
|
||||||
end
|
// input logic tready
|
||||||
assign adc_otr = 1'b0;
|
// );
|
||||||
|
// @(posedge clk);
|
||||||
|
// tdata <= data;
|
||||||
|
// tlast <= last;
|
||||||
|
// tvalid <= 1'b1;
|
||||||
|
|
||||||
// AXIS tasks
|
// // Ждем готовности приемника
|
||||||
task automatic axis_send_byte(
|
// wait(tready === 1'b1);
|
||||||
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);
|
||||||
wait(tready === 1'b1);
|
// tvalid <= 1'b0;
|
||||||
|
// tlast <= 1'b0;
|
||||||
|
// endtask
|
||||||
|
|
||||||
@(posedge clk);
|
// task automatic dut_soft_reset();
|
||||||
tvalid <= 1'b0;
|
// axis_send_byte(
|
||||||
tlast <= 1'b0;
|
// .clk(clk_eth_phy_rx),
|
||||||
endtask
|
// .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_soft_reset();
|
// task automatic dut_start();
|
||||||
axis_send_byte(
|
// axis_send_byte(
|
||||||
.clk(clk_eth_phy_rx),
|
// .clk(clk_eth_phy_rx),
|
||||||
.data(8'b00001111),
|
// .data(8'b11110000),
|
||||||
.last(1'b1),
|
// .last(1'b1),
|
||||||
.tvalid(m_axis_rx_tvalid),
|
// .tvalid(m_axis_rx_tvalid),
|
||||||
.tdata(m_axis_rx_tdata),
|
// .tdata(m_axis_rx_tdata),
|
||||||
.tlast(m_axis_rx_tlast),
|
// .tlast(m_axis_rx_tlast),
|
||||||
.tready(m_axis_rx_tready)
|
// .tready(m_axis_rx_tready)
|
||||||
);
|
// );
|
||||||
endtask
|
// 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(
|
// task automatic dut_send_config(
|
||||||
// input logic [127:0] ctrl_config
|
// input logic [127:0] ctrl_config
|
||||||
@ -217,51 +224,16 @@ module tb_reflectometer;
|
|||||||
// endtask
|
// 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
|
initial begin
|
||||||
// setup
|
$display("[TB] Tests start");
|
||||||
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
|
wait(mmcm_locked === 1'b1);
|
||||||
#100;
|
#10000;
|
||||||
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;
|
$display("[TB] ALL PASSED");
|
||||||
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("=== ALL BASIC TESTS PASSED ===");
|
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
endmodule
|
endmodule
|
||||||
Reference in New Issue
Block a user