circuitscript 0.1.23 → 0.1.24
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/cjs/BaseVisitor.js +35 -23
- package/dist/cjs/BomGeneration.js +167 -0
- package/dist/cjs/ComponentMatchConditions.js +116 -0
- package/dist/cjs/antlr/CircuitScriptLexer.js +247 -244
- package/dist/cjs/antlr/CircuitScriptParser.js +1476 -825
- package/dist/cjs/builtinMethods.js +6 -1
- package/dist/cjs/execute.js +27 -16
- package/dist/cjs/graph.js +10 -9
- package/dist/cjs/helpers.js +23 -4
- package/dist/cjs/layout.js +14 -13
- package/dist/cjs/main.js +17 -1
- package/dist/cjs/objects/ExecutionScope.js +3 -0
- package/dist/cjs/objects/PinDefinition.js +11 -1
- package/dist/cjs/objects/types.js +6 -4
- package/dist/cjs/rules-check/no-connect-on-connected-pin.js +81 -0
- package/dist/cjs/rules-check/rules.js +74 -0
- package/dist/cjs/rules-check/unconnected-pins.js +52 -0
- package/dist/cjs/visitor.js +121 -5
- package/dist/esm/BaseVisitor.js +35 -23
- package/dist/esm/BomGeneration.js +137 -0
- package/dist/esm/ComponentMatchConditions.js +109 -0
- package/dist/esm/antlr/CircuitScriptLexer.js +247 -244
- package/dist/esm/antlr/CircuitScriptParser.js +1471 -824
- package/dist/esm/antlr/CircuitScriptVisitor.js +7 -0
- package/dist/esm/builtinMethods.js +6 -1
- package/dist/esm/execute.js +27 -16
- package/dist/esm/graph.js +11 -10
- package/dist/esm/helpers.js +23 -4
- package/dist/esm/layout.js +15 -13
- package/dist/esm/main.js +17 -1
- package/dist/esm/objects/ExecutionScope.js +3 -0
- package/dist/esm/objects/PinDefinition.js +11 -1
- package/dist/esm/objects/types.js +7 -5
- package/dist/esm/rules-check/no-connect-on-connected-pin.js +77 -0
- package/dist/esm/rules-check/rules.js +70 -0
- package/dist/esm/rules-check/unconnected-pins.js +48 -0
- package/dist/esm/visitor.js +121 -5
- package/dist/libs/std.cst +7 -3
- package/dist/types/BomGeneration.d.ts +13 -0
- package/dist/types/ComponentMatchConditions.d.ts +19 -0
- package/dist/types/antlr/CircuitScriptLexer.d.ts +60 -59
- package/dist/types/antlr/CircuitScriptParser.d.ts +146 -62
- package/dist/types/antlr/CircuitScriptVisitor.d.ts +14 -0
- package/dist/types/execute.d.ts +2 -1
- package/dist/types/graph.d.ts +6 -1
- package/dist/types/helpers.d.ts +3 -0
- package/dist/types/layout.d.ts +3 -2
- package/dist/types/objects/ExecutionScope.d.ts +8 -2
- package/dist/types/objects/ParamDefinition.d.ts +1 -1
- package/dist/types/objects/PinDefinition.d.ts +1 -0
- package/dist/types/objects/types.d.ts +4 -2
- package/dist/types/rules-check/no-connect-on-connected-pin.d.ts +3 -0
- package/dist/types/rules-check/rules.d.ts +15 -0
- package/dist/types/rules-check/unconnected-pins.d.ts +2 -0
- package/dist/types/visitor.d.ts +10 -1
- package/libs/std.cst +7 -3
- package/package.json +2 -1
|
@@ -166,7 +166,12 @@ function toString(obj) {
|
|
|
166
166
|
return obj.toDisplayString();
|
|
167
167
|
}
|
|
168
168
|
else if (obj.toString) {
|
|
169
|
-
|
|
169
|
+
if (typeof obj === 'object') {
|
|
170
|
+
return JSON.stringify(obj);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
return obj.toString();
|
|
174
|
+
}
|
|
170
175
|
}
|
|
171
176
|
else {
|
|
172
177
|
throw "Could not create string from object: " + obj;
|
package/dist/cjs/execute.js
CHANGED
|
@@ -373,9 +373,9 @@ class ExecutionContext {
|
|
|
373
373
|
+ pinId + ' in ' + component);
|
|
374
374
|
}
|
|
375
375
|
this.scope.setCurrent(component, usePinId);
|
|
376
|
-
if (!this.scope.hasNet(component,
|
|
376
|
+
if (!this.scope.hasNet(component, usePinId)) {
|
|
377
377
|
const tmpNet = new Net_js_1.Net(this.netNamespace, this.getUniqueNetName());
|
|
378
|
-
this.scope.setNet(component,
|
|
378
|
+
this.scope.setNet(component, usePinId, tmpNet);
|
|
379
379
|
}
|
|
380
380
|
this.scope.clearActive();
|
|
381
381
|
if (addSequence) {
|
|
@@ -497,7 +497,9 @@ class ExecutionContext {
|
|
|
497
497
|
const { start_point: [component, pin, wireId] } = stackRef;
|
|
498
498
|
this.atComponent(component, pin, { addSequence: true });
|
|
499
499
|
if (wireId !== -1) {
|
|
500
|
-
this.scope.
|
|
500
|
+
const wireObject = this.scope.wires[wireId];
|
|
501
|
+
this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.WireJump,
|
|
502
|
+
wireId, PinDefinition_js_1.PinId.from(1), wireObject]);
|
|
501
503
|
}
|
|
502
504
|
}
|
|
503
505
|
else if (blockType === globals_js_1.BlockTypes.Join || blockType === globals_js_1.BlockTypes.Parallel) {
|
|
@@ -623,7 +625,7 @@ class ExecutionContext {
|
|
|
623
625
|
type: isVariable ? globals_js_1.ReferenceTypes.variable
|
|
624
626
|
: globals_js_1.ReferenceTypes.instance,
|
|
625
627
|
found: (tmpReference.value !== undefined),
|
|
626
|
-
|
|
628
|
+
rootValue: tmpReference.rootValue,
|
|
627
629
|
value: tmpReference.value,
|
|
628
630
|
name: idName,
|
|
629
631
|
trailers,
|
|
@@ -637,16 +639,19 @@ class ExecutionContext {
|
|
|
637
639
|
});
|
|
638
640
|
}
|
|
639
641
|
resolveTrailers(type, item, trailers = []) {
|
|
640
|
-
let
|
|
642
|
+
let rootValue;
|
|
641
643
|
let useValue = item;
|
|
642
644
|
if (trailers.length > 0) {
|
|
643
|
-
|
|
645
|
+
rootValue = useValue;
|
|
644
646
|
const trailersPath = trailers.join(".");
|
|
645
647
|
if (type === globals_js_1.ReferenceTypes.variable) {
|
|
646
|
-
useValue =
|
|
648
|
+
useValue = rootValue;
|
|
649
|
+
trailers.forEach(trailerPath => {
|
|
650
|
+
useValue = useValue[trailerPath];
|
|
651
|
+
});
|
|
647
652
|
}
|
|
648
653
|
else if (type === globals_js_1.ReferenceTypes.instance) {
|
|
649
|
-
const tmpComponent =
|
|
654
|
+
const tmpComponent = rootValue;
|
|
650
655
|
if (tmpComponent.typeProp === globals_js_1.ComponentTypes.net) {
|
|
651
656
|
const usedNet = this.scope.getNet(tmpComponent, new PinDefinition_js_1.PinId(1));
|
|
652
657
|
if (usedNet) {
|
|
@@ -655,20 +660,21 @@ class ExecutionContext {
|
|
|
655
660
|
}
|
|
656
661
|
}
|
|
657
662
|
else {
|
|
658
|
-
useValue =
|
|
663
|
+
useValue = rootValue
|
|
659
664
|
.parameters.get(trailersPath);
|
|
660
665
|
}
|
|
661
666
|
}
|
|
662
667
|
}
|
|
663
668
|
let found = false;
|
|
664
|
-
if (
|
|
669
|
+
if (rootValue !== undefined && useValue !== undefined) {
|
|
665
670
|
found = true;
|
|
666
671
|
}
|
|
667
672
|
return new types_js_1.AnyReference({
|
|
668
673
|
found,
|
|
669
674
|
type: type,
|
|
670
|
-
|
|
675
|
+
rootValue,
|
|
671
676
|
trailers,
|
|
677
|
+
trailerIndex: trailers.length,
|
|
672
678
|
value: useValue,
|
|
673
679
|
});
|
|
674
680
|
}
|
|
@@ -769,13 +775,16 @@ class ExecutionContext {
|
|
|
769
775
|
childScope.sequence.forEach(sequenceAction => {
|
|
770
776
|
const [action] = sequenceAction;
|
|
771
777
|
if (action === ExecutionScope_js_1.SequenceAction.Wire) {
|
|
772
|
-
const [, innerWireId, segments] = sequenceAction;
|
|
773
|
-
this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.Wire, wireIdOffset + innerWireId,
|
|
778
|
+
const [, innerWireId, segments, wire] = sequenceAction;
|
|
779
|
+
this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.Wire, wireIdOffset + innerWireId,
|
|
780
|
+
segments, wire]);
|
|
774
781
|
this.scope.wires.push(new Wire_js_1.Wire(segments));
|
|
775
782
|
}
|
|
776
783
|
else if (action === ExecutionScope_js_1.SequenceAction.WireJump) {
|
|
777
784
|
const jumpWireId = wireIdOffset + sequenceAction[1];
|
|
778
|
-
this.scope.
|
|
785
|
+
const wireObject = this.scope.wires[jumpWireId];
|
|
786
|
+
this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.WireJump, jumpWireId,
|
|
787
|
+
PinDefinition_js_1.PinId.from(1), wireObject]);
|
|
779
788
|
}
|
|
780
789
|
else if (action === ExecutionScope_js_1.SequenceAction.At || action === ExecutionScope_js_1.SequenceAction.To) {
|
|
781
790
|
this.scope.sequence.push(sequenceAction);
|
|
@@ -823,7 +832,8 @@ class ExecutionContext {
|
|
|
823
832
|
};
|
|
824
833
|
});
|
|
825
834
|
const wireId = this.scope.wires.length;
|
|
826
|
-
|
|
835
|
+
const newWire = new Wire_js_1.Wire(tmp);
|
|
836
|
+
this.scope.wires.push(newWire);
|
|
827
837
|
const output = [];
|
|
828
838
|
segments.forEach(item => {
|
|
829
839
|
const tmpArray = item.map(item2 => {
|
|
@@ -838,12 +848,13 @@ class ExecutionContext {
|
|
|
838
848
|
});
|
|
839
849
|
this.log('add wire: ', output.join("|"));
|
|
840
850
|
this.scope.setActive(ExecutionScope_js_1.ActiveObject.Wire, wireId);
|
|
841
|
-
this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.Wire, wireId, tmp]);
|
|
851
|
+
this.scope.sequence.push([ExecutionScope_js_1.SequenceAction.Wire, wireId, tmp, newWire]);
|
|
842
852
|
this.scope.currentComponent.pinWires.set(this.scope.currentPin, tmp);
|
|
843
853
|
if (!this.scope.currentComponent.didSetWireOrientationAngle) {
|
|
844
854
|
this.applyComponentAngleFromWire(this.scope.currentComponent, this.scope.currentPin, true);
|
|
845
855
|
this.scope.currentComponent.didSetWireOrientationAngle = true;
|
|
846
856
|
}
|
|
857
|
+
return newWire;
|
|
847
858
|
}
|
|
848
859
|
addPoint(pointId, userDefined = true) {
|
|
849
860
|
if (this.scope.instances.has(pointId)) {
|
package/dist/cjs/graph.js
CHANGED
|
@@ -106,8 +106,9 @@ class NetGraph {
|
|
|
106
106
|
break;
|
|
107
107
|
}
|
|
108
108
|
case ExecutionScope_js_1.SequenceAction.Wire: {
|
|
109
|
-
const [, wireId,
|
|
109
|
+
const [, wireId, , wire] = sequenceStep;
|
|
110
110
|
let useNet;
|
|
111
|
+
const wireSegments = wire.path;
|
|
111
112
|
if (previousNode !== null) {
|
|
112
113
|
const [prevNodeType, prevNodeItem] = graph.node(previousNode);
|
|
113
114
|
if (prevNodeType === RenderItemType.Component) {
|
|
@@ -123,15 +124,15 @@ class NetGraph {
|
|
|
123
124
|
useNet = prevNodeItem.net;
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const wireName = getWireName(
|
|
130
|
-
graph.setNode(wireName, [RenderItemType.Wire,
|
|
127
|
+
const renderWire = new layout_js_1.RenderWire(useNet, (0, ParamDefinition_js_1.numeric)(0), (0, ParamDefinition_js_1.numeric)(0), wireSegments, wire);
|
|
128
|
+
renderWire.id = wireId;
|
|
129
|
+
renderWire.netName = useNet.toString();
|
|
130
|
+
const wireName = getWireName(renderWire.id);
|
|
131
|
+
graph.setNode(wireName, [RenderItemType.Wire, renderWire, index]);
|
|
131
132
|
let tmpPreviousNode = previousNode;
|
|
132
|
-
this.setGraphEdge(graph, previousNode, wireName, makeEdgeValue(previousNode, previousPin, wireName, 0, index));
|
|
133
|
+
this.setGraphEdge(graph, previousNode, wireName, makeEdgeValue(previousNode, previousPin, wireName, PinDefinition_js_1.PinId.from(0), index));
|
|
133
134
|
previousNode = wireName;
|
|
134
|
-
previousPin = 1;
|
|
135
|
+
previousPin = PinDefinition_js_1.PinId.from(1);
|
|
135
136
|
const wireSegmentsInfo = wireSegments.map(item => {
|
|
136
137
|
const tmp = {
|
|
137
138
|
direction: item.direction,
|
|
@@ -165,7 +166,7 @@ class NetGraph {
|
|
|
165
166
|
wirePin = sequenceStep[2];
|
|
166
167
|
}
|
|
167
168
|
previousNode = wireName;
|
|
168
|
-
previousPin = wirePin;
|
|
169
|
+
previousPin = PinDefinition_js_1.PinId.from(wirePin);
|
|
169
170
|
break;
|
|
170
171
|
}
|
|
171
172
|
case ExecutionScope_js_1.SequenceAction.Frame: {
|
package/dist/cjs/helpers.js
CHANGED
|
@@ -25,6 +25,8 @@ const big_js_1 = __importDefault(require("big.js"));
|
|
|
25
25
|
const logger_js_1 = require("./logger.js");
|
|
26
26
|
const graph_js_1 = require("./graph.js");
|
|
27
27
|
const RefdesAnnotationVisitor_js_1 = require("./RefdesAnnotationVisitor.js");
|
|
28
|
+
const rules_js_1 = require("./rules-check/rules.js");
|
|
29
|
+
const BomGeneration_js_1 = require("./BomGeneration.js");
|
|
28
30
|
var JSModuleType;
|
|
29
31
|
(function (JSModuleType) {
|
|
30
32
|
JSModuleType["CommonJs"] = "cjs";
|
|
@@ -166,7 +168,7 @@ async function renderScript(scriptData, outputPath, options) {
|
|
|
166
168
|
}
|
|
167
169
|
exports.renderScript = renderScript;
|
|
168
170
|
async function renderScriptCustom(scriptData, outputPath, options, parseHandlers) {
|
|
169
|
-
const { dumpNets = false, dumpData = false, showStats = false, environment, inputPath = null, updateSource = false, saveAnnotatedCopy = undefined, } = options;
|
|
171
|
+
const { dumpNets = false, dumpData = false, showStats = false, enableErc = false, enableBom = false, bomOutputPath = undefined, environment, inputPath = null, updateSource = false, saveAnnotatedCopy = undefined, } = options;
|
|
170
172
|
const errors = [];
|
|
171
173
|
const onErrorHandler = (message, context, error) => {
|
|
172
174
|
if (error && error instanceof utils_js_1.RuntimeExecutionError) {
|
|
@@ -220,10 +222,10 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
|
|
|
220
222
|
catch (err) {
|
|
221
223
|
throw new utils_js_1.RenderError(`Error during component annotation: ${err}`, 'annotation');
|
|
222
224
|
}
|
|
223
|
-
const componentLinks = visitor.getComponentCtxLinks();
|
|
224
|
-
const refdesVisitor = new RefdesAnnotationVisitor_js_1.RefdesAnnotationVisitor(true, scriptData, tokens, componentLinks);
|
|
225
|
-
await refdesVisitor.visitAsync(tree);
|
|
226
225
|
if (inputPath && (updateSource || saveAnnotatedCopy !== undefined)) {
|
|
226
|
+
const componentLinks = visitor.getComponentCtxLinks();
|
|
227
|
+
const refdesVisitor = new RefdesAnnotationVisitor_js_1.RefdesAnnotationVisitor(true, scriptData, tokens, componentLinks);
|
|
228
|
+
await refdesVisitor.visitAsync(tree);
|
|
227
229
|
let usePath = inputPath;
|
|
228
230
|
if (saveAnnotatedCopy === true) {
|
|
229
231
|
const dir = path_1.default.dirname(inputPath);
|
|
@@ -250,6 +252,14 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
|
|
|
250
252
|
if (errors.length === 0) {
|
|
251
253
|
const { frameComponent } = visitor.applySheetFrameComponent();
|
|
252
254
|
const { sequence, nets } = visitor.getGraph();
|
|
255
|
+
if (enableBom && bomOutputPath) {
|
|
256
|
+
const documentVariable = visitor.getScope().variables.get('document');
|
|
257
|
+
const bomConfig = documentVariable.bom;
|
|
258
|
+
const bomData = (0, BomGeneration_js_1.generateBom)(bomConfig, visitor.getScope().getInstances());
|
|
259
|
+
const bomCsvOutput = (0, BomGeneration_js_1.generateBomCSV)(bomData);
|
|
260
|
+
await (0, BomGeneration_js_1.saveBomOutputCsv)(bomCsvOutput, bomOutputPath);
|
|
261
|
+
console.log('Generated BOM file', bomOutputPath);
|
|
262
|
+
}
|
|
253
263
|
const tmpSequence = (0, utils_js_1.generateDebugSequenceAction)(sequence).map(item => (0, utils_js_1.sequenceActionString)(item));
|
|
254
264
|
dumpData && (0, fs_1.writeFileSync)(dumpDirectory + 'raw-sequence.txt', tmpSequence.join('\n'));
|
|
255
265
|
try {
|
|
@@ -278,6 +288,15 @@ async function renderScriptCustom(scriptData, outputPath, options, parseHandlers
|
|
|
278
288
|
try {
|
|
279
289
|
const { graph, containerFrames } = graphEngine.generateLayoutGraph(sequence, nets);
|
|
280
290
|
sheetFrames = layoutEngine.runLayout(graph, containerFrames, nets);
|
|
291
|
+
if (enableErc) {
|
|
292
|
+
const ercResults = (0, rules_js_1.EvaluateERCRules)(visitor, graph, nets);
|
|
293
|
+
if (ercResults.length > 0) {
|
|
294
|
+
console.log(`ERC found ${ercResults.length} items:`);
|
|
295
|
+
ercResults.forEach((item, index) => {
|
|
296
|
+
console.log(`${(index + 1).toString().padStart(3)}. line ${item.start.line}, column ${item.start.column}: ${item.type} - ${item.message}`);
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
281
300
|
}
|
|
282
301
|
catch (err) {
|
|
283
302
|
throw new utils_js_1.RenderError(`Error during layout generation: ${err}`, 'layout');
|
package/dist/cjs/layout.js
CHANGED
|
@@ -56,23 +56,23 @@ class LayoutEngine {
|
|
|
56
56
|
const sheetFrameObjects = sheetFrames.map(sheet => {
|
|
57
57
|
const items = this.flattenFrameItems(sheet);
|
|
58
58
|
const components = items.filter(item => item instanceof RenderComponent);
|
|
59
|
-
const
|
|
59
|
+
const renderWires = items.filter(item => item instanceof RenderWire);
|
|
60
60
|
const textObjects = items.filter(item => item instanceof RenderText);
|
|
61
61
|
const frames = items.filter(item => item instanceof RenderFrame);
|
|
62
|
-
const
|
|
63
|
-
|
|
62
|
+
const renderWireGroups = new Map();
|
|
63
|
+
renderWires.forEach(wire => {
|
|
64
64
|
const { netName } = wire;
|
|
65
|
-
if (!
|
|
66
|
-
|
|
65
|
+
if (!renderWireGroups.has(netName)) {
|
|
66
|
+
renderWireGroups.set(netName, []);
|
|
67
67
|
}
|
|
68
|
-
|
|
68
|
+
renderWireGroups.get(netName).push(wire);
|
|
69
69
|
});
|
|
70
|
-
const { junctions, mergedWires } = this.findJunctions(
|
|
70
|
+
const { junctions, mergedWires } = this.findJunctions(renderWireGroups, renderNets);
|
|
71
71
|
return {
|
|
72
72
|
frame: sheet,
|
|
73
73
|
frames,
|
|
74
74
|
components,
|
|
75
|
-
wires,
|
|
75
|
+
wires: renderWires,
|
|
76
76
|
textObjects,
|
|
77
77
|
junctions,
|
|
78
78
|
mergedWires
|
|
@@ -124,12 +124,12 @@ class LayoutEngine {
|
|
|
124
124
|
});
|
|
125
125
|
return items;
|
|
126
126
|
}
|
|
127
|
-
findJunctions(
|
|
127
|
+
findJunctions(renderWireGroups, nets) {
|
|
128
128
|
const junctions = [];
|
|
129
129
|
const mergedWires = [];
|
|
130
130
|
const debugSegments = false;
|
|
131
|
-
for (const [netName,
|
|
132
|
-
const allLines =
|
|
131
|
+
for (const [netName, renderWires] of renderWireGroups) {
|
|
132
|
+
const allLines = renderWires.map(wire => {
|
|
133
133
|
return wire.points.map(pt => {
|
|
134
134
|
return {
|
|
135
135
|
x: wire.x.add(pt.x),
|
|
@@ -848,7 +848,7 @@ class LayoutEngine {
|
|
|
848
848
|
item.y = fromY.sub(pinPosition.y);
|
|
849
849
|
}
|
|
850
850
|
else if (item instanceof RenderWire) {
|
|
851
|
-
if (pin === 0) {
|
|
851
|
+
if (pin.getValue() === 0) {
|
|
852
852
|
item.x = fromX;
|
|
853
853
|
item.y = fromY;
|
|
854
854
|
}
|
|
@@ -1023,7 +1023,7 @@ class RenderObject {
|
|
|
1023
1023
|
}
|
|
1024
1024
|
exports.RenderObject = RenderObject;
|
|
1025
1025
|
class RenderWire extends RenderObject {
|
|
1026
|
-
constructor(net, x, y, segments) {
|
|
1026
|
+
constructor(net, x, y, segments, wire) {
|
|
1027
1027
|
super();
|
|
1028
1028
|
this.segments = [];
|
|
1029
1029
|
this.points = [];
|
|
@@ -1031,6 +1031,7 @@ class RenderWire extends RenderObject {
|
|
|
1031
1031
|
this.x = x;
|
|
1032
1032
|
this.y = y;
|
|
1033
1033
|
this.segments = segments;
|
|
1034
|
+
this.wire = wire;
|
|
1034
1035
|
this.refreshPoints();
|
|
1035
1036
|
}
|
|
1036
1037
|
refreshPoints() {
|
package/dist/cjs/main.js
CHANGED
|
@@ -26,7 +26,9 @@ async function main() {
|
|
|
26
26
|
.option('-n, --dump-nets', 'Dump out net information')
|
|
27
27
|
.option('-d, --dump-data', 'Dump data during parsing')
|
|
28
28
|
.option('-s, --stats', 'Show stats during generation')
|
|
29
|
-
.option('-x, --skip-output', 'Skip output generation')
|
|
29
|
+
.option('-x, --skip-output', 'Skip output generation')
|
|
30
|
+
.option('-e, --erc', 'Enable ERC output')
|
|
31
|
+
.option('-b, --bom [output-path]', 'Generate Bill of Materials in csv format');
|
|
30
32
|
commander_1.program.addHelpText('before', figlet_1.default.textSync('circuitscript', {
|
|
31
33
|
font: 'Small Slant'
|
|
32
34
|
}));
|
|
@@ -39,6 +41,9 @@ async function main() {
|
|
|
39
41
|
const watchFileChanges = options.watch;
|
|
40
42
|
const dumpNets = options.dumpNets;
|
|
41
43
|
const dumpData = options.dumpData;
|
|
44
|
+
const enableErc = options.erc;
|
|
45
|
+
const enableBom = options.bom !== undefined;
|
|
46
|
+
let bomOutputPath = options.bom;
|
|
42
47
|
if (options.currentDirectory) {
|
|
43
48
|
throw "Parameter not supported yet";
|
|
44
49
|
}
|
|
@@ -77,10 +82,21 @@ async function main() {
|
|
|
77
82
|
if (options.annotatedPath !== undefined) {
|
|
78
83
|
saveAnnotatedCopyPath = options.annotatedPath;
|
|
79
84
|
}
|
|
85
|
+
if (enableBom && (bomOutputPath === true || bomOutputPath === undefined)) {
|
|
86
|
+
if (inputFilePath) {
|
|
87
|
+
bomOutputPath = inputFilePath + '.bom.csv';
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
bomOutputPath = 'output.bom.csv';
|
|
91
|
+
}
|
|
92
|
+
}
|
|
80
93
|
const scriptOptions = {
|
|
81
94
|
dumpNets,
|
|
82
95
|
dumpData,
|
|
83
96
|
showStats: options.stats,
|
|
97
|
+
enableErc,
|
|
98
|
+
enableBom,
|
|
99
|
+
bomOutputPath,
|
|
84
100
|
environment: env,
|
|
85
101
|
inputPath: inputFilePath,
|
|
86
102
|
updateSource,
|
|
@@ -166,6 +166,9 @@ class ExecutionScope {
|
|
|
166
166
|
const propertyTree = this.findPropertyKeyTree(visitor);
|
|
167
167
|
lastHandler && lastHandler(propertyTree, value, valueCtx);
|
|
168
168
|
}
|
|
169
|
+
getInstances() {
|
|
170
|
+
return Array.from(this.instances.values());
|
|
171
|
+
}
|
|
169
172
|
}
|
|
170
173
|
exports.ExecutionScope = ExecutionScope;
|
|
171
174
|
ExecutionScope.scopeId = 0;
|
|
@@ -29,10 +29,20 @@ class PinId {
|
|
|
29
29
|
}
|
|
30
30
|
equals(other) {
|
|
31
31
|
if (other instanceof PinId) {
|
|
32
|
-
return this.value === other.value
|
|
32
|
+
return this.value === other.value
|
|
33
|
+
&& this.getType() === other.getType();
|
|
33
34
|
}
|
|
34
35
|
return this.value === other;
|
|
35
36
|
}
|
|
37
|
+
getHashValue() {
|
|
38
|
+
if (this.type === PinIdType.Int) {
|
|
39
|
+
return 'int-' + this.value;
|
|
40
|
+
}
|
|
41
|
+
else if (this.type === PinIdType.Str) {
|
|
42
|
+
return 'str-' + this.value;
|
|
43
|
+
}
|
|
44
|
+
return '';
|
|
45
|
+
}
|
|
36
46
|
static from(value) {
|
|
37
47
|
if (value instanceof ParamDefinition_js_1.NumericValue) {
|
|
38
48
|
return new PinId(value.toNumber());
|
|
@@ -20,6 +20,7 @@ class AnyReference {
|
|
|
20
20
|
constructor(refType) {
|
|
21
21
|
this.found = false;
|
|
22
22
|
this.trailers = [];
|
|
23
|
+
this.trailerIndex = -1;
|
|
23
24
|
this.referenceName = 'AnyReference';
|
|
24
25
|
if (refType.value instanceof AnyReference
|
|
25
26
|
&& refType.value.type !== globals_js_1.ReferenceTypes.function) {
|
|
@@ -28,9 +29,10 @@ class AnyReference {
|
|
|
28
29
|
this.found = refType.found;
|
|
29
30
|
this.name = refType.name;
|
|
30
31
|
this.trailers = refType.trailers;
|
|
32
|
+
this.trailerIndex = refType.trailerIndex;
|
|
31
33
|
this.type = refType.type ?? globals_js_1.ReferenceTypes.unknown;
|
|
32
34
|
this.value = refType.value;
|
|
33
|
-
this.
|
|
35
|
+
this.rootValue = refType.rootValue;
|
|
34
36
|
}
|
|
35
37
|
toString() {
|
|
36
38
|
return `[${this.referenceName} name: ${this.name} trailers:${this.trailers} found: ${this.found}]`;
|
|
@@ -65,13 +67,13 @@ class DeclaredReference extends AnyReference {
|
|
|
65
67
|
}
|
|
66
68
|
toDisplayString() {
|
|
67
69
|
let returnValue = undefined;
|
|
68
|
-
if (this.
|
|
70
|
+
if (this.rootValue) {
|
|
69
71
|
const trailersString = this.trailers.join(".");
|
|
70
72
|
if (this.type === 'instance') {
|
|
71
|
-
returnValue = this.
|
|
73
|
+
returnValue = this.rootValue.parameters.get(trailersString);
|
|
72
74
|
}
|
|
73
75
|
else if (this.type === 'variable') {
|
|
74
|
-
returnValue = this.
|
|
76
|
+
returnValue = this.rootValue[trailersString];
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
else {
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RuleCheck_NoConnectOnConnectedPin = void 0;
|
|
4
|
+
const graph_js_1 = require("../graph.js");
|
|
5
|
+
const rules_js_1 = require("./rules.js");
|
|
6
|
+
function RuleCheck_NoConnectOnConnectedPin(graph, nets) {
|
|
7
|
+
const allNodes = graph.nodes();
|
|
8
|
+
const items = [];
|
|
9
|
+
const netComponentPins = new Map();
|
|
10
|
+
const pinMapping = new Map();
|
|
11
|
+
const makeComponentPinHash = (instanceName, pin) => {
|
|
12
|
+
return instanceName + '-' + pin.getHashValue();
|
|
13
|
+
};
|
|
14
|
+
nets.forEach(item => {
|
|
15
|
+
const [component, pin, net] = item;
|
|
16
|
+
if (!netComponentPins.has(net)) {
|
|
17
|
+
netComponentPins.set(net, []);
|
|
18
|
+
}
|
|
19
|
+
const items = netComponentPins.get(net);
|
|
20
|
+
items.push([
|
|
21
|
+
component.instanceName,
|
|
22
|
+
pin
|
|
23
|
+
]);
|
|
24
|
+
netComponentPins.set(net, items);
|
|
25
|
+
pinMapping.set(makeComponentPinHash(component.instanceName, pin), net);
|
|
26
|
+
});
|
|
27
|
+
allNodes.forEach(node => {
|
|
28
|
+
const nodeInfo = graph.node(node);
|
|
29
|
+
if (nodeInfo[0] === graph_js_1.RenderItemType.Component) {
|
|
30
|
+
const { component } = nodeInfo[1];
|
|
31
|
+
if (component.hasParam('no_connect')) {
|
|
32
|
+
const instanceName = component.instanceName;
|
|
33
|
+
const edges = graph.nodeEdges(node);
|
|
34
|
+
const otherNodes = [];
|
|
35
|
+
edges.forEach(edge => {
|
|
36
|
+
const edgeInfo = graph.edge(edge.v, edge.w);
|
|
37
|
+
let targetComponentName;
|
|
38
|
+
let targetPin;
|
|
39
|
+
if (edge.v === instanceName) {
|
|
40
|
+
otherNodes.push(edge.w);
|
|
41
|
+
targetComponentName = edge.w;
|
|
42
|
+
targetPin = edgeInfo[3];
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
targetComponentName = edge.v;
|
|
46
|
+
targetPin = edgeInfo[1];
|
|
47
|
+
}
|
|
48
|
+
const componentPinHash = makeComponentPinHash(targetComponentName, targetPin);
|
|
49
|
+
if (pinMapping.has(componentPinHash)) {
|
|
50
|
+
const net = pinMapping.get(componentPinHash);
|
|
51
|
+
const tmpNetComponentPins = netComponentPins.get(net);
|
|
52
|
+
const remainingItems = tmpNetComponentPins.filter(item => {
|
|
53
|
+
if (item[0] === instanceName) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
else if (item[0] === targetComponentName
|
|
57
|
+
&& item[1].getHashValue() === targetPin.getHashValue()) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
});
|
|
62
|
+
if (remainingItems.length > 0) {
|
|
63
|
+
const targetInfo = graph.node(targetComponentName);
|
|
64
|
+
const tmpComponent = targetInfo[1];
|
|
65
|
+
items.push({
|
|
66
|
+
type: rules_js_1.ERC_Rules.NoConnectOnConnectedPin,
|
|
67
|
+
instance: component,
|
|
68
|
+
target: {
|
|
69
|
+
instance: tmpComponent.component,
|
|
70
|
+
pin: targetPin
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return items;
|
|
80
|
+
}
|
|
81
|
+
exports.RuleCheck_NoConnectOnConnectedPin = RuleCheck_NoConnectOnConnectedPin;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EvaluateERCRules = exports.ERC_Rules = void 0;
|
|
4
|
+
const unconnected_pins_js_1 = require("./unconnected-pins.js");
|
|
5
|
+
const no_connect_on_connected_pin_js_1 = require("./no-connect-on-connected-pin.js");
|
|
6
|
+
var ERC_Rules;
|
|
7
|
+
(function (ERC_Rules) {
|
|
8
|
+
ERC_Rules["UnconnectedPin"] = "UNCONNECTED-PIN";
|
|
9
|
+
ERC_Rules["UnconnectedWire"] = "UNCONNECTED-WIRE";
|
|
10
|
+
ERC_Rules["NoConnectOnConnectedPin"] = "NO-CONNECT-ON-CONNECTED-PIN";
|
|
11
|
+
})(ERC_Rules || (exports.ERC_Rules = ERC_Rules = {}));
|
|
12
|
+
function EvaluateERCRules(visitor, graph, nets) {
|
|
13
|
+
const ruleCheckItems = [];
|
|
14
|
+
const creationCtx = visitor.creationCtx;
|
|
15
|
+
ruleCheckItems.push(...(0, unconnected_pins_js_1.RuleCheck_UnconnectedPinsWires)(graph), ...(0, no_connect_on_connected_pin_js_1.RuleCheck_NoConnectOnConnectedPin)(graph, nets));
|
|
16
|
+
const reportItems = [];
|
|
17
|
+
ruleCheckItems.forEach(item => {
|
|
18
|
+
const { type } = item;
|
|
19
|
+
switch (type) {
|
|
20
|
+
case ERC_Rules.UnconnectedPin:
|
|
21
|
+
{
|
|
22
|
+
const instance = item.instance;
|
|
23
|
+
const token = getComponentFirstCtxToken(instance);
|
|
24
|
+
if (token) {
|
|
25
|
+
reportItems.push({
|
|
26
|
+
type,
|
|
27
|
+
start: token,
|
|
28
|
+
message: `Unconnected pin ${item.pin} for component`
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
break;
|
|
33
|
+
case ERC_Rules.UnconnectedWire:
|
|
34
|
+
{
|
|
35
|
+
const wire = item.wire;
|
|
36
|
+
if (creationCtx.has(wire)) {
|
|
37
|
+
const tmpCtx = creationCtx.get(wire);
|
|
38
|
+
const startToken = tmpCtx.start;
|
|
39
|
+
reportItems.push({
|
|
40
|
+
type,
|
|
41
|
+
start: startToken,
|
|
42
|
+
message: `Unconnected wire end`
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
break;
|
|
47
|
+
case ERC_Rules.NoConnectOnConnectedPin:
|
|
48
|
+
{
|
|
49
|
+
const instance = item.instance;
|
|
50
|
+
const token = getComponentFirstCtxToken(instance);
|
|
51
|
+
if (token) {
|
|
52
|
+
reportItems.push({
|
|
53
|
+
type,
|
|
54
|
+
start: token,
|
|
55
|
+
message: `No connect on connected pin`
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
const sortedReport = reportItems.toSorted((a, b) => {
|
|
63
|
+
return a.start.start - b.start.start;
|
|
64
|
+
});
|
|
65
|
+
return sortedReport;
|
|
66
|
+
}
|
|
67
|
+
exports.EvaluateERCRules = EvaluateERCRules;
|
|
68
|
+
function getComponentFirstCtxToken(instance) {
|
|
69
|
+
if (instance.ctxReferences.length > 0) {
|
|
70
|
+
const { ctx } = instance.ctxReferences[0];
|
|
71
|
+
return ctx.start;
|
|
72
|
+
}
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RuleCheck_UnconnectedPinsWires = void 0;
|
|
4
|
+
const graph_js_1 = require("../graph.js");
|
|
5
|
+
const rules_js_1 = require("./rules.js");
|
|
6
|
+
function RuleCheck_UnconnectedPinsWires(graph) {
|
|
7
|
+
const items = [];
|
|
8
|
+
const allNodes = graph.nodes();
|
|
9
|
+
allNodes.forEach(node => {
|
|
10
|
+
const nodeInfo = graph.node(node);
|
|
11
|
+
if (nodeInfo[0] === graph_js_1.RenderItemType.Component) {
|
|
12
|
+
const { component } = nodeInfo[1];
|
|
13
|
+
const edges = graph.nodeEdges(node);
|
|
14
|
+
const instanceName = component.instanceName;
|
|
15
|
+
const connectedPins = [];
|
|
16
|
+
edges.forEach(edge => {
|
|
17
|
+
const edgeInfo = graph.edge(edge.v, edge.w);
|
|
18
|
+
let pin;
|
|
19
|
+
if (edge.v === instanceName) {
|
|
20
|
+
pin = edgeInfo[1];
|
|
21
|
+
}
|
|
22
|
+
else if (edge.w === instanceName) {
|
|
23
|
+
pin = edgeInfo[3];
|
|
24
|
+
}
|
|
25
|
+
connectedPins.push(pin.getHashValue());
|
|
26
|
+
});
|
|
27
|
+
const pinIds = Array.from(component.pins.keys());
|
|
28
|
+
pinIds.forEach(pinId => {
|
|
29
|
+
const hashValue = pinId.getHashValue();
|
|
30
|
+
if (connectedPins.indexOf(hashValue) === -1) {
|
|
31
|
+
items.push({
|
|
32
|
+
type: rules_js_1.ERC_Rules.UnconnectedPin,
|
|
33
|
+
instance: component,
|
|
34
|
+
pin: pinId,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
else if (nodeInfo[0] === graph_js_1.RenderItemType.Wire) {
|
|
40
|
+
const renderWire = nodeInfo[1];
|
|
41
|
+
const edges = graph.nodeEdges(node);
|
|
42
|
+
if (edges.length < 2) {
|
|
43
|
+
items.push({
|
|
44
|
+
type: rules_js_1.ERC_Rules.UnconnectedWire,
|
|
45
|
+
wire: renderWire.wire,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return items;
|
|
51
|
+
}
|
|
52
|
+
exports.RuleCheck_UnconnectedPinsWires = RuleCheck_UnconnectedPinsWires;
|