{"id":16816106,"url":"https://github.com/charlottia/sh1107","last_synced_at":"2025-11-06T03:30:25.228Z","repository":{"id":153943675,"uuid":"612830862","full_name":"charlottia/sh1107","owner":"charlottia","description":"SH1107 OLED (I²C) driver, plus virtual hardware testbench.","archived":true,"fork":false,"pushed_at":"2024-10-23T02:17:24.000Z","size":3672,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-16T04:24:44.384Z","etag":null,"topics":["amaranth","amaranth-hdl","cxxrtl","fpga","i2c","icebreaker","oled","sh1107","zig"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/charlottia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2023-03-12T05:12:36.000Z","updated_at":"2024-10-23T02:18:13.000Z","dependencies_parsed_at":"2023-11-07T08:26:26.818Z","dependency_job_id":"9a9f50d2-a3b3-49f7-aa37-ab4c50d77b6e","html_url":"https://github.com/charlottia/sh1107","commit_stats":null,"previous_names":["kivikakk/sh1107","charlottia/sh1107"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charlottia%2Fsh1107","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charlottia%2Fsh1107/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charlottia%2Fsh1107/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/charlottia%2Fsh1107/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/charlottia","download_url":"https://codeload.github.com/charlottia/sh1107/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239372200,"owners_count":19627776,"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":["amaranth","amaranth-hdl","cxxrtl","fpga","i2c","icebreaker","oled","sh1107","zig"],"created_at":"2024-10-13T10:37:20.448Z","updated_at":"2025-11-06T03:30:25.165Z","avatar_url":"https://github.com/charlottia.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sh1107\n\nThis repository is a testbed for exploring [Amaranth] while learning digital\ndesign. It consists of a basic driver for SH1107-type OLEDs over I²C such as the\n[Pimoroni 1.12\" 128x128 monochrome OLED][Pimoroni OLED], a read/write I²C\ncontroller, plus a simple SPI flash reader. The driver supports commands akin to\nold BASIC: `CLS`, `PRINT`, `LOCATE`. The classic IBM 8x8 font is used to this\nend.\n\n[Amaranth]: https://github.com/amaranth-lang/amaranth\n[Pimoroni OLED]: https://shop.pimoroni.com/products/1-12-oled-breakout\n\nExecute the package to see what it can do:\n\n```console\n$ py -m sh1107 -h\nusage: sh1107 [-h] {test,formal,build,rom,vsh} ...\n\npositional arguments:\n  {test,formal,build,rom,vsh}\n    test                run the unit tests and sim tests\n    formal              formally verify the design\n    build               build the design, and optionally program it\n    rom                 build the ROM image, and optionally program it\n    vsh                 run the Virtual SH1107\n\noptions:\n  -h, --help            show this help message and exit\n```\n\nThe current test deployment targets are:\n\n* iCEBreaker ([Crowd Supply][iCEBreaker on Crowd Supply],\n  [1BitSquared][iCEBreaker on 1BitSquared]).\n  * Connect PMOD1 A1 to SDA, A2 to SCL.\n* OrangeCrab ([1BitSquared][OrangeCrab on 1BitSquared]).\n  * Connect the pins named SDA and SCL.\n  * The code currently expects you have rev 0.2 with an 85F like I do. It's\n    trivial to add support for rev 0.1 and/or the 25F.\n\n[iCEBreaker on Crowd Supply]: https://www.crowdsupply.com/1bitsquared/icebreaker-fpga\n[iCEBreaker on 1BitSquared]: https://1bitsquared.com/products/icebreaker\n[OrangeCrab on 1BitSquared]: https://1bitsquared.com/products/orangecrab\n\n## Requirements\n\nIf no version is specified, the most recent release or the version in your\npackage manager is probably fine, and if neither concept applies, just try the\nlatest commit.\n\nFor a detailed guide on installing specific versions of some of these tools,\nplease see [Installing an HDL toolchain from source][notes-0001].  On Nix,\n[hdx] packages everything — `nix develop '.?submodules=1'`/`nix-shell` will\nuse it.\n\nTo run at all:\n\n* [Python 3] (3.8+ works; I work on 3.12 beta)\n* [Amaranth] ([`d218273`] or later)\n* [Board definitions for Amaranth][amaranth-boards]\n\nTo run vsh:\n\n* [Zig] (~[`50339f5`] or later)\n* [SDL2]\n\nTo build and deploy:\n\n* [nextpnr] configured with appropriate flows:\n  * [Project IceStorm] for iCEBreaker\n  * [Project Trellis] for OrangeCrab\n    * [`dfu-util`] to upload the bitstream and ROM\n\nTo run formal tests:\n\n* [Yosys] ([`d3ee4eb`] or later)\n* [SymbiYosys]\n* [Z3] (4.12+ is known to work; 4.8 is known not to)\n\n[notes-0001]: https://lottia.net/notes/0001-hdl-toolchain-source.html\n[hdx]: https://github.com/charlottia/hdx\n[Python 3]: https://www.python.org\n[`d218273`]: https://github.com/amaranth-lang/amaranth/commit/d218273b9b2c6e65b7d92eb0f280306ea9c07ea3\n[amaranth-boards]: https://github.com/amaranth-lang/amaranth-boards\n[Yosys]: https://github.com/yosyshq/yosys\n[`d3ee4eb`]: https://github.com/YosysHQ/yosys/commit/d3ee4eba5b8d68c891f0beb831f19068e08765ed\n[SymbiYosys]: https://github.com/YosysHQ/sby\n[Z3]: https://github.com/Z3Prover/z3\n[nextpnr]: https://github.com/YosysHQ/nextpnr\n[Project IceStorm]: https://github.com/YosysHQ/icestorm\n[Project Trellis]: https://github.com/YosysHQ/prjtrellis\n[`dfu-util`]: https://dfu-util.sourceforge.net/\n[Zig]: https://ziglang.org/\n[SDL2]: https://libsdl.org/\n[`50339f5`]: https://github.com/ziglang/zig/commit/50339f595aa6ec96760b1cd9f8d0e0bfc3f167fc\n\n\n## TODOs\n\n- try QSPI.\n- OrangeCrab: try on-board DDR3 instead of EBR.\n\n## vsh\n\nMaybe the most interesting thing right now is the Virtual SH1107 for testing the\ngateware. It emulates the internal state of the SH1107 device — what you see\nrendered is what you should see on the display.\n\n[\u003cimg alt=\"screenshot of the Virtual SH1107 testbench\" src=\"doc/vsh.png\"\nheight=\"300\"\u003e](doc/vsh.png) [\u003cimg alt=\"photo of the OLED device being run on an\niCEBreaker\" src=\"doc/helloworld.jpg\" height=\"300\"\u003e](doc/helloworld.jpg)\n\nInitially this was implemented in Python and ran cooperatively with Amaranth's\nown simulator, like the unit tests, but it was pretty slow. It's now written in\n[Zig], and interacts with the simulated hardware running on its own thread by\ncompiling it to C++ through Yosys's [CXXRTL backend][CXXRTL].\n\n[CXXRTL]: https://github.com/YosysHQ/yosys/tree/master/backends/cxxrtl\n\n```console\n$ py -m sh1107 vsh -h\nusage: sh1107 vsh [-h] [-i] [-f] [-c] [-s {100000,400000,2000000}] [-t TOP]\n                  [-v] [-O {none,rtl,zig,both}]\n\noptions:\n  -h, --help            show this help message and exit\n  -i, --whitebox-i2c    simulate the full I2C protocol; by default it is\n                        replaced with a blackbox for speed\n  -f, --whitebox-spifr  simulate the full SPI protocol for the flash reader;\n                        by default it is replaced with a blackbox for speed\n  -c, --compile         compile only; don't run\n  -s {100000,400000,2000000}, --speed {100000,400000,2000000}\n                        I2C bus speed to build at\n  -t TOP, --top TOP     which top-level module to simulate (default:\n                        oled.Top)\n  -v, --vcd             output a VCD file\n  -O {none,rtl,zig,both}, --optimize {none,rtl,zig,both}\n                        build RTL or Zig with optimizations (default: both)\n```\n\n### I²C\n\nBy default, the I²C circuit is stubbed out with a\n[blackbox](vsh/i2c_blackbox.cc) that acts close enough to the real controller\nfor the rest of the design, and the Virtual SH1107\n[spies](vsh/src/I2CBBConnector.zig) on the inputs to the blackbox directly. This\nis fast.\n\nAt the most fine-grained level (`vsh -i`), it responds to the gateware by doing\nedge detection at I²C level, [spying](vsh/src/I2CConnector.zig) on the I²C\nlines. This method is faster than the pure Python version I started with, but\nstill slow enough to take several seconds to clear the screen when not compiled\nwith optimizations.\n\n### SPI flash\n\nSequences of SH1107 commands used by the driver are packed into a ROM image\nwhich is separately programmed onto the on-board flash.  The driver reads the\ncontents into RAM on startup over SPI.\n\nBy default, the SPI flash reader component is stubbed out with a\n[blackbox](vsh/spifr_blackbox.cc), which emulates the component's\n[interface](vsh/spifr_blackbox.il), returning data bytes directly to the OLED\ndriver from the ROM embedded in the build.\n\nThis blackbox can be replaced with a [whitebox](vsh/spifr_whitebox.cc) (`vsh\n-f`), which emulates at one level lower, emulating the [SPI\ninterface](vsh/spifr_whitebox.il) itself, returning data bitwise to the [flash\nreader](sh1107/spi/spi_flash_reader.py).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcharlottia%2Fsh1107","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcharlottia%2Fsh1107","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcharlottia%2Fsh1107/lists"}