Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[proposal][wip] Add event trace configuration to mlir-aie#2705

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
fifield wants to merge41 commits intoXilinx:main
base:main
Choose a base branch
Loading
fromfifield:events_proposal
Draft
Show file tree
Hide file tree
Changes from1 commit
Commits
Show all changes
41 commits
Select commitHold shift + click to select a range
80a48e3
Add a callable library function to parse_trace.py
fifieldNov 13, 2025
733652a
Apply suggestions from code review
fifieldNov 13, 2025
edee5a6
Generate trace_events package with CMake instead of checking into git
fifieldNov 10, 2025
7a7e694
Apply suggestions from code review
fifieldNov 11, 2025
a1cb4cf
Make duplicate event number detection fail the build (#2697)
CopilotNov 11, 2025
e1bfbde
Generate and include tablegen event enums in AIE dialect
fifieldNov 14, 2025
543bedb
Commit 1: Add TableGen definitions for trace operations
fifieldNov 8, 2025
c5e52d5
Commit 2: Add verification tests for trace operations
fifieldNov 8, 2025
7034d74
Commit 3: Implement standalone JSON register database loader
fifieldNov 8, 2025
6c506c6
Commit 4: Implement AIETraceToConfigPass
fifieldNov 8, 2025
c7c734c
Commit 5: Implement AIEInlineTraceConfigPass
fifieldNov 8, 2025
c4c8b5e
Commit 6: Add AIEConfigToNPUPass stub implementation
fifieldNov 8, 2025
a25c6fe
Commit 7: Add end-to-end trace pipeline test
fifieldNov 8, 2025
b4f5660
Complete Pass 3 implementation with RegisterDatabase integration
fifieldNov 8, 2025
b611636
Refactor: Fix design issue with col/row preservation
fifieldNov 8, 2025
248af1c
Move trace NPU passes to AIEX dialect (fixes AIEX loading issue)
fifieldNov 8, 2025
9a4ff28
Move and update trace tests to AIEX dialect
fifieldNov 8, 2025
184c25d
Update AIEX tests to use runtime_sequence
fifieldNov 8, 2025
10449f3
checkpoint
fifieldNov 10, 2025
4a4e41f
start a test
fifieldNov 11, 2025
300908f
format
fifieldNov 11, 2025
6b591cc
checkpoint
fifieldNov 11, 2025
97007eb
updates, fixes, formatting
fifieldNov 12, 2025
caaf7f4
clang-format
fifieldNov 12, 2025
b58edf2
remove aie-config-to-npu placeholder
fifieldNov 12, 2025
6556d01
fixes for core mem events
fifieldNov 12, 2025
1635816
fix test location
fifieldNov 12, 2025
aa79764
Add stream switch port event monitoring to AIE trace infrastructure
fifieldNov 13, 2025
41ba2c7
update example to use aie.trace.port
fifieldNov 13, 2025
bb18de2
Replace BoolAttr with DMAChannelDir for trace port direction
fifieldNov 13, 2025
ebfab0d
Add test.py for trace example
fifieldNov 13, 2025
6095f3a
implement trace and combo event op tablegen
fifieldNov 14, 2025
7907894
Update lower pass for combo and edge events
fifieldNov 14, 2025
01c9a32
Update dialect to use generated enums for events
fifieldNov 15, 2025
a2433db
fix aie1 suffix
fifieldNov 15, 2025
e6a6457
checkpoint
fifieldNov 15, 2025
2532c8a
fixes, format, refactor, cleanup
fifieldNov 15, 2025
2e0fc12
checkpoint
fifieldNov 15, 2025
ef6c53e
wip
fifieldNov 16, 2025
cc56b4d
cleanup, fixes, refactor
fifieldNov 17, 2025
fc99d49
implement AIETargetModel getStreamSwitchPortIndex
fifieldNov 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PrevPrevious commit
NextNext commit
implement trace and combo event op tablegen
  • Loading branch information
@fifield
fifield committedNov 14, 2025
commit6095f3aaba3121659f99fbffce588091d95e71d1
51 changes: 51 additions & 0 deletionsinclude/aie/Dialect/AIE/IR/AIETraceAttrs.td
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -94,4 +94,55 @@ def TraceEventAttr : AttrDef<AIE_Dialect, "TraceEvent"> {
let assemblyFormat = "`<` $name `>`";
}

//===----------------------------------------------------------------------===//
// Combo Event Logic Enumeration
//===----------------------------------------------------------------------===//

def ComboLogicAND : I32EnumAttrCase<"AND", 0, "AND">;
def ComboLogicAND_NOT : I32EnumAttrCase<"AND_NOT", 1, "AND_NOT">;
def ComboLogicOR : I32EnumAttrCase<"OR", 2, "OR">;
def ComboLogicOR_NOT : I32EnumAttrCase<"OR_NOT", 3, "OR_NOT">;

def ComboLogicAttr : I32EnumAttr<"ComboLogic",
"Combo event logic function",
[
ComboLogicAND,
ComboLogicAND_NOT,
ComboLogicOR,
ComboLogicOR_NOT
]> {
let cppNamespace = "::xilinx::AIE";
let description = [{
Logical operation for combining two events:
- AND (00): eventA AND eventB
- AND_NOT (01): eventA AND NOT eventB
- OR (10): eventA OR eventB
- OR_NOT (11): eventA OR NOT eventB
}];
}

//===----------------------------------------------------------------------===//
// Edge Detection Trigger Mode Enumeration
//===----------------------------------------------------------------------===//

def EdgeTriggerRISING : I32EnumAttrCase<"RISING", 1, "RISING">;
def EdgeTriggerFALLING : I32EnumAttrCase<"FALLING", 2, "FALLING">;
def EdgeTriggerBOTH : I32EnumAttrCase<"BOTH", 3, "BOTH">;

def EdgeTriggerAttr : I32EnumAttr<"EdgeTrigger",
"Edge detection trigger mode",
[
EdgeTriggerRISING,
EdgeTriggerFALLING,
EdgeTriggerBOTH
]> {
let cppNamespace = "::xilinx::AIE";
let description = [{
Edge detection trigger mode:
- RISING (01): Trigger on rising edge (0→1 transition)
- FALLING (10): Trigger on falling edge (1→0 transition)
- BOTH (11): Trigger on both edges
}];
}

#endif // AIE_TRACE_ATTRS
110 changes: 110 additions & 0 deletionsinclude/aie/Dialect/AIE/IR/AIETraceOps.td
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -359,6 +359,116 @@ def AIE_TraceRegOp : AIE_Op<"trace.reg", [
}];
}

