99 lines
3.7 KiB
Verilog
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
|