From 7be1c699f018d96540d76e67ad7254bafe4caab1 Mon Sep 17 00:00:00 2001 From: tzlil Date: Thu, 16 Nov 2023 19:29:37 +0200 Subject: inital commit --- .envrc | 1 + .gitignore | 3 ++ blinker.cabal | 84 +++++++++++++++++++++++++++++++++++++++++++++++++ flake.lock | 61 ++++++++++++++++++++++++++++++++++++ flake.nix | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/Blinker.hs | 32 +++++++++++++++++++ 6 files changed, 280 insertions(+) create mode 100644 .envrc create mode 100644 .gitignore create mode 100644 blinker.cabal create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 src/Blinker.hs diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..8392d15 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..16023c9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +result +.direnv +dist-newstyle \ No newline at end of file diff --git a/blinker.cabal b/blinker.cabal new file mode 100644 index 0000000..3a2d389 --- /dev/null +++ b/blinker.cabal @@ -0,0 +1,84 @@ +cabal-version: 2.4 +name: Blinker +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 + InstanceSigs + KindSignatures + LambdaCase + NoStarIsType + PolyKinds + RankNTypes + 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: Blinker + default-language: Haskell2010 \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..f6b8125 --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1699781429, + "narHash": "sha256-UYefjidASiLORAjIvVsUHG6WBtRhM67kTjEY4XfZOFs=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e44462d6021bfe23dfb24b775cc7c390844f773d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..1517d5a --- /dev/null +++ b/flake.nix @@ -0,0 +1,99 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { nixpkgs, flake-utils, self }: + flake-utils.lib.eachDefaultSystem (system: + let + name = "Blinker"; + family = "Cyclone V"; + device = "5CGXFC5C6F27C7"; + hdl = "vhdl"; + src = ./.; + + pkgs = import nixpkgs { inherit system; config.allowUnfree = true; }; + hpkgs = pkgs.haskellPackages.override { + overrides = self: super: { + clash-prelude = super.callHackageDirect { + pkg = "clash-prelude"; + ver = "1.8.1"; + sha256 = "sha256-HUt8Aw5vMFWThp26e/FdVkcjGQK8rvUV/ZMlv/KvHgg="; + } {}; + clash-ghc = super.callHackageDirect { + pkg = "clash-ghc"; + ver = "1.8.1"; + sha256 = "sha256-oMK756+7WA5rGSRLkJ6Rpdkb2IkJ2VA6S82HGGyiK7Y="; + } {}; + clash-lib = super.callHackageDirect { + pkg = "clash-lib"; + ver = "1.8.1"; + sha256 = "sha256-/dFgCj9e+gkyyUDAB1n1ukaEnkugCR7cRkP+SFJmjjY="; + } {}; + }; + }; + hpkg = pkgs.haskell.lib.overrideCabal (hpkgs.callCabal2nix name src {}) (drv: { + enableLibraryProfiling = false; + + postBuild = '' + ${hpkgs.clash-ghc}/bin/clash -package-db dist/package.conf.inplace ${name} --${hdl} + ''; + + postInstall = '' + mkdir -p "$out/share" + cp -r "${hdl}/" "$out/share/${hdl}" + ''; + }); + + f = "${hpkg}/share/${hdl}/${name}.topEntity"; + hdls = builtins.filter (x: pkgs.lib.hasSuffix hdl x) (builtins.attrNames (builtins.readDir f)); + # qsys = pkgs.lib.findFirst (x: pkgs.lib.hasSuffix "qsys" x) (throw "no qsys found") (builtins.attrNames (builtins.readDir f)); + qsf = pkgs.lib.concatStringsSep "\n" ([ + "set_global_assignment -name DEVICE ${device}" + "set_global_assignment -name FAMILY \"${family}\"" + "set_global_assignment -name TOP_LEVEL_ENTITY ${name}" + "set_global_assignment -name SDC_FILE ${name}.sdc" + # "set_global_assignment -name QSYS_FILE ${qsys}" + ] ++ (map (x: "set_global_assignment -name VHDL_FILE ${x}") hdls)); + in + { + packages.default = hpkg; + packages.sof = pkgs.runCommand "${name}.sof" { + buildInputs = [ pkgs.quartus-prime-lite ]; + src = pkgs.symlinkJoin { + name = "${name}.topEntity"; + paths = [ + "${hpkg}/share/${hdl}/${name}.topEntity" + (pkgs.writeTextDir "${name}.qsf" qsf) + (pkgs.writeTextDir "${name}.qpf" '' + PROJECT_REVISION = "${name}" + '') + ]; + }; + } '' + mkdir $out + ln -s $src/* . + # quartus_map --read_settings_files=on --write_settings_files=off Blinker -c Blinker + quartus_sh --flow compile ${name} + cp -r * $out + ''; + + devShells.default = hpkgs.shellFor { + packages = p: [ hpkg ]; + nativeBuildInputs = [ + pkgs.cabal-install + hpkgs.haskell-language-server + hpkgs.clash-ghc + + (pkgs.writeShellScriptBin "flash" '' + quartus_pgm -m jtag -o "p;$1" + '') + ]; + buildInputs = [ pkgs.quartus-prime-lite ]; + }; + + formatter.x86_64-linux = nixpkgs.legacyPackages.x86_64-linux.nixpkgs-fmt; + } + ); +} diff --git a/src/Blinker.hs b/src/Blinker.hs new file mode 100644 index 0000000..30e6f0e --- /dev/null +++ b/src/Blinker.hs @@ -0,0 +1,32 @@ +{-# OPTIONS_GHC -fno-warn-orphans #-} +module Blinker where + +import Clash.Prelude +import Clash.Annotations.SynthesisAttributes + +-- Define a synthesis domain with a clock with a period of 20000 /ps/. +-- i.e. 50 MHz +-- createDomain vSystem{vName="Input", vPeriod=20000} + +-- Define a synthesis domain with a clock with a period of 50000 /ps/. +-- i.e. 20 MHz +createDomain vSystem{vName="Dom20MHz", vPeriod=50000} + +{-# ANN topEntity + (Synthesize + { t_name = "Blinker" + , t_inputs = [ PortName "KEY0" ] + , t_output = PortName "LED" + }) #-} +topEntity :: + Signal Dom20MHz Bit + `Annotate` 'StringAttr "chip_pin" "AC9" + `Annotate` 'StringAttr + "altera_attribute" "-name IO_STANDARD \"3.3-V LVTTL\"" -> + + Signal Dom20MHz Bit + `Annotate` 'StringAttr + "chip_pin" "F7" + `Annotate` 'StringAttr + "altera_attribute" "-name IO_STANDARD \"3.3-V LVTTL\"" +topEntity sw = sw \ No newline at end of file -- cgit 1.4.1