clash-lang / clash-compiler

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

Let primitive .json files contain multi-language templates #211

Closed thoughtpolice closed 4 years ago

thoughtpolice commented 7 years ago

If I'm using a Clash package that's been installed by cabal, I can now use primitives included in the package defined as .json files. But as far as I can see, there is no way to distinguish between which set of primitives to use, for different compiler backends.

In other words: when a user uses my package from hackage, maybe they want to synthesize Verilog, or instead VHDL. But how do they specify which primitive .json to use, the one with the right language templates?

Perhaps the JSON representation of a primitive should be extended to include a language field. Then, I could include both VHDL and Verilog templates for my primitive in the same file:

[ { "BlackBox":
    { "name": "Foo.bar#"
    , "type": "bar# :: ..."
    , "language": "verilog"
    , "templateD": "... lots of verilog code"
    }
}, { "BlackBox":
    { "name": "Foo.bar#"
    , "type": "bar# :: ..."
    , "language": "vhdl"
    , "templateD": "... lots of vhdl code"
    }
}
]

It would be even better if the templateD sections could be merged together instead, so you only have to specify the fully qualified name and type once.

christiaanb commented 7 years ago

On the master branch, but not yet released, you can associate .json files with modules. See commit https://github.com/clash-lang/clash-compiler/commit/82cd31863aafcbaf3bdbf7746d89d13859af5aaf, which describes:

i.e. give a foobar.cabal file with:

> data-files: primitives/vhdl/Foo.json
>             primitives/verilog/Foo.json
>             primitives/systemverilog/Foo.json

and a Foo.hs file:

> module Foo where
>
> import qualified Paths_foobar
> import           System.FilePath
> import           System.IO.Unsafe
>
> {-# ANN module (Primitive VHDL (unsafePerformIO Paths.getDataDir </> "primitives </> "vhdl")) #-}
> {-# ANN module (Primitive Verilog (unsafePerformIO Paths.getDataDir </> "primitives </> "verilog")) #-}
> {-# ANN module (Primitive SystemVerilog (unsafePerformIO Paths.getDataDir </> "primitives </> "systemverilog")) #-}

the CLaSH compiler can figure out that the BlackBox definitions
corresponding to the primitives defined in Foo.hs can be found
in the `datadir` directories of the installed `foobar` package.

p.s. the only fields that you need in the .json files are: name and, templateE or templateD. I add the type field for documentation purposes only.

thoughtpolice commented 7 years ago

Nice! That's really good to know and should go in the Tutorial, IMO.

Do you think supporting this at the .json level is still valid, though? Personally IMO I think I'd prefer a 1-to-1 module<->HDL setup rather than a 1-to-N module<->HDL setup, but I can understand if this seems like a needlessly flexible knob to tweak.

christiaanb commented 7 years ago

Yeah, I think it's preferable to have just 1 .json file. So I will probably change it before te release.

thoughtpolice commented 7 years ago

OK, cool. Maybe this weekend I can hack something up to help with that based on the earlier commit.

christiaanb commented 4 years ago

Now that we have TemplateFunctions, BlackBoxFunctions, and InlinePrimitives that can support multiple backends, we should probably not invest more in the file-based blackboxes.