Files
templates/hdl/logic-analyzer/rtl/la_advanced_trigger.v
T

99 lines
3.7 KiB
Verilog

`timescale 1ns / 1ps
// Eight-channel DSView Stage and Serial triggers. Each pattern contains
// level mask, expected value, and required-change mask in ascending bytes.
module la_advanced_trigger (
input wire clk, reset, arm, tick,
input wire [7:0] sample,
input wire serial_mode,
input wire [3:0] last_stage,
input wire config_write,
input wire [3:0] config_stage, config_flags,
input wire [23:0] config_a, config_b,
input wire [31:0] config_count,
output wire hit
);
reg [83:0] stages [0:15];
reg [83:0] condition;
reg [3:0] stage, last;
reg [31:0] count;
reg serial;
reg [7:0] previous;
reg previous_valid;
reg [23:0] start_flag, stop_flag, clock_flag;
reg [2:0] data_channel;
reg [15:0] data_mask, data_value, shift;
reg [4:0] bits, received;
reg serial_active;
function pattern_hit;
input [23:0] pattern;
input [7:0] value, prior;
input seen;
begin
pattern_hit = (value & pattern[7:0]) == pattern[15:8] &&
(pattern[23:16] == 0 ||
(seen && ((value ^ prior) & pattern[23:16]) == pattern[23:16]));
end
endfunction
wire a = pattern_hit(condition[23:0], sample, previous, previous_valid) ^ condition[82];
wire b = pattern_hit(condition[47:24], sample, previous, previous_valid) ^ condition[83];
wire stage_match = condition[80] ? (a && b) : (a || b);
wire stage_done = stage_match && count == condition[79:48];
wire start_hit = pattern_hit(start_flag, sample, previous, previous_valid);
wire stop_hit = stop_flag != 0 && pattern_hit(stop_flag, sample, previous, previous_valid);
wire clock_hit = pattern_hit(clock_flag, sample, previous, previous_valid);
wire [15:0] shifted = {shift[14:0], sample[data_channel]};
wire serial_hit = serial_active && !stop_hit && clock_hit &&
received >= bits && (shifted & data_mask) == data_value;
assign hit = tick && (serial ? serial_hit : stage_done && stage == last);
always @(posedge clk) begin
if (config_write) begin
stages[config_stage] <= {config_flags, config_count, config_b, config_a};
case (config_stage)
0: begin start_flag <= config_a; stop_flag <= config_b; end
1: clock_flag <= config_a;
2: data_channel <= config_count[2:0];
3: begin data_mask <= config_b[15:0]; data_value <= config_a[15:0]; bits <= config_count[4:0]; end
default: ;
endcase
end
if (reset || arm) begin
condition <= stages[0];
stage <= 0;
last <= last_stage;
count <= 0;
serial <= serial_mode;
previous_valid <= 0;
serial_active <= 0;
shift <= 0;
received <= 0;
end else if (tick) begin
previous <= sample;
previous_valid <= 1;
if (serial) begin
if (stop_hit) begin
serial_active <= 0;
shift <= 0;
received <= 0;
end else if (serial_active && clock_hit) begin
shift <= shifted;
if (received < bits)
received <= received + 1'b1;
end else if (start_hit) begin
serial_active <= 1;
end
end else if (stage_done && stage != last) begin
condition <= stages[stage + 4'd1];
stage <= stage + 1'b1;
count <= 0;
end else if (stage_match) begin
count <= count + 1'b1;
end else if (condition[81]) begin
count <= 0;
end
end
end
endmodule