ad_dds: Fix noise caused by dac_data_sync
For projects where the clock ratio between the sampling clock and core clock is higher than 2, the ad_dds generates a number of samples equal with the clock ratio. There is a phase offset between the samples, proportional with the requested DDS frequency. In scenarios where the DDS out frequency is closer to the upper limit(Nyquist) and/or the clock ratio is also greater than 2 and the dac_data_sync reminds low for an extended period of time, the DAC will receive at each core clock period, a number of samples equal with the clock ratio and with an amplitude influenced by the DDS out frequency. In most cases similar with a sawtooth signal. With this commit we ensures that samples received by the DAC are 0 for the period where dac_data_sync signal is high. Only when the signal transitions to low, the phase accumulator is initialized and the phase information is passed to the phase to amplitude converter. Another issue can appear when the sync signal is too short; less then CLK_RATIO * clock cycles. Because the phase accumulator will not synchronize at all stages, the final result will be a random combination of sine-waves. Added a minimum sync pulse after the dac_data_sync is set low.main
parent
6ca6257341
commit
a7a131cb36
|
@ -70,6 +70,8 @@ module ad_dds #(
|
|||
|
||||
wire [DDS_DW*CLK_RATIO-1:0] dac_dds_data_s;
|
||||
|
||||
reg dac_data_sync_m = 1'd0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
dac_dds_data <= dac_dds_data_s;
|
||||
end
|
||||
|
@ -87,26 +89,51 @@ module ad_dds #(
|
|||
reg [PHASE_DW-1:0] dac_dds_phase_1[1:CLK_RATIO];
|
||||
reg [PHASE_DW-1:0] dac_dds_incr_0 = 'd0;
|
||||
reg [PHASE_DW-1:0] dac_dds_incr_1 = 'd0;
|
||||
reg sync_min_pulse_m[1:CLK_RATIO];
|
||||
|
||||
// For scenarios where the synchronization signal comes from an external
|
||||
// source and it is high for a longer period of time, the phase
|
||||
// accumulator stages must be reset, in order to avoid a noise like
|
||||
// signal caused by sending all the summed outputs of each DDS stage.
|
||||
// There is a minimum synchronization pulse width of n clock cycles,
|
||||
// that is required to synchronize all phase accumulator stages.
|
||||
// Where n is equal to the CLK_RATIO.
|
||||
always @(posedge clk) begin
|
||||
dac_data_sync_m <= dac_data_sync;
|
||||
sync_min_pulse_m[1] <= dac_data_sync_m & !dac_data_sync |
|
||||
sync_min_pulse_m[1] & !sync_min_pulse_m[CLK_RATIO];
|
||||
end
|
||||
|
||||
for (i=1; i <= CLK_RATIO; i=i+1) begin: sync_delay
|
||||
always @(posedge clk) begin
|
||||
sync_min_pulse_m[i+1] <= sync_min_pulse_m[i];
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
dac_dds_incr_0 <= tone_1_freq_word * CLK_RATIO;
|
||||
dac_dds_incr_1 <= tone_2_freq_word * CLK_RATIO;
|
||||
end
|
||||
|
||||
// phase accumulator
|
||||
// phase accumulator
|
||||
for (i=1; i <= CLK_RATIO; i=i+1) begin: dds_phase
|
||||
always @(posedge clk) begin
|
||||
if (dac_data_sync == 1'b1) begin
|
||||
if (i == 1) begin
|
||||
dac_dds_phase_0[1] <= tone_1_init_offset;
|
||||
dac_dds_phase_1[1] <= tone_2_init_offset;
|
||||
end else if (CLK_RATIO > 1)begin
|
||||
dac_dds_phase_0[i] <= dac_dds_phase_0[i-1] + tone_1_freq_word;
|
||||
dac_dds_phase_1[i] <= dac_dds_phase_1[i-1] + tone_2_freq_word;
|
||||
if (dac_valid == 1'b1) begin
|
||||
if (dac_data_sync == 1'b1) begin
|
||||
dac_dds_phase_0[i] <= 'd0;
|
||||
dac_dds_phase_1[i] <= 'd0;
|
||||
end else if (sync_min_pulse_m[1] == 1'b1) begin
|
||||
if (i == 1) begin
|
||||
dac_dds_phase_0[1] <= tone_1_init_offset;
|
||||
dac_dds_phase_1[1] <= tone_2_init_offset;
|
||||
end else if (CLK_RATIO > 1)begin
|
||||
dac_dds_phase_0[i] <= dac_dds_phase_0[i-1] + tone_1_freq_word;
|
||||
dac_dds_phase_1[i] <= dac_dds_phase_1[i-1] + tone_2_freq_word;
|
||||
end
|
||||
end else begin
|
||||
dac_dds_phase_0[i] <= dac_dds_phase_0[i] + dac_dds_incr_0;
|
||||
dac_dds_phase_1[i] <= dac_dds_phase_1[i] + dac_dds_incr_1;
|
||||
end
|
||||
end else if (dac_valid == 1'b1) begin
|
||||
dac_dds_phase_0[i] <= dac_dds_phase_0[i] + dac_dds_incr_0;
|
||||
dac_dds_phase_1[i] <= dac_dds_phase_1[i] + dac_dds_incr_1;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue