tomcl / issie

Issie - an intuitive cross-platform hardware design application. https://tomcl.github.io/issie
GNU General Public License v3.0
67 stars 96 forks source link
digital editor educational electron fable fpga fsharp logic simulator verilog

Issie - an Interactive Schematic Simulator with Integrated Editor

Issie (Interactive Schematic Simulator with Integrated Editor) is an application for digital circuit design and simulation. It is targeted at students and hobbyists that want to get a grasp of Digital Electronics concepts in a simple and fun way. Issie is designed to be beginner-friendly and guide the users toward their goals via clear error messages and visual clues. Issie is developed and actively used in teaching at Imperial College London.

For more technical info about the project, read on. This documentation is partly based on the excellent VisUAL2 documentation, given the similarity in the technology stack used.

Introduction

For the Issie website go here.

The application is mostly written in F#, which gets transpiled to JavaScript via the Fable compiler. Electron is then used to convert the developed web-app to a cross-platform application. Electron provides access to platform-level APIs (such as access to the file system) which would not be available to vanilla browser web-apps.

Webpack 5 is the module bundler responsible for the JavaScript concatenation and automated building process: the electron-webpack build is automated using the pre-existing scripts under the scripts directory.

The drawing capabilities are provided (now) by a custom schemetic editor library implemented in F# and specialised for digital components.

The choice of F# as main programming language for the app has been dictated by a few factors:

Getting Started

If you just want to run the app go to the releases page and download and run the latest prebuilt binary for your platform (Windows or Macos). Issie will require in total about 200M of disk space.

Issie installs and runs without making system changes - all of its code is inside the directory you download. You can delete this and replace it by a later version of Issie. Each design sheet is stored in a similarly named file under the project directory. The subdirectory backup there contains a large numbers of backup snapshots for design recovery. These are not needed for Issie operation so you can delete them - or even the whole backup directory, if you wish.

Issie binaries will not run (in some cases) from a networked file location (found on many cluster machines). If you have this problem navigate to the top-level directory containing the Issie binaries in a command window and type issie.exe --no-sandbox. See https://github.com/tomcl/issie/issues/125 for details.

Once you open up Issie and are ready to go, feel free to open one of the Demo Projects from the start-up window. These are there to show you what a complete Issie project looks like and enable you to have fun with it without having to design and build it from scratch. Every time you reopen a demo project it will be reset to its initial state.

Getting Started as Developer

If you want to get started as a developer, follow these steps.

Development Install Prerequisites (common to windows, macos, linux)

Download and install (if you already have these tools installed just check the version constraints).

Issie Development

  1. Download & unzip the Issie repo, or clone it locally, or fork it on github and then clone it locally.

  2. Check you have , .Net 7 (2024: .Net 8 will be OK too, I think), Node v18, VS 2022 (or latest VS Code + ionide or Rider) installed.

    • In a terminal window: node -v shows Node version. dotnet --version shows Dotnet version.
  3. Navigate to the project root directory from the master branch (which contains this README) in a command-line interpreter, or start one from directory context menu.

  4. Run build.cmd under Windows or build.sh under linux or macos. This will download and install all dependencies then launch the application in dev mode with HMR.

    • HMR: the application will automatically recompile and update while running if you save updated source files
    • To initialise and reload: File -> reload page
    • To exit: after you exit the application the auto-compile script will terminate after about 15s
    • To recompile the whole application again run npm run dev. Run npm run debug for the debug mode (this is going to be a lot slower than dev).
    • To generate distributable binaries for dev host system npm run dist.
    • If you have changed packet.json and therefore need to remake the lock file paket-lock.json use npm install.
    • On windows build killzombies will terminate orphan node and dotnet processes which occasionally happen using this build chain after unusual terminations (maybe no longer needed?)

NB - in parallel with the above compilation, Issie code will always compile without errors (but not run) under dotnet, for example by building it from Visuak Studio. Compilation should be identical but when unsure why there is an error it is very helpful to build the current code under VS or VSC and get easier to find error messages. Similarly, VS or VSC can be used with confidence to refactor code, testing with compilation. Building under VS or VSC cannot work because the code depends on electron and Node APIs to work.

Node management details

Development on Macos

A clean build will work equally well on macos, however things are more likely to go wrong if you have previously installed conflicting packages:

Under the hood for developers

Although the dev chain is complex, it is now very smooth and identical for all platforms. Each of these steps can be performed as needed:

  1. You need Dotnet SDK and Node installed. Dotnet SDK gives you F#.
  2. dotnet tool restore gets you the dev tools: Fable compiler, Fake build automation, paket dotnet package manager. (Node package management is via npm which comes with Node).
  3. dotnet paket install installs all of the dotnet-side packages needed
  4. npm ci downloads and audits correct versions of all of the npm packages. npm install will redo the versions if these have changed and generate an updated lock file.
  5. npm run dev, npm run dist, npm run debug: scripts defined in package.json which control developmment (with HMR) or production compilation with Fable, and packing using Webpack 5.
  6. The build.cmd and build.sh scripts package the above steps adding some not usually necessary directory cleaning - you can run them individually in order if you have problems.

Project Structure

Electron bundles Chromium (View) and node.js (Engine), therefore as in every node.js project, the package.json file specifies the (Node) module dependencies.

Additionally, the section "scripts":

"scripts": {
    "clean-dev-mac": "sudo killall -9 node && sudo killall -9 dotnet && sudo killall -9 issie",
    "clean-dev-win": "taskkill /f /im node.exe && taskkill /f /im dotnet.exe && taskkill /f /im issie.exe",
    "compile": "dotnet fable src/Main -s && dotnet fable src/Renderer -s --define PRODUCTION",
    "debug": "dotnet fable watch src/Main -s --run npm run debugrenderer",
    "debugrenderer": "dotnet fable watch src/Renderer -s --define ASSERTS --run npm run start",
    "dev": "dotnet fable watch src/Main -s --run npm run devrenderer",
    "devrenderer": "dotnet fable watch src/Renderer -s --run npm run start",
    "start": "cross-env NODE_ENV=development node scripts/start.js",
    "build": "cross-env NODE_ENV=production node scripts/build.js",
    "pack": "npm run compile && npm run build && electron-builder --dir",
    "dist": "npm run compile && npm run build && electron-builder",
    "buildonly": "electron-builder",
    "compile-sass": "cd src/renderer/scss && node-sass main.scss main.css",
    "testcompiler": "cd src/Renderer/VerilogComponent/test && dotnet fable --noCache && node testParser.fs.js"
  }

Defines the in-project shortcut commands as a set of <key> : <value lines, so that when we use npm run <stript_key> it is equivalent to calling <script_value>. For example, in the root of the project, running in the terminal npm run dev is equivalent to the command line:

dotnet fable watch src/Main -s --run npm run devrenderer

This runs fable 4 to transpile the main process, then (--run is an option of fable to run another command) runs script devrenderer to transpile to javascript and watch the F# files in the renderer process. After the renderer transpilation is finished start.js script will be run. This invokes webpack to pack and lauch the javascript code, under electron, and also watches for changes in the javascript code, and hot loads these on the running application

As result of this, at any time saving an edited F# renderer project file causes (nearly) immediate:

The build system depends on a Fake file build.fsx. Fake is a DSL written in F# that is specialised to automate build tasks. Build.fsx has targets representing build tasks, and normally these are run via build.cmd or build.sh, instead of using dotnet fake directly:

Code Overview

The source code consists of two distinct sections transpiled separately to Javascript to make a complete Electron application.

Electron thus allows code written for a browser (HTML + CSS + JavaScript) to be run as a desktop app with the additional capability of desktop filesystem access via communication between the two processes.

Both processes run Javascript under Node.

The src/Main/Main.fs source configures electron start-up and is boilerplate. It is transpiled to the root project directory so it can be automatically picked up by Electron.

The remaining app code (in )

The code that turns the F# project source into renderer.js is the FABLE compiler followed by the Node Webpack bundler that combines multiple Javascript files into a single renderer.js.

The compile process is controlled by the .fsproj files (defining the F# source) and webpack.additions.main.js, webpack.additions.renderer.js which define how Webpack combines F# outputs for both electron main and electron app processes and where the executable code is put. This is boilerplate which you do not need to change; normally the F# project files are all that needs to be modified.

File Structure

src folder

Subfolder or file Description
Main/main.fs Code for the main electron process that sets everything up - not normally changed
Renderer/Common/* Provides some common types and utilities, as well as interfaces to libraries APIs and custom libraries
Renderer/Interface/* Contains low-level interface functions, and all the low-level file management
Renderer/DrawBlock/* Contains all the SVG-based schematic editor code in F#
Renderer/Simulator/* Contains the logic to analyse and simulate a schematic sheet
Renderer/UI/* Contains the UI logic
./renderer.fs Top-level file that drives the renderer code: contains Elmish MVU loop and Electron menu code

Tests folder

Currently tests are very old, and will not work. They are based on F# Expecto testing library and in principle the widthinferrer and simulator code (which runs under dotnet) could be tested here.

Static folder

Contains static files used in the application.

Docs folder

Contains source information that controls the project documentation web site https://tomcl.github.io/issie/.

Project versus File in the Issie application

Issie allows the users to create projects and files within those projects. A Issie project is simply a folder named <project-name> that contains an empty file named <project_name>.dprj (dprj stands for diagram project). The project folder any non-zero number of design files, each named <component_name>.dgm (dgm stands for diagram). each deisgn file represents one design sheet of a hierarchical hardware design, sheets can contain, as components, other sheets.

When opening a project, Issie will initially search the given repository for .dgm files, parse and load their content, and allow the user to open them in Issie or use them as components in other designs.

Reinstalling Compiler and Libraries

To reinstall the build environment (without changing project code) rerun build.cmd (Windows) or build.sh (Linux and MacOS).

Creating binaries

npm run dist will generate the correct binaries for your system under /dist.