@celox-sim/celox 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dut.d.ts +14 -7
- package/dist/dut.d.ts.map +1 -1
- package/dist/dut.js +103 -27
- package/dist/dut.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/napi-helpers.d.ts +62 -1
- package/dist/napi-helpers.d.ts.map +1 -1
- package/dist/napi-helpers.js +154 -19
- package/dist/napi-helpers.js.map +1 -1
- package/dist/simulation.d.ts +59 -3
- package/dist/simulation.d.ts.map +1 -1
- package/dist/simulation.js +162 -16
- package/dist/simulation.js.map +1 -1
- package/dist/simulator.d.ts +7 -1
- package/dist/simulator.d.ts.map +1 -1
- package/dist/simulator.js +35 -14
- package/dist/simulator.js.map +1 -1
- package/dist/types.d.ts +36 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +17 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/src/dut.test.ts +66 -66
- package/src/dut.ts +124 -31
- package/src/e2e.bench.ts +176 -13
- package/src/e2e.test.ts +632 -195
- package/src/index.ts +10 -2
- package/src/matchers.ts +4 -7
- package/src/napi-helpers.ts +224 -22
- package/src/simulation.test.ts +220 -12
- package/src/simulation.ts +198 -13
- package/src/simulator.test.ts +8 -8
- package/src/simulator.ts +43 -11
- package/src/types.ts +54 -3
package/dist/simulator.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Wraps a NativeSimulatorHandle and provides a high-level TypeScript API
|
|
5
5
|
* for manually controlling clock edges via `tick()`.
|
|
6
6
|
*/
|
|
7
|
-
import type { CreateResult, EventHandle, ModuleDefinition, NativeSimulatorHandle, SimulatorOptions } from "./types.js";
|
|
7
|
+
import type { CreateResult, EventHandle, FourStateValue, ModuleDefinition, NativeSimulatorHandle, SimulatorOptions } from "./types.js";
|
|
8
8
|
/**
|
|
9
9
|
* Placeholder for the NAPI binding's `createSimulator()`.
|
|
10
10
|
* Stream B will provide the real implementation; until then tests can
|
|
@@ -25,6 +25,8 @@ export declare class Simulator<P = Record<string, unknown>> {
|
|
|
25
25
|
private readonly _events;
|
|
26
26
|
private readonly _defaultEventId;
|
|
27
27
|
private readonly _state;
|
|
28
|
+
private readonly _buffer;
|
|
29
|
+
private readonly _layout;
|
|
28
30
|
private _disposed;
|
|
29
31
|
private constructor();
|
|
30
32
|
/**
|
|
@@ -83,6 +85,10 @@ export declare class Simulator<P = Record<string, unknown>> {
|
|
|
83
85
|
tick(count?: number): void;
|
|
84
86
|
/** Resolve an event name to a handle for use with `tick()`. */
|
|
85
87
|
event(name: string): EventHandle;
|
|
88
|
+
/**
|
|
89
|
+
* Read the raw 4-state (value + mask) pair for the named port.
|
|
90
|
+
*/
|
|
91
|
+
fourState(portName: string): FourStateValue;
|
|
86
92
|
/** Write current signal values to VCD at the given timestamp. */
|
|
87
93
|
dump(timestamp: number): void;
|
|
88
94
|
/** Release native resources. */
|
package/dist/simulator.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simulator.d.ts","sourceRoot":"","sources":["../src/simulator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"simulator.d.ts","sourceRoot":"","sources":["../src/simulator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,cAAc,EACd,gBAAgB,EAChB,qBAAqB,EAErB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAWpB;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,CAC3B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,gBAAgB,KACtB,YAAY,CAAC,qBAAqB,CAAC,CAAC;AAIzC;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,CAEjE;AAMD,qBAAa,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAI;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA+B;IACvD,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO;IAkBP;;;;;;;OAOG;IACH,MAAM,CAAC,MAAM,CAAC,CAAC,EACb,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC3B,OAAO,CAAC,EAAE,gBAAgB,GAAG;QAC3B,iEAAiE;QACjE,cAAc,CAAC,EAAE,cAAc,CAAC;KACjC,GACA,SAAS,CAAC,CAAC,CAAC;IA8Bf;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3C,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,gBAAgB,GAAG;QAAE,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GACxD,SAAS,CAAC,CAAC,CAAC;IAoBf;;;;;;;;;;OAUG;IACH,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5C,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,gBAAgB,GAAG;QAAE,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,GACxD,SAAS,CAAC,CAAC,CAAC;IAoBf,sEAAsE;IACtE,IAAI,GAAG,IAAI,CAAC,CAEX;IAED;;;;;;OAMG;IACH,IAAI,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IACxD,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAoC1B,+DAA+D;IAC/D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;IAUhC;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc;IAY3C,iEAAiE;IACjE,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAK7B,gCAAgC;IAChC,OAAO,IAAI,IAAI;IAWf,OAAO,CAAC,WAAW;CAKpB"}
|
package/dist/simulator.js
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* Wraps a NativeSimulatorHandle and provides a high-level TypeScript API
|
|
5
5
|
* for manually controlling clock edges via `tick()`.
|
|
6
6
|
*/
|
|
7
|
-
import { createDut } from "./dut.js";
|
|
8
|
-
import { loadNativeAddon, parseNapiLayout, buildPortsFromLayout, wrapDirectSimulatorHandle, } from "./napi-helpers.js";
|
|
7
|
+
import { createDut, readFourState } from "./dut.js";
|
|
8
|
+
import { loadNativeAddon, parseNapiLayout, parseHierarchyLayout, buildPortsFromLayout, wrapDirectSimulatorHandle, buildNapiOpts, } from "./napi-helpers.js";
|
|
9
9
|
let _nativeCreate;
|
|
10
10
|
/**
|
|
11
11
|
* Register the NAPI binding at module load time.
|
|
@@ -24,12 +24,16 @@ export class Simulator {
|
|
|
24
24
|
_events;
|
|
25
25
|
_defaultEventId;
|
|
26
26
|
_state;
|
|
27
|
+
_buffer;
|
|
28
|
+
_layout;
|
|
27
29
|
_disposed = false;
|
|
28
|
-
constructor(handle, dut, events, state) {
|
|
30
|
+
constructor(handle, dut, events, state, buffer, layout) {
|
|
29
31
|
this._handle = handle;
|
|
30
32
|
this._dut = dut;
|
|
31
33
|
this._events = events;
|
|
32
34
|
this._state = state;
|
|
35
|
+
this._buffer = buffer;
|
|
36
|
+
this._layout = layout;
|
|
33
37
|
const keys = Object.keys(events);
|
|
34
38
|
this._defaultEventId = keys.length > 0 ? events[keys[0]] : -1;
|
|
35
39
|
}
|
|
@@ -51,11 +55,11 @@ export class Simulator {
|
|
|
51
55
|
throw new Error("Native simulator binding not loaded. " +
|
|
52
56
|
"Ensure @celox-sim/celox-napi is installed.");
|
|
53
57
|
}
|
|
54
|
-
const { fourState, vcd } = options ?? {};
|
|
55
|
-
const result = createFn(module.source, module.name, { fourState, vcd });
|
|
58
|
+
const { fourState, vcd, optimize, falseLoops, trueLoops, clockType, resetType } = options ?? {};
|
|
59
|
+
const result = createFn(module.source, module.name, { fourState, vcd, optimize, falseLoops, trueLoops, clockType, resetType });
|
|
56
60
|
const state = { dirty: false };
|
|
57
|
-
const dut = createDut(result.buffer, result.layout, module.ports, result.handle, state);
|
|
58
|
-
return new Simulator(result.handle, dut, result.events, state);
|
|
61
|
+
const dut = createDut(result.buffer, result.layout, module.ports, result.handle, state, result.hierarchy);
|
|
62
|
+
return new Simulator(result.handle, dut, result.events, state, result.buffer, result.layout);
|
|
59
63
|
}
|
|
60
64
|
/**
|
|
61
65
|
* Create a Simulator directly from Veryl source code.
|
|
@@ -73,16 +77,17 @@ export class Simulator {
|
|
|
73
77
|
*/
|
|
74
78
|
static fromSource(source, top, options) {
|
|
75
79
|
const addon = loadNativeAddon(options?.nativeAddonPath);
|
|
76
|
-
const napiOpts = options
|
|
80
|
+
const napiOpts = buildNapiOpts(options);
|
|
77
81
|
const raw = new addon.NativeSimulatorHandle(source, top, napiOpts);
|
|
78
82
|
const layout = parseNapiLayout(raw.layoutJson);
|
|
79
83
|
const events = JSON.parse(raw.eventsJson);
|
|
84
|
+
const hierarchy = parseHierarchyLayout(raw.hierarchyJson, events);
|
|
80
85
|
const ports = buildPortsFromLayout(layout.signals, events);
|
|
81
86
|
const buf = raw.sharedMemory().buffer;
|
|
82
87
|
const state = { dirty: false };
|
|
83
88
|
const handle = wrapDirectSimulatorHandle(raw);
|
|
84
|
-
const dut = createDut(buf, layout.forDut, ports, handle, state);
|
|
85
|
-
return new Simulator(handle, dut, events, state);
|
|
89
|
+
const dut = createDut(buf, layout.forDut, ports, handle, state, hierarchy);
|
|
90
|
+
return new Simulator(handle, dut, events, state, buf, layout.forDut);
|
|
86
91
|
}
|
|
87
92
|
/**
|
|
88
93
|
* Create a Simulator from a Veryl project directory.
|
|
@@ -97,16 +102,17 @@ export class Simulator {
|
|
|
97
102
|
*/
|
|
98
103
|
static fromProject(projectPath, top, options) {
|
|
99
104
|
const addon = loadNativeAddon(options?.nativeAddonPath);
|
|
100
|
-
const napiOpts = options
|
|
105
|
+
const napiOpts = buildNapiOpts(options);
|
|
101
106
|
const raw = addon.NativeSimulatorHandle.fromProject(projectPath, top, napiOpts);
|
|
102
107
|
const layout = parseNapiLayout(raw.layoutJson);
|
|
103
108
|
const events = JSON.parse(raw.eventsJson);
|
|
109
|
+
const hierarchy = parseHierarchyLayout(raw.hierarchyJson, events);
|
|
104
110
|
const ports = buildPortsFromLayout(layout.signals, events);
|
|
105
111
|
const buf = raw.sharedMemory().buffer;
|
|
106
112
|
const state = { dirty: false };
|
|
107
113
|
const handle = wrapDirectSimulatorHandle(raw);
|
|
108
|
-
const dut = createDut(buf, layout.forDut, ports, handle, state);
|
|
109
|
-
return new Simulator(handle, dut, events, state);
|
|
114
|
+
const dut = createDut(buf, layout.forDut, ports, handle, state, hierarchy);
|
|
115
|
+
return new Simulator(handle, dut, events, state, buf, layout.forDut);
|
|
110
116
|
}
|
|
111
117
|
/** The DUT accessor object — read/write ports as plain properties. */
|
|
112
118
|
get dut() {
|
|
@@ -131,13 +137,16 @@ export class Simulator {
|
|
|
131
137
|
eventId = this._defaultEventId;
|
|
132
138
|
ticks = 1;
|
|
133
139
|
}
|
|
140
|
+
if (this._state.dirty) {
|
|
141
|
+
this._handle.evalComb();
|
|
142
|
+
this._state.dirty = false;
|
|
143
|
+
}
|
|
134
144
|
if (ticks === 1) {
|
|
135
145
|
this._handle.tick(eventId);
|
|
136
146
|
}
|
|
137
147
|
else if (ticks > 1) {
|
|
138
148
|
this._handle.tickN(eventId, ticks);
|
|
139
149
|
}
|
|
140
|
-
this._state.dirty = false;
|
|
141
150
|
}
|
|
142
151
|
/** Resolve an event name to a handle for use with `tick()`. */
|
|
143
152
|
event(name) {
|
|
@@ -147,6 +156,18 @@ export class Simulator {
|
|
|
147
156
|
}
|
|
148
157
|
return { name, id };
|
|
149
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* Read the raw 4-state (value + mask) pair for the named port.
|
|
161
|
+
*/
|
|
162
|
+
fourState(portName) {
|
|
163
|
+
this.ensureAlive();
|
|
164
|
+
const sig = this._layout[portName];
|
|
165
|
+
if (!sig) {
|
|
166
|
+
throw new Error(`Unknown port '${portName}'. Available: ${Object.keys(this._layout).join(", ")}`);
|
|
167
|
+
}
|
|
168
|
+
const [value, mask] = readFourState(this._buffer, sig);
|
|
169
|
+
return { __fourState: true, value, mask };
|
|
170
|
+
}
|
|
150
171
|
/** Write current signal values to VCD at the given timestamp. */
|
|
151
172
|
dump(timestamp) {
|
|
152
173
|
this.ensureAlive();
|
package/dist/simulator.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simulator.js","sourceRoot":"","sources":["../src/simulator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"simulator.js","sourceRoot":"","sources":["../src/simulator.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -47,6 +47,10 @@ export interface SignalLayout {
|
|
|
47
47
|
/** If true, an equal-sized mask follows immediately after the value. */
|
|
48
48
|
readonly is4state: boolean;
|
|
49
49
|
readonly direction: "input" | "output" | "inout";
|
|
50
|
+
/** The Veryl type kind (e.g. "clock", "reset_async_high", "logic"). */
|
|
51
|
+
readonly typeKind?: string;
|
|
52
|
+
/** For reset signals, the name of the associated clock (from FfDeclaration). */
|
|
53
|
+
readonly associatedClock?: string;
|
|
50
54
|
}
|
|
51
55
|
/**
|
|
52
56
|
* Opaque handle returned by NAPI for event-based simulation.
|
|
@@ -69,6 +73,7 @@ export interface NativeSimulationHandle {
|
|
|
69
73
|
runUntil(endTime: number): void;
|
|
70
74
|
step(): number | null;
|
|
71
75
|
time(): number;
|
|
76
|
+
nextEventTime(): number | null;
|
|
72
77
|
evalComb(): void;
|
|
73
78
|
dump(timestamp: number): void;
|
|
74
79
|
dispose(): void;
|
|
@@ -91,12 +96,24 @@ export interface CreateResult<H extends NativeHandle = NativeHandle> {
|
|
|
91
96
|
readonly events: Record<string, number>;
|
|
92
97
|
/** Native control handle. */
|
|
93
98
|
readonly handle: H;
|
|
99
|
+
/** Full instance hierarchy (optional — present when NAPI provides it). */
|
|
100
|
+
readonly hierarchy?: import("./napi-helpers.js").HierarchyNode;
|
|
94
101
|
}
|
|
95
102
|
export interface SimulatorOptions {
|
|
96
103
|
/** Enable 4-state (X/Z) simulation. Default: false. */
|
|
97
104
|
fourState?: boolean;
|
|
98
105
|
/** Path to write VCD waveform output. */
|
|
99
106
|
vcd?: string;
|
|
107
|
+
/** Enable Cranelift optimization passes. */
|
|
108
|
+
optimize?: boolean;
|
|
109
|
+
/** False-loop declarations to ignore during compilation. */
|
|
110
|
+
falseLoops?: LoopBreak[];
|
|
111
|
+
/** True-loop declarations with convergence limits. */
|
|
112
|
+
trueLoops?: TrueLoopSpec[];
|
|
113
|
+
/** Clock polarity. Default: "posedge". */
|
|
114
|
+
clockType?: "posedge" | "negedge";
|
|
115
|
+
/** Reset type. Default: "async_low". */
|
|
116
|
+
resetType?: "async_high" | "async_low" | "sync_high" | "sync_low";
|
|
100
117
|
}
|
|
101
118
|
/** A resolved event reference for use with `tick()`. */
|
|
102
119
|
export interface EventHandle {
|
|
@@ -108,10 +125,27 @@ export declare const X: unique symbol;
|
|
|
108
125
|
/** A 4-state value with explicit bit-level mask. */
|
|
109
126
|
export interface FourStateValue {
|
|
110
127
|
readonly __fourState: true;
|
|
111
|
-
readonly value:
|
|
112
|
-
readonly mask:
|
|
128
|
+
readonly value: bigint;
|
|
129
|
+
readonly mask: bigint;
|
|
113
130
|
}
|
|
114
131
|
/** Construct a 4-state value. Mask bits set to 1 indicate X. */
|
|
115
132
|
export declare function FourState(value: number | bigint, mask: number | bigint): FourStateValue;
|
|
116
133
|
export declare function isFourStateValue(v: unknown): v is FourStateValue;
|
|
134
|
+
/**
|
|
135
|
+
* Thrown when a simulation helper exceeds its step budget.
|
|
136
|
+
*/
|
|
137
|
+
export declare class SimulationTimeoutError extends Error {
|
|
138
|
+
readonly time: number;
|
|
139
|
+
readonly steps: number;
|
|
140
|
+
constructor(message: string, time: number, steps: number);
|
|
141
|
+
}
|
|
142
|
+
/** Specifies a false-loop to ignore during compilation. */
|
|
143
|
+
export interface LoopBreak {
|
|
144
|
+
from: string;
|
|
145
|
+
to: string;
|
|
146
|
+
}
|
|
147
|
+
/** Specifies a true-loop with a convergence iteration limit. */
|
|
148
|
+
export interface TrueLoopSpec extends LoopBreak {
|
|
149
|
+
maxIter: number;
|
|
150
|
+
}
|
|
117
151
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC/D,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,sEAAsE;IACtE,QAAQ,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC;CAC1B;AAED,qDAAqD;AACrD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IACjD,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;IACnD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,4CAA4C;IAC5C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CAC/C;AAMD;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+BAA+B;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
CHANGED
|
@@ -13,11 +13,27 @@
|
|
|
13
13
|
export const X = Symbol.for("veryl:X");
|
|
14
14
|
/** Construct a 4-state value. Mask bits set to 1 indicate X. */
|
|
15
15
|
export function FourState(value, mask) {
|
|
16
|
-
return { __fourState: true, value, mask };
|
|
16
|
+
return { __fourState: true, value: BigInt(value), mask: BigInt(mask) };
|
|
17
17
|
}
|
|
18
18
|
export function isFourStateValue(v) {
|
|
19
19
|
return (typeof v === "object" &&
|
|
20
20
|
v !== null &&
|
|
21
21
|
v.__fourState === true);
|
|
22
22
|
}
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// Simulation timeout error
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
/**
|
|
27
|
+
* Thrown when a simulation helper exceeds its step budget.
|
|
28
|
+
*/
|
|
29
|
+
export class SimulationTimeoutError extends Error {
|
|
30
|
+
time;
|
|
31
|
+
steps;
|
|
32
|
+
constructor(message, time, steps) {
|
|
33
|
+
super(message);
|
|
34
|
+
this.name = "SimulationTimeoutError";
|
|
35
|
+
this.time = time;
|
|
36
|
+
this.steps = steps;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
23
39
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAiJH,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,mCAAmC;AACnC,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AASvC,gEAAgE;AAChE,MAAM,UAAU,SAAS,CACvB,KAAsB,EACtB,IAAqB;IAErB,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,CAAU;IACzC,OAAO,CACL,OAAO,CAAC,KAAK,QAAQ;QACrB,CAAC,KAAK,IAAI;QACT,CAAoB,CAAC,WAAW,KAAK,IAAI,CAC3C,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,2BAA2B;AAC3B,8EAA8E;AAE9E;;GAEG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IACtC,IAAI,CAAS;IACb,KAAK,CAAS;IAEvB,YAAY,OAAe,EAAE,IAAY,EAAE,KAAa;QACtD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@celox-sim/celox",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "TypeScript runtime for Celox HDL simulation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
},
|
|
30
30
|
"license": "MIT",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@celox-sim/celox-napi": "0.1.
|
|
32
|
+
"@celox-sim/celox-napi": "0.1.7"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"vitest": ">=1.0.0"
|
package/src/dut.test.ts
CHANGED
|
@@ -41,11 +41,11 @@ describe("createDut — scalar ports", () => {
|
|
|
41
41
|
const handle = mockHandle();
|
|
42
42
|
const state: DirtyState = { dirty: false };
|
|
43
43
|
|
|
44
|
-
const dut = createDut<{ a:
|
|
44
|
+
const dut = createDut<{ a: bigint }>(buffer, layout, ports, handle, state);
|
|
45
45
|
|
|
46
|
-
dut.a =
|
|
46
|
+
dut.a = 42n;
|
|
47
47
|
expect(state.dirty).toBe(true);
|
|
48
|
-
expect(dut.a).toBe(
|
|
48
|
+
expect(dut.a).toBe(42n);
|
|
49
49
|
// Reading an input doesn't trigger evalComb
|
|
50
50
|
expect(handle.evalComb).not.toHaveBeenCalled();
|
|
51
51
|
});
|
|
@@ -61,10 +61,10 @@ describe("createDut — scalar ports", () => {
|
|
|
61
61
|
const handle = mockHandle();
|
|
62
62
|
const state: DirtyState = { dirty: false };
|
|
63
63
|
|
|
64
|
-
const dut = createDut<{ a:
|
|
64
|
+
const dut = createDut<{ a: bigint }>(buffer, layout, ports, handle, state);
|
|
65
65
|
|
|
66
|
-
dut.a =
|
|
67
|
-
expect(dut.a).toBe(
|
|
66
|
+
dut.a = 0xABCDn;
|
|
67
|
+
expect(dut.a).toBe(0xABCDn);
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
test("write and read 32-bit input", () => {
|
|
@@ -78,13 +78,13 @@ describe("createDut — scalar ports", () => {
|
|
|
78
78
|
const handle = mockHandle();
|
|
79
79
|
const state: DirtyState = { dirty: false };
|
|
80
80
|
|
|
81
|
-
const dut = createDut<{ a:
|
|
81
|
+
const dut = createDut<{ a: bigint }>(buffer, layout, ports, handle, state);
|
|
82
82
|
|
|
83
|
-
dut.a =
|
|
84
|
-
expect(dut.a).toBe(
|
|
83
|
+
dut.a = 0xDEAD_BEEFn;
|
|
84
|
+
expect(dut.a).toBe(0xDEAD_BEEFn);
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
test("write and read 48-bit value
|
|
87
|
+
test("write and read 48-bit value", () => {
|
|
88
88
|
const buffer = makeBuffer(64);
|
|
89
89
|
const layout: Record<string, SignalLayout> = {
|
|
90
90
|
a: { offset: 0, width: 48, byteSize: 8, is4state: false, direction: "input" },
|
|
@@ -95,9 +95,9 @@ describe("createDut — scalar ports", () => {
|
|
|
95
95
|
const handle = mockHandle();
|
|
96
96
|
const state: DirtyState = { dirty: false };
|
|
97
97
|
|
|
98
|
-
const dut = createDut<{ a:
|
|
98
|
+
const dut = createDut<{ a: bigint }>(buffer, layout, ports, handle, state);
|
|
99
99
|
|
|
100
|
-
const val =
|
|
100
|
+
const val = 0x1234_5678_9ABCn;
|
|
101
101
|
dut.a = val;
|
|
102
102
|
expect(dut.a).toBe(val);
|
|
103
103
|
});
|
|
@@ -131,10 +131,10 @@ describe("createDut — scalar ports", () => {
|
|
|
131
131
|
const handle = mockHandle();
|
|
132
132
|
const state: DirtyState = { dirty: false };
|
|
133
133
|
|
|
134
|
-
const dut = createDut<{ a:
|
|
134
|
+
const dut = createDut<{ a: bigint }>(buffer, layout, ports, handle, state);
|
|
135
135
|
|
|
136
|
-
dut.a =
|
|
137
|
-
expect(dut.a).toBe(
|
|
136
|
+
dut.a = 0xFFn; // Only lower 4 bits should be stored
|
|
137
|
+
expect(dut.a).toBe(0x0Fn);
|
|
138
138
|
});
|
|
139
139
|
});
|
|
140
140
|
|
|
@@ -156,12 +156,12 @@ describe("createDut — dirty tracking", () => {
|
|
|
156
156
|
const handle = mockHandle();
|
|
157
157
|
const state: DirtyState = { dirty: false };
|
|
158
158
|
|
|
159
|
-
const dut = createDut<{ a:
|
|
159
|
+
const dut = createDut<{ a: bigint; readonly sum: bigint }>(
|
|
160
160
|
buffer, layout, ports, handle, state,
|
|
161
161
|
);
|
|
162
162
|
|
|
163
163
|
// Write input → dirty
|
|
164
|
-
dut.a =
|
|
164
|
+
dut.a = 100n;
|
|
165
165
|
expect(state.dirty).toBe(true);
|
|
166
166
|
|
|
167
167
|
// Read output → evalComb should be called
|
|
@@ -181,7 +181,7 @@ describe("createDut — dirty tracking", () => {
|
|
|
181
181
|
const handle = mockHandle();
|
|
182
182
|
const state: DirtyState = { dirty: false };
|
|
183
183
|
|
|
184
|
-
const dut = createDut<{ readonly sum:
|
|
184
|
+
const dut = createDut<{ readonly sum: bigint }>(
|
|
185
185
|
buffer, layout, ports, handle, state,
|
|
186
186
|
);
|
|
187
187
|
|
|
@@ -200,7 +200,7 @@ describe("createDut — dirty tracking", () => {
|
|
|
200
200
|
const handle = mockHandle();
|
|
201
201
|
const state: DirtyState = { dirty: true };
|
|
202
202
|
|
|
203
|
-
const dut = createDut<{ a:
|
|
203
|
+
const dut = createDut<{ a: bigint }>(buffer, layout, ports, handle, state);
|
|
204
204
|
|
|
205
205
|
void dut.a;
|
|
206
206
|
expect(handle.evalComb).not.toHaveBeenCalled();
|
|
@@ -217,10 +217,10 @@ describe("createDut — dirty tracking", () => {
|
|
|
217
217
|
const handle = mockHandle();
|
|
218
218
|
const state: DirtyState = { dirty: false };
|
|
219
219
|
|
|
220
|
-
const dut = createDut<{ sum:
|
|
220
|
+
const dut = createDut<{ sum: bigint }>(buffer, layout, ports, handle, state);
|
|
221
221
|
|
|
222
222
|
expect(() => {
|
|
223
|
-
dut.sum =
|
|
223
|
+
dut.sum = 42n;
|
|
224
224
|
}).toThrow("Cannot write to output port 'sum'");
|
|
225
225
|
});
|
|
226
226
|
});
|
|
@@ -243,7 +243,7 @@ describe("createDut — clock ports", () => {
|
|
|
243
243
|
const handle = mockHandle();
|
|
244
244
|
const state: DirtyState = { dirty: false };
|
|
245
245
|
|
|
246
|
-
const dut = createDut<{ a:
|
|
246
|
+
const dut = createDut<{ a: bigint }>(buffer, layout, ports, handle, state);
|
|
247
247
|
|
|
248
248
|
expect(Object.keys(dut as object)).toEqual(["a"]);
|
|
249
249
|
expect((dut as any).clk).toBeUndefined();
|
|
@@ -281,20 +281,20 @@ describe("createDut — multiple signals", () => {
|
|
|
281
281
|
|
|
282
282
|
const state: DirtyState = { dirty: false };
|
|
283
283
|
const dut = createDut<{
|
|
284
|
-
rst:
|
|
285
|
-
a:
|
|
286
|
-
b:
|
|
287
|
-
readonly sum:
|
|
284
|
+
rst: bigint;
|
|
285
|
+
a: bigint;
|
|
286
|
+
b: bigint;
|
|
287
|
+
readonly sum: bigint;
|
|
288
288
|
}>(buffer, layout, ports, handle, state);
|
|
289
289
|
|
|
290
|
-
dut.a =
|
|
291
|
-
dut.b =
|
|
290
|
+
dut.a = 100n;
|
|
291
|
+
dut.b = 200n;
|
|
292
292
|
// sum read triggers evalComb
|
|
293
|
-
expect(dut.sum).toBe(
|
|
293
|
+
expect(dut.sum).toBe(300n);
|
|
294
294
|
expect(handle.evalComb).toHaveBeenCalledTimes(1);
|
|
295
295
|
|
|
296
296
|
// second read without changes → no evalComb
|
|
297
|
-
expect(dut.sum).toBe(
|
|
297
|
+
expect(dut.sum).toBe(300n);
|
|
298
298
|
expect(handle.evalComb).toHaveBeenCalledTimes(1);
|
|
299
299
|
});
|
|
300
300
|
});
|
|
@@ -316,13 +316,13 @@ describe("createDut — 4-state", () => {
|
|
|
316
316
|
const handle = mockHandle();
|
|
317
317
|
const state: DirtyState = { dirty: false };
|
|
318
318
|
|
|
319
|
-
const dut = createDut<{ a:
|
|
319
|
+
const dut = createDut<{ a: bigint }>(buffer, layout, ports, handle, state);
|
|
320
320
|
|
|
321
321
|
(dut as any).a = X;
|
|
322
322
|
// Value should be 0, mask should be 0xFF
|
|
323
323
|
const [value, mask] = readFourState(buffer, layout.a);
|
|
324
|
-
expect(value).toBe(
|
|
325
|
-
expect(mask).toBe(
|
|
324
|
+
expect(value).toBe(0n);
|
|
325
|
+
expect(mask).toBe(0xFFn);
|
|
326
326
|
});
|
|
327
327
|
|
|
328
328
|
test("write FourState to a 4-state signal", () => {
|
|
@@ -336,12 +336,12 @@ describe("createDut — 4-state", () => {
|
|
|
336
336
|
const handle = mockHandle();
|
|
337
337
|
const state: DirtyState = { dirty: false };
|
|
338
338
|
|
|
339
|
-
const dut = createDut<{ a:
|
|
339
|
+
const dut = createDut<{ a: bigint }>(buffer, layout, ports, handle, state);
|
|
340
340
|
|
|
341
341
|
(dut as any).a = FourState(0b1010, 0b0100);
|
|
342
342
|
const [value, mask] = readFourState(buffer, layout.a);
|
|
343
|
-
expect(value).toBe(
|
|
344
|
-
expect(mask).toBe(
|
|
343
|
+
expect(value).toBe(0b1010n);
|
|
344
|
+
expect(mask).toBe(0b0100n);
|
|
345
345
|
});
|
|
346
346
|
|
|
347
347
|
test("writing X to non-4-state signal throws", () => {
|
|
@@ -355,7 +355,7 @@ describe("createDut — 4-state", () => {
|
|
|
355
355
|
const handle = mockHandle();
|
|
356
356
|
const state: DirtyState = { dirty: false };
|
|
357
357
|
|
|
358
|
-
const dut = createDut<{ a:
|
|
358
|
+
const dut = createDut<{ a: bigint }>(buffer, layout, ports, handle, state);
|
|
359
359
|
|
|
360
360
|
expect(() => {
|
|
361
361
|
(dut as any).a = X;
|
|
@@ -373,7 +373,7 @@ describe("createDut — 4-state", () => {
|
|
|
373
373
|
const handle = mockHandle();
|
|
374
374
|
const state: DirtyState = { dirty: false };
|
|
375
375
|
|
|
376
|
-
const dut = createDut<{ a:
|
|
376
|
+
const dut = createDut<{ a: bigint }>(buffer, layout, ports, handle, state);
|
|
377
377
|
|
|
378
378
|
expect(() => {
|
|
379
379
|
(dut as any).a = FourState(0xA5, 0x0F);
|
|
@@ -391,18 +391,18 @@ describe("createDut — 4-state", () => {
|
|
|
391
391
|
const handle = mockHandle();
|
|
392
392
|
const state: DirtyState = { dirty: false };
|
|
393
393
|
|
|
394
|
-
const dut = createDut<{ a:
|
|
394
|
+
const dut = createDut<{ a: bigint }>(buffer, layout, ports, handle, state);
|
|
395
395
|
|
|
396
396
|
// First write X
|
|
397
397
|
(dut as any).a = X;
|
|
398
398
|
const [, maskBefore] = readFourState(buffer, layout.a);
|
|
399
|
-
expect(maskBefore).toBe(
|
|
399
|
+
expect(maskBefore).toBe(0xFFn);
|
|
400
400
|
|
|
401
401
|
// Then write a defined value — mask should clear
|
|
402
|
-
dut.a =
|
|
402
|
+
dut.a = 42n;
|
|
403
403
|
const [value, maskAfter] = readFourState(buffer, layout.a);
|
|
404
|
-
expect(value).toBe(
|
|
405
|
-
expect(maskAfter).toBe(
|
|
404
|
+
expect(value).toBe(42n);
|
|
405
|
+
expect(maskAfter).toBe(0n);
|
|
406
406
|
});
|
|
407
407
|
|
|
408
408
|
test("reading 4-state output returns value part only", () => {
|
|
@@ -417,14 +417,14 @@ describe("createDut — 4-state", () => {
|
|
|
417
417
|
const handle = mockHandle();
|
|
418
418
|
const state: DirtyState = { dirty: false };
|
|
419
419
|
|
|
420
|
-
const dut = createDut<{ readonly y:
|
|
420
|
+
const dut = createDut<{ readonly y: bigint }>(buffer, layout, ports, handle, state);
|
|
421
421
|
|
|
422
422
|
// Set value=0xAB, mask=0x0F (lower 4 bits are X)
|
|
423
423
|
view.setUint8(0, 0xAB);
|
|
424
424
|
view.setUint8(1, 0x0F);
|
|
425
425
|
|
|
426
426
|
// DUT getter returns the value part
|
|
427
|
-
expect(dut.y).toBe(
|
|
427
|
+
expect(dut.y).toBe(0xABn);
|
|
428
428
|
});
|
|
429
429
|
|
|
430
430
|
test("write X sets dirty flag", () => {
|
|
@@ -438,7 +438,7 @@ describe("createDut — 4-state", () => {
|
|
|
438
438
|
const handle = mockHandle();
|
|
439
439
|
const state: DirtyState = { dirty: false };
|
|
440
440
|
|
|
441
|
-
const dut = createDut<{ a:
|
|
441
|
+
const dut = createDut<{ a: bigint }>(buffer, layout, ports, handle, state);
|
|
442
442
|
|
|
443
443
|
(dut as any).a = X;
|
|
444
444
|
expect(state.dirty).toBe(true);
|
|
@@ -462,20 +462,20 @@ describe("createDut — array ports", () => {
|
|
|
462
462
|
const handle = mockHandle();
|
|
463
463
|
const state: DirtyState = { dirty: false };
|
|
464
464
|
|
|
465
|
-
const dut = createDut<{ data: number
|
|
465
|
+
const dut = createDut<{ data: { at(i: number): bigint; set(i: number, v: bigint): void; length: number } }>(
|
|
466
466
|
buffer, layout, ports, handle, state,
|
|
467
467
|
);
|
|
468
468
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
469
|
+
dut.data.set(0, 0xAAn);
|
|
470
|
+
dut.data.set(1, 0xBBn);
|
|
471
|
+
dut.data.set(2, 0xCCn);
|
|
472
|
+
dut.data.set(3, 0xDDn);
|
|
473
473
|
|
|
474
|
-
expect(
|
|
475
|
-
expect(
|
|
476
|
-
expect(
|
|
477
|
-
expect(
|
|
478
|
-
expect(
|
|
474
|
+
expect(dut.data.at(0)).toBe(0xAAn);
|
|
475
|
+
expect(dut.data.at(1)).toBe(0xBBn);
|
|
476
|
+
expect(dut.data.at(2)).toBe(0xCCn);
|
|
477
|
+
expect(dut.data.at(3)).toBe(0xDDn);
|
|
478
|
+
expect(dut.data.length).toBe(4);
|
|
479
479
|
});
|
|
480
480
|
});
|
|
481
481
|
|
|
@@ -515,20 +515,20 @@ describe("createDut — interface ports", () => {
|
|
|
515
515
|
const state: DirtyState = { dirty: false };
|
|
516
516
|
const dut = createDut<{
|
|
517
517
|
bus: {
|
|
518
|
-
addr:
|
|
519
|
-
data:
|
|
520
|
-
valid:
|
|
521
|
-
readonly ready:
|
|
518
|
+
addr: bigint;
|
|
519
|
+
data: bigint;
|
|
520
|
+
valid: bigint;
|
|
521
|
+
readonly ready: bigint;
|
|
522
522
|
};
|
|
523
523
|
}>(buffer, layout, ports, handle, state);
|
|
524
524
|
|
|
525
|
-
dut.bus.addr =
|
|
526
|
-
dut.bus.data =
|
|
527
|
-
dut.bus.valid =
|
|
525
|
+
dut.bus.addr = 0x1000n;
|
|
526
|
+
dut.bus.data = 0xFFn;
|
|
527
|
+
dut.bus.valid = 1n;
|
|
528
528
|
|
|
529
|
-
expect(dut.bus.addr).toBe(
|
|
530
|
-
expect(dut.bus.data).toBe(
|
|
531
|
-
expect(dut.bus.ready).toBe(
|
|
529
|
+
expect(dut.bus.addr).toBe(0x1000n);
|
|
530
|
+
expect(dut.bus.data).toBe(0xFFn);
|
|
531
|
+
expect(dut.bus.ready).toBe(1n);
|
|
532
532
|
expect(handle.evalComb).toHaveBeenCalledTimes(1);
|
|
533
533
|
});
|
|
534
534
|
});
|