{"id":17267508,"url":"https://github.com/technius/democlash","last_synced_at":"2025-03-26T11:14:14.521Z","repository":{"id":143021353,"uuid":"344296533","full_name":"Technius/democlash","owner":"Technius","description":null,"archived":false,"fork":false,"pushed_at":"2021-03-03T23:53:13.000Z","size":12,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-31T12:24:58.464Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Haskell","has_issues":true,"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/Technius.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":"2021-03-03T23:52:53.000Z","updated_at":"2021-03-03T23:53:16.000Z","dependencies_parsed_at":"2023-06-16T16:30:58.060Z","dependency_job_id":null,"html_url":"https://github.com/Technius/democlash","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Technius%2Fdemoclash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Technius%2Fdemoclash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Technius%2Fdemoclash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Technius%2Fdemoclash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Technius","download_url":"https://codeload.github.com/Technius/democlash/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245641437,"owners_count":20648644,"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":[],"created_at":"2024-10-15T08:10:53.130Z","updated_at":"2025-03-26T11:14:14.504Z","avatar_url":"https://github.com/Technius.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Notes\n\nThis repository contains a toy instruction set and CPU implemented with Clash.\nSee `src/Example/Project.hs` for the code. If you want to run this code, you\nwill need to have the Clash compiler installed somewhere.\n\nTo try out the sample code, run the interpreter with\n```bash\nstack run clashi -- src/Example/Project.hs\n```\nIn the interpreter, execute:\n```haskell\nprintX $ sampleN @System 10 (system myProgram (blockRam (replicate d64 0)))\n```\nThis will execute the system for 10 clock cycles and print out the debug values.\n\nThe remaining part of this readme is from the default sample project readme.\n\n\u003c!-- omit in toc --\u003e\n# Simple Starter Project\nThis starter project contains the scaffolding needed to integrate Clash with the Cabal and Stack build systems. It allows you to use dependencies from [Hackage](https://hackage.haskell.org/) easily.\n\n\u003c!-- omit in toc --\u003e\n# Table of Contents\n- [Getting this project](#getting-this-project)\n- [Building and testing this project](#building-and-testing-this-project)\n  - [Stack (Windows, Linux, MacOS) [recommended]](#stack-windows-linux-macos-recommended)\n  - [Cabal (Linux, MacOS)](#cabal-linux-macos)\n  - [REPL](#repl)\n  - [IDE support](#ide-support)\n- [Project overview](#project-overview)\n  - [democlash.cabal](#namecabal)\n  - [cabal.project](#cabalproject)\n  - [stack.yaml](#stackyaml)\n  - [src/](#src)\n  - [tests/](#tests)\n- [Change the license](#change-the-license)\n\n# Getting this project\nStack users can run `stack new my-clash-project clash-lang/simple`. Cabal users can [download a zip](https://raw.githubusercontent.com/clash-lang/clash-starters/main/simple.zip) containing the project.\n\n# Building and testing this project\nThere's a number of ways to build this project on your machine. The recommended way of doing so is using _Stack_, whose instructions will follow directly after this section.\n\n## Stack (Windows, Linux, MacOS) [recommended]\nInstall Stack using your package manager or refer to the [How to install](https://docs.haskellstack.org/en/stable/README/#how-to-install) section of the [Stack manual](https://docs.haskellstack.org/en/stable/README/).\n\nBuild the project with:\n\n```bash\nstack build\n```\n\nTo run the tests defined in `tests/`, use:\n\n```bash\nstack test\n```\n\nTo compile the project to VHDL, run:\n\n```bash\nstack run clash -- Example.Project --vhdl\n```\n\nYou can find the HDL files in `vhdl/`. The source can be found in `src/Example/Project.hs`.\n\n## Cabal (Linux, MacOS)\n**The following instructions only work for Cabal \u003e=3.0 and GHC \u003e=8.4.**\n\nFirst, update your cabal package database:\n\n```bash\ncabal update\n```\n\nYou only have to run the update command once. After that, you can keep rebuilding your project by running the build command:\n\n```bash\ncabal build\n```\n\nTo run the tests defined in `tests/`, use:\n\n```bash\ncabal run test-library --enable-tests\ncabal run doctests --enable-tests\n```\n\nTo compile the project to VHDL, run:\n\n```bash\ncabal run clash --write-ghc-environment-files=always -- Example.Project --vhdl\n```\n\nYou can find the HDL files in `vhdl/`. The source can be found in `src/Example/Project.hs`.\n\n## REPL\nClash offers a [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) as a quick way to try things, similar to Python's `python` or Ruby's `irb`. Stack users can open the REPL by invoking:\n\n```\nstack run clashi\n```\n\nCabal users use:\n\n```\ncabal run --write-ghc-environment-files=always clashi\n```\n\n## IDE support\nWe currently recommend Visual Studio Code in combination with the _Haskell_ plugin. All you need to do is open this folder in VSCode; it will prompt you to install the plugin.\n\n# Project overview\nThis section will give a tour of all the files present in this starter project. It's also a general introduction into Clash dependency management. It's not an introduction to Clash itself though. If you're looking for an introduction to Clash, read [\"Clash.Tutorial\" on Hackage](https://hackage.haskell.org/package/clash-prelude).\n\n```\ndemoclash\n├── bin\n│   ├── Clash.hs\n│   └── Clashi.hs\n├── src\n│   └── Example\n│       └── Project.hs\n├─── tests\n│   ├── Tests\n│   │   └── Example\n│   │       └── Project.hs\n│   ├── doctests.hs\n│   └── unittests.hs\n├── cabal.project\n├── democlash.cabal\n└── stack.yaml\n```\n\n## democlash.cabal\nThis is the most important file in your project. It describes how to build your project. Even though it ends in `.cabal`, Stack will use this file too. It starts of with meta-information:\n\n```yaml\ncabal-version:       2.4\nname:                democlash\nversion:             0.1\nlicense:             BSD-2-Clause\nauthor:              John Smith \u003cjohn@example.com\u003e\nmaintainer:          John Smith \u003cjohn@example.com\u003e\n```\n\nIf you decide to publish your code on [Hackage](https://hackage.haskell.org/), this will show up on your package's front page. Take note of the license, it's set to `BSD-2-Clause` by default, but this might bee too liberal for your project. You can use any of the licenses on [spdx.org/licenses](https://spdx.org/licenses/). If none of those suit, remove the `license` line, add `license-file: LICENSE`, and add a `LICENSE` file of your choice to the root of this project. Moving on:\n\n```yaml\ncommon common-options\n  default-extensions:\n    BangPatterns\n    BinaryLiterals\n    ConstraintKinds\n    [..]\n    QuasiQuotes\n\n    -- Prelude isn't imported by default as Clash offers Clash.Prelude\n    NoImplicitPrelude\n```\n\nClash's parent language is Haskell and its de-facto compiler, GHC, does a lot of heavy lifting before Clash gets to see anything. Because using Clash's Prelude requires a lot of extensions to be enabled to be used, we enable them here for all files in the project. Alternatively, you could add them where needed using `{-# LANGUAGE SomeExtension #-}` at the top of a `.hs` file instead. The next section, `ghc-options`, sets warning flags (`-Wall -Wcompat`) and flags that make GHC generate code Clash can handle.\n\nNote that this whole section is a `common` \"stanza\". We'll use it as a template for any other definitions (more on those later). The last thing we add to the common section is some build dependencies:\n\n```yaml\n  build-depends:\n    base,\n    Cabal,\n\n    -- clash-prelude will set suitable version bounds for the plugins\n    clash-prelude \u003e= 1.2.5 \u0026\u0026 \u003c 1.4,\n    ghc-typelits-natnormalise,\n    ghc-typelits-extra,\n    ghc-typelits-knownnat\n```\n\nThese dependencies are fetched from [Hackage](https://hackage.haskell.org/), Haskell's store for packages. Next up is a `library` stanza. It defines where the source is located, in our case `src/`, and what modules can be found there. In our case that's just a single module, `Example.Project`.\n\n```yaml\nlibrary\n  import: common-options\n  hs-source-dirs: src\n  exposed-modules:\n    Example.Project\n  default-language: Haskell2010\n```\n\nNote that extra dependencies could be added by adding a `build-depends` line to this section. The following section defines a testsuite called _doctests_. Doctests are tests that are defined in the documentation of your project. We'll see this in action in [src/](#src).\n\n```yaml\ntest-suite doctests\n  import:           common-options\n  type:             exitcode-stdio-1.0\n  default-language: Haskell2010\n  main-is:          doctests.hs\n  hs-source-dirs:   tests\n\n  build-depends:\n    base,\n    doctest \u003e= 0.16.1 \u0026\u0026 \u003c 0.18,\n    clash-prelude\n```\n\nLast but not least, another testsuite stanza is defined:\n\n```yaml\ntest-suite test-library\n  import: common-options\n  default-language: Haskell2010\n  hs-source-dirs: tests\n  type: exitcode-stdio-1.0\n  ghc-options: -threaded\n  main-is: unittests.hs\n  other-modules:\n    Tests.Example.Project\n  build-depends:\n    democlash,\n    QuickCheck,\n    hedgehog,\n    tasty \u003e= 1.2 \u0026\u0026 \u003c 1.3,\n    tasty-hedgehog,\n    tasty-th\n```\n\nThese testsuites are executed when using `stack test` or `cabal test --enable-tests`. Note that Cabal swallows the output if more than one testsuite is defined, as is the case here. You might want to consider running the testsuites separately. More on tests in [/tests](#tests).\n\n## cabal.project\nA `cabal.project` file is used to configure details of the build, more info can be found in the [Cabal user documentation](https://cabal.readthedocs.io/en/latest/cabal-project.html). We use it to disable a build flag on `clash-prelude`: `large-tuples`. It is ignored by Stack.\n\n```haskell\npackages:\n  democlash.cabal\n\npackage clash-prelude\n  -- 'large-tuples' generates tuple instances for various classes up to the\n  -- GHC imposed maximum of 62 elements. This severely slows down compiling\n  -- Clash, and triggers Template Haskell bugs on Windows. Hence, we disable\n  -- it by default. This will be the default for Clash \u003e=1.4.\n  flags: -large-tuples\n```\n\n`cabal.project` can be used to build multi-package projects, by extending `packages`.\n\n## stack.yaml\nWhile Cabal fetches packages straight from Hackage (with a bias towards the latest versions), Stack works through _snapshots_. Snapshots are an index of packages from Hackage know to work well with each other. In addition to that, they specify a GHC version. These snapshots are curated by the community and FP Complete and can be found on [stackage.org](https://www.stackage.org/).\n\n```yaml\nresolver: lts-17.2\n\nflags:\n  clash-prelude:\n    # 'large-tuples' generates tuple instances for various classes up to the\n    # GHC imposed maximum of 62 elements. This severely slows down compiling\n    # Clash, and triggers Template Haskell bugs on Windows. Hence, we disable\n    # it by default. This will be the default for Clash \u003e=1.4.\n    large-tuples: false\n```\n\nThis project uses [lts-17.2](https://www.stackage.org/lts-17.2), which includes Clash 1.2.5. If `democlash.cabal` constrains a dependency such that it cannot be fetched from the snapshot, Stack will ask you to add it to `stack.yaml`. Stack will then fetch it from Hackage. The point of this exercise is to make reproducible builds. Or in other words, if a `stack build` works now, it will work in 10 years too.\n\nSimilar to `cabal.project`, this is where we specify any build flags for dependencies.\n\n## src/\nThis is where the source code of the project lives, as specified in `democlash.cabal`. It contains a single file, `Example/Project.hs` which starts with:\n\n```haskell\nmodule Example.Project (topEntity, plus) where\n\nimport Clash.Prelude\n\n-- | Add two numbers. Example:\n--\n-- \u003e\u003e\u003e plus 3 5\n-- 8\nplus :: Signed 8 -\u003e Signed 8 -\u003e Signed 8\nplus a b = a + b\n```\n\n`democlash.cabal` enabled `NoImplicitPrelude` which enables the use of `Clash.Prelude` here. Next, a function `plus` is defined. It simply adds two numbers. Note that the example (`\u003e\u003e\u003e plus 3 5`) gets executed by the _doctests_ defined for this project and checked for consistency with the result in the documentation (`8`).\n\n```haskell\n-- | 'topEntity' is Clash's equivalent of 'main' in other programming\n-- languages. Clash will look for it when compiling 'Example.Project'\n-- and translate it to HDL. While polymorphism can be used freely in\n-- Clash projects, a 'topEntity' must be monomorphic and must use non-\n-- recursive types. Or, to put it hand-wavily, a 'topEntity' must be\n-- translatable to a static number of wires.\ntopEntity :: Signed 8 -\u003e Signed 8 -\u003e Signed 8\ntopEntity = plus\n```\n\nas the comment says `topEntity` will get compiled by Clash if we ask it to compile this module:\n\n```\nstack run clash -- Example.Project --vhdl\n```\n\nor\n\n```\ncabal run clash --write-ghc-environment-files=always -- Example.Project --vhdl\n```\n\nWe could instead ask it to synthesize `plus` instead:\n\n```\nstack run clash -- Example.Project --vhdl -main-is plus\n```\n\nIf you want to play around with Clash, this is probably where you would put all the definitions mentioned in [\"Clash.Tutorial\" on Hackage](https://hackage.haskell.org/package/clash-prelude).\n\n## tests/\nMost of this directory is scaffolding, with the meat of the tests being defined in `tests/Tests/Example/Project.hs`. Writing good test cases is pretty hard: edge cases are easy to forget both in the implementation and tests. To this end, it's a good idea to use _fuzz testing_. In this project we use [Hedgehog](https://hedgehog.qa/):\n\n```haskell\nimport Example.Project (plus)\n\nprop_plusIsCommutative :: H.Property\nprop_plusIsCommutative = H.property $ do\n  a \u003c- H.forAll (Gen.integral (Range.linear minBound maxBound))\n  b \u003c- H.forAll (Gen.integral (Range.linear minBound maxBound))\n  plus a b === plus b a\n```\n\nThis test generates two numbers `a` and `b` that fit neatly into domain of `Signed 8`, thanks to the use of `minBound` and `maxBound`. It then tests whether the `plus` operation commutes. I.e., whether `a + b ~ b + a`. All functions called `prop_*` are collected automatically:\n\n```haskell\ntests :: TestTree\ntests = $(testGroupGenerator)\n```\n\nWe can run the tests using `stack test` or `cabal run test-library --enable-tests`:\n\n```\n.\n  Tests.Example.Project\n    plusIsCommutative: OK\n        ✓ plusIsCommutative passed 100 tests.\n\nAll 1 tests passed (0.00s)\n```\n\n# Change the license\nBy default `democlash.cabal` sets its `license` field to `BSD-2-Clause`. You might want to change this.\n\n\n\n# Experiences\n\n* Very strong type safety.\n* Can write mostly \"plain\" Haskell without having to shoehorn in HDL specific\n  stuff.\n* `Signal dom a` means sequential logic. Ordinary types mean combinational\n  logic. Combinational logic can easily be lifted into sequential logic because\n  `Signal dom` is an applicative functor.\n* Loops in sequential logic can be expressed directly with recursion! But there\n  aren't any warnings if you loop in combinational logic, instead you get\n  infinite recursion in the repl. Hard to debug. e.g. I got an infinite loop\n  when I made a typo (`mop_stall mop` instead of `m_stall m`), or when reading\n  the address from the async program ROM without using a register for the next\n  PC.\n* Can test combinational logic directly in the interpreter, since it's just a\n  function. `stack run clashi --` and then `:load src/Example/Project.hs`.\n* Generate SystemVerilog with `stack run clash -- Example.project\n  --systemverilog`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechnius%2Fdemoclash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftechnius%2Fdemoclash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechnius%2Fdemoclash/lists"}