//===----------------------------------------------------------------------===//
// AIE_TraceComboEventOp - Combo Event Configuration (within trace)
//===----------------------------------------------------------------------===//

def AIE_TraceComboEventOp : AIE_Op<"trace.combo_event", [
HasParent<"TraceOp">
]> {
let summary = "Configure a combo event for logical event combinations";

let description = [{
Configures a combo event that creates a derived event from logical
combinations of other events. Combo events are evaluated by hardware
Event Logic and produce new events (COMBO_EVENT_0/1/2/3) that can be
traced using aie.trace.event operations.

The combo event is configured with two input events and a logic function
(AND, AND_NOT, OR, OR_NOT). AIE2 supports hierarchical combinations
through slot 2 (combo of combo0 and combo1 results).

Slots:
- Slot 0 (combo0): uses eventA, eventB
- Slot 1 (combo1): uses eventC, eventD
- Slot 2 (combo2): hierarchical, uses COMBO_EVENT_0 and COMBO_EVENT_1
- Slot 3 (combo3): architecture-specific state machine (no configuration)

Example:
```mlir
aie.trace @my_trace(%tile02) {
// Combo 0: lock stalled AND NOT DMA active
aie.trace.combo_event<0> "LOCK_STALL" AND_NOT "DMA_S2MM_0_STALLED"

// Combo 1: instruction event OR vector operation
aie.trace.combo_event<1> "INSTR_EVENT_0" OR "INSTR_VECTOR"

// Combo 2: (combo0) AND (combo1)
aie.trace.combo_event<2> "COMBO_EVENT_0" AND "COMBO_EVENT_1"

// Trace the combo results
aie.trace.event<"COMBO_EVENT_0">
aie.trace.event<"COMBO_EVENT_1">
aie.trace.event<"COMBO_EVENT_2">
...
}
```
}];

let arguments = (ins
AIEI32Attr:$slot, // 0, 1, or 2
TraceEventAttr:$eventA, // First input event
ComboLogicAttr:$logic, // Logic function
TraceEventAttr:$eventB // Second input event
);

let assemblyFormat = [{
`<` $slot `>` $eventA $logic $eventB attr-dict
}];

let hasVerifier = 1;
}

