From af2f243b0244683d29484cf3a926cc3de4810c1e Mon Sep 17 00:00:00 2001 From: AndreiGrozav Date: Mon, 19 Aug 2019 18:35:59 +0300 Subject: [PATCH] axi_dac_interpolate: Add dac trigger feature --- .../axi_dac_interpolate/axi_dac_interpolate.v | 86 +++++++++++++++++++ .../axi_dac_interpolate_constr.xdc | 8 ++ .../axi_dac_interpolate_filter.v | 13 ++- .../axi_dac_interpolate_ip.tcl | 1 + .../axi_dac_interpolate_reg.v | 12 ++- 5 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 library/axi_dac_interpolate/axi_dac_interpolate_constr.xdc diff --git a/library/axi_dac_interpolate/axi_dac_interpolate.v b/library/axi_dac_interpolate/axi_dac_interpolate.v index bbafb0291..4c6401247 100644 --- a/library/axi_dac_interpolate/axi_dac_interpolate.v +++ b/library/axi_dac_interpolate/axi_dac_interpolate.v @@ -55,6 +55,10 @@ module axi_dac_interpolate #( output dac_int_valid_a, output dac_int_valid_b, + input [ 1:0] trigger_i, + input trigger_adc, + input trigger_la, + // axi interface input s_axi_aclk, @@ -79,6 +83,23 @@ module axi_dac_interpolate #( output [ 1:0] s_axi_rresp, input s_axi_rready); + + reg [ 1:0] trigger_i_m1; + reg [ 1:0] trigger_i_m2; + reg [ 1:0] trigger_i_m3; + reg trigger_adc_m1; + reg trigger_adc_m2; + reg trigger_adc_m3; + reg trigger_la_m1; + reg trigger_la_m2; + reg trigger_la_m3; + + reg [ 1:0] any_edge_trigger; + reg [ 1:0] rise_edge_trigger; + reg [ 1:0] fall_edge_trigger; + reg [ 1:0] high_level_trigger; + reg [ 1:0] low_level_trigger; + // internal signals wire up_clk; @@ -104,12 +125,72 @@ module axi_dac_interpolate #( wire dac_correction_enable_b; wire [15:0] dac_correction_coefficient_a; wire [15:0] dac_correction_coefficient_b; + wire [19:0] trigger_config; + + wire [ 1:0] en_trigger_pins; + wire en_trigger_adc; + wire en_trigger_la; + + wire [ 1:0] low_level; + wire [ 1:0] high_level; + wire [ 1:0] any_edge; + wire [ 1:0] rise_edge; + wire [ 1:0] fall_edge; + + wire trigger_active; + wire ext_trigger; + // signal name changes assign up_clk = s_axi_aclk; assign up_rstn = s_axi_aresetn; + // trigger logic + + assign low_level = trigger_config[1:0]; + assign high_level = trigger_config[3:2]; + assign any_edge = trigger_config[5:4]; + assign rise_edge = trigger_config[7:6]; + assign fall_edge = trigger_config[9:8]; + + 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 = (ext_trigger & en_trigger_pins) | + (trigger_adc_m2 & en_trigger_adc) | + (trigger_la_m2 & en_trigger_la); + + assign ext_trigger = |(any_edge_trigger | + rise_edge_trigger | + fall_edge_trigger | + high_level_trigger | + low_level_trigger); + + // sync + always @(posedge dac_clk) begin + trigger_i_m1 <= trigger_i; + trigger_i_m2 <= trigger_i_m1; + trigger_i_m3 <= trigger_i_m2; + + trigger_adc_m1 <= trigger_adc; + trigger_adc_m2 <= trigger_adc_m1; + + trigger_la_m1 <= trigger_la; + trigger_la_m2 <= trigger_la_m1; + end + + always @(posedge dac_clk) begin + any_edge_trigger <= (trigger_i_m3 ^ trigger_i_m2) & any_edge; + rise_edge_trigger <= (~trigger_i_m3 & trigger_i_m2) & rise_edge; + fall_edge_trigger <= (trigger_i_m3 & ~trigger_i_m2) & fall_edge; + high_level_trigger <= trigger_i_m3 & high_level; + low_level_trigger <= ~trigger_i_m3 & low_level; + end + + axi_dac_interpolate_filter #( .CORRECTION_DISABLE(CORRECTION_DISABLE)) i_filter_a ( @@ -126,6 +207,8 @@ module axi_dac_interpolate #( .interpolation_ratio (interpolation_ratio_a), .dma_transfer_suspend (dma_transfer_suspend), .start_sync_channels (start_sync_channels), + .trigger (trigger), + .trigger_active (trigger_active), .dma_valid (dma_valid_a), .dma_valid_adjacent (dma_valid_b), .dac_correction_enable(dac_correction_enable_a), @@ -148,6 +231,8 @@ module axi_dac_interpolate #( .interpolation_ratio (interpolation_ratio_b), .dma_transfer_suspend (dma_transfer_suspend), .start_sync_channels (start_sync_channels), + .trigger (trigger), + .trigger_active (trigger_active), .dma_valid (dma_valid_b), .dma_valid_adjacent (dma_valid_a), .dac_correction_enable(dac_correction_enable_b), @@ -169,6 +254,7 @@ module axi_dac_interpolate #( .dac_correction_enable_b(dac_correction_enable_b), .dac_correction_coefficient_a(dac_correction_coefficient_a), .dac_correction_coefficient_b(dac_correction_coefficient_b), + .trigger_config (trigger_config), .up_rstn (up_rstn), .up_clk (up_clk), diff --git a/library/axi_dac_interpolate/axi_dac_interpolate_constr.xdc b/library/axi_dac_interpolate/axi_dac_interpolate_constr.xdc new file mode 100644 index 000000000..68d1042ce --- /dev/null +++ b/library/axi_dac_interpolate/axi_dac_interpolate_constr.xdc @@ -0,0 +1,8 @@ +set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *trigger_i_m*}] +set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *trigger_adc_m*}] +set_property ASYNC_REG TRUE [get_cells -hier -filter {name =~ *trigger_la_m*}] + +set_false_path -to [get_cells -hier -filter {name =~ *trigger_i_m1_reg* && IS_SEQUENTIAL}] +set_false_path -to [get_cells -hier -filter {name =~ *trigger_adc_m1_reg* && IS_SEQUENTIAL}] +set_false_path -to [get_cells -hier -filter {name =~ *trigger_la_m1_reg* && IS_SEQUENTIAL}] + diff --git a/library/axi_dac_interpolate/axi_dac_interpolate_filter.v b/library/axi_dac_interpolate/axi_dac_interpolate_filter.v index b92d2aae9..17b836591 100644 --- a/library/axi_dac_interpolate/axi_dac_interpolate_filter.v +++ b/library/axi_dac_interpolate/axi_dac_interpolate_filter.v @@ -55,6 +55,8 @@ module axi_dac_interpolate_filter #( input dac_correction_enable, input dma_transfer_suspend, input start_sync_channels, + input trigger, + input trigger_active, input dma_valid, input dma_valid_adjacent ); @@ -68,11 +70,12 @@ module axi_dac_interpolate_filter #( reg cic_change_rate; reg [31:0] interpolation_counter; - reg transmit_valid = 1'b1; + reg transmit_ready = 1'b1; reg dma_data_valid = 1'b0; reg dma_data_valid_adjacent = 1'b0; reg filter_enable = 1'b0; + reg triggered = 1'b0; wire dac_valid_corrected; wire [15:0] dac_data_corrected; @@ -154,19 +157,21 @@ module axi_dac_interpolate_filter #( if (dma_transfer_suspend) begin dma_data_valid <= 1'b0; dma_data_valid_adjacent <= 1'b0; + triggered <= 1'b0; end else begin dma_data_valid <= dma_valid ? 1'b1 : dma_data_valid; dma_data_valid_adjacent <= dma_valid_adjacent ? 1'b1 : dma_data_valid_adjacent; + triggered <= trigger ? 1'b1 : triggered | !trigger_active; end if (start_sync_channels == 1'b0) begin - transmit_valid <= 1'b1; + transmit_ready <= triggered; end else begin - transmit_valid <= (dma_data_valid & dma_data_valid_adjacent) ? 1'b1 : ~dma_data_valid; + transmit_ready <= (dma_data_valid & dma_data_valid_adjacent) ? triggered : ~dma_data_valid; end end - assign dac_int_valid = transmit_valid ? dac_int_valid_d : 1'b0; + assign dac_int_valid = transmit_ready ? dac_int_valid_d : 1'b0; always @(posedge dac_clk) begin case (filter_mask) diff --git a/library/axi_dac_interpolate/axi_dac_interpolate_ip.tcl b/library/axi_dac_interpolate/axi_dac_interpolate_ip.tcl index 2094d19a3..d12c3d623 100644 --- a/library/axi_dac_interpolate/axi_dac_interpolate_ip.tcl +++ b/library/axi_dac_interpolate/axi_dac_interpolate_ip.tcl @@ -10,6 +10,7 @@ adi_ip_files axi_dac_interpolate [list \ "$ad_hdl_dir/library/common/ad_iqcor.v" \ "$ad_hdl_dir/library/xilinx/common/ad_mul.v" \ "$ad_hdl_dir/library/xilinx/common/up_xfer_cntrl_constr.xdc" \ + "axi_dac_interpolate_constr.xdc" \ "cic_interp.v" \ "fir_interp.v" \ "axi_dac_interpolate_reg.v" \ diff --git a/library/axi_dac_interpolate/axi_dac_interpolate_reg.v b/library/axi_dac_interpolate/axi_dac_interpolate_reg.v index be0e003b7..3e4871e22 100644 --- a/library/axi_dac_interpolate/axi_dac_interpolate_reg.v +++ b/library/axi_dac_interpolate/axi_dac_interpolate_reg.v @@ -49,7 +49,7 @@ module axi_dac_interpolate_reg( output dac_correction_enable_b, output [15:0] dac_correction_coefficient_a, output [15:0] dac_correction_coefficient_b, - + output [19:0] trigger_config, // bus interface input up_rstn, @@ -76,6 +76,7 @@ module axi_dac_interpolate_reg( reg [1:0] up_config = 2'h0; reg [15:0] up_correction_coefficient_a = 16'h0; reg [15:0] up_correction_coefficient_b = 16'h0; + reg [19:0] up_trigger_config = 20'h0; wire [ 1:0] flags; @@ -94,6 +95,7 @@ module axi_dac_interpolate_reg( up_config <= 'd0; up_correction_coefficient_a <= 'd0; up_correction_coefficient_b <= 'd0; + up_trigger_config <= 'd0; end else begin up_wack <= up_wreq; if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h1)) begin @@ -123,6 +125,9 @@ module axi_dac_interpolate_reg( if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h17)) begin up_correction_coefficient_b <= up_wdata[15:0]; end + if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h18)) begin + up_trigger_config <= up_wdata[19:0]; + end end end @@ -146,6 +151,7 @@ module axi_dac_interpolate_reg( 5'h15: up_rdata <= {30'h0,up_config}; 5'h16: up_rdata <= {16'h0,up_correction_coefficient_a}; 5'h17: up_rdata <= {16'h0,up_correction_coefficient_b}; + 5'h18: up_rdata <= {12'h0,up_trigger_config}; default: up_rdata <= 0; endcase end else begin @@ -154,13 +160,14 @@ module axi_dac_interpolate_reg( end end - up_xfer_cntrl #(.DATA_WIDTH(106)) i_xfer_cntrl ( + up_xfer_cntrl #(.DATA_WIDTH(126)) i_xfer_cntrl ( .up_rstn (up_rstn), .up_clk (up_clk), .up_data_cntrl ({ up_config[1], // 1 up_config[0], // 1 up_correction_coefficient_b,// 16 up_correction_coefficient_a,// 16 + up_trigger_config, // 20 up_flags, // 2 up_interpolation_ratio_b, // 32 up_interpolation_ratio_a, // 32 @@ -174,6 +181,7 @@ module axi_dac_interpolate_reg( dac_correction_enable_a, // 1 dac_correction_coefficient_b, // 16 dac_correction_coefficient_a, // 16 + trigger_config, // 20 flags, // 2 dac_interpolation_ratio_b, // 32 dac_interpolation_ratio_a, // 32