`timescale 1ns / 1ps module sync_top #( 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 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, // 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 //------------------------------------------------------------ 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 //------------------------------------------------------------ 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 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 //------------------------------------------------------------ logic [1:0] sync_AD; always_ff @(posedge clk_dac or posedge rst_dac) begin if (rst_dac) sync_AD <= 0; else begin 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), .ZERO_LEVEL(ZERO_LEVEL) ) generator_inst ( .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), .dac_out(dac_signal), .request(dac_request), .done(dac_done) ); //------------------------------------------------------------ // Sampler //------------------------------------------------------------ sampler #( .DATA_WIDTH(ADC_DATA_WIDTH), .PACK_FACTOR(PACK_FACTOR), .PROCESS_MODE(PROCESS_MODE) ) sampler_inst ( .clk_in(clk_adc), .rst(rst_adc), .data_in(adc_singnal), .out_of_range(out_of_range), .smp_num(smp_num), .m_axis_tdata(m_axis_tdata), .m_axis_tvalid(m_axis_tvalid), .request(adc_request), .done(adc_done) ); endmodule