124 lines
4.0 KiB
Systemverilog
124 lines
4.0 KiB
Systemverilog
`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 |