Skip to content

Hello Hardware World

The Basic DFHDL Program

Since DFHDL is a Scala library, were are creating a Scala program that takes DFHDL designs and compiles (transpiles) them into lower representations (e.g., VHDL or Verilog). As such, some of DFHDL's compilation process is done statically via the Scala compiler and the rest during the Scala runtime execution. The Scala code below describes a program that runs the DFHDL compiler on an 8-bit overlapping counter design, Counter8.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import dfhdl.* //import all the DFHDL goodness

/** Generates an 8-bit overlapping count */
class Counter8 extends RTDesign:
  val cnt = UInt(8) <> OUT.REG init 0
  cnt.din := cnt + 1

////////////////////////////////////////////////////////////////////////////////////////////////
// DFHDL Compiler Options:                                                                    //
////////////////////////////////////////////////////////////////////////////////////////////////
// Enables printing the generated chosen backend code:
given options.CompilerOptions.PrintGenFiles = true
// Uncomment to select vhdl compilation (default is verilog):
// given options.CompilerOptions.Backend = backends.vhdl
// Uncomment to enable printing design code before compilation (after elaboration):
// given options.CompilerOptions.PrintDesignCodeBefore = true
// Uncomment to enable printing design code after compilation:
// given options.CompilerOptions.PrintDesignCodeAfter = true
// Uncomment to set different clock and reset configurations:
// given options.CompilerOptions.DefaultClkCfg = ClkCfg(ClkCfg.Edge.Rising)
// given options.CompilerOptions.DefaultRstCfg = RstCfg(RstCfg.Mode.Async, RstCfg.Active.Low)
////////////////////////////////////////////////////////////////////////////////////////////////

//The entry point to your compilation program starts here
@main def main = Counter8().compile.commit

Writing a DFHDL compilation program – as easy as 01-10-11!

  1. import dfhdl.* once per source file, to import all the required namespace objects, types, and functionality.
  2. class _design_name_ extends RTDesign: to define your register-transfer (RT) domain design. Populate your design with the required interface and functionality. DFHDL supports two additional design domains: dataflow (DF), and event-driven (ED).
  3. @main def main = _design_name_().compile.commit to create your compilation program entry point, instantiate the design, elaborate it, compile it to Verilog or VHDL (see compiler options), and finally commit the files to disk.

Run It In Your Browser

Run it here
import dfhdl.* //import all the DFHDL goodness

/** Generates an 8-bit overlapping count */
class Counter8 extends RTDesign:
  val cnt = UInt(8) <> OUT.REG init 0
  cnt.din := cnt + 1

////////////////////////////////////////////////////////////////////////////////////////////////
// DFHDL Compiler Options:                                                                    //
////////////////////////////////////////////////////////////////////////////////////////////////
// Enables printing the generated chosen backend code:
given options.CompilerOptions.PrintGenFiles = true
// Uncomment to select vhdl compilation (default is verilog):
// given options.CompilerOptions.Backend = backends.vhdl
// Uncomment to enable printing design code before compilation (after elaboration):
// given options.CompilerOptions.PrintDesignCodeBefore = true
// Uncomment to enable printing design code after compilation:
// given options.CompilerOptions.PrintDesignCodeAfter = true
// Uncomment to set different clock and reset configurations:
// given options.CompilerOptions.DefaultClkCfg = ClkCfg(ClkCfg.Edge.Rising)
// given options.CompilerOptions.DefaultRstCfg = RstCfg(RstCfg.Mode.Async, RstCfg.Active.Low)
////////////////////////////////////////////////////////////////////////////////////////////////

//The entry point to your compilation program starts here
@main def main = Counter8().compile.commit

For more examples that are available to run in your browser, see the relevant section.

Run It On Your System

To run this example on your system, make sure to first follow the initial setup instructions.

You have several options to run Scala programs on your system:

  • For this simple Counter8 example, you can just use the simplest scala-cli-single-file approach.
  • For common DFHDL projects, we recommend using the scala-cli project approach.
  • For more complex, full-production DFHDL projects, we recommended using an sbt project.

Scala-cli Single File

View the scala-cli single file example
Counter8.scala
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//> using scala 3.4.2
//> using dep io.github.dfianthdl::dfhdl::0.4.9
//> using plugin io.github.dfianthdl:::dfhdl-plugin:0.4.9
//> using option -deprecation -language:implicitConversions

import dfhdl.* //import all the DFHDL goodness

/** Generates an 8-bit overlapping count */
class Counter8 extends RTDesign:
  val cnt = UInt(8) <> OUT.REG init 0
  cnt.din := cnt + 1

