@celox-sim/celox 0.2.2 → 0.3.0

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.
Files changed (2) hide show
  1. package/package.json +2 -2
  2. package/src/e2e.test.ts +123 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celox-sim/celox",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
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.2.2"
32
+ "@celox-sim/celox-napi": "0.3.0"
33
33
  },
34
34
  "peerDependencies": {
35
35
  "vitest": ">=1.0.0"
package/src/e2e.test.ts CHANGED
@@ -81,6 +81,76 @@ module Counter (
81
81
  }
82
82
  `;
83
83
 
84
+ // Regression: preserve every lane when a wide SIMD store forwards an unpacked
85
+ // output array through multiple module instances. Fourteen 64-bit elements
86
+ // exercise the native SLP path that previously aliased its scratch XMM register
87
+ // with a live forwarding vector.
88
+ const NESTED_OUTPUT_ARRAY_SOURCE = `
89
+ module Element (
90
+ clk: input clock,
91
+ rst: input reset,
92
+ value: output logic<64>,
93
+ ) {
94
+ var value_r: logic<64>;
95
+ assign value = value_r;
96
+ always_ff {
97
+ if_reset {
98
+ value_r = -1;
99
+ }
100
+ }
101
+ }
102
+
103
+ module GeneratedArray (
104
+ clk: input clock,
105
+ rst: input reset,
106
+ value: output logic<64> [14],
107
+ ) {
108
+ for i in 0..14: elements {
109
+ inst element: Element (
110
+ clk,
111
+ rst,
112
+ value: value[i],
113
+ );
114
+ }
115
+ }
116
+
117
+ module ForwardA (
118
+ clk: input clock,
119
+ rst: input reset,
120
+ value: output logic<64> [14],
121
+ ) {
122
+ inst source: GeneratedArray (
123
+ clk,
124
+ rst,
125
+ value,
126
+ );
127
+ }
128
+
129
+ module ForwardB (
130
+ clk: input clock,
131
+ rst: input reset,
132
+ value: output logic<64> [14],
133
+ ) {
134
+ inst source: ForwardA (
135
+ clk,
136
+ rst,
137
+ value,
138
+ );
139
+ }
140
+
141
+ module NestedOutputArrayMre (
142
+ clk: input clock,
143
+ rst: input reset,
144
+ value: output logic<64> [14],
145
+ ) {
146
+ inst source: ForwardB (
147
+ clk,
148
+ rst,
149
+ value,
150
+ );
151
+ }
152
+ `;
153
+
84
154
  const MULTIPLEXER_SOURCE = `
85
155
  module Mux4 (
86
156
  sel: input logic<2>,
@@ -441,6 +511,58 @@ describe("E2E: Simulator.create (backward compat)", () => {
441
511
  });
442
512
  });
443
513
 
514
+ describe("E2E: nested output-array forwarding", () => {
515
+ test("forwards every generated 64-bit output-array element", () => {
516
+ const addon = loadNativeAddon();
517
+ const sim = Simulator.create<{ rst: bigint }>(
518
+ {
519
+ __celox_module: true,
520
+ name: "NestedOutputArrayMre",
521
+ sources: [{ path: "", content: NESTED_OUTPUT_ARRAY_SOURCE }],
522
+ ports: {
523
+ clk: { direction: "input", type: "clock", width: 1 },
524
+ rst: { direction: "input", type: "reset", width: 1 },
525
+ value: {
526
+ direction: "output",
527
+ type: "logic",
528
+ width: 64,
529
+ arrayDims: [14],
530
+ },
531
+ },
532
+ events: ["clk"],
533
+ },
534
+ { __nativeCreate: createSimulatorBridge(addon) },
535
+ );
536
+
537
+ sim.dut.rst = 0n;
538
+ sim.tick();
539
+ sim.tick();
540
+ sim.dut.rst = 1n;
541
+
542
+ const dut = sim.dut as any;
543
+ const generated = Array.from({ length: 14 }, (_, index) =>
544
+ dut.source.source.source.value.at(index),
545
+ );
546
+ const forwardA = Array.from({ length: 14 }, (_, index) =>
547
+ dut.source.source.value.at(index),
548
+ );
549
+ const forwardB = Array.from({ length: 14 }, (_, index) =>
550
+ dut.source.value.at(index),
551
+ );
552
+ const forwarded = Array.from({ length: 14 }, (_, index) =>
553
+ dut.value.at(index),
554
+ );
555
+ sim.dispose();
556
+
557
+ const allOnes = (1n << 64n) - 1n;
558
+ const expected = Array.from({ length: 14 }, () => allOnes);
559
+ expect(generated).toEqual(expected);
560
+ expect(forwardA).toEqual(generated);
561
+ expect(forwardB).toEqual(forwardA);
562
+ expect(forwarded).toEqual(forwardB);
563
+ });
564
+ });
565
+
444
566
  // ---------------------------------------------------------------------------
445
567
  // 4-state simulation e2e tests
446
568
  // ---------------------------------------------------------------------------
@@ -1883,7 +2005,7 @@ describe("E2E: celox.toml test sources", () => {
1883
2005
  // Both the regular source (Adder) and the test-only source (Reg) must appear
1884
2006
  expect(names).toContain("Adder");
1885
2007
  expect(names).toContain("Reg");
1886
- });
2008
+ }, 15_000);
1887
2009
 
1888
2010
  test("[simulation] max_steps from celox.toml is used as waitUntil default", () => {
1889
2011
  // celox.toml sets [simulation] max_steps = 20; waitUntil should honour it