//===----------------------------------------------------------------------===//
// AIE_TraceEdgeEventOp - Edge Detection Event Configuration (within trace)
//===----------------------------------------------------------------------===//

def AIE_TraceEdgeEventOp : AIE_Op<"trace.edge_event", [
HasParent<"TraceOp">
]> {
let summary = "Configure an edge detection event";

let description = [{
Configures an edge detection event that triggers on signal transitions
(rising edge, falling edge, or both) rather than signal levels.

Edge detection is useful for counting event occurrences rather than
measuring duration. For example, counting the number of lock stalls
vs. the total cycles spent stalled.

Each module has 2 edge detectors producing EDGE_DETECTION_EVENT_0/1
that can be traced using aie.trace.event operations.

Example:
```mlir
aie.trace @my_trace(%tile02) {
// Edge detector 0: count lock stalls (rising edges)
aie.trace.edge_event<0> event="LOCK_STALL" trigger=RISING

// Edge detector 1: count DMA transitions (both edges)
aie.trace.edge_event<1> event="DMA_MM2S_0_FINISHED_BD" trigger=BOTH

// Trace the edge-detected events
aie.trace.event<"EDGE_DETECTION_EVENT_0">
aie.trace.event<"EDGE_DETECTION_EVENT_1">
...
}
```
}];

let arguments = (ins
AIEI32Attr:$slot, // 0 or 1
TraceEventAttr:$event, // Source event to monitor
EdgeTriggerAttr:$trigger // RISING, FALLING, or BOTH
);

let assemblyFormat = [{
`<` $slot `>` `event` `=` $event `trigger` `=` $trigger attr-dict
}];

let hasVerifier = 1;
}

//===----------------------------------------------------------------------===//
// AIE_TraceStartConfigOp - Runtime Configuration Invocation
//===----------------------------------------------------------------------===//
Expand Down
94 changes: 94 additions & 0 deletionslib/Dialect/AIE/IR/AIETraceOps.cpp
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,6 +49,26 @@ LogicalResult TraceOp::verify() {
return emitOpError("tile operand must be a TileOp");
}

// Track combo/edge slot usage within this trace
llvm::DenseSet<uint32_t> comboSlots;
llvm::DenseSet<uint32_t> edgeSlots;

for (auto &op : getBody().getOps()) {
if (auto comboOp = dyn_cast<TraceComboEventOp>(op)) {
uint32_t slot = comboOp.getSlot();
if (!comboSlots.insert(slot).second) {
return comboOp.emitOpError("combo event slot ")
<< slot << " already in use in this trace";
}
} else if (auto edgeOp = dyn_cast<TraceEdgeEventOp>(op)) {
uint32_t slot = edgeOp.getSlot();
if (!edgeSlots.insert(slot).second) {
return edgeOp.emitOpError("edge detection slot ")
<< slot << " already in use in this trace";
}
}
}

return success();
}

