diff --git a/library/axi_adc_trigger/axi_adc_trigger.v b/library/axi_adc_trigger/axi_adc_trigger.v index fa4b11ca3..f07aac4ab 100644 --- a/library/axi_adc_trigger/axi_adc_trigger.v +++ b/library/axi_adc_trigger/axi_adc_trigger.v @@ -45,8 +45,10 @@ module axi_adc_trigger #( input clk, + input trigger_in, + input [ 1:0] trigger_i, - output [ 1:0] trigger_o, + output reg [ 1:0] trigger_o, output [ 1:0] trigger_t, input [15:0] data_a, @@ -58,6 +60,8 @@ module axi_adc_trigger #( output [15:0] data_b_trig, output data_valid_a_trig, output data_valid_b_trig, + output reg trigger_out, + output reg trigger_out_la, output [31:0] fifo_depth, @@ -101,7 +105,7 @@ module axi_adc_trigger #( wire up_rreq; wire [ 4:0] up_raddr; - wire [ 1:0] io_selection; + wire [ 7:0] io_selection; wire [ 1:0] low_level; wire [ 1:0] high_level; @@ -119,7 +123,7 @@ module axi_adc_trigger #( wire [31:0] hysteresis_b; wire [ 3:0] trigger_l_mix_b; - wire [ 2:0] trigger_out_mix; + wire [16:0] trigger_out_control; wire [31:0] trigger_delay; wire signed [DW:0] data_a_cmp; @@ -140,7 +144,11 @@ module axi_adc_trigger #( wire trigger_a_any_edge; wire trigger_b_any_edge; wire trigger_out_delayed; + wire [ 1:0] trigger_up_o_s; wire streaming; + wire trigger_out_s; + wire embedded_trigger; + wire external_trigger; reg trigger_a_d1; // synchronization flip flop reg trigger_a_d2; // synchronization flip flop @@ -163,6 +171,13 @@ module axi_adc_trigger #( reg trigger_pin_a; reg trigger_pin_b; + reg [ 1:0] trigger_o_m; + reg [ 1:0] trigger_o_m_1; + + reg trig_o_hold_0; + reg trig_o_hold_1; + reg [16:0] trig_o_hold_cnt_0; + reg [16:0] trig_o_hold_cnt_1; reg trigger_adc_a; reg trigger_adc_b; @@ -180,13 +195,9 @@ module axi_adc_trigger #( reg up_triggered_reset_d1; reg up_triggered_reset_d2; - reg [14:0] data_a_r; - reg [14:0] data_b_r; - reg data_valid_a_r; - reg data_valid_b_r; - reg [31:0] trigger_delay_counter; reg triggered; + reg trigger_out_m1; reg streaming_on; @@ -195,7 +206,7 @@ module axi_adc_trigger #( assign up_clk = s_axi_aclk; assign up_rstn = s_axi_aresetn; - assign trigger_t = io_selection; + assign trigger_t = io_selection[1:0]; assign trigger_a_fall_edge = (trigger_a_d2 == 1'b0 && trigger_a_d3 == 1'b1) ? 1'b1: 1'b0; assign trigger_a_rise_edge = (trigger_a_d2 == 1'b1 && trigger_a_d3 == 1'b0) ? 1'b1: 1'b0; @@ -209,10 +220,76 @@ module axi_adc_trigger #( assign limit_a_cmp = limit_a[DW:0]; assign limit_b_cmp = limit_b[DW:0]; - assign data_a_trig = trigger_delay == 32'h0 ? {trigger_out_mixed | streaming_on, data_a_r} : {trigger_out_delayed |streaming_on, data_a_r}; - assign data_b_trig = trigger_delay == 32'h0 ? {trigger_out_mixed | streaming_on, data_b_r} : {trigger_out_delayed |streaming_on, data_b_r}; - assign data_valid_a_trig = data_valid_a_r; - assign data_valid_b_trig = data_valid_b_r; + always @(*) begin + case(io_selection[4:2]) + 3'h0: trigger_o_m[0] = trigger_up_o_s[0]; + 3'h1: trigger_o_m[0] = trigger_i[0]; + 3'h2: trigger_o_m[0] = trigger_i[1]; + 3'h3: trigger_o_m[0] = trigger_out_mixed; + 3'h4: trigger_o_m[0] = trigger_in; + default: trigger_o_m[0] = trigger_up_o_s[0]; + endcase + case(io_selection[7:5]) + 3'h0: trigger_o_m[1] = trigger_up_o_s[1]; + 3'h1: trigger_o_m[1] = trigger_i[1]; + 3'h2: trigger_o_m[1] = trigger_i[0]; + 3'h3: trigger_o_m[1] = trigger_out_mixed; + 3'h4: trigger_o_m[1] = trigger_in; + default: trigger_o_m[1] = trigger_up_o_s[1]; + endcase + end + + // External trigger output hold 100000 clock cycles(1ms) on polarity change. + // All trigger signals that are to be outputted on the external trigger after a + // trigger out is acknowledged by the hold counter will be disregarded for 1ms. + // This was done to avoid noise created by high frequency switches on long + // wires. + always @(posedge clk) begin + // trigger_o[0] hold start + if ((trigger_o_m[0] != trigger_o_m_1[0]) & (trig_o_hold_cnt_0 == 17'd0)) begin + trig_o_hold_cnt_0 <= 17'd100000; + trig_o_hold_0 <= trigger_o_m[0]; + end + if (trig_o_hold_cnt_0 != 17'd0) begin + trig_o_hold_cnt_0 <= trig_o_hold_cnt_0 - 17'd1; + end + trigger_o_m_1[0] <= trigger_o_m[0]; + + // trigger_o[1] hold start + if ((trigger_o_m[1] != trigger_o_m_1[1]) & (trig_o_hold_cnt_1 == 17'd0)) begin + trig_o_hold_cnt_1 <= 17'd100000; + trig_o_hold_1 <= trigger_o_m[1]; + end + if (trig_o_hold_cnt_1 != 17'd0) begin + trig_o_hold_cnt_1 <= trig_o_hold_cnt_1 - 17'd1; + end + trigger_o_m_1[1] <= trigger_o_m[1]; + + // hold + trigger_o[0] <= (trig_o_hold_cnt_0 == 'd0) ? trigger_o_m[0] : trig_o_hold_0; + trigger_o[1] <= (trig_o_hold_cnt_1 == 'd0) ? trigger_o_m[1] : trig_o_hold_1; + end + + // - keep data in sync with the trigger. The trigger bypasses the variable fifo. + // The data goes through and it is delayed with 4 clock cycles) + always @(posedge clk) begin + trigger_out_m1 <= trigger_out_s; + trigger_out <= trigger_out_m1; + + // triggers logic analyzer + trigger_out_la <= trigger_out_mixed; + end + + // the embedded trigger does not require any extra delay, since the util_extract + // present in this case, delays the trigger with 2 clock cycles + assign data_a_trig = (embedded_trigger == 1'h0) ? {data_a[14],data_a[14:0]} : {trigger_out_s,data_a[14:0]}; + assign data_b_trig = (embedded_trigger == 1'h0) ? {data_b[14],data_b[14:0]} : {trigger_out_s,data_b[14:0]}; + + assign embedded_trigger = trigger_out_control[16]; + assign trigger_out_s = (trigger_delay == 32'h0) ? (trigger_out_mixed | streaming_on) : + (trigger_out_delayed | streaming_on); + assign data_valid_a_trig = data_valid_a; + assign data_valid_b_trig = data_valid_b; assign trigger_out_delayed = (trigger_delay_counter == 32'h0) ? 1 : 0; @@ -220,7 +297,7 @@ module axi_adc_trigger #( if (trigger_delay == 0) begin trigger_delay_counter <= 32'h0; end else begin - if (data_valid_a_r == 1'b1) begin + if (data_valid_a == 1'b1) begin triggered <= trigger_out_mixed | triggered; if (trigger_delay_counter == 0) begin trigger_delay_counter <= trigger_delay; @@ -236,13 +313,13 @@ module axi_adc_trigger #( always @(posedge clk) begin if (trigger_delay == 0) begin - if (streaming == 1'b1 && data_valid_a_r == 1'b1 && trigger_out_mixed == 1'b1) begin + if (streaming == 1'b1 && data_valid_a == 1'b1 && trigger_out_mixed == 1'b1) begin streaming_on <= 1'b1; end else if (streaming == 1'b0) begin streaming_on <= 1'b0; end end else begin - if (streaming == 1'b1 && data_valid_a_r == 1'b1 && trigger_out_delayed == 1'b1) begin + if (streaming == 1'b1 && data_valid_a == 1'b1 && trigger_out_delayed == 1'b1) begin streaming_on <= 1'b1; end else if (streaming == 1'b0) begin streaming_on <= 1'b0; @@ -251,7 +328,7 @@ module axi_adc_trigger #( end always @(posedge clk) begin - if (data_valid_a_r == 1'b1 && trigger_out_mixed == 1'b1) begin + if (data_valid_a == 1'b1 && trigger_out_mixed == 1'b1) begin up_triggered_set <= 1'b1; end else if (up_triggered_reset == 1'b1) begin up_triggered_set <= 1'b0; @@ -267,13 +344,6 @@ module axi_adc_trigger #( up_triggered <= up_triggered_d2; end - always @(posedge clk) begin - data_a_r <= data_a[14:0]; - data_valid_a_r <= data_valid_a; - data_b_r <= data_b[14:0]; - data_valid_b_r <= data_valid_b; - end - always @(*) begin case(trigger_l_mix_a) 4'h0: trigger_a = 1'b1; @@ -350,12 +420,16 @@ module axi_adc_trigger #( end always @(*) begin - case(trigger_out_mix) - 3'h0: trigger_out_mixed = trigger_a; - 3'h1: trigger_out_mixed = trigger_b; - 3'h2: trigger_out_mixed = trigger_a | trigger_b; - 3'h3: trigger_out_mixed = trigger_a & trigger_b; - 3'h4: trigger_out_mixed = trigger_a ^ trigger_b; + case(trigger_out_control[3:0]) + 4'h0: trigger_out_mixed = trigger_a; + 4'h1: trigger_out_mixed = trigger_b; + 4'h2: trigger_out_mixed = trigger_a | trigger_b; + 4'h3: trigger_out_mixed = trigger_a & trigger_b; + 4'h4: trigger_out_mixed = trigger_a ^ trigger_b; + 4'h5: trigger_out_mixed = trigger_in; + 4'h6: trigger_out_mixed = trigger_a | trigger_in; + 4'h7: trigger_out_mixed = trigger_b | trigger_in; + 4'h8: trigger_out_mixed = trigger_a | trigger_b | trigger_in; default: trigger_out_mixed = trigger_a; endcase end @@ -417,7 +491,7 @@ module axi_adc_trigger #( .clk(clk), .io_selection(io_selection), - .trigger_o(trigger_o), + .trigger_o(trigger_up_o_s), .triggered(up_triggered), .low_level(low_level), @@ -436,8 +510,9 @@ module axi_adc_trigger #( .hysteresis_b(hysteresis_b), .trigger_l_mix_b(trigger_l_mix_b), - .trigger_out_mix(trigger_out_mix), + .trigger_out_control(trigger_out_control), .trigger_delay(trigger_delay), + .fifo_depth(fifo_depth), .streaming(streaming), diff --git a/library/axi_adc_trigger/axi_adc_trigger_reg.v b/library/axi_adc_trigger/axi_adc_trigger_reg.v index 21432a760..4c97d45fc 100644 --- a/library/axi_adc_trigger/axi_adc_trigger_reg.v +++ b/library/axi_adc_trigger/axi_adc_trigger_reg.v @@ -39,8 +39,8 @@ module axi_adc_trigger_reg ( input clk, - output reg [ 1:0] io_selection, - output reg [ 1:0] trigger_o, + output [ 7:0] io_selection, + output [ 1:0] trigger_o, input triggered, output [ 1:0] low_level, @@ -59,9 +59,10 @@ module axi_adc_trigger_reg ( output [31:0] hysteresis_b, output [ 3:0] trigger_l_mix_b, - output [ 2:0] trigger_out_mix, + output [16:0] trigger_out_control, output [31:0] fifo_depth, output [31:0] trigger_delay, + output streaming, // bus interface @@ -79,40 +80,42 @@ module axi_adc_trigger_reg ( // internal signals - wire [ 9:0] config_trigger; + wire [ 9:0] config_trigger_i; // internal registers - reg [31:0] up_version = 32'h00010000; + reg [31:0] up_version = 32'h00030000; reg [31:0] up_scratch = 32'h0; - reg [ 9:0] up_config_trigger = 10'h0; + reg [ 7:0] up_io_selection = 8'h0; + reg [ 1:0] up_trigger_o = 2'h0; + reg [ 9:0] up_config_trigger_i = 10'h0; reg [15:0] up_limit_a = 16'h0; reg [ 1:0] up_function_a = 2'h0; reg [31:0] up_hysteresis_a = 32'h0; - reg [ 3:0] up_trigger_l_mix_a = 32'h0; + reg [ 3:0] up_trigger_l_mix_a = 4'h0; reg [15:0] up_limit_b = 16'h0; reg [ 1:0] up_function_b = 2'h0; reg [31:0] up_hysteresis_b = 32'h0; - reg [ 3:0] up_trigger_l_mix_b = 32'h0; - reg [ 2:0] up_trigger_out_mix = 32'h0; + reg [ 3:0] up_trigger_l_mix_b = 4'h0; + reg [16:0] up_trigger_out_control = 17'h0; reg [31:0] up_fifo_depth = 32'h0; reg [31:0] up_trigger_delay = 32'h0; reg up_triggered = 1'h0; reg up_streaming = 1'h0; - assign low_level = config_trigger[1:0]; - assign high_level = config_trigger[3:2]; - assign any_edge = config_trigger[5:4]; - assign rise_edge = config_trigger[7:6]; - assign fall_edge = config_trigger[9:8]; + assign low_level = config_trigger_i[1:0]; + assign high_level = config_trigger_i[3:2]; + assign any_edge = config_trigger_i[5:4]; + assign rise_edge = config_trigger_i[7:6]; + assign fall_edge = config_trigger_i[9:8]; always @(negedge up_rstn or posedge up_clk) begin if (up_rstn == 0) begin up_wack <= 'd0; up_scratch <= 'd0; - io_selection <= 'd3; - trigger_o <= 'd0; - up_config_trigger <= 'd0; + up_trigger_o <= 'd0; + up_io_selection <= 'd1; + up_config_trigger_i <= 'd0; up_limit_a <= 'd0; up_function_a <= 'd0; up_hysteresis_a <= 'd0; @@ -123,7 +126,7 @@ module axi_adc_trigger_reg ( up_trigger_delay <= 'd0; up_trigger_l_mix_a <= 'd0; up_trigger_l_mix_b <= 'd0; - up_trigger_out_mix <= 'd0; + up_trigger_out_control <= 'd0; up_triggered <= 1'd0; up_streaming <= 1'd0; end else begin @@ -132,13 +135,13 @@ module axi_adc_trigger_reg ( up_scratch <= up_wdata; end if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h2)) begin - trigger_o <= up_wdata[1:0]; + up_trigger_o <= up_wdata[1:0]; end if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h3)) begin - io_selection <= up_wdata[1:0]; + up_io_selection <= up_wdata[7:0]; end if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h4)) begin - up_config_trigger <= up_wdata[9:0]; + up_config_trigger_i <= up_wdata[9:0]; end if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'h5)) begin up_limit_a <= up_wdata[15:0]; @@ -165,7 +168,7 @@ module axi_adc_trigger_reg ( up_trigger_l_mix_b <= up_wdata[3:0]; end if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'hd)) begin - up_trigger_out_mix <= up_wdata[2:0]; + up_trigger_out_control <= up_wdata[16:0]; end if ((up_wreq == 1'b1) && (up_waddr[4:0] == 5'he)) begin up_fifo_depth <= up_wdata; @@ -196,9 +199,9 @@ module axi_adc_trigger_reg ( case (up_raddr[4:0]) 5'h0: up_rdata <= up_version; 5'h1: up_rdata <= up_scratch; - 5'h2: up_rdata <= {30'h0,trigger_o}; - 5'h3: up_rdata <= {30'h0,io_selection}; - 5'h4: up_rdata <= {22'h0,up_config_trigger}; + 5'h2: up_rdata <= {30'h0,up_trigger_o}; + 5'h3: up_rdata <= {24'h0,up_io_selection}; + 5'h4: up_rdata <= {22'h0,up_config_trigger_i}; 5'h5: up_rdata <= {16'h0,up_limit_a}; 5'h6: up_rdata <= {30'h0,up_function_a}; 5'h7: up_rdata <= up_hysteresis_a; @@ -207,7 +210,7 @@ module axi_adc_trigger_reg ( 5'ha: up_rdata <= {30'h0,up_function_b}; 5'hb: up_rdata <= up_hysteresis_b; 5'hc: up_rdata <= {28'h0,up_trigger_l_mix_b}; - 5'hd: up_rdata <= {29'h0,up_trigger_out_mix}; + 5'hd: up_rdata <= {15'h0,up_trigger_out_control}; 5'he: up_rdata <= up_fifo_depth; 5'hf: up_rdata <= {31'h0,up_triggered}; 5'h10: up_rdata <= up_trigger_delay; @@ -220,28 +223,32 @@ module axi_adc_trigger_reg ( end end - up_xfer_cntrl #(.DATA_WIDTH(186)) i_xfer_cntrl ( + up_xfer_cntrl #(.DATA_WIDTH(210)) i_xfer_cntrl ( .up_rstn (up_rstn), .up_clk (up_clk), - .up_data_cntrl ({ up_streaming, // 1 - up_config_trigger, // 10 - up_limit_a, // 16 - up_function_a, // 2 - up_hysteresis_a, // 32 - up_trigger_l_mix_a, // 4 - up_limit_b, // 16 - up_function_b, // 2 - up_hysteresis_b, // 32 - up_trigger_l_mix_b, // 4 - up_trigger_out_mix, // 3 - up_fifo_depth, // 32 - up_trigger_delay}), // 32 + .up_data_cntrl ({ up_streaming, // 1 + up_trigger_o, // 2 + up_io_selection, // 8 + up_config_trigger_i, // 10 + up_limit_a, // 16 + up_function_a, // 2 + up_hysteresis_a, // 32 + up_trigger_l_mix_a, // 4 + up_limit_b, // 16 + up_function_b, // 2 + up_hysteresis_b, // 32 + up_trigger_l_mix_b, // 4 + up_trigger_out_control, // 17 + up_fifo_depth, // 32 + up_trigger_delay}), // 32 .up_xfer_done (), .d_rst (1'b0), .d_clk (clk), .d_data_cntrl ({ streaming, // 1 - config_trigger, // 10 + trigger_o, // 2 + io_selection, // 8 + config_trigger_i, // 10 limit_a, // 16 function_a, // 2 hysteresis_a, // 32 @@ -250,7 +257,7 @@ module axi_adc_trigger_reg ( function_b, // 2 hysteresis_b, // 32 trigger_l_mix_b, // 4 - trigger_out_mix, // 3 + trigger_out_control,// 17 fifo_depth, // 32 trigger_delay})); // 32