axi_dac_interpolate: Add last sample support

This feature will allow the user to hold(indefinitely) the last sample, from an
ongoing DMA transfer, simple or cyclic(stooped by user or trigger).

This commit also adds as functionality option:
-synchronized stop between the two channels(DMAs)
-stop by trigger
main
AndreiGrozav 2020-08-28 23:51:18 +03:00 committed by AndreiGrozav
parent d676cfd64f
commit 4f4a4208cd
3 changed files with 66 additions and 5 deletions

View File

@ -56,6 +56,9 @@ module axi_dac_interpolate #(
input dac_enable_b, input dac_enable_b,
output [15:0] dac_int_data_a, output [15:0] dac_int_data_a,
output [15:0] dac_int_data_b, output [15:0] dac_int_data_b,
output dac_valid_out_a,
output dac_valid_out_b,
output hold_last_sample,
output underflow, output underflow,
input [ 1:0] trigger_i, input [ 1:0] trigger_i,
@ -130,6 +133,8 @@ module axi_dac_interpolate #(
wire [15:0] dac_correction_coefficient_b; wire [15:0] dac_correction_coefficient_b;
wire [19:0] trigger_config; wire [19:0] trigger_config;
wire en_start_trigger;
wire en_stop_trigger;
wire [ 1:0] en_trigger_pins; wire [ 1:0] en_trigger_pins;
wire en_trigger_adc; wire en_trigger_adc;
wire en_trigger_la; wire en_trigger_la;
@ -141,11 +146,15 @@ module axi_dac_interpolate #(
wire [ 1:0] fall_edge; wire [ 1:0] fall_edge;
wire trigger_active; wire trigger_active;
wire trigger;
wire ext_trigger; wire ext_trigger;
wire underflow_a; wire underflow_a;
wire underflow_b; wire underflow_b;
wire [ 1:0] lsample_hold_config;
wire sync_stop_channels;
// signal name changes // signal name changes
assign up_clk = s_axi_aclk; assign up_clk = s_axi_aclk;
@ -159,9 +168,11 @@ module axi_dac_interpolate #(
assign rise_edge = trigger_config[7:6]; assign rise_edge = trigger_config[7:6];
assign fall_edge = trigger_config[9:8]; assign fall_edge = trigger_config[9:8];
assign en_trigger_pins = trigger_config[17:16]; assign en_start_trigger = trigger_config[14];
assign en_trigger_adc = trigger_config[18]; assign en_stop_trigger = trigger_config[15];
assign en_trigger_la = trigger_config[19]; assign en_trigger_pins = trigger_config[17:16];
assign en_trigger_adc = trigger_config[18];
assign en_trigger_la = trigger_config[19];
assign trigger_active = |trigger_config[19:16]; assign trigger_active = |trigger_config[19:16];
assign trigger = (ext_trigger & en_trigger_pins) | assign trigger = (ext_trigger & en_trigger_pins) |
@ -195,6 +206,9 @@ module axi_dac_interpolate #(
low_level_trigger <= ~trigger_i_m3 & low_level; low_level_trigger <= ~trigger_i_m3 & low_level;
end end
assign hold_last_sample = lsample_hold_config[0];
assign sync_stop_channels = lsample_hold_config[1];
assign underflow = underflow_a | underflow_b; assign underflow = underflow_a | underflow_b;
axi_dac_interpolate_filter #( axi_dac_interpolate_filter #(
@ -205,6 +219,8 @@ module axi_dac_interpolate #(
.dac_data (dac_data_a), .dac_data (dac_data_a),
.dac_valid (dac_valid_a), .dac_valid (dac_valid_a),
.dac_valid_out (dac_valid_out_a),
.sync_stop_channels (sync_stop_channels),
.dac_enable (dac_enable_a), .dac_enable (dac_enable_a),
.dac_int_data (dac_int_data_a), .dac_int_data (dac_int_data_a),
@ -217,6 +233,8 @@ module axi_dac_interpolate #(
.start_sync_channels (start_sync_channels), .start_sync_channels (start_sync_channels),
.trigger (trigger), .trigger (trigger),
.trigger_active (trigger_active), .trigger_active (trigger_active),
.en_start_trigger (en_start_trigger),
.en_stop_trigger (en_stop_trigger),
.dma_valid (dma_valid_a), .dma_valid (dma_valid_a),
.dma_valid_adjacent (dma_valid_b), .dma_valid_adjacent (dma_valid_b),
.dac_correction_enable(dac_correction_enable_a), .dac_correction_enable(dac_correction_enable_a),
@ -231,6 +249,8 @@ module axi_dac_interpolate #(
.dac_data (dac_data_b), .dac_data (dac_data_b),
.dac_valid (dac_valid_b), .dac_valid (dac_valid_b),
.dac_valid_out (dac_valid_out_b),
.sync_stop_channels (sync_stop_channels),
.underflow (underflow_b), .underflow (underflow_b),
.dac_enable (dac_enable_b), .dac_enable (dac_enable_b),
@ -243,6 +263,8 @@ module axi_dac_interpolate #(
.start_sync_channels (start_sync_channels), .start_sync_channels (start_sync_channels),
.trigger (trigger), .trigger (trigger),
.trigger_active (trigger_active), .trigger_active (trigger_active),
.en_start_trigger (en_start_trigger),
.en_stop_trigger (en_stop_trigger),
.dma_valid (dma_valid_b), .dma_valid (dma_valid_b),
.dma_valid_adjacent (dma_valid_a), .dma_valid_adjacent (dma_valid_a),
.dac_correction_enable(dac_correction_enable_b), .dac_correction_enable(dac_correction_enable_b),
@ -265,6 +287,7 @@ module axi_dac_interpolate #(
.dac_correction_coefficient_a(dac_correction_coefficient_a), .dac_correction_coefficient_a(dac_correction_coefficient_a),
.dac_correction_coefficient_b(dac_correction_coefficient_b), .dac_correction_coefficient_b(dac_correction_coefficient_b),
.trigger_config (trigger_config), .trigger_config (trigger_config),
.lsample_hold_config (lsample_hold_config),
.up_rstn (up_rstn), .up_rstn (up_rstn),
.up_clk (up_clk), .up_clk (up_clk),