Expand DownExpand Up@@ -164,6 +184,80 @@ LogicalResult TraceStopEventOp::verify() {
return success();
}

//===----------------------------------------------------------------------===//
// TraceComboEventOp
//===----------------------------------------------------------------------===//

LogicalResult TraceComboEventOp::verify() {
uint32_t slot = getSlot();

// Check slot is valid (0, 1, or 2)
if (slot > 2) {
return emitOpError("combo event slot must be 0, 1, or 2, got ") << slot;
}

// Validate event selection based on slot
std::string eventAName = getEventA().getName().str();
std::string eventBName = getEventB().getName().str();

if (slot == 0) {
// Combo 0: should not use eventC/D or combo results
if (eventAName.find("COMBO_EVENT") != std::string::npos ||
eventBName.find("COMBO_EVENT") != std::string::npos) {
return emitOpError("combo slot 0 should use regular events, not "
"COMBO_EVENT_* (uses eventA/B)");
}
} else if (slot == 1) {
// Combo 1: should not use combo results
if (eventAName.find("COMBO_EVENT") != std::string::npos ||
eventBName.find("COMBO_EVENT") != std::string::npos) {
return emitOpError("combo slot 1 should use regular events, not "
"COMBO_EVENT_* (uses eventC/D)");
}
} else if (slot == 2) {
// Combo 2 is hierarchical - must use COMBO_EVENT_0 and COMBO_EVENT_1
if (eventAName != "COMBO_EVENT_0") {
return emitOpError("combo slot 2 first event must be COMBO_EVENT_0 "
"(hierarchical), got ")
<< eventAName;
}
if (eventBName != "COMBO_EVENT_1") {
return emitOpError("combo slot 2 second event must be COMBO_EVENT_1 "
"(hierarchical), got ")
<< eventBName;
}
}

return success();
}

//===----------------------------------------------------------------------===//
// TraceEdgeEventOp
//===----------------------------------------------------------------------===//

LogicalResult TraceEdgeEventOp::verify() {
uint32_t slot = getSlot();

// Check slot is valid (0 or 1)
if (slot > 1) {
return emitOpError("edge detection slot must be 0 or 1, got ") << slot;
}

// Edge events should not be other edge/combo events
std::string eventName = getEvent().getName().str();
if (eventName.find("EDGE_DETECTION_EVENT") != std::string::npos) {
return emitOpError("edge detection source should be a regular event, not "
"another EDGE_DETECTION_EVENT");
}
if (eventName.find("COMBO_EVENT") != std::string::npos) {
return emitOpError("edge detection source should be a regular event, not "
"a COMBO_EVENT (combo events can be used but may have "
"unexpected behavior)");
}

return success();
}

//===----------------------------------------------------------------------===//
// TraceStartConfigOp
//===----------------------------------------------------------------------===//
Expand Down
86 changes: 86 additions & 0 deletionstest/Dialect/AIE/combo_edge/test_combo_event_parse.mlir
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
// RUN: aie-opt %s | FileCheck %s

