Skip to content

Commit e540989

Browse files
committed
Add diagnostic display in the UI.
1 parent b467eac commit e540989

File tree

6 files changed

+129
-5
lines changed

6 files changed

+129
-5
lines changed

example/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ design_sim: design_sim.cc design.cc
99
clang++ $(CXXFLAGS) -o $@ $(abspath $^)
1010

1111
design.h: design.cc
12-
design.cc: design.v
12+
design.cc: design.sv
1313
$(YOSYS) -q $(abspath $^) -p hierarchy -p 'write_cxxrtl -header $@'
1414

1515
clean:

example/design.v renamed to example/design.sv

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,10 @@ module top(
5454
.cnt(timer),
5555
);
5656

57+
always @(*)
58+
$display("message_index = %d, timer = %d", message_index, timer);
59+
60+
always @(posedge clk)
61+
assert (timer < 5);
62+
5763
endmodule

src/extension.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as sidebar from './ui/sidebar';
55
import { globalWatchList } from './debug/watch';
66
import { globalVariableOptions } from './debug/options';
77
import { HoverProvider } from './ui/hover';
8+
import { DiagnosticProvider } from './ui/diagnostic';
89
import { inputTime } from './ui/input';
910

1011
export function activate(context: vscode.ExtensionContext) {
@@ -21,6 +22,10 @@ export function activate(context: vscode.ExtensionContext) {
2122
context.subscriptions.push(vscode.languages.registerHoverProvider(language, hoverProvider));
2223
}
2324

25+
const diagnosticCollection = vscode.languages.createDiagnosticCollection('rtlDebugger');
26+
const diagnosticProvider = new DiagnosticProvider(rtlDebugger, diagnosticCollection);
27+
context.subscriptions.push(diagnosticProvider);
28+
2429
vscode.commands.executeCommand('setContext', 'rtlDebugger.sessionStatus', rtlDebugger.sessionStatus);
2530
context.subscriptions.push(rtlDebugger.onDidChangeSessionStatus((state) =>
2631
vscode.commands.executeCommand('setContext', 'rtlDebugger.sessionStatus', state)));

src/model/source.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as vscode from 'vscode';
33
export class Location {
44
constructor(
55
readonly file: string,
6+
// All zero-based, like VS Code itself.
67
readonly startLine: number,
78
readonly startColumn?: number,
89
readonly endLine?: number,
@@ -26,10 +27,23 @@ export class Location {
2627
);
2728
}
2829

30+
get fileUri(): vscode.Uri {
31+
return vscode.Uri.file(this.file);
32+
}
33+
34+
get range(): vscode.Range {
35+
return new vscode.Range(
36+
this.startLine,
37+
this.startColumn ?? 0,
38+
this.endLine ?? this.startLine,
39+
this.endColumn ?? this.startColumn ?? 0
40+
);
41+
}
42+
2943
private openCommandArguments(): [vscode.Uri, vscode.TextDocumentShowOptions] {
30-
const position = new vscode.Position(this.startLine || 0, this.startColumn || 0);
44+
const position = new vscode.Position(this.startLine, this.startColumn ?? 0);
3145
return [
32-
vscode.Uri.parse(this.file),
46+
this.fileUri,
3347
{
3448
selection: new vscode.Selection(position, position),
3549
preview: true,

src/ui/diagnostic.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import * as vscode from 'vscode';
2+
3+
import { CXXRTLDebugger } from '../debugger';
4+
import { Diagnostic, DiagnosticType } from '../model/sample';
5+
import { Session } from '../debug/session';
6+
7+
export class DiagnosticProvider {
8+
constructor(
9+
private rtlDebugger: CXXRTLDebugger,
10+
private diagnosticCollection: vscode.DiagnosticCollection,
11+
) {
12+
rtlDebugger.onDidChangeSession((session) => {
13+
this.update(session);
14+
if (session !== null) {
15+
session.onDidChangeSimulationStatus((_simulationStatus) => this.update(session));
16+
session.onDidChangeTimeCursor((_timeCursor) => this.update(session));
17+
}
18+
});
19+
}
20+
21+
dispose() {
22+
this.diagnosticCollection.dispose();
23+
}
24+
25+
private async update(session: Session | null) {
26+
if (session === null || session?.simulationStatus.status === 'running') {
27+
this.apply([]);
28+
} else {
29+
const sample = await session.queryAtCursor({ diagnostics: true });
30+
this.apply(sample.diagnostics!);
31+
}
32+
}
33+
34+
private apply(diagnostics: Diagnostic[]) {
35+
const diagnosticMap = new Map();
36+
for (const diagnostic of diagnostics) {
37+
if (diagnostic.location === null) {
38+
continue;
39+
}
40+
const uri = diagnostic.location.fileUri;
41+
const range = diagnostic.location.range;
42+
if (!diagnosticMap.has(uri)) {
43+
diagnosticMap.set(uri, []);
44+
}
45+
46+
console.warn('[RTL Debugger]', diagnostic);
47+
48+
let message;
49+
let severity;
50+
switch (diagnostic.type) {
51+
case DiagnosticType.Break:
52+
if (diagnostic.text !== '') {
53+
message = `breakpoint: ${diagnostic.text}`;
54+
} else {
55+
message = 'breakpoint';
56+
}
57+
severity = vscode.DiagnosticSeverity.Warning;
58+
break;
59+
60+
case DiagnosticType.Print:
61+
message = diagnostic.text;
62+
severity = vscode.DiagnosticSeverity.Information;
63+
break;
64+
65+
case DiagnosticType.Assert:
66+
if (diagnostic.text !== '') {
67+
message = `assertion violated: ${diagnostic.text}`;
68+
} else {
69+
message = 'assertion violated';
70+
}
71+
severity = vscode.DiagnosticSeverity.Error;
72+
break;
73+
74+
case DiagnosticType.Assume:
75+
if (diagnostic.text !== '') {
76+
message = `assumption violated: ${diagnostic.text}`;
77+
} else {
78+
message = 'assumption violated';
79+
}
80+
severity = vscode.DiagnosticSeverity.Error;
81+
break;
82+
83+
default:
84+
message = `(unknown diagnostic type ${diagnostic.type}): ${diagnostic.text}`;
85+
severity = vscode.DiagnosticSeverity.Error;
86+
break;
87+
}
88+
if (message !== '') {
89+
const mappedDiagnostic = new vscode.Diagnostic(range, message, severity);
90+
mappedDiagnostic.code = <string>diagnostic.type;
91+
mappedDiagnostic.source = 'RTL Debug';
92+
diagnosticMap.get(uri).push(mappedDiagnostic);
93+
}
94+
}
95+
96+
this.diagnosticCollection.clear();
97+
this.diagnosticCollection.set(Array.from(diagnosticMap.entries()));
98+
}
99+
}

src/ui/status.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ export class StatusBarItem {
1212
rtlDebugger.onDidChangeSession((session) => {
1313
this.update(session);
1414
if (session !== null) {
15-
session.onDidChangeSimulationStatus((_status) => this.update(session));
16-
session.onDidChangeTimeCursor((_time) => this.update(session));
15+
session.onDidChangeSimulationStatus((_simulationStatus) => this.update(session));
16+
session.onDidChangeTimeCursor((_timeCursor) => this.update(session));
1717
}
1818
});
1919
}

0 commit comments

Comments
 (0)