{"id":13437160,"url":"https://github.com/tilk/digitaljs","last_synced_at":"2025-12-30T14:04:36.451Z","repository":{"id":32907189,"uuid":"143185711","full_name":"tilk/digitaljs","owner":"tilk","description":"Teaching-focused digital circuit simulator","archived":false,"fork":false,"pushed_at":"2024-05-08T09:46:39.000Z","size":7931,"stargazers_count":697,"open_issues_count":12,"forks_count":52,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-03-14T04:18:06.891Z","etag":null,"topics":["circuit-simulator","digital-logic","logic-circuit-simulator","logic-gates","simulator"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tilk.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"tilk"}},"created_at":"2018-08-01T17:10:12.000Z","updated_at":"2025-03-13T21:37:50.000Z","dependencies_parsed_at":"2023-01-16T22:45:08.697Z","dependency_job_id":"41ce6b3f-a16e-4b87-9935-688a3e28e2cb","html_url":"https://github.com/tilk/digitaljs","commit_stats":{"total_commits":466,"total_committers":10,"mean_commits":46.6,"dds":"0.13090128755364805","last_synced_commit":"a541f0ff32b4560e593cfb6cf5b5eed06b902fec"},"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tilk%2Fdigitaljs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tilk%2Fdigitaljs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tilk%2Fdigitaljs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tilk%2Fdigitaljs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tilk","download_url":"https://codeload.github.com/tilk/digitaljs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244370822,"owners_count":20442306,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["circuit-simulator","digital-logic","logic-circuit-simulator","logic-gates","simulator"],"created_at":"2024-07-31T03:00:54.728Z","updated_at":"2025-12-30T14:04:36.445Z","avatar_url":"https://github.com/tilk.png","language":"JavaScript","funding_links":["https://github.com/sponsors/tilk"],"categories":["JavaScript"],"sub_categories":[],"readme":"![][digitaljs-logo]\n\n# DigitalJS\n\nThis project is a digital circuit simulator implemented in Javascript.\nIt is designed to simulate circuits synthesized by hardware design tools\nlike [Yosys](https://yosyshq.net/yosys/) (Github repo [here](https://github.com/YosysHQ/yosys/)), and it has a companion project\n[yosys2digitaljs](https://github.com/tilk/yosys2digitaljs), which converts\nYosys output files to DigitalJS. It is also intended to be a teaching tool,\ntherefore readability and ease of inspection is one of top concerns for\nthe project.\n\nYou can [try it out online](https://digitaljs.tilk.eu/). The web app is\n[a separate Github project](https://github.com/tilk/digitaljs_online/).\n\n## Conference paper\n\nMarek Materzok. 2020. DigitalJS: a Visual Verilog Simulator for Teaching.\nIn Proceedings of the 8th Computer Science Education Research Conference\n(CSERC '19). Association for Computing Machinery, New York, NY, USA,\n110–115. https://doi.org/10.1145/3375258.3375272\n\n# Usage\n\nYou can use DigitalJS in your project by installing it from NPM:\n\n```bash\nnpm install digitaljs\n```\n\nOr you can use the [Webpack bundle](https://tilk.github.io/digitaljs/main.js) directly.\n\nTo simulate a circuit represented using the JSON input format (described later)\nand display it on a `div` named `#paper`, you need to run the following\nJS code ([see running example](https://tilk.github.io/digitaljs/test/fulladder.html)):\n\n```javascript\n// create the simulation object\nconst circuit = new digitaljs.Circuit(input_goes_here);\n// display on #paper\nconst paper = circuit.displayOn($('#paper'));\n// activate real-time simulation\ncircuit.start();\n```\n\n# Input format\n\nCircuits are represented using JSON. The top-level object has three keys, `devices`,\n`connectors` and `subcircuits`. Under `devices` is a list of all devices forming\nthe circuit, represented as an object, where keys are (unique and internal) device\nnames. Each device has a number of properties, which are represented by an object.\nA mandatory property is `type`, which specifies the type of the device. Example\ndevice:\n\n```javascript\n\"dev1\": {\n    \"type\": \"And\",\n    \"label\": \"AND1\"\n}\n```\n\nUnder `connectors` is a list of connections between device ports, represented as an\narray of objects with two keys, `from` and `to`. Both keys map to an object with two\nkeys, `id` and `port`; the first corresponds to a device name, and the second -- to\na valid port name for the device. A connection must lead from an output port to\nan input port, and the bitwidth of both ports must be equal. Example connection:\n\n```javascript\n{\n    \"from\": {\n        \"id\": \"dev1\",\n        \"port\": \"out\"\n    },\n    \"to\": {\n        \"id\": \"dev2\",\n        \"port\": \"in\"\n    }\n}\n```\n\nUnder `subcircuits` is a list of subcircuit definitions, represented as an object,\nwhere keys are unique subcircuit names. A subcircuit name can be used as\na `celltype` for a device of type `Subcircuit`; this instantiates the subcircuit. \nA subcircuit definition\nfollows the representation of whole circuits, with the exception that subcircuits\ncannot (currently) define their own subcircuits. A subcircuit can include\n`Input` and `Output` devices, these are mapped to ports on a subcircuit\ninstance.\n\n## Device types\n\n * Unary gates: `Not`, `Repeater`\n    * Attributes: `bits` (natural number)\n    * Inputs: `in` (`bits`-bit)\n    * Outputs: `out` (`bits`-bit)\n * N-ary gates: `And`, `Nand`, `Or`, `Nor`, `Xor`, `Xnor`\n    * Attributes: `bits` (natural number), `inputs` (natural number, default 2)\n    * Inputs: `in1`, `in2` ... `inN` (`bits`-bit, `N` = `inputs`)\n    * Outputs: `out` (`bits`-bit)\n * Reducing gates: `AndReduce`, `NandReduce`, `OrReduce`, `NorReduce`, `XorReduce`, `XnorReduce`\n    * Attributes: `bits` (natural number)\n    * Inputs: `in` (`bits`-bit)\n    * Outputs: `out` (1-bit)\n * Bit shifts: `ShiftLeft`, `ShiftRight`\n    * Attributes: `bits.in1`, `bits.in2` and `bits.out` (natural number), `signed.in1`, `signed.in2`, `signed.out` and `fillx` (boolean)\n    * Inputs: `in1` (`bits.in1`-bit), `in2` (`bits.in2`-bit)\n    * Outputs: `out` (`bits.out`-bit)\n * Comparisons: `Eq`, `Ne`, `Lt`, `Le`, `Gt`, `Ge`\n    * Attributes: `bits.in1` and `bits.in2` (natural number), `signed.in1` and `signed.in2` (boolean)\n    * Inputs: `in1` (`bits.in1`-bit), `in2` (`bits.in2`-bit)\n    * Outputs: `out` (1-bit)\n * Number constant: `Constant`\n    * Attributes: `constant` (binary string)\n    * Outputs: `out` (`constant.length`-bit)\n * Unary arithmetic: `Negation`, `UnaryPlus`\n    * Attributes: `bits.in` and `bits.out` (natural number), `signed` (boolean)\n    * Inputs: `in` (`bits.in`-bit)\n    * Outputs: `out` (`bits.out`-bit)\n * Binary arithmetic: `Addition`, `Subtraction`, `Multiplication`, `Division`, `Modulo`, `Power`\n    * Attributes: `bits.in1`, `bits.in2` and `bits.out` (natural number), `signed.in1` and `signed.in2` (boolean)\n    * Inputs: `in1` (`bits.in1`-bit), `in2` (`bits.in2`-bit)\n    * Outputs: `out` (`bits.out`-bit)\n * Multiplexer: `Mux`\n    * Attributes: `bits.in`, `bits.sel` (natural number)\n    * Inputs: `in0` ... `inN` (`bits.in`-bit, `N` = 2**`bits.sel`-1), `sel` (`bits.sel`-bit)\n    * Outputs: `out` (`bits.in`-bit)\n * One-hot multiplexer: `Mux1Hot`\n    * Attributes: `bits.in`, `bits.sel` (natural number)\n    * Inputs: `in0` ... `inN` (`bits.in`-bit, `N` = `bits.sel`), `sel` (`bits.sel`-bit)\n    * Outputs: `out` (`bits.in`-bit)\n * Sparse multiplexer: `MuxSparse`\n    * Attributes: `bits.in`, `bits.sel` (natural number), `inputs` (list of natural numbers), `default_input` (optional boolean)\n    * Inputs: `in0` ... `inN` (`bits.in`-bit, `N` = `inputs.length`, +1 if `default_input` is true)\n    * Outputs: `out` (`bits.in`-bit)\n * D flip-flop: `Dff`\n    * Attributes: `bits` (natural number), `polarity.clock`, `polarity.arst`, `polarity.srst`, `polarity.aload`, `polarity.set`, `polarity.clr`, `polarity.enable`, `enable_srst` (optional booleans), `initial` (optional binary string), `arst_value`, `srst_value` (optional binary string), `no_data` (optional boolean)\n    * Inputs: `in` (`bits`-bit), `clk` (1-bit, if `polarity.clock` is present), `arst` (1-bit, if `polarity.arst` is present), `srst` (1-bit, if `polarity.srst` is present), `en` (1-bit, if `polarity.enable` is present), `set` (1-bit, if `polarity.set` is present), `clr` (1-bit, if `polarity.clr` is present), `ain` (`bits`-bit, if `polarity.aload` is present), `aload` (1-bit, if `polarity.aload` is present)\n    * Outputs: `out` (`bits`-bit)\n * Memory: `Memory`\n    * Attributes: `bits`, `abits`, `words`, `offset` (natural number), `rdports` (array of read port descriptors), `wrports` (array of write port descriptors), `memdata` (memory contents description)\n    * Read port descriptor attributes: `enable_polarity`, `clock_polarity`, `arst_polarity`, `srst_polarity` (optional booleans), `init_value`, `arst_value`, `srst_value` (optional binary strings), `transparent`, `collision` (optional booleans or arrays of booleans)\n    * Write port descriptor attributes: `enable_polarity`, `clock_polarity`, `no_bit_enable` (optional booleans)\n    * Inputs (per read port): `rdKaddr` (`abits`-bit), `rdKen` (1-bit, if `enable_polarity` is present), `rdKclk` (1-bit, if `clock_polarity` is present), `rdKarst` (1-bit, if `arst_polarity` is present), `rdKsrst` (1-bit, if `srst_polarity` is present)\n    * Outputs (per read port): `rdKdata` (`bits`-bit)\n    * Inputs (per write port): `wrKaddr` (`abits`-bit), `wrKdata` (`bits`-bit), `wrKen` (1-bit (when `no_bit_enable` is true) or `bits`-bit (otherwise), if `enable_polarity` is present), `wrKclk` (1-bit, if `clock_polarity` is present)\n * Clock source: `Clock` \n    * Outputs: `out` (1-bit)\n * Button input: `Button`\n    * Outputs: `out` (1-bit)\n * Lamp output: `Lamp`\n    * Inputs: `in` (1-bit)\n * Number input: `NumEntry`\n    * Attributes: `bits` (natural number), `numbase` (string)\n    * Outputs: `out` (`bits`-bit)\n * Number output: `NumDisplay`\n    * Attributes: `bits` (natural number), `numbase` (string)\n    * Inputs: `in` (`bits`-bit)\n * Subcircuit input: `Input`\n    * Attributes: `bits` (natural number)\n    * Outputs: `out` (`bits`-bit)\n * Subcircuit output: `Output`\n    * Attributes: `bits` (natural number)\n    * Inputs: `in` (`bits`-bit)\n * 7 segment display output: `Display7`\n    * Inputs: `bits` (8-bit only - most significant bit controls decimal point LED)\n * Bus grouping: `BusGroup`\n    * Attributes: `groups` (array of natural numbers)\n    * Inputs: `in0` (`groups[0]`-bit) ... `inN` (`groups[N]`-bit)\n    * Outputs: `out` (sum-of-`groups`-bit)\n * Bus ungrouping: `BusUngroup`\n    * Attributes: `groups` (array of natural numbers)\n    * Inputs: `in` (sum-of-`groups`-bit)\n    * Outputs: `out0` (`groups[0]`-bit) ... `outN` (`groups[N]`-bit)\n * Bus slicing: `BusSlice`\n    * Attributes: `slice.first`, `slice.count`, `slice.total` (natural number)\n    * Inputs: `in` (`slice.total`-bit)\n    * Outputs: `out` (`slice.count`-bit)\n * Zero- and sign-extension: `ZeroExtend`, `SignExtend`\n    * Attributes: `extend.input`, `extend.output` (natural number)\n    * Inputs: `in` (`extend.input`-bit)\n    * Outputs: `out` (`extend.output`-bit)\n * Finite state machines: `FSM`\n    * Attributes: `bits.in`, `bits.out`, `states`, `init_state`, `current_state` (natural number), `trans_table` (array of transition descriptors)\n    * Transition descriptor attributes: `ctrl_in`, `ctrl_out` (binary strings), `state_in`, `state_out` (natural numbers)\n    * Inputs: `clk` (1-bit), `arst` (1-bit), `in` (`bits.in`-bit)\n    * Outputs: `out` (`bits.out`-bit)\n\n# TODO\n\nSome ideas for further developing the simulator.\n\n * Use JointJS elementTools for configuring/removing gates.\n * RAM/ROM import/export for Verilog format and Intel HEX.\n * Framebuffer element with character/bitmap display.\n * More editing capability: adding and removing blocks, modifying some of blocks' properties.\n * Undo-redo capability.\n * Saving and loading circuits, including layout and state.\n * Generic handling of negation for unary/binary gates (negation on inputs/outputs) for better clarity.\n * SVG export.\n * Verilog export.\n * Smartphone and tablet compatible UI.\n\n[digitaljs-logo]: docs/resources/digitaljs_textpath_right.svg\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftilk%2Fdigitaljs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftilk%2Fdigitaljs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftilk%2Fdigitaljs/lists"}