aie.device(npu1_1col) {
%tile02 = aie.tile(0, 2)

// CHECK-LABEL: @test_combo_basic
aie.trace @test_combo_basic(%tile02) {
// CHECK: aie.trace.combo_event<0> <"LOCK_STALL"> AND <"DMA_S2MM_0_STALLED">
aie.trace.combo_event<0> <"LOCK_STALL"> AND <"DMA_S2MM_0_STALLED">

// CHECK: aie.trace.combo_event<1> <"INSTR_EVENT_0"> OR <"INSTR_VECTOR">
aie.trace.combo_event<1> <"INSTR_EVENT_0"> OR <"INSTR_VECTOR">

// CHECK: aie.trace.event <"COMBO_EVENT_0">
aie.trace.event<"COMBO_EVENT_0">
}

// CHECK-LABEL: @test_edge_basic
aie.trace @test_edge_basic(%tile02) {
// CHECK: aie.trace.edge_event<0> event = <"LOCK_STALL"> trigger = RISING
aie.trace.edge_event<0> event=<"LOCK_STALL"> trigger=RISING

// CHECK: aie.trace.edge_event<1> event = <"DMA_MM2S_0_FINISHED_BD"> trigger = BOTH
aie.trace.edge_event<1> event=<"DMA_MM2S_0_FINISHED_BD"> trigger=BOTH

// CHECK: aie.trace.event <"EDGE_DETECTION_EVENT_0">
aie.trace.event<"EDGE_DETECTION_EVENT_0">
}

// CHECK-LABEL: @test_hierarchical
aie.trace @test_hierarchical(%tile02) {
// CHECK: aie.trace.combo_event<0> <"LOCK_STALL"> AND <"DMA_S2MM_0_STALLED">
aie.trace.combo_event<0> <"LOCK_STALL"> AND <"DMA_S2MM_0_STALLED">

// CHECK: aie.trace.combo_event<1> <"INSTR_EVENT_0"> OR <"INSTR_VECTOR">
aie.trace.combo_event<1> <"INSTR_EVENT_0"> OR <"INSTR_VECTOR">

// CHECK: aie.trace.combo_event<2> <"COMBO_EVENT_0"> AND <"COMBO_EVENT_1">
aie.trace.combo_event<2> <"COMBO_EVENT_0"> AND <"COMBO_EVENT_1">

// CHECK: aie.trace.event <"COMBO_EVENT_2">
aie.trace.event<"COMBO_EVENT_2">
}

// CHECK-LABEL: @test_all_logic
aie.trace @test_all_logic(%tile02) {
// CHECK: aie.trace.combo_event<0> <"LOCK_STALL"> AND <"DMA_S2MM_0_STALLED">
aie.trace.combo_event<0> <"LOCK_STALL"> AND <"DMA_S2MM_0_STALLED">
}

// CHECK-LABEL: @test_and_not
aie.trace @test_and_not(%tile02) {
// CHECK: aie.trace.combo_event<0> <"LOCK_STALL"> AND_NOT <"DMA_S2MM_0_STALLED">
aie.trace.combo_event<0> <"LOCK_STALL"> AND_NOT <"DMA_S2MM_0_STALLED">
}

// CHECK-LABEL: @test_or
aie.trace @test_or(%tile02) {
// CHECK: aie.trace.combo_event<0> <"LOCK_STALL"> OR <"DMA_S2MM_0_STALLED">
aie.trace.combo_event<0> <"LOCK_STALL"> OR <"DMA_S2MM_0_STALLED">
}

// CHECK-LABEL: @test_or_not
aie.trace @test_or_not(%tile02) {
// CHECK: aie.trace.combo_event<0> <"LOCK_STALL"> OR_NOT <"DMA_S2MM_0_STALLED">
aie.trace.combo_event<0> <"LOCK_STALL"> OR_NOT <"DMA_S2MM_0_STALLED">
}

// CHECK-LABEL: @test_rising
aie.trace @test_rising(%tile02) {
// CHECK: aie.trace.edge_event<0> event = <"LOCK_STALL"> trigger = RISING
aie.trace.edge_event<0> event=<"LOCK_STALL"> trigger=RISING
}

// CHECK-LABEL: @test_falling
aie.trace @test_falling(%tile02) {
// CHECK: aie.trace.edge_event<0> event = <"LOCK_STALL"> trigger = FALLING
aie.trace.edge_event<0> event=<"LOCK_STALL"> trigger=FALLING
}

// CHECK-LABEL: @test_both
aie.trace @test_both(%tile02) {
// CHECK: aie.trace.edge_event<0> event = <"LOCK_STALL"> trigger = BOTH
aie.trace.edge_event<0> event=<"LOCK_STALL"> trigger=BOTH
}
}
Loading

[8]ページ先頭

©2009-2025 Movatter.jp