DHDL 0.1 Documentation¶
Contents:
Introduction¶
DHDL is an intermediate language for describing hardware datapaths. A DHDL program describes a dataflow graph consisting of various kinds of nodes connected to each other by data dependencies. Each node in a DHDL program corresponds to a architectural template. DHDL is represented in-memory as a parameterized, hierarchical dataflow graph.
Templates in DHDL capture parallelism, locality, and access pattern information at multiple levels. This dramatically simplifies coarse-grained pipelining and enables us to explicitly capture and represent a large space of designs which other tools cannot capture, as shown in Figure 2. Every template is parameterized. A specific hardware design point is instantiated from a DHDL description by instantiating all the templates in the design with concrete parameter values passed to the program. DHDL heavily uses metaprogramming, so these values are passed in as arguments to the DHDL program. The generated design instance is represented internally as a graph that can be analyzed to provide estimates of metrics such as area and cycle count. The parameters used to create the design instance can be automatically generated by a design space exploration tool.
This document was auto-generated using Sphinx. For corrections, post an issue on GitHub Issues .
Type Classes¶
Data Structures¶
BRAM¶
BRAMs are on-chip scratchpads with fixed size. BRAMs can be specified as multi-dimensional, but the underlying addressing in hardware is always flat. The contents of BRAMs are currently persistent across loop iterations, even when they are declared in an inner scope. BRAMs can have an arbitrary number of readers but only one writer. This writer may be an element-based store or a load from an OffChipMem.
Static methods¶
def apply(name: String, dims: Index*)(implicit ev0: Num[T]): BRAM[T]
Creates a BRAM with given name and dimensions. Dimensions must be statically known signed integers (constants or parameters).
def apply(dims: Index*)(implicit ev0: Num[T]): BRAM[T]
Creates an unnamed BRAM with given dimensions. Dimensions must be statically known signed integers (constants or parameters).
Infix methods¶
def :=(tile: Tile[T]): Unit
Creates a tile store from a Tile of an OffChipMem to this BRAM.
def apply(ii: Index*): T
Creates a read from this BRAM at the given multi-dimensional address. Number of indices given can either be 1 or the same as the number of dimensions that the BRAM was declared with.
- ii - multi-dimensional address
def update(i: Index, x: T): Unit
Creates a write to this BRAM at the given 1D address.
- i - 1D address
- x - element to be stored to BRAM
def update(i: Index, j: Index, x: T): Unit
Creates a write to this BRAM at the given 2D address. The BRAM must have initially been declared as 2D.
- i - row index
- j - column index
- x - element to be stored to BRAM
def update(i: Index, j: Index, k: Index, x: T): Unit
Creates a write to this BRAM at the given 3D address. The BRAM must have initially been declared as 3D.
- i - row index
- j - column index
- k - page index
- x - element to be stored to BRAM
def update(y: Seq[Index], z: T): Unit
Counter¶
Counter is a single hardware counter with an associated minimum, maximum, step size, and parallelization factor. By default, the parallelization factor is assumed to be a design parameter. Counters can be chained together using CounterChain, but this is typically done implicitly when creating controllers.
Static methods¶
def apply(max: Index): Counter
Creates an unnamed Counter with min of 0, given max, and step size of 1
def apply(min: Index, max: Index): Counter
Creates an unnamed Counter with given min and max, and step size of 1
def apply(min: Index, max: Index, step: Index): Counter
Creates an unnamed Counter with given min, max and step size
def apply(min: Index, max: Index, step: Index, par: Int): Counter
Creates an unnamed Counter with given min, max, step size, and parallelization factor
def apply(name: String, max: Index): Counter
Creates a named Counter with min of 0, given max, and step size of 1
def apply(name: String, min: Index, max: Index): Counter
Creates a named Counter with given min and max, and step size of 1
def apply(name: String, min: Index, max: Index, step: Index): Counter
Creates a named Counter with given min, max and step size
def apply(name: String, min: Index, max: Index, step: Index, par: Int): Counter
Creates a named Counter with given min, max, step size, and parallelization factor
CounterChain¶
CounterChain describes a set of chained hardware counters, where a given counter increments only when the counter below it wraps around. Order is specified as outermost to innermost.
Static methods¶
def apply(x: Counter*): CounterChain
Creates a chain of counters. Order is specified as outermost to innermost
LoopRange¶
<auto-generated stub>
OffChipMem¶
OffChipMems are pointers to locations in the accelerators main memory to dense multi-dimensional arrays. They are the primary form of communication of data between the host and the accelerator. Data may be loaded to and from the accelerator in contiguous chunks (Tiles). Other access patterns will be supported soon!
Static methods¶
def apply(name: String, dims: Index*)(implicit ev0: Num[T]): OffChipMem[T]
Creates a reference to a multi-dimensional array in main memory with given name and dimensions
def apply(dims: Index*)(implicit ev0: Num[T]): OffChipMem[T]
Creates a reference to an unnamed multi-dimensional array in main memory with given dimensions
Infix methods¶
def apply(cols: Range): Tile[T]
Creates a reference to a 1D Tile of this 1D OffChipMem which can be loaded into on-chip BRAM.
def apply(rows: Range, cols: Range): Tile[T]
Creates a reference to a 2D Tile of this 2D OffChipMem which can be loaded into on-chip BRAM.
def apply(rows: Range, cols: Range, pages: Range): Tile[T]
Creates a reference to a 3D Tile of this 3D OffChipMem which can be loaded into on-chip BRAM.
def apply(row: Index, cols: Range): Tile[T]
Creates a reference to a 1D row Tile of this 2D OffChipMem
def apply(rows: Range, col: Index): Tile[T]
Creates a reference to a 1D column Tile of this 2D OffChipMem
def apply(row: Index, cols: Range, pages: Range): Tile[T]
Creates a reference to a 2D column/page Tile of this 3D OffChipMem
def apply(rows: Range, col: Index, pages: Range): Tile[T]
Creates a reference to a 2D row/page Tile of this 3D OffChipMem
def apply(rows: Range, cols: Range, page: Index): Tile[T]
Creates a reference to a 2D row/column Tile of this 3D OffChipMem
def apply(row: Index, col: Index, pages: Range): Tile[T]
Creates a reference to a 1D page Tile of this 3D OffChipMem
def apply(row: Index, cols: Range, page: Index): Tile[T]
Creates a reference to a 1D column Tile of this 3D OffChipMem
def apply(rows: Range, col: Index, page: Index): Tile[T]
Creates a reference to a 1D row Tile of this 3D OffChipMem
Reg¶
Reg defines a hardware register used to hold a scalar value. Regs have an optional name (primarily used for debugging) and reset value. The default reset value for a Reg is the numeric zero value for it’s specified type. Regs can have an arbitrary number of readers but can only have one writer. By default, Regs are reset based upon the controller that they are defined within. A Reg defined within a Pipe, for example, is reset at the beginning of each iteration of that Pipe.
Static methods¶
def apply(name: String)(implicit ev0: Num[T]): Reg[T]
Creates a register with type T and given name
def apply()(implicit ev0: Num[T]): Reg[T]
Creates an unnamed register with type T
def apply(name: String, reset: Int)(implicit ev0: Num[T]): Reg[T]
Creates a register of type T with given name and reset value
def apply(reset: Int)(implicit ev0: Num[T]): Reg[T]
Creates an unnamed register with type T and given reset value
def apply(name: String, reset: Long)(implicit ev0: Num[T]): Reg[T]
Creates a register of type T with given name and reset value
def apply(reset: Long)(implicit ev0: Num[T]): Reg[T]
Creates an unnamed register with type T and given reset value
def apply(name: String, reset: Float)(implicit ev0: Num[T]): Reg[T]
Creates a register of type T with given name and reset value
def apply(reset: Float)(implicit ev0: Num[T]): Reg[T]
Creates an unnamed register with type T and given reset value
def apply(name: String, reset: Double)(implicit ev0: Num[T]): Reg[T]
Creates a register of type T with given name and reset value
def apply(reset: Double)(implicit ev0: Num[T]): Reg[T]
Creates an unnamed register with type T and given reset value
Infix methods¶
def :=(x: T): Unit
Creates a writer to this Reg. Note that Regs and ArgOuts can only have one writer, while ArgIns cannot have any
def value(): T
Reads the current value of this register
Implicit methods¶
def regBitToBit(x: Reg[Bit]): Bit
Enables implicit reading from bit type Regs
def regFixToFix(x: Reg[FixPt[S,I,F]]): FixPt[S,I,F]
Enables implicit reading from fixed point type Regs
def regFltToFlt(x: Reg[FltPt[G,E]]): FltPt[G,E]
Enables implicit reading from floating point type Regs
Tile¶
A Tile describes a continguous slice of an OffChipMem which can be loaded onto the accelerator for processing or which can be updated with results once computation is complete.
Tup3¶
<auto-generated stub>
Tup4¶
<auto-generated stub>
Tup5¶
<auto-generated stub>
Tup6¶
<auto-generated stub>
Tup7¶
<auto-generated stub>
Tup8¶
<auto-generated stub>
Objects¶
Array¶
Unsynthesizable helper object for creating arrays on the CPU
Static methods¶
def empty(length: Index): ForgeArray[T]
Creates an empty array with given length
def fill(length: Index)(f: => T): ForgeArray[T] Creates an array with given length whose elements are determined by the supplied function
def tabulate(length: Index)(f: (Index) => T): ForgeArray[T]
Creates an array with the given length whose elements are determined by the supplied indexed function
Indices¶
<auto-generated stub>
MetaPipe¶
<auto-generated stub>
Static methods¶
def apply(x: Counter)(y: (Index) => Unit): Unit
def apply(x: Counter, y: Counter)(z: (Index, Index) => Unit): Unit
def apply(x: Counter, y: Counter, z: Counter)(v: (Index, Index, Index) => Unit): Unit
def apply(x: Counter, y: C[T])(z: (Index) => T)(v: (T, T) => T)(implicit ev0: Mem[T,C],ev1: Manifest[C[T]]): Unit
def apply(x: Counter, y: Counter, z: C[T])(v: (Index, Index) => T)(w: (T, T) => T)(implicit ev0: Mem[T,C],ev1: Manifest[C[T]]): Unit
def apply(x: Counter, y: Counter, z: Counter, v: C[T])(w: (Index, Index, Index) => T)(a: (T, T) => T)(implicit ev0: Mem[T,C],ev1: Manifest[C[T]]): Unit
def apply(x: => Unit): Unit
def foreach(x: CounterChain)(y: (Indices) => Unit): Unit
def reduce(x: CounterChain, y: C[T])(z: (Indices) => T)(v: (T, T) => T)(implicit ev0: Mem[T,C],ev1: Manifest[C[T]]): Unit
Pipe¶
<auto-generated stub>
Static methods¶
def apply(x: Counter)(y: (Index) => Unit): Unit
def apply(x: Counter, y: Counter)(z: (Index, Index) => Unit): Unit
def apply(x: Counter, y: Counter, z: Counter)(v: (Index, Index, Index) => Unit): Unit
def apply(x: Counter, y: C[T])(z: (Index) => T)(v: (T, T) => T)(implicit ev0: Mem[T,C],ev1: Manifest[C[T]]): Unit
def apply(x: Counter, y: Counter, z: C[T])(v: (Index, Index) => T)(w: (T, T) => T)(implicit ev0: Mem[T,C],ev1: Manifest[C[T]]): Unit
def apply(x: Counter, y: Counter, z: Counter, v: C[T])(w: (Index, Index, Index) => T)(a: (T, T) => T)(implicit ev0: Mem[T,C],ev1: Manifest[C[T]]): Unit
def apply(x: => Unit): Unit
def foreach(x: CounterChain)(y: (Indices) => Unit): Unit
def reduce(x: CounterChain, y: C[T])(z: (Indices) => T)(v: (T, T) => T)(implicit ev0: Mem[T,C],ev1: Manifest[C[T]]): Unit
Sequential¶
<auto-generated stub>
Static methods¶
def apply(x: Counter)(y: (Index) => Unit): Unit
def apply(x: Counter, y: Counter)(z: (Index, Index) => Unit): Unit
def apply(x: Counter, y: Counter, z: Counter)(v: (Index, Index, Index) => Unit): Unit
def apply(x: Counter, y: C[T])(z: (Index) => T)(v: (T, T) => T)(implicit ev0: Mem[T,C],ev1: Manifest[C[T]]): Unit
def apply(x: Counter, y: Counter, z: C[T])(v: (Index, Index) => T)(w: (T, T) => T)(implicit ev0: Mem[T,C],ev1: Manifest[C[T]]): Unit
def apply(x: Counter, y: Counter, z: Counter, v: C[T])(w: (Index, Index, Index) => T)(a: (T, T) => T)(implicit ev0: Mem[T,C],ev1: Manifest[C[T]]): Unit
def apply(x: => Unit): Unit
def foreach(x: CounterChain)(y: (Indices) => Unit): Unit
def reduce(x: CounterChain, y: C[T])(z: (Indices) => T)(v: (T, T) => T)(implicit ev0: Mem[T,C],ev1: Manifest[C[T]]): Unit
bound¶
<auto-generated stub>
Static methods¶
def apply(x: Any): Option[Double]
def update(x: Any, y: Double): Unit
def update(x: Any, y: MBound): Unit
def update(x: Any, y: Option[MBound]): Unit
Primitives¶
Bit¶
Bit represents a single bit, equivalent to a Boolean
FixPt¶
FixPt[S,I,F] represents an arbitrary precision fixed point representation. FixPt values may be signed or unsigned. Negative values, if applicable, are represented in twos complement.
The type parameters for FixPt are:
S | Signed or unsigned representation | (Signed/Unsign) |
I | Number of integer bits | (B0 - B64) |
F | Number of fractional bits | (B0 - B64) |
Note that numbers of bits use the B- prefix as integers cannot be used as type parameters in Scala
Type Aliases¶
type | SInt | FixPt[Signed,B32,B0] | Signed 32 bit integer |
type | Index | FixPt[Signed,B32,B0] | Signed 32 bit integer (indexing) |
type | UInt | FixPt[Unsign,B32,B0] | Unsigned 32 bit integer |
Infix methods¶
def !=(y: FixPt[S,I,F]): Bit
def !=(y: Int): Bit
def !=(y: Long): Bit
def !=(y: Float): Bit
def !=(y: Double): Bit
def %(y: FixPt[S,I,B0]): FixPt[S,I,B0]
def %(y: Int): FixPt[S,I,B0]
def %(y: Long): FixPt[S,I,B0]
def %(y: Float): FixPt[S,I,B0]
def %(y: Double): FixPt[S,I,B0]
def &(y: FixPt[S,I,F]): FixPt[S,I,F]
def &(y: Int): FixPt[S,I,F]
def &(y: Long): FixPt[S,I,F]
def &(y: Float): FixPt[S,I,F]
def &(y: Double): FixPt[S,I,F]
def *(y: FixPt[S,I,F]): FixPt[S,I,F]
def *(y: Int): FixPt[S,I,F]
def *(y: Long): FixPt[S,I,F]
def *(y: Float): FixPt[S,I,F]
def *(y: Double): FixPt[S,I,F]
def **(y: Int): FixPt[S,I,F]
def +(y: FixPt[S,I,F]): FixPt[S,I,F]
def +(y: Int): FixPt[S,I,F]
def +(y: Long): FixPt[S,I,F]
def +(y: Float): FixPt[S,I,F]
def +(y: Double): FixPt[S,I,F]
def -(y: FixPt[S,I,F]): FixPt[S,I,F]
def -(y: Int): FixPt[S,I,F]
def -(y: Long): FixPt[S,I,F]
def -(y: Float): FixPt[S,I,F]
def -(y: Double): FixPt[S,I,F]
def /(y: FixPt[S,I,F]): FixPt[S,I,F]
def /(y: Int): FixPt[S,I,F]
def /(y: Long): FixPt[S,I,F]
def /(y: Float): FixPt[S,I,F]
def /(y: Double): FixPt[S,I,F]
def ::(y: Index): Range
def <(y: FixPt[S,I,F]): Bit
def <(y: Int): Bit
def <(y: Long): Bit
def <(y: Float): Bit
def <(y: Double): Bit
def <<(y: FixPt[S,I,B0]): FixPt[S,I,F]
def <<(y: Int): FixPt[S,I,B0]
def <=(y: FixPt[S,I,F]): Bit
def <=(y: Int): Bit
def <=(y: Long): Bit
def <=(y: Float): Bit
def <=(y: Double): Bit
def >(y: FixPt[S,I,F]): Bit
def >(y: Int): Bit
def >(y: Long): Bit
def >(y: Float): Bit
def >(y: Double): Bit
def >=(y: FixPt[S,I,F]): Bit
def >=(y: Int): Bit
def >=(y: Long): Bit
def >=(y: Float): Bit
def >=(y: Double): Bit
def >>(y: FixPt[S,I,B0]): FixPt[S,I,F]
def >>(y: Int): FixPt[S,I,B0]
def by(y: Index): LoopRange
def mkString(): String
def to(): R
def toString(): String
def unary_-(): FixPt[S,I,F]
def until(y: Index): LoopRange
def |(y: FixPt[S,I,F]): FixPt[S,I,F]
def |(y: Int): FixPt[S,I,F]
def |(y: Long): FixPt[S,I,F]
def |(y: Float): FixPt[S,I,F]
def |(y: Double): FixPt[S,I,F]
FltPt¶
FltPt[G,E] represents an arbitrary precision, IEEE-754-like representation. FltPt values are always assumed to be signed.
The type parameters for FltPt are:
G | Number of significand bits, including sign bit | (B2 - B64) |
E | Number of exponent bits | (B1 - B64) |
Note that numbers of bits use the B- prefix as integers cannot be used as type parameters in Scala
Type Aliases¶
type | Half | FltPt[B11,B5] | IEEE-754 half precision |
type | Flt | FltPt[B24,B8] | IEEE-754 single precision |
type | Dbl | FltPt[B53,B11] | IEEE-754 double precision |
Infix methods¶
def !=(y: FltPt[G,E]): Bit
def !=(y: Int): Bit
def !=(y: Long): Bit
def !=(y: Float): Bit
def !=(y: Double): Bit
def *(y: FltPt[G,E]): FltPt[G,E]
def *(y: Int): FltPt[G,E]
def *(y: Long): FltPt[G,E]
def *(y: Float): FltPt[G,E]
def *(y: Double): FltPt[G,E]
def **(y: Int): FltPt[G,E]
def +(y: FltPt[G,E]): FltPt[G,E]
def +(y: Int): FltPt[G,E]
def +(y: Long): FltPt[G,E]
def +(y: Float): FltPt[G,E]
def +(y: Double): FltPt[G,E]
def -(y: FltPt[G,E]): FltPt[G,E]
def -(y: Int): FltPt[G,E]
def -(y: Long): FltPt[G,E]
def -(y: Float): FltPt[G,E]
def -(y: Double): FltPt[G,E]
def /(y: FltPt[G,E]): FltPt[G,E]
def /(y: Int): FltPt[G,E]
def /(y: Long): FltPt[G,E]
def /(y: Float): FltPt[G,E]
def /(y: Double): FltPt[G,E]
def <(y: FltPt[G,E]): Bit
def <(y: Int): Bit
def <(y: Long): Bit
def <(y: Float): Bit
def <(y: Double): Bit
def <=(y: FltPt[G,E]): Bit
def <=(y: Int): Bit
def <=(y: Long): Bit
def <=(y: Float): Bit
def <=(y: Double): Bit
def >(y: FltPt[G,E]): Bit
def >(y: Int): Bit
def >(y: Long): Bit
def >(y: Float): Bit
def >(y: Double): Bit
def >=(y: FltPt[G,E]): Bit
def >=(y: Int): Bit
def >=(y: Long): Bit
def >=(y: Float): Bit
def >=(y: Double): Bit
def mkString(): String
def to(): R
def toString(): String
def unary_-(): FltPt[G,E]
ForgeArray¶
<auto-generated stub>
Infix methods¶
def apply(i: Index): T
Returns the element at the given index
def flatten(): ForgeArray[T]
def length(): Index
Returns the length of this Array
def map(y: T => R): ForgeArray[R]
def mkString(y: String): String
def reduce(y: (T, T) => T)(implicit ev0: Coll[T]): T
def update(i: Index, x: T): Unit
Updates the array at the given index
def zip(y: ForgeArray[S])(z: (T, S) => R): ForgeArray[R]
def zipWithIndex(): ForgeArray[Tup2[T,:doc:Index <fixpt>]]
String¶
<auto-generated stub>
Infix methods¶
def contains(y: String): Boolean
def endsWith(y: String): Boolean
def fcharAt(y: Int): Char
def fsplit(y: String, numSplits: Int = 0): ForgeArray[String]
def getBytes(): ForgeArray[Byte]
def length(): Int
def replaceAllLiterally(y: String, z: String): String
def slice(y: Int, z: Int): String
def split(y: String, numSplits: Int = 0): ForgeArray[String]
def startsWith(y: String): Boolean
def substring(y: Int): String
def substring(y: Int, z: Int): String
def to(): R
def toBoolean(): Boolean
def toDouble(): Double
def toFloat(): Float
def toInt(): Int
def toLong(): Long
def toLowerCase(): String
def toUpperCase(): String
def trim(): String