View File

@ -49,6 +49,8 @@ module axi_dac_interpolate_filter #(
input dac_enable, input dac_enable,
output reg [15:0] dac_int_data, output reg [15:0] dac_int_data,
output dma_ready, output dma_ready,
output dac_valid_out,
input sync_stop_channels,
output underflow, output underflow,
input [ 2:0] filter_mask, input [ 2:0] filter_mask,
@ -59,6 +61,8 @@ module axi_dac_interpolate_filter #(
input start_sync_channels, input start_sync_channels,
input trigger, input trigger,
input trigger_active, input trigger_active,
input en_start_trigger,
input en_stop_trigger,
input dma_valid, input dma_valid,
input dma_valid_adjacent input dma_valid_adjacent
); );
@ -78,6 +82,8 @@ module axi_dac_interpolate_filter #(
reg filter_enable = 1'b0; reg filter_enable = 1'b0;
reg transfer = 1'b0; reg transfer = 1'b0;
reg [15:0] dma_valid_m = 16'd0;
reg stop_transfer = 1'd0;
wire dac_valid_corrected; wire dac_valid_corrected;
wire [15:0] dac_data_corrected; wire [15:0] dac_data_corrected;
@ -87,6 +93,9 @@ module axi_dac_interpolate_filter #(
wire dac_cic_valid; wire dac_cic_valid;
wire [109:0] dac_cic_data; wire [109:0] dac_cic_data;
wire dma_valid_ch_sync;
wire dma_valid_ch;
ad_iqcor #(.Q_OR_I_N (0), ad_iqcor #(.Q_OR_I_N (0),
.DISABLE(CORRECTION_DISABLE), .DISABLE(CORRECTION_DISABLE),
.SCALE_ONLY(1)) .SCALE_ONLY(1))
@ -119,6 +128,21 @@ module axi_dac_interpolate_filter #(
.filter_out (dac_cic_data), .filter_out (dac_cic_data),
.ce_out (dac_cic_valid)); .ce_out (dac_cic_valid));
assign dma_valid_ch_sync = sync_stop_channels ?
dma_valid & dma_valid_adjacent & !dma_transfer_suspend :
dma_valid & !dma_transfer_suspend;
assign dma_valid_ch = dma_valid_ch_sync & !stop_transfer;
always @(posedge dac_clk) begin
if (dac_rst == 1'b1) begin
dma_valid_m <= 'd0;
end else begin
dma_valid_m <= {dma_valid_m[14:0], dma_valid_ch};
end
end
assign dac_valid_out = dma_valid_m[4'h5];
always @(posedge dac_clk) begin always @(posedge dac_clk) begin
filter_mask_d1 <= filter_mask; filter_mask_d1 <= filter_mask;
if (filter_mask_d1 != filter_mask) begin if (filter_mask_d1 != filter_mask) begin
@ -151,7 +175,7 @@ module axi_dac_interpolate_filter #(
always @(posedge dac_clk) begin always @(posedge dac_clk) begin
if (dma_transfer_suspend == 1'b0) begin if (dma_transfer_suspend == 1'b0) begin
transfer <= trigger ? 1'b1 : transfer | !trigger_active; transfer <= trigger ? 1'b1 : transfer | !(trigger_active & en_start_trigger);
end else begin end else begin
transfer <= 1'b0; transfer <= 1'b0;
end end
@ -162,6 +186,11 @@ module axi_dac_interpolate_filter #(
end end
end end
always @(posedge dac_clk) begin
stop_transfer <= !en_stop_trigger | dma_transfer_suspend ? 1'b0 :
stop_transfer | (trigger_active & trigger & transfer);
end
assign dma_ready = transmit_ready ? dac_int_ready : 1'b0; assign dma_ready = transmit_ready ? dac_int_ready : 1'b0;
assign underflow = dac_enable & dma_ready & ~dma_valid; assign underflow = dac_enable & dma_ready & ~dma_valid;

View File

@ -50,6 +50,7 @@ module axi_dac_interpolate_reg(
output [15:0] dac_correction_coefficient_a, output [15:0] dac_correction_coefficient_a,
output [15:0] dac_correction_coefficient_b, output [15:0] dac_correction_coefficient_b,
output [19:0] trigger_config, output [19:0] trigger_config,
output [ 1:0] lsample_hold_config,
// bus interface // bus interface
input up_rstn, input up_rstn,
@ -77,6 +78,7 @@ module axi_dac_interpolate_reg(
reg [15:0] up_correction_coefficient_a = 16'h0; reg [15:0] up_correction_coefficient_a = 16'h0;
reg [15:0] up_correction_coefficient_b = 16'h0; reg [15:0] up_correction_coefficient_b = 16'h0;
reg [19:0] up_trigger_config = 20'h0; reg [19:0] up_trigger_config = 20'h0;
reg [ 1:0] up_lsample_hold_config = 2'h0;
wire [ 1:0] flags; wire [ 1:0] flags;
@ -96,6 +98,7 @@ module axi_dac_interpolate_reg(
up_correction_coefficient_a <= 'd0; up_correction_coefficient_a <= 'd0;
up_correction_coefficient_b <= 'd0; up_correction_coefficient_b <= 'd0;
up_trigger_config <= 'd0; up_trigger_config <= 'd0;
up_lsample_hold_config <= 'h0;
end else begin end else begin
up_wack <= up_wreq; up_wack <= up_wreq;
if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h1)) begin if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h1)) begin
@ -128,6 +131,9 @@ module axi_dac_interpolate_reg(
if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h18)) begin if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h18)) begin
up_trigger_config <= up_wdata[19:0]; up_trigger_config <= up_wdata[19:0];
end end
if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h19)) begin
up_lsample_hold_config <= up_wdata[1:0];
end
end end
end end
@ -152,6 +158,7 @@ module axi_dac_interpolate_reg(
5'h16: up_rdata <= {16'h0,up_correction_coefficient_a}; 5'h16: up_rdata <= {16'h0,up_correction_coefficient_a};
5'h17: up_rdata <= {16'h0,up_correction_coefficient_b}; 5'h17: up_rdata <= {16'h0,up_correction_coefficient_b};
5'h18: up_rdata <= {12'h0,up_trigger_config}; 5'h18: up_rdata <= {12'h0,up_trigger_config};
5'h19: up_rdata <= {30'h0,up_lsample_hold_config};
default: up_rdata <= 0; default: up_rdata <= 0;
endcase endcase
end else begin end else begin
@ -160,7 +167,7 @@ module axi_dac_interpolate_reg(
end end
end end
up_xfer_cntrl #(.DATA_WIDTH(126)) i_xfer_cntrl ( up_xfer_cntrl #(.DATA_WIDTH(128)) i_xfer_cntrl (
.up_rstn (up_rstn), .up_rstn (up_rstn),
.up_clk (up_clk), .up_clk (up_clk),
.up_data_cntrl ({ up_config[1], // 1 .up_data_cntrl ({ up_config[1], // 1
@ -168,6 +175,7 @@ module axi_dac_interpolate_reg(
up_correction_coefficient_b,// 16 up_correction_coefficient_b,// 16
up_correction_coefficient_a,// 16 up_correction_coefficient_a,// 16
up_trigger_config, // 20 up_trigger_config, // 20
up_lsample_hold_config, // 2
up_flags, // 2 up_flags, // 2
up_interpolation_ratio_b, // 32 up_interpolation_ratio_b, // 32
up_interpolation_ratio_a, // 32 up_interpolation_ratio_a, // 32
@ -182,6 +190,7 @@ module axi_dac_interpolate_reg(
dac_correction_coefficient_b, // 16 dac_correction_coefficient_b, // 16
dac_correction_coefficient_a, // 16 dac_correction_coefficient_a, // 16
trigger_config, // 20 trigger_config, // 20
lsample_hold_config, // 2
flags, // 2 flags, // 2
dac_interpolation_ratio_b, // 32 dac_interpolation_ratio_b, // 32
dac_interpolation_ratio_a, // 32 dac_interpolation_ratio_a, // 32