Full Code of mbad0la/Architect for AI

master 6fefaebc7d3a cached
13 files
26.8 KB
8.3k tokens
53 symbols
1 requests
Download .txt
Repository: mbad0la/Architect
Branch: master
Commit: 6fefaebc7d3a
Files: 13
Total size: 26.8 KB

Directory structure:
gitextract_b37vrddc/

├── .gitignore
├── Combinational/
│   ├── arithmetics.js
│   ├── decoders.js
│   └── gates.js
├── Connectors/
│   └── transport.js
├── LICENSE
├── README.md
├── Sequential/
│   └── ff.js
├── Utility/
│   ├── ioManager.js
│   └── new.js
├── index.js
├── package.json
└── test.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
node_modules


================================================
FILE: Combinational/arithmetics.js
================================================
const { AndGate, XorGate, OrGate } = require('./gates')
const { wires } = require('../Connectors/transport')
const { Hardware } = require('../Utility/new')

class HalfAdder extends Hardware {

  constructor(x, s) {
    if (x.length != 2 || s.length != 2) throw new Error('Invalid Connection/s')
    super([x, s])
    this.components.push(new XorGate([x[0]], [x[1]], [s[1]]))
    this.components.push(new AndGate([x[0]], [x[1]], [s[0]]))
  }

}

class FullAdder extends Hardware {

  constructor(x, s) {
    if (x.length != 3 || s.length != 2) throw new Error('Invalid Connection/s')
    super([x, s])
    this.internalWiring = wires(3)
    this.components.push(new HalfAdder([x[0], x[1]], [this.internalWiring[0], this.internalWiring[1]]))
    this.components.push(new HalfAdder([this.internalWiring[1], x[2]], [this.internalWiring[2], s[1]]))
    this.components.push(new OrGate([this.internalWiring[0]], [this.internalWiring[2]], [s[0]]))
  }

}

class PipoAdder extends Hardware {

  constructor(a, b, s) {
    if (a.length != b.length || s.length != a.length + 1) throw new Error('Invalid Connection/s')
    super([a, b, s])
    let size = a.length
    this.internalWiring = wires(size)
    if (size > 1) {
      this.components.push(new FullAdder([a[0], b[0], this.internalWiring[0]], [this.internalWiring[1], s[size]]))
      for(let i = 1; i < size - 1; i++) {
        this.components.push(new FullAdder([a[i], b[i], this.internalWiring[i]], [this.internalWiring[i+1], s[size-i]]))
      }
      this.components.push(new FullAdder([a[size-1], b[size-1], this.internalWiring[size-1]], [s[0], s[1]]))
    } else {
      this.components.push(new FullAdder([a[0], b[0], this.internalWiring[0]], [s[0], s[1]]))
    }
    this.internalWiring[0].propagateSignal(0)
  }

}

module.exports = { HalfAdder, FullAdder, PipoAdder }


================================================
FILE: Combinational/decoders.js
================================================
const { Hardware } = require('../Utility/new')
const { wires } = require('../Connectors/transport')
const { NotGate, AndGate } = require('./gates')

class Decoder1x2 extends Hardware {

  constructor(x, o) {
    if (x.length != 1 || o.length != 1) throw new Error('Invalid Connection/s')
    super([x, [o[0], x[0]]])
    this.components.push(new NotGate(x, o))
  }

}

class Decoder2x4 extends Hardware {

  constructor(x0, x1, o) {
    if(x0.length != 1 || x1.length != 1 || o.length != 4) throw new Error('Invalid Connection/s')
    super([x0, x1, o])
    this.internalWiring = wires(2)
    this.components.push(new Decoder1x2(x0, [this.internalWiring[0]]))
    this.components.push(new Decoder1x2(x1, [this.internalWiring[1]]))
    this.components.push(new AndGate([this.internalWiring[0]], [this.internalWiring[1]], [o[0]]))
    this.components.push(new AndGate([this.internalWiring[0]], x1, [o[1]]))
    this.components.push(new AndGate(x0, [this.internalWiring[1]], [o[2]]))
    this.components.push(new AndGate(x0, x1, [o[3]]))
  }

}

module.exports = { Decoder1x2, Decoder2x4 }


================================================
FILE: Combinational/gates.js
================================================
const { Hardware } = require('../Utility/new')

class AndGate extends Hardware {

  constructor(x, y, o) {
    if (x.length != 1 || y.length != 1 || o.length != 1) throw new Error('Invalid Connection/s')
    super([x, y, o])
    this.x = x
    this.y = y
    this.o = o
    this.hardware = this.hardware.bind(this)
    x[0].on('signal', this.hardware)
    y[0].on('signal', this.hardware)
  }

  hardware() {
    let xSig = this.x[0].getSignal()
    let ySig = this.y[0].getSignal()
    if (xSig === 0 || ySig === 0) {
      this.o[0].propagateSignal(0)
    } else if (xSig === undefined || ySig === undefined) {
      this.o[0].propagateSignal(undefined)
    } else this.o[0].propagateSignal(xSig && ySig)
  }

}

class TriInpAndGate extends Hardware {

  constructor(x, y, z, o) {
    if (x.length != 1 || y.length != 1 || z.length != 1 || o.length != 1) throw new Error('Invalid Connection/s')
    super([x, y, z, o])
    this.x = x
    this.y = y
    this.z = z
    this.o = o
    this.hardware = this.hardware.bind(this)
    x[0].on('signal', this.hardware)
    y[0].on('signal', this.hardware)
    z[0].on('signal', this.hardware)
  }

  hardware() {
    let xSig = this.x[0].getSignal()
    let ySig = this.y[0].getSignal()
    let zSig = this.z[0].getSignal()
    if (xSig === 0 || ySig === 0 || zSig === 0) {
      this.o[0].propagateSignal(0)
    } else if (xSig === undefined || ySig === undefined || zSig === undefined) {
      this.o[0].propagateSignal(undefined)
    } else this.o[0].propagateSignal(xSig && ySig && zSig)
  }

}

class OrGate extends Hardware {

  constructor(x, y, o) {
    if (x.length != 1 || y.length != 1 || o.length != 1) throw new Error('Invalid Connection/s')
    super([x, y, o])
    this.x = x
    this.y = y
    this.o  = o
    this.hardware = this.hardware.bind(this)
    x[0].on('signal', this.hardware)
    y[0].on('signal', this.hardware)
  }

  hardware() {
    let xSig = this.x[0].getSignal()
    let ySig = this.y[0].getSignal()
    if (xSig === 1 || ySig === 1) {
      this.o[0].propagateSignal(1)
    } else if (xSig === undefined || ySig === undefined) {
      this.o[0].propagateSignal(undefined)
    } else this.o[0].propagateSignal(xSig || ySig)
  }

}

class XorGate extends Hardware {

  constructor(x, y, o) {
    if (x.length != 1 || y.length != 1 || o.length != 1) throw new Error('Invalid Connection/s')
    super([x, y, o])
    this.x = x
    this.y = y
    this.o  = o
    this.hardware = this.hardware.bind(this)
    x[0].on('signal', this.hardware)
    y[0].on('signal', this.hardware)
  }

  hardware() {
    let xSig = this.x[0].getSignal()
    let ySig = this.y[0].getSignal()
    if (xSig === undefined || ySig === undefined) {
      this.o[0].propagateSignal(undefined)
    } else this.o[0].propagateSignal(Number(xSig != ySig))
  }

}

class NotGate extends Hardware {

  constructor(x, o) {
    if (x.length != 1 || o.length != 1) throw new Error('Invalid Connection/s')
    super([x, o])
    this.x = x
    this.o = o
    this.hardware = this.hardware.bind(this)
    x[0].on('signal', this.hardware)
  }

  hardware() {
    let xSig = this.x[0].getSignal()
    if (xSig === undefined) {
      this.o[0].propagateSignal(undefined)
    } else this.o[0].propagateSignal(Number(!xSig))
  }

}

class NandGate extends Hardware {

  constructor(x, y, o) {
    if (x.length != 1 || y.length != 1 || o.length != 1) throw new Error('Invalid Connection/s')
    super([x, y, o])
    this.x = x
    this.y = y
    this.o  = o
    this.hardware = this.hardware.bind(this)
    x[0].on('signal', this.hardware)
    y[0].on('signal', this.hardware)
  }

  hardware() {
    let xSig = this.x[0].getSignal()
    let ySig = this.y[0].getSignal()
    if (xSig === 0 || ySig === 0) {
      this.o[0].propagateSignal(1)
    } else if (xSig === undefined || ySig === undefined) {
      this.o[0].propagateSignal(undefined)
    } else this.o[0].propagateSignal(Number(!(xSig && ySig)))
  }

}

class NorGate extends Hardware {

  constructor(x, y, o) {
    if (x.length != 1 || y.length != 1 || o.length != 1) throw new Error('Invalid Connection/s')
    super([x, y, o])
    this.x = x
    this.y = y
    this.o  = o
    this.hardware = this.hardware.bind(this)
    x[0].on('signal', this.hardware)
    y[0].on('signal', this.hardware)
  }

  hardware() {
    let xSig = this.x[0].getSignal()
    let ySig = this.y[0].getSignal()
    if (xSig === 1 || ySig === 1) {
      this.o[0].propagateSignal(0)
    } else if (xSig === undefined || ySig === undefined) {
      this.o[0].propagateSignal(undefined)
    } else this.o[0].propagateSignal(Number(!(xSig || ySig)))
  }

}

class XnorGate extends Hardware {

  constructor(x, y, o) {
    if (x.length != 1 || y.length != 1 || o.length != 1) throw new Error('Invalid Connection/s')
    super([x, y, o])
    this.x = x
    this.y = y
    this.o  = o
    this.hardware = this.hardware.bind(this)
    x[0].on('signal', this.hardware)
    y[0].on('signal', this.hardware)
  }

  hardware() {
    let xSig = this.x[0].getSignal()
    let ySig = this.y[0].getSignal()
    if (xSig === undefined || ySig === undefined) {
      this.o[0].propagateSignal(undefined)
    } else this.o[0].propagateSignal(Number(xSig == ySig))
  }

}

module.exports = { AndGate, TriInpAndGate, OrGate, XorGate, NotGate, NandGate, NorGate, XnorGate }


================================================
FILE: Connectors/transport.js
================================================
const EventEmitter = require('events')

class Wire extends EventEmitter {

  constructor(sig) {
    super()

    this.signal = sig
    this.propagateSignal = this.propagateSignal.bind(this)
    this.getSignal = this.getSignal.bind(this)
  }

  propagateSignal(newSignal) {
    let oldSignal = this.signal

    this.signal = newSignal

    if (oldSignal != this.signal) this.emit('signal')
  }

  getSignal() {
    return this.signal
  }

}

class Pulse extends Wire {

  constructor(t, i) {
    super()

    this.i = i
    this.timePeriod = t
    this.alter = this.alter.bind(this)
    this.switchOn = this.switchOn.bind(this)
    this.switchOff = this.switchOff.bind(this)
    this.interval = undefined
  }

  alter() {
    this.propagateSignal(Number(!this.signal))
  }

  switchOn() {
    if (!this.interval) {
      this.signal = this.i
      this.interval = setInterval(this.alter, this.timePeriod)
    }
  }

  switchOff() {
    if (this.interval) {
      clearInterval(this.interval)
      this.signal = undefined
      this.interval = undefined
    }
  }

}

function wires(n) {
  let wireSet = []
  for(let i = 0; i < n ; i++) {
    wireSet.push(new Wire())
  }
  return wireSet
}

module.exports = { Pulse, wires }


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2017 Mayank Badola

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
![Architect](media/banner.png)

> Highly Extensible Hardware Description Library for JavaScript Developers

Hardware is event-driven. And it is functional in nature, having abstractions on abstractions.

Makes sense to have JavaScript emulate it doesn't it?

### Motivation

