{"id":13416995,"url":"https://github.com/nturley/netlistsvg","last_synced_at":"2026-02-20T12:32:22.854Z","repository":{"id":37925863,"uuid":"75149809","full_name":"nturley/netlistsvg","owner":"nturley","description":"draws an SVG schematic from a JSON netlist","archived":false,"fork":false,"pushed_at":"2024-01-25T15:56:06.000Z","size":1069,"stargazers_count":761,"open_issues_count":54,"forks_count":102,"subscribers_count":23,"default_branch":"master","last_synced_at":"2026-02-05T14:48:46.416Z","etag":null,"topics":["diagram","elk","klayjs","netlist","visualization","yosys"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nturley.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2016-11-30T04:01:16.000Z","updated_at":"2026-01-28T09:09:57.000Z","dependencies_parsed_at":"2023-02-17T15:01:10.417Z","dependency_job_id":"68aaa279-ab73-4a8a-9db6-5f21dd4e2fe5","html_url":"https://github.com/nturley/netlistsvg","commit_stats":{"total_commits":210,"total_committers":15,"mean_commits":14.0,"dds":"0.32380952380952377","last_synced_commit":"1e187a75babc049db98a33a899b4030bdd7d3f6e"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/nturley/netlistsvg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nturley%2Fnetlistsvg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nturley%2Fnetlistsvg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nturley%2Fnetlistsvg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nturley%2Fnetlistsvg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nturley","download_url":"https://codeload.github.com/nturley/netlistsvg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nturley%2Fnetlistsvg/sbom","scorecard":{"id":697879,"data":{"date":"2025-08-11","repo":{"name":"github.com/nturley/netlistsvg","commit":"d3518f1b5c996a876b72a1a984bb39d3572c47dc"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":6,"reason":"Found 19/29 approved changesets -- score normalized to 6","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 20 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-22T04:14:43.857Z","repository_id":37925863,"created_at":"2025-08-22T04:14:43.857Z","updated_at":"2025-08-22T04:14:43.857Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29650867,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-20T09:27:29.698Z","status":"ssl_error","status_checked_at":"2026-02-20T09:26:12.373Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["diagram","elk","klayjs","netlist","visualization","yosys"],"created_at":"2024-07-30T22:00:30.960Z","updated_at":"2026-02-20T12:32:22.821Z","avatar_url":"https://github.com/nturley.png","language":"JavaScript","funding_links":[],"categories":["Visualization and Documentation generators","JavaScript","Documentation","others"],"sub_categories":[],"readme":"[![Linux Build Status](https://travis-ci.org/nturley/netlistsvg.svg?branch=master)](https://travis-ci.org/nturley/netlistsvg)\n[![Windows Build status](https://ci.appveyor.com/api/projects/status/heijuq5nhw9m7rib/branch/master?svg=true)](https://ci.appveyor.com/project/nturley/netlistsvg/branch/master)\n[![Gitter chat](https://badges.gitter.im/nturley/netlistsvg.png)](https://gitter.im/netlistsvg)\n[![npm version](https://badge.fury.io/js/netlistsvg.svg)](https://badge.fury.io/js/netlistsvg)\n![npm](https://img.shields.io/npm/dm/netlistsvg.svg)\n\n# netlistsvg\ndraws an SVG schematic from a [yosys](https://github.com/yosyshq/yosys) JSON netlist. This can be generated [the `write_json` command](https://yosyshq.readthedocs.io/projects/yosys/en/latest/cmd/write_json.html). It uses [elkjs](https://github.com/OpenKieler/elkjs) for layout.\n\nYou can see an online demo [here](https://nturley.github.io/netlistsvg)\n\n# Installation/Usage Instructions\n\n## Command Line Interface\nInstall nodejs if isn't already installed.\n\nTo install the latest version from npm:\n```sh\nnpm install -g netlistsvg\n```\n\nTo install the latest version from source:\n```sh\ngit clone https://github.com/nturley/netlistsvg\ncd netlistsvg\nnpm install # install dependencies\nsudo npm install -g . # install netlistsvg to system\n\nsudo npm uninstall -g netlistsvg # uninstall from system\n```\n\nYou can execute netlistsvg like this.\n```\nnetlistsvg input_json_file [-o output_svg_file] [--skin skin_file]\n```\nThe default value for the output file is out.svg.\n\nShould work on Linux, OSX, and Windows. Running the build scripts (makefiles and the web demo) is easiest on Linux and OSX.\n\n## Web bundle\n\nI have a web bundle hosted on github pages here: https://nturley.github.io/netlistsvg/built/netlistsvg.bundle.js\nIt doesn't wrap ELKjs, so you'll need to include it separately. ELK creates a global variable, so you'll need to include ELKjs before netlistsvg.\n\nIn HTML it would look something like this\n```html\n\u003cscript type=\"text/javascript\" src=\"https://nturley.github.io/netlistsvg/elk.bundled.js\"\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\" src=\"https://nturley.github.io/netlistsvg/built/netlistsvg.bundle.js\"\u003e\u003c/script\u003e\n```\n\nOn ObservableHQ, you can require it like this.\n\n```javascript\nnetlistsvg = {\n  var ELK = await require('https://nturley.github.io/netlistsvg/elk.bundled.js')\n  window.ELK = ELK\n  return require('https://nturley.github.io/netlistsvg/built/netlistsvg.bundle.js')\n}\n```\n\nYou may want to download and host your own copy.\n\nThe web bundle includes both the analog and digital skin and an example netlist for each. Using a promise would look like this.\n```javascript\nawait netlistsvg.render(netlistsvg.digitalSkin, netlistsvg.exampleDigital);\n```\nOr to log the result to console using the callback API:\n```javascript\nnetlistsvg.render(netlistsvg.digitalSkin, netlistsvg.exampleDigital, (err, result) =\u003e console.log(result));\n```\n\nTo turn Verilog into YosysJSON in the browser, you can use [YosysJS](https://yosyshq.net/yosys/yosysjs.html)\n\n## Development\n\nThe `lib/` folder contains the main source code for netlistsvg in Typescript. The `built/` folder contains said source code compiled to Javascript. When wanting to make changes to netlistsvg, one should modify the Typescript source, compile to Javascript, then test their modifications.\n\nTo compile, lint, and do self-tests, run\n```sh\nnpm test\n```\n\nTo build the web bundle, run\n```sh\nnpm run build-module\n```\n\n# Examples\n\nHere's an digital netlist produced by Yosys along with the diagram that netlistsvg created from it.\n\u003cdetails\u003e\n  \u003csummary\u003eJSON Source\u003c/summary\u003e\n\n```json\n{\n  \"modules\": {\n    \"up3down5\": {\n      \"ports\": {\n        \"clock\": {\n          \"direction\": \"input\",\n          \"bits\": [ 2 ]\n        },\n        \"data_in\": {\n          \"direction\": \"input\",\n          \"bits\": [ 3, 4, 5, 6, 7, 8, 9, 10, 11 ]\n        },\n        \"up\": {\n          \"direction\": \"input\",\n          \"bits\": [ 12 ]\n        },\n        \"down\": {\n          \"direction\": \"input\",\n          \"bits\": [ 13 ]\n        },\n        \"carry_out\": {\n          \"direction\": \"output\",\n          \"bits\": [ 14 ]\n        },\n        \"borrow_out\": {\n          \"direction\": \"output\",\n          \"bits\": [ 15 ]\n        },\n        \"count_out\": {\n          \"direction\": \"output\",\n          \"bits\": [ 16, 17, 18, 19, 20, 21, 22, 23, 24 ]\n        },\n        \"parity_out\": {\n          \"direction\": \"output\",\n          \"bits\": [ 25 ]\n        }\n      },\n      \"cells\": {\n        \"$add$input.v:17$3\": {\n          \"type\": \"$add\",\n          \"port_directions\": {\n            \"A\": \"input\",\n            \"B\": \"input\",\n            \"Y\": \"output\"\n          },\n          \"connections\": {\n            \"A\": [ 16, 17, 18, 19, 20, 21, 22, 23, 24 ],\n            \"B\": [ \"1\", \"1\" ],\n            \"Y\": [ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35 ]\n          }\n        },\n        \"$and$input.v:28$5\": {\n          \"type\": \"$and\",\n          \"port_directions\": {\n            \"A\": \"input\",\n            \"B\": \"input\",\n            \"Y\": \"output\"\n          },\n          \"connections\": {\n            \"A\": [ 12 ],\n            \"B\": [ 35 ],\n            \"Y\": [ 36 ]\n          }\n        },\n        \"$and$input.v:29$6\": {\n          \"type\": \"$and\",\n          \"port_directions\": {\n            \"A\": \"input\",\n            \"B\": \"input\",\n            \"Y\": \"output\"\n          },\n          \"connections\": {\n            \"A\": [ 13 ],\n            \"B\": [ 37 ],\n            \"Y\": [ 38 ]\n          }\n        },\n        \"$procdff$40\": {\n          \"type\": \"$dff\",\n          \"port_directions\": {\n            \"CLK\": \"input\",\n            \"D\": \"input\",\n            \"Q\": \"output\"\n          },\n          \"connections\": {\n            \"CLK\": [ 2 ],\n            \"D\": [ 39, 40, 41, 42, 43, 44, 45, 46, 47 ],\n            \"Q\": [ 16, 17, 18, 19, 20, 21, 22, 23, 24 ]\n          }\n        },\n        \"$procdff$41\": {\n          \"type\": \"$dff\",\n          \"port_directions\": {\n            \"CLK\": \"input\",\n            \"D\": \"input\",\n            \"Q\": \"output\"\n          },\n          \"connections\": {\n            \"CLK\": [ 2 ],\n            \"D\": [ 36 ],\n            \"Q\": [ 14 ]\n          }\n        },\n        \"$procdff$42\": {\n          \"type\": \"$dff\",\n          \"port_directions\": {\n            \"CLK\": \"input\",\n            \"D\": \"input\",\n            \"Q\": \"output\"\n          },\n          \"connections\": {\n            \"CLK\": [ 2 ],\n            \"D\": [ 38 ],\n            \"Q\": [ 15 ]\n          }\n        },\n        \"$procdff$43\": {\n          \"type\": \"$dff\",\n          \"port_directions\": {\n            \"CLK\": \"input\",\n            \"D\": \"input\",\n            \"Q\": \"output\"\n          },\n          \"connections\": {\n            \"CLK\": [ 2 ],\n            \"D\": [ 48 ],\n            \"Q\": [ 25 ]\n          }\n        },\n        \"$procmux$36\": {\n          \"type\": \"$pmux\",\n          \"port_directions\": {\n            \"A\": \"input\",\n            \"B\": \"input\",\n            \"S\": \"input\",\n            \"Y\": \"output\"\n          },\n          \"connections\": {\n            \"A\": [ 16, 17, 18, 19, 20, 21, 22, 23, 24 ],\n            \"B\": [ 26, 27, 28, 29, 30, 31, 32, 33, 34, 49, 50, 51, 52, 53, 54, 55, 56, 57, 3, 4, 5, 6, 7, 8, 9, 10, 11 ],\n            \"S\": [ 58, 59, 60 ],\n            \"Y\": [ 39, 40, 41, 42, 43, 44, 45, 46, 47 ]\n          }\n        },\n        \"$procmux$37_CMP0\": {\n          \"type\": \"$eq\",\n          \"port_directions\": {\n            \"A\": \"input\",\n            \"B\": \"input\",\n            \"Y\": \"output\"\n          },\n          \"connections\": {\n            \"A\": [ 13, 12 ],\n            \"B\": [ \"0\", \"1\" ],\n            \"Y\": [ 58 ]\n          }\n        },\n        \"$procmux$38_CMP0\": {\n          \"type\": \"$eq\",\n          \"port_directions\": {\n            \"A\": \"input\",\n            \"B\": \"input\",\n            \"Y\": \"output\"\n          },\n          \"connections\": {\n            \"A\": [ 13, 12 ],\n            \"B\": [ \"1\", \"0\" ],\n            \"Y\": [ 59 ]\n          }\n        },\n        \"$procmux$39_CMP0\": {\n          \"type\": \"$eq\",\n          \"port_directions\": {\n            \"A\": \"input\",\n            \"B\": \"input\",\n            \"Y\": \"output\"\n          },\n          \"connections\": {\n            \"A\": [ 13, 12 ],\n            \"B\": [ \"0\", \"0\" ],\n            \"Y\": [ 60 ]\n          }\n        },\n        \"$reduce_xor$input.v:27$4\": {\n          \"type\": \"$reduce_xor\",\n          \"port_directions\": {\n            \"A\": \"input\",\n            \"Y\": \"output\"\n          },\n          \"connections\": {\n            \"A\": [ 39, 40, 41, 42, 43, 44, 45, 46, 47 ],\n            \"Y\": [ 48 ]\n          }\n        },\n        \"$sub$input.v:16$2\": {\n          \"type\": \"$sub\",\n          \"port_directions\": {\n            \"A\": \"input\",\n            \"B\": \"input\",\n            \"Y\": \"output\"\n          },\n          \"connections\": {\n            \"A\": [ 16, 17, 18, 19, 20, 21, 22, 23, 24 ],\n            \"B\": [ \"1\", \"0\", \"1\" ],\n            \"Y\": [ 49, 50, 51, 52, 53, 54, 55, 56, 57, 37 ]\n          }\n        }\n      }\n    }\n  }\n}\n```\n\u003c/details\u003e\n\n![example](https://raw.githubusercontent.com/nturley/netlistsvg/master/doc/up3down5.svg?sanitize=true)\n\nYou can also write out the JSON by hand, of course. We support [JSON5](https://json5.org) syntax.\n\nHere's an analog example.\n\n\u003cdetails\u003e\n  \u003csummary\u003eJSON Source\u003c/summary\u003e\n\n```json\n{\n  \"modules\": {\n    \"resistor_divider\": {\n      \"ports\": {\n        \"A\": {\n          \"direction\": \"input\",\n          \"bits\": [2]\n        },\n        \"B\": {\n          \"direction\": \"input\",\n          \"bits\": [3]\n        },\n        \"A AND B\": {\n          \"direction\": \"output\",\n          \"bits\": [4]\n        }\n      },\n      \"cells\": {\n        \"R1\": {\n          \"type\": \"r_v\",\n          \"connections\": {\n            \"A\": [2],\n            \"B\": [5]\n          },\n          \"attributes\": {\n            \"value\":\"10k\"\n          }\n        },\n        \"R2\": {\n          \"type\": \"r_v\",\n          \"connections\": {\n            \"A\": [3],\n            \"B\": [5]\n          },\n          \"attributes\": {\n            \"value\":\"10k\"\n          }\n        },\n        \"Q1\": {\n          \"type\": \"q_pnp\",\n          \"port_directions\": {\n            \"C\": \"input\",\n            \"B\": \"input\",\n            \"E\": \"output\"\n          },\n          \"connections\": {\n            \"C\": [6],\n            \"B\": [5],\n            \"E\": [7]\n          }\n        },\n        \"R3\": {\n          \"type\": \"r_v\",\n          \"connections\": {\n            \"A\": [7],\n            \"B\": [8]\n          },\n          \"attributes\": {\n            \"value\":\"10k\"\n          }\n        },\n        \"R4\": {\n          \"type\": \"r_v\",\n          \"connections\": {\n            \"A\": [7],\n            \"B\": [9]\n          },\n          \"attributes\": {\n            \"value\":\"10k\"\n          }\n        },\n        \"R5\": {\n          \"type\": \"r_v\",\n          \"connections\": {\n            \"A\": [4],\n            \"B\": [12]\n          },\n          \"attributes\": {\n            \"value\":\"10k\"\n          }\n        },\n        \"Q2\": {\n          \"type\": \"q_pnp\",\n          \"port_directions\": {\n            \"C\": \"input\",\n            \"B\": \"input\",\n            \"E\": \"output\"\n          },\n          \"connections\": {\n            \"C\": [10],\n            \"B\": [9],\n            \"E\": [4]\n          }\n        },\n        \"vcc\": {\n          \"type\": \"vcc\",\n          \"connections\": {\n            \"A\": [6]\n          },\n          \"attributes\": {\n            \"name\":\"VCC\"\n          }\n        },\n        \"vcc2\": {\n          \"type\": \"vcc\",\n          \"connections\": {\n            \"A\": [10]\n          },\n          \"attributes\": {\n            \"name\":\"VCC\"\n          }\n        },\n        \"gnd\": {\n          \"type\": \"gnd\",\n          \"port_directions\": {\n            \"A\": \"input\"\n          },\n          \"connections\": {\n            \"A\": [8]\n          },\n          \"attributes\": {\n            \"name\":\"DGND\"\n          }\n        },\n        \"gnd2\": {\n          \"type\": \"gnd\",\n          \"port_directions\": {\n            \"A\": \"input\"\n          },\n          \"connections\": {\n            \"A\": [12]\n          },\n          \"attributes\": {\n            \"name\":\"DGND\"\n          }\n        }\n      }\n    }\n  }\n}\n```\n\u003c/details\u003e\n\n![example](https://raw.githubusercontent.com/nturley/netlistsvg/master/doc/and.svg?sanitize=true)\n\n## Skin File\nIt pulls the node icons and configuration options from a SVG skin file. This our default digital skin file.\n\n\u003cimg src=\"https://raw.githubusercontent.com/nturley/netlistsvg/master/lib/default.svg?sanitize=true\"\u003e\n\nThis is our analog skin file.\n\n\u003cimg src=\"https://raw.githubusercontent.com/nturley/netlistsvg/master/lib/analog.svg?sanitize=true\"\u003e\n\nA skin file can use style tags or inline CSS to style the elements. That will be copied onto the output file. A skin file also defines a library of components to use. Each component has an alias list. It will use that component as a template for any cell with that type that it encounters. Each component defines the position and id of each of its ports so we know where to attach the wires to.\n\nFor example, here is a mux definition. It has two aliases: \"$pmux\" and \"$mux\". It defines a type name, and a width and height, as well as the position and id of each of it's ports. In general you can rearrange them however you like, and add whatever SVG elements you like inside the template.\n\n```XML\n\u003cg s:type=\"mux\" transform=\"translate(50, 50)\" s:width=\"20\" s:height=\"40\"\u003e\n  \u003cs:alias val=\"$pmux\"/\u003e\n  \u003cs:alias val=\"$mux\"/\u003e\n\n  \u003cpath d=\"M0,0 L20,10 L20,30 L0,40 Z\"/\u003e\n\n  \u003cg s:x=\"0\" s:y=\"10\" s:pid=\"A\"/\u003e\n  \u003cg s:x=\"0\" s:y=\"30\" s:pid=\"B\"/\u003e\n  \u003cg s:x=\"10\" s:y=\"35\" s:pid=\"S\"/\u003e\n  \u003cg s:x=\"20\" s:y=\"20\" s:pid=\"Y\"/\u003e\n\u003c/g\u003e\n```\n\nIn addition to the library of components that are matched to cells, a skin file defines some special nodes. Input/Output ports, constants, Splits/Joins, and the generic node. Splits/Joins and the generic nodes are resized and ports are added or removed to adjust to the cell.\n\nThe elkjs layout properties are also defined in the skin file.\n\n```XML\n\u003cs:layoutEngine\n      org.eclipse.elk.layered.spacing.nodeNodeBetweenLayers=\"5\"\n      org.eclipse.elk.spacing.nodeNode= \"35\"\n      org.eclipse.elk.direction=\"DOWN\"\n    /\u003e\n```\nAny properties specified here will get passed along to the layout engine. Node and edge properties aren't configurable (yet).\n\nUsing the classes `.busLabel_*` and `.width_*` (where * indicates the bus width) in the `\u003cstyle\u003e` tag at the top of the skin file (or the resulting svg), styling based on bus width can be added to lines and labels.\n\nFor instance, to turn off bus width labels for buses of two wires, simply add:\n```svg\n.busLabel_2 {\n    fill-opacity: 0;\n}\n```\nTo change the color of all lines of width 4 to red, simply add:\n```svg\nline.width_4 {\n    stroke: red;\n}\n```\n## Input JSON\nYosys JSON includes more information than we need. We only render one module (either the first or the module with an attribute \"top\"). If the cell name matches one of the aliases of a template from the skin, then it will use it as a template for the SVG file. Port directions are optional for cells that are defined in the skin (not generic cells).\n\nSo it should look something like this.\n```json\n{\n  \"modules\": {\n    \"\u003cdont care\u003e\": {\n      \"ports\": {\n        \"\u003cport name\u003e\": {\n          \"direction\": \"\u003cinput|output\u003e\",\n          \"bits\": [ 2, \"1\", ... ]\n        },\n        ...\n      },\n      \"cells\": {\n        \"\u003ccell name\u003e\": {\n          \"type\": \"\u003ctype name\u003e\",\n          \"parameters\": {\n            \"WIDTH\": 3,\n            ...\n          },\n          \"port_directions\": {\n            \"\u003cport name\u003e\": \"\u003cinput|output\u003e\",\n            ...\n          },\n          \"connections\": {\n            \"\u003cport name\u003e\": [ 3, \"0\", ... ],\n            ...\n          }\n      },\n      ...\n    }\n  }\n}\n```\n\nIf the cell has a WIDTH parameter greater than 1, `-bus` will be appended to the end of the cell type. This is useful for changing the skin of a cell for single and multibit variants, but is currently only used for `$mux` (and its variants). The appended `-bus` will show up in the generic name above the cell for any cells that have a `WIDTH` parameter that aren't in the skin file provided.\n\n## ElkJS\nELK is using a layered approach (Sugiyama, Ganser), similar to dot in the Graphviz package. You can read about their algorithm here: https://rtsys.informatik.uni-kiel.de/%7Ebiblio/downloads/papers/jvlc13.pdf\n\n# Status\nWe are getting close to the 1.0 release. At that point, the skin file format will be considered specified and breaking changes will only happen on major version bumps.\n\n## Generating `input_json_file` with Yosys\n\n[Yosys from Claire Wolf](https://github.com/yosyshq/yosys) can be used to generate the `input_json_file` using [the `write_json` command](https://yosyshq.readthedocs.io/projects/yosys/en/latest/cmd/write_json.html).\n\nUnless you are doing something special you will want to use [the `prep` command](https://yosyshq.readthedocs.io/projects/yosys/en/latest/cmd/prep.html). Some examples are provided below and you can find some runnable examples which go from Verilog to diagrams in the [examples directory](./examples) (with example Makefile).\n\n#### Generate top level diagram\n\nThis command will generate a diagram of the top module with all the inner modules shown as boxes.\n\n```\nyosys -p \"prep -top my_top_module; write_json output.json\" input.v\n```\n\n#### Generate logic diagram\n\nYou can give it the `-flatten` argument to  [the `prep` command](https://yosyshq.readthedocs.io/projects/yosys/en/latest/cmd/prep.html) if you want Yosys to convert everything into low level logic. Only basic logic cells and black boxes will exist after flattening.\n\n```\nyosys -p \"prep -top my_top_module -flatten; write_json output.json\" input.v\n```\n\n### Generate AND (or not) and inverter (NOT) diagram\n\nIt is also frequently common that you want to create a diagram only using AND and NOT (or NAND and NOT) cells. ([This is called an AIG](https://en.wikipedia.org/wiki/And-inverter_graph).) This can be done with Yosys' [`aigmap` command](https://yosyshq.readthedocs.io/projects/yosys/en/latest/cmd/aigmap.html).\n\n```\nyosys -p \"prep -top my_top_module; aigmap; write_json output.json\" input.v\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnturley%2Fnetlistsvg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnturley%2Fnetlistsvg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnturley%2Fnetlistsvg/lists"}