Compare commits
53 Commits
dev/sw
...
dev/design
| Author | SHA1 | Date | |
|---|---|---|---|
| 81970c8b42 | |||
| a528838741 | |||
| 04eb927a25 | |||
| 4240604f26 | |||
| ef65dd1a97 | |||
| 71b825ef2c | |||
| d80f5ff31f | |||
| 493d6844c0 | |||
| 11a9e97691 | |||
| 0ba25a3541 | |||
| 64f94a90e6 | |||
| 7665afd50b | |||
| c3275d5b46 | |||
| 7b96fbddbf | |||
| 2282eb4e16 | |||
| 287d855df4 | |||
| 725826b07c | |||
| d878bac42a | |||
| 771225cd77 | |||
| b38a693676 | |||
| 789255fa04 | |||
| efcd6ef5d0 | |||
| 4fbecd5e30 | |||
| d71aaf1650 | |||
| 035d02234c | |||
| 4923f01322 | |||
| 45a57d57e4 | |||
| 29e1541ffb | |||
| fd9280737d | |||
| 64843b462d | |||
| c0714f271e | |||
| c165d346a0 | |||
| 753f4a2128 | |||
| 6155c6a9fb | |||
| bb65aea4f1 | |||
| 5d3b761b07 | |||
| d7e46445d8 | |||
| cacfe04061 | |||
| 4270c2fca8 | |||
| cf2985813a | |||
| f670df9b54 | |||
| 6542995930 | |||
| b0e886893b | |||
| d90167984a | |||
| 3a1d9c27e7 | |||
| c9aa2cde0f | |||
| ccd9964ada | |||
| 1a3b811e75 | |||
| 9c74fe91e8 | |||
| c8e11a2a1f | |||
| 0a68a753be | |||
| 906d5090cd | |||
| dc761f31dc |
4
.gitignore
vendored
4
.gitignore
vendored
@ -27,3 +27,7 @@ run_sim.tcl
|
|||||||
*.xsa
|
*.xsa
|
||||||
*.ltx
|
*.ltx
|
||||||
*.bin
|
*.bin
|
||||||
|
|
||||||
|
# slang files
|
||||||
|
.slang
|
||||||
|
files.f
|
||||||
@ -27,6 +27,7 @@ XDC_FILES += ../../constraints/ax7102.xdc
|
|||||||
XDC_FILES += debug.xdc
|
XDC_FILES += debug.xdc
|
||||||
|
|
||||||
SYN_FILES += tb_sync_top.sv
|
SYN_FILES += tb_sync_top.sv
|
||||||
|
|
||||||
SIM_TOP = tb_top
|
SIM_TOP = tb_top
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
# Primary clocks
|
# Primary clocks
|
||||||
create_clock -name eth_clk -period 8.000 [get_ports dac_clk_in]
|
create_clock -name geneartor_clk -period 8.000 [get_ports clk_dac]
|
||||||
create_clock -name acc_clk -period 15.385 [get_ports adc_clk_in]
|
create_clock -name sampler_clk -period 15.385 [get_ports clk_adc]
|
||||||
|
set_clock_groups -asynchronous -group [get_clocks geneartor_clk] -group [get_clocks sampler_clk]
|
||||||
|
|
||||||
|
# set_false_path -through [get_nets -hierarchical {*dac_signal* *internal_wire_singnal* *adc_singnal*}]
|
||||||
|
# set_false_path -through [get_nets {dac_done dac_done_stretched dac_request adc_done adc_request}]
|
||||||
|
|
||||||
# Asynchronous clock groups
|
set_property DONT_TOUCH true [get_cells -hierarchical -filter {NAME =~ *generator_inst*pulse_height_reg*}]
|
||||||
|
set_property DONT_TOUCH true [get_cells -hierarchical -filter {NAME =~ *generator_inst*dac_out_reg*}]
|
||||||
set_clock_groups -name ASYNC_ETH_ACC -asynchronous \
|
# Применяем к самому проводу сигнала CE, чтобы Vivado не дробила его
|
||||||
-group [get_clocks eth_clk] \
|
# set_property DONT_TOUCH true [get_nets -of_objects [get_pins -hierarchical -filter {PIN_NAME =~ *CE} -of_objects [get_cells *pulse_height_reg*]]]
|
||||||
-group [get_clocks acc_clk]
|
|
||||||
@ -2,113 +2,137 @@
|
|||||||
|
|
||||||
module sync_top
|
module sync_top
|
||||||
#(
|
#(
|
||||||
parameter int unsigned DAC_DATA_WIDTH = 14,
|
parameter int unsigned DAC_DATA_WIDTH = 14, // DAC bit-width
|
||||||
parameter int unsigned ADC_DATA_WIDTH = 12,
|
parameter int unsigned ADC_DATA_WIDTH = 12, // ADC bit-width
|
||||||
parameter int unsigned PACK_FACTOR = 1,
|
parameter int unsigned PACK_FACTOR = 1, // number of ADC readings per transaction
|
||||||
parameter int unsigned PROCESS_MODE = 0
|
parameter int unsigned PROCESS_MODE = 0, // representation format of ADC readings (0 - direct code, 1 - 2's completment)
|
||||||
|
parameter int unsigned ZERO_LEVEL = 0,
|
||||||
|
parameter int unsigned USE_DELAY_LINE = 0
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input adc_clk_in,
|
input clk_adc,
|
||||||
input adc_rst,
|
input rst_adc,
|
||||||
|
input clk_dac,
|
||||||
input dac_clk_in,
|
input rst_dac,
|
||||||
input dac_rst,
|
input start,
|
||||||
|
input out_of_range,
|
||||||
input dac_start,
|
|
||||||
|
|
||||||
input [31:0] pulse_width,
|
input [31:0] pulse_width,
|
||||||
input [31:0] pulse_period,
|
input [31:0] pulse_period, // DAC counter limit
|
||||||
input [DAC_DATA_WIDTH-1:0] pulse_height,
|
input [DAC_DATA_WIDTH-1:0] pulse_height,
|
||||||
input [15:0] pulse_num,
|
input [15:0] pulse_num,
|
||||||
input [31:0] smp_num,
|
input [31:0] smp_num, // ADC counter limit
|
||||||
|
output [ADC_DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata,
|
||||||
output logic [ADC_DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata,
|
output m_axis_tvalid
|
||||||
output logic m_axis_tvalid
|
|
||||||
);
|
);
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// Internal signals
|
// Internal signals
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
|
wire dac_done, dac_request, adc_done, adc_request;
|
||||||
|
wire [DAC_DATA_WIDTH-1:0] dac_signal;
|
||||||
|
wire [ADC_DATA_WIDTH-1:0] internal_wire_signal;
|
||||||
|
wire [ADC_DATA_WIDTH-1:0] adc_signal;
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) logic sample_req;
|
// 1. Адаптация разрядности и «заземление» лишних бит
|
||||||
(* MARK_DEBUG="true" *) logic sample_req_sync1;
|
generate
|
||||||
(* MARK_DEBUG="true" *) logic sample_req_sync2;
|
if (ADC_DATA_WIDTH > DAC_DATA_WIDTH) begin : g_pad_zeros
|
||||||
(* MARK_DEBUG="true" *) logic sample_req_sync3;
|
// АЦП шире ЦАП: добиваем нулями старшие биты
|
||||||
|
assign internal_wire_signal = { {(ADC_DATA_WIDTH - DAC_DATA_WIDTH){1'b0}}, dac_signal };
|
||||||
|
end
|
||||||
|
else if (ADC_DATA_WIDTH < DAC_DATA_WIDTH) begin : g_truncate
|
||||||
|
// ЦАП шире АЦП (например, 14 -> 12): забираем младшие биты
|
||||||
|
assign internal_wire_signal = dac_signal[DAC_DATA_WIDTH-1:DAC_DATA_WIDTH-ADC_DATA_WIDTH];
|
||||||
|
// (* mark_debug = "true" *) wire dummy;
|
||||||
|
// assign dummy = ^dac_signal;
|
||||||
|
end
|
||||||
|
else begin : g_match
|
||||||
|
// Разрядности равны
|
||||||
|
assign internal_wire_signal = dac_signal;
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) logic sample_done;
|
generate
|
||||||
(* MARK_DEBUG="true" *) logic sample_done_sync1;
|
if (USE_DELAY_LINE > 0) begin : g_delay_line
|
||||||
(* MARK_DEBUG="true" *) logic sample_done_sync2;
|
localparam int DELAY_LENGTH = USE_DELAY_LINE;
|
||||||
(* MARK_DEBUG="true" *) logic sample_done_sync3;
|
// Двумерный массив для линии задержки
|
||||||
|
logic [DELAY_LENGTH-1:0][ADC_DATA_WIDTH-1:0] signal_delay_line;
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) logic pulse;
|
always_ff @(posedge clk_dac) begin
|
||||||
(* MARK_DEBUG="true" *) logic [DAC_DATA_WIDTH-1:0] pulse_height_out;
|
signal_delay_line[0] <= internal_wire_signal;
|
||||||
|
for (int i = 0; i < DELAY_LENGTH-1; i++) begin
|
||||||
|
signal_delay_line[i+1] <= signal_delay_line[i];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
//------------------------------------------------------------
|
// ИСПРАВЛЕНО: читаем из последнего элемента массива
|
||||||
// Simple DAC -> ADC test source
|
assign adc_signal = signal_delay_line[DELAY_LENGTH-1];
|
||||||
//
|
end
|
||||||
// generator output is directly connected to sampler input
|
else begin : g_no_delay
|
||||||
// with width truncation:
|
assign adc_signal = internal_wire_signal;
|
||||||
//
|
end
|
||||||
// pulse_height_out[13:0] -> data_in[11:0]
|
endgenerate
|
||||||
//------------------------------------------------------------
|
|
||||||
(* MARK_DEBUG="true" *) logic [ADC_DATA_WIDTH-1:0] data_in;
|
|
||||||
(* MARK_DEBUG="true" *) logic out_of_range;
|
|
||||||
|
|
||||||
assign data_in = pulse_height_out[ADC_DATA_WIDTH-1:0];
|
|
||||||
assign out_of_range = 1'b0;
|
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// DAC -> ADC CDC
|
// DAC -> ADC CDC
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
always_ff @(posedge adc_clk_in 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;
|
always_ff @(posedge clk_dac or posedge rst_dac)
|
||||||
end
|
begin
|
||||||
|
if (rst_dac)
|
||||||
|
stretch <= 0;
|
||||||
else begin
|
else begin
|
||||||
sample_req_sync2 <= sample_req_sync1;
|
stretch[0] <= dac_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_adc or posedge rst_adc) begin
|
||||||
|
if (rst_adc)
|
||||||
|
sync_DA <= 0;
|
||||||
|
else begin
|
||||||
|
sync_DA[0] <= dac_done_stretched;
|
||||||
|
sync_DA[1] <= sync_DA[0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assign adc_request = sync_DA[1];
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// ADC -> DAC CDC
|
// ADC -> DAC CDC
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
always_ff @(posedge dac_clk_in or posedge dac_rst) begin
|
logic [1:0] sync_AD;
|
||||||
if (dac_rst) begin
|
|
||||||
sample_done <= 1'b0;
|
always_ff @(posedge clk_dac or posedge rst_dac) begin
|
||||||
sample_done_sync2 <= 1'b0;
|
if (rst_dac)
|
||||||
sample_done_sync3 <= 1'b0;
|
sync_AD <= 0;
|
||||||
end
|
|
||||||
else begin
|
else begin
|
||||||
sample_done_sync2 <= sample_done_sync1;
|
sync_AD[0] <= adc_done;
|
||||||
sample_done_sync3 <= sample_done_sync2;
|
sync_AD[1] <= sync_AD[0];
|
||||||
sample_done <= sample_done_sync3;
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
assign dac_request = sync_AD[1];
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// Generator
|
// Generator
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
generator #(
|
generator #(
|
||||||
.DATA_WIDTH(DAC_DATA_WIDTH)
|
.DATA_WIDTH(DAC_DATA_WIDTH),
|
||||||
|
.ZERO_LEVEL(ZERO_LEVEL)
|
||||||
) generator_inst (
|
) generator_inst (
|
||||||
.clk_in(dac_clk_in),
|
.clk_dac(clk_dac),
|
||||||
.rst(dac_rst),
|
.rst(rst_dac),
|
||||||
.start(dac_start),
|
.start(start),
|
||||||
|
|
||||||
.pulse_width(pulse_width),
|
.pulse_width(pulse_width),
|
||||||
.pulse_period(pulse_period),
|
.pulse_period(pulse_period),
|
||||||
.pulse_height(pulse_height),
|
.pulse_height(pulse_height),
|
||||||
.pulse_num(pulse_num),
|
.pulse_num(pulse_num),
|
||||||
|
.dac_out(dac_signal),
|
||||||
.sample_done(sample_done),
|
.request(dac_request),
|
||||||
|
.done(dac_done)
|
||||||
.pulse(pulse),
|
|
||||||
.pulse_height_out(pulse_height_out),
|
|
||||||
.sample_req(sample_req_sync1)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
@ -119,18 +143,15 @@ module sync_top
|
|||||||
.PACK_FACTOR(PACK_FACTOR),
|
.PACK_FACTOR(PACK_FACTOR),
|
||||||
.PROCESS_MODE(PROCESS_MODE)
|
.PROCESS_MODE(PROCESS_MODE)
|
||||||
) sampler_inst (
|
) sampler_inst (
|
||||||
.clk_in(adc_clk_in),
|
.clk_in(clk_adc),
|
||||||
.rst(adc_rst),
|
.rst(rst_adc),
|
||||||
|
.data_in(adc_signal),
|
||||||
.data_in(data_in),
|
|
||||||
.out_of_range(out_of_range),
|
.out_of_range(out_of_range),
|
||||||
|
|
||||||
.smp_num(smp_num),
|
.smp_num(smp_num),
|
||||||
.sample_req(sample_req),
|
|
||||||
|
|
||||||
.m_axis_tdata(m_axis_tdata),
|
.m_axis_tdata(m_axis_tdata),
|
||||||
.m_axis_tvalid(m_axis_tvalid),
|
.m_axis_tvalid(m_axis_tvalid),
|
||||||
.sample_done(sample_done_sync1)
|
.request(adc_request),
|
||||||
|
.done(adc_done)
|
||||||
);
|
);
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
@ -2,39 +2,50 @@
|
|||||||
|
|
||||||
module tb_top;
|
module tb_top;
|
||||||
|
|
||||||
localparam DAC_DATA_WIDTH = 14;
|
//------------------------------------------------------------
|
||||||
localparam ADC_DATA_WIDTH = 12;
|
// Параметры
|
||||||
localparam PACK_FACTOR = 1;
|
//------------------------------------------------------------
|
||||||
localparam PROCESS_MODE = 0;
|
parameter string ZERO_LEVEL_PARAM = "logic"; // "logic" VS "true"
|
||||||
|
parameter VERBOSE = 1;
|
||||||
|
|
||||||
|
localparam DAC_DATA_WIDTH = 14;
|
||||||
|
localparam ADC_DATA_WIDTH = 12;
|
||||||
|
localparam PACK_FACTOR = 1;
|
||||||
|
localparam PROCESS_MODE = 0;
|
||||||
|
localparam CLK_DAC_PERIOD = 8;
|
||||||
|
localparam CLK_ADC_PERIOD = 15.385;
|
||||||
|
localparam USE_DELAY_LINE = 0;
|
||||||
|
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 ZERO_LEVEL = (ZERO_LEVEL_PARAM == "logic") ? LOGIC_ZERO_LEVEL : VOLTAGE_ZERO_LEVEL;
|
||||||
|
|
||||||
|
localparam CLOCK_DEVIATION = 3; // Maximum clock deviation of pulse stats
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// clocks / reset
|
// Тактовые сигналы и сброс
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
logic adc_clk_in;
|
logic clk_dac;
|
||||||
logic adc_rst;
|
logic rst_dac;
|
||||||
|
logic clk_adc;
|
||||||
logic dac_clk_in;
|
logic rst_adc;
|
||||||
logic dac_rst;
|
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// control
|
// Управление и конфиг
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
logic dac_start;
|
logic dac_start;
|
||||||
|
logic [31:0] pulse_width;
|
||||||
logic [31:0] pulse_width;
|
logic [31:0] pulse_period;
|
||||||
logic [31:0] pulse_period;
|
logic [DAC_DATA_WIDTH-1:0] pulse_height;
|
||||||
logic [DAC_DATA_WIDTH-1:0] pulse_height;
|
logic [15:0] pulse_num;
|
||||||
logic [15:0] pulse_num;
|
logic [31:0] smp_num;
|
||||||
logic [31:0] smp_num;
|
|
||||||
|
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// outputs
|
// Входы
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
logic [ADC_DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata;
|
reg out_of_range;
|
||||||
logic m_axis_tvalid;
|
//------------------------------------------------------------
|
||||||
|
// Выходы
|
||||||
integer valid_count;
|
//------------------------------------------------------------
|
||||||
|
wire [ADC_DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata;
|
||||||
|
wire m_axis_tvalid;
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
// DUT
|
// DUT
|
||||||
//------------------------------------------------------------
|
//------------------------------------------------------------
|
||||||
@ -42,127 +53,521 @@ module tb_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),
|
||||||
.PACK_FACTOR(PACK_FACTOR),
|
.PACK_FACTOR(PACK_FACTOR),
|
||||||
.PROCESS_MODE(PROCESS_MODE)
|
.PROCESS_MODE(PROCESS_MODE),
|
||||||
|
.ZERO_LEVEL(ZERO_LEVEL),
|
||||||
|
.USE_DELAY_LINE(USE_DELAY_LINE)
|
||||||
) dut (
|
) dut (
|
||||||
.adc_clk_in(adc_clk_in),
|
.clk_adc(clk_adc),
|
||||||
.adc_rst(adc_rst),
|
.clk_dac(clk_dac),
|
||||||
|
.rst_adc(rst_adc),
|
||||||
.dac_clk_in(dac_clk_in),
|
.rst_dac(rst_dac),
|
||||||
.dac_rst(dac_rst),
|
.start(dac_start),
|
||||||
|
|
||||||
.dac_start(dac_start),
|
|
||||||
|
|
||||||
.pulse_width(pulse_width),
|
.pulse_width(pulse_width),
|
||||||
.pulse_period(pulse_period),
|
.pulse_period(pulse_period),
|
||||||
.pulse_height(pulse_height),
|
.pulse_height(pulse_height),
|
||||||
.pulse_num(pulse_num),
|
.pulse_num(pulse_num),
|
||||||
.smp_num(smp_num),
|
.smp_num(smp_num),
|
||||||
|
|
||||||
.m_axis_tdata(m_axis_tdata),
|
.m_axis_tdata(m_axis_tdata),
|
||||||
.m_axis_tvalid(m_axis_tvalid)
|
.m_axis_tvalid(m_axis_tvalid),
|
||||||
|
.out_of_range(out_of_range)
|
||||||
);
|
);
|
||||||
|
|
||||||
//------------------------------------------------------------
|
// Тактовые сигналы
|
||||||
// ADC clock
|
|
||||||
//------------------------------------------------------------
|
|
||||||
initial begin
|
initial begin
|
||||||
adc_clk_in = 1'b0;
|
clk_adc = 0;
|
||||||
forever #5 adc_clk_in = ~adc_clk_in; // 100 MHz
|
forever #(CLK_ADC_PERIOD/2) clk_adc = ~clk_adc;
|
||||||
|
end
|
||||||
|
initial begin
|
||||||
|
clk_dac = 0;
|
||||||
|
forever #(CLK_DAC_PERIOD/2) clk_dac = ~clk_dac;
|
||||||
end
|
end
|
||||||
|
|
||||||
//------------------------------------------------------------
|
// === Таски для тестирования ===
|
||||||
// DAC clock
|
// Функция модуля
|
||||||
//------------------------------------------------------------
|
function automatic real fabs(real val);
|
||||||
initial begin
|
return (val < 0.0) ? -val : val;
|
||||||
dac_clk_in = 1'b0;
|
endfunction
|
||||||
forever #8 dac_clk_in = ~dac_clk_in; // slower domain
|
|
||||||
end
|
|
||||||
|
|
||||||
//------------------------------------------------------------
|
`define MIN(x, y) (((x) < (y)) ? (x) : (y))
|
||||||
// monitor output stream
|
|
||||||
//------------------------------------------------------------
|
|
||||||
always @(posedge adc_clk_in) begin
|
|
||||||
if (m_axis_tvalid) begin
|
|
||||||
valid_count = valid_count + 1;
|
|
||||||
|
|
||||||
$display("[%0t] VALID: data=%0d",
|
// Таска сброса DAC DUT
|
||||||
$time,
|
task automatic reset_dut_dac(
|
||||||
m_axis_tdata);
|
input int rst_duration // сколько тактов держать сброс
|
||||||
|
);
|
||||||
|
@(negedge clk_dac);
|
||||||
|
rst_dac <= 1;
|
||||||
|
repeat(rst_duration) @(negedge clk_dac);
|
||||||
|
rst_dac <= 0;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
// Таска сброса ADC DUT
|
||||||
|
task automatic reset_dut_adc(
|
||||||
|
input int rst_duration // сколько тактов держать сброс
|
||||||
|
);
|
||||||
|
@(negedge clk_adc);
|
||||||
|
rst_adc <= 1;
|
||||||
|
repeat(rst_duration) @(negedge clk_adc);
|
||||||
|
rst_adc <= 0;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
// Таска запуска DUT
|
||||||
|
task automatic start_dut(
|
||||||
|
input int start_duration // сколько тактов держать импульс
|
||||||
|
);
|
||||||
|
@(negedge clk_dac); // to make signal stable
|
||||||
|
dac_start <= 1;
|
||||||
|
repeat(start_duration) @(negedge clk_dac);
|
||||||
|
dac_start <= 0;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
// Таска конфигурации DUT
|
||||||
|
task automatic set_config(
|
||||||
|
input logic [31:0] w, // ширина импульса
|
||||||
|
input logic [31:0] p, // период импульса
|
||||||
|
input logic [15:0] n, // количество импульсов
|
||||||
|
input logic [DAC_DATA_WIDTH-1:0] h, // высота импульса
|
||||||
|
input logic [31:0] sn // число сэмплов
|
||||||
|
);
|
||||||
|
// Задаем конфигурационные регистры
|
||||||
|
pulse_width <= w;
|
||||||
|
pulse_period <= p;
|
||||||
|
pulse_num <= n;
|
||||||
|
pulse_height <= h;
|
||||||
|
smp_num <= sn;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
// Основная таска проверки DUT
|
||||||
|
task automatic run_test_case(
|
||||||
|
input int pulse_width,
|
||||||
|
input int pulse_period,
|
||||||
|
input int pulse_height,
|
||||||
|
input int pulse_num,
|
||||||
|
input int sample_num,
|
||||||
|
input bit skip_reset,
|
||||||
|
input bit randomize_start_timing,
|
||||||
|
input bit out_of_range_val,
|
||||||
|
input bit randomize_out_of_range
|
||||||
|
);
|
||||||
|
int error_flag = 0;
|
||||||
|
int start_hold_time = 1;
|
||||||
|
realtime sync_start_time, pulse_start_time, pulse_update_val_time;
|
||||||
|
realtime sync_time_stats[$], pulse_width_time_stats[$], pulse_period_time_stats[$], pulse_delay_time_stats[$];
|
||||||
|
realtime avearge_pulse_delay, average_pulse_width, average_pulse_period, average_sync_time;
|
||||||
|
|
||||||
|
out_of_range = out_of_range_val;
|
||||||
|
|
||||||
|
if (VERBOSE >= 2) begin
|
||||||
|
$display("[TB] -run_test_case- Starting test case");
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
//------------------------------------------------------------
|
if (randomize_out_of_range)
|
||||||
// test
|
fork
|
||||||
//------------------------------------------------------------
|
begin : randomize_out_of_range_proc
|
||||||
|
forever begin
|
||||||
|
@(posedge clk_adc);
|
||||||
|
out_of_range = $urandom_range(0, 1);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
join_none
|
||||||
|
|
||||||
|
if (!skip_reset)
|
||||||
|
fork
|
||||||
|
reset_dut_adc(1);
|
||||||
|
reset_dut_dac(1);
|
||||||
|
join
|
||||||
|
|
||||||
|
set_config(
|
||||||
|
.w(pulse_width),
|
||||||
|
.p(pulse_period),
|
||||||
|
.n(pulse_num),
|
||||||
|
.h(pulse_height),
|
||||||
|
.sn(sample_num)
|
||||||
|
);
|
||||||
|
@(posedge clk_dac);
|
||||||
|
@(posedge clk_dac);
|
||||||
|
|
||||||
|
if (randomize_start_timing)
|
||||||
|
start_hold_time = $urandom_range(1, 15);
|
||||||
|
fork // warning: check not forever
|
||||||
|
start_dut(start_hold_time);
|
||||||
|
begin
|
||||||
|
@(posedge clk_dac);
|
||||||
|
// старт первой синхронизации
|
||||||
|
sync_start_time = $realtime;
|
||||||
|
end
|
||||||
|
join_none
|
||||||
|
|
||||||
|
if (VERBOSE >= 2) begin
|
||||||
|
$display("[TB] -run_test_case- Starting pulse generation");
|
||||||
|
end
|
||||||
|
|
||||||
|
for (int i = 0; i < pulse_num; i++) begin
|
||||||
|
if (VERBOSE >= 3) begin
|
||||||
|
$display("[TB] -run_test_case- Start sync for pulse #%d", i);
|
||||||
|
end
|
||||||
|
@(posedge m_axis_tvalid);
|
||||||
|
if (VERBOSE >= 3) begin
|
||||||
|
$display("[TB] -run_test_case- Found valid pulse response data positive front");
|
||||||
|
end
|
||||||
|
// Старт цикла. Завершение синхронизации
|
||||||
|
sync_time_stats.push_back($realtime - sync_start_time);
|
||||||
|
pulse_start_time = $realtime;
|
||||||
|
|
||||||
|
fork
|
||||||
|
// Поток будет запущен для ненулевых импульсов и гарантированно завершится как только зафиксирует статистику импульса
|
||||||
|
// Начало импульса
|
||||||
|
if (pulse_height != ZERO_LEVEL && pulse_width != 0) begin
|
||||||
|
if (VERBOSE >= 4) begin
|
||||||
|
$display("[TB] -run_test_case- Wait until pulse become high");
|
||||||
|
end
|
||||||
|
wait(m_axis_tdata != ZERO_LEVEL);
|
||||||
|
// Фактическое начало импульса. Поступление высокого уровня
|
||||||
|
pulse_update_val_time = $realtime;
|
||||||
|
pulse_delay_time_stats.push_back(pulse_update_val_time - pulse_start_time);
|
||||||
|
|
||||||
|
// Проверим что высота импульса совпала с заданной. Т.к. OTR != 0 влияет на выходные данные сэмплера, то не будем проверять такие случаи.
|
||||||
|
@(posedge clk_adc);
|
||||||
|
#1.5; // Ожидание завершения переходных процессов
|
||||||
|
// Будем считать что из-за OTR данные изменились (по условию OTR + MSB), проверка пропускается, т.к. сложно понять точное значение OTR в момент обработки данных от tdata
|
||||||
|
if (m_axis_tdata != (pulse_height >> 2) && (randomize_out_of_range || out_of_range_val)) begin
|
||||||
|
$display("[ERROR] -run_test_case- Wrong pulse height: %d. Must be: %d", m_axis_tdata, pulse_height >> 2);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (VERBOSE >= 4) begin
|
||||||
|
$display("[TB] -run_test_case- Wait until pulse become low");
|
||||||
|
end
|
||||||
|
wait(m_axis_tdata == ZERO_LEVEL);
|
||||||
|
pulse_width_time_stats.push_back($realtime - pulse_update_val_time);
|
||||||
|
end
|
||||||
|
// Конец импульса
|
||||||
|
join_none
|
||||||
|
|
||||||
|
@(negedge m_axis_tvalid);
|
||||||
|
if (VERBOSE >= 3) begin
|
||||||
|
$display("[TB] -run_test_case- Found valid pulse response data negative front");
|
||||||
|
end
|
||||||
|
// Завершение цикла. Старт синхронизации
|
||||||
|
pulse_period_time_stats.push_back($realtime - pulse_start_time);
|
||||||
|
sync_start_time = $realtime;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (VERBOSE >= 2) begin
|
||||||
|
$display("[TB] -run_test_case- Stop pulse generation");
|
||||||
|
end
|
||||||
|
|
||||||
|
fork // Проверка с таймаутом на лишние циклы
|
||||||
|
@(posedge m_axis_tvalid);
|
||||||
|
repeat(30) @(posedge clk_adc);
|
||||||
|
join_any
|
||||||
|
if (m_axis_tvalid == 1) begin
|
||||||
|
$display("[ERROR] -run_test_case- Extra pulse cycle num. More than must be.");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (VERBOSE >= 2) begin
|
||||||
|
$display("[TB] -run_test_case- Exit waiting via timeout");
|
||||||
|
end
|
||||||
|
|
||||||
|
if (randomize_out_of_range) begin
|
||||||
|
disable randomize_out_of_range_proc;
|
||||||
|
if (VERBOSE >= 2) begin
|
||||||
|
$display("[TB] -run_test_case- Stop randomize_out_of_range_proc");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
out_of_range = 0;
|
||||||
|
|
||||||
|
// Проверка по статистике. Подсчет средних значений
|
||||||
|
if (pulse_delay_time_stats.size() != pulse_num && pulse_height != ZERO_LEVEL && pulse_width != 0 && !(randomize_out_of_range || out_of_range_val)) begin // Detected with pulse level. Skip if pulse level undetectable
|
||||||
|
$display("[ERROR] -run_test_case- Size of pulse_delay_time_stats samples not equal to pulse_num: %d VS %d", pulse_delay_time_stats.size(), pulse_num);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
if (pulse_width_time_stats.size() != pulse_num && pulse_height != ZERO_LEVEL && pulse_width != 0 && !(randomize_out_of_range || out_of_range_val)) begin // Detected with pulse level. Skip if pulse level undetectable
|
||||||
|
$display("[ERROR] -run_test_case- Size of pulse_width_time_stats samples not equal to pulse_num: %d VS %d", pulse_width_time_stats.size(), pulse_num);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
if (pulse_period_time_stats.size() != pulse_num) begin
|
||||||
|
$display("[ERROR] -run_test_case- Size of pulse_period_time_stats samples not equal to pulse_num: %d VS %d", pulse_period_time_stats.size(), pulse_num);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
if (sync_time_stats.size() != pulse_num) begin
|
||||||
|
$display("[ERROR] -run_test_case- Size of sync_time_stats samples not equal to pulse_num: %d VS %d", sync_time_stats.size(), pulse_num);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
avearge_pulse_delay = 0;
|
||||||
|
foreach (pulse_delay_time_stats[i])
|
||||||
|
avearge_pulse_delay += pulse_delay_time_stats[i];
|
||||||
|
avearge_pulse_delay /= pulse_num;
|
||||||
|
|
||||||
|
average_pulse_width = 0;
|
||||||
|
foreach (pulse_width_time_stats[i])
|
||||||
|
average_pulse_width += pulse_width_time_stats[i];
|
||||||
|
average_pulse_width /= pulse_num;
|
||||||
|
|
||||||
|
average_pulse_period = 0;
|
||||||
|
foreach (pulse_period_time_stats[i])
|
||||||
|
average_pulse_period += pulse_period_time_stats[i];
|
||||||
|
average_pulse_period /= pulse_num;
|
||||||
|
|
||||||
|
average_sync_time = 0;
|
||||||
|
foreach (sync_time_stats[i])
|
||||||
|
average_sync_time += sync_time_stats[i];
|
||||||
|
average_sync_time /= pulse_num;
|
||||||
|
|
||||||
|
if (VERBOSE >= 1) begin
|
||||||
|
$display("[TB] -run_test_case- Pulse test stats:\n\tavearge_pulse_delay: %0.3f\n\taverage_pulse_width: %0.3f\n\taverage_pulse_period: %0.3f\n\taverage_sync_time: %0.3f", avearge_pulse_delay, average_pulse_width, average_pulse_period, average_sync_time);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (avearge_pulse_delay > CLOCK_DEVIATION * CLK_ADC_PERIOD) begin
|
||||||
|
$display("[ERROR] -run_test_case- avearge_pulse_delay too big: %0.3f", avearge_pulse_delay);
|
||||||
|
error_flag = 1;
|
||||||
|
end
|
||||||
|
if (fabs(average_pulse_width - pulse_width * CLK_DAC_PERIOD * (pulse_height != ZERO_LEVEL)) > CLOCK_DEVIATION * CLK_ADC_PERIOD && sample_num * CLK_ADC_PERIOD >= pulse_width * CLK_DAC_PERIOD) begin
|
||||||
|
$display("[ERROR] -run_test_case- average_pulse_width deviates from choosen pulse_width. Deviation: %0.3f > %0.3f ns", fabs(average_pulse_width - pulse_width * CLK_DAC_PERIOD), CLOCK_DEVIATION * CLK_ADC_PERIOD);
|
||||||
|
error_flag = 1;
|
||||||
|
end
|
||||||
|
if (fabs(average_pulse_period - sample_num * CLK_ADC_PERIOD) > CLOCK_DEVIATION * CLK_ADC_PERIOD) begin
|
||||||
|
$display("[ERROR] -run_test_case- average_pulse_period deviates from choosen pulse_width. Deviation: %0.3f > %0.3f ns", fabs(average_pulse_period - sample_num * CLK_ADC_PERIOD), CLOCK_DEVIATION * CLK_ADC_PERIOD);
|
||||||
|
error_flag = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (VERBOSE >= 2) begin
|
||||||
|
$display("[TB] -run_test_case- Pass error processing");
|
||||||
|
end
|
||||||
|
|
||||||
|
if (error_flag)
|
||||||
|
$finish;
|
||||||
|
|
||||||
|
if (VERBOSE >= 2) begin
|
||||||
|
$display("[TB] -run_test_case- Passed checks");
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
// Таска
|
||||||
|
|
||||||
|
// --- ОСНОВНОЙ ПРОЦЕСС ТЕСТИРОВАНИЯ ---
|
||||||
initial begin
|
initial begin
|
||||||
|
$display("[TB] Tests start");
|
||||||
|
|
||||||
adc_rst = 1'b1;
|
// Инициализация
|
||||||
dac_rst = 1'b1;
|
dac_start = 0;
|
||||||
|
|
||||||
dac_start = 1'b0;
|
|
||||||
|
|
||||||
pulse_width = 0;
|
pulse_width = 0;
|
||||||
pulse_period = 0;
|
pulse_period = 0;
|
||||||
pulse_height = 0;
|
pulse_height = 0;
|
||||||
pulse_num = 0;
|
pulse_num = 0;
|
||||||
smp_num = 0;
|
smp_num = 0;
|
||||||
|
out_of_range = 0;
|
||||||
|
rst_adc = 0;
|
||||||
|
rst_dac = 0;
|
||||||
|
|
||||||
valid_count = 0;
|
#100; // init
|
||||||
|
|
||||||
//--------------------------------------------------------
|
$display("[TB] Test 1. Simple test. (1/4)");
|
||||||
// reset
|
run_test_case(
|
||||||
//--------------------------------------------------------
|
.pulse_width(50),
|
||||||
repeat (10) @(posedge adc_clk_in);
|
.pulse_period(125),
|
||||||
repeat (10) @(posedge dac_clk_in);
|
.pulse_height(2**DAC_DATA_WIDTH-1),
|
||||||
|
.pulse_num(5),
|
||||||
|
.sample_num(65),
|
||||||
|
.skip_reset(0),
|
||||||
|
.randomize_start_timing(1),
|
||||||
|
.out_of_range_val(0),
|
||||||
|
.randomize_out_of_range(0)
|
||||||
|
);
|
||||||
|
$display("[TB] Test 1. Simple test. (2/4)");
|
||||||
|
run_test_case(
|
||||||
|
.pulse_width(25),
|
||||||
|
.pulse_period(125),
|
||||||
|
.pulse_height(2**(ADC_DATA_WIDTH-1)),
|
||||||
|
.pulse_num(10),
|
||||||
|
.sample_num(65),
|
||||||
|
.skip_reset(1),
|
||||||
|
.randomize_start_timing(1),
|
||||||
|
.out_of_range_val(0),
|
||||||
|
.randomize_out_of_range(0)
|
||||||
|
);
|
||||||
|
$display("[TB] Test 1. Simple test. (3/4)");
|
||||||
|
run_test_case(
|
||||||
|
.pulse_width(10),
|
||||||
|
.pulse_period(50),
|
||||||
|
.pulse_height(ZERO_LEVEL),
|
||||||
|
.pulse_num(4),
|
||||||
|
.sample_num(25),
|
||||||
|
.skip_reset(1),
|
||||||
|
.randomize_start_timing(1),
|
||||||
|
.out_of_range_val(0),
|
||||||
|
.randomize_out_of_range(0)
|
||||||
|
);
|
||||||
|
|
||||||
adc_rst = 1'b0;
|
$display("[TB] Test 1. Simple test. (4/4)");
|
||||||
dac_rst = 1'b0;
|
run_test_case(
|
||||||
|
.pulse_width(25),
|
||||||
|
.pulse_period(125),
|
||||||
|
.pulse_height(2**(DAC_DATA_WIDTH-1)),
|
||||||
|
.pulse_num(10),
|
||||||
|
.sample_num(65),
|
||||||
|
.skip_reset(1),
|
||||||
|
.randomize_start_timing(1),
|
||||||
|
.out_of_range_val(0),
|
||||||
|
.randomize_out_of_range(0)
|
||||||
|
);
|
||||||
|
$display("[TB] Test 1 complete");
|
||||||
|
|
||||||
repeat (5) @(posedge dac_clk_in);
|
$display("[TB] Test 2. Edge cases. Pulse width 0%%. (1/7)");
|
||||||
|
run_test_case(
|
||||||
|
.pulse_width(0),
|
||||||
|
.pulse_period(125),
|
||||||
|
.pulse_height(2**(ADC_DATA_WIDTH-1)),
|
||||||
|
.pulse_num(5),
|
||||||
|
.sample_num(65),
|
||||||
|
.skip_reset(1),
|
||||||
|
.randomize_start_timing(1),
|
||||||
|
.out_of_range_val(0),
|
||||||
|
.randomize_out_of_range(0)
|
||||||
|
);
|
||||||
|
$display("[TB] Test 2. Edge cases. Pulse width 100%%. (2/7)");
|
||||||
|
run_test_case(
|
||||||
|
.pulse_width(10),
|
||||||
|
.pulse_period(10),
|
||||||
|
.pulse_height(2**(ADC_DATA_WIDTH-1)),
|
||||||
|
.pulse_num(5),
|
||||||
|
.sample_num(65),
|
||||||
|
.skip_reset(1),
|
||||||
|
.randomize_start_timing(1),
|
||||||
|
.out_of_range_val(0),
|
||||||
|
.randomize_out_of_range(0)
|
||||||
|
);
|
||||||
|
$display("[TB] Test 2. Edge cases. Pulse height == ZERO_LEVEL. (3/7)");
|
||||||
|
run_test_case(
|
||||||
|
.pulse_width(10),
|
||||||
|
.pulse_period(125),
|
||||||
|
.pulse_height(ZERO_LEVEL),
|
||||||
|
.pulse_num(5),
|
||||||
|
.sample_num(65),
|
||||||
|
.skip_reset(1),
|
||||||
|
.randomize_start_timing(1),
|
||||||
|
.out_of_range_val(0),
|
||||||
|
.randomize_out_of_range(0)
|
||||||
|
);
|
||||||
|
$display("[TB] Test 2. Edge cases. Pulse num == 0. (4/7)");
|
||||||
|
run_test_case(
|
||||||
|
.pulse_width(10),
|
||||||
|
.pulse_period(125),
|
||||||
|
.pulse_height(2**(ADC_DATA_WIDTH-3)),
|
||||||
|
.pulse_num(0),
|
||||||
|
.sample_num(65),
|
||||||
|
.skip_reset(1),
|
||||||
|
.randomize_start_timing(1),
|
||||||
|
.out_of_range_val(0),
|
||||||
|
.randomize_out_of_range(0)
|
||||||
|
);
|
||||||
|
|
||||||
//--------------------------------------------------------
|
$display("[TB] Test 2. Edge cases. Sample num time << Pulse width time. (5/7)");
|
||||||
// config
|
run_test_case(
|
||||||
//--------------------------------------------------------
|
.pulse_width(10),
|
||||||
pulse_width = 32'd3;
|
.pulse_period(125),
|
||||||
pulse_period = 32'd8;
|
.pulse_height(2**(ADC_DATA_WIDTH-1)),
|
||||||
pulse_height = 14'd200;
|
.pulse_num(5),
|
||||||
pulse_num = 16'd4;
|
.sample_num(2),
|
||||||
smp_num = 32'd8;
|
.skip_reset(1),
|
||||||
|
.randomize_start_timing(1),
|
||||||
|
.out_of_range_val(0),
|
||||||
|
.randomize_out_of_range(0)
|
||||||
|
);
|
||||||
|
|
||||||
//--------------------------------------------------------
|
// Ожидание окончания работы генератора. Т.к. конец работы определяется по tvalid сэмплера, а он завершается сильно раньше. Чтобы не пропустить start следующей таски, ждем
|
||||||
// start
|
wait(dut.generator_inst.enable == 0);
|
||||||
//--------------------------------------------------------
|
#50;
|
||||||
@(posedge dac_clk_in);
|
|
||||||
dac_start = 1'b1;
|
|
||||||
|
|
||||||
@(posedge dac_clk_in);
|
$display("[TB] Test 2. Edge cases. Sample num == 0. (6/7)");
|
||||||
dac_start = 1'b0;
|
// Запустим в работу вручную, т.к. run_test_case обязательно ждет pulse num циклов. Детекция цикла производится по активности сэплера. Ее не должно быть при sample num = 0
|
||||||
|
set_config(
|
||||||
|
.w(10),
|
||||||
|
.p(125),
|
||||||
|
.h(2**(ADC_DATA_WIDTH-1)),
|
||||||
|
.n(5),
|
||||||
|
.sn(0)
|
||||||
|
);
|
||||||
|
start_dut(3);
|
||||||
|
fork
|
||||||
|
begin : wait_sampler_active_proc
|
||||||
|
@(posedge m_axis_tvalid);
|
||||||
|
$display("[ERROR] Sampler active with sample num == 0");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
begin
|
||||||
|
@(negedge dut.generator_inst.enable);
|
||||||
|
end
|
||||||
|
join_any
|
||||||
|
disable wait_sampler_active_proc;
|
||||||
|
repeat(30) @(posedge clk_adc);
|
||||||
|
|
||||||
$display("==================================");
|
// Данный тест должен приводить к тому, что сэмплер будет давать крайние значения вместо заданного pulse height из-за OTR=1
|
||||||
$display("TEST START");
|
// Дописать авто тест
|
||||||
$display("==================================");
|
$display("[TB] Test 2. Edge cases. OTR == 1. (7/7)");
|
||||||
|
run_test_case(
|
||||||
|
.pulse_width(10),
|
||||||
|
.pulse_period(125),
|
||||||
|
.pulse_height(10), // goes to 0x0..
|
||||||
|
.pulse_num(5),
|
||||||
|
.sample_num(65),
|
||||||
|
.skip_reset(1),
|
||||||
|
.randomize_start_timing(1),
|
||||||
|
.out_of_range_val(1),
|
||||||
|
.randomize_out_of_range(0)
|
||||||
|
);
|
||||||
|
$display("[TB] Test 2. Edge cases. OTR == 1. (7-2/7)");
|
||||||
|
run_test_case(
|
||||||
|
.pulse_width(10),
|
||||||
|
.pulse_period(125),
|
||||||
|
.pulse_height(14'b11010000000000), // goes to 0xff..
|
||||||
|
.pulse_num(5),
|
||||||
|
.sample_num(65),
|
||||||
|
.skip_reset(1),
|
||||||
|
.randomize_start_timing(1),
|
||||||
|
.out_of_range_val(1),
|
||||||
|
.randomize_out_of_range(0)
|
||||||
|
);
|
||||||
|
$display("[TB] Test 2 complete");
|
||||||
|
|
||||||
//--------------------------------------------------------
|
$display("[TB] Test 3. Random tests");
|
||||||
// wait
|
for (int i = 0; i < 100; i++) begin
|
||||||
//--------------------------------------------------------
|
int r_w, r_p, r_n, r_h, r_sn;
|
||||||
repeat (600) @(posedge adc_clk_in);
|
bit r_skip, r_otr, r_otr_rand;
|
||||||
|
|
||||||
//--------------------------------------------------------
|
// Генерируем параметры
|
||||||
// check
|
r_p = $urandom_range(50, 150); // Период от 5 до 50
|
||||||
//--------------------------------------------------------
|
r_w = $urandom_range(10, r_p); // Ширина не больше периода
|
||||||
if (valid_count > 0) begin
|
r_n = $urandom_range(1, 10); // Количество импульсов
|
||||||
$display("==================================");
|
r_h = $urandom_range(0, 2**(`MIN(ADC_DATA_WIDTH, DAC_DATA_WIDTH))-1); // Высота импульса
|
||||||
$display("TEST PASSED");
|
r_sn = $urandom_range(2, 40); // Число сэмплов
|
||||||
$display("valid_count = %0d", valid_count);
|
r_skip = $urandom_range(0, 1); // Случайный сброс (0 - сброс, 1 - пропуск)
|
||||||
$display("==================================");
|
r_otr = 0; // Out Of Range стартовое значение
|
||||||
end
|
r_otr_rand = 0; // Сделать OTR случайным
|
||||||
else begin
|
|
||||||
$display("==================================");
|
if (VERBOSE >= 1)
|
||||||
$display("TEST FAILED");
|
$display("[TB] --- Test #%0d (Config: W=%0d, P=%0d, N=%0d, H=%0d, SN=%0d, SkipReset=%0b) ---",
|
||||||
$display("No valid output detected");
|
i+1, r_w, r_p, r_n, r_h, r_sn, r_skip);
|
||||||
$display("==================================");
|
|
||||||
|
run_test_case(
|
||||||
|
.pulse_width(r_w),
|
||||||
|
.pulse_period(r_p),
|
||||||
|
.pulse_height(r_h),
|
||||||
|
.pulse_num(r_n),
|
||||||
|
.sample_num(r_sn),
|
||||||
|
.skip_reset(r_skip),
|
||||||
|
.randomize_start_timing(0),
|
||||||
|
.out_of_range_val(r_otr),
|
||||||
|
.randomize_out_of_range(r_otr_rand)
|
||||||
|
);
|
||||||
|
|
||||||
|
wait(dut.generator_inst.enable == 0); // Проверка на завершение работы
|
||||||
|
#50;
|
||||||
end
|
end
|
||||||
|
$display("[TB] Test 3 complete");
|
||||||
|
|
||||||
|
$display("[TB] ALL PASSED");
|
||||||
|
$display("[TB] Maximum clock deviation of stats %0.2f", CLOCK_DEVIATION);
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -10,13 +10,21 @@
|
|||||||
FPGA_PART = xc7a100tfgg484-2
|
FPGA_PART = xc7a100tfgg484-2
|
||||||
FPGA_TOP = reflectometer_top
|
FPGA_TOP = reflectometer_top
|
||||||
FPGA_ARCH = artix7
|
FPGA_ARCH = artix7
|
||||||
|
SIM_TOP = reflectometer_tb
|
||||||
|
|
||||||
RTL_DIR = ../../rtl
|
RTL_DIR = ../../rtl
|
||||||
|
|
||||||
|
|
||||||
include ../../scripts/vivado.mk
|
include ../../scripts/vivado.mk
|
||||||
|
|
||||||
|
|
||||||
|
INC_FILES += interfaces.svh
|
||||||
|
|
||||||
|
TB_FILES += reflectometer_tb.sv
|
||||||
SYN_FILES += reflectometer.sv
|
SYN_FILES += reflectometer.sv
|
||||||
|
SYN_FILES += dac_model.sv
|
||||||
|
SYN_FILES += adc_model.sv
|
||||||
|
SYN_FILES += reflectometer_tb.sv
|
||||||
SYN_FILES += $(sort $(shell find ../../rtl -type f \( -name '*.v' -o -name '*.sv' \)))
|
SYN_FILES += $(sort $(shell find ../../rtl -type f \( -name '*.v' -o -name '*.sv' \)))
|
||||||
|
|
||||||
XCI_FILES = $(sort $(shell find ../../rtl/ethernet-udp/src -type f -name '*.xci'))
|
XCI_FILES = $(sort $(shell find ../../rtl/ethernet-udp/src -type f -name '*.xci'))
|
||||||
|
|||||||
59
designs/reflectometer_base/adc_model.sv
Normal file
59
designs/reflectometer_base/adc_model.sv
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
// AN9238 virtual ADC model (1 port)
|
||||||
|
|
||||||
|
module virtual_adc_model #(
|
||||||
|
parameter int unsigned ADC_DATA_WIDTH = 12,
|
||||||
|
|
||||||
|
// Bipolar input range: +/- VOLTAGE_RANGE
|
||||||
|
parameter real VOLTAGE_RANGE = 1.0,
|
||||||
|
|
||||||
|
// Analog input correction
|
||||||
|
parameter real VOLTAGE_GAIN = 0.2,
|
||||||
|
parameter real GROUND_BIAS = 0.0,
|
||||||
|
|
||||||
|
// ADC timing parameters
|
||||||
|
parameter time CONVERSION_DELAY = 250ps
|
||||||
|
)(
|
||||||
|
input logic clk_i,
|
||||||
|
input real voltage_i,
|
||||||
|
|
||||||
|
output logic otr_o,
|
||||||
|
output logic [ADC_DATA_WIDTH-1:0] data_o
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam int unsigned ZERO_CODE = (1 << (ADC_DATA_WIDTH - 1));
|
||||||
|
localparam real VOLTAGE_STEP = (2 * VOLTAGE_RANGE) / real'((1 << ADC_DATA_WIDTH) - 1);
|
||||||
|
|
||||||
|
real voltage_corrected;
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Convert analog voltage to ADC code
|
||||||
|
//------------------------------------------------------------
|
||||||
|
function automatic logic [ADC_DATA_WIDTH-1:0] voltage_to_code( input real voltage );
|
||||||
|
if (voltage <= -VOLTAGE_RANGE) return '0;
|
||||||
|
if (voltage >= VOLTAGE_RANGE) return {ADC_DATA_WIDTH{1'b1}};
|
||||||
|
return $rtoi(voltage / VOLTAGE_STEP + real'((ZERO_CODE)) + 0.5);
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function automatic logic range_check( input real voltage );
|
||||||
|
real v_abs = (voltage < 0.0) ? -voltage : voltage;
|
||||||
|
return v_abs >= VOLTAGE_RANGE;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Initial state
|
||||||
|
//------------------------------------------------------------
|
||||||
|
initial begin
|
||||||
|
data_o = ZERO_CODE; // 0V
|
||||||
|
otr_o = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Update analog output
|
||||||
|
//------------------------------------------------------------
|
||||||
|
always @(posedge clk_i) begin
|
||||||
|
voltage_corrected = (voltage_i - GROUND_BIAS) * VOLTAGE_GAIN;
|
||||||
|
data_o <= #(CONVERSION_DELAY) voltage_to_code(voltage_corrected);
|
||||||
|
otr_o <= #(CONVERSION_DELAY) range_check(voltage_corrected);
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
58
designs/reflectometer_base/dac_model.sv
Normal file
58
designs/reflectometer_base/dac_model.sv
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// AN9767 model (1 port)
|
||||||
|
|
||||||
|
module virtual_dac_model #(
|
||||||
|
parameter int unsigned DAC_DATA_WIDTH = 14,
|
||||||
|
|
||||||
|
// Bipolar output range: +/- VOLTAGE_RANGE
|
||||||
|
parameter real VOLTAGE_RANGE = 5.0,
|
||||||
|
|
||||||
|
// Analog output correction
|
||||||
|
parameter real VOLTAGE_GAIN = 1.0,
|
||||||
|
parameter real GROUND_BIAS = 0.0,
|
||||||
|
|
||||||
|
// DAC timing parameters
|
||||||
|
parameter time TRANSMISSION_DELAY = 150ps,
|
||||||
|
parameter time CONVERSION_DELAY = 150ps
|
||||||
|
)(
|
||||||
|
input logic clk_i,
|
||||||
|
input logic wrt_i,
|
||||||
|
input logic [DAC_DATA_WIDTH-1:0] data_i,
|
||||||
|
|
||||||
|
output real voltage_o
|
||||||
|
);
|
||||||
|
|
||||||
|
localparam int unsigned ZERO_CODE = (1 << (DAC_DATA_WIDTH - 1));
|
||||||
|
localparam real VOLTAGE_STEP = (2 * VOLTAGE_RANGE) / real'((1 << DAC_DATA_WIDTH) - 1);
|
||||||
|
|
||||||
|
logic [DAC_DATA_WIDTH-1:0] dac_code;
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Convert DAC code to analog voltage
|
||||||
|
//------------------------------------------------------------
|
||||||
|
function automatic real code_to_voltage( input logic [DAC_DATA_WIDTH-1:0] code);
|
||||||
|
return (int'(code) - int'(ZERO_CODE)) * VOLTAGE_STEP;
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Initial state
|
||||||
|
//------------------------------------------------------------
|
||||||
|
initial begin
|
||||||
|
dac_code = '0;
|
||||||
|
voltage_o = code_to_voltage('0) * VOLTAGE_GAIN + GROUND_BIAS;
|
||||||
|
end
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Latch new DAC code
|
||||||
|
//------------------------------------------------------------
|
||||||
|
always @(posedge wrt_i) begin
|
||||||
|
dac_code <= #(TRANSMISSION_DELAY) data_i;
|
||||||
|
end
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Update analog output
|
||||||
|
//------------------------------------------------------------
|
||||||
|
always @(posedge clk_i) begin
|
||||||
|
voltage_o <= #(CONVERSION_DELAY) code_to_voltage(dac_code) * VOLTAGE_GAIN + GROUND_BIAS;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
@ -1 +1,9 @@
|
|||||||
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]
|
||||||
|
|
||||||
|
set clk_125_name [get_clocks -of_objects [get_pins generator_inst/clk_dac_125]]
|
||||||
|
set clk_65_name [get_clocks -of_objects [get_pins accumulator_top_dut/clk_adc_65]]
|
||||||
|
|
||||||
|
set_clock_groups -asynchronous -group $clk_125_name -group $clk_65_name
|
||||||
130
designs/reflectometer_base/interfaces.svh
Normal file
130
designs/reflectometer_base/interfaces.svh
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
`ifndef AXIS_INTERFACE_SVH
|
||||||
|
`define AXIS_INTERFACE_SVH
|
||||||
|
|
||||||
|
interface axis_if #(
|
||||||
|
parameter int DATA_WIDTH = 8
|
||||||
|
)(
|
||||||
|
input logic clk,
|
||||||
|
input logic rst_n
|
||||||
|
);
|
||||||
|
|
||||||
|
// Сигналы шины AXI-Stream
|
||||||
|
logic [DATA_WIDTH-1:0] tdata;
|
||||||
|
logic tvalid;
|
||||||
|
logic tlast;
|
||||||
|
logic tready;
|
||||||
|
|
||||||
|
initial begin // Default values
|
||||||
|
tdata = 'x;
|
||||||
|
tvalid = 1'b0;
|
||||||
|
tlast = 1'b0;
|
||||||
|
tready = 1'b0;
|
||||||
|
end
|
||||||
|
|
||||||
|
// Master Clocking Block (для отправки данных из TB)
|
||||||
|
clocking drv_cb @(posedge clk);
|
||||||
|
default input #1step output #100ps;
|
||||||
|
output tdata, tvalid, tlast;
|
||||||
|
input tready;
|
||||||
|
endclocking
|
||||||
|
|
||||||
|
// Slave Clocking Block (для приема данных в TB с генерацией tready)
|
||||||
|
clocking slv_cb @(posedge clk);
|
||||||
|
default input #1step output #100ps;
|
||||||
|
input tdata, tvalid, tlast;
|
||||||
|
output tready;
|
||||||
|
endclocking
|
||||||
|
|
||||||
|
// Passive Monitor Clocking Block
|
||||||
|
clocking mon_cb @(posedge clk);
|
||||||
|
default input #1step;
|
||||||
|
input tdata, tvalid, tlast, tready;
|
||||||
|
endclocking
|
||||||
|
|
||||||
|
modport master (output tdata, tvalid, tlast, input tready);
|
||||||
|
modport slave (input tdata, tvalid, tlast, output tready);
|
||||||
|
|
||||||
|
// Модпорт для тестбенча с тасками
|
||||||
|
modport tb (
|
||||||
|
clocking drv_cb,
|
||||||
|
clocking slv_cb,
|
||||||
|
clocking mon_cb,
|
||||||
|
import master_send,
|
||||||
|
import slave_recv,
|
||||||
|
import monitor_recv
|
||||||
|
);
|
||||||
|
|
||||||
|
// Отправка пакета (Тестбенч выступает как Master)
|
||||||
|
task automatic master_send(input logic [DATA_WIDTH-1:0] payload[]);
|
||||||
|
if (payload.size() == 0) return;
|
||||||
|
|
||||||
|
@(drv_cb);
|
||||||
|
|
||||||
|
for (int i = 0; i < payload.size(); i++) begin
|
||||||
|
drv_cb.tdata <= payload[i];
|
||||||
|
drv_cb.tvalid <= 1'b1;
|
||||||
|
drv_cb.tlast <= (i == payload.size() - 1);
|
||||||
|
|
||||||
|
forever begin // Ждем подтверждение от слейва пока не получим
|
||||||
|
@(drv_cb);
|
||||||
|
if (drv_cb.tready === 1'b1) begin
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
// Сбрасываем сигналы после отправки пакета
|
||||||
|
drv_cb.tvalid <= 1'b0;
|
||||||
|
drv_cb.tlast <= 1'b0;
|
||||||
|
drv_cb.tdata <= 'x;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
// Прием пакета (Тестбенч выступает как Slave и управляет tready). Не применять если есть реальный Slave (его tready опустится насильно)
|
||||||
|
task automatic slave_recv(output logic [DATA_WIDTH-1:0] payload[]);
|
||||||
|
logic [DATA_WIDTH-1:0] local_queue[$]; // Внутри таски очередь использовать можно
|
||||||
|
|
||||||
|
slv_cb.tready <= 1'b1; // Показываем, что готовы принимать
|
||||||
|
|
||||||
|
forever begin
|
||||||
|
@(slv_cb);
|
||||||
|
if (slv_cb.tvalid === 1'b1) begin
|
||||||
|
local_queue.push_back(slv_cb.tdata);
|
||||||
|
if (slv_cb.tlast === 1'b1) begin
|
||||||
|
break; // Пакет закончился
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
slv_cb.tready <= 1'b0; // Снимаем готовность
|
||||||
|
|
||||||
|
// Перекладываем из очереди в динамический массив
|
||||||
|
payload = new[local_queue.size()](local_queue);
|
||||||
|
endtask
|
||||||
|
|
||||||
|
// Прием пакета (Тестбенч выступает как пассивный наблюдатель без tready)
|
||||||
|
task automatic monitor_recv(output logic [DATA_WIDTH-1:0] payload[]);
|
||||||
|
logic [DATA_WIDTH-1:0] local_queue[$]; // Внутри таски очередь использовать можно
|
||||||
|
|
||||||
|
forever begin
|
||||||
|
if (mon_cb.tready === 1'b1) begin
|
||||||
|
break; // Дождались слейва
|
||||||
|
end
|
||||||
|
@(slv_cb);
|
||||||
|
end
|
||||||
|
|
||||||
|
forever begin
|
||||||
|
@(mon_cb);
|
||||||
|
if (mon_cb.tvalid === 1'b1) begin
|
||||||
|
local_queue.push_back(mon_cb.tdata);
|
||||||
|
if (mon_cb.tlast === 1'b1) begin
|
||||||
|
break; // Пакет закончился
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// Перекладываем из очереди в динамический массив
|
||||||
|
payload = new[local_queue.size()](local_queue);
|
||||||
|
endtask
|
||||||
|
|
||||||
|
endinterface
|
||||||
|
|
||||||
|
`endif // AXIS_INTERFACE_SVH`
|
||||||
@ -3,8 +3,8 @@
|
|||||||
"ip_inst": {
|
"ip_inst": {
|
||||||
"xci_name": "clk_wiz_ctrl_inst",
|
"xci_name": "clk_wiz_ctrl_inst",
|
||||||
"component_reference": "xilinx.com:ip:clk_wiz:6.0",
|
"component_reference": "xilinx.com:ip:clk_wiz:6.0",
|
||||||
"ip_revision": "16",
|
"ip_revision": "17",
|
||||||
"gen_directory": "../../../../eth_generator_top.gen/sources_1/ip/clk_wiz_ctrl_inst",
|
"gen_directory": "../../../../reflectometer_top.gen/sources_1/ip/clk_wiz_ctrl_inst",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"component_parameters": {
|
"component_parameters": {
|
||||||
"Component_Name": [ { "value": "clk_wiz_ctrl_inst", "resolve_type": "user", "usage": "all" } ],
|
"Component_Name": [ { "value": "clk_wiz_ctrl_inst", "resolve_type": "user", "usage": "all" } ],
|
||||||
@ -31,7 +31,7 @@
|
|||||||
"USE_MIN_POWER": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"USE_MIN_POWER": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"USE_DYN_PHASE_SHIFT": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"USE_DYN_PHASE_SHIFT": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"USE_DYN_RECONFIG": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"USE_DYN_RECONFIG": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"JITTER_SEL": [ { "value": "No_Jitter", "resolve_type": "user", "usage": "all" } ],
|
"JITTER_SEL": [ { "value": "Min_O_Jitter", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"PRIM_IN_FREQ": [ { "value": "200.000", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"PRIM_IN_FREQ": [ { "value": "200.000", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"PRIM_IN_TIMEPERIOD": [ { "value": "10.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"PRIM_IN_TIMEPERIOD": [ { "value": "10.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"IN_FREQ_UNITS": [ { "value": "Units_MHz", "resolve_type": "user", "usage": "all" } ],
|
"IN_FREQ_UNITS": [ { "value": "Units_MHz", "resolve_type": "user", "usage": "all" } ],
|
||||||
@ -52,12 +52,12 @@
|
|||||||
"CLKIN2_JITTER_PS": [ { "value": "100.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKIN2_JITTER_PS": [ { "value": "100.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT1_USED": [ { "value": "true", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLKOUT1_USED": [ { "value": "true", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"CLKOUT2_USED": [ { "value": "true", "value_src": "user", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLKOUT2_USED": [ { "value": "true", "value_src": "user", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"CLKOUT3_USED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLKOUT3_USED": [ { "value": "true", "value_src": "user", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"CLKOUT4_USED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLKOUT4_USED": [ { "value": "true", "value_src": "user", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"CLKOUT5_USED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLKOUT5_USED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"CLKOUT6_USED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLKOUT6_USED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"CLKOUT7_USED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLKOUT7_USED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"NUM_OUT_CLKS": [ { "value": "2", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
"NUM_OUT_CLKS": [ { "value": "4", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||||
"CLK_OUT1_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLK_OUT1_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"CLK_OUT2_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLK_OUT2_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"CLK_OUT3_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLK_OUT3_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
@ -65,11 +65,11 @@
|
|||||||
"CLK_OUT5_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLK_OUT5_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"CLK_OUT6_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLK_OUT6_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"CLK_OUT7_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLK_OUT7_USE_FINE_PS_GUI": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"PRIMARY_PORT": [ { "value": "clk_in1", "resolve_type": "user", "usage": "all" } ],
|
"PRIMARY_PORT": [ { "value": "clk_200", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLK_OUT1_PORT": [ { "value": "clk_out1", "resolve_type": "user", "usage": "all" } ],
|
"CLK_OUT1_PORT": [ { "value": "clk_adc_65", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLK_OUT2_PORT": [ { "value": "clk_out2", "resolve_type": "user", "usage": "all" } ],
|
"CLK_OUT2_PORT": [ { "value": "clk_adc_65_180", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLK_OUT3_PORT": [ { "value": "clk_out3", "resolve_type": "user", "usage": "all" } ],
|
"CLK_OUT3_PORT": [ { "value": "clk_dac_125", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLK_OUT4_PORT": [ { "value": "clk_out4", "resolve_type": "user", "usage": "all" } ],
|
"CLK_OUT4_PORT": [ { "value": "clk_dac_125_180", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLK_OUT5_PORT": [ { "value": "clk_out5", "resolve_type": "user", "usage": "all" } ],
|
"CLK_OUT5_PORT": [ { "value": "clk_out5", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLK_OUT6_PORT": [ { "value": "clk_out6", "resolve_type": "user", "usage": "all" } ],
|
"CLK_OUT6_PORT": [ { "value": "clk_out6", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLK_OUT7_PORT": [ { "value": "clk_out7", "resolve_type": "user", "usage": "all" } ],
|
"CLK_OUT7_PORT": [ { "value": "clk_out7", "resolve_type": "user", "usage": "all" } ],
|
||||||
@ -84,17 +84,17 @@
|
|||||||
"PSEN_PORT": [ { "value": "psen", "resolve_type": "user", "usage": "all" } ],
|
"PSEN_PORT": [ { "value": "psen", "resolve_type": "user", "usage": "all" } ],
|
||||||
"PSINCDEC_PORT": [ { "value": "psincdec", "resolve_type": "user", "usage": "all" } ],
|
"PSINCDEC_PORT": [ { "value": "psincdec", "resolve_type": "user", "usage": "all" } ],
|
||||||
"PSDONE_PORT": [ { "value": "psdone", "resolve_type": "user", "usage": "all" } ],
|
"PSDONE_PORT": [ { "value": "psdone", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLKOUT1_REQUESTED_OUT_FREQ": [ { "value": "125", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT1_REQUESTED_OUT_FREQ": [ { "value": "65", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT1_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT1_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT1_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT1_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT2_REQUESTED_OUT_FREQ": [ { "value": "65.000", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT2_REQUESTED_OUT_FREQ": [ { "value": "65", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT2_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT2_REQUESTED_PHASE": [ { "value": "180", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT2_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT2_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT3_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT3_REQUESTED_OUT_FREQ": [ { "value": "125", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT3_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT3_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT3_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT3_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT4_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT4_REQUESTED_OUT_FREQ": [ { "value": "125", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT4_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT4_REQUESTED_PHASE": [ { "value": "180", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT4_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT4_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT5_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT5_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT5_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT5_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
@ -115,14 +115,14 @@
|
|||||||
"CLKOUT6_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLKOUT6_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"CLKOUT7_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"CLKOUT7_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"PRIM_SOURCE": [ { "value": "Single_ended_clock_capable_pin", "resolve_type": "user", "usage": "all" } ],
|
"PRIM_SOURCE": [ { "value": "Single_ended_clock_capable_pin", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLKOUT1_DRIVES": [ { "value": "BUFG", "resolve_type": "user", "usage": "all" } ],
|
"CLKOUT1_DRIVES": [ { "value": "BUFGCE", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLKOUT2_DRIVES": [ { "value": "BUFG", "resolve_type": "user", "usage": "all" } ],
|
"CLKOUT2_DRIVES": [ { "value": "BUFGCE", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLKOUT3_DRIVES": [ { "value": "BUFG", "resolve_type": "user", "usage": "all" } ],
|
"CLKOUT3_DRIVES": [ { "value": "BUFGCE", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLKOUT4_DRIVES": [ { "value": "BUFG", "resolve_type": "user", "usage": "all" } ],
|
"CLKOUT4_DRIVES": [ { "value": "BUFGCE", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLKOUT5_DRIVES": [ { "value": "BUFG", "resolve_type": "user", "usage": "all" } ],
|
"CLKOUT5_DRIVES": [ { "value": "BUFGCE", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLKOUT6_DRIVES": [ { "value": "BUFG", "resolve_type": "user", "usage": "all" } ],
|
"CLKOUT6_DRIVES": [ { "value": "BUFGCE", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLKOUT7_DRIVES": [ { "value": "BUFG", "resolve_type": "user", "usage": "all" } ],
|
"CLKOUT7_DRIVES": [ { "value": "BUFGCE", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"FEEDBACK_SOURCE": [ { "value": "FDBK_AUTO", "resolve_type": "user", "usage": "all" } ],
|
"FEEDBACK_SOURCE": [ { "value": "FDBK_AUTO", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLKFB_IN_SIGNALING": [ { "value": "SINGLE", "resolve_type": "user", "usage": "all" } ],
|
"CLKFB_IN_SIGNALING": [ { "value": "SINGLE", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLKFB_IN_PORT": [ { "value": "clkfb_in", "resolve_type": "user", "usage": "all" } ],
|
"CLKFB_IN_PORT": [ { "value": "clkfb_in", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLKFB_IN_P_PORT": [ { "value": "clkfb_in_p", "resolve_type": "user", "usage": "all" } ],
|
"CLKFB_IN_P_PORT": [ { "value": "clkfb_in_p", "resolve_type": "user", "usage": "all" } ],
|
||||||
@ -141,7 +141,7 @@
|
|||||||
"USE_CLK_VALID": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"USE_CLK_VALID": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"USE_INCLK_STOPPED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"USE_INCLK_STOPPED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"USE_CLKFB_STOPPED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"USE_CLKFB_STOPPED": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"RESET_PORT": [ { "value": "reset", "resolve_type": "user", "usage": "all" } ],
|
"RESET_PORT": [ { "value": "resetn", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"LOCKED_PORT": [ { "value": "locked", "resolve_type": "user", "usage": "all" } ],
|
"LOCKED_PORT": [ { "value": "locked", "resolve_type": "user", "usage": "all" } ],
|
||||||
"POWER_DOWN_PORT": [ { "value": "power_down", "resolve_type": "user", "usage": "all" } ],
|
"POWER_DOWN_PORT": [ { "value": "power_down", "resolve_type": "user", "usage": "all" } ],
|
||||||
"CLK_VALID_PORT": [ { "value": "CLK_VALID", "resolve_type": "user", "usage": "all" } ],
|
"CLK_VALID_PORT": [ { "value": "CLK_VALID", "resolve_type": "user", "usage": "all" } ],
|
||||||
@ -154,34 +154,34 @@
|
|||||||
"SS_MOD_TIME": [ { "value": "0.004", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"SS_MOD_TIME": [ { "value": "0.004", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"OVERRIDE_MMCM": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"OVERRIDE_MMCM": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"MMCM_NOTES": [ { "value": "None", "resolve_type": "user", "usage": "all" } ],
|
"MMCM_NOTES": [ { "value": "None", "resolve_type": "user", "usage": "all" } ],
|
||||||
"MMCM_DIVCLK_DIVIDE": [ { "value": "4", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
"MMCM_DIVCLK_DIVIDE": [ { "value": "5", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||||
"MMCM_BANDWIDTH": [ { "value": "OPTIMIZED", "resolve_type": "user", "usage": "all" } ],
|
"MMCM_BANDWIDTH": [ { "value": "HIGH", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"MMCM_CLKFBOUT_MULT_F": [ { "value": "16.875", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_CLKFBOUT_MULT_F": [ { "value": "34.125", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_CLKFBOUT_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_CLKFBOUT_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_CLKFBOUT_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"MMCM_CLKFBOUT_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"MMCM_CLKIN1_PERIOD": [ { "value": "5.000", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_CLKIN1_PERIOD": [ { "value": "5.000", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_CLKIN2_PERIOD": [ { "value": "10.0", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_CLKIN2_PERIOD": [ { "value": "10.000", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT4_CASCADE": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"MMCM_CLKOUT4_CASCADE": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"MMCM_CLOCK_HOLD": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"MMCM_CLOCK_HOLD": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"MMCM_COMPENSATION": [ { "value": "ZHOLD", "resolve_type": "user", "usage": "all" } ],
|
"MMCM_COMPENSATION": [ { "value": "ZHOLD", "resolve_type": "user", "usage": "all" } ],
|
||||||
"MMCM_REF_JITTER1": [ { "value": "0.010", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_REF_JITTER1": [ { "value": "0.010", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_REF_JITTER2": [ { "value": "0.010", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_REF_JITTER2": [ { "value": "0.010", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_STARTUP_WAIT": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"MMCM_STARTUP_WAIT": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT0_DIVIDE_F": [ { "value": "6.750", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_CLKOUT0_DIVIDE_F": [ { "value": "21.000", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT0_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_CLKOUT0_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT0_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_CLKOUT0_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT0_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"MMCM_CLKOUT0_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT1_DIVIDE": [ { "value": "13", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
"MMCM_CLKOUT1_DIVIDE": [ { "value": "21", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT1_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_CLKOUT1_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT1_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_CLKOUT1_PHASE": [ { "value": "180.000", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT1_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"MMCM_CLKOUT1_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT2_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
"MMCM_CLKOUT2_DIVIDE": [ { "value": "11", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT2_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_CLKOUT2_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT2_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_CLKOUT2_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT2_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"MMCM_CLKOUT2_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT3_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
"MMCM_CLKOUT3_DIVIDE": [ { "value": "11", "value_src": "user", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT3_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_CLKOUT3_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT3_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_CLKOUT3_PHASE": [ { "value": "180.000", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT3_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"MMCM_CLKOUT3_USE_FINE_PS": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT4_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
"MMCM_CLKOUT4_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||||
"MMCM_CLKOUT4_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"MMCM_CLKOUT4_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
@ -223,8 +223,8 @@
|
|||||||
"PLL_CLKOUT5_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
"PLL_CLKOUT5_DIVIDE": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||||
"PLL_CLKOUT5_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"PLL_CLKOUT5_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"PLL_CLKOUT5_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"PLL_CLKOUT5_PHASE": [ { "value": "0.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"RESET_TYPE": [ { "value": "ACTIVE_HIGH", "resolve_type": "user", "usage": "all" } ],
|
"RESET_TYPE": [ { "value": "ACTIVE_LOW", "value_src": "user", "resolve_type": "user", "usage": "all" } ],
|
||||||
"USE_SAFE_CLOCK_STARTUP": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"USE_SAFE_CLOCK_STARTUP": [ { "value": "true", "value_src": "user", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"USE_CLOCK_SEQUENCING": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"USE_CLOCK_SEQUENCING": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"CLKOUT1_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
"CLKOUT1_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||||
"CLKOUT2_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
"CLKOUT2_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "user", "format": "long", "usage": "all" } ],
|
||||||
@ -245,14 +245,14 @@
|
|||||||
"CDDCREQ_PORT": [ { "value": "cddcreq", "resolve_type": "user", "usage": "all" } ],
|
"CDDCREQ_PORT": [ { "value": "cddcreq", "resolve_type": "user", "usage": "all" } ],
|
||||||
"ENABLE_CLKOUTPHY": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
"ENABLE_CLKOUTPHY": [ { "value": "false", "resolve_type": "user", "format": "bool", "usage": "all" } ],
|
||||||
"CLKOUTPHY_REQUESTED_FREQ": [ { "value": "600.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUTPHY_REQUESTED_FREQ": [ { "value": "600.000", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT1_JITTER": [ { "value": "162.582", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT1_JITTER": [ { "value": "137.256", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT1_PHASE_ERROR": [ { "value": "137.238", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT1_PHASE_ERROR": [ { "value": "148.044", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT2_JITTER": [ { "value": "185.296", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT2_JITTER": [ { "value": "137.256", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT2_PHASE_ERROR": [ { "value": "137.238", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT2_PHASE_ERROR": [ { "value": "148.044", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT3_JITTER": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT3_JITTER": [ { "value": "123.850", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT3_PHASE_ERROR": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT3_PHASE_ERROR": [ { "value": "148.044", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT4_JITTER": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT4_JITTER": [ { "value": "123.850", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT4_PHASE_ERROR": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT4_PHASE_ERROR": [ { "value": "148.044", "value_src": "user", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT5_JITTER": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT5_JITTER": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT5_PHASE_ERROR": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT5_PHASE_ERROR": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
"CLKOUT6_JITTER": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
"CLKOUT6_JITTER": [ { "value": "0.0", "resolve_type": "user", "format": "float", "usage": "all" } ],
|
||||||
@ -280,8 +280,8 @@
|
|||||||
"C_Enable_PLL1": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_Enable_PLL1": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_REF_CLK_FREQ": [ { "value": "100.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_REF_CLK_FREQ": [ { "value": "100.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_PRECISION": [ { "value": "1", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_PRECISION": [ { "value": "1", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT3_USED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_CLKOUT3_USED": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_CLKOUT4_USED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_CLKOUT4_USED": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_CLKOUT5_USED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_CLKOUT5_USED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_CLKOUT6_USED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_CLKOUT6_USED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_CLKOUT7_USED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_CLKOUT7_USED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
@ -295,9 +295,9 @@
|
|||||||
"C_USE_PHASE_ALIGNMENT": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_USE_PHASE_ALIGNMENT": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_PRIM_IN_JITTER": [ { "value": "0.010", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_PRIM_IN_JITTER": [ { "value": "0.010", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_SECONDARY_IN_JITTER": [ { "value": "0.010", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_SECONDARY_IN_JITTER": [ { "value": "0.010", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_JITTER_SEL": [ { "value": "No_Jitter", "resolve_type": "generated", "usage": "all" } ],
|
"C_JITTER_SEL": [ { "value": "Min_O_Jitter", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_USE_MIN_POWER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_USE_MIN_POWER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_USE_MIN_O_JITTER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_USE_MIN_O_JITTER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_USE_MAX_I_JITTER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_USE_MAX_I_JITTER": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_USE_DYN_PHASE_SHIFT": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_USE_DYN_PHASE_SHIFT": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_OPTIMIZE_CLOCKING_STRUCTURE_EN": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_OPTIMIZE_CLOCKING_STRUCTURE_EN": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
@ -318,44 +318,44 @@
|
|||||||
"C_SECONDARY_SOURCE": [ { "value": "Single_ended_clock_capable_pin", "resolve_type": "generated", "usage": "all" } ],
|
"C_SECONDARY_SOURCE": [ { "value": "Single_ended_clock_capable_pin", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKFB_IN_SIGNALING": [ { "value": "SINGLE", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKFB_IN_SIGNALING": [ { "value": "SINGLE", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_USE_RESET": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_USE_RESET": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_RESET_LOW": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_RESET_LOW": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_USE_LOCKED": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_USE_LOCKED": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_USE_INCLK_STOPPED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_USE_INCLK_STOPPED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_USE_CLKFB_STOPPED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_USE_CLKFB_STOPPED": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_USE_POWER_DOWN": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_USE_POWER_DOWN": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_USE_STATUS": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_USE_STATUS": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_USE_FREEZE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_USE_FREEZE": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_NUM_OUT_CLKS": [ { "value": "2", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_NUM_OUT_CLKS": [ { "value": "4", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_CLKOUT1_DRIVES": [ { "value": "BUFG", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT1_DRIVES": [ { "value": "BUFGCE", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT2_DRIVES": [ { "value": "BUFG", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT2_DRIVES": [ { "value": "BUFGCE", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT3_DRIVES": [ { "value": "BUFG", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT3_DRIVES": [ { "value": "BUFGCE", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT4_DRIVES": [ { "value": "BUFG", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT4_DRIVES": [ { "value": "BUFGCE", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT5_DRIVES": [ { "value": "BUFG", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT5_DRIVES": [ { "value": "BUFGCE", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT6_DRIVES": [ { "value": "BUFG", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT6_DRIVES": [ { "value": "BUFGCE", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT7_DRIVES": [ { "value": "BUFG", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT7_DRIVES": [ { "value": "BUFGCE", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_INCLK_SUM_ROW0": [ { "value": "Input Clock Freq (MHz) Input Jitter (UI)", "resolve_type": "generated", "usage": "all" } ],
|
"C_INCLK_SUM_ROW0": [ { "value": "Input Clock Freq (MHz) Input Jitter (UI)", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_INCLK_SUM_ROW1": [ { "value": "__primary_________200.000____________0.010", "resolve_type": "generated", "usage": "all" } ],
|
"C_INCLK_SUM_ROW1": [ { "value": "__primary_________200.000____________0.010", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_INCLK_SUM_ROW2": [ { "value": "no_secondary_input_clock ", "resolve_type": "generated", "usage": "all" } ],
|
"C_INCLK_SUM_ROW2": [ { "value": "no_secondary_input_clock ", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_OUTCLK_SUM_ROW0A": [ { "value": " Output Output Phase Duty Cycle Pk-to-Pk Phase", "resolve_type": "generated", "usage": "all" } ],
|
"C_OUTCLK_SUM_ROW0A": [ { "value": " Output Output Phase Duty Cycle Pk-to-Pk Phase", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_OUTCLK_SUM_ROW0B": [ { "value": " Clock Freq (MHz) (degrees) (%) Jitter (ps) Error (ps)", "resolve_type": "generated", "usage": "all" } ],
|
"C_OUTCLK_SUM_ROW0B": [ { "value": " Clock Freq (MHz) (degrees) (%) Jitter (ps) Error (ps)", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_OUTCLK_SUM_ROW1": [ { "value": "clk_out1__125.00000______0.000______50.0______162.582____137.238", "resolve_type": "generated", "usage": "all" } ],
|
"C_OUTCLK_SUM_ROW1": [ { "value": "clk_adc_65__65.00000______0.000______50.0______137.256____148.044", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_OUTCLK_SUM_ROW2": [ { "value": "clk_out2__64.90385______0.000______50.0______185.296____137.238", "resolve_type": "generated", "usage": "all" } ],
|
"C_OUTCLK_SUM_ROW2": [ { "value": "clk_adc_65_180__65.00000____180.000______50.0______137.256____148.044", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_OUTCLK_SUM_ROW3": [ { "value": "no_CLK_OUT3_output", "resolve_type": "generated", "usage": "all" } ],
|
"C_OUTCLK_SUM_ROW3": [ { "value": "clk_dac_125__124.09091______0.000______50.0______123.850____148.044", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_OUTCLK_SUM_ROW4": [ { "value": "no_CLK_OUT4_output", "resolve_type": "generated", "usage": "all" } ],
|
"C_OUTCLK_SUM_ROW4": [ { "value": "clk_dac_125_180__124.09091____180.000______50.0______123.850____148.044", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_OUTCLK_SUM_ROW5": [ { "value": "no_CLK_OUT5_output", "resolve_type": "generated", "usage": "all" } ],
|
"C_OUTCLK_SUM_ROW5": [ { "value": "no_CLK_OUT5_output", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_OUTCLK_SUM_ROW6": [ { "value": "no_CLK_OUT6_output", "resolve_type": "generated", "usage": "all" } ],
|
"C_OUTCLK_SUM_ROW6": [ { "value": "no_CLK_OUT6_output", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_OUTCLK_SUM_ROW7": [ { "value": "no_CLK_OUT7_output", "resolve_type": "generated", "usage": "all" } ],
|
"C_OUTCLK_SUM_ROW7": [ { "value": "no_CLK_OUT7_output", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT1_REQUESTED_OUT_FREQ": [ { "value": "125", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT1_REQUESTED_OUT_FREQ": [ { "value": "65", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT2_REQUESTED_OUT_FREQ": [ { "value": "65.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT2_REQUESTED_OUT_FREQ": [ { "value": "65", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT3_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT3_REQUESTED_OUT_FREQ": [ { "value": "125", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT4_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT4_REQUESTED_OUT_FREQ": [ { "value": "125", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT5_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT5_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT6_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT6_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT7_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT7_REQUESTED_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT1_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT1_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT2_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT2_REQUESTED_PHASE": [ { "value": "180", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT3_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT3_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT4_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT4_REQUESTED_PHASE": [ { "value": "180", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT5_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT5_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT6_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT6_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT7_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT7_REQUESTED_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
@ -366,28 +366,28 @@
|
|||||||
"C_CLKOUT5_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT5_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT6_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT6_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT7_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT7_REQUESTED_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT1_OUT_FREQ": [ { "value": "125.00000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT1_OUT_FREQ": [ { "value": "65.00000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT2_OUT_FREQ": [ { "value": "64.90385", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT2_OUT_FREQ": [ { "value": "65.00000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT3_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT3_OUT_FREQ": [ { "value": "124.09091", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT4_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT4_OUT_FREQ": [ { "value": "124.09091", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT5_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT5_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT6_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT6_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT7_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT7_OUT_FREQ": [ { "value": "100.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT1_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT1_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT2_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT2_PHASE": [ { "value": "180.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT3_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT3_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT4_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT4_PHASE": [ { "value": "180.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT5_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT5_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT6_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT6_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT7_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT7_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT1_DUTY_CYCLE": [ { "value": "50.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT1_DUTY_CYCLE": [ { "value": "50.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT2_DUTY_CYCLE": [ { "value": "50.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT2_DUTY_CYCLE": [ { "value": "50.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT3_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT3_DUTY_CYCLE": [ { "value": "50.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT4_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT4_DUTY_CYCLE": [ { "value": "50.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT5_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT5_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT6_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT6_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_CLKOUT7_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_CLKOUT7_DUTY_CYCLE": [ { "value": "50.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_USE_SAFE_CLOCK_STARTUP": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_USE_SAFE_CLOCK_STARTUP": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_USE_CLOCK_SEQUENCING": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_USE_CLOCK_SEQUENCING": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_CLKOUT1_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_CLKOUT1_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_CLKOUT2_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_CLKOUT2_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
@ -397,21 +397,21 @@
|
|||||||
"C_CLKOUT6_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_CLKOUT6_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_CLKOUT7_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_CLKOUT7_SEQUENCE_NUMBER": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_MMCM_NOTES": [ { "value": "None", "resolve_type": "generated", "usage": "all" } ],
|
"C_MMCM_NOTES": [ { "value": "None", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_MMCM_BANDWIDTH": [ { "value": "OPTIMIZED", "resolve_type": "generated", "usage": "all" } ],
|
"C_MMCM_BANDWIDTH": [ { "value": "HIGH", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_MMCM_CLKFBOUT_MULT_F": [ { "value": "16.875", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_CLKFBOUT_MULT_F": [ { "value": "34.125", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_MMCM_CLKIN1_PERIOD": [ { "value": "5.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_CLKIN1_PERIOD": [ { "value": "5.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_MMCM_CLKIN2_PERIOD": [ { "value": "10.0", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_CLKIN2_PERIOD": [ { "value": "10.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT4_CASCADE": [ { "value": "FALSE", "resolve_type": "generated", "format": "bool", "usage": "all" } ],
|
"C_MMCM_CLKOUT4_CASCADE": [ { "value": "FALSE", "resolve_type": "generated", "format": "bool", "usage": "all" } ],
|
||||||
"C_MMCM_CLOCK_HOLD": [ { "value": "FALSE", "resolve_type": "generated", "format": "bool", "usage": "all" } ],
|
"C_MMCM_CLOCK_HOLD": [ { "value": "FALSE", "resolve_type": "generated", "format": "bool", "usage": "all" } ],
|
||||||
"C_MMCM_COMPENSATION": [ { "value": "ZHOLD", "resolve_type": "generated", "usage": "all" } ],
|
"C_MMCM_COMPENSATION": [ { "value": "ZHOLD", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_MMCM_DIVCLK_DIVIDE": [ { "value": "4", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_MMCM_DIVCLK_DIVIDE": [ { "value": "5", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_MMCM_REF_JITTER1": [ { "value": "0.010", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_REF_JITTER1": [ { "value": "0.010", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_MMCM_REF_JITTER2": [ { "value": "0.010", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_REF_JITTER2": [ { "value": "0.010", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_MMCM_STARTUP_WAIT": [ { "value": "FALSE", "resolve_type": "generated", "usage": "all" } ],
|
"C_MMCM_STARTUP_WAIT": [ { "value": "FALSE", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT0_DIVIDE_F": [ { "value": "6.750", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_CLKOUT0_DIVIDE_F": [ { "value": "21.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT1_DIVIDE": [ { "value": "13", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_MMCM_CLKOUT1_DIVIDE": [ { "value": "21", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT2_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_MMCM_CLKOUT2_DIVIDE": [ { "value": "11", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT3_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_MMCM_CLKOUT3_DIVIDE": [ { "value": "11", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT4_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_MMCM_CLKOUT4_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT5_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_MMCM_CLKOUT5_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT6_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_MMCM_CLKOUT6_DIVIDE": [ { "value": "1", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
@ -424,9 +424,9 @@
|
|||||||
"C_MMCM_CLKOUT6_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_CLKOUT6_DUTY_CYCLE": [ { "value": "0.500", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_MMCM_CLKFBOUT_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_CLKFBOUT_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT0_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_CLKOUT0_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT1_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_CLKOUT1_PHASE": [ { "value": "180.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT2_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_CLKOUT2_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT3_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_CLKOUT3_PHASE": [ { "value": "180.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT4_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_CLKOUT4_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT5_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_CLKOUT5_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_MMCM_CLKOUT6_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_MMCM_CLKOUT6_PHASE": [ { "value": "0.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
@ -468,16 +468,16 @@
|
|||||||
"C_CLOCK_MGR_TYPE": [ { "value": "NA", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLOCK_MGR_TYPE": [ { "value": "NA", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_OVERRIDE_MMCM": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_OVERRIDE_MMCM": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_OVERRIDE_PLL": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
"C_OVERRIDE_PLL": [ { "value": "0", "resolve_type": "generated", "format": "long", "usage": "all" } ],
|
||||||
"C_PRIMARY_PORT": [ { "value": "clk_in1", "resolve_type": "generated", "usage": "all" } ],
|
"C_PRIMARY_PORT": [ { "value": "clk_200", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_SECONDARY_PORT": [ { "value": "clk_in2", "resolve_type": "generated", "usage": "all" } ],
|
"C_SECONDARY_PORT": [ { "value": "clk_in2", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLK_OUT1_PORT": [ { "value": "clk_out1", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLK_OUT1_PORT": [ { "value": "clk_adc_65", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLK_OUT2_PORT": [ { "value": "clk_out2", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLK_OUT2_PORT": [ { "value": "clk_adc_65_180", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLK_OUT3_PORT": [ { "value": "clk_out3", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLK_OUT3_PORT": [ { "value": "clk_dac_125", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLK_OUT4_PORT": [ { "value": "clk_out4", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLK_OUT4_PORT": [ { "value": "clk_dac_125_180", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLK_OUT5_PORT": [ { "value": "clk_out5", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLK_OUT5_PORT": [ { "value": "clk_out5", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLK_OUT6_PORT": [ { "value": "clk_out6", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLK_OUT6_PORT": [ { "value": "clk_out6", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLK_OUT7_PORT": [ { "value": "clk_out7", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLK_OUT7_PORT": [ { "value": "clk_out7", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_RESET_PORT": [ { "value": "reset", "resolve_type": "generated", "usage": "all" } ],
|
"C_RESET_PORT": [ { "value": "resetn", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_LOCKED_PORT": [ { "value": "locked", "resolve_type": "generated", "usage": "all" } ],
|
"C_LOCKED_PORT": [ { "value": "locked", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKFB_IN_PORT": [ { "value": "clkfb_in", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKFB_IN_PORT": [ { "value": "clkfb_in", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKFB_IN_P_PORT": [ { "value": "clkfb_in_p", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKFB_IN_P_PORT": [ { "value": "clkfb_in_p", "resolve_type": "generated", "usage": "all" } ],
|
||||||
@ -540,12 +540,12 @@
|
|||||||
"C_FILTER_1": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
"C_FILTER_1": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_FILTER_2": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
"C_FILTER_2": [ { "value": "0000", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_DIVIDE1_AUTO": [ { "value": "1", "resolve_type": "generated", "usage": "all" } ],
|
"C_DIVIDE1_AUTO": [ { "value": "1", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_DIVIDE2_AUTO": [ { "value": "1.9259259259259258", "resolve_type": "generated", "usage": "all" } ],
|
"C_DIVIDE2_AUTO": [ { "value": "1.0", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_DIVIDE3_AUTO": [ { "value": "0.14814814814814814", "resolve_type": "generated", "usage": "all" } ],
|
"C_DIVIDE3_AUTO": [ { "value": "0.5238095238095238", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_DIVIDE4_AUTO": [ { "value": "0.14814814814814814", "resolve_type": "generated", "usage": "all" } ],
|
"C_DIVIDE4_AUTO": [ { "value": "0.5238095238095238", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_DIVIDE5_AUTO": [ { "value": "0.14814814814814814", "resolve_type": "generated", "usage": "all" } ],
|
"C_DIVIDE5_AUTO": [ { "value": "0.047619047619047616", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_DIVIDE6_AUTO": [ { "value": "0.14814814814814814", "resolve_type": "generated", "usage": "all" } ],
|
"C_DIVIDE6_AUTO": [ { "value": "0.047619047619047616", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_DIVIDE7_AUTO": [ { "value": "0.14814814814814814", "resolve_type": "generated", "usage": "all" } ],
|
"C_DIVIDE7_AUTO": [ { "value": "0.047619047619047616", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_PLLBUFGCEDIV": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
"C_PLLBUFGCEDIV": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_MMCMBUFGCEDIV": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
"C_MMCMBUFGCEDIV": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_PLLBUFGCEDIV1": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
"C_PLLBUFGCEDIV1": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||||
@ -566,66 +566,68 @@
|
|||||||
"C_CLKOUT5_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT5_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT6_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT6_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT7_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT7_MATCHED_ROUTING": [ { "value": "false", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT0_ACTUAL_FREQ": [ { "value": "125.00000", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT0_ACTUAL_FREQ": [ { "value": "65.00000", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT1_ACTUAL_FREQ": [ { "value": "64.90385", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT1_ACTUAL_FREQ": [ { "value": "65.00000", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT2_ACTUAL_FREQ": [ { "value": "100.000", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT2_ACTUAL_FREQ": [ { "value": "124.09091", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT3_ACTUAL_FREQ": [ { "value": "100.000", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT3_ACTUAL_FREQ": [ { "value": "124.09091", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT4_ACTUAL_FREQ": [ { "value": "100.000", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT4_ACTUAL_FREQ": [ { "value": "100.000", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT5_ACTUAL_FREQ": [ { "value": "100.000", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT5_ACTUAL_FREQ": [ { "value": "100.000", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_CLKOUT6_ACTUAL_FREQ": [ { "value": "100.000", "resolve_type": "generated", "usage": "all" } ],
|
"C_CLKOUT6_ACTUAL_FREQ": [ { "value": "100.000", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"C_M_MAX": [ { "value": "64.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_M_MAX": [ { "value": "64.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_M_MIN": [ { "value": "2.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_M_MIN": [ { "value": "2.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_D_MAX": [ { "value": "80.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_D_MAX": [ { "value": "93.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_D_MIN": [ { "value": "1.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_D_MIN": [ { "value": "1.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_O_MAX": [ { "value": "128.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_O_MAX": [ { "value": "128.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_O_MIN": [ { "value": "1.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_O_MIN": [ { "value": "1.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_VCO_MIN": [ { "value": "600.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
"C_VCO_MIN": [ { "value": "600.000", "resolve_type": "generated", "format": "float", "usage": "all" } ],
|
||||||
"C_VCO_MAX": [ { "value": "1200.000", "resolve_type": "generated", "format": "float", "usage": "all" } ]
|
"C_VCO_MAX": [ { "value": "1440.000", "resolve_type": "generated", "format": "float", "usage": "all" } ]
|
||||||
},
|
},
|
||||||
"project_parameters": {
|
"project_parameters": {
|
||||||
"ARCHITECTURE": [ { "value": "artix7" } ],
|
"ARCHITECTURE": [ { "value": "artix7", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"BASE_BOARD_PART": [ { "value": "" } ],
|
"BASE_BOARD_PART": [ { "value": "", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"BOARD_CONNECTIONS": [ { "value": "" } ],
|
"BOARD_CONNECTIONS": [ { "value": "", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"DEVICE": [ { "value": "xc7a35t" } ],
|
"DEVICE": [ { "value": "xc7a100t", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"PACKAGE": [ { "value": "fgg484" } ],
|
"PACKAGE": [ { "value": "fgg484", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"PREFHDL": [ { "value": "VERILOG" } ],
|
"PREFHDL": [ { "value": "VERILOG", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"SILICON_REVISION": [ { "value": "" } ],
|
"SILICON_REVISION": [ { "value": "", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"SIMULATOR_LANGUAGE": [ { "value": "MIXED" } ],
|
"SIMULATOR_LANGUAGE": [ { "value": "MIXED", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"SPEEDGRADE": [ { "value": "-1" } ],
|
"SPEEDGRADE": [ { "value": "-2", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"STATIC_POWER": [ { "value": "" } ],
|
"STATIC_POWER": [ { "value": "", "resolve_type": "generated", "usage": "all" } ],
|
||||||
"TEMPERATURE_GRADE": [ { "value": "" } ]
|
"TEMPERATURE_GRADE": [ { "value": "", "resolve_type": "generated", "usage": "all" } ]
|
||||||
},
|
},
|
||||||
"runtime_parameters": {
|
"runtime_parameters": {
|
||||||
"IPCONTEXT": [ { "value": "IP_Flow" } ],
|
"IPCONTEXT": [ { "value": "IP_Flow" } ],
|
||||||
"IPREVISION": [ { "value": "16" } ],
|
"IPREVISION": [ { "value": "17" } ],
|
||||||
"MANAGED": [ { "value": "TRUE" } ],
|
"MANAGED": [ { "value": "TRUE" } ],
|
||||||
"OUTPUTDIR": [ { "value": "../../../../eth_generator_top.gen/sources_1/ip/clk_wiz_ctrl_inst" } ],
|
"OUTPUTDIR": [ { "value": "../../../../reflectometer_top.gen/sources_1/ip/clk_wiz_ctrl_inst" } ],
|
||||||
"SELECTEDSIMMODEL": [ { "value": "" } ],
|
"SELECTEDSIMMODEL": [ { "value": "" } ],
|
||||||
"SHAREDDIR": [ { "value": "." } ],
|
"SHAREDDIR": [ { "value": "." } ],
|
||||||
"SWVERSION": [ { "value": "2025.1" } ],
|
"SWVERSION": [ { "value": "2025.2" } ],
|
||||||
"SYNTHESISFLOW": [ { "value": "OUT_OF_CONTEXT" } ]
|
"SYNTHESISFLOW": [ { "value": "OUT_OF_CONTEXT" } ]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"boundary": {
|
"boundary": {
|
||||||
"ports": {
|
"ports": {
|
||||||
"reset": [ { "direction": "in", "driver_value": "0" } ],
|
"resetn": [ { "direction": "in", "driver_value": "0" } ],
|
||||||
"clk_in1": [ { "direction": "in" } ],
|
"clk_200": [ { "direction": "in" } ],
|
||||||
"clk_out1": [ { "direction": "out" } ],
|
"clk_adc_65": [ { "direction": "out" } ],
|
||||||
"clk_out2": [ { "direction": "out" } ],
|
"clk_adc_65_180": [ { "direction": "out" } ],
|
||||||
|
"clk_dac_125": [ { "direction": "out" } ],
|
||||||
|
"clk_dac_125_180": [ { "direction": "out" } ],
|
||||||
"locked": [ { "direction": "out" } ]
|
"locked": [ { "direction": "out" } ]
|
||||||
},
|
},
|
||||||
"interfaces": {
|
"interfaces": {
|
||||||
"reset": {
|
"resetn": {
|
||||||
"vlnv": "xilinx.com:signal:reset:1.0",
|
"vlnv": "xilinx.com:signal:reset:1.0",
|
||||||
"abstraction_type": "xilinx.com:signal:reset_rtl:1.0",
|
"abstraction_type": "xilinx.com:signal:reset_rtl:1.0",
|
||||||
"mode": "slave",
|
"mode": "slave",
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"POLARITY": [ { "value": "ACTIVE_HIGH", "value_src": "constant", "usage": "all" } ],
|
"POLARITY": [ { "value": "ACTIVE_LOW", "value_src": "constant", "usage": "all" } ],
|
||||||
"BOARD.ASSOCIATED_PARAM": [ { "value": "RESET_BOARD_INTERFACE", "value_src": "constant", "usage": "all" } ],
|
"BOARD.ASSOCIATED_PARAM": [ { "value": "RESET_BOARD_INTERFACE", "value_src": "constant", "usage": "all" } ],
|
||||||
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
|
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
|
||||||
},
|
},
|
||||||
"port_maps": {
|
"port_maps": {
|
||||||
"RST": [ { "physical_name": "reset" } ]
|
"RST": [ { "physical_name": "resetn" } ]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"clock_CLK_IN1": {
|
"clock_CLK_IN1": {
|
||||||
@ -644,7 +646,7 @@
|
|||||||
"BOARD.ASSOCIATED_PARAM": [ { "value": "CLK_IN1_BOARD_INTERFACE", "usage": "all", "is_static_object": false } ]
|
"BOARD.ASSOCIATED_PARAM": [ { "value": "CLK_IN1_BOARD_INTERFACE", "usage": "all", "is_static_object": false } ]
|
||||||
},
|
},
|
||||||
"port_maps": {
|
"port_maps": {
|
||||||
"CLK_IN1": [ { "physical_name": "clk_in1" } ]
|
"CLK_IN1": [ { "physical_name": "clk_200" } ]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"clock_CLK_OUT1": {
|
"clock_CLK_OUT1": {
|
||||||
@ -662,7 +664,7 @@
|
|||||||
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
|
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
|
||||||
},
|
},
|
||||||
"port_maps": {
|
"port_maps": {
|
||||||
"CLK_OUT1": [ { "physical_name": "clk_out1" } ]
|
"CLK_OUT1": [ { "physical_name": "clk_adc_65" } ]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"clock_CLK_OUT2": {
|
"clock_CLK_OUT2": {
|
||||||
@ -680,10 +682,47 @@
|
|||||||
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
|
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
|
||||||
},
|
},
|
||||||
"port_maps": {
|
"port_maps": {
|
||||||
"CLK_OUT2": [ { "physical_name": "clk_out2" } ]
|
"CLK_OUT2": [ { "physical_name": "clk_adc_65_180" } ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"clock_CLK_OUT3": {
|
||||||
|
"vlnv": "xilinx.com:signal:clock:1.0",
|
||||||
|
"abstraction_type": "xilinx.com:signal:clock_rtl:1.0",
|
||||||
|
"mode": "master",
|
||||||
|
"parameters": {
|
||||||
|
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||||
|
"FREQ_TOLERANCE_HZ": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||||
|
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
|
||||||
|
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||||
|
"ASSOCIATED_BUSIF": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||||
|
"ASSOCIATED_PORT": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||||
|
"ASSOCIATED_RESET": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||||
|
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
|
||||||
|
},
|
||||||
|
"port_maps": {
|
||||||
|
"CLK_OUT3": [ { "physical_name": "clk_dac_125" } ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"clock_CLK_OUT4": {
|
||||||
|
"vlnv": "xilinx.com:signal:clock:1.0",
|
||||||
|
"abstraction_type": "xilinx.com:signal:clock_rtl:1.0",
|
||||||
|
"mode": "master",
|
||||||
|
"parameters": {
|
||||||
|
"FREQ_HZ": [ { "value": "100000000", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||||
|
"FREQ_TOLERANCE_HZ": [ { "value": "0", "resolve_type": "generated", "format": "long", "is_ips_inferred": true, "is_static_object": false } ],
|
||||||
|
"PHASE": [ { "value": "0.0", "resolve_type": "generated", "format": "float", "is_ips_inferred": true, "is_static_object": false } ],
|
||||||
|
"CLK_DOMAIN": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||||
|
"ASSOCIATED_BUSIF": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||||
|
"ASSOCIATED_PORT": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||||
|
"ASSOCIATED_RESET": [ { "value": "", "resolve_type": "generated", "is_ips_inferred": true, "is_static_object": false } ],
|
||||||
|
"INSERT_VIP": [ { "value": "0", "resolve_type": "user", "format": "long", "usage": "simulation.rtl", "is_ips_inferred": true, "is_static_object": false } ]
|
||||||
|
},
|
||||||
|
"port_maps": {
|
||||||
|
"CLK_OUT4": [ { "physical_name": "clk_dac_125_180" } ]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"checksum": "3ec15bbf"
|
||||||
}
|
}
|
||||||
@ -1,128 +1,111 @@
|
|||||||
`timescale 1 ns / 1 ns
|
`timescale 1 ns / 1 ns
|
||||||
|
|
||||||
|
`include "interfaces.svh"
|
||||||
|
|
||||||
module reflectometer_top #(
|
module reflectometer_top #(
|
||||||
parameter int unsigned DAC_DATA_WIDTH = 14,
|
parameter int unsigned DAC_DATA_WIDTH = 14,
|
||||||
parameter int unsigned ADC_DATA_WIDTH = 12,
|
parameter int unsigned ADC_DATA_WIDTH = 12,
|
||||||
parameter PACK_FACTOR = 1,
|
parameter int unsigned PACK_FACTOR = 1,
|
||||||
parameter PROCESS_MODE = 0,
|
parameter int unsigned PROCESS_MODE = 0,
|
||||||
parameter ZERO_LEVEL = 8192,
|
parameter int unsigned ZERO_LEVEL = 8192,
|
||||||
parameter ACCUM_WIDTH = 32,
|
parameter int unsigned ACCUM_WIDTH = 32,
|
||||||
parameter N_MAX = 4096,
|
parameter int unsigned N_MAX = 4096,
|
||||||
parameter WINDOW_SIZE = 65,
|
parameter int unsigned WINDOW_SIZE = 65,
|
||||||
parameter 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_axis_accumulator, // GMII PHY RX clock
|
||||||
|
axis_if.master axis_accumulator,
|
||||||
|
|
||||||
input gmii_rx_clk,
|
// Control AXI-S bus
|
||||||
input gmii_tx_clk,
|
input wire clk_axis_control, // GMII PHY TX clock
|
||||||
|
axis_if.slave axis_control,
|
||||||
|
|
||||||
(* 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 wire dac_clk_o,
|
||||||
output wire p2_clk,
|
output wire [DAC_DATA_WIDTH-1:0] dac_data,
|
||||||
(* MARK_DEBUG="true" *) output wire [DAC_DATA_WIDTH-1:0] p2_data,
|
output wire dac_wrt,
|
||||||
(* MARK_DEBUG="true" *) output wire p2_wrt,
|
|
||||||
|
|
||||||
// ADC
|
// ADC
|
||||||
output ch2_clk,
|
output wire adc_clk_o,
|
||||||
(* MARK_DEBUG="true" *) input [ADC_DATA_WIDTH-1:0] ch2_data,
|
input wire [ADC_DATA_WIDTH-1:0] adc_data,
|
||||||
input ch2_otr
|
input wire adc_otr
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// IDELAYCTRL
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
(* IODELAY_GROUP = "rgmii_idelay_group" *)
|
|
||||||
IDELAYCTRL IDELAYCTRL_inst (
|
|
||||||
.RDY (),
|
|
||||||
.REFCLK (sys_clk),
|
|
||||||
.RST (1'b0)
|
|
||||||
);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// 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 clk_wiz_ctrl_inst (
|
clk_wiz_ctrl_inst clk_wiz_inst
|
||||||
.clk_in1 (sys_clk),
|
(
|
||||||
.reset (~rst_n),
|
// Clock in ports
|
||||||
.clk_out1 (dac_clk), // 130 MHz
|
.clk_200(clk_in),
|
||||||
.clk_out2 (adc_clk), // 65 MHz
|
// Clock out ports
|
||||||
.locked (clk_wiz_locked)
|
.clk_adc_65(clk_sampler),
|
||||||
|
.clk_adc_65_180(adc_clk_o),
|
||||||
|
.clk_dac_125(clk_generator),
|
||||||
|
.clk_dac_125_180(dac_clk_o),
|
||||||
|
// Status and control signals
|
||||||
|
.resetn(rst_n),
|
||||||
|
.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
|
||||||
// Use both external reset and clk_wiz lock
|
// Use both external reset and clk_wiz lock
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
wire ctrl_rst_n = rst_n & clk_wiz_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_axis_control),
|
||||||
.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 (axis_control.tdata),
|
||||||
.s_axis_tvalid (m_axis_rx_tvalid),
|
.s_axis_tvalid (axis_control.tvalid),
|
||||||
.s_axis_tready (m_axis_rx_tready),
|
.s_axis_tready (axis_control.tready),
|
||||||
.s_axis_tlast (m_axis_rx_tlast),
|
.s_axis_tlast (axis_control.tlast),
|
||||||
|
|
||||||
.finish (finish),
|
.finish (finish),
|
||||||
|
|
||||||
@ -141,180 +124,122 @@ 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
|
(* ASYNC_REG = "TRUE" *) logic [2:0] stretch; // 125/65~=2. Чтобы поймать единичный импульс, растянем его во времени
|
||||||
if (adc_rst) begin
|
(* ASYNC_REG = "TRUE" *) 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
|
(* ASYNC_REG = "TRUE" *) 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)
|
||||||
)
|
) sampler_dut (
|
||||||
sampler_dut
|
.clk_in(clk_sampler),
|
||||||
(
|
.rst(adc_rst),
|
||||||
.clk_in(adc_clk),
|
.data_in(adc_data),
|
||||||
.rst(adc_rst),
|
.out_of_range(adc_otr),
|
||||||
.data_in(ch2_data),
|
.m_axis_tdata(sampler_m_axis_tdata),
|
||||||
.out_of_range(ch2_otr),
|
.m_axis_tvalid(sampler_m_axis_tvalid),
|
||||||
.m_axis_tdata(accum_m_axis_tdata),
|
|
||||||
.m_axis_tvalid(acum_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_axis_accumulator),
|
||||||
.m_axis_tdata(s_axis_tx_tdata),
|
.m_axis_tdata(axis_accumulator.tdata),
|
||||||
.m_axis_tvalid(s_axis_tx_tvalid),
|
.m_axis_tvalid(axis_accumulator.tvalid),
|
||||||
.m_axis_tready(s_axis_tx_tready),
|
.m_axis_tready(axis_accumulator.tready),
|
||||||
.m_axis_tlast(s_axis_tx_tlast),
|
.m_axis_tlast(axis_accumulator.tlast),
|
||||||
|
|
||||||
.finish(finish)
|
.finish(finish)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// Simple LED status
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
assign led[0] = clk_wiz_locked;
|
|
||||||
assign led[1] = m_axis_rx_tvalid;
|
|
||||||
assign led[2] = dac_start;
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
285
designs/reflectometer_base/reflectometer_tb.sv
Normal file
285
designs/reflectometer_base/reflectometer_tb.sv
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
|
`include "interfaces.svh"
|
||||||
|
|
||||||
|
module reflectometer_tb;
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Параметры
|
||||||
|
//------------------------------------------------------------
|
||||||
|
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 = 1; // 0 - uint, 1 - int
|
||||||
|
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 ZERO_LEVEL = LOGIC_ZERO_LEVEL; // "logic" VS "voltage"
|
||||||
|
|
||||||
|
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;
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Управление и конфиг
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Входы
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Выходы
|
||||||
|
//------------------------------------------------------------
|
||||||
|
wire mmcm_locked;
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Внутренние сигналы тестбенча
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// AXI-S интерфейс для управления
|
||||||
|
axis_if axis_control_if (
|
||||||
|
.clk(clk_eth_phy),
|
||||||
|
.rst_n(rst_n)
|
||||||
|
);
|
||||||
|
// AXI-S интерфейс для данных
|
||||||
|
axis_if axis_accumulator_if (
|
||||||
|
.clk(clk_eth_phy),
|
||||||
|
.rst_n(rst_n)
|
||||||
|
);
|
||||||
|
// DAC интерфейс
|
||||||
|
wire clk_dac;
|
||||||
|
wire dac_wrt;
|
||||||
|
wire [DAC_DATA_WIDTH-1:0] dac_data;
|
||||||
|
// ADC интерфейс
|
||||||
|
wire clk_adc;
|
||||||
|
wire adc_otr;
|
||||||
|
wire [ADC_DATA_WIDTH-1:0] adc_data;
|
||||||
|
// Интерфейс хендшейка с MAC-PHY
|
||||||
|
wire send_request;
|
||||||
|
logic request_ready;
|
||||||
|
// Сигналы ЦАП и АЦП
|
||||||
|
real signal_voltage;
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Virtual DAC
|
||||||
|
//------------------------------------------------------------
|
||||||
|
virtual_dac_model #( // default voltage range is +/- 5V
|
||||||
|
.DAC_DATA_WIDTH(DAC_DATA_WIDTH)
|
||||||
|
// ,.VOLTAGE_GAIN(2)
|
||||||
|
) virtual_dac (
|
||||||
|
.clk_i(clk_dac),
|
||||||
|
.wrt_i(dac_wrt),
|
||||||
|
.data_i(dac_data),
|
||||||
|
.voltage_o(signal_voltage)
|
||||||
|
);
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Virtual ADC
|
||||||
|
//------------------------------------------------------------
|
||||||
|
virtual_adc_model #( // default voltage range is +/- 5V
|
||||||
|
.ADC_DATA_WIDTH(ADC_DATA_WIDTH)
|
||||||
|
) virtual_adc (
|
||||||
|
.clk_i(clk_adc),
|
||||||
|
.voltage_i(signal_voltage),
|
||||||
|
.otr_o(adc_otr),
|
||||||
|
.data_o(adc_data)
|
||||||
|
);
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Statistics monitor
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Config handler
|
||||||
|
//------------------------------------------------------------
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// DUT
|
||||||
|
//------------------------------------------------------------
|
||||||
|
reflectometer_top #(
|
||||||
|
.DAC_DATA_WIDTH(DAC_DATA_WIDTH),
|
||||||
|
.ADC_DATA_WIDTH(ADC_DATA_WIDTH),
|
||||||
|
.PACK_FACTOR(PACK_FACTOR),
|
||||||
|
.PROCESS_MODE(PROCESS_MODE),
|
||||||
|
.ZERO_LEVEL(ZERO_LEVEL),
|
||||||
|
.ACCUM_WIDTH(ACCUM_WIDTH),
|
||||||
|
.N_MAX(N_MAX),
|
||||||
|
.WINDOW_SIZE(WINDOW_SIZE),
|
||||||
|
.PACKET_SIZE(PACKET_SIZE)
|
||||||
|
) DUT (
|
||||||
|
.clk_in(clk_ref),
|
||||||
|
.rst_n(rst_n),
|
||||||
|
.locked(mmcm_locked),
|
||||||
|
|
||||||
|
// Accumulator AXI-S bus
|
||||||
|
.clk_axis_accumulator(clk_eth_phy), // GMII PHY RX clock
|
||||||
|
.axis_accumulator(axis_accumulator_if.master),
|
||||||
|
|
||||||
|
// Control AXI-S bus
|
||||||
|
.clk_axis_control(clk_eth_phy), // GMII PHY TX clock
|
||||||
|
.axis_control(axis_control_if.slave),
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
);
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Тактовые сигналы
|
||||||
|
//------------------------------------------------------------
|
||||||
|
initial begin
|
||||||
|
forever #(CLK_REF_PERIOD/2) clk_ref = ~clk_ref;
|
||||||
|
end
|
||||||
|
initial begin
|
||||||
|
forever #(CLK_ETH_PHY_PERIOD/2) clk_eth_phy = ~clk_eth_phy;
|
||||||
|
end
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Таски для тестирования
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// Таски работы с AXI-Stream
|
||||||
|
task automatic dut_soft_reset(virtual axis_if#(8).tb vif);
|
||||||
|
logic [7:0] tx_packet[];
|
||||||
|
tx_packet = '{8'h0f};
|
||||||
|
vif.master_send(tx_packet);
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task automatic dut_start(virtual axis_if#(8).tb vif);
|
||||||
|
logic [7:0] tx_packet[];
|
||||||
|
tx_packet = '{8'hf0};
|
||||||
|
vif.master_send(tx_packet);
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task automatic dut_send_system_config(
|
||||||
|
virtual axis_if#(8).tb vif,
|
||||||
|
input logic [31:0] pulse_width,
|
||||||
|
input logic [31:0] pulse_period,
|
||||||
|
input logic [15:0] pulse_num,
|
||||||
|
input logic [13:0] pulse_height, // achtung! p_height strictly must have 14 bits of width
|
||||||
|
input logic [31:0] pulse_period_adc
|
||||||
|
);
|
||||||
|
// Создаем временный фиксированный массив и упаковываем всё одной строкой
|
||||||
|
logic [7:0] tx_packet[];
|
||||||
|
|
||||||
|
tx_packet = '{
|
||||||
|
8'h88, // Команда
|
||||||
|
pulse_width[7:0], pulse_width[15:8], pulse_width[23:16], pulse_width[31:24],
|
||||||
|
pulse_period[7:0], pulse_period[15:8], pulse_period[23:16], pulse_period[31:24],
|
||||||
|
pulse_num[7:0], pulse_num[15:8], pulse_height[7:0], 8'({2'b00, pulse_height[13:8]}),
|
||||||
|
pulse_period_adc[7:0], pulse_period_adc[15:8], pulse_period_adc[23:16], pulse_period_adc[31:24]
|
||||||
|
};
|
||||||
|
|
||||||
|
vif.master_send(tx_packet);
|
||||||
|
endtask
|
||||||
|
|
||||||
|
// Таски сбора и обработки статистики
|
||||||
|
task automatic dut_read_output(
|
||||||
|
virtual axis_if#(8).tb vif,
|
||||||
|
input int sample_num,
|
||||||
|
input bit randomize_recv_delays,
|
||||||
|
output int output_data[]
|
||||||
|
);
|
||||||
|
logic [7:0] rx_packet[];
|
||||||
|
logic [ACCUM_WIDTH-1:0] data_packet[];
|
||||||
|
int packet_num = $ceil(real'(sample_num / WINDOW_SIZE) / real'(PACKET_SIZE));
|
||||||
|
int numbers_per_packet = PACKET_SIZE/(ACCUM_WIDTH/8);
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
if (sample_num % WINDOW_SIZE) begin
|
||||||
|
$display("[TB] -dut_read_output- Error, sample_num must be multiple of WINDOW_SIZE: %0d %% %0d = %0d", sample_num, WINDOW_SIZE, sample_num % WINDOW_SIZE);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
|
||||||
|
data_packet = new[numbers_per_packet];
|
||||||
|
output_data = new[numbers_per_packet * packet_num];
|
||||||
|
// count send_request posedge todo
|
||||||
|
// timeout todo
|
||||||
|
|
||||||
|
// recv loop
|
||||||
|
for (int i = 0; i < packet_num; i++) begin
|
||||||
|
// randomize_recv_delays todo
|
||||||
|
request_ready = 1;
|
||||||
|
vif.slave_recv(rx_packet);
|
||||||
|
request_ready = 0;
|
||||||
|
|
||||||
|
// unpack values
|
||||||
|
data_packet = {<< byte {rx_packet}};
|
||||||
|
data_packet = {<< ACCUM_WIDTH {data_packet}};
|
||||||
|
|
||||||
|
// copy and convert values
|
||||||
|
for (int j = 0; j < data_packet.size(); j++) begin
|
||||||
|
output_data[i * data_packet.size() + j] = int'(data_packet[j]);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// wait for dut.finish posedge todo
|
||||||
|
// timeout todo
|
||||||
|
|
||||||
|
// error handling todo
|
||||||
|
endtask
|
||||||
|
|
||||||
|
//------------------------------------------------------------
|
||||||
|
// ОСНОВНОЙ ПРОЦЕСС ТЕСТИРОВАНИЯ
|
||||||
|
//------------------------------------------------------------
|
||||||
|
initial begin
|
||||||
|
int output_data[];
|
||||||
|
|
||||||
|
automatic virtual axis_if.tb control_vif = axis_control_if.tb;
|
||||||
|
automatic virtual axis_if.tb accumulator_vif = axis_accumulator_if.tb;
|
||||||
|
|
||||||
|
$display("[TB] DUT initializaton");
|
||||||
|
// Инициализация
|
||||||
|
request_ready = 0;
|
||||||
|
rst_n = 0;
|
||||||
|
#100;
|
||||||
|
rst_n = 1;
|
||||||
|
wait(mmcm_locked === 1'b1);
|
||||||
|
#150;
|
||||||
|
$display("[TB] MMCM locked");
|
||||||
|
|
||||||
|
dut_soft_reset(control_vif);
|
||||||
|
#100;
|
||||||
|
|
||||||
|
// Тесты
|
||||||
|
$display("[TB] Tests start");
|
||||||
|
dut_send_system_config(
|
||||||
|
.vif(control_vif),
|
||||||
|
.pulse_width(32'd123),
|
||||||
|
.pulse_period(32'd5000),
|
||||||
|
.pulse_num(16'd1),
|
||||||
|
.pulse_height(14'd15000), // 0V
|
||||||
|
.pulse_period_adc(32'd2600)
|
||||||
|
);
|
||||||
|
#100;
|
||||||
|
dut_start(control_vif);
|
||||||
|
|
||||||
|
dut_read_output(
|
||||||
|
.vif(accumulator_vif),
|
||||||
|
.sample_num(2600),
|
||||||
|
.randomize_recv_delays(0),
|
||||||
|
.output_data(output_data)
|
||||||
|
);
|
||||||
|
|
||||||
|
$display("Received %0d numbers", output_data.size());
|
||||||
|
for (int i = 0; i < output_data.size(); i++) begin
|
||||||
|
$write("%0d ", output_data[i]);
|
||||||
|
end
|
||||||
|
$display("");
|
||||||
|
|
||||||
|
$display("[TB] ALL PASSED");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
117
designs/reflectometer_base/reflectometer_tb_behav.wcfg
Normal file
117
designs/reflectometer_base/reflectometer_tb_behav.wcfg
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<wave_config>
|
||||||
|
<wave_state>
|
||||||
|
</wave_state>
|
||||||
|
<db_ref_list>
|
||||||
|
<db_ref path="reflectometer_tb_behav.wdb" id="1">
|
||||||
|
<top_modules>
|
||||||
|
<top_module name="glbl" />
|
||||||
|
<top_module name="reflectometer_tb" />
|
||||||
|
</top_modules>
|
||||||
|
</db_ref>
|
||||||
|
</db_ref_list>
|
||||||
|
<zoom_setting>
|
||||||
|
<ZoomStartTime time="0.000 ns"></ZoomStartTime>
|
||||||
|
<ZoomEndTime time="1,506.001 ns"></ZoomEndTime>
|
||||||
|
<Cursor1Time time="1,000.000 ns"></Cursor1Time>
|
||||||
|
</zoom_setting>
|
||||||
|
<column_width_setting>
|
||||||
|
<NameColumnWidth column_width="196"></NameColumnWidth>
|
||||||
|
<ValueColumnWidth column_width="76"></ValueColumnWidth>
|
||||||
|
</column_width_setting>
|
||||||
|
<WVObjectSize size="7" />
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/rst_n">
|
||||||
|
<obj_property name="ElementShortName">rst_n</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">rst_n</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/mmcm_locked">
|
||||||
|
<obj_property name="ElementShortName">mmcm_locked</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">mmcm_locked</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="group" fp_name="group28">
|
||||||
|
<obj_property name="label">Signal</obj_property>
|
||||||
|
<obj_property name="DisplayName">label</obj_property>
|
||||||
|
<wvobject type="array" fp_name="/reflectometer_tb/dac_data">
|
||||||
|
<obj_property name="ElementShortName">dac_data[13:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">dac_data[13:0]</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="other" fp_name="/reflectometer_tb/signal_voltage">
|
||||||
|
<obj_property name="ElementShortName">signal_voltage</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">signal_voltage</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="array" fp_name="/reflectometer_tb/adc_data">
|
||||||
|
<obj_property name="ElementShortName">adc_data[11:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">adc_data[11:0]</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/adc_otr">
|
||||||
|
<obj_property name="ElementShortName">adc_otr</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">adc_otr</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/send_request">
|
||||||
|
<obj_property name="ElementShortName">send_request</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">send_request</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/request_ready">
|
||||||
|
<obj_property name="ElementShortName">request_ready</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">request_ready</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="group" fp_name="group51">
|
||||||
|
<obj_property name="label">Controller</obj_property>
|
||||||
|
<obj_property name="DisplayName">label</obj_property>
|
||||||
|
<obj_property name="isExpanded"></obj_property>
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/axis_control_if/clk">
|
||||||
|
<obj_property name="ElementShortName">clk</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">clk</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/axis_control_if/rst_n">
|
||||||
|
<obj_property name="ElementShortName">rst_n</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">rst_n</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="array" fp_name="/reflectometer_tb/axis_control_if/tdata">
|
||||||
|
<obj_property name="ElementShortName">tdata[7:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">tdata[7:0]</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/axis_control_if/tvalid">
|
||||||
|
<obj_property name="ElementShortName">tvalid</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">tvalid</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/axis_control_if/tlast">
|
||||||
|
<obj_property name="ElementShortName">tlast</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">tlast</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/axis_control_if/tready">
|
||||||
|
<obj_property name="ElementShortName">tready</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">tready</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="group" fp_name="group52">
|
||||||
|
<obj_property name="label">Accumulator</obj_property>
|
||||||
|
<obj_property name="DisplayName">label</obj_property>
|
||||||
|
<obj_property name="isExpanded"></obj_property>
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/axis_accumulator_if/clk">
|
||||||
|
<obj_property name="ElementShortName">clk</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">clk</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/axis_accumulator_if/rst_n">
|
||||||
|
<obj_property name="ElementShortName">rst_n</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">rst_n</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="array" fp_name="/reflectometer_tb/axis_accumulator_if/tdata">
|
||||||
|
<obj_property name="ElementShortName">tdata[7:0]</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">tdata[7:0]</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/axis_accumulator_if/tvalid">
|
||||||
|
<obj_property name="ElementShortName">tvalid</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">tvalid</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/axis_accumulator_if/tlast">
|
||||||
|
<obj_property name="ElementShortName">tlast</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">tlast</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
<wvobject type="logic" fp_name="/reflectometer_tb/axis_accumulator_if/tready">
|
||||||
|
<obj_property name="ElementShortName">tready</obj_property>
|
||||||
|
<obj_property name="ObjectShortName">tready</obj_property>
|
||||||
|
</wvobject>
|
||||||
|
</wvobject>
|
||||||
|
</wave_config>
|
||||||
@ -1,7 +1,7 @@
|
|||||||
# Генератор
|
# Генератор
|
||||||
|
|
||||||
Модуль выполняет задачу формирования последовательности импульсов заданной амплитуды, длительности и периода.
|
Модуль выполняет задачу формирования последовательности импульсов заданной амплитуды, длительности и периода.
|
||||||
Дополнительно реализован механизм синхронизации с модулем сэмплера через сигналы `sample_req` и `sample_done`, позволяющий запускать сбор данных для каждого импульса и ожидать подтверждения завершения выборки перед переходом к следующему импульсу.
|
Дополнительно реализован механизм синхронизации с модулем сэмплера через сигналы `request` и `done`, позволяющий запускать сбор данных для каждого импульса и ожидать подтверждения завершения выборки перед переходом к следующему импульсу.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
## Список входных портов
|
## Список входных портов
|
||||||
|
|
||||||
### clk_in
|
### clk_dac
|
||||||
Сигнал тактирования модуля.
|
Сигнал тактирования модуля.
|
||||||
|
|
||||||
### rst
|
### rst
|
||||||
@ -47,25 +47,25 @@
|
|||||||
### [15:0] pulse_num
|
### [15:0] pulse_num
|
||||||
Количество импульсов, которое необходимо сгенерировать.
|
Количество импульсов, которое необходимо сгенерировать.
|
||||||
|
|
||||||
### sample_done
|
### request
|
||||||
Сигнал подтверждения от сэмплера о завершении выборки данных для текущего импульса.
|
Сигнал запроса на синхронизацию от сэмплера для текущего импульса.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Список выходных портов
|
## Список выходных портов
|
||||||
|
|
||||||
pulse
|
### dac_wrt
|
||||||
Выходной сигнал разрешения записи сигнала
|
Выходной сигнал разрешения записи сигнала
|
||||||
|
|
||||||
[DATA_WIDTH-1:0] pulse_height_out
|
### [DATA_WIDTH-1:0] dac_out
|
||||||
Выходное значение амплитуды сигнала.
|
Выходное значение амплитуды сигнала.
|
||||||
|
|
||||||
Во время активной части импульса равно `pulse_height`, вне импульса — `ZERO_LEVEL`.
|
Во время активной части импульса равно `pulse_height`, вне импульса — `ZERO_LEVEL`.
|
||||||
|
|
||||||
sample_req
|
### done
|
||||||
Сигнал запроса на запуск выборки в модуле сэмплера.
|
Сигнал запроса на запуск синхронизации с сэмплером для текущего импульса.
|
||||||
|
|
||||||
Поднимается в начале каждого нового импульса и снимается после получения `sample_done`.
|
Поднимается в начале каждого нового импульса и снимается после получения `request`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -74,11 +74,11 @@ sample_req
|
|||||||
После прихода сигнала `start` модуль:
|
После прихода сигнала `start` модуль:
|
||||||
|
|
||||||
- фиксирует входные параметры генерации
|
- фиксирует входные параметры генерации
|
||||||
- сбрасывает внутренние счетчики
|
|
||||||
- поднимает `enable = 1`
|
- поднимает `enable = 1`
|
||||||
- формирует первый `sample_req`
|
- выполняет `pulse_num` циклов работы
|
||||||
|
- - типичный цикл состоит в ожидании синхронизации (`synced`), после чего запуск генерации импульса
|
||||||
|
|
||||||
После этого начинается последовательная генерация импульсов.
|
Синхронизация представляет из себя простое рукопожатие с внешним модулем, имеющим сигналы `request`/`done` работающими в соответствии с этими сигналами генератора. Один из модулей, входит в ожидание и ставит на свой done активный уровень, после чего ждет, пока второй, запаздывающий модуль не войдет в свой режим ожидания, и не выставит для своего done активный уровень. Для каждого из модулей, на следующий такт после выставления активного уровня, производится проверка своего request. Так, при получении активного request (иными словами активного done от внешнего модуля), модуль незамедлительно опускает уровень своего done и начинает работать. Done подымается до активного уровня хотя-бы на один такт работы соответствующего модуля.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@ -1,105 +1,95 @@
|
|||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
|
|
||||||
module generator
|
module generator
|
||||||
#(
|
#(
|
||||||
parameter DATA_WIDTH = 14,
|
parameter DATA_WIDTH = 14,
|
||||||
parameter ZERO_LEVEL = 8192 // 8192 or 0
|
parameter ZERO_LEVEL = 8192 // 8192 or 0
|
||||||
)
|
)
|
||||||
(
|
(
|
||||||
input clk_in,
|
input clk_dac,
|
||||||
input rst,
|
input rst,
|
||||||
input start,
|
input start,
|
||||||
input [31:0] pulse_width,
|
input [31:0] pulse_width,
|
||||||
input [31:0] pulse_period,
|
input [31:0] pulse_period,
|
||||||
input [DATA_WIDTH-1:0] pulse_height,
|
input [DATA_WIDTH-1:0] pulse_height,
|
||||||
input [15:0] pulse_num,
|
input [15:0] pulse_num,
|
||||||
input sample_done,
|
input request,
|
||||||
|
|
||||||
output pulse,
|
output logic [DATA_WIDTH-1:0] dac_out,
|
||||||
output[DATA_WIDTH-1:0] pulse_height_out,
|
output logic done
|
||||||
output logic sample_req
|
);
|
||||||
|
logic [DATA_WIDTH-1:0] pulse_height_reg;
|
||||||
|
logic [31:0] pulse_width_reg, pulse_period_reg;
|
||||||
|
logic [15:0] pulse_num_reg;
|
||||||
|
|
||||||
);
|
logic [15:0] cnt_pulse_num;
|
||||||
|
logic [31:0] cnt_pulse_period;
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) logic [DATA_WIDTH-1:0] pulse_height_reg, pulse_height_out_reg;
|
logic enable, synced;
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) logic [31:0] pulse_width_reg, pulse_period_reg;
|
initial begin
|
||||||
(* MARK_DEBUG="true" *) logic [15:0] pulse_num_reg;
|
cnt_pulse_period = '0;
|
||||||
|
cnt_pulse_num = '0;
|
||||||
|
enable = 0;
|
||||||
|
synced = 0;
|
||||||
|
dac_out = ZERO_LEVEL;
|
||||||
|
end
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) logic enable;
|
always @(posedge clk_dac) begin
|
||||||
(* MARK_DEBUG="true" *) logic [15:0] cnt_pulse_num;
|
|
||||||
(* MARK_DEBUG="true" *) logic [31:0] cnt_period;
|
|
||||||
|
|
||||||
|
|
||||||
always @(posedge clk_in) begin
|
|
||||||
if (rst) begin
|
if (rst) begin
|
||||||
pulse_height_reg <= ZERO_LEVEL;
|
pulse_height_reg <= ZERO_LEVEL;
|
||||||
pulse_height_out_reg <= ZERO_LEVEL;
|
pulse_width_reg <= 0;
|
||||||
pulse_width_reg <= '0;
|
pulse_period_reg <= 0;
|
||||||
pulse_period_reg <= '0;
|
pulse_num_reg <= 0;
|
||||||
pulse_num_reg <= '0;
|
cnt_pulse_num <= 0;
|
||||||
enable <= 0;
|
cnt_pulse_period <= 0;
|
||||||
cnt_pulse_num <= '0;
|
dac_out <= ZERO_LEVEL;
|
||||||
cnt_period <= '0;
|
done <= 0;
|
||||||
sample_req <= 0;
|
enable <= 0;
|
||||||
end else begin
|
synced <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
// wait start for updating registers
|
||||||
if (start & !enable) begin
|
if (start & !enable) begin
|
||||||
enable <= 1'b1;
|
enable <= 1;
|
||||||
cnt_pulse_num <= '0;
|
pulse_width_reg <= pulse_width;
|
||||||
cnt_period <= '0;
|
pulse_period_reg <= pulse_period;
|
||||||
|
pulse_num_reg <= pulse_num;
|
||||||
sample_req <= 1;
|
pulse_height_reg <= pulse_height;
|
||||||
|
|
||||||
pulse_width_reg <= pulse_width;
|
|
||||||
pulse_period_reg <= pulse_period;
|
|
||||||
pulse_num_reg <= pulse_num;
|
|
||||||
pulse_height_reg <= pulse_height;
|
|
||||||
end
|
end
|
||||||
|
// main work cycle
|
||||||
if (enable) begin
|
if (enable) begin
|
||||||
|
if (cnt_pulse_num != pulse_num_reg) begin
|
||||||
if (!sample_req && (cnt_period == 0)) begin
|
// wait for synchronization with sampler
|
||||||
pulse_height_out_reg <= ZERO_LEVEL;
|
if (!synced) begin
|
||||||
if (sample_done) begin
|
if (request & done) begin
|
||||||
sample_req <= 1'b0;
|
synced <= 1;
|
||||||
|
done <= 0;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
done <= 1;
|
||||||
end
|
end
|
||||||
|
else begin
|
||||||
if (!sample_done) begin
|
if (cnt_pulse_period != pulse_period_reg) begin
|
||||||
if (cnt_pulse_num == pulse_num_reg - 1) begin
|
if (cnt_pulse_period < pulse_width_reg)
|
||||||
enable <= 1'b0;
|
dac_out <= pulse_height_reg;
|
||||||
|
else
|
||||||
|
dac_out <= ZERO_LEVEL;
|
||||||
|
cnt_pulse_period++;
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
cnt_pulse_num <= cnt_pulse_num + 1;
|
cnt_pulse_num++;
|
||||||
sample_req <= 1'b1;
|
cnt_pulse_period <= 0;
|
||||||
cnt_period <= 1;
|
synced <= 0;
|
||||||
|
dac_out <= ZERO_LEVEL;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
|
cnt_pulse_num <= 0;
|
||||||
if (cnt_period <= pulse_width_reg) begin
|
enable <= 0;
|
||||||
pulse_height_out_reg <= pulse_height_reg;
|
|
||||||
end else begin
|
|
||||||
pulse_height_out_reg <= ZERO_LEVEL;
|
|
||||||
end
|
|
||||||
if (cnt_period == pulse_period_reg) begin
|
|
||||||
cnt_period <= 0;
|
|
||||||
end else begin
|
|
||||||
cnt_period <= cnt_period + 1;
|
|
||||||
end
|
|
||||||
if (sample_req && sample_done) begin
|
|
||||||
sample_req <= 0;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
OBUF OBUF_pulse_clk (
|
|
||||||
.I(clk_in),
|
|
||||||
.O(pulse)
|
|
||||||
);
|
|
||||||
|
|
||||||
assign pulse_height_out = pulse_height_out_reg;
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|||||||
@ -1,114 +1,360 @@
|
|||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
module generator_tb;
|
module generator_tb;
|
||||||
|
// === Параметры ===
|
||||||
|
localparam DATA_WIDTH = 14;
|
||||||
|
localparam LOGIC_ZERO_LEVEL = 0; // DAC -5V for logic zero
|
||||||
|
localparam VOLTAGE_ZERO_LEVEL = 2**(DATA_WIDTH-1); // DAC 0V for logic zero
|
||||||
|
localparam CLK_PERIOD = 8;
|
||||||
|
parameter string ZERO_LEVEL = "logic"; // "logic" VS "true"
|
||||||
|
|
||||||
parameter DATA_WIDTH = 14;
|
// === Сигналы ===
|
||||||
parameter ZERO_LEVEL = 8192;
|
// Системные сигналы
|
||||||
parameter CLK_PERIOD = 16;
|
|
||||||
|
|
||||||
logic clk;
|
logic clk;
|
||||||
logic rst;
|
logic rst;
|
||||||
logic start;
|
logic start;
|
||||||
|
// Входные сигналы
|
||||||
|
logic [31:0] pulse_width; // config reg
|
||||||
|
logic [31:0] pulse_period; // config reg
|
||||||
|
logic [DATA_WIDTH-1:0] pulse_height; // config reg
|
||||||
|
logic [15:0] pulse_num; // config reg
|
||||||
|
logic sampler_done; // sampler request for synchronization
|
||||||
|
// Выходные сигналы
|
||||||
|
wire [DATA_WIDTH-1:0] dac_out; // DAC input logic signal
|
||||||
|
wire generator_done; // generator request for synchronization
|
||||||
|
|
||||||
logic [31:0] pulse_width;
|
// === Переменные ===
|
||||||
logic [31:0] pulse_period;
|
int current_zero_level;
|
||||||
logic [DATA_WIDTH-1:0] pulse_height;
|
initial begin
|
||||||
logic [15:0] pulse_num;
|
if (ZERO_LEVEL == "true")
|
||||||
|
current_zero_level = VOLTAGE_ZERO_LEVEL;
|
||||||
logic pulse;
|
else
|
||||||
logic [DATA_WIDTH-1:0] pulse_height_out;
|
current_zero_level = LOGIC_ZERO_LEVEL;
|
||||||
|
end
|
||||||
|
|
||||||
// DUT
|
// DUT
|
||||||
generator #(
|
generate
|
||||||
.DATA_WIDTH(DATA_WIDTH)
|
if (ZERO_LEVEL == "true") begin : gen_dut_true
|
||||||
) dut (
|
generator #(
|
||||||
.clk_in(clk),
|
.DATA_WIDTH(DATA_WIDTH),
|
||||||
.rst(rst),
|
.ZERO_LEVEL(VOLTAGE_ZERO_LEVEL)
|
||||||
.start(start),
|
) dut (
|
||||||
.pulse_width(pulse_width),
|
.clk_dac(clk),
|
||||||
.pulse_period(pulse_period),
|
.rst(rst),
|
||||||
.pulse_height(pulse_height),
|
.start(start),
|
||||||
.pulse_num(pulse_num),
|
.pulse_width(pulse_width),
|
||||||
.pulse(pulse),
|
.pulse_period(pulse_period),
|
||||||
.pulse_height_out(pulse_height_out)
|
.pulse_height(pulse_height),
|
||||||
);
|
.pulse_num(pulse_num),
|
||||||
|
.dac_out(dac_out),
|
||||||
|
.done(generator_done),
|
||||||
|
.request(sampler_done)
|
||||||
|
);
|
||||||
|
initial $display("[TB] Generator compiled. ZERO_LEVEL: TRUE");
|
||||||
|
end
|
||||||
|
else if (ZERO_LEVEL == "logic") begin : gen_dut_logic
|
||||||
|
generator #(
|
||||||
|
.DATA_WIDTH(DATA_WIDTH),
|
||||||
|
.ZERO_LEVEL(LOGIC_ZERO_LEVEL)
|
||||||
|
) dut (
|
||||||
|
.clk_dac(clk),
|
||||||
|
.rst(rst),
|
||||||
|
.start(start),
|
||||||
|
.pulse_width(pulse_width),
|
||||||
|
.pulse_period(pulse_period),
|
||||||
|
.pulse_height(pulse_height),
|
||||||
|
.pulse_num(pulse_num),
|
||||||
|
.dac_out(dac_out),
|
||||||
|
.done(generator_done),
|
||||||
|
.request(sampler_done)
|
||||||
|
);
|
||||||
|
initial $display("[TB] Generator compiled. ZERO_LEVEL: LOGIC");
|
||||||
|
end
|
||||||
|
else begin : gen_dut_error
|
||||||
|
// Защита от дурака
|
||||||
|
initial begin
|
||||||
|
$display("[ERROR] Unknown value ZERO_LEVEL: %s", ZERO_LEVEL);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
// Clock
|
// Тактовые сигналы
|
||||||
initial begin
|
initial begin
|
||||||
clk = 0;
|
clk = 0;
|
||||||
forever #(CLK_PERIOD/2) clk = ~clk;
|
forever #(CLK_PERIOD/2) clk = ~clk;
|
||||||
end
|
end
|
||||||
|
|
||||||
initial begin
|
// === Таски для тестипрования ===
|
||||||
$display("\n=== GENERATOR TEST ===\n");
|
// Таска синхронизации, одно рукопожатие
|
||||||
|
task automatic synchronize(
|
||||||
|
input bit sampler_first, // 1 - выставить sampler_done ДО генератора, 0 - ПОСЛЕ
|
||||||
|
input int delay_before_ack, // Если sampler_first=0: задержка ПОСЛЕ gen_done. Если 1: задержка от НАЧАЛА цикла.
|
||||||
|
input int ack_duration // сколько тактов удерживать sampler_done после встречи сигналов
|
||||||
|
);
|
||||||
|
if (sampler_first) begin
|
||||||
|
// --- сэмплер готов до генератора ---
|
||||||
|
repeat(delay_before_ack) @(posedge clk);
|
||||||
|
sampler_done <= 1;
|
||||||
|
wait(generator_done == 1);
|
||||||
|
repeat(ack_duration) @(posedge clk);
|
||||||
|
sampler_done <= 0;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
// --- генератора готов до сэмплер ---
|
||||||
|
wait(generator_done == 1);
|
||||||
|
repeat(delay_before_ack) @(posedge clk);
|
||||||
|
sampler_done <= 1;
|
||||||
|
repeat(ack_duration) @(posedge clk);
|
||||||
|
sampler_done <= 0;
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
// Таска сброса DUT
|
||||||
|
task automatic reset_dut(
|
||||||
|
input int rst_duration // сколько тактов держать сброс
|
||||||
|
);
|
||||||
|
rst <= 1;
|
||||||
|
repeat(rst_duration) @(posedge clk);
|
||||||
|
rst <= 0;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
// Таска запуска DUT
|
||||||
|
task automatic start_dut(
|
||||||
|
input int start_duration // сколько тактов держать импульс
|
||||||
|
);
|
||||||
|
start <= 1;
|
||||||
|
repeat(start_duration) @(posedge clk);
|
||||||
|
start <= 0;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
// Таска конфигурации DUT
|
||||||
|
task automatic set_config(
|
||||||
|
input logic [31:0] w, // ширина импульса
|
||||||
|
input logic [31:0] p, // период импульса
|
||||||
|
input logic [15:0] n, // количество импульсов
|
||||||
|
input logic [DATA_WIDTH-1:0] h // высота импульса
|
||||||
|
);
|
||||||
|
// Задаем конфигурационные регистры
|
||||||
|
@(posedge clk);
|
||||||
|
pulse_width <= w;
|
||||||
|
pulse_period <= p;
|
||||||
|
pulse_num <= n;
|
||||||
|
pulse_height <= h;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
// Таска проверки устойчивости к долгим управляющим импульсам
|
||||||
|
task automatic check_impulses;
|
||||||
|
// Локальные переменные для хранения случайных параметров
|
||||||
|
int rand_start_duration;
|
||||||
|
int rand_delay;
|
||||||
|
int rand_ack;
|
||||||
|
bit rand_first;
|
||||||
|
int total_impulse_cycles = 0;
|
||||||
|
|
||||||
|
int pulse_w = 11;
|
||||||
|
int pulse_p = 31;
|
||||||
|
int pulse_n = 5;
|
||||||
|
int pulse_h = 1024;
|
||||||
|
|
||||||
|
$display("[TB] -check_impulses- Check system stability under random latencies");
|
||||||
|
|
||||||
|
// Установка конфигурации
|
||||||
|
set_config(
|
||||||
|
.w(pulse_w),
|
||||||
|
.p(pulse_p),
|
||||||
|
.n(pulse_n),
|
||||||
|
.h(pulse_h)
|
||||||
|
);
|
||||||
|
|
||||||
|
reset_dut(5);
|
||||||
|
repeat(2) @(posedge clk);
|
||||||
|
|
||||||
|
// Старт норме 1 такт. Сделаем случайным от 5 до 25 тактов.
|
||||||
|
rand_start_duration = $urandom_range(5, 25);
|
||||||
|
$display("[TB] Long start: %0d clocks", rand_start_duration);
|
||||||
|
|
||||||
|
// Фоновый процесс подсчета тактов импульса
|
||||||
|
fork
|
||||||
|
begin : counter_proc
|
||||||
|
forever begin
|
||||||
|
@(negedge clk); // 180 deg. phase shift for "DAC strobing signal"
|
||||||
|
if (dac_out == pulse_h) begin
|
||||||
|
total_impulse_cycles++;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
join_none
|
||||||
|
|
||||||
|
// Параллельный запуск длинного старта и обработки синхронизации
|
||||||
|
fork
|
||||||
|
// Поток 1: Удерживаем старт аномально долго
|
||||||
|
begin
|
||||||
|
start_dut(rand_start_duration);
|
||||||
|
end
|
||||||
|
// Поток 2: Обслуживаем n=4 циклов синхронизации со случайными задержками
|
||||||
|
begin
|
||||||
|
repeat(pulse_n) begin
|
||||||
|
// Рандомизируем параметры для каждого из 4-х рукопожатий
|
||||||
|
rand_first = $urandom; // Случайно: Самплер первый (1) или Генератор первый (0)
|
||||||
|
rand_delay = $urandom_range(1, 8); // Случайная задержка ожидания (1..8 тактов)
|
||||||
|
rand_ack = $urandom_range(5, 10); // Аномально долгий удерживаемый импульс sampler_done (10..30 тактов)
|
||||||
|
|
||||||
|
synchronize(
|
||||||
|
.sampler_first(rand_first),
|
||||||
|
.delay_before_ack(rand_delay),
|
||||||
|
.ack_duration(rand_ack)
|
||||||
|
);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
join
|
||||||
|
repeat(pulse_p+5) @(posedge clk);
|
||||||
|
disable counter_proc;
|
||||||
|
// Ожидание завершения переходных процессов
|
||||||
|
repeat(10) @(posedge clk);
|
||||||
|
if (total_impulse_cycles == pulse_w*pulse_n)
|
||||||
|
$display("[TB] -check_impulses- Pulse generation CORRECT");
|
||||||
|
else begin
|
||||||
|
$display("[ERROR] -check_impulses- Pulse generation INCORRECT. Total number of pulses: %d, must be: %d", total_impulse_cycles, pulse_w*pulse_n);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
$display("[TB] -check_impulses- Done");
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task automatic run_test_case(
|
||||||
|
input int pulse_w,
|
||||||
|
input int pulse_p,
|
||||||
|
input int pulse_n,
|
||||||
|
input int pulse_h,
|
||||||
|
input bit skip_reset, // skip reset sequence on demand
|
||||||
|
input bit count_level // count ticks of amplitude == pulse_h or amplitude != pulse_h
|
||||||
|
);
|
||||||
|
int total_impulse_cycles = 0;
|
||||||
|
|
||||||
|
if (!skip_reset) begin
|
||||||
|
reset_dut(1);
|
||||||
|
@(posedge clk);
|
||||||
|
end
|
||||||
|
|
||||||
|
set_config(
|
||||||
|
.w(pulse_w),
|
||||||
|
.p(pulse_p),
|
||||||
|
.n(pulse_n),
|
||||||
|
.h(pulse_h)
|
||||||
|
);
|
||||||
|
@(posedge clk);
|
||||||
|
|
||||||
|
start_dut(1);
|
||||||
|
|
||||||
|
// Фоновый процесс подсчета тактов импульса
|
||||||
|
fork
|
||||||
|
begin : counter_proc
|
||||||
|
forever begin
|
||||||
|
@(negedge clk); // 180 deg. phase shift for "DAC strobing signal"
|
||||||
|
if (count_level) begin
|
||||||
|
if (dac_out == pulse_h) begin
|
||||||
|
total_impulse_cycles++;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (dac_out != current_zero_level) begin
|
||||||
|
total_impulse_cycles++;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
join_none
|
||||||
|
|
||||||
|
repeat(pulse_n) begin
|
||||||
|
synchronize(
|
||||||
|
.sampler_first(0),
|
||||||
|
.delay_before_ack(1),
|
||||||
|
.ack_duration(2)
|
||||||
|
);
|
||||||
|
end
|
||||||
|
repeat(pulse_p+5) @(posedge clk);
|
||||||
|
disable counter_proc;
|
||||||
|
repeat(10) @(posedge clk);
|
||||||
|
|
||||||
|
if (count_level) begin
|
||||||
|
if (total_impulse_cycles == pulse_w*pulse_n)
|
||||||
|
$display("[TB] -run_test_case- Pulse generation CORRECT");
|
||||||
|
else begin
|
||||||
|
$display("[ERROR] -run_test_case- Pulse generation INCORRECT. Total number of pulses: %d, must be: %d", total_impulse_cycles, pulse_w*pulse_n);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if (total_impulse_cycles == 0)
|
||||||
|
$display("[TB] -run_test_case- Pulse generation CORRECT");
|
||||||
|
else begin
|
||||||
|
$display("[ERROR] -run_test_case- Pulse generation INCORRECT. Total number of pulses: %d, must be: %d", total_impulse_cycles, 0);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endtask
|
||||||
|
|
||||||
|
// --- ОСНОВНОЙ ПРОЦЕСС ТЕСТИРОВАНИЯ ---
|
||||||
|
initial begin
|
||||||
|
$display("[TB] Tests start");
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
rst = 1;
|
rst = 1;
|
||||||
start = 0;
|
start = 0;
|
||||||
|
|
||||||
pulse_width = 0;
|
pulse_width = 0;
|
||||||
pulse_period = 0;
|
pulse_period = 0;
|
||||||
pulse_height = 0;
|
pulse_height = 0;
|
||||||
pulse_num = 0;
|
pulse_num = 0;
|
||||||
|
sampler_done = 0;
|
||||||
|
|
||||||
repeat(5) @(posedge clk);
|
$display("[TB] Test 1. Random latency for control signals");
|
||||||
rst = 0;
|
check_impulses();
|
||||||
|
$display("[TB] Test 1 complete");
|
||||||
|
|
||||||
// --- Test 1 ---
|
$display("[TB] Test 2. Random configs");
|
||||||
// 3 clk 1, 5 clk 0, 4 pulses
|
for (int i = 0; i < 25; i++) begin
|
||||||
repeat(2) @(posedge clk);
|
int r_w, r_p, r_n, r_h;
|
||||||
pulse_width = 3;
|
bit r_skip;
|
||||||
pulse_period = 8;
|
|
||||||
pulse_num = 4;
|
|
||||||
pulse_height = 14'h3FF;
|
|
||||||
start = 1;
|
|
||||||
|
|
||||||
repeat(1) @(posedge clk);
|
// Генерируем параметры
|
||||||
start = 0;
|
r_p = $urandom_range(5, 50); // Период от 5 до 50
|
||||||
|
r_w = $urandom_range(0, r_p); // Ширина не больше периода
|
||||||
|
r_n = $urandom_range(1, 10); // Количество импульсов
|
||||||
|
r_h = $urandom_range(1, 2**DATA_WIDTH-1); // Высота (для 14 бит)
|
||||||
|
r_skip = $urandom_range(0, 1); // Случайный сброс (0 - сброс, 1 - пропуск)
|
||||||
|
|
||||||
repeat(50) @(posedge clk);
|
// Защита от "нулевого" импульса. Невозможно проверить длительность.
|
||||||
|
if (r_h == current_zero_level) begin
|
||||||
|
r_h += $urandom_range(1, 10);
|
||||||
|
end
|
||||||
|
|
||||||
// --- Test 2 ---
|
$display("[TB] --- Test #%0d (Config: W=%0d, P=%0d, N=%0d, H=%0d, SkipReset=%0b) ---",
|
||||||
$display("\n--- SECOND RUN ---\n");
|
i+1, r_w, r_p, r_n, r_h, r_skip);
|
||||||
|
|
||||||
@(posedge clk);
|
run_test_case(
|
||||||
pulse_width = 2;
|
.pulse_w(r_w),
|
||||||
pulse_period = 5;
|
.pulse_p(r_p),
|
||||||
pulse_num = 3;
|
.pulse_n(r_n),
|
||||||
pulse_height = 14'h155;
|
.pulse_h(r_h),
|
||||||
start = 1;
|
.skip_reset(r_skip),
|
||||||
|
.count_level(1)
|
||||||
|
);
|
||||||
|
end
|
||||||
|
$display("[TB] Test 2 complete");
|
||||||
|
|
||||||
@(posedge clk);
|
$display("[TB] Test 3. Zero level of pulse height");
|
||||||
start = 0;
|
run_test_case(
|
||||||
|
.pulse_w(77),
|
||||||
|
.pulse_p(131),
|
||||||
|
.pulse_n(13),
|
||||||
|
.pulse_h(current_zero_level),
|
||||||
|
.skip_reset(0),
|
||||||
|
.count_level(0)
|
||||||
|
);
|
||||||
|
$display("[TB] Test 3 complete");
|
||||||
|
|
||||||
repeat(40) @(posedge clk);
|
$display("[TB] ALL PASSED");
|
||||||
|
|
||||||
pulse_width = 3;
|
|
||||||
pulse_period = 8;
|
|
||||||
pulse_num = 4;
|
|
||||||
pulse_height = 14'h3FF;
|
|
||||||
start = 1;
|
|
||||||
|
|
||||||
repeat(1) @(posedge clk);
|
|
||||||
start = 0;
|
|
||||||
|
|
||||||
repeat(5) @(posedge clk);
|
|
||||||
start = 1;
|
|
||||||
pulse_height = 14'h155;
|
|
||||||
|
|
||||||
repeat(1) @(posedge clk);
|
|
||||||
start = 0;
|
|
||||||
|
|
||||||
repeat(50) @(posedge clk);
|
|
||||||
|
|
||||||
|
|
||||||
$display("\n=== TEST FINISHED ===");
|
|
||||||
$finish;
|
$finish;
|
||||||
end
|
end
|
||||||
|
|
||||||
// Display
|
|
||||||
always @(posedge clk) begin
|
|
||||||
$display("t=%0t | pulse=%0b | height=%h",
|
|
||||||
$time, pulse, pulse_height_out);
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
@ -1,7 +1,7 @@
|
|||||||
# Сэмплер
|
# Сэмплер
|
||||||
|
|
||||||
Модуль выполняет задачу сбора данных с выхода АЦП, их обработки, упаковки и передачи дальше с помощью AXI Stream интерфейса.
|
Модуль выполняет задачу сбора данных с выхода АЦП, их обработки, упаковки и передачи дальше с помощью AXI Stream интерфейса.
|
||||||
Дополнительно реализован механизм синхронизации с внешним генератором через сигналы `sample_req` и `sample_done`, позволяющий запускать сбор строго по запросу и подтверждать завершение выборки.
|
Дополнительно реализован механизм синхронизации с внешним генератором через сигналы `request` и `done`, позволяющий запускать сбор строго по запросу и подтверждать завершение выборки.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -41,9 +41,8 @@ out_of_range
|
|||||||
[31:0] smp_num
|
[31:0] smp_num
|
||||||
Количество валидных отсчетов, которое необходимо собрать после получения запроса на выборку.
|
Количество валидных отсчетов, которое необходимо собрать после получения запроса на выборку.
|
||||||
|
|
||||||
sample_req
|
request
|
||||||
Сигнал запроса на запуск выборки.
|
Сигнал запроса на синхронизацию от генератора для текущего импульса.
|
||||||
При его активации модуль начинает сбор данных и переходит в активное состояние (`enable = 1`).
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -57,9 +56,10 @@ m_axis_tvalid
|
|||||||
Урезанный AXI Stream формат, сигнал валидности выходных данных.
|
Урезанный AXI Stream формат, сигнал валидности выходных данных.
|
||||||
Формируется при готовности очередного пакета.
|
Формируется при готовности очередного пакета.
|
||||||
|
|
||||||
sample_done
|
done
|
||||||
Сигнал завершения выборки.
|
Сигнал запроса на запуск синхронизации с генератором для текущего импульса.
|
||||||
Поднимается после того, как модуль собрал количество валидных отсчетов, равное `smp_num`.
|
|
||||||
|
Поднимается в начале каждого нового импульса и снимается после получения `request`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ sample_done
|
|||||||
|
|
||||||
### Запуск выборки
|
### Запуск выборки
|
||||||
|
|
||||||
Сбор данных начинается только после прихода сигнала `sample_req`.
|
Сбор данных начинается только после прихода сигнала `request`.
|
||||||
|
|
||||||
При этом:
|
При этом:
|
||||||
|
|
||||||
@ -94,7 +94,9 @@ sample_done
|
|||||||
- внутренний счетчик собранных отсчетов обнуляется
|
- внутренний счетчик собранных отсчетов обнуляется
|
||||||
- модуль переходит в активное состояние (`enable = 1`)
|
- модуль переходит в активное состояние (`enable = 1`)
|
||||||
|
|
||||||
Пока `enable = 1`, модуль принимает только валидные отсчеты и считает их.
|
Пока `enable = 1`, модуль принимает только валидные отсчеты.
|
||||||
|
|
||||||
|
Синхронизация представляет из себя простое рукопожатие с внешним модулем, имеющим сигналы `request`/`done` работающими в соответствии с этими сигналами сэмплера. Один из модулей, входит в ожидание и ставит на свой done активный уровень, после чего ждет, пока второй, запаздывающий модуль не войдет в свой режим ожидания, и не выставит для своего done активный уровень. Для каждого из модулей, на следующий такт после выставления активного уровня, производится проверка своего request. Так, при получении активного request (иными словами активного done от внешнего модуля), модуль незамедлительно опускает уровень своего done и начинает работать. Done подымается до активного уровня хотя-бы на один такт работы соответствующего модуля.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -126,7 +128,6 @@ sample_done
|
|||||||
|
|
||||||
Когда количество собранных валидных отсчетов достигает значения `smp_num`:
|
Когда количество собранных валидных отсчетов достигает значения `smp_num`:
|
||||||
|
|
||||||
- поднимается сигнал `sample_done`
|
|
||||||
- внутренние счетчики сбрасываются
|
- внутренние счетчики сбрасываются
|
||||||
- буфер очищается
|
- буфер очищается
|
||||||
- `enable` сбрасывается в `0`
|
- `enable` сбрасывается в `0`
|
||||||
@ -141,4 +142,3 @@ sample_done
|
|||||||
cd tests
|
cd tests
|
||||||
make sim
|
make sim
|
||||||
```
|
```
|
||||||
При успешном завершении теста высвечивается "ALL PASSED".
|
|
||||||
@ -1,154 +1,87 @@
|
|||||||
`timescale 1ns / 1ps
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module sampler
|
module sampler
|
||||||
#(
|
#(
|
||||||
parameter DATA_WIDTH = 12,
|
parameter DATA_WIDTH = 12,
|
||||||
parameter PACK_FACTOR = 1,
|
parameter PACK_FACTOR = 1,
|
||||||
parameter PROCESS_MODE = 0
|
parameter PROCESS_MODE = 0
|
||||||
)
|
) (
|
||||||
(
|
|
||||||
input clk_in,
|
input clk_in,
|
||||||
input rst,
|
input rst,
|
||||||
input [DATA_WIDTH-1:0] data_in,
|
input [DATA_WIDTH-1:0] data_in,
|
||||||
input out_of_range,
|
input out_of_range,
|
||||||
input [31:0] smp_num,
|
input [31:0] smp_num,
|
||||||
input sample_req,
|
input request,
|
||||||
|
|
||||||
output logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata,
|
output logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata,
|
||||||
output logic m_axis_tvalid,
|
output logic m_axis_tvalid,
|
||||||
output logic sample_done
|
output logic done
|
||||||
);
|
);
|
||||||
(* MARK_DEBUG="true" *) logic [DATA_WIDTH-1:0] data_converted;
|
// WARNING: number of samples smp_num must be multiple of PACK_FACTOR
|
||||||
(* MARK_DEBUG="true" *) logic out_of_range_reg;
|
// Last (smp_num % PACK_FACTOR) will be lost and not transmitted
|
||||||
(* MARK_DEBUG="true" *) logic [31:0] smp_num_reg, cnt_smp_num;
|
logic [DATA_WIDTH-1:0] data_converted;
|
||||||
(* MARK_DEBUG="true" *) logic enable;
|
logic [31:0] smp_num_reg, cnt_smp_num;
|
||||||
|
logic synced;
|
||||||
|
logic [$clog2(PACK_FACTOR):0] pack_cnt;
|
||||||
|
|
||||||
generate
|
always_comb begin
|
||||||
if (PROCESS_MODE) begin
|
if (PROCESS_MODE) begin
|
||||||
|
if (out_of_range) begin
|
||||||
always @(posedge clk_in) begin
|
data_converted = {~data_in[DATA_WIDTH-1], {(DATA_WIDTH-1){data_in[DATA_WIDTH-1]}}};
|
||||||
if (rst) begin
|
end else begin
|
||||||
data_converted <= '0;
|
data_converted = {~data_in[DATA_WIDTH-1], data_in[DATA_WIDTH-2:0]};
|
||||||
out_of_range_reg <= 0;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
out_of_range_reg <= out_of_range;
|
|
||||||
if (data_in == {1'b1, {(DATA_WIDTH-1){1'b0}}})
|
|
||||||
data_converted <= data_in;
|
|
||||||
else
|
|
||||||
data_converted <= data_in[DATA_WIDTH-1] ?{1'b1, (~data_in[DATA_WIDTH-2:0] + 1'b1)}:data_in;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end else begin
|
|
||||||
always @(posedge clk_in) begin
|
|
||||||
if (rst) begin
|
|
||||||
data_converted <= '0;
|
|
||||||
out_of_range_reg <= 0;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
out_of_range_reg <= out_of_range;
|
|
||||||
data_converted <= data_in;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
(* MARK_DEBUG="true" *) logic [DATA_WIDTH*PACK_FACTOR-1:0] buffer;
|
|
||||||
(* MARK_DEBUG="true" *) logic buffer_ready;
|
|
||||||
|
|
||||||
logic [$clog2(PACK_FACTOR):0] cnt;
|
|
||||||
|
|
||||||
generate
|
|
||||||
if (PACK_FACTOR == 1) begin
|
|
||||||
always @(posedge clk_in) begin
|
|
||||||
if (rst) begin
|
|
||||||
buffer <= '0;
|
|
||||||
buffer_ready <= 0;
|
|
||||||
cnt_smp_num <= '0;
|
|
||||||
smp_num_reg <= '0;
|
|
||||||
enable <= '0;
|
|
||||||
sample_done <= 0;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
buffer_ready <= 0;
|
|
||||||
if (sample_done && !sample_req) begin
|
|
||||||
sample_done <= 1'b0;
|
|
||||||
end
|
end
|
||||||
if (!enable && sample_req && !sample_done) begin
|
end else begin
|
||||||
enable <= 1;
|
if (out_of_range) begin
|
||||||
|
data_converted = {DATA_WIDTH{data_in[DATA_WIDTH-1]}};
|
||||||
|
end else begin
|
||||||
|
data_converted = data_in;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
synced = 0;
|
||||||
|
m_axis_tdata = '0;
|
||||||
|
m_axis_tvalid = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(posedge clk_in) begin
|
||||||
|
if (rst) begin
|
||||||
|
m_axis_tdata <= '0;
|
||||||
|
m_axis_tvalid <= 0;
|
||||||
|
cnt_smp_num <= '0;
|
||||||
|
smp_num_reg <= '0;
|
||||||
|
pack_cnt <= '0;
|
||||||
|
synced <= 0;
|
||||||
|
done <= 0;
|
||||||
|
end else begin
|
||||||
|
if (!synced) begin
|
||||||
|
if (done && request) begin
|
||||||
|
synced <= 1;
|
||||||
|
done <= 0;
|
||||||
cnt_smp_num <= 0;
|
cnt_smp_num <= 0;
|
||||||
smp_num_reg <= smp_num;
|
smp_num_reg <= smp_num;
|
||||||
|
end else begin
|
||||||
|
done <= 1;
|
||||||
end
|
end
|
||||||
if (enable) begin
|
end else begin
|
||||||
if (!out_of_range_reg) begin
|
if (cnt_smp_num != smp_num_reg) begin
|
||||||
if (cnt_smp_num != smp_num_reg) begin
|
cnt_smp_num++;
|
||||||
buffer <= data_converted;
|
m_axis_tdata[pack_cnt*DATA_WIDTH +: DATA_WIDTH] <= data_converted;
|
||||||
buffer_ready <= 1;
|
if (pack_cnt == PACK_FACTOR-1) begin
|
||||||
cnt_smp_num <= cnt_smp_num +1;
|
pack_cnt <= 0;
|
||||||
end
|
m_axis_tvalid <= 1;
|
||||||
else begin
|
end else begin
|
||||||
cnt_smp_num <= '0;
|
pack_cnt++;
|
||||||
sample_done <= 1'b1;
|
m_axis_tvalid <= 0;
|
||||||
buffer_ready <= 0;
|
|
||||||
buffer <= '0;
|
|
||||||
enable <= 0;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
end else begin
|
||||||
|
pack_cnt <= '0;
|
||||||
|
synced <= 0;
|
||||||
|
m_axis_tvalid <= 0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end else begin
|
end
|
||||||
always @(posedge clk_in) begin
|
|
||||||
if (rst) begin
|
|
||||||
buffer <= '0;
|
|
||||||
cnt <= '0; //
|
|
||||||
buffer_ready <= 0;
|
|
||||||
cnt_smp_num <= '0;
|
|
||||||
smp_num_reg <= '0;
|
|
||||||
enable <= 0;
|
|
||||||
sample_done <= 0;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
buffer_ready <= 0;
|
|
||||||
if (sample_done && !sample_req) begin
|
|
||||||
sample_done <= 1'b0;
|
|
||||||
end
|
|
||||||
if (!enable && sample_req && !sample_done) begin
|
|
||||||
enable <= 1;
|
|
||||||
cnt_smp_num <= 0;
|
|
||||||
smp_num_reg <= smp_num;
|
|
||||||
end
|
|
||||||
if (enable) begin
|
|
||||||
if (!out_of_range_reg) begin
|
|
||||||
if (cnt_smp_num != smp_num_reg) begin
|
|
||||||
cnt_smp_num <= cnt_smp_num +1;
|
|
||||||
buffer <= {buffer[DATA_WIDTH*(PACK_FACTOR-1)-1:0], data_converted};
|
|
||||||
if (cnt == PACK_FACTOR-1) begin
|
|
||||||
cnt <= 0;
|
|
||||||
buffer_ready <= 1;
|
|
||||||
buffer <= {buffer[DATA_WIDTH*(PACK_FACTOR-1)-1:0], data_converted};
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
cnt <= cnt + 1;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
sample_done <= 1'b1;
|
|
||||||
cnt_smp_num <= '0;
|
|
||||||
buffer_ready <= 0;
|
|
||||||
buffer <= '0;
|
|
||||||
enable <= 0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
assign m_axis_tdata = buffer;
|
|
||||||
assign m_axis_tvalid = buffer_ready;
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
|||||||
@ -1,51 +0,0 @@
|
|||||||
# SPDX-License-Identifier: MIT
|
|
||||||
#
|
|
||||||
# Copyright (c) 2025 FPGA Ninja, LLC
|
|
||||||
#
|
|
||||||
# Authors:
|
|
||||||
# - Alex Forencich
|
|
||||||
#
|
|
||||||
|
|
||||||
# FPGA settings
|
|
||||||
FPGA_PART = xc7a35tfgg484-1
|
|
||||||
FPGA_TOP = sampler
|
|
||||||
FPGA_ARCH = artix7
|
|
||||||
|
|
||||||
RTL_DIR = ../src
|
|
||||||
|
|
||||||
|
|
||||||
include ../../../scripts/vivado.mk
|
|
||||||
|
|
||||||
SYN_FILES += $(sort $(shell find ../src -type f \( -name '*.v' -o -name '*.sv' \)))
|
|
||||||
|
|
||||||
XCI_FILES = $(sort $(shell find ../src -type f -name '*.xci'))
|
|
||||||
|
|
||||||
XDC_FILES += ../../../constraints/ax7a035b.xdc
|
|
||||||
|
|
||||||
SYN_FILES += sampler_main_tb.sv
|
|
||||||
SIM_TOP = sampler_tb
|
|
||||||
|
|
||||||
|
|
||||||
program: $(PROJECT).bit
|
|
||||||
echo "open_hw_manager" > program.tcl
|
|
||||||
echo "connect_hw_server" >> program.tcl
|
|
||||||
echo "open_hw_target" >> program.tcl
|
|
||||||
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
|
|
||||||
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
|
|
||||||
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
|
|
||||||
echo "program_hw_devices [current_hw_device]" >> program.tcl
|
|
||||||
echo "exit" >> program.tcl
|
|
||||||
vivado -nojournal -nolog -mode batch -source program.tcl
|
|
||||||
|
|
||||||
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
|
|
||||||
echo "write_cfgmem -force -format mcs -size 16 -interface SPIx4 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
|
|
||||||
echo "exit" >> generate_mcs.tcl
|
|
||||||
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
|
|
||||||
mkdir -p rev
|
|
||||||
COUNT=100; \
|
|
||||||
while [ -e rev/$*_rev$$COUNT.bit ]; \
|
|
||||||
do COUNT=$$((COUNT+1)); done; \
|
|
||||||
COUNT=$$((COUNT-1)); \
|
|
||||||
for x in .mcs .prm; \
|
|
||||||
do cp $*$$x rev/$*_rev$$COUNT$$x; \
|
|
||||||
echo "Output: rev/$*_rev$$COUNT$$x"; done;
|
|
||||||
@ -1,132 +0,0 @@
|
|||||||
`timescale 1ns / 1ps
|
|
||||||
|
|
||||||
module sampler_tb;
|
|
||||||
|
|
||||||
parameter DATA_WIDTH = 12;
|
|
||||||
parameter PROCESS_MODE = 0;
|
|
||||||
parameter CLK_PERIOD = 15.3846;
|
|
||||||
parameter TEST_NUM = 1000;
|
|
||||||
|
|
||||||
logic clk;
|
|
||||||
logic rst;
|
|
||||||
|
|
||||||
logic [DATA_WIDTH-1:0] data_in;
|
|
||||||
logic out_of_range;
|
|
||||||
|
|
||||||
logic [DATA_WIDTH-1:0] m_axis_tdata;
|
|
||||||
logic m_axis_tvalid;
|
|
||||||
|
|
||||||
integer errors = 0;
|
|
||||||
|
|
||||||
sampler #(
|
|
||||||
.DATA_WIDTH(DATA_WIDTH),
|
|
||||||
.PROCESS_MODE(PROCESS_MODE)
|
|
||||||
) dut (
|
|
||||||
.clk_in(clk),
|
|
||||||
.rst(rst),
|
|
||||||
.data_in(data_in),
|
|
||||||
.out_of_range(out_of_range),
|
|
||||||
.m_axis_tdata(m_axis_tdata),
|
|
||||||
.m_axis_tvalid(m_axis_tvalid)
|
|
||||||
);
|
|
||||||
|
|
||||||
initial begin
|
|
||||||
clk = 0;
|
|
||||||
forever #(CLK_PERIOD/2) clk = ~clk;
|
|
||||||
end
|
|
||||||
|
|
||||||
function automatic [DATA_WIDTH-1:0] ref_convert(input [DATA_WIDTH-1:0] din);
|
|
||||||
if (PROCESS_MODE == 0)
|
|
||||||
return din;
|
|
||||||
else if (din == {1'b1, {(DATA_WIDTH-1){1'b0}}})
|
|
||||||
return din;
|
|
||||||
else
|
|
||||||
return din[DATA_WIDTH-1] ?
|
|
||||||
{1'b1, (~din[DATA_WIDTH-2:0] + 1'b1)} :
|
|
||||||
din;
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
task send(input [DATA_WIDTH-1:0] word, input bit oor);
|
|
||||||
@(posedge clk);
|
|
||||||
data_in <= word;
|
|
||||||
out_of_range <= oor;
|
|
||||||
endtask
|
|
||||||
|
|
||||||
logic [DATA_WIDTH-1:0] exp_d0, exp_d1, exp_d2;
|
|
||||||
logic oor_d0, oor_d1, oor_d2;
|
|
||||||
|
|
||||||
initial begin
|
|
||||||
$display("\n=== RANDOM SAMPLER TEST===\n");
|
|
||||||
|
|
||||||
rst = 1;
|
|
||||||
data_in = 0;
|
|
||||||
out_of_range = 0;
|
|
||||||
|
|
||||||
exp_d0 = 0;
|
|
||||||
exp_d1 = 0;
|
|
||||||
exp_d2 = 0;
|
|
||||||
|
|
||||||
oor_d0 = 1;
|
|
||||||
oor_d1 = 1;
|
|
||||||
oor_d2 = 1;
|
|
||||||
|
|
||||||
repeat(5) @(posedge clk);
|
|
||||||
rst = 0;
|
|
||||||
repeat(2) @(posedge clk);
|
|
||||||
|
|
||||||
repeat (TEST_NUM) begin
|
|
||||||
logic [DATA_WIDTH-1:0] rand_data;
|
|
||||||
bit rand_oor;
|
|
||||||
|
|
||||||
rand_data = $urandom_range(0, (1 << DATA_WIDTH) - 1);
|
|
||||||
rand_oor = ($urandom_range(0, 99) < 20);
|
|
||||||
|
|
||||||
@(negedge clk);
|
|
||||||
|
|
||||||
if (!oor_d2) begin
|
|
||||||
if (m_axis_tvalid !== 1) begin
|
|
||||||
$display("ERROR: valid=0");
|
|
||||||
errors++;
|
|
||||||
end
|
|
||||||
|
|
||||||
if (m_axis_tdata !== exp_d2) begin
|
|
||||||
$display("ERROR: data mismatch");
|
|
||||||
$display(" expected = %h", exp_d2);
|
|
||||||
$display(" got = %h", m_axis_tdata);
|
|
||||||
errors++;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
send(rand_data, rand_oor);
|
|
||||||
|
|
||||||
exp_d2 = exp_d1;
|
|
||||||
exp_d1 = exp_d0;
|
|
||||||
exp_d0 = ref_convert(rand_data);
|
|
||||||
|
|
||||||
oor_d2 = oor_d1;
|
|
||||||
oor_d1 = oor_d0;
|
|
||||||
oor_d0 = rand_oor;
|
|
||||||
end
|
|
||||||
|
|
||||||
@(posedge clk);
|
|
||||||
|
|
||||||
|
|
||||||
if (!oor_d2) begin
|
|
||||||
|
|
||||||
if (m_axis_tdata !== exp_d2) begin
|
|
||||||
$display("ERROR: final mismatch");
|
|
||||||
$display(" expected = %h", exp_d2);
|
|
||||||
$display(" got = %h", m_axis_tdata);
|
|
||||||
errors++;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if (errors == 0)
|
|
||||||
$display("\n========== ALL PASSED ==========\n");
|
|
||||||
else
|
|
||||||
$display("\n========== FAILED: %0d errors ==========\n", errors);
|
|
||||||
|
|
||||||
$finish;
|
|
||||||
end
|
|
||||||
|
|
||||||
endmodule
|
|
||||||
218
rtl/sampler/tests/sampler_tb.sv
Normal file
218
rtl/sampler/tests/sampler_tb.sv
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
`timescale 1ns / 1ps
|
||||||
|
|
||||||
|
module sampler_tb;
|
||||||
|
|
||||||
|
localparam DATA_WIDTH = 12;
|
||||||
|
localparam PACK_FACTOR = 7;
|
||||||
|
localparam PROCESS_MODE = 0;
|
||||||
|
localparam CLK_PERIOD = 15.3846;
|
||||||
|
localparam OTR_OFFSET = 0;
|
||||||
|
|
||||||
|
logic clk;
|
||||||
|
logic rst_dut;
|
||||||
|
logic rst_gen;
|
||||||
|
|
||||||
|
wire [DATA_WIDTH-1:0] data_in;
|
||||||
|
wire out_of_range;
|
||||||
|
|
||||||
|
logic [31:0] smp_num;
|
||||||
|
|
||||||
|
logic done;
|
||||||
|
logic request;
|
||||||
|
|
||||||
|
logic [DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata;
|
||||||
|
logic m_axis_tvalid;
|
||||||
|
|
||||||
|
sampler #(
|
||||||
|
.DATA_WIDTH (DATA_WIDTH),
|
||||||
|
.PACK_FACTOR (PACK_FACTOR),
|
||||||
|
.PROCESS_MODE(PROCESS_MODE)
|
||||||
|
) dut (
|
||||||
|
.clk_in (clk),
|
||||||
|
.rst (rst_dut),
|
||||||
|
|
||||||
|
.data_in (data_in),
|
||||||
|
.out_of_range (out_of_range),
|
||||||
|
|
||||||
|
.smp_num (smp_num),
|
||||||
|
.done (done),
|
||||||
|
|
||||||
|
.m_axis_tdata (m_axis_tdata),
|
||||||
|
.m_axis_tvalid(m_axis_tvalid),
|
||||||
|
|
||||||
|
.request (request)
|
||||||
|
);
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// CLOCK
|
||||||
|
// =====================================================
|
||||||
|
initial begin
|
||||||
|
clk = 0;
|
||||||
|
forever #(CLK_PERIOD/2) clk = ~clk;
|
||||||
|
end
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// RESET
|
||||||
|
// =====================================================
|
||||||
|
task automatic reset_dut();
|
||||||
|
@(posedge clk);
|
||||||
|
rst_dut = 1;
|
||||||
|
@(posedge clk);
|
||||||
|
rst_dut = 0;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// FEED DATA
|
||||||
|
// =====================================================
|
||||||
|
triangle_wave_gen #(
|
||||||
|
.DATA_WIDTH(DATA_WIDTH),
|
||||||
|
.OFFSET(OTR_OFFSET), // offset of bits from '0 and '1 for OTR
|
||||||
|
.STEP(1) // LSB bit per clock
|
||||||
|
) signal_gen (
|
||||||
|
.clk(clk),
|
||||||
|
.rst(rst_gen),
|
||||||
|
.signal(data_in),
|
||||||
|
.otr(out_of_range)
|
||||||
|
);
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// TEST TASKS
|
||||||
|
// =====================================================
|
||||||
|
task automatic run_test_case(
|
||||||
|
input int sample_num
|
||||||
|
);
|
||||||
|
logic [DATA_WIDTH-1:0] input_values[$];
|
||||||
|
logic [DATA_WIDTH-1:0] output_values[$];
|
||||||
|
bit flag;
|
||||||
|
|
||||||
|
// Startup sequence
|
||||||
|
rst_gen <= 1;
|
||||||
|
smp_num <= sample_num;
|
||||||
|
request <= 1;
|
||||||
|
@(posedge clk);
|
||||||
|
|
||||||
|
// syncronize
|
||||||
|
while (!done)
|
||||||
|
@(posedge clk);
|
||||||
|
request <= 0;
|
||||||
|
|
||||||
|
// Wait for sync and start signal generator
|
||||||
|
// while (!dut.synced)
|
||||||
|
// @(posedge clk);
|
||||||
|
wait(dut.synced === 1);
|
||||||
|
rst_gen <= 0;
|
||||||
|
|
||||||
|
// Wait for valid data
|
||||||
|
fork
|
||||||
|
begin : stat_mon_proc
|
||||||
|
forever begin
|
||||||
|
@(posedge clk);
|
||||||
|
input_values.push_back(data_in);
|
||||||
|
if (m_axis_tvalid) begin
|
||||||
|
for (int i = 0; i < PACK_FACTOR; i++)
|
||||||
|
output_values.push_back(m_axis_tdata[DATA_WIDTH*i +: DATA_WIDTH]);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
join_none
|
||||||
|
|
||||||
|
// Wait until end
|
||||||
|
// while (dut.synced)
|
||||||
|
// @(posedge clk);
|
||||||
|
wait(dut.synced === 0);
|
||||||
|
|
||||||
|
disable stat_mon_proc;
|
||||||
|
// Pop last input value. Signal is ahead of tdata for 1 cycle
|
||||||
|
input_values.pop_back();
|
||||||
|
|
||||||
|
// check data
|
||||||
|
if (input_values.size() != output_values.size()) begin
|
||||||
|
$display("[ERROR] -run_test_case- Input queue size don't equal to output queue size: %0d vs %0d", input_values.size(), output_values.size());
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
flag = 0;
|
||||||
|
for (int i = 0; i < input_values.size(); i++) begin
|
||||||
|
$write(" %0d", input_values[i]);
|
||||||
|
if (input_values[i] != output_values[i])
|
||||||
|
flag = 1;
|
||||||
|
end
|
||||||
|
$write("\n");
|
||||||
|
for (int i = 0; i < input_values.size(); i++) begin
|
||||||
|
$write(" %0d", output_values[i]);
|
||||||
|
end
|
||||||
|
$write("\n");
|
||||||
|
$display("Total: %0d", output_values.size());
|
||||||
|
if (flag) $display("FUCK");
|
||||||
|
else $display("SUCKASS");
|
||||||
|
|
||||||
|
endtask
|
||||||
|
|
||||||
|
// =====================================================
|
||||||
|
// MAIN
|
||||||
|
// =====================================================
|
||||||
|
initial begin
|
||||||
|
|
||||||
|
$display("\n=== BASIC TEST ===");
|
||||||
|
|
||||||
|
rst_dut = 1;
|
||||||
|
rst_gen = 1;
|
||||||
|
smp_num = 0;
|
||||||
|
repeat(2) @(posedge clk);
|
||||||
|
rst_dut = 0;
|
||||||
|
repeat(2) @(posedge clk);
|
||||||
|
|
||||||
|
run_test_case(100);
|
||||||
|
|
||||||
|
|
||||||
|
$display("\n=== RANDOM STRESS TEST ===");
|
||||||
|
// todo
|
||||||
|
|
||||||
|
$display("\n=== TEST FINISHED ===");
|
||||||
|
$finish;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module triangle_wave_gen #(
|
||||||
|
parameter DATA_WIDTH = 12,
|
||||||
|
parameter OFFSET = 100, // offset of bits from '0 and '1 for OTR
|
||||||
|
parameter STEP = 1 // LSB bit per clock
|
||||||
|
) (
|
||||||
|
input clk,
|
||||||
|
input rst,
|
||||||
|
output logic [DATA_WIDTH-1:0] signal,
|
||||||
|
output logic otr
|
||||||
|
);
|
||||||
|
logic [DATA_WIDTH:0] counter;
|
||||||
|
logic direction;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
counter = '0;
|
||||||
|
direction = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
assign signal = counter > (2**DATA_WIDTH-1) ? (2**DATA_WIDTH-1) : counter;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
if (signal < OFFSET || (2**DATA_WIDTH - signal) <= OFFSET)
|
||||||
|
otr <= 1;
|
||||||
|
else
|
||||||
|
otr <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (rst) begin
|
||||||
|
counter = 0;
|
||||||
|
direction = 1;
|
||||||
|
end else begin
|
||||||
|
if (direction)
|
||||||
|
counter += STEP;
|
||||||
|
else
|
||||||
|
counter -= STEP;
|
||||||
|
|
||||||
|
if (counter >= 2**DATA_WIDTH-1 || counter <= 0)
|
||||||
|
direction <= ~direction;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
Reference in New Issue
Block a user