Hardware Description can be fun and very educational, but I had to learn [VHDL](https://en.wikipedia.org/wiki/VHDL) to be able to do so.

Hence, being a JavaScript Enthusiast, I decided to write this library down for JavaScript Developers who wanted to get into Hardware Description but were reluctant to learn a new language for it.

For people not acquainted with both VHDL and JS, I'm pretty sure the learning curve would be lesser for this library. Although I cannot state that my library is better as it is not easy to compete with a language intended for hardware description, nevertheless, I will keep on hacking this library to see how this experiment goes.

Let's get to business!

### Installation

`npm install architectjs`

### Existing Hardware Abstractions

* Gates
  * AndGate
  * TriInpAndGate
  * OrGate
  * XorGate
  * NotGate
  * NandGate
  * NorGate
  * XnorGate
* Decoders
  * Decoder1x2
  * Decoder2x4
* Arithmetics
  * HalfAdder
  * FullAdder
  * PipoAdder
* Flip-Flops
  * SRFlipFlop
  * DFlipFlop

### :electric_plug: Plug-n-Play

Use existing abstractions seemlessly.

Let's plug in an AND-Gate

```js
const { wires } = require('architectjs')('Connectors')
const { AndGate } = require('architectjs')('Gates')
const { StringIO } = require('architectjs')('IO')

// provision wires to connect to your hardware
const inputA = wires(1)
const inputB = wires(1)
const output = wires(1)
// initialise the hardware
const hWare = new AndGate(inputA, inputB, output)
// wrap hardware in a I/O BlackBox
// this is compulsory, to be able to do I/O using strings
const ioHandler = new StringIO(hWare)

console.log(ioHandler.input('1', '1')) // prints 1

console.log(ioHandler.input('0', '0')) // prints 0
```

Say what? `AND` is way too easy to be called an abstraction?

No worries, let's plug in this generalised Parallel-in-Parallel-out Adder!

```js
const { wires } = require('architectjs')('Connectors')
const { PipoAdder } = require('architectjs')('Arithmetics')
const { StringIO } = require('architectjs')('IO')

// code for 4-bit adder
const inputA = wires(4)
const inputB = wires(4)
const sum = wires(5)
const hWare = new PipoAdder(inputA, inputB, sum)
const ioHandler = new StringIO(hWare)
console.log(ioHandler.input('1111', '1111')) // prints 11110
```

Or maybe we want to build something from existing abstractions?

#### Abstraction Rules and Specs

* Every Class/hardware extends on `Hardware`.
* Every initialisation argument to the class instance has to be an array of `Wire` instances (obtained from the `wires` method).
* An array consisting of I/O `wires` is passed onto the parent class `Hardware`, with only the last element being the output parameter. It is necessary to provide every input parameter and the output parameter to be able to wrap this in a `StringIO` instance to do I/O operations with `string` arguments.
* Every class instance has two instance variables available from the parent `Hardware` instance :
  * internalWiring - Array of `Wire` instances (initially empty).
  * components - Array of abstractions used to build your hardware (initially empty).
* Your entire logic goes into your Class' constructor.
* `internalWiring` variable is used to initialise `Wire` instances that are not a part of the I/O for the hardware but are required to inter-connect the sub-components in your abstraction.
* `components` variable is used to store instances of subcomponents used in your hardware. This helps a designer to quickly refer to all the build blocks that went into making a particular piece of hardware.


Let's build a 4-input AND Gate using the above rules and specifications.

```js
const { wires } = require('architectjs')('Connectors')
const { AndGate } = require('architectjs')('Gates')
const { StringIO } = require('architectjs')('IO')
const { Hardware } = require('architectjs')('Base')

class FourInpAndGate extends Hardware {

  constructor(a, b, c, d, o) {
    super([a, b, c, d, o])
    this.internalWiring = wires(2) // declare wires to be used internally
    this.components.push(new AndGate(a, b, this.internalWiring[0]))
    this.components.push(new AndGate(c, d, this.internalWiring[1]))
    this.components.push(new AndGate(this.internalWiring[0], this.internalWiring[1], o))
  }

}

const a = wires(1)
const b = wires(1)
const c = wires(1)
const d = wires(1)
const o = wires(1)

const fourInpAnd = new FourInpAndGate(a, b, c, d, o)
const ioHandler = new StringIO(fourInpAnd)

console.log(ioHandler('0', '1', '1', '1')) // prints 0

console.log(ioHandler('1', '1', '1', '1')) // prints 1
```

### Creating a Declarative Hardware Component

#### Some Basic Rules

* Every Class/hardware extends on `Hardware`.
* All the logic goes inside the `hardware` method of your component's Class.
* Event to be listened for must be `signal`.

#### Let's get started

Every `Wire` instance extends on `EventEmitter`, thus this library essentially works by registering listeners in a Class instance and binding them to the `hardware` method of the Class.

With the help of `getSignal` and `propagateSignal` methods of `Wire`, read changes from input `Wire` instances, use your logic on them, and emit result through the output `Wire` instance.

Let's set this up with an example taken from this library

```js
const { Hardware } = require('architectjs')('Base')

class AndGate extends Hardware {

  constructor(x, y, o) {
    if (x.length != 1 || y.length != 1 || o.length != 1) throw new Error('Invalid Connection/s')
    super([x, y, o])
    this.x = x
    this.y = y
    this.o = o
    this.hardware = this.hardware.bind(this)
    x[0].on('signal', this.hardware)
    y[0].on('signal', this.hardware)
  }

  hardware() {
    let xSig = this.x[0].getSignal()
    let ySig = this.y[0].getSignal()
    if (xSig === 0 || ySig === 0) {
      this.o[0].propagateSignal(0)
    } else if (xSig === undefined || ySig === undefined) {
      this.o[0].propagateSignal(undefined)
    } else this.o[0].propagateSignal(xSig && ySig)
  }

}
```
### Development

New Hardware Component Proposals should be put up as an issue to discuss it's vialibility and modelling. I won't be considering anything else other than component proposals at the moment.

I am also facing some problems in figuring out how to implement clock-edge driven circuits and circuits that have a feedback to them. Most of time, infinte events are triggered due to the feedbacking in the circuits.

There are just so many possibilities to do here! Would love to get contributions from the community :smile:


================================================
FILE: Sequential/ff.js
================================================
const { AndGate, NorGate, NandGate, NotGate } = require('../Combinational/gates')
const { wires } = require('../Connectors/transport')
const { Hardware } = require('../Utility/new')

class SRFlipFlop extends Hardware {

  constructor(s, r, qqbar, c) {
    if (s.length != 1 || r.length != 1 || qqbar.length != 2) throw new Error('Invalid Connection/s')
    super([s, r, [qqbar[0]]])
    this.internalWiring = wires(2)
    this.components.push(new AndGate([c], s, [this.internalWiring[0]]))
    this.components.push(new AndGate([c], r, [this.internalWiring[1]]))
    this.components.push(new NorGate([this.internalWiring[0]], [qqbar[0]], [qqbar[1]]))
    this.components.push(new NorGate([this.internalWiring[1]], [qqbar[1]], [qqbar[0]]))
  }

}

class DFlipFlop extends Hardware {

  constructor(d, qqbar, c) {
    if (d.length != 1 || qqbar.length != 2) throw new Error('Invalid Connection/s')
    super([d, [qqbar[0]]])
    this.internalWiring = wires(3)
    this.components.push(new NotGate(d, [this.internalWiring[0]]))
    this.components.push(new NandGate([c], d, [this.internalWiring[1]]))
    this.components.push(new NandGate([c], [this.internalWiring[0]], [this.internalWiring[2]]))
    this.components.push(new NandGate([this.internalWiring[1]], [qqbar[1]], [qqbar[0]]))
    this.components.push(new NandGate([this.internalWiring[2]], [qqbar[0]], [qqbar[1]]))
  }

}

module.exports = { SRFlipFlop, DFlipFlop }


================================================
FILE: Utility/ioManager.js
================================================
class StringIO {

  constructor({ioMapping}) {
    let inputGroup = ioMapping.length - 1
    this.i = ioMapping.slice(0, inputGroup)
    this.o = ioMapping[inputGroup]
  }

  input(...inputSeqs) {
    let inpIndex = inputSeqs[0].length - 1
    let totalInps = this.i.length
    let pos = 0
    while (inpIndex >= 0) {
      for (let inpNum = 0; inpNum < totalInps; ++inpNum) {
        this.i[inpNum][pos].propagateSignal(Number(inputSeqs[inpNum][inpIndex]))
      }
      ++pos
      --inpIndex
    }

    let outBuff = this.o.map((wire) => {
      return wire.getSignal()
    })

    outBuff = outBuff.join('')

    return outBuff
  }

}

module.exports = { StringIO }


================================================
FILE: Utility/new.js
================================================
class Hardware {

  constructor(io) {
    this.ioMapping = io
    this.internalWiring = []
    this.components = []
  }

}

module.exports = { Hardware }


================================================
FILE: index.js
================================================
module.exports = function(path) {
  return {
    'Gates': require('./Combinational/gates'),
    'Arithmetics': require('./Combinational/arithmetics'),
    'Connectors': require('./Connectors/transport'),
    'Sequential': require('./Sequential/ff'),
    'IO': require('./Utility/ioManager'),
    'Base': require('./Utility/new')
  } [ path ]
}


================================================
FILE: package.json
================================================
{
  "name": "architectjs",
  "version": "0.1.2",
  "description": "Hardware Description and Emulation Library",
  "keywords": [
    "hardware",
    "design",
    "emulation",
    "hardware emulation",
    "vhdl",
    "architect",
    "architectjs",
    "library"
  ],
  "scripts": {
    "test": "ava"
  },
  "repository": "mbad0la/Architect",
  "author": {
    "name": "Mayank Badola",
    "email": "badola21295@gmail.com",
    "url": "https://mayankbadola.me"
  },
  "license": "MIT",
  "devDependencies": {
    "ava": "^0.25.0"
  }
}


================================================
FILE: test.js
================================================
import test from 'ava'
import { wires, Pulse } from './Connectors/transport'
import { NotGate, AndGate, TriInpAndGate, XorGate } from './Combinational/gates'
import { PipoAdder, HalfAdder, FullAdder } from './Combinational/arithmetics'
import { SRFlipFlop } from './Sequential/ff'
import { StringIO } from './Utility/ioManager'
import { Decoder1x2, Decoder2x4 } from './Combinational/decoders'


test('Not-Gate : 1', t => {
  const inputA = wires(1)
  const output = wires(1)
  const hWare = new NotGate(inputA, output)
  const ioHandler = new StringIO(hWare)
  t.is(ioHandler.input('1'), '0')
})

test('Not-Gate : 2', t => {
  const inputA = wires(1)
  const output = wires(1)
  const hWare = new NotGate(inputA, output)
  const ioHandler = new StringIO(hWare)
  t.is(ioHandler.input('0'), '1')
})

test('And-Gate : 1', t => {
  const inputA = wires(1)
  const inputB = wires(1)
  const output = wires(1)
  const hWare = new AndGate(inputA, inputB, output)
  const ioHandler = new StringIO(hWare)
  t.is(ioHandler.input('0', '0'), '0')
})

test('And-Gate : 2', t => {
  const inputA = wires(1)
  const inputB = wires(1)
  const output = wires(1)
  const hWare = new AndGate(inputA, inputB, output)
  const ioHandler = new StringIO(hWare)
  t.is(ioHandler.input('0', '1'), '0')
})

test('And-Gate : 3', t => {
  const inputA = wires(1)
  const inputB = wires(1)
  const output = wires(1)
  const hWare = new AndGate(inputA, inputB, output)
  const ioHandler = new StringIO(hWare)
  t.is(ioHandler.input('1', '1'), '1')
})

test('Tri-Input And-Gate', t => {
  const inputX = wires(1)
  const inputY = wires(1)
  const inputZ = wires(1)
  const output = wires(1)
  const hWare = new TriInpAndGate(inputX, inputY, inputZ, output)
  const ioHandler = new StringIO(hWare)
  t.is(ioHandler.input('1', '1', '1'), '1')
})

test('Xor-Gate : 1', t => {
  const inputA = wires(1)
  const inputB = wires(1)
  const output = wires(1)
  const hWare = new XorGate(inputA, inputB, output)
  const ioHandler = new StringIO(hWare)
  t.is(ioHandler.input('1', '1'), '0')
})

test('Xor-Gate : 2', t => {
  const inputA = wires(1)
  const inputB = wires(1)
  const output = wires(1)
  const hWare = new XorGate(inputA, inputB, output)
  const ioHandler = new StringIO(hWare)
  t.is(ioHandler.input('0', '1'), '1')
})

test('Overflow for HalfAdder', t => {
  const inputA = wires(2)
  const sum = wires(2)
  const hWare = new HalfAdder(inputA, sum)
  const ioHandler = new StringIO(hWare)
  t.is(ioHandler.input('11'), '10')
})

test('Overflow for FullAdder', t => {
  const inputA = wires(3)
  const sum = wires(2)
  const hWare = new FullAdder(inputA, sum)
  const ioHandler = new StringIO(hWare)
  t.is(ioHandler.input('111'), '11')
})

test('Overflow for Parallel Adder (1 bit)', t => {
  const inputA = wires(1)
  const inputB = wires(1)
  const sum = wires(2)
  const hWare = new PipoAdder(inputA, inputB, sum)
  const ioHandler = new StringIO(hWare)
  t.is(ioHandler.input('1', '1'), '10')
})

test('Overflow for Parallel Adder (2 bit)', t => {
  const inputA = wires(2)
  const inputB = wires(2)
  const sum = wires(3)
  const hWare = new PipoAdder(inputA, inputB, sum)
  const ioHandler = new StringIO(hWare)
  t.is(ioHandler.input('11', '11'), '110')
})

test('Overflow for Parallel Adder (4 bit)', t => {
  const inputA = wires(4)
  const inputB = wires(4)
  const sum = wires(5)
  const hWare = new PipoAdder(inputA, inputB, sum)
  const ioHandler = new StringIO(hWare)
  t.is(ioHandler.input('1111', '1111'), '11110')
})

test('HalfAdder - 1 bit PIPO Equivalence : 1', t => {
  const inputA = wires(1)
  const inputB = wires(1)
  const sum1 = wires(2)
  const halfAdderInput = wires(2)
  const sum2 = wires(2)
  const hWare1 = new PipoAdder(inputA, inputB, sum1)
  const hWare2 = new HalfAdder(halfAdderInput, sum2)
  const ioHandler1 = new StringIO(hWare1)
  const ioHandler2 = new StringIO(hWare2)
  t.is(ioHandler1.input('1', '1'), ioHandler2.input('11'))
})

test('HalfAdder - 1 bit PIPO Equivalence : 2', t => {
  const inputA = wires(1)
  const inputB = wires(1)
  const sum1 = wires(2)
  const halfAdderInput = wires(2)
  const sum2 = wires(2)
  const hWare1 = new PipoAdder(inputA, inputB, sum1)
  const hWare2 = new HalfAdder(halfAdderInput, sum2)
  const ioHandler1 = new StringIO(hWare1)
  const ioHandler2 = new StringIO(hWare2)
  t.is(ioHandler1.input('1', '0'), ioHandler2.input('10'))
})

test('HalfAdder - 1 bit PIPO Equivalence : 3', t => {
  const inputA = wires(1)
  const inputB = wires(1)
  const sum1 = wires(2)
  const halfAdderInput = wires(2)
  const sum2 = wires(2)
  const hWare1 = new PipoAdder(inputA, inputB, sum1)
  const hWare2 = new HalfAdder(halfAdderInput, sum2)
  const ioHandler1 = new StringIO(hWare1)
  const ioHandler2 = new StringIO(hWare2)
  t.is(ioHandler1.input('0', '0'), ioHandler2.input('00'))
})

test('SR-Flip-Flop : Set', t => {
  const s = wires(1)
  const r = wires(1)
  const qqbar = wires(2)
  const clock = new Pulse(500, 1)
  clock.switchOn()
  const ff = new SRFlipFlop(s, r, qqbar, clock)
  const ioHandler = new StringIO(ff)
  t.is(ioHandler.input('1', '0'), '1')
  clock.switchOff()
})

test('SR-Flip-Flop : Reset', t => {
  const s = wires(1)
  const r = wires(1)
  const qqbar = wires(2)
  const clock = new Pulse(500, 1)
  clock.switchOn()
  const ff = new SRFlipFlop(s, r, qqbar, clock)
  const ioHandler = new StringIO(ff)
  t.is(ioHandler.input('0', '1'), '0')
  clock.switchOff()
})

test('SR-Flip-Flop : No Change', t => {
  const s = wires(1)
  const r = wires(1)
  const qqbar = wires(2)
  const clock = new Pulse(500, 1)
  clock.switchOn()
  const ff = new SRFlipFlop(s, r, qqbar, clock)
  const ioHandler = new StringIO(ff)
  const prevQ = ioHandler.input('0', '1')
  t.is(ioHandler.input('0', '0'), prevQ)
  clock.switchOff()
})

test('1x2 Decoder : 1', t => {
  const inputA = wires(1)
  const outputA = wires(1)
  const linerDecoder = new Decoder1x2(inputA, outputA)
  const ioHandler = new StringIO(linerDecoder)
  t.is(ioHandler.input('0'), '10')
})

test('1x2 Decoder : 2', t => {
  const inputA = wires(1)
  const outputA = wires(1)
  const linerDecoder = new Decoder1x2(inputA, outputA)
  const ioHandler = new StringIO(linerDecoder)
  t.is(ioHandler.input('1'), '01')
})

test('2x4 Decoder : 1', t => {
  const inputX = wires(1)
  const inputY = wires(1)
  const output = wires(4)
  const d2x4 = new Decoder2x4(inputX, inputY, output)
  const ioHandler = new StringIO(d2x4)
  t.is(ioHandler.input('0', '0'), '1000')
})

test('2x4 Decoder : 2', t => {
  const inputX = wires(1)
  const inputY = wires(1)
  const output = wires(4)
  const d2x4 = new Decoder2x4(inputX, inputY, output)
  const ioHandler = new StringIO(d2x4)
  t.is(ioHandler.input('1' ,'0'), '0010')
})

test('2x4 Decoder : 3', t => {
  const inputX = wires(1)
  const inputY = wires(1)
  const output = wires(4)
  const d2x4 = new Decoder2x4(inputX, inputY, output)
  const ioHandler = new StringIO(d2x4)
  t.is(ioHandler.input('1', '1'), '0001')
})
Download .txt
gitextract_b37vrddc/

├── .gitignore
├── Combinational/
│   ├── arithmetics.js
│   ├── decoders.js
│   └── gates.js
├── Connectors/
│   └── transport.js
├── LICENSE
├── README.md
├── Sequential/
│   └── ff.js
├── Utility/
│   ├── ioManager.js
│   └── new.js
├── index.js
├── package.json
└── test.js
Download .txt
SYMBOL INDEX (53 symbols across 7 files)

FILE: Combinational/arithmetics.js
  class HalfAdder (line 5) | class HalfAdder extends Hardware {
    method constructor (line 7) | constructor(x, s) {
  class FullAdder (line 16) | class FullAdder extends Hardware {
    method constructor (line 18) | constructor(x, s) {
  class PipoAdder (line 29) | class PipoAdder extends Hardware {
    method constructor (line 31) | constructor(a, b, s) {

FILE: Combinational/decoders.js
  class Decoder1x2 (line 5) | class Decoder1x2 extends Hardware {
    method constructor (line 7) | constructor(x, o) {
  class Decoder2x4 (line 15) | class Decoder2x4 extends Hardware {
    method constructor (line 17) | constructor(x0, x1, o) {

FILE: Combinational/gates.js
  class AndGate (line 3) | class AndGate extends Hardware {
    method constructor (line 5) | constructor(x, y, o) {
    method hardware (line 16) | hardware() {
  class TriInpAndGate (line 28) | class TriInpAndGate extends Hardware {
    method constructor (line 30) | constructor(x, y, z, o) {
    method hardware (line 43) | hardware() {
  class OrGate (line 56) | class OrGate extends Hardware {
    method constructor (line 58) | constructor(x, y, o) {
    method hardware (line 69) | hardware() {
  class XorGate (line 81) | class XorGate extends Hardware {
    method constructor (line 83) | constructor(x, y, o) {
    method hardware (line 94) | hardware() {
  class NotGate (line 104) | class NotGate extends Hardware {
    method constructor (line 106) | constructor(x, o) {
    method hardware (line 115) | hardware() {
  class NandGate (line 124) | class NandGate extends Hardware {
    method constructor (line 126) | constructor(x, y, o) {
    method hardware (line 137) | hardware() {
  class NorGate (line 149) | class NorGate extends Hardware {
    method constructor (line 151) | constructor(x, y, o) {
    method hardware (line 162) | hardware() {
  class XnorGate (line 174) | class XnorGate extends Hardware {
    method constructor (line 176) | constructor(x, y, o) {
    method hardware (line 187) | hardware() {

FILE: Connectors/transport.js
  class Wire (line 3) | class Wire extends EventEmitter {
    method constructor (line 5) | constructor(sig) {
    method propagateSignal (line 13) | propagateSignal(newSignal) {
    method getSignal (line 21) | getSignal() {
  class Pulse (line 27) | class Pulse extends Wire {
    method constructor (line 29) | constructor(t, i) {
    method alter (line 40) | alter() {
    method switchOn (line 44) | switchOn() {
    method switchOff (line 51) | switchOff() {
  function wires (line 61) | function wires(n) {

FILE: Sequential/ff.js
  class SRFlipFlop (line 5) | class SRFlipFlop extends Hardware {
    method constructor (line 7) | constructor(s, r, qqbar, c) {
  class DFlipFlop (line 19) | class DFlipFlop extends Hardware {
    method constructor (line 21) | constructor(d, qqbar, c) {

FILE: Utility/ioManager.js
  class StringIO (line 1) | class StringIO {
    method constructor (line 3) | constructor({ioMapping}) {
    method input (line 9) | input(...inputSeqs) {

FILE: Utility/new.js
  class Hardware (line 1) | class Hardware {
    method constructor (line 3) | constructor(io) {
Condensed preview — 13 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (29K chars).
[
  {
    "path": ".gitignore",
    "chars": 13,
    "preview": "node_modules\n"
  },
  {
    "path": "Combinational/arithmetics.js",
    "chars": 1826,
    "preview": "const { AndGate, XorGate, OrGate } = require('./gates')\nconst { wires } = require('../Connectors/transport')\nconst { Har"
  },
  {
    "path": "Combinational/decoders.js",
    "chars": 1087,
    "preview": "const { Hardware } = require('../Utility/new')\nconst { wires } = require('../Connectors/transport')\nconst { NotGate, And"
  },
  {
    "path": "Combinational/gates.js",
    "chars": 5322,
    "preview": "const { Hardware } = require('../Utility/new')\n\nclass AndGate extends Hardware {\n\n  constructor(x, y, o) {\n    if (x.len"
  },
  {
    "path": "Connectors/transport.js",
    "chars": 1225,
    "preview": "const EventEmitter = require('events')\n\nclass Wire extends EventEmitter {\n\n  constructor(sig) {\n    super()\n\n    this.si"
  },
  {
    "path": "LICENSE",
    "chars": 1070,
    "preview": "MIT License\n\nCopyright (c) 2017 Mayank Badola\n\nPermission is hereby granted, free of charge, to any person obtaining a c"
  },
  {
    "path": "README.md",
    "chars": 6800,
    "preview": "![Architect](media/banner.png)\n\n> Highly Extensible Hardware Description Library for JavaScript Developers\n\nHardware is "
  },
  {
    "path": "Sequential/ff.js",
    "chars": 1422,
    "preview": "const { AndGate, NorGate, NandGate, NotGate } = require('../Combinational/gates')\nconst { wires } = require('../Connecto"
  },
  {
    "path": "Utility/ioManager.js",
    "chars": 670,
    "preview": "class StringIO {\n\n  constructor({ioMapping}) {\n    let inputGroup = ioMapping.length - 1\n    this.i = ioMapping.slice(0,"
  },
  {
    "path": "Utility/new.js",
    "chars": 154,
    "preview": "class Hardware {\n\n  constructor(io) {\n    this.ioMapping = io\n    this.internalWiring = []\n    this.components = []\n  }\n"
  },
  {
    "path": "index.js",
    "chars": 344,
    "preview": "module.exports = function(path) {\n  return {\n    'Gates': require('./Combinational/gates'),\n    'Arithmetics': require('"
  },
  {
    "path": "package.json",
    "chars": 536,
    "preview": "{\n  \"name\": \"architectjs\",\n  \"version\": \"0.1.2\",\n  \"description\": \"Hardware Description and Emulation Library\",\n  \"keywo"
  },
  {
    "path": "test.js",
    "chars": 6987,
    "preview": "import test from 'ava'\nimport { wires, Pulse } from './Connectors/transport'\nimport { NotGate, AndGate, TriInpAndGate, X"
  }
]

About this extraction

This page contains the full source code of the mbad0la/Architect GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 13 files (26.8 KB), approximately 8.3k tokens, and a symbol index with 53 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!