////////////////////////////////////////////////////////////////////////////////////////////////
// DFHDL Compiler Options:                                                                    //
////////////////////////////////////////////////////////////////////////////////////////////////
// Enables printing the generated chosen backend code:
given options.CompilerOptions.PrintGenFiles = true
// Uncomment to select vhdl compilation (default is verilog):
// given options.CompilerOptions.Backend = backends.vhdl
// Uncomment to enable printing design code before compilation (after elaboration):
// given options.CompilerOptions.PrintDesignCodeBefore = true
// Uncomment to enable printing design code after compilation:
// given options.CompilerOptions.PrintDesignCodeAfter = true
// Uncomment to set different clock and reset configurations:
// given options.CompilerOptions.DefaultClkCfg = ClkCfg(ClkCfg.Edge.Rising)
// given options.CompilerOptions.DefaultRstCfg = RstCfg(RstCfg.Mode.Async, RstCfg.Active.Low)
////////////////////////////////////////////////////////////////////////////////////////////////

//The entry point to your compilation program starts here
@main def main = Counter8().compile.commit
Download and run in your terminal
curl -o Counter8.scala https://dfianthdl.github.io/getting-started/hello-world/scala-cli-single-file/Counter8.scala
scala-cli run ./Counter8.scala

For more information, please consult the scala-cli documentation.

Scala-cli Project

View the scala-cli project files example
projectFolder/project.scala
1
2
3
4
//> using scala 3.4.2
//> using dep io.github.dfianthdl::dfhdl::0.4.9
//> using plugin io.github.dfianthdl:::dfhdl-plugin:0.4.9
//> using option -deprecation -language:implicitConversions
projectFolder/Counter8.scala
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import dfhdl.* //import all the DFHDL goodness

/** Generates an 8-bit overlapping count */
class Counter8 extends RTDesign:
  val cnt = UInt(8) <> OUT.REG init 0
  cnt.din := cnt + 1

////////////////////////////////////////////////////////////////////////////////////////////////
// DFHDL Compiler Options:                                                                    //
////////////////////////////////////////////////////////////////////////////////////////////////
// Enables printing the generated chosen backend code:
given options.CompilerOptions.PrintGenFiles = true
// Uncomment to select vhdl compilation (default is verilog):
// given options.CompilerOptions.Backend = backends.vhdl
// Uncomment to enable printing design code before compilation (after elaboration):
// given options.CompilerOptions.PrintDesignCodeBefore = true
// Uncomment to enable printing design code after compilation:
// given options.CompilerOptions.PrintDesignCodeAfter = true
// Uncomment to set different clock and reset configurations:
// given options.CompilerOptions.DefaultClkCfg = ClkCfg(ClkCfg.Edge.Rising)
// given options.CompilerOptions.DefaultRstCfg = RstCfg(RstCfg.Mode.Async, RstCfg.Active.Low)
////////////////////////////////////////////////////////////////////////////////////////////////

//The entry point to your compilation program starts here
@main def main = Counter8().compile.commit
Download and run in your terminal
curl -o project.scala https://dfianthdl.github.io/getting-started/hello-world/scala-cli-project/project.scala
curl -o Counter8.scala https://dfianthdl.github.io/getting-started/hello-world/scala-cli-project/Counter8.scala
scala-cli run .

For more information, please consult the scala-cli documentation.

sbt Project

The best way to get started with a DFHDL sbt project, is clone our template from github:

Clone and run in your terminal
git clone https://github.com/DFiantHDL/dfhdl-template
cd dfhdl-template
sbt run

For more information, please consult the sbt documentation.

We recommend to actively use Scalafmt, a code formatter for Scala that integrates well with your toolchain. The following setting is recommended for DFHDL designs:

View the Scalafmt recommended configuration file
projectFolder/.scalafmt.conf
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
version = 3.8.1
runner.dialect = scala3

maxColumn = 100
align.tokens = [{code = "<>"}, {code = "="}, {code = "=>"}, {code = ":="}, {code = ":=="}]
rewrite.scala3.removeOptionalBraces = oldSyntaxToo
rewrite.scala3.insertEndMarkerMinLines = 15

binPack.literalArgumentLists = true
binPack.literalsMinArgCount = 5
binPack.literalsInclude = [".*"]
binPack.literalsIncludeSimpleExpr = true
binPack.literalsSingleLine = false

newlines.selectChains = keep
Download it via your terminal
curl -o .scalafmt.conf https://dfianthdl.github.io/getting-started/hello-world/scala-cli-project/.scalafmt.conf

For more information, please consult the Scalafmt documentation.