clash-lang / clash-compiler

Haskell to VHDL/Verilog/SystemVerilog compiler
https://clash-lang.org/
Other
1.44k stars 154 forks source link

"No blackbox found" when trying to use a function from another package #677

Closed gergoerdi closed 5 years ago

gergoerdi commented 5 years ago

I am trying to modularize my Space Invaders so that the Intel 8080 core can be put into a separate Cabal package. My aim with this is to reuse the Intel 8080 code in a Compucolor II project.

So I've set up a bunch of Cabal packages for clash-utils and clash-intel8080, but when I try to use them in Space Invaders, CLaSH complains about a missing blackbox for my function (I assume it's just the first one it encounters):

$ stack exec -- clash -isrc-clash   -iclash-intel8080/src   -outputdir _build  -Wno-partial-type-signatures -fclash-inline-limit=60 -fclash-intwidth=32 --verilog src-clash/SpaceInvaders.hs
GHC: Parsing and optimising modules took: 19.793s
GHC: Loading external modules from interface files took: 2.467s
GHC: Parsing annotations took: 0.014s

Warning: primitive Clash.Sized.Internal.Unsigned.shiftR# isn't using all its arguments, some might be optimized away.

Warning: primitive Clash.Sized.Vector.length isn't using all its arguments, some might be optimized away.

Warning: primitive Clash.Explicit.BlockRam.File.blockRamFile# isn't using all its arguments, some might be optimized away.

Warning: primitive Clash.Sized.Internal.Unsigned.size# isn't using all its arguments, some might be optimized away.
GHC+Clash: Loading modules cumulatively took 31.626s
Clash: Parsing and compiling primitives took 2.458s
Clash: Compiling SpaceInvaders.topEntity
Clash: Applied 10402 transformations
Clash: Normalisation took 15.457s

src-clash/SpaceInvaders.hs:75:1: error:
    Clash.Netlist.BlackBox(227): No blackbox found for: Cactus.Clash.VGA.$wvgaDriver. Did you forget to include directories containing primitives? You can use '-i/my/prim/dir' to achieve this.

    NB: The source location of the error is not exact, only indicative, as it is acquired after optimisations.
    The actual location of the error can be in a function that is inlined.
    To prevent inlining of those functions, annotate them with a NOINLINE pragma.
   |
75 | topEntity = exposeClockResetEnable board
   | ^^^^^^^^^

I've pushed the full repro to a branch; my stack.yaml file is as follows:

resolver: lts-13.24

packages:
  - location:
      git: https://github.com/gergoerdi/empty-clash
      commit: f5ce90ce1
    extra-dep: false

  - clash-utils
  - clash-intel8080

extra-deps:
  - git: git@github.com:clash-lang/clash-compiler
    commit: 8ddd65254ade547501b76ae40304c2b7727763e5
    subdirs:
    - clash-prelude
    - clash-lib
    - clash-ghc

  - git: https://github.com/clash-lang/ghc-typelits-extra
    commit: 145a1a524d9ee163887e7da2edc11cd2ff977ab8

  - higgledy-0.3.0.0
martijnbastiaan commented 5 years ago

Can you try and compile your package with -fexpose-all-unfoldings -fno-worker-wrapper? I'm not sure where you'd add it in a stack.yaml, but you can find a cabal example here. The former makes sure that the compiled files (*.hi*) also contain the core Clash needs to translate functions. The latter makes sure that no worker versions of your functions are created ($wvgaDriver), which sometimes confuses Clash.

martijnbastiaan commented 5 years ago

@gergoerdi Can you confirm adding the flags works?

gergoerdi commented 5 years ago

Yes indeed. I have upgraded CLaSH and started using these flags and now I am able to build space-invaders and compucolor2 without any shady source-based importing: https://github.com/gergoerdi/clash-spaceinvaders/commit/d98a9489c1d9dd8667787c2903cd9ecd8b08e7e5

gergoerdi commented 5 years ago

Oh and one more observation: I think the nicest way to do this would be if there was a way to specify CLaSH as the Haskell compiler in Cabal/Stack so that it would come with its own set of default flags.

martijnbastiaan commented 5 years ago

I've tried that a while ago and I remember it being not completely trivial. I should have written my thoughts down, because I don't remember why it was hard.. But yeah, I agree that it should be possible!