Skip to content

Commit 95e4d65

Browse files
authored
Merge pull request #18 from ialokim/refactor-ports
Refactor class hierarchy, markup and ports
2 parents 8c36026 + 5ba54a6 commit 95e4d65

15 files changed

+1444
-752
lines changed

examples/gates.json

+420
Large diffs are not rendered by default.

src/cells/arith.mjs

+112-122
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,56 @@ import bigInt from 'big-integer';
66
import * as help from '../help.mjs';
77
import { Vector3vl } from '3vl';
88

9-
// Unary arithmetic operations
10-
export const Arith11 = Gate.define('Arith11', {
9+
// base class for arithmetic operations displayed with a circle
10+
export const Arith = Gate.define('Arith', {
1111
size: { width: 40, height: 40 },
1212
attrs: {
13-
'circle.body': { r: 20, cx: 20, cy: 20 },
13+
'circle.body': { refR: 0.5, refCx: 0.5, refCy: 0.5 },
1414
'text.oper': {
15-
fill: 'black',
16-
'ref-x': .5, 'ref-y': .5, 'y-alignment': 'middle',
17-
'text-anchor': 'middle',
18-
'font-size': '14px'
15+
refX: .5, refY: .5,
16+
textAnchor: 'middle', textVerticalAnchor: 'middle',
17+
fontSize: '12pt'
18+
}
19+
},
20+
ports: {
21+
groups: {
22+
'in': { position: { name: 'left', args: { dx: 10 } }, attrs: { 'line.wire': { x2: -35 }, 'circle.port': { refX: -35 } }, z: -1 },
23+
'out': { position: { name: 'right', args: { dx: -10 } }, attrs: { 'line.wire': { x2: 35 }, 'circle.port': { refX: 35 } }, z: -1 }
1924
}
2025
}
2126
}, {
22-
constructor: function(args) {
23-
if (!args.bits) args.bits = { in: 1, out: 1 };
24-
if (!args.signed) args.signed = false;
25-
this.markup = [
26-
this.addWire(args, 'right', 0.5, { id: 'out', dir: 'out', bits: args.bits.out }),
27-
this.addWire(args, 'left', 0.5, { id: 'in', dir: 'in', bits: args.bits.in }),
28-
'<circle class="body"/>',
29-
'<text class="label"/>',
30-
'<text class="oper"/>',
31-
].join('');
32-
Gate.prototype.constructor.apply(this, arguments);
27+
markup: Gate.prototype.markup.concat([{
28+
tagName: 'circle',
29+
className: 'body'
30+
}, {
31+
tagName: 'text',
32+
className: 'oper'
33+
}
34+
]),
35+
gateParams: Gate.prototype.gateParams.concat(['bits', 'signed']),
36+
unsupportedPropChanges: Gate.prototype.unsupportedPropChanges.concat(['signed'])
37+
});
38+
39+
// Unary arithmetic operations
40+
export const Arith11 = Arith.define('Arith11', {
41+
/* default properties */
42+
bits: { in: 1, out: 1 },
43+
signed: false
44+
}, {
45+
initialize: function() {
46+
Arith.prototype.initialize.apply(this, arguments);
47+
48+
const bits = this.prop('bits');
49+
50+
this.addPorts([
51+
{ id: 'in', group: 'in', dir: 'in', bits: bits.in },
52+
{ id: 'out', group: 'out', dir: 'out', bits: bits.out }
53+
]);
54+
55+
this.on('change:bits', (_,bits) => {
56+
this.setPortBits('in', bits.in);
57+
this.setPortBits('out', bits.out);
58+
});
3359
},
3460
operation: function(data) {
3561
const bits = this.get('bits');
@@ -38,35 +64,31 @@ export const Arith11 = Gate.define('Arith11', {
3864
return {
3965
out: help.bigint2sig(this.arithop(help.sig2bigint(data.in, this.get('signed'))), bits.out)
4066
};
41-
},
42-
gateParams: Gate.prototype.gateParams.concat(['bits', 'signed'])
67+
}
4368
});
4469

4570
// Binary arithmetic operations
46-
export const Arith21 = Gate.define('Arith21', {
47-
size: { width: 40, height: 40 },
48-
attrs: {
49-
'circle.body': { r: 20, cx: 20, cy: 20 },
50-
'text.oper': {
51-
fill: 'black',
52-
'ref-x': .5, 'ref-y': .5, 'y-alignment': 'middle',
53-
'text-anchor': 'middle',
54-
'font-size': '14px'
55-
}
56-
}
71+
export const Arith21 = Arith.define('Arith21', {
72+
/* default properties */
73+
bits: { in1: 1, in2: 1, out: 1 },
74+
signed: { in1: false, in2: false }
5775
}, {
58-
constructor: function(args) {
59-
if (!args.bits) args.bits = { in1: 1, in2: 1, out: 1 };
60-
if (!args.signed) args.signed = { in1: false, in2: false };
61-
this.markup = [
62-
this.addWire(args, 'right', 0.5, { id: 'out', dir: 'out', bits: args.bits.out }),
63-
this.addWire(args, 'left', 0.3, { id: 'in1', dir: 'in', bits: args.bits.in1 }),
64-
this.addWire(args, 'left', 0.7, { id: 'in2', dir: 'in', bits: args.bits.in2 }),
65-
'<circle class="body"/>',
66-
'<text class="label"/>',
67-
'<text class="oper"/>',
68-
].join('');
69-
Gate.prototype.constructor.apply(this, arguments);
76+
initialize: function() {
77+
Arith.prototype.initialize.apply(this, arguments);
78+
79+
const bits = this.prop('bits');
80+
81+
this.addPorts([
82+
{ id: 'in1', group: 'in', dir: 'in', bits: bits.in1 },
83+
{ id: 'in2', group: 'in', dir: 'in', bits: bits.in2 },
84+
{ id: 'out', group: 'out', dir: 'out', bits: bits.out }
85+
]);
86+
87+
this.on('change:bits', (_, bits) => {
88+
this.setPortBits('in1', bits.in1);
89+
this.setPortBits('in2', bits.in2);
90+
this.setPortBits('out', bits.out);
91+
});
7092
},
7193
operation: function(data) {
7294
const bits = this.get('bits');
@@ -78,36 +100,32 @@ export const Arith21 = Gate.define('Arith21', {
78100
help.sig2bigint(data.in1, sgn.in1 && sgn.in2),
79101
help.sig2bigint(data.in2, sgn.in1 && sgn.in2)), bits.out)
80102
};
81-
},
82-
gateParams: Gate.prototype.gateParams.concat(['bits', 'signed'])
103+
}
83104
});
84105

85106
// Bit shift operations
86-
export const Shift = Gate.define('Shift', {
87-
size: { width: 40, height: 40 },
88-
attrs: {
89-
'circle.body': { r: 20, cx: 20, cy: 20 },
90-
'text.oper': {
91-
fill: 'black',
92-
'ref-x': .5, 'ref-y': .5, 'y-alignment': 'middle',
93-
'text-anchor': 'middle',
94-
'font-size': '14px'
95-
}
96-
}
107+
export const Shift = Arith.define('Shift', {
108+
/* default properties */
109+
bits: { in1: 1, in2: 1, out: 1 },
110+
signed: { in1: false, in2: false, out: false },
111+
fillx: false
97112
}, {
98-
constructor: function(args) {
99-
if (!args.bits) args.bits = { in1: 1, in2: 1, out: 1 };
100-
if (!args.signed) args.signed = { in1: false, in2: false, out: false };
101-
if (!args.fillx) args.fillx = false;
102-
this.markup = [
103-
this.addWire(args, 'right', 0.5, { id: 'out', dir: 'out', bits: args.bits.out }),
104-
this.addWire(args, 'left', 0.3, { id: 'in1', dir: 'in', bits: args.bits.in1 }),
105-
this.addWire(args, 'left', 0.7, { id: 'in2', dir: 'in', bits: args.bits.in2 }),
106-
'<circle class="body"/>',
107-
'<text class="label"/>',
108-
'<text class="oper"/>',
109-
].join('');
110-
Gate.prototype.constructor.apply(this, arguments);
113+
initialize: function() {
114+
Arith.prototype.initialize.apply(this, arguments);
115+
116+
const bits = this.prop('bits');
117+
118+
this.addPorts([
119+
{ id: 'in1', group: 'in', dir: 'in', bits: bits.in1 },
120+
{ id: 'in2', group: 'in', dir: 'in', bits: bits.in2 },
121+
{ id: 'out', group: 'out', dir: 'out', bits: bits.out }
122+
]);
123+
124+
this.on('change:bits', (_, bits) => {
125+
this.setPortBits('in1', bits.in1);
126+
this.setPortBits('in2', bits.in2);
127+
this.setPortBits('out', bits.out);
128+
});
111129
},
112130
operation: function(data) {
113131
const bits = this.get('bits');
@@ -125,34 +143,31 @@ export const Shift = Gate.define('Shift', {
125143
: my_in.slice(am).concat(Vector3vl.make(am, fillx ? 0 : sgn.out ? my_in.get(my_in.bits-1) : -1));
126144
return { out: out.slice(0, bits.out) };
127145
},
128-
gateParams: Gate.prototype.gateParams.concat(['bits', 'signed', 'fillx'])
146+
gateParams: Arith.prototype.gateParams.concat(['fillx']),
147+
unsupportedPropChanges: Arith.prototype.unsupportedPropChanges.concat(['fillx'])
129148
});
130149

131150
// Comparison operations
132-
export const Compare = Gate.define('Compare', {
133-
size: { width: 40, height: 40 },
134-
attrs: {
135-
'circle.body': { r: 20, cx: 20, cy: 20 },
136-
'text.oper': {
137-
fill: 'black',
138-
'ref-x': .5, 'ref-y': .5, 'y-alignment': 'middle',
139-
'text-anchor': 'middle',
140-
'font-size': '14px'
141-
}
142-
}
151+
export const Compare = Arith.define('Compare', {
152+
/* default properties */
153+
bits: { in1: 1, in2: 1 },
154+
signed: { in1: false, in2: false }
143155
}, {
144-
constructor: function(args) {
145-
if (!args.bits) args.bits = { in1: 1, in2: 1 };
146-
if (!args.signed) args.signed = { in1: false, in2: false };
147-
this.markup = [
148-
this.addWire(args, 'right', 0.5, { id: 'out', dir: 'out', bits: 1 }),
149-
this.addWire(args, 'left', 0.3, { id: 'in1', dir: 'in', bits: args.bits.in1 }),
150-
this.addWire(args, 'left', 0.7, { id: 'in2', dir: 'in', bits: args.bits.in2 }),
151-
'<circle class="body"/>',
152-
'<text class="label"/>',
153-
'<text class="oper"/>',
154-
].join('');
155-
Gate.prototype.constructor.apply(this, arguments);
156+
initialize: function() {
157+
Arith.prototype.initialize.apply(this, arguments);
158+
159+
const bits = this.prop('bits');
160+
161+
this.addPorts([
162+
{ id: 'in1', group: 'in', dir: 'in', bits: bits.in1 },
163+
{ id: 'in2', group: 'in', dir: 'in', bits: bits.in2 },
164+
{ id: 'out', group: 'out', dir: 'out', bits: 1 }
165+
]);
166+
167+
this.on('change:bits', (_, bits) => {
168+
this.setPortBits('in1', bits.in1);
169+
this.setPortBits('in2', bits.in2);
170+
});
156171
},
157172
operation: function(data) {
158173
const bits = this.get('bits');
@@ -164,35 +179,11 @@ export const Compare = Gate.define('Compare', {
164179
help.sig2bigint(data.in1, sgn.in1 && sgn.in2),
165180
help.sig2bigint(data.in2, sgn.in1 && sgn.in2)))
166181
};
167-
},
168-
gateParams: Gate.prototype.gateParams.concat(['bits', 'signed'])
182+
}
169183
});
170184

171-
export const EqCompare = Gate.define('EqCompare', {
172-
size: { width: 40, height: 40 },
173-
attrs: {
174-
'circle.body': { r: 20, cx: 20, cy: 20 },
175-
'text.oper': {
176-
fill: 'black',
177-
'ref-x': .5, 'ref-y': .5, 'y-alignment': 'middle',
178-
'text-anchor': 'middle',
179-
'font-size': '14px'
180-
}
181-
}
182-
}, {
183-
constructor: function(args) {
184-
if (!args.bits) args.bits = { in1: 1, in2: 1 };
185-
if (!args.signed) args.signed = { in1: false, in2: false };
186-
this.markup = [
187-
this.addWire(args, 'right', 0.5, { id: 'out', dir: 'out', bits: 1 }),
188-
this.addWire(args, 'left', 0.3, { id: 'in1', dir: 'in', bits: args.bits.in1 }),
189-
this.addWire(args, 'left', 0.7, { id: 'in2', dir: 'in', bits: args.bits.in2 }),
190-
'<circle class="body"/>',
191-
'<text class="label"/>',
192-
'<text class="oper"/>',
193-
].join('');
194-
Gate.prototype.constructor.apply(this, arguments);
195-
},
185+
// Equality operations
186+
export const EqCompare = Compare.define('EqCompare', {}, {
196187
operation: function(data) {
197188
const bits = this.get('bits');
198189
const sgn = this.get('signed');
@@ -203,8 +194,7 @@ export const EqCompare = Gate.define('EqCompare', {
203194
return {
204195
out: this.bincomp(in1, in2)
205196
};
206-
},
207-
gateParams: Gate.prototype.gateParams.concat(['bits', 'signed'])
197+
}
208198
});
209199

210200
// Negation

0 commit comments

Comments
 (0)