This language provides a high level, imperative-style programming model for building pipelined processors and accelerators. Designers use scheduling and optimization operators to define when computations happen and to enable common hardware optimizations like out-of-order execution and speculation.
The compiler is built in Scala and currently targets Bluespec System Verilog (BSV) as the output language.
You will need a Java runtime, Scala, and sbt to build and run the compiler.
- Install Java:
- On Linux:
- On Mac:
brew tap AdoptOpenJDK/openjdk && brew cask install adoptopenjdk8
- Install Scala and sbt:
- Install an IDE like intellij and install the scala/sbt plugins (recommended)
- OR
- On Mac:
brew install scala sbt
- On Linux: TODO
You will need the Bluespec compiler and simulator to run end-to-end tests. The instructions can be found on the bluespec github. Linux is currently the only supported platform.
In the top-level directory of this repo, simply run make
.
This will produce an executable jar, pdl.jar
, in the target/scala-2.13/
directory
and will use BSV to compile the custom hardware module libraries.
You can also manually build the compiler by running sbt compile
.
sbt assembly
can be used to compile and then produce the executable jar.
The main class is pipedsl.Main
and can be run via
the sbt command sbt "run pipedsl.Main <args>"
.
Alternatively, the executable jar can be used by
running java with the command java -jar pdl.jar <args>
.
We also provide a script pdl
in the bin
directory that
runs the executable jar with the provided arguments.
We provide a bash autocomplete script in the bin
directory.
To enable tab completion on ./bin/pdl
and pdl
, simply source
the script pdl-completion.bash
. You can do this by adding it to
the file ~/.bash_completion
, or whatever your preferred sourcing
method may be.
PDL produces BSV code which can then be run via the BSV simulator, or transformed into Verilog for hardware synthesis.
We provide a convenience script runbsc
in the bin
directory
which can 1) generate verilog, 2) run the BSV simulator, or 3) clean up BSV generated files.
The usage is runbsc [v|s|c] <dir>
, where <dir>
is the directory containing all
of the relevant *.bsv files generated by pdl
.
Here we describe each of the packages and their contents and then we will describe the high level architecture of compilation.
Packages:
- pipedsl
- The toplevel package containing the main file and some of the other primary components, such as the parser.
- pipedsl.common
- This package contains a bunch of common utility files that are useful in many places, such as a Dataflow analysis framework.
- It also contains most of the case class definitions used to build the AST for the parsed language and some of the intermediate representations.
- Lastly it contains pretty printer files used to print out various ASTs.
- pipedsl.passes
- A number of transformation passes that take in various parts of the AST (e.g. whole programs, single pipeline modules, other intermediate representations) and produce new versions of the input structure.
- pipedsl.typechecker
- This contains a number of typechecking passes that may transform the existing AST, but only by modifying type (and potentially other) annotations. Various typecheckers check different subcomponents of the type system (e.g. base types, data availability, locking, speculation, etc.)
- pipedsl.codegen
- The functions that transform our internal representations to ASTs in target languages.
The compiler works in the following steps:
- Parse the input text file into a
Program
that contains: combinational function definitions; pipeline definitions; and, the full circuit instantiation. - Apply the various typechecker passes to annotate all of the
Id
andEVar
expressions with the appropriate types. - Generate the internal
PStage
representation for each pipeline which is a dataflow graph representation of the original AST, where nodes in the graph represent distinct pipeline stages. These stages can execute concurrently with each other and primarily communicate with each other via channels represented by edges in the graph. - Run passes to annotate this graph with any extra information needed for code generation, such as live variable analysis that computes which data to send along the edges.
- Generate the target AST (currently BSV) by applying transformations to each of the nodes in the stage graph.
- Print the target AST to an output directory using the pretty printers.