diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..74c65a5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + labels: + - dependabot + - actions + schedule: + interval: "weekly" diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml new file mode 100644 index 0000000..e61ba10 --- /dev/null +++ b/.github/workflows/build-and-test.yaml @@ -0,0 +1,77 @@ +on: + workflow_call: + +jobs: + pedantic-build: + name: Pedantic build + runs-on: ubuntu-latest + steps: + - name: Clone project + uses: actions/checkout@v4 + + - name: Setup Haskell with Stack + uses: haskell-actions/setup@v2 + with: + enable-stack: true + stack-version: "latest" + + - name: Cache dependencies + uses: actions/cache@v4 + with: + path: ~/.stack + key: pedantic-${{ hashFiles('stack.yaml') }} + restore-keys: | + pedantic- + + - name: Install dependencies + run: | + stack update + stack build --only-dependencies + + - name: Pedantic build + run: | + stack build --pedantic + + build-and-test: + name: Build and Test on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macOS-latest, windows-latest] + + steps: + - name: Clone project + uses: actions/checkout@v4 + + - name: Setup Haskell with Stack + uses: haskell-actions/setup@v2 + with: + enable-stack: true + stack-version: "latest" + + - name: Cache dependencies on Unix-like OS + if: startsWith(runner.os, 'Linux') || startsWith(runner.os, 'macOS') + uses: actions/cache@v4 + with: + path: ~/.stack + key: ${{ runner.os }}-${{ hashFiles('stack.yaml') }} + + - name: Cache dependencies on Windows + if: startsWith(runner.os, 'Windows') + uses: actions/cache@v4 + with: + path: | + ~\AppData\Roaming\stack + ~\AppData\Local\Programs\stack + key: ${{ runner.os }}-${{ hashFiles('stack.yaml') }} + + - name: Install dependencies + run: | + stack update + stack build --only-dependencies --test --bench --no-run-tests --no-run-benchmarks + + - name: Build + run: stack build --test --bench --no-run-tests --no-run-benchmarks + + - name: Run tests + run: stack test diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..9b0dfd7 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,29 @@ +name: CI + +on: + push: + branches: + # PRs can only use caches from their target branch. We therefore need to + # make sure we run on 'master' too. + - main + pull_request: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + pre-commit: + uses: ./.github/workflows/pre-commit.yaml + + fourmolu: + needs: pre-commit + uses: ./.github/workflows/fourmolu.yaml + + hlint: + needs: fourmolu + uses: ./.github/workflows/hlint.yaml + + build-and-test: + needs: hlint + uses: ./.github/workflows/build-and-test.yaml diff --git a/.github/workflows/fourmolu.yaml b/.github/workflows/fourmolu.yaml new file mode 100644 index 0000000..3fb8bfa --- /dev/null +++ b/.github/workflows/fourmolu.yaml @@ -0,0 +1,15 @@ +on: + workflow_call: + +jobs: + hlint: + name: Fourmolu + runs-on: ubuntu-latest + steps: + - name: Clone project + uses: actions/checkout@v4 + + - name: Run fourmolu + uses: haskell-actions/run-fourmolu@v10 + with: + version: "latest" diff --git a/.github/workflows/hlint.yaml b/.github/workflows/hlint.yaml new file mode 100644 index 0000000..52a2e48 --- /dev/null +++ b/.github/workflows/hlint.yaml @@ -0,0 +1,19 @@ +on: + workflow_call: + +jobs: + hlint: + name: Hlint + runs-on: ubuntu-latest + steps: + - name: Clone project + uses: actions/checkout@v4 + + - name: Set up HLint + uses: haskell-actions/hlint-setup@v2 + + - name: Run HLint + uses: haskell-actions/hlint-run@v2 + with: + path: . + fail-on: warning diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml new file mode 100644 index 0000000..e1785b2 --- /dev/null +++ b/.github/workflows/pre-commit.yaml @@ -0,0 +1,18 @@ +on: + workflow_call: + +jobs: + pre-commit: + name: Pre-commit + runs-on: ubuntu-latest + steps: + - name: Clone project + uses: actions/checkout@v4 + + - name: Install pre-commit + run: | + pip install pre-commit + + - name: Run pre-commit + run: | + pre-commit run --all-files diff --git a/.gitignore b/.gitignore index 4c9e245..ba7d650 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ +# File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig +# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,linux,haskell +# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,linux,haskell + +### Haskell ### dist dist-* cabal-dev @@ -21,3 +26,49 @@ cabal.project.local cabal.project.local~ .HTF/ .ghc.environment.* + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### VisualStudioCode ### +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +# End of https://www.toptal.com/developers/gitignore/api/visualstudiocode,linux,haskell + +# Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) + +# Because of prettier in pre-commit +node_modules/ + +# HDL directories often created during development cycle +/vhdl +/verilog +/systemverilog diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..f665979 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,13 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: fix-byte-order-marker + - id: mixed-line-ending + # - repo: https://github.com/pre-commit/mirrors-prettier + # rev: v4.0.0-alpha.8 + # hooks: + # - id: prettier diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..d7272b2 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "redhat.vscode-yaml", + "haskell.haskell", + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..eb561fe --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,38 @@ +{ + "editor.formatOnSave": true, + "files.insertFinalNewline": true, + "files.trimFinalNewlines": true, + "files.trimTrailingWhitespace": true, + "editor.renderWhitespace": "all", + "[haskell]": { + "editor.tabSize": 4 + }, + "haskell.manageHLS": "GHCup", + "haskell.formattingProvider": "fourmolu", + "yaml.format.enable": true, + "[yaml]": { + "editor.defaultFormatter": "redhat.vscode-yaml" + }, + "files.exclude": { + "**/*.vo": true, + "**/*.vok": true, + "**/*.vos": true, + "**/*.aux": true, + "**/*.glob": true, + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/Thumbs.db": true, + "**/*.dyn_hi": true, + "**/*.dyn_o": true, + "**/*.hi": true, + "**/*.o": true, + "**/dist-newstyle": true, + "**/.stack-work": true, + "**/.ghc.environment.*": true, + "**/*.o-boot": true, + "**/*.hi-boot": true + } +} diff --git a/README.md b/README.md index 454bca2..b0ada21 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,30 @@ -# interaction-nets-in-fpga -Interaction nets based processor in Clash +# Interaction nets based processor in Clash + +## Required tools + +### Pre-commit + +We use [pre-commit](https://pre-commit.com/) for general tidy up of files. +To install pre-commit run: + +```shell +pip install pre-commit # or install using your distro package manager +pre-commit install +``` + +To run pre-commit on all files run + +```shell +pre-commit run --all-files +``` + +### Fourmolu + +We use [Fourmolu](https://fourmolu.github.io/) as a formatter for Haskell source files with our custom config. +**Fourmolu must be explicitly enabled in VS Code!** + +## Editor + +Our editor of choice is [VS Code](https://code.visualstudio.com/) with following extensions: + +- [Haskell](https://marketplace.visualstudio.com/items?itemName=haskell.haskell) diff --git a/fourmolu.yaml b/fourmolu.yaml new file mode 100644 index 0000000..0074c28 --- /dev/null +++ b/fourmolu.yaml @@ -0,0 +1,50 @@ +# Number of spaces per indentation step +indentation: 4 + +# Max line length for automatic line breaking +column-limit: 120 + +# Styling of arrows in type signatures (choices: trailing, leading, or leading-args) +function-arrows: trailing + +# How to place commas in multi-line lists, records, etc. (choices: leading or trailing) +comma-style: leading + +# Styling of import/export lists (choices: leading, trailing, or diff-friendly) +import-export-style: diff-friendly + +# Whether to full-indent or half-indent 'where' bindings past the preceding body +indent-wheres: false + +# Whether to leave a space before an opening record brace +record-brace-space: false + +# Number of spaces between top-level declarations +newlines-between-decls: 1 + +# How to print Haddock comments (choices: single-line, multi-line, or multi-line-compact) +haddock-style: multi-line + +# How to print module docstring +haddock-style-module: null + +# Styling of let blocks (choices: auto, inline, newline, or mixed) +let-style: auto + +# How to align the 'in' keyword with respect to the 'let' keyword (choices: left-align, right-align, or no-space) +in-style: right-align + +# Whether to put parentheses around a single constraint (choices: auto, always, or never) +single-constraint-parens: always + +# Output Unicode syntax (choices: detect, always, or never) +unicode: never + +# Give the programmer more choice on where to insert blank lines +respectful: true + +# Fixity information for operators +fixities: [] + +# Module reexports Fourmolu should know about +reexports: [] diff --git a/lamagraph-compiler/CHANGELOG.md b/lamagraph-compiler/CHANGELOG.md new file mode 100644 index 0000000..8498a52 --- /dev/null +++ b/lamagraph-compiler/CHANGELOG.md @@ -0,0 +1,11 @@ +# Changelog for `lamagraph-compiler` + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to the +[Haskell Package Versioning Policy](https://pvp.haskell.org/). + +## Unreleased + +## 0.1.0.0 - YYYY-MM-DD diff --git a/lamagraph-compiler/README.md b/lamagraph-compiler/README.md new file mode 100644 index 0000000..e69de29 diff --git a/lamagraph-compiler/Setup.hs b/lamagraph-compiler/Setup.hs new file mode 100644 index 0000000..e8ef27d --- /dev/null +++ b/lamagraph-compiler/Setup.hs @@ -0,0 +1,3 @@ +import Distribution.Simple + +main = defaultMain diff --git a/lamagraph-compiler/app/Main.hs b/lamagraph-compiler/app/Main.hs new file mode 100644 index 0000000..4c6b30f --- /dev/null +++ b/lamagraph-compiler/app/Main.hs @@ -0,0 +1,6 @@ +module Main (main) where + +import Lib + +main :: IO () +main = someFunc diff --git a/lamagraph-compiler/lamagraph-compiler.cabal b/lamagraph-compiler/lamagraph-compiler.cabal new file mode 100644 index 0000000..ef20843 --- /dev/null +++ b/lamagraph-compiler/lamagraph-compiler.cabal @@ -0,0 +1,60 @@ +cabal-version: 1.12 + +-- This file has been generated from package.yaml by hpack version 0.37.0. +-- +-- see: https://github.com/sol/hpack + +name: lamagraph-compiler +version: 0.1.0.0 +description: Please see the README on GitHub at +homepage: https://github.com/Lamagraph/interaction-nets-in-fpga#readme +bug-reports: https://github.com/Lamagraph/interaction-nets-in-fpga/issues +author: Nikolai Ponomarev +maintainer: wowasterdev@gmail.com +copyright: 2024 Lamagraph +license: MIT +build-type: Simple +extra-source-files: + README.md + CHANGELOG.md + +source-repository head + type: git + location: https://github.com/Lamagraph/interaction-nets-in-fpga + +library + exposed-modules: + Lib + other-modules: + Paths_lamagraph_compiler + hs-source-dirs: + src + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints + build-depends: + base >=4.7 && <5 + default-language: Haskell2010 + +executable lamagraph-compiler-exe + main-is: Main.hs + other-modules: + Paths_lamagraph_compiler + hs-source-dirs: + app + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N + build-depends: + base >=4.7 && <5 + , lamagraph-compiler + default-language: Haskell2010 + +test-suite lamagraph-compiler-test + type: exitcode-stdio-1.0 + main-is: Spec.hs + other-modules: + Paths_lamagraph_compiler + hs-source-dirs: + test + ghc-options: -Wall -Wcompat -Widentities -Wincomplete-record-updates -Wincomplete-uni-patterns -Wmissing-export-lists -Wmissing-home-modules -Wpartial-fields -Wredundant-constraints -threaded -rtsopts -with-rtsopts=-N + build-depends: + base >=4.7 && <5 + , lamagraph-compiler + default-language: Haskell2010 diff --git a/lamagraph-compiler/package.yaml b/lamagraph-compiler/package.yaml new file mode 100644 index 0000000..0b77761 --- /dev/null +++ b/lamagraph-compiler/package.yaml @@ -0,0 +1,59 @@ +name: lamagraph-compiler +version: 0.1.0.0 +github: "Lamagraph/interaction-nets-in-fpga" +license: MIT +author: "Nikolai Ponomarev" +maintainer: "wowasterdev@gmail.com" +copyright: "2024 Lamagraph" + +extra-source-files: + - README.md + - CHANGELOG.md + +# Metadata used when publishing your package +# synopsis: Short description of your package +# category: Web + +# To avoid duplicated efforts in documentation and dealing with the +# complications of embedding Haddock markup inside cabal files, it is +# common to point users to the README.md file. +description: Please see the README on GitHub at + +dependencies: + - base >= 4.7 && < 5 + +ghc-options: + - -Wall + - -Wcompat + - -Widentities + - -Wincomplete-record-updates + - -Wincomplete-uni-patterns + - -Wmissing-export-lists + - -Wmissing-home-modules + - -Wpartial-fields + - -Wredundant-constraints + +library: + source-dirs: src + +executables: + lamagraph-compiler-exe: + main: Main.hs + source-dirs: app + ghc-options: + - -threaded + - -rtsopts + - -with-rtsopts=-N + dependencies: + - lamagraph-compiler + +tests: + lamagraph-compiler-test: + main: Spec.hs + source-dirs: test + ghc-options: + - -threaded + - -rtsopts + - -with-rtsopts=-N + dependencies: + - lamagraph-compiler diff --git a/lamagraph-compiler/src/Lib.hs b/lamagraph-compiler/src/Lib.hs new file mode 100644 index 0000000..60f4a3e --- /dev/null +++ b/lamagraph-compiler/src/Lib.hs @@ -0,0 +1,6 @@ +module Lib ( + someFunc, +) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/lamagraph-compiler/test/Spec.hs b/lamagraph-compiler/test/Spec.hs new file mode 100644 index 0000000..cd4753f --- /dev/null +++ b/lamagraph-compiler/test/Spec.hs @@ -0,0 +1,2 @@ +main :: IO () +main = putStrLn "Test suite not yet implemented" diff --git a/lamagraph-core/README.md b/lamagraph-core/README.md new file mode 100644 index 0000000..5c79dc8 --- /dev/null +++ b/lamagraph-core/README.md @@ -0,0 +1,3 @@ +# interaction-nets-in-fpga-core + +Interaction nets based processor in Clash diff --git a/lamagraph-core/bin/Clash.hs b/lamagraph-core/bin/Clash.hs new file mode 100644 index 0000000..1024263 --- /dev/null +++ b/lamagraph-core/bin/Clash.hs @@ -0,0 +1,6 @@ +import Clash.Main (defaultMain) +import System.Environment (getArgs) +import Prelude + +main :: IO () +main = getArgs >>= defaultMain diff --git a/lamagraph-core/bin/Clashi.hs b/lamagraph-core/bin/Clashi.hs new file mode 100644 index 0000000..4f03050 --- /dev/null +++ b/lamagraph-core/bin/Clashi.hs @@ -0,0 +1,6 @@ +import Clash.Main (defaultMain) +import System.Environment (getArgs) +import Prelude + +main :: IO () +main = getArgs >>= defaultMain . ("--interactive" :) diff --git a/lamagraph-core/cabal.project b/lamagraph-core/cabal.project new file mode 100644 index 0000000..9ba3efb --- /dev/null +++ b/lamagraph-core/cabal.project @@ -0,0 +1,7 @@ +packages: + lamagraph-core.cabal + +write-ghc-environment-files: always + +-- Eliminates the need for `--enable-tests`, which is needed for HLS. +tests: true diff --git a/lamagraph-core/hie.yaml b/lamagraph-core/hie.yaml new file mode 100644 index 0000000..f62bc4d --- /dev/null +++ b/lamagraph-core/hie.yaml @@ -0,0 +1,12 @@ +cradle: + cabal: + - path: "./src" + component: "lib:lamagraph-core" + - path: "./tests/doctests.hs" + component: "lamagraph-core:doctests" + - path: "./tests" + component: "lamagraph-core:test-library" + - path: "./bin/Clashi.hs" + component: "lamagraph-core:exe:clashi" + - path: "./bin/Clash.hs" + component: "lamagraph-core:exe:clash" diff --git a/lamagraph-core/lamagraph-core.cabal b/lamagraph-core/lamagraph-core.cabal new file mode 100644 index 0000000..89002be --- /dev/null +++ b/lamagraph-core/lamagraph-core.cabal @@ -0,0 +1,134 @@ +cabal-version: 2.4 +name: lamagraph-core +version: 0.1 +license: BSD-2-Clause +author: John Smith +maintainer: John Smith + +common common-options + default-extensions: + BangPatterns + BinaryLiterals + ConstraintKinds + DataKinds + DefaultSignatures + DeriveAnyClass + DeriveDataTypeable + DeriveFoldable + DeriveFunctor + DeriveGeneric + DeriveLift + DeriveTraversable + DerivingStrategies + FlexibleContexts + InstanceSigs + KindSignatures + LambdaCase + NamedFieldPuns + NoStarIsType + PolyKinds + RankNTypes + RecordWildCards + ScopedTypeVariables + StandaloneDeriving + TupleSections + TypeApplications + TypeFamilies + TypeOperators + ViewPatterns + + -- TemplateHaskell is used to support convenience functions such as + -- 'listToVecTH' and 'bLit'. + TemplateHaskell + QuasiQuotes + + -- Prelude isn't imported by default as Clash offers Clash.Prelude + NoImplicitPrelude + ghc-options: + -Wall -Wcompat + -haddock + + -- Plugins to support type-level constraint solving on naturals + -fplugin GHC.TypeLits.Extra.Solver + -fplugin GHC.TypeLits.Normalise + -fplugin GHC.TypeLits.KnownNat.Solver + + -- Clash needs access to the source code in compiled modules + -fexpose-all-unfoldings + + -- Worker wrappers introduce unstable names for functions that might have + -- blackboxes attached for them. You can disable this, but be sure to add + -- a no-specialize pragma to every function with a blackbox. + -fno-worker-wrapper + + -- Strict annotations - while sometimes preventing space leaks - trigger + -- optimizations Clash can't deal with. See: + -- + -- https://github.com/clash-lang/clash-compiler/issues/2361 + -- + -- These flags disables these optimizations. Note that the fields will + -- remain strict. + -fno-unbox-small-strict-fields + -fno-unbox-strict-fields + build-depends: + base, + Cabal, + + -- clash-prelude will set suitable version bounds for the plugins + clash-prelude >= 1.8.1 && < 1.10, + ghc-typelits-natnormalise, + ghc-typelits-extra, + ghc-typelits-knownnat + + +library + import: common-options + hs-source-dirs: src + exposed-modules: + Example.Project + default-language: Haskell2010 + +-- Builds the executable 'clash', with lamagraph-core project in scope +executable clash + main-is: bin/Clash.hs + default-language: Haskell2010 + Build-Depends: base, clash-ghc, lamagraph-core + if !os(Windows) + ghc-options: -dynamic + +-- Builds the executable 'clashi', with lamagraph-core project in scope +executable clashi + main-is: bin/Clashi.hs + default-language: Haskell2010 + if !os(Windows) + ghc-options: -dynamic + build-depends: base, clash-ghc, lamagraph-core + +test-suite doctests + type: exitcode-stdio-1.0 + default-language: Haskell2010 + main-is: doctests.hs + ghc-options: -Wall -Wcompat -threaded + hs-source-dirs: tests + build-depends: + base, + lamagraph-core, + doctest-parallel >= 0.2 && < 0.4, + +test-suite test-library + import: common-options + default-language: Haskell2010 + hs-source-dirs: tests + type: exitcode-stdio-1.0 + ghc-options: -threaded + main-is: unittests.hs + other-modules: + Tests.Example.Project + build-depends: + lamagraph-core, + QuickCheck, + clash-prelude-hedgehog, + hedgehog, + tasty >= 1.2 && < 1.5, + tasty-hedgehog, + tasty-th diff --git a/lamagraph-core/src/Example/Project.hs b/lamagraph-core/src/Example/Project.hs new file mode 100644 index 0000000..0156eae --- /dev/null +++ b/lamagraph-core/src/Example/Project.hs @@ -0,0 +1,58 @@ +-- @createDomain@ below generates a warning about orphan instances, but we like +-- our code to be warning-free. +{-# OPTIONS_GHC -Wno-orphans #-} + +module Example.Project where + +import Clash.Prelude + +-- Create a domain with the frequency of your input clock. For this example we used +-- 50 MHz. +createDomain vSystem{vName = "Dom50", vPeriod = hzToPeriod 50e6} + +{- | @topEntity@ is Clash@s equivalent of @main@ in other programming languages. +Clash will look for it when compiling "Example.Project" and translate it to +HDL. While polymorphism can be used freely in Clash projects, a @topEntity@ +must be monomorphic and must use non- recursive types. Or, to put it +hand-wavily, a @topEntity@ must be translatable to a static number of wires. + +Top entities must be monomorphic, meaning we have to specify all type variables. +In this case, we are using the @Dom50@ domain, which we created with @createDomain@ +and we are using 8-bit unsigned numbers. +-} +topEntity :: + Clock Dom50 -> + Reset Dom50 -> + Enable Dom50 -> + Signal Dom50 (Unsigned 8) -> + Signal Dom50 (Unsigned 8) +topEntity = exposeClockResetEnable accum +-- To specify the names of the ports of our top entity, we create a @Synthesize@ annotation. +{-# ANN + topEntity + ( Synthesize + { t_name = "accum" + , t_inputs = + [ PortName "CLK" + , PortName "RST" + , PortName "EN" + , PortName "DIN" + ] + , t_output = PortName "DOUT" + } + ) + #-} +-- Make sure GHC does not apply any optimizations to the boundaries of the design. +-- For GHC versions 9.2 or older, use: {-# NOINLINE topEntity #-} +{-# OPAQUE topEntity #-} + +{- | A simple accumulator that works on unsigned numbers of any size. +It has hidden clock, reset, and enable signals. +-} +accum :: + (HiddenClockResetEnable dom, KnownNat n) => + Signal dom (Unsigned n) -> + Signal dom (Unsigned n) +accum = mealy accumT 0 + where + accumT s i = (s + i, s) diff --git a/lamagraph-core/tests/Tests/Example/Project.hs b/lamagraph-core/tests/Tests/Example/Project.hs new file mode 100644 index 0000000..d303596 --- /dev/null +++ b/lamagraph-core/tests/Tests/Example/Project.hs @@ -0,0 +1,51 @@ +module Tests.Example.Project where + +import Prelude + +import Clash.Hedgehog.Sized.Unsigned +import Test.Tasty +import Test.Tasty.Hedgehog +import Test.Tasty.TH + +import qualified Clash.Prelude as C +import qualified Hedgehog as H +import qualified Hedgehog.Gen as Gen +import qualified Hedgehog.Range as Range + +-- Import the module containing the @accum@ function +import Example.Project (accum) + +-- Define a Hedgehog property to test the @accum@ function +prop_accum :: H.Property +prop_accum = H.property $ do + -- Simulate for a random duration between 1 and 100 cycles + simDuration <- H.forAll (Gen.integral (Range.linear 1 100)) + + -- Generate a list of random unsigned numbers. + inp <- + H.forAll + ( Gen.list + (Range.singleton simDuration) + (genUnsigned Range.linearBounded) + ) + let + -- Simulate the @accum@ function for the pre-existing @System@ domain + -- and 8 bit unsigned numbers. + -- + -- The (hidden) reset input of @accum@ will be asserted in the first cycle; + -- during this cycle it will emit its initial value and the input is + -- ignored. So we need to present a dummy input value. + simOut = C.sampleN (simDuration + 1) (accum @C.System @8 (C.fromList (0 : inp))) + -- Calculate the expected output. The first cycle is the initial value, and + -- the result of the final input value does not appear because the + -- accumulator has 1 cycle latency. + expected = 0 : init (scanl (+) 0 inp) + + -- Check that the simulated output matches the expected output + simOut H.=== expected + +accumTests :: TestTree +accumTests = $(testGroupGenerator) + +main :: IO () +main = defaultMain accumTests diff --git a/lamagraph-core/tests/doctests.hs b/lamagraph-core/tests/doctests.hs new file mode 100644 index 0000000..6b82d0e --- /dev/null +++ b/lamagraph-core/tests/doctests.hs @@ -0,0 +1,7 @@ +module Main where + +import System.Environment (getArgs) +import Test.DocTest (mainFromCabal) + +main :: IO () +main = mainFromCabal "lamagraph-core" =<< getArgs diff --git a/lamagraph-core/tests/unittests.hs b/lamagraph-core/tests/unittests.hs new file mode 100644 index 0000000..1323f44 --- /dev/null +++ b/lamagraph-core/tests/unittests.hs @@ -0,0 +1,13 @@ +import Prelude + +import Test.Tasty + +import qualified Tests.Example.Project + +main :: IO () +main = + defaultMain $ + testGroup + "." + [ Tests.Example.Project.accumTests + ] diff --git a/stack.yaml b/stack.yaml new file mode 100644 index 0000000..5b64a7a --- /dev/null +++ b/stack.yaml @@ -0,0 +1,73 @@ +# This file was automatically generated by 'stack init' +# +# Some commonly used options have been documented as comments in this file. +# For advanced use and comprehensive documentation of the format, please see: +# https://docs.haskellstack.org/en/stable/yaml_configuration/ + +# Resolver to choose a 'specific' stackage snapshot or a compiler version. +# A snapshot resolver dictates the compiler version and the set of packages +# to be used for project dependencies. For example: +# +# resolver: lts-22.7 +# resolver: nightly-2024-01-20 +# resolver: ghc-9.6.4 +# +# The location of a snapshot can be provided as a file or url. Stack assumes +# a snapshot provided as a file might change, whereas a url resource does not. +# +# resolver: ./custom-snapshot.yaml +# resolver: https://example.com/snapshots/2023-01-01.yaml +resolver: lts-21.25 + +# User packages to be built. +# Various formats can be used as shown in the example below. +# +# packages: +# - some-directory +# - https://example.com/foo/bar/baz-0.0.2.tar.gz +# subdirs: +# - auto-update +# - wai +packages: + - lamagraph-compiler + - lamagraph-core +# Dependency packages to be pulled from upstream that are not in the resolver. +# These entries can reference officially published versions as well as +# forks / in-progress versions pinned to a git hash. For example: +# +# extra-deps: +# - acme-missiles-0.3 +# - git: https://github.com/commercialhaskell/stack.git +# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a +# + +extra-deps: + - clash-ghc-1.8.1@sha256:3bab304fa5584f3541650bddd01160f2710b9ced52e52c06481a91ac73d71bb8,9753 + - clash-lib-1.8.1@sha256:17d78e786dedf16a76394cd5813372870a3d70a1a4c7f964309f126b800e90f6,15693 + - clash-prelude-1.8.1@sha256:c3fbb9f6b8e74140fb3d5c4d59ec84cfe4a53e9f8520e606c187cfc04b149065,17626 + - clash-prelude-hedgehog-1.8.1@sha256:9ec3aa3f8195481f5ce4942b34a49c97dd132dd1c8f1fa58aeecbd82c2602e86,1410 + - concurrent-supply-0.1.8@sha256:80b658533141660818d0781b8c8fb9a8cf69b987fcfbab782dc788bfc7df4846,1627 + - prettyprinter-interp-0.2.0.0@sha256:69c339a95b265dab9b3478ca19ec96952b6b472bd0ff6e2127112a9562362c1d,2086 +# Override default flag values for local packages and extra-deps +# flags: {} + +# Extra package databases containing global packages +# extra-package-dbs: [] + +# Control whether we use the GHC we find on the path +# system-ghc: true +# +# Require a specific version of Stack, using version ranges +# require-stack-version: -any # Default +# require-stack-version: ">=2.15" +# +# Override the architecture used by Stack, especially useful on Windows +# arch: i386 +# arch: x86_64 +# +# Extra directories used by Stack for building +# extra-include-dirs: [/path/to/dir] +# extra-lib-dirs: [/path/to/dir] +# +# Allow a newer minor version of GHC than the snapshot specifies +# compiler-check: newer-minor diff --git a/stack.yaml.lock b/stack.yaml.lock new file mode 100644 index 0000000..6c6db8d --- /dev/null +++ b/stack.yaml.lock @@ -0,0 +1,54 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: +- completed: + hackage: clash-ghc-1.8.1@sha256:3bab304fa5584f3541650bddd01160f2710b9ced52e52c06481a91ac73d71bb8,9753 + pantry-tree: + sha256: 7ed7168cb8383f86eb0f8f97409c0af484ea9b645a0e9fd416115483932ce695 + size: 5655 + original: + hackage: clash-ghc-1.8.1@sha256:3bab304fa5584f3541650bddd01160f2710b9ced52e52c06481a91ac73d71bb8,9753 +- completed: + hackage: clash-lib-1.8.1@sha256:17d78e786dedf16a76394cd5813372870a3d70a1a4c7f964309f126b800e90f6,15693 + pantry-tree: + sha256: 622764296ca18046991406e7e2a2b0ae08485cb440623bfe44cefd896f11a4cb + size: 23320 + original: + hackage: clash-lib-1.8.1@sha256:17d78e786dedf16a76394cd5813372870a3d70a1a4c7f964309f126b800e90f6,15693 +- completed: + hackage: clash-prelude-1.8.1@sha256:c3fbb9f6b8e74140fb3d5c4d59ec84cfe4a53e9f8520e606c187cfc04b149065,17626 + pantry-tree: + sha256: 189a67c035b1e18188a33ad003f386c2baf15363e55fef35d2546be43d00e213 + size: 13511 + original: + hackage: clash-prelude-1.8.1@sha256:c3fbb9f6b8e74140fb3d5c4d59ec84cfe4a53e9f8520e606c187cfc04b149065,17626 +- completed: + hackage: clash-prelude-hedgehog-1.8.1@sha256:9ec3aa3f8195481f5ce4942b34a49c97dd132dd1c8f1fa58aeecbd82c2602e86,1410 + pantry-tree: + sha256: 886fd3f21d7acdcd86a5e8ff582c903edf8195a22cd38fc04ddcbf7a27f7dd20 + size: 735 + original: + hackage: clash-prelude-hedgehog-1.8.1@sha256:9ec3aa3f8195481f5ce4942b34a49c97dd132dd1c8f1fa58aeecbd82c2602e86,1410 +- completed: + hackage: concurrent-supply-0.1.8@sha256:80b658533141660818d0781b8c8fb9a8cf69b987fcfbab782dc788bfc7df4846,1627 + pantry-tree: + sha256: 8ede0db0bb492f20b2ef34e822ac3e957b31693cd6b7ffd502bec11abcba1955 + size: 400 + original: + hackage: concurrent-supply-0.1.8@sha256:80b658533141660818d0781b8c8fb9a8cf69b987fcfbab782dc788bfc7df4846,1627 +- completed: + hackage: prettyprinter-interp-0.2.0.0@sha256:69c339a95b265dab9b3478ca19ec96952b6b472bd0ff6e2127112a9562362c1d,2086 + pantry-tree: + sha256: 72ec39fe4a40e437e7c0d3efba1f97c4e4e860a7b5503f31d185cef389c9c6e1 + size: 300 + original: + hackage: prettyprinter-interp-0.2.0.0@sha256:69c339a95b265dab9b3478ca19ec96952b6b472bd0ff6e2127112a9562362c1d,2086 +snapshots: +- completed: + sha256: a81fb3877c4f9031e1325eb3935122e608d80715dc16b586eb11ddbff8671ecd + size: 640086 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/21/25.yaml + original: lts-21.25