Trigger selection
This commit is contained in:
@@ -30,9 +30,10 @@ module signal_scope_q15 #(
|
|||||||
reg scope_armed;
|
reg scope_armed;
|
||||||
reg scope_triggered;
|
reg scope_triggered;
|
||||||
reg capture_done;
|
reg capture_done;
|
||||||
|
reg [1:0] trigger_channel;
|
||||||
reg [15:0] trig_val;
|
reg [15:0] trig_val;
|
||||||
reg [15:0] signal_a_prev;
|
reg [15:0] trigger_prev;
|
||||||
reg signal_a_prev_valid;
|
reg trigger_prev_valid;
|
||||||
|
|
||||||
reg [15:0] signal_a;
|
reg [15:0] signal_a;
|
||||||
reg [15:0] signal_b;
|
reg [15:0] signal_b;
|
||||||
@@ -54,6 +55,8 @@ module signal_scope_q15 #(
|
|||||||
wire [aw-1:0] wb_mem_idx = wb_adr[aw+2:3];
|
wire [aw-1:0] wb_mem_idx = wb_adr[aw+2:3];
|
||||||
wire wb_is_reg = (wb_adr[31:28] == reg_base_addr[31:28]);
|
wire wb_is_reg = (wb_adr[31:28] == reg_base_addr[31:28]);
|
||||||
wire [3:0] wb_reg_idx = wb_adr[5:2];
|
wire [3:0] wb_reg_idx = wb_adr[5:2];
|
||||||
|
reg [15:0] trigger_sample;
|
||||||
|
reg trigger_sample_valid;
|
||||||
|
|
||||||
jtag_wb_bridge #(
|
jtag_wb_bridge #(
|
||||||
.chain(chain),
|
.chain(chain),
|
||||||
@@ -72,6 +75,27 @@ module signal_scope_q15 #(
|
|||||||
.o_cmd_reset()
|
.o_cmd_reset()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
always @(*) begin
|
||||||
|
case(trigger_channel)
|
||||||
|
2'd0: begin
|
||||||
|
trigger_sample = i_signal_a;
|
||||||
|
trigger_sample_valid = i_signal_valid_a;
|
||||||
|
end
|
||||||
|
2'd1: begin
|
||||||
|
trigger_sample = i_signal_b;
|
||||||
|
trigger_sample_valid = i_signal_valid_b;
|
||||||
|
end
|
||||||
|
2'd2: begin
|
||||||
|
trigger_sample = i_signal_c;
|
||||||
|
trigger_sample_valid = i_signal_valid_c;
|
||||||
|
end
|
||||||
|
default: begin
|
||||||
|
trigger_sample = i_signal_d;
|
||||||
|
trigger_sample_valid = i_signal_valid_d;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
always @(posedge i_clk) begin
|
always @(posedge i_clk) begin
|
||||||
if(i_rst) begin
|
if(i_rst) begin
|
||||||
counter <= {aw{1'b0}};
|
counter <= {aw{1'b0}};
|
||||||
@@ -81,11 +105,12 @@ module signal_scope_q15 #(
|
|||||||
scope_armed <= 1'b0;
|
scope_armed <= 1'b0;
|
||||||
scope_triggered <= 1'b0;
|
scope_triggered <= 1'b0;
|
||||||
capture_done <= 1'b0;
|
capture_done <= 1'b0;
|
||||||
|
trigger_channel <= 2'd0;
|
||||||
wb_ack <= 1'b0;
|
wb_ack <= 1'b0;
|
||||||
wb_rdt <= 32'b0;
|
wb_rdt <= 32'b0;
|
||||||
trig_val <= 16'h0000;
|
trig_val <= 16'h0000;
|
||||||
signal_a_prev <= 16'h0000;
|
trigger_prev <= 16'h0000;
|
||||||
signal_a_prev_valid <= 1'b0;
|
trigger_prev_valid <= 1'b0;
|
||||||
signal_a <= 0;
|
signal_a <= 0;
|
||||||
signal_b <= 0;
|
signal_b <= 0;
|
||||||
signal_c <= 0;
|
signal_c <= 0;
|
||||||
@@ -100,18 +125,6 @@ module signal_scope_q15 #(
|
|||||||
if(i_signal_valid_a) begin
|
if(i_signal_valid_a) begin
|
||||||
signal_a <= i_signal_a;
|
signal_a <= i_signal_a;
|
||||||
signal_a_pending <= 1'b1;
|
signal_a_pending <= 1'b1;
|
||||||
|
|
||||||
// Trigger on signal_a rising across trig_val.
|
|
||||||
if(scope_armed && trigger_enable && !count_enable) begin
|
|
||||||
if(signal_a_prev_valid &&
|
|
||||||
($signed(signal_a_prev) < $signed(trig_val)) &&
|
|
||||||
($signed(i_signal_a) >= $signed(trig_val))) begin
|
|
||||||
count_enable <= 1'b1;
|
|
||||||
scope_triggered <= 1'b1;
|
|
||||||
end
|
|
||||||
signal_a_prev <= i_signal_a;
|
|
||||||
signal_a_prev_valid <= 1'b1;
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
if(i_signal_valid_b) begin
|
if(i_signal_valid_b) begin
|
||||||
signal_b <= i_signal_b;
|
signal_b <= i_signal_b;
|
||||||
@@ -126,6 +139,18 @@ module signal_scope_q15 #(
|
|||||||
signal_d_pending <= 1'b1;
|
signal_d_pending <= 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
// Trigger on selected channel rising across trig_val.
|
||||||
|
if(scope_armed && trigger_enable && !count_enable && trigger_sample_valid) begin
|
||||||
|
if(trigger_prev_valid &&
|
||||||
|
($signed(trigger_prev) < $signed(trig_val)) &&
|
||||||
|
($signed(trigger_sample) >= $signed(trig_val))) begin
|
||||||
|
count_enable <= 1'b1;
|
||||||
|
scope_triggered <= 1'b1;
|
||||||
|
end
|
||||||
|
trigger_prev <= trigger_sample;
|
||||||
|
trigger_prev_valid <= 1'b1;
|
||||||
|
end
|
||||||
|
|
||||||
// Arm/rearm capture. If trigger is disabled, start capture immediately.
|
// Arm/rearm capture. If trigger is disabled, start capture immediately.
|
||||||
if(arm_req) begin
|
if(arm_req) begin
|
||||||
counter <= {aw{1'b0}};
|
counter <= {aw{1'b0}};
|
||||||
@@ -133,7 +158,7 @@ module signal_scope_q15 #(
|
|||||||
scope_armed <= 1'b1;
|
scope_armed <= 1'b1;
|
||||||
scope_triggered <= !trigger_enable;
|
scope_triggered <= !trigger_enable;
|
||||||
capture_done <= 1'b0;
|
capture_done <= 1'b0;
|
||||||
signal_a_prev_valid <= 1'b0;
|
trigger_prev_valid <= 1'b0;
|
||||||
signal_a_pending <= 1'b0;
|
signal_a_pending <= 1'b0;
|
||||||
signal_b_pending <= 1'b0;
|
signal_b_pending <= 1'b0;
|
||||||
signal_c_pending <= 1'b0;
|
signal_c_pending <= 1'b0;
|
||||||
@@ -178,6 +203,8 @@ module signal_scope_q15 #(
|
|||||||
arm_req <= 1'b1;
|
arm_req <= 1'b1;
|
||||||
// Bit 1: trigger enable.
|
// Bit 1: trigger enable.
|
||||||
trigger_enable <= wb_dat[1];
|
trigger_enable <= wb_dat[1];
|
||||||
|
// Bits [3:2]: trigger channel (0=a,1=b,2=c,3=d).
|
||||||
|
trigger_channel <= wb_dat[3:2];
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
reg_trig_val: begin
|
reg_trig_val: begin
|
||||||
@@ -191,8 +218,8 @@ module signal_scope_q15 #(
|
|||||||
end else begin
|
end else begin
|
||||||
if(wb_is_reg) begin
|
if(wb_is_reg) begin
|
||||||
case(wb_reg_idx)
|
case(wb_reg_idx)
|
||||||
// [1]=trigger_enable, [0]=arm bit is write-pulse only.
|
// [3:2]=trigger_channel, [1]=trigger_enable, [0]=arm(write pulse only/read 0).
|
||||||
reg_control: wb_rdt <= {30'b0, trigger_enable, 1'b0};
|
reg_control: wb_rdt <= {28'b0, trigger_channel, trigger_enable, 1'b0};
|
||||||
// [0]=triggered, [1]=capturing, [2]=armed, [3]=done
|
// [0]=triggered, [1]=capturing, [2]=armed, [3]=done
|
||||||
reg_status: wb_rdt <= {28'b0, capture_done, scope_armed, count_enable, scope_triggered};
|
reg_status: wb_rdt <= {28'b0, capture_done, scope_armed, count_enable, scope_triggered};
|
||||||
reg_trig_val: wb_rdt <= {16'b0, trig_val};
|
reg_trig_val: wb_rdt <= {16'b0, trig_val};
|
||||||
|
|||||||
@@ -53,6 +53,12 @@ def parse_args() -> argparse.Namespace:
|
|||||||
default=None,
|
default=None,
|
||||||
help="Optional trigger threshold (16-bit, signal_a rising crossing). If omitted, triggering is disabled.",
|
help="Optional trigger threshold (16-bit, signal_a rising crossing). If omitted, triggering is disabled.",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--trigger-channel",
|
||||||
|
choices=["a", "b", "c", "d"],
|
||||||
|
default="a",
|
||||||
|
help="Trigger source channel when triggering is enabled",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--unsigned",
|
"--unsigned",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
@@ -81,15 +87,20 @@ def parse_args() -> argparse.Namespace:
|
|||||||
def capture_once(bridge, args: argparse.Namespace) -> list[tuple[int, int, int, int]]:
|
def capture_once(bridge, args: argparse.Namespace) -> list[tuple[int, int, int, int]]:
|
||||||
samples = []
|
samples = []
|
||||||
frame_count = args.depth
|
frame_count = args.depth
|
||||||
|
trigger_channel_map = {"a": 0, "b": 1, "c": 2, "d": 3}
|
||||||
|
trigger_channel = trigger_channel_map[args.trigger_channel]
|
||||||
if args.trigger_value is None:
|
if args.trigger_value is None:
|
||||||
print("[signal_scope] Arming scope with trigger disabled...")
|
print("[signal_scope] Arming scope with trigger disabled...")
|
||||||
bridge.write32(REG_CONTROL, 0x1) # bit0: arm pulse, bit1: trigger enable=0
|
bridge.write32(REG_CONTROL, 0x1) # bit0: arm pulse, bit1: trigger enable=0
|
||||||
else:
|
else:
|
||||||
trig_val = args.trigger_value & 0xFFFF
|
trig_val = args.trigger_value & 0xFFFF
|
||||||
print(f"[signal_scope] Config trigger: trig_val=0x{trig_val:04x}, source=signal_a rising")
|
print(
|
||||||
|
f"[signal_scope] Config trigger: trig_val=0x{trig_val:04x}, "
|
||||||
|
f"source=signal_{args.trigger_channel} rising"
|
||||||
|
)
|
||||||
bridge.write32(REG_TRIG_VAL, trig_val)
|
bridge.write32(REG_TRIG_VAL, trig_val)
|
||||||
print("[signal_scope] Arming scope with trigger enabled...")
|
print("[signal_scope] Arming scope with trigger enabled...")
|
||||||
bridge.write32(REG_CONTROL, 0x3) # bit0: arm pulse, bit1: trigger enable
|
bridge.write32(REG_CONTROL, 0x3 | (trigger_channel << 2)) # bit0: arm, bit1: trig_en, bits[3:2]: channel
|
||||||
|
|
||||||
# Wait until the new arm command is active, then wait for its trigger event.
|
# Wait until the new arm command is active, then wait for its trigger event.
|
||||||
while (bridge.read32(REG_STATUS) & 0x4) == 0:
|
while (bridge.read32(REG_STATUS) & 0x4) == 0:
|
||||||
|
|||||||
Reference in New Issue
Block a user