Skip to content

Commit

Permalink
Implement configurable radix.
Browse files Browse the repository at this point in the history
  • Loading branch information
whitequark committed Oct 8, 2024
1 parent de28e8a commit 8ddd697
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 26 deletions.
11 changes: 10 additions & 1 deletion example/.vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,14 @@
"rtlDebugger.command": [
"${workspaceFolder}/design_sim"
],
"rtlDebugger.watchList": []
"rtlDebugger.watchList": [
{
"id": "data"
}
],
"rtlDebugger.variableOptions": {
"data": {
"radix": 16
}
}
}
65 changes: 62 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@
"default": "Verilog",
"markdownDescription": "Specifies the display format for variables."
},
"rtlDebugger.variableOptions": {
"type": "object",
"patternProperties": {
"": {
"type": "object",
"properties": {
"radix": "number"
}
}
}
},
"rtlDebugger.watchList": {
"type": "array",
"items": {
Expand Down Expand Up @@ -117,6 +128,26 @@
"title": "Step Backward",
"icon": "$(debug-step-back)"
},
{
"command": "rtlDebugger.setRadix.2",
"category": "RTL Debugger",
"title": "Use Radix 2"
},
{
"command": "rtlDebugger.setRadix.8",
"category": "RTL Debugger",
"title": "Use Radix 8"
},
{
"command": "rtlDebugger.setRadix.10",
"category": "RTL Debugger",
"title": "Use Radix 10"
},
{
"command": "rtlDebugger.setRadix.16",
"category": "RTL Debugger",
"title": "Use Radix 16"
},
{
"command": "rtlDebugger.watchVariable",
"category": "RTL Debugger",
Expand Down Expand Up @@ -223,18 +254,46 @@
}
],
"view/item/context": [
{
"submenu": "rtlDebugger.setRadix",
"when": "view == rtlDebugger.sidebar && viewItem =~ /canSetRadix/"
},
{
"command": "rtlDebugger.watchVariable",
"when": "view == rtlDebugger.sidebar && viewItem == canWatch",
"when": "view == rtlDebugger.sidebar && viewItem =~ /canWatch/",
"group": "inline"
},
{
"command": "rtlDebugger.unWatchVariable",
"when": "view == rtlDebugger.sidebar && viewItem == inWatchList",
"when": "view == rtlDebugger.sidebar && viewItem =~ /inWatchList/",
"group": "inline"
}
],
"rtlDebugger.setRadix": [
{
"command": "rtlDebugger.setRadix.2",
"group": "radix@2"
},
{
"command": "rtlDebugger.setRadix.8",
"group": "radix@8"
},
{
"command": "rtlDebugger.setRadix.10",
"group": "radix@10"
},
{
"command": "rtlDebugger.setRadix.16",
"group": "radix@16"
}
]
}
},
"submenus": [
{
"id": "rtlDebugger.setRadix",
"label": "Radix"
}
]
},
"scripts": {
"lint": "eslint --fix",
Expand Down
4 changes: 2 additions & 2 deletions src/debug/watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export interface IWatchList {
onDidChange(callback: (items: IWatchItem[]) => any): vscode.Disposable;
}

export const watchList: IWatchList = {
export const globalWatchList: IWatchList = {
get(): IWatchItem[] {
return vscode.workspace.getConfiguration('rtlDebugger').get('watchList') || [];
},
Expand All @@ -37,7 +37,7 @@ export const watchList: IWatchList = {
onDidChange(callback: (items: IWatchItem[]) => any): vscode.Disposable {
return vscode.workspace.onDidChangeConfiguration((event) => {
if (event.affectsConfiguration('rtlDebugger.watchList')) {
callback(watchList.get());
callback(globalWatchList.get());
}
});
},
Expand Down
16 changes: 13 additions & 3 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as vscode from 'vscode';
import { watchList } from './debug/watch';
import { globalWatchList } from './debug/watch';
import { CXXRTLDebugger } from './debugger';
import * as sidebar from './ui/sidebar';
import { inputTime } from './ui/input';
import { globalVariableOptions } from './debug/options';

Check failure on line 6 in src/extension.ts

View workflow job for this annotation

GitHub Actions / build

Cannot find module './debug/options' or its corresponding type declarations.

export function activate(context: vscode.ExtensionContext) {
const rtlDebugger = new CXXRTLDebugger();
Expand Down Expand Up @@ -50,10 +51,19 @@ export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(vscode.commands.registerCommand('rtlDebugger.stepForward', () =>
rtlDebugger.session!.stepForward()));

context.subscriptions.push(vscode.commands.registerCommand('rtlDebugger.setRadix.2', (treeItem) =>
globalVariableOptions.update(treeItem.designation.variable.cxxrtlIdentifier, { radix: 2 })));
context.subscriptions.push(vscode.commands.registerCommand('rtlDebugger.setRadix.8', (treeItem) =>
globalVariableOptions.update(treeItem.designation.variable.cxxrtlIdentifier, { radix: 8 })));
context.subscriptions.push(vscode.commands.registerCommand('rtlDebugger.setRadix.10', (treeItem) =>
globalVariableOptions.update(treeItem.designation.variable.cxxrtlIdentifier, { radix: 10 })));
context.subscriptions.push(vscode.commands.registerCommand('rtlDebugger.setRadix.16', (treeItem) =>
globalVariableOptions.update(treeItem.designation.variable.cxxrtlIdentifier, { radix: 16 })));

context.subscriptions.push(vscode.commands.registerCommand('rtlDebugger.watchVariable', (treeItem) =>
watchList.append(treeItem.getWatchItem())));
globalWatchList.append(treeItem.getWatchItem())));
context.subscriptions.push(vscode.commands.registerCommand('rtlDebugger.unWatchVariable', (treeItem) =>
watchList.remove(treeItem.metadata.index)));
globalWatchList.remove(treeItem.metadata.index)));

// For an unknown reason, the `vscode.open` command (which does the exact same thing) ignores the options.
context.subscriptions.push(vscode.commands.registerCommand('rtlDebugger.openDocument',
Expand Down
20 changes: 15 additions & 5 deletions src/model/styling.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as vscode from 'vscode';

import { MemoryVariable, ScalarVariable, Variable } from './variable';
import { globalVariableOptions } from '../debug/options';

Check failure on line 4 in src/model/styling.ts

View workflow job for this annotation

GitHub Actions / build

Cannot find module '../debug/options' or its corresponding type declarations.

export enum DisplayStyle {
Python = 'Python',
Expand Down Expand Up @@ -65,26 +66,35 @@ export function* memoryRowIndices(variable: MemoryVariable): Generator<number> {
}
}

export function variableValue(style: DisplayStyle, variable: Variable, value: bigint | undefined, base: 2 | 8 | 10 | 16 = 10): string {
export function variableValue(style: DisplayStyle, variable: Variable, value: bigint | undefined, radix?: 2 | 8 | 10 | 16): string {

Check failure on line 69 in src/model/styling.ts

View workflow job for this annotation

GitHub Actions / build

Function lacks ending return statement and return type does not include 'undefined'.
if (value === undefined) {
return '...';
} else if (variable.width === 1) {
}

// There is a bug in CXXRTL that occasionally causes out-of-bounds bits to be set.
// Ideally it should be fixed there, but for now let's work around it here, for usability.
value &= (1n << BigInt(variable.width)) - 1n;

if (variable.width === 1) {
return value.toString();
} else {
if (radix === undefined) {
radix = globalVariableOptions.get(variable.cxxrtlIdentifier).radix ?? 10;
}
switch (style) {
case DisplayStyle.Python:
switch (base) {
switch (radix) {
case 2: return `0b${value.toString(2)}`;
case 8: return `0o${value.toString(8)}`;
case 10: return value.toString(10);
case 16: return `0x${value.toString(16)}`;
}

case DisplayStyle.Verilog:
return `${base}'${value.toString(base)}`;
return `${radix}'${value.toString(radix)}`;

case DisplayStyle.VHDL:
switch (base) {
switch (radix) {
case 2: return `B"${value.toString(2)}"`;
case 8: return `O"${value.toString(8)}"`;
case 10: return value.toString(10);
Expand Down
27 changes: 15 additions & 12 deletions src/ui/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { DisplayStyle, variableDescription, variableBitIndices, memoryRowIndices
import { CXXRTLDebugger } from '../debugger';
import { Observer } from '../debug/observer';
import { Designation, MemoryRangeDesignation, MemoryRowDesignation, ScalarDesignation } from '../model/sample';
import { IWatchItem, watchList } from '../debug/watch';
import { IWatchItem, globalWatchList } from '../debug/watch';
import { Session } from '../debug/session';

abstract class TreeItem {
Expand Down Expand Up @@ -37,7 +37,7 @@ class BitTreeItem extends TreeItem {
provider: TreeDataProvider,
readonly designation: ScalarDesignation | MemoryRowDesignation,
readonly bitIndex: number,
readonly contextValue?: string,
readonly contextValue: string = '',
) {
super(provider);
}
Expand Down Expand Up @@ -81,7 +81,7 @@ class ScalarTreeItem extends TreeItem {
constructor(
provider: TreeDataProvider,
readonly designation: ScalarDesignation | MemoryRowDesignation,
readonly contextValue?: string,
readonly contextValue: string = '',
) {
super(provider);
}
Expand Down Expand Up @@ -127,7 +127,7 @@ class ArrayTreeItem extends TreeItem {
constructor(
provider: TreeDataProvider,
readonly designation: MemoryRangeDesignation,
readonly contextValue?: string,
readonly contextValue: string = '',
) {
super(provider);
}
Expand Down Expand Up @@ -197,10 +197,11 @@ class ScopeTreeItem extends TreeItem {
}
for (const variable of await this.scope.variables) {
if (variable instanceof ScalarVariable) {
children.push(new ScalarTreeItem(this.provider, variable.designation(), 'canWatch'));
children.push(new ScalarTreeItem(this.provider, variable.designation(),
variable.width > 1 ? 'canWatch|canSetRadix' : 'canWatch'));
}
if (variable instanceof MemoryVariable) {
children.push(new ArrayTreeItem(this.provider, variable.designation(), 'canWatch'));
children.push(new ArrayTreeItem(this.provider, variable.designation(), 'canWatch|canSetRadix'));
}
}
return children;
Expand All @@ -215,7 +216,7 @@ class WatchTreeItem extends TreeItem {
}

override async getTreeItem(): Promise<vscode.TreeItem> {
if (watchList.get().length > 0) {
if (globalWatchList.get().length > 0) {
return new vscode.TreeItem('Watch', vscode.TreeItemCollapsibleState.Expanded);
} else {
return new vscode.TreeItem('Watch (empty)');
Expand All @@ -224,7 +225,7 @@ class WatchTreeItem extends TreeItem {

override async getChildren(): Promise<TreeItem[]> {
const children = [];
for (const [index, watchItem] of watchList.get().entries()) {
for (const [index, watchItem] of globalWatchList.get().entries()) {
const variable = await this.provider.getVariable(watchItem.id);
if (variable === null) {
continue;
Expand All @@ -241,10 +242,11 @@ class WatchTreeItem extends TreeItem {
}
let treeItem;
if (designation instanceof MemoryRangeDesignation) {
treeItem = new ArrayTreeItem(this.provider, designation, 'inWatchList');
treeItem = new ArrayTreeItem(this.provider, designation, 'inWatchList|canSetRadix');
} else if (designation instanceof ScalarDesignation || designation instanceof MemoryRowDesignation) {
if (watchItem.bit === undefined) {
treeItem = new ScalarTreeItem(this.provider, designation, 'inWatchList');
treeItem = new ScalarTreeItem(this.provider, designation,
designation.variable.width > 1 ? 'inWatchList|canSetRadix' : 'inWatchList');
} else {
treeItem = new BitTreeItem(this.provider, designation, watchItem.bit, 'inWatchList');
}
Expand All @@ -269,7 +271,8 @@ export class TreeDataProvider implements vscode.TreeDataProvider<TreeItem> {

constructor(rtlDebugger: CXXRTLDebugger) {
vscode.workspace.onDidChangeConfiguration((event) => {
if (event.affectsConfiguration('rtlDebugger.displayStyle')) {
if (event.affectsConfiguration('rtlDebugger.displayStyle') ||
event.affectsConfiguration('rtlDebugger.variableOptions')) {
this._onDidChangeTreeData.fire(null);
}
});
Expand All @@ -287,7 +290,7 @@ export class TreeDataProvider implements vscode.TreeDataProvider<TreeItem> {
}
this._onDidChangeTreeData.fire(null);
});
watchList.onDidChange((_items) => {
globalWatchList.onDidChange((_items) => {
if (this.watchTreeItem !== null) {
this._onDidChangeTreeData.fire(this.watchTreeItem);
}
Expand Down

0 comments on commit 8ddd697

Please sign in to comment.