Comparing version 0.0.22 to 0.0.23
{ | ||
"name": "hdl-js", | ||
"version": "0.0.22", | ||
"version": "0.0.23", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "description": "Hardware definition language (HDL) and Hardware simulator", |
110
README.md
@@ -29,2 +29,3 @@ # hdl-js | ||
- [Memory chips](#memory-chips) | ||
- [Clock](#clock) | ||
- [Composite gates](#composite-gates) | ||
@@ -148,3 +149,3 @@ | ||
- `BUILTIN` -- refer to a name of a built-in chip: in this case the implementation is fully take from the built-in gate, and the `PARTS` section can be omitted | ||
- `CLOCKED` -- describes which inputs/outputs are _clocked_ (see clock description below in [memory chips](#memory-chips)) | ||
- `CLOCKED` -- describes which inputs/outputs are [clocked](#clock) | ||
@@ -730,3 +731,3 @@ Let's take a look at the [examples/And.hdl](https://github.com/DmitrySoshnikov/hdl-js/blob/master/examples/And.hdl) file: | ||
For example, the more complex [HalfAdder](https://github.com/DmitrySoshnikov/hdl-js/blob/master/src/emulator/hardware/builtin-gates/HalfAdder.js) chip can be built on top of Xor, and And gates: | ||
For example, the more complex [HalfAdder](https://github.com/DmitrySoshnikov/hdl-js/blob/master/src/emulator/hardware/builtin-gates/HalfAdder.js) chip can be built on top of `Xor`, and `And` gates: | ||
@@ -771,4 +772,4 @@ ``` | ||
- [Register](https://github.com/DmitrySoshnikov/hdl-js/blob/master/src/emulator/hardware/builtin-gates/Register.js) (16-bit memory unit) | ||
- ARegister (Address Register) | ||
- DRegister (Data Register) | ||
- [ARegister](https://github.com/DmitrySoshnikov/hdl-js/blob/master/src/emulator/hardware/builtin-gates/ARegister.js) (Address Register) | ||
- [DRegister](https://github.com/DmitrySoshnikov/hdl-js/blob/master/src/emulator/hardware/builtin-gates/DRegister.js) (Data Register) | ||
- [PC](https://github.com/DmitrySoshnikov/hdl-js/blob/master/src/emulator/hardware/builtin-gates/PC.js) (Program Counter) | ||
@@ -784,4 +785,18 @@ - [RAM](https://github.com/DmitrySoshnikov/hdl-js/blob/master/src/emulator/hardware/builtin-gates/RAM.js) (Random Access Memory) | ||
Running the: | ||
The _internal state_ of a clocked chip can _only_ change on the _rising edge_. While the _output_ is _committed_ (usually to reflect the internal state) on the _falling edge_ of the clock. This _delay_ of the output is exactly reflected in the DFF, that is _Delay_ Flip-Flop, name. | ||
See detailed clock description in the next section. | ||
### Clock | ||
The _System clock_ is used to synchronize clocked chips (see example above in [memory chips](#memory-chips)). | ||
A clock operates on the [clock rate](https://en.wikipedia.org/wiki/Clock_rate), that is, _number of cycles per second_, measured in **Hz**. The hight the clock rate, the faster machine is. | ||
And a **clock cycle** consists of two parts: _rising edge_, and _falling edge_. | ||
As mentioned in the [memory chips](#memory-chips) section, all clocked gates can change their internal state _only on the rising edge_. And on the falling edge the _commit_ the value form the state to the output pins. | ||
For example, running the: | ||
``` | ||
@@ -841,6 +856,89 @@ hdl-js --gate Bit --describe | ||
The _internal state_ of a clocked chip can _only_ change on the _rising edge_. While the _output_ is _committed_ (usually to reflect the internal state) on the _falling edge_ of the clock. This _delay_ of the output is exactly reflected in the DFF, that is _Delay_ Flip-Flop, name. | ||
From Node the `Clock` is available on the `emulator` object, and we can also get access to the global singleton `SystemClock`, which is used to synchronize the clocked chips: | ||
```js | ||
const hdl = require('hdl-js'); | ||
const { | ||
emulator: { | ||
Clock, | ||
Pin, | ||
}, | ||
} = hdl; | ||
const clock = new Clock({rate: 10, value: -5}); | ||
const pin = new Pin({name: 'a'}); | ||
// Track clock events. | ||
clock.on('tick', value => pin.setValue(value)); | ||
clock.tick(); | ||
console.log(pin.getValue()); // +5; | ||
``` | ||
The clock emits the following events: | ||
- `tick` - rising edge | ||
- `tock` - falling edge | ||
- `next` - half cycle (`tick` or `tock`) | ||
- `cycle` - full cycle (`tick` -> `tock`) | ||
- `value` - clock value change | ||
All the clocked gates are automatically subscribed to `SystemClock` events, and update the value of their `$clock` pin: | ||
```js | ||
const hdl = require('hdl-js'); | ||
const { | ||
emulator: { | ||
Gate, | ||
Clock: { | ||
SystemClock, | ||
}, | ||
}, | ||
} = hdl; | ||
class MyGate extends Gate { | ||
static isClocked() { | ||
return true; | ||
} | ||
eval() { | ||
// Noop, handle only clock signal. | ||
return; | ||
} | ||
clockUp(clockValue) { | ||
console.log('Handle rising edge:', clockValue); | ||
} | ||
clockDown(clockValue) { | ||
console.log('Handle falling edge:', clockValue); | ||
} | ||
} | ||
MyGate.Spec = { | ||
inputPins: ['a'], | ||
outputPins: ['b'], | ||
}; | ||
const gate = MyGate.defaultFromSpec(); | ||
// Run full clock cycle. | ||
SystemClock.cycle(); | ||
/* | ||
Output: | ||
Handle rising edge: 0 | ||
Handle falling edge: -1 | ||
*/ | ||
``` | ||
### Composite gates | ||
TODO; WIP |
@@ -13,4 +13,6 @@ /** | ||
const {int16} = require('../../../util/typed-numbers'); | ||
const {SystemClock} = require('../Clock'); | ||
const {int16} = require('../../../util/numbers'); | ||
// Inputs. | ||
@@ -276,17 +278,12 @@ const a = new Pin({name: 'a', value: 1}); | ||
Gate.resetClock(); | ||
expect(Gate.isClockDown()).toBe(true); | ||
expect(Gate.isClockUp()).toBe(false); | ||
expect(Gate.getClockValue()).toBe(-0); | ||
SystemClock.reset(); | ||
gate.tick(); | ||
expect(Gate.isClockDown()).toBe(false); | ||
expect(Gate.isClockUp()).toBe(true); | ||
expect(Gate.getClockValue()).toBe(+0); | ||
const gateClock = gate.getPin('$clock'); | ||
SystemClock.tick(); | ||
expect(gateClock.getValue()).toBe(+0); | ||
expect(state).toBe(1); | ||
gate.tock(); | ||
expect(Gate.isClockDown()).toBe(true); | ||
expect(Gate.isClockUp()).toBe(false); | ||
expect(Gate.getClockValue()).toBe(-1); | ||
SystemClock.tock(); | ||
expect(gateClock.getValue()).toBe(-1); | ||
expect(state).toBe(1); | ||
@@ -297,17 +294,22 @@ expect(gate.getPin('out').getValue()).toBe(state); | ||
Gate.setClockValue(+3); | ||
expect(Gate.getClockValue()).toBe(+3); | ||
SystemClock.setValue(+3); | ||
expect(gateClock.getValue()).toBe(+3); | ||
gate.tock(); | ||
gate.tick(); | ||
expect(Gate.getClockValue()).toBe(+4); | ||
SystemClock.tock(); | ||
SystemClock.tick(); | ||
expect(gateClock.getValue()).toBe(+4); | ||
SystemClock.cycle(); | ||
expect(gateClock.getValue()).toBe(+5); | ||
// Convenient wrapper for `SystemClock.cycle`. | ||
gate.clockCycle(); | ||
expect(Gate.getClockValue()).toBe(+5); | ||
expect(SystemClock.getValue()).toBe(+6); | ||
expect(gateClock.getValue()).toBe(+6); | ||
gate.tock(); | ||
expect(Gate.getClockValue()).toBe(-6); | ||
SystemClock.tock(); | ||
expect(gateClock.getValue()).toBe(-7); | ||
gate.clockCycle(); | ||
expect(Gate.getClockValue()).toBe(-7); | ||
expect(gateClock.getValue()).toBe(-8); | ||
}); | ||
@@ -314,0 +316,0 @@ |
@@ -11,2 +11,227 @@ /** | ||
const {SystemClock} = require('../../Clock'); | ||
const {int16Table} = require('../../../../util/numbers'); | ||
/** | ||
* Testing data. | ||
*/ | ||
const data = int16Table([ | ||
{$clock: -0, in: 0, load: 0, out: 0}, | ||
{$clock: +0, in: 0, load: 0, out: 0}, | ||
{$clock: -1, in: 0, load: 0, out: 0}, | ||
{$clock: +1, in: 0, load: 1, out: 0}, | ||
{$clock: -2, in: 0, load: 1, out: 0}, | ||
{$clock: +2, in: 1, load: 0, out: 0}, | ||
{$clock: -3, in: 1, load: 0, out: 0}, | ||
{$clock: +3, in: 1, load: 1, out: 0}, | ||
{$clock: -4, in: 1, load: 1, out: 1}, | ||
{$clock: +4, in: 0, load: 0, out: 1}, | ||
{$clock: -5, in: 0, load: 0, out: 1}, | ||
{$clock: +5, in: 1, load: 0, out: 1}, | ||
{$clock: -6, in: 1, load: 0, out: 1}, | ||
{$clock: +6, in: 0, load: 1, out: 1}, | ||
{$clock: -7, in: 0, load: 1, out: 0}, | ||
{$clock: +7, in: 1, load: 1, out: 0}, | ||
{$clock: -8, in: 1, load: 1, out: 1}, | ||
{$clock: +8, in: 0, load: 0, out: 1}, | ||
{$clock: -9, in: 0, load: 0, out: 1}, | ||
{$clock: +9, in: 0, load: 0, out: 1}, | ||
{$clock: -10, in: 0, load: 0, out: 1}, | ||
{$clock: +10, in: 0, load: 0, out: 1}, | ||
{$clock: -11, in: 0, load: 0, out: 1}, | ||
{$clock: +11, in: 0, load: 0, out: 1}, | ||
{$clock: -12, in: 0, load: 0, out: 1}, | ||
{$clock: +12, in: 0, load: 0, out: 1}, | ||
{$clock: -13, in: 0, load: 0, out: 1}, | ||
{$clock: +13, in: 0, load: 0, out: 1}, | ||
{$clock: -14, in: 0, load: 0, out: 1}, | ||
{$clock: +14, in: 0, load: 0, out: 1}, | ||
{$clock: -15, in: 0, load: 0, out: 1}, | ||
{$clock: +15, in: 0, load: 0, out: 1}, | ||
{$clock: -16, in: 0, load: 0, out: 1}, | ||
{$clock: +16, in: 0, load: 0, out: 1}, | ||
{$clock: -17, in: 0, load: 0, out: 1}, | ||
{$clock: +17, in: 0, load: 0, out: 1}, | ||
{$clock: -18, in: 0, load: 0, out: 1}, | ||
{$clock: +18, in: 0, load: 0, out: 1}, | ||
{$clock: -19, in: 0, load: 0, out: 1}, | ||
{$clock: +19, in: 0, load: 0, out: 1}, | ||
{$clock: -20, in: 0, load: 0, out: 1}, | ||
{$clock: +20, in: 0, load: 0, out: 1}, | ||
{$clock: -21, in: 0, load: 0, out: 1}, | ||
{$clock: +21, in: 0, load: 0, out: 1}, | ||
{$clock: -22, in: 0, load: 0, out: 1}, | ||
{$clock: +22, in: 0, load: 0, out: 1}, | ||
{$clock: -23, in: 0, load: 0, out: 1}, | ||
{$clock: +23, in: 0, load: 0, out: 1}, | ||
{$clock: -24, in: 0, load: 0, out: 1}, | ||
{$clock: +24, in: 0, load: 0, out: 1}, | ||
{$clock: -25, in: 0, load: 0, out: 1}, | ||
{$clock: +25, in: 0, load: 0, out: 1}, | ||
{$clock: -26, in: 0, load: 0, out: 1}, | ||
{$clock: +26, in: 0, load: 0, out: 1}, | ||
{$clock: -27, in: 0, load: 0, out: 1}, | ||
{$clock: +27, in: 0, load: 0, out: 1}, | ||
{$clock: -28, in: 0, load: 0, out: 1}, | ||
{$clock: +28, in: 0, load: 0, out: 1}, | ||
{$clock: -29, in: 0, load: 0, out: 1}, | ||
{$clock: +29, in: 0, load: 0, out: 1}, | ||
{$clock: -30, in: 0, load: 0, out: 1}, | ||
{$clock: +30, in: 0, load: 0, out: 1}, | ||
{$clock: -31, in: 0, load: 0, out: 1}, | ||
{$clock: +31, in: 0, load: 0, out: 1}, | ||
{$clock: -32, in: 0, load: 0, out: 1}, | ||
{$clock: +32, in: 0, load: 0, out: 1}, | ||
{$clock: -33, in: 0, load: 0, out: 1}, | ||
{$clock: +33, in: 0, load: 0, out: 1}, | ||
{$clock: -34, in: 0, load: 0, out: 1}, | ||
{$clock: +34, in: 0, load: 0, out: 1}, | ||
{$clock: -35, in: 0, load: 0, out: 1}, | ||
{$clock: +35, in: 0, load: 0, out: 1}, | ||
{$clock: -36, in: 0, load: 0, out: 1}, | ||
{$clock: +36, in: 0, load: 0, out: 1}, | ||
{$clock: -37, in: 0, load: 0, out: 1}, | ||
{$clock: +37, in: 0, load: 0, out: 1}, | ||
{$clock: -38, in: 0, load: 0, out: 1}, | ||
{$clock: +38, in: 0, load: 0, out: 1}, | ||
{$clock: -39, in: 0, load: 0, out: 1}, | ||
{$clock: +39, in: 0, load: 0, out: 1}, | ||
{$clock: -40, in: 0, load: 0, out: 1}, | ||
{$clock: +40, in: 0, load: 0, out: 1}, | ||
{$clock: -41, in: 0, load: 0, out: 1}, | ||
{$clock: +41, in: 0, load: 0, out: 1}, | ||
{$clock: -42, in: 0, load: 0, out: 1}, | ||
{$clock: +42, in: 0, load: 0, out: 1}, | ||
{$clock: -43, in: 0, load: 0, out: 1}, | ||
{$clock: +43, in: 0, load: 0, out: 1}, | ||
{$clock: -44, in: 0, load: 0, out: 1}, | ||
{$clock: +44, in: 0, load: 0, out: 1}, | ||
{$clock: -45, in: 0, load: 0, out: 1}, | ||
{$clock: +45, in: 0, load: 0, out: 1}, | ||
{$clock: -46, in: 0, load: 0, out: 1}, | ||
{$clock: +46, in: 0, load: 0, out: 1}, | ||
{$clock: -47, in: 0, load: 0, out: 1}, | ||
{$clock: +47, in: 0, load: 0, out: 1}, | ||
{$clock: -48, in: 0, load: 0, out: 1}, | ||
{$clock: +48, in: 0, load: 0, out: 1}, | ||
{$clock: -49, in: 0, load: 0, out: 1}, | ||
{$clock: +49, in: 0, load: 0, out: 1}, | ||
{$clock: -50, in: 0, load: 0, out: 1}, | ||
{$clock: +50, in: 0, load: 0, out: 1}, | ||
{$clock: -51, in: 0, load: 0, out: 1}, | ||
{$clock: +51, in: 0, load: 0, out: 1}, | ||
{$clock: -52, in: 0, load: 0, out: 1}, | ||
{$clock: +52, in: 0, load: 0, out: 1}, | ||
{$clock: -53, in: 0, load: 0, out: 1}, | ||
{$clock: +53, in: 0, load: 0, out: 1}, | ||
{$clock: -54, in: 0, load: 0, out: 1}, | ||
{$clock: +54, in: 0, load: 0, out: 1}, | ||
{$clock: -55, in: 0, load: 0, out: 1}, | ||
{$clock: +55, in: 0, load: 0, out: 1}, | ||
{$clock: -56, in: 0, load: 0, out: 1}, | ||
{$clock: +56, in: 0, load: 0, out: 1}, | ||
{$clock: -57, in: 0, load: 0, out: 1}, | ||
{$clock: +57, in: 0, load: 1, out: 1}, | ||
{$clock: -58, in: 0, load: 1, out: 0}, | ||
{$clock: +58, in: 1, load: 0, out: 0}, | ||
{$clock: -59, in: 1, load: 0, out: 0}, | ||
{$clock: +59, in: 1, load: 0, out: 0}, | ||
{$clock: -60, in: 1, load: 0, out: 0}, | ||
{$clock: +60, in: 1, load: 0, out: 0}, | ||
{$clock: -61, in: 1, load: 0, out: 0}, | ||
{$clock: +61, in: 1, load: 0, out: 0}, | ||
{$clock: -62, in: 1, load: 0, out: 0}, | ||
{$clock: +62, in: 1, load: 0, out: 0}, | ||
{$clock: -63, in: 1, load: 0, out: 0}, | ||
{$clock: +63, in: 1, load: 0, out: 0}, | ||
{$clock: -64, in: 1, load: 0, out: 0}, | ||
{$clock: +64, in: 1, load: 0, out: 0}, | ||
{$clock: -65, in: 1, load: 0, out: 0}, | ||
{$clock: +65, in: 1, load: 0, out: 0}, | ||
{$clock: -66, in: 1, load: 0, out: 0}, | ||
{$clock: +66, in: 1, load: 0, out: 0}, | ||
{$clock: -67, in: 1, load: 0, out: 0}, | ||
{$clock: +67, in: 1, load: 0, out: 0}, | ||
{$clock: -68, in: 1, load: 0, out: 0}, | ||
{$clock: +68, in: 1, load: 0, out: 0}, | ||
{$clock: -69, in: 1, load: 0, out: 0}, | ||
{$clock: +69, in: 1, load: 0, out: 0}, | ||
{$clock: -70, in: 1, load: 0, out: 0}, | ||
{$clock: +70, in: 1, load: 0, out: 0}, | ||
{$clock: -71, in: 1, load: 0, out: 0}, | ||
{$clock: +71, in: 1, load: 0, out: 0}, | ||
{$clock: -72, in: 1, load: 0, out: 0}, | ||
{$clock: +72, in: 1, load: 0, out: 0}, | ||
{$clock: -73, in: 1, load: 0, out: 0}, | ||
{$clock: +73, in: 1, load: 0, out: 0}, | ||
{$clock: -74, in: 1, load: 0, out: 0}, | ||
{$clock: +74, in: 1, load: 0, out: 0}, | ||
{$clock: -75, in: 1, load: 0, out: 0}, | ||
{$clock: +75, in: 1, load: 0, out: 0}, | ||
{$clock: -76, in: 1, load: 0, out: 0}, | ||
{$clock: +76, in: 1, load: 0, out: 0}, | ||
{$clock: -77, in: 1, load: 0, out: 0}, | ||
{$clock: +77, in: 1, load: 0, out: 0}, | ||
{$clock: -78, in: 1, load: 0, out: 0}, | ||
{$clock: +78, in: 1, load: 0, out: 0}, | ||
{$clock: -79, in: 1, load: 0, out: 0}, | ||
{$clock: +79, in: 1, load: 0, out: 0}, | ||
{$clock: -80, in: 1, load: 0, out: 0}, | ||
{$clock: +80, in: 1, load: 0, out: 0}, | ||
{$clock: -81, in: 1, load: 0, out: 0}, | ||
{$clock: +81, in: 1, load: 0, out: 0}, | ||
{$clock: -82, in: 1, load: 0, out: 0}, | ||
{$clock: +82, in: 1, load: 0, out: 0}, | ||
{$clock: -83, in: 1, load: 0, out: 0}, | ||
{$clock: +83, in: 1, load: 0, out: 0}, | ||
{$clock: -84, in: 1, load: 0, out: 0}, | ||
{$clock: +84, in: 1, load: 0, out: 0}, | ||
{$clock: -85, in: 1, load: 0, out: 0}, | ||
{$clock: +85, in: 1, load: 0, out: 0}, | ||
{$clock: -86, in: 1, load: 0, out: 0}, | ||
{$clock: +86, in: 1, load: 0, out: 0}, | ||
{$clock: -87, in: 1, load: 0, out: 0}, | ||
{$clock: +87, in: 1, load: 0, out: 0}, | ||
{$clock: -88, in: 1, load: 0, out: 0}, | ||
{$clock: +88, in: 1, load: 0, out: 0}, | ||
{$clock: -89, in: 1, load: 0, out: 0}, | ||
{$clock: +89, in: 1, load: 0, out: 0}, | ||
{$clock: -90, in: 1, load: 0, out: 0}, | ||
{$clock: +90, in: 1, load: 0, out: 0}, | ||
{$clock: -91, in: 1, load: 0, out: 0}, | ||
{$clock: +91, in: 1, load: 0, out: 0}, | ||
{$clock: -92, in: 1, load: 0, out: 0}, | ||
{$clock: +92, in: 1, load: 0, out: 0}, | ||
{$clock: -93, in: 1, load: 0, out: 0}, | ||
{$clock: +93, in: 1, load: 0, out: 0}, | ||
{$clock: -94, in: 1, load: 0, out: 0}, | ||
{$clock: +94, in: 1, load: 0, out: 0}, | ||
{$clock: -95, in: 1, load: 0, out: 0}, | ||
{$clock: +95, in: 1, load: 0, out: 0}, | ||
{$clock: -96, in: 1, load: 0, out: 0}, | ||
{$clock: +96, in: 1, load: 0, out: 0}, | ||
{$clock: -97, in: 1, load: 0, out: 0}, | ||
{$clock: +97, in: 1, load: 0, out: 0}, | ||
{$clock: -98, in: 1, load: 0, out: 0}, | ||
{$clock: +98, in: 1, load: 0, out: 0}, | ||
{$clock: -99, in: 1, load: 0, out: 0}, | ||
{$clock: +99, in: 1, load: 0, out: 0}, | ||
{$clock: -100, in: 1, load: 0, out: 0}, | ||
{$clock: +100, in: 1, load: 0, out: 0}, | ||
{$clock: -101, in: 1, load: 0, out: 0}, | ||
{$clock: +101, in: 1, load: 0, out: 0}, | ||
{$clock: -102, in: 1, load: 0, out: 0}, | ||
{$clock: +102, in: 1, load: 0, out: 0}, | ||
{$clock: -103, in: 1, load: 0, out: 0}, | ||
{$clock: +103, in: 1, load: 0, out: 0}, | ||
{$clock: -104, in: 1, load: 0, out: 0}, | ||
{$clock: +104, in: 1, load: 0, out: 0}, | ||
{$clock: -105, in: 1, load: 0, out: 0}, | ||
{$clock: +105, in: 1, load: 0, out: 0}, | ||
{$clock: -106, in: 1, load: 0, out: 0}, | ||
{$clock: +106, in: 1, load: 0, out: 0}, | ||
{$clock: -107, in: 1, load: 0, out: 0}, | ||
]); | ||
describe('Bit', () => { | ||
@@ -17,2 +242,9 @@ it('Bit interface', () => { | ||
}); | ||
it('testing data', () => { | ||
SystemClock.reset(); | ||
expect(() => GateTestUtil.testTruthTable(data, Bit.defaultFromSpec())) | ||
.not.toThrow(); | ||
}); | ||
}); |
@@ -8,8 +8,9 @@ /** | ||
const Gate = require('../../Gate'); | ||
const GateTestUtil = require('../../gate-test-util'); | ||
const PC = require('../PC'); | ||
const {int16Table} = require('../../../../util/typed-numbers'); | ||
const {SystemClock} = require('../../Clock'); | ||
const {int16Table} = require('../../../../util/numbers'); | ||
/** | ||
@@ -59,3 +60,3 @@ * Testing data. | ||
it('testing data', () => { | ||
Gate.resetClock(); | ||
SystemClock.reset(); | ||
@@ -62,0 +63,0 @@ expect(() => GateTestUtil.testTruthTable(data, PC.defaultFromSpec())) |
@@ -8,6 +8,7 @@ /** | ||
const Gate = require('../../Gate'); | ||
const RAM = require('../RAM'); | ||
const GateTestUtil = require('../../gate-test-util'); | ||
const {SystemClock} = require('../../Clock'); | ||
describe('RAM', () => { | ||
@@ -20,3 +21,3 @@ it('RAM interface', () => { | ||
it('storage', () => { | ||
Gate.resetClock(); | ||
SystemClock.reset(); | ||
@@ -23,0 +24,0 @@ // Default is 8 registers. |
@@ -8,6 +8,7 @@ /** | ||
const Gate = require('../../Gate'); | ||
const RAM16K = require('../RAM16K'); | ||
const GateTestUtil = require('../../gate-test-util'); | ||
const {SystemClock} = require('../../Clock'); | ||
describe('RAM16K', () => { | ||
@@ -20,3 +21,3 @@ it('RAM16K interface', () => { | ||
it('storage', () => { | ||
Gate.resetClock(); | ||
SystemClock.reset(); | ||
@@ -23,0 +24,0 @@ const ram16KChip = new RAM16K(RAM16K.Spec); |
@@ -8,6 +8,7 @@ /** | ||
const Gate = require('../../Gate'); | ||
const RAM4K = require('../RAM4K'); | ||
const GateTestUtil = require('../../gate-test-util'); | ||
const {SystemClock} = require('../../Clock'); | ||
describe('RAM4K', () => { | ||
@@ -20,3 +21,3 @@ it('RAM4K interface', () => { | ||
it('storage', () => { | ||
Gate.resetClock(); | ||
SystemClock.reset(); | ||
@@ -23,0 +24,0 @@ const ram4KChip = new RAM4K(RAM4K.Spec); |
@@ -8,6 +8,7 @@ /** | ||
const Gate = require('../../Gate'); | ||
const RAM512 = require('../RAM512'); | ||
const GateTestUtil = require('../../gate-test-util'); | ||
const {SystemClock} = require('../../Clock'); | ||
describe('RAM512', () => { | ||
@@ -20,3 +21,3 @@ it('RAM512 interface', () => { | ||
it('storage', () => { | ||
Gate.resetClock(); | ||
SystemClock.reset(); | ||
@@ -23,0 +24,0 @@ const ram512Chip = new RAM512(RAM512.Spec); |
@@ -8,6 +8,7 @@ /** | ||
const Gate = require('../../Gate'); | ||
const RAM64 = require('../RAM64'); | ||
const GateTestUtil = require('../../gate-test-util'); | ||
const {SystemClock} = require('../../Clock'); | ||
describe('RAM64', () => { | ||
@@ -20,3 +21,3 @@ it('RAM64 interface', () => { | ||
it('storage', () => { | ||
Gate.resetClock(); | ||
SystemClock.reset(); | ||
@@ -23,0 +24,0 @@ const ram64Chip = new RAM64(RAM64.Spec); |
@@ -8,6 +8,7 @@ /** | ||
const Gate = require('../../Gate'); | ||
const RAM8 = require('../RAM8'); | ||
const GateTestUtil = require('../../gate-test-util'); | ||
const {SystemClock} = require('../../Clock'); | ||
describe('RAM8', () => { | ||
@@ -20,3 +21,3 @@ it('RAM8 interface', () => { | ||
it('storage', () => { | ||
Gate.resetClock(); | ||
SystemClock.reset(); | ||
@@ -23,0 +24,0 @@ const ram8Chip = new RAM8(RAM8.Spec); |
@@ -8,5 +8,164 @@ /** | ||
const GateTestUtil = require('../../gate-test-util'); | ||
const Register = require('../Register'); | ||
const GateTestUtil = require('../../gate-test-util'); | ||
const {SystemClock} = require('../../Clock'); | ||
const {int16Table} = require('../../../../util/numbers'); | ||
/** | ||
* Testing data. | ||
*/ | ||
const data = int16Table([ | ||
{$clock: -0, in: 0, load: 0, out: 0}, | ||
{$clock: +0, in: 0, load: 0, out: 0}, | ||
{$clock: -1, in: 0, load: 0, out: 0}, | ||
{$clock: +1, in: 0, load: 1, out: 0}, | ||
{$clock: -2, in: 0, load: 1, out: 0}, | ||
{$clock: +2, in: -32123, load: 0, out: 0}, | ||
{$clock: -3, in: -32123, load: 0, out: 0}, | ||
{$clock: +3, in: 11111, load: 0, out: 0}, | ||
{$clock: -4, in: 11111, load: 0, out: 0}, | ||
{$clock: +4, in: -32123, load: 1, out: 0}, | ||
{$clock: -5, in: -32123, load: 1, out: -32123}, | ||
{$clock: +5, in: -32123, load: 1, out: -32123}, | ||
{$clock: -6, in: -32123, load: 1, out: -32123}, | ||
{$clock: +6, in: -32123, load: 0, out: -32123}, | ||
{$clock: -7, in: -32123, load: 0, out: -32123}, | ||
{$clock: +7, in: 12345, load: 1, out: -32123}, | ||
{$clock: -8, in: 12345, load: 1, out: 12345}, | ||
{$clock: +8, in: 0, load: 0, out: 12345}, | ||
{$clock: -9, in: 0, load: 0, out: 12345}, | ||
{$clock: +9, in: 0, load: 1, out: 12345}, | ||
{$clock: -10, in: 0, load: 1, out: 0}, | ||
{$clock: +10, in: 1, load: 0, out: 0}, | ||
{$clock: -11, in: 1, load: 0, out: 0}, | ||
{$clock: +11, in: 1, load: 1, out: 0}, | ||
{$clock: -12, in: 1, load: 1, out: 1}, | ||
{$clock: +12, in: 2, load: 0, out: 1}, | ||
{$clock: -13, in: 2, load: 0, out: 1}, | ||
{$clock: +13, in: 2, load: 1, out: 1}, | ||
{$clock: -14, in: 2, load: 1, out: 2}, | ||
{$clock: +14, in: 4, load: 0, out: 2}, | ||
{$clock: -15, in: 4, load: 0, out: 2}, | ||
{$clock: +15, in: 4, load: 1, out: 2}, | ||
{$clock: -16, in: 4, load: 1, out: 4}, | ||
{$clock: +16, in: 8, load: 0, out: 4}, | ||
{$clock: -17, in: 8, load: 0, out: 4}, | ||
{$clock: +17, in: 8, load: 1, out: 4}, | ||
{$clock: -18, in: 8, load: 1, out: 8}, | ||
{$clock: +18, in: 16, load: 0, out: 8}, | ||
{$clock: -19, in: 16, load: 0, out: 8}, | ||
{$clock: +19, in: 16, load: 1, out: 8}, | ||
{$clock: -20, in: 16, load: 1, out: 16}, | ||
{$clock: +20, in: 32, load: 0, out: 16}, | ||
{$clock: -21, in: 32, load: 0, out: 16}, | ||
{$clock: +21, in: 32, load: 1, out: 16}, | ||
{$clock: -22, in: 32, load: 1, out: 32}, | ||
{$clock: +22, in: 64, load: 0, out: 32}, | ||
{$clock: -23, in: 64, load: 0, out: 32}, | ||
{$clock: +23, in: 64, load: 1, out: 32}, | ||
{$clock: -24, in: 64, load: 1, out: 64}, | ||
{$clock: +24, in: 128, load: 0, out: 64}, | ||
{$clock: -25, in: 128, load: 0, out: 64}, | ||
{$clock: +25, in: 128, load: 1, out: 64}, | ||
{$clock: -26, in: 128, load: 1, out: 128}, | ||
{$clock: +26, in: 256, load: 0, out: 128}, | ||
{$clock: -27, in: 256, load: 0, out: 128}, | ||
{$clock: +27, in: 256, load: 1, out: 128}, | ||
{$clock: -28, in: 256, load: 1, out: 256}, | ||
{$clock: +28, in: 512, load: 0, out: 256}, | ||
{$clock: -29, in: 512, load: 0, out: 256}, | ||
{$clock: +29, in: 512, load: 1, out: 256}, | ||
{$clock: -30, in: 512, load: 1, out: 512}, | ||
{$clock: +30, in: 1024, load: 0, out: 512}, | ||
{$clock: -31, in: 1024, load: 0, out: 512}, | ||
{$clock: +31, in: 1024, load: 1, out: 512}, | ||
{$clock: -32, in: 1024, load: 1, out: 1024}, | ||
{$clock: +32, in: 2048, load: 0, out: 1024}, | ||
{$clock: -33, in: 2048, load: 0, out: 1024}, | ||
{$clock: +33, in: 2048, load: 1, out: 1024}, | ||
{$clock: -34, in: 2048, load: 1, out: 2048}, | ||
{$clock: +34, in: 4096, load: 0, out: 2048}, | ||
{$clock: -35, in: 4096, load: 0, out: 2048}, | ||
{$clock: +35, in: 4096, load: 1, out: 2048}, | ||
{$clock: -36, in: 4096, load: 1, out: 4096}, | ||
{$clock: +36, in: 8192, load: 0, out: 4096}, | ||
{$clock: -37, in: 8192, load: 0, out: 4096}, | ||
{$clock: +37, in: 8192, load: 1, out: 4096}, | ||
{$clock: -38, in: 8192, load: 1, out: 8192}, | ||
{$clock: +38, in: 16384, load: 0, out: 8192}, | ||
{$clock: -39, in: 16384, load: 0, out: 8192}, | ||
{$clock: +39, in: 16384, load: 1, out: 8192}, | ||
{$clock: -40, in: 16384, load: 1, out: 16384}, | ||
{$clock: +40, in: -32768, load: 0, out: 16384}, | ||
{$clock: -41, in: -32768, load: 0, out: 16384}, | ||
{$clock: +41, in: -32768, load: 1, out: 16384}, | ||
{$clock: -42, in: -32768, load: 1, out: -32768}, | ||
{$clock: +42, in: -2, load: 0, out: -32768}, | ||
{$clock: -43, in: -2, load: 0, out: -32768}, | ||
{$clock: +43, in: -2, load: 1, out: -32768}, | ||
{$clock: -44, in: -2, load: 1, out: -2}, | ||
{$clock: +44, in: -3, load: 0, out: -2}, | ||
{$clock: -45, in: -3, load: 0, out: -2}, | ||
{$clock: +45, in: -3, load: 1, out: -2}, | ||
{$clock: -46, in: -3, load: 1, out: -3}, | ||
{$clock: +46, in: -5, load: 0, out: -3}, | ||
{$clock: -47, in: -5, load: 0, out: -3}, | ||
{$clock: +47, in: -5, load: 1, out: -3}, | ||
{$clock: -48, in: -5, load: 1, out: -5}, | ||
{$clock: +48, in: -9, load: 0, out: -5}, | ||
{$clock: -49, in: -9, load: 0, out: -5}, | ||
{$clock: +49, in: -9, load: 1, out: -5}, | ||
{$clock: -50, in: -9, load: 1, out: -9}, | ||
{$clock: +50, in: -17, load: 0, out: -9}, | ||
{$clock: -51, in: -17, load: 0, out: -9}, | ||
{$clock: +51, in: -17, load: 1, out: -9}, | ||
{$clock: -52, in: -17, load: 1, out: -17}, | ||
{$clock: +52, in: -33, load: 0, out: -17}, | ||
{$clock: -53, in: -33, load: 0, out: -17}, | ||
{$clock: +53, in: -33, load: 1, out: -17}, | ||
{$clock: -54, in: -33, load: 1, out: -33}, | ||
{$clock: +54, in: -65, load: 0, out: -33}, | ||
{$clock: -55, in: -65, load: 0, out: -33}, | ||
{$clock: +55, in: -65, load: 1, out: -33}, | ||
{$clock: -56, in: -65, load: 1, out: -65}, | ||
{$clock: +56, in: -129, load: 0, out: -65}, | ||
{$clock: -57, in: -129, load: 0, out: -65}, | ||
{$clock: +57, in: -129, load: 1, out: -65}, | ||
{$clock: -58, in: -129, load: 1, out: -129}, | ||
{$clock: +58, in: -257, load: 0, out: -129}, | ||
{$clock: -59, in: -257, load: 0, out: -129}, | ||
{$clock: +59, in: -257, load: 1, out: -129}, | ||
{$clock: -60, in: -257, load: 1, out: -257}, | ||
{$clock: +60, in: -513, load: 0, out: -257}, | ||
{$clock: -61, in: -513, load: 0, out: -257}, | ||
{$clock: +61, in: -513, load: 1, out: -257}, | ||
{$clock: -62, in: -513, load: 1, out: -513}, | ||
{$clock: +62, in: -1025, load: 0, out: -513}, | ||
{$clock: -63, in: -1025, load: 0, out: -513}, | ||
{$clock: +63, in: -1025, load: 1, out: -513}, | ||
{$clock: -64, in: -1025, load: 1, out: -1025}, | ||
{$clock: +64, in: -2049, load: 0, out: -1025}, | ||
{$clock: -65, in: -2049, load: 0, out: -1025}, | ||
{$clock: +65, in: -2049, load: 1, out: -1025}, | ||
{$clock: -66, in: -2049, load: 1, out: -2049}, | ||
{$clock: +66, in: -4097, load: 0, out: -2049}, | ||
{$clock: -67, in: -4097, load: 0, out: -2049}, | ||
{$clock: +67, in: -4097, load: 1, out: -2049}, | ||
{$clock: -68, in: -4097, load: 1, out: -4097}, | ||
{$clock: +68, in: -8193, load: 0, out: -4097}, | ||
{$clock: -69, in: -8193, load: 0, out: -4097}, | ||
{$clock: +69, in: -8193, load: 1, out: -4097}, | ||
{$clock: -70, in: -8193, load: 1, out: -8193}, | ||
{$clock: +70, in: -16385, load: 0, out: -8193}, | ||
{$clock: -71, in: -16385, load: 0, out: -8193}, | ||
{$clock: +71, in: -16385, load: 1, out: -8193}, | ||
{$clock: -72, in: -16385, load: 1, out: -16385}, | ||
{$clock: +72, in: 32767, load: 0, out: -16385}, | ||
{$clock: -73, in: 32767, load: 0, out: -16385}, | ||
{$clock: +73, in: 32767, load: 1, out: -16385}, | ||
{$clock: -74, in: 32767, load: 1, out: 32767}, | ||
]); | ||
describe('Register', () => { | ||
@@ -17,2 +176,9 @@ it('Register interface', () => { | ||
}); | ||
it('testing data', () => { | ||
SystemClock.reset(); | ||
expect(() => GateTestUtil.testTruthTable(data, Register.defaultFromSpec())) | ||
.not.toThrow(); | ||
}); | ||
}); |
@@ -10,3 +10,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -13,0 +13,0 @@ /** |
@@ -10,3 +10,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -13,0 +13,0 @@ /** |
@@ -10,3 +10,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -13,0 +13,0 @@ /** |
@@ -10,3 +10,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -13,0 +13,0 @@ /** |
@@ -10,3 +10,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -13,0 +13,0 @@ /** |
@@ -10,3 +10,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -13,0 +13,0 @@ /** |
@@ -10,3 +10,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -13,0 +13,0 @@ /** |
@@ -10,3 +10,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -13,0 +13,0 @@ /** |
@@ -10,3 +10,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -13,0 +13,0 @@ /** |
@@ -10,3 +10,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -13,0 +13,0 @@ /** |
@@ -10,3 +10,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -13,0 +13,0 @@ /** |
@@ -11,3 +11,3 @@ /** | ||
const {int16Table, int16} = require('../../../util/typed-numbers'); | ||
const {int16Table, int16} = require('../../../util/numbers'); | ||
@@ -14,0 +14,0 @@ /** |
@@ -11,3 +11,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -14,0 +14,0 @@ /** |
@@ -11,3 +11,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -14,0 +14,0 @@ /** |
@@ -11,3 +11,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -14,0 +14,0 @@ /** |
@@ -11,3 +11,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -14,0 +14,0 @@ /** |
@@ -11,3 +11,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -14,0 +14,0 @@ /** |
@@ -11,3 +11,3 @@ /** | ||
const {int16Table} = require('../../../util/typed-numbers'); | ||
const {int16Table} = require('../../../util/numbers'); | ||
@@ -14,0 +14,0 @@ /** |
@@ -11,3 +11,3 @@ /** | ||
const {int16Table, int16} = require('../../../util/typed-numbers'); | ||
const {int16Table, int16} = require('../../../util/numbers'); | ||
@@ -14,0 +14,0 @@ /** |
@@ -9,5 +9,6 @@ /** | ||
const assert = require('assert'); | ||
const Gate = require('./Gate'); | ||
const Pin = require('./Pin'); | ||
const {SystemClock} = require('./Clock'); | ||
/** | ||
@@ -28,3 +29,3 @@ * Evaluates the gate logic on the truth table input. | ||
function testTruthTable(table, gate) { | ||
Gate.resetClock(); | ||
SystemClock.reset(); | ||
const {result} = gate.execOnData(table); | ||
@@ -31,0 +32,0 @@ assert.deepEqual(table, result); |
@@ -13,23 +13,11 @@ /** | ||
const {int16} = require('../../util/typed-numbers'); | ||
const {SystemClock} = require('./Clock'); | ||
/** | ||
* Test for a neagtive zero. | ||
*/ | ||
function isNegativeZero(value) { | ||
return value === 0 && (1 / value === -Infinity); | ||
} | ||
const { | ||
int16, | ||
isNegativeZero, | ||
toSignedString, | ||
} = require('../../util/numbers'); | ||
/** | ||
* Converts a number value to decimal string with the sign. | ||
*/ | ||
function toSignString(value) { | ||
if (isNegativeZero(value)) { | ||
return '-0'; | ||
} | ||
return (value >= 0 ? '+' : '') + value; | ||
} | ||
/** | ||
* Abstract gate class, base for `BuiltInGate`, and `CompositeGate`. | ||
@@ -65,2 +53,11 @@ */ | ||
this.init(); | ||
// Subscribe to the clock events for clocked gates. | ||
if (this.getClass().isClocked()) { | ||
SystemClock.on('tick', () => this.tick()); | ||
SystemClock.on('tock', () => this.tock()); | ||
SystemClock.on('value', value => { | ||
this.getPin(Pin.CLOCK).setValue(value); | ||
}); | ||
} | ||
} | ||
@@ -230,8 +227,6 @@ | ||
if (this.getClass().isClocked()) { | ||
// The -0 is a setup row, don't execute on it. | ||
if (!isNegativeZero(row[Pin.CLOCK])) { | ||
Gate.isClockDown() ? this.tick() : this.tock(); | ||
this.getPin(Pin.CLOCK).setValue(Gate.getClockValue()); | ||
} | ||
// The -0 is a setup row, don't execute on it, | ||
// otherwise, emulate next clock half-cycle (tick or tock). | ||
if (this.getClass().isClocked() && !isNegativeZero(row[Pin.CLOCK])) { | ||
SystemClock.next(); | ||
} else { | ||
@@ -317,3 +312,3 @@ this.eval(); | ||
if (pinInfo.kind === 'special') { | ||
content = toSignString(row[name]); | ||
content = toSignedString(row[name]); | ||
} else { | ||
@@ -394,3 +389,3 @@ // Normal pin. | ||
name: Pin.CLOCK, | ||
value: Gate.getClockValue(), | ||
value: SystemClock.getValue(), | ||
}); | ||
@@ -462,5 +457,5 @@ } | ||
tick() { | ||
Gate._clockValue = -Gate._clockValue; | ||
this.eval(); | ||
this.clockUp(); | ||
this.clockUp(this.getPin(Pin.CLOCK).getValue()); | ||
return this; | ||
} | ||
@@ -475,5 +470,5 @@ | ||
tock() { | ||
Gate._clockValue = -(Math.abs(Gate._clockValue) + 1); | ||
this.clockDown(); | ||
this.clockDown(this.getPin(Pin.CLOCK).getValue()); | ||
this.eval(); | ||
return this; | ||
} | ||
@@ -485,52 +480,7 @@ | ||
clockCycle() { | ||
if (Gate.isClockDown()) { | ||
this.tick(); | ||
this.tock(); | ||
} else { | ||
this.tock(); | ||
this.tick(); | ||
} | ||
SystemClock.cycle(); | ||
return this; | ||
} | ||
/** | ||
* Resets clock. | ||
* | ||
* Initial clock value. Each tick: set positive sign, | ||
* each tock: increase, set negative sign back. | ||
*/ | ||
static resetClock() { | ||
Gate.setClockValue(-0); | ||
} | ||
/** | ||
* Sets clock value. | ||
*/ | ||
static setClockValue(value) { | ||
Gate._clockValue = value; | ||
} | ||
/** | ||
* Returns clock value. | ||
*/ | ||
static getClockValue() { | ||
return Gate._clockValue; | ||
} | ||
/** | ||
* Whether the clock is up. | ||
*/ | ||
static isClockUp() { | ||
return !this.isClockDown(); | ||
} | ||
/** | ||
* Whether the clock is down. | ||
*/ | ||
static isClockDown() { | ||
return isNegativeZero(Gate._clockValue) || Gate._clockValue < 0; | ||
} | ||
} | ||
Gate.resetClock(); | ||
module.exports = Gate; |
@@ -11,2 +11,3 @@ /** | ||
const CompositeGate = require('./CompositeGate'); | ||
const Clock = require('./Clock'); | ||
const Gate = require('./Gate'); | ||
@@ -20,2 +21,7 @@ const Pin = require('./Pin'); | ||
/** | ||
* Expose `Clock` class. | ||
*/ | ||
Clock, | ||
/** | ||
* Expose `Gate` class. | ||
@@ -22,0 +28,0 @@ */ |
@@ -8,3 +8,3 @@ /** | ||
const {int16} = require('../../util/typed-numbers'); | ||
const {int16} = require('../../util/numbers'); | ||
@@ -11,0 +11,0 @@ /** |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
216598
102
5665
938