update: new synchronizer + half-baked TB

This commit is contained in:
2026-06-10 16:40:53 +03:00
parent bb65aea4f1
commit c165d346a0
3 changed files with 334 additions and 214 deletions

View File

@ -2,113 +2,104 @@
module sync_top
#(
parameter int unsigned DAC_DATA_WIDTH = 14,
parameter int unsigned ADC_DATA_WIDTH = 12,
parameter int unsigned PACK_FACTOR = 1,
parameter int unsigned PROCESS_MODE = 0
parameter int unsigned DAC_DATA_WIDTH = 14, // DAC bit-width
parameter int unsigned ADC_DATA_WIDTH = 12, // ADC bit-width
parameter int unsigned PACK_FACTOR = 1, // number of ADC readings per transaction
parameter int unsigned PROCESS_MODE = 0, // representation format of ADC readings (0 - direct code, 1 - 2's completment)
parameter int unsigned ZERO_LEVEL = 0
)
(
input adc_clk_in,
input adc_rst,
input dac_clk_in,
input dac_rst,
input dac_start,
input clk_adc,
input rst_adc,
input clk_dac,
input rst_dac,
input start,
input out_of_range,
input [31:0] pulse_width,
input [31:0] pulse_period,
input [DAC_DATA_WIDTH-1:0] pulse_height,
input [15:0] pulse_num,
input [31:0] smp_num,
output logic [ADC_DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata,
output logic m_axis_tvalid
input [15:0] pulse_num, // DAC counter limit
input [31:0] smp_num, // ADC counter limit
output [ADC_DATA_WIDTH*PACK_FACTOR-1:0] m_axis_tdata,
output m_axis_tvalid
);
//------------------------------------------------------------
// Internal signals
//------------------------------------------------------------
(* 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;
(* MARK_DEBUG="true" *) logic pulse;
(* MARK_DEBUG="true" *) logic [DAC_DATA_WIDTH-1:0] pulse_height_out;
//------------------------------------------------------------
// Simple DAC -> ADC test source
//
// generator output is directly connected to sampler input
// with width truncation:
//
// pulse_height_out[13:0] -> data_in[11:0]
//------------------------------------------------------------
(* 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;
wire dac_done, dac_request, adc_done, adc_request;
wire [DAC_DATA_WIDTH-1:0] dac_signal;
wire [ADC_DATA_WIDTH-1:0] adc_singnal;
generate
if (ADC_DATA_WIDTH > DAC_DATA_WIDTH) begin : g_pad_zeros
assign adc_singnal = { {(ADC_DATA_WIDTH - DAC_DATA_WIDTH){1'b0}}, dac_signal };
end
else begin : g_truncate
assign adc_singnal = dac_signal[ADC_DATA_WIDTH-1:0];
end
endgenerate
//------------------------------------------------------------
// DAC -> ADC CDC
//------------------------------------------------------------
always_ff @(posedge adc_clk_in or posedge adc_rst) begin
if (adc_rst) begin
sample_req <= 1'b0;
sample_req_sync2 <= 1'b0;
sample_req_sync3 <= 1'b0;
end
logic [2:0] stretch; // 125/65~=2. Чтобы поймать единичный импульс, растянем его во времени
logic [1:0] sync_DA;
wire dac_done_stretched;
always_ff @(posedge clk_dac or posedge rst_dac)
begin
if (rst_dac)
stretch <= 0;
else begin
sample_req_sync2 <= sample_req_sync1;
sample_req_sync3 <= sample_req_sync2;
sample_req <= sample_req_sync3;
stretch[0] <= dac_done;
stretch[1] <= stretch[0];
stretch[2] <= stretch[1];
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
//------------------------------------------------------------
always_ff @(posedge dac_clk_in or posedge dac_rst) begin
if (dac_rst) begin
sample_done <= 1'b0;
sample_done_sync2 <= 1'b0;
sample_done_sync3 <= 1'b0;
end
logic [1:0] sync_AD;
always_ff @(posedge clk_dac or posedge rst_dac) begin
if (rst_dac)
sync_AD <= 0;
else begin
sample_done_sync2 <= sample_done_sync1;
sample_done_sync3 <= sample_done_sync2;
sample_done <= sample_done_sync3;
sync_AD[0] <= adc_done;
sync_AD[1] <= sync_AD[0];
end
end
assign dac_request = sync_AD[1];
//------------------------------------------------------------
// Generator
//------------------------------------------------------------
generator #(
.DATA_WIDTH(DAC_DATA_WIDTH)
.DATA_WIDTH(DAC_DATA_WIDTH),
.ZERO_LEVEL(ZERO_LEVEL)
) generator_inst (
.clk_in(dac_clk_in),
.rst(dac_rst),
.start(dac_start),
.clk_dac(clk_dac),
.rst(rst_dac),
.start(start),
.pulse_width(pulse_width),
.pulse_period(pulse_period),
.pulse_height(pulse_height),
.pulse_num(pulse_num),
.sample_done(sample_done),
.pulse(pulse),
.pulse_height_out(pulse_height_out),
.sample_req(sample_req_sync1)
.dac_out(dac_signal),
.request(dac_request),
.done(dac_done)
);
//------------------------------------------------------------
@ -119,18 +110,15 @@ module sync_top
.PACK_FACTOR(PACK_FACTOR),
.PROCESS_MODE(PROCESS_MODE)
) sampler_inst (
.clk_in(adc_clk_in),
.rst(adc_rst),
.data_in(data_in),
.clk_in(clk_adc),
.rst(rst_adc),
.data_in(adc_singnal),
.out_of_range(out_of_range),
.smp_num(smp_num),
.sample_req(sample_req),
.m_axis_tdata(m_axis_tdata),
.m_axis_tvalid(m_axis_tvalid),
.sample_done(sample_done_sync1)
.request(adc_request),
.done(adc_done)
);
endmodule