Skip to content

Commit

Permalink
Bump Chisel version to 3.6.0
Browse files Browse the repository at this point in the history
* Remove deprecated API usage
* Disable parallel test execution due to bugs
* Update shadow.MuxLookup interface
* Enable '-Xfatal-warnings' compiler option
* Add Chisel version branches to CI & install firtool
  • Loading branch information
konda-x1 committed Jul 28, 2023
1 parent 4e69127 commit e14b122
Show file tree
Hide file tree
Showing 12 changed files with 150 additions and 149 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ on:
push:
branches:
- master
- 'chisel*.*'

pull_request:
branches:
- master
- 'chisel*.*'

permissions:
contents: read
Expand All @@ -18,6 +20,8 @@ env:
VERILATOR_REPO: https://github.com/verilator/verilator
VERILATOR_DIR: verilator
VERILATOR_VERSION_TAG: v4.228
FIRTOOL_VERSION: v1.37.0
FIRTOOL_VERSION_TAG: firtool-1.37.0

jobs:
test:
Expand All @@ -33,6 +37,10 @@ jobs:
java-version: ${{ env.JDK_VERSION }}
distribution: ${{ env.JDK_DIST }}
cache: 'sbt'
- name: Install firtool ${{ env.FIRTOOL_VERSION }}
run: |
wget -q -O - "https://github.com/llvm/circt/releases/download/${{ env.FIRTOOL_VERSION_TAG }}/firrtl-bin-ubuntu-20.04.tar.gz" | tar -zx
sudo mv "${{ env.FIRTOOL_VERSION_TAG }}/bin/firtool" /usr/local/bin
- name: "Cache: Verilator ${{ env.VERILATOR_VERSION_TAG }}"
uses: actions/cache@v3
id: install-cache
Expand Down
28 changes: 15 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,23 @@

## Introduction

This is an attempt to add the FixedPoint type to Chisel as a user-level library. The main motivation behind this is the deprecation of FixedPoint starting from [Chisel 3.6](https://github.com/chipsalliance/chisel/releases/v3.6.0), where Chisel is transitioning from Scala for Chisel compiler (SFC) to MLIR FIRRTL compiler. In this transition, FixedPoint [was dropped at the FIRRTL level](https://github.com/chipsalliance/chisel/issues/3161), meaning that FixedPoint would need to be re-implemented as something that depends on the remaining existing Chisel types, and by using Chisel's public API. This library aims to provide that user-level implementation.
This is an attempt to add the FixedPoint type to Chisel as a user-level library. The main motivation behind this is the deprecation of FixedPoint starting from [Chisel v3.6](https://github.com/chipsalliance/chisel/releases/v3.6.0), where Chisel is transitioning from Scala for Chisel compiler (SFC) to MLIR FIRRTL compiler. In this transition, FixedPoint [was dropped at the FIRRTL level](https://github.com/chipsalliance/chisel/issues/3161), meaning that FixedPoint would need to be re-implemented as something that depends on the remaining existing Chisel types, and by using Chisel's public API. This library aims to provide that user-level implementation.

The main goal of this library is to faithfully reproduce Chisel's established FixedPoint interface, so that existing code that depends on it can just replace Chisel's FixedPoint imports with this library's FixedPoint imports and have the code
work just as it did before. To that end, the following classes/traits have been (re)implemented:
* FixedPoint
* BinaryPoint, KnownBinaryPoint, UnknownBinaryPoint
* HasBinaryPoint

Currently, this library works with [Chisel v3.5.6](https://github.com/chipsalliance/chisel/releases/v3.5.6).
Currently, this library works with [Chisel v3.6.0](https://github.com/chipsalliance/chisel/releases/v3.6.0).

## Usage

Here is an example module using this library's FixedPoint type:

```scala
import chisel3.{fromDoubleToLiteral => _, fromIntToBinaryPoint => _, _}
import circt.stage.ChiselStage
import fixedpoint._

class Example extends Module {
Expand All @@ -30,29 +31,30 @@ class Example extends Module {
}

object ExampleApp extends App {
println(stage.ChiselStage.emitSystemVerilog(new Example))
println(ChiselStage.emitSystemVerilog(new Example))
}
```

This outputs the following SystemVerilog code:

```systemverilog
module Example(
input clock,
input reset,
input [7:0] in,
output [7:0] out1,
output [10:0] out2
// Generated by CIRCT firtool-1.37.0
module Example( // <stdin>:3:10
input clock, // <stdin>:4:11
reset, // <stdin>:5:11
input [7:0] in, // src/main/scala/Example.scala:6:14
output [7:0] out1, // src/main/scala/Example.scala:7:16
output [10:0] out2 // src/main/scala/Example.scala:8:16
);
wire [8:0] _out1_T = {$signed(in), 1'h0}; // @[Example.scala 9:8]
assign out1 = _out1_T[7:0]; // @[Example.scala 9:8]
assign out2 = 11'sh324; // @[Example.scala 10:22]
assign out1 = {in[6:0], 1'h0}; // <stdin>:3:10, src/main/scala/Example.scala:10:8
assign out2 = 11'h324; // <stdin>:3:10, src/main/scala/Example.scala:11:22
endmodule
```

## How It Works

FixedPoint is implemented as an extension of `Record`, which has one *anonymous* data field of type `SInt`; it is also an [opaque type](https://github.com/chipsalliance/chisel/blob/v3.5.6/core/src/main/scala/chisel3/experimental/OpaqueType.scala). Most of the arithmetic involving FixedPoints has been delegated to the `SInt` arithmetic of the underlying data field, where shift operations are first used to align the data of FixedPoints that have different binary points. Connect methods have also been overridden to account for data alignment of FixedPoints with different binary points, and to implement binary point inference.
FixedPoint is implemented as an extension of `Record`, which has one *anonymous* data field of type `SInt`; it is also an [opaque type](https://github.com/chipsalliance/chisel/blob/v3.6.0/core/src/main/scala/chisel3/experimental/OpaqueType.scala). Most of the arithmetic involving FixedPoints has been delegated to the `SInt` arithmetic of the underlying data field, where shift operations are first used to align the data of FixedPoints that have different binary points. Connect methods have also been overridden to account for data alignment of FixedPoints with different binary points, and to implement binary point inference.

## Limitations

Expand Down
8 changes: 5 additions & 3 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ scalacOptions ++= Seq(
"-encoding", "UTF-8",
"-feature",
"-unchecked",
// "-Xfatal-warnings",
"-Xfatal-warnings",
"-language:reflectiveCalls",
"-Ymacro-annotations"
)
val chiselVersion = "3.5.6"
val chiselVersion = "3.6.0"
addCompilerPlugin("edu.berkeley.cs" %% "chisel3-plugin" % chiselVersion cross CrossVersion.full)
libraryDependencies ++= Seq(
"edu.berkeley.cs" %% "chisel3" % chiselVersion,
"org.scalatest" %% "scalatest" % "3.2.10" % "test",
"org.scalatest" %% "scalatest" % "3.2.15" % "test",
"org.scalatestplus" %% "scalacheck-1-14" % "3.2.2.0" % "test",
)

Test / parallelExecution := false
26 changes: 13 additions & 13 deletions src/main/scala/fixedpoint/FixedPoint.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,18 @@ package fixedpoint

import chisel3.{fromDoubleToLiteral => _, fromIntToBinaryPoint => _, _}
import chisel3.experimental.BundleLiterals.AddBundleLiteralConstructor
import chisel3.experimental.{AutoCloneType, OpaqueType}
import chisel3.internal.firrtl.Width
import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform, SourceInfoWhiteboxTransform}
import chisel3.stage.ChiselStage
import fixedpoint.shadow.{Mux, Mux1H, MuxCase, MuxLookup, PriorityMux}
import chisel3.experimental.OpaqueType
import chisel3.internal.firrtl.{KnownWidth, UnknownWidth, Width}
import chisel3.experimental.SourceInfo
import chisel3.internal.sourceinfo.{SourceInfoTransform, SourceInfoWhiteboxTransform}

import scala.collection.immutable.SeqMap
import scala.language.experimental.macros

object FixedPoint extends NumObject {

/** Create a FixedPoint type with inferred width. */
def apply(): FixedPoint = apply(Width(), BinaryPoint())
def apply(): FixedPoint = apply(UnknownWidth(), BinaryPoint())

/** Create a FixedPoint type or port with fixed width. */
def apply(width: Width, binaryPoint: BinaryPoint): FixedPoint = new FixedPoint(width, binaryPoint)
Expand All @@ -43,17 +42,17 @@ object FixedPoint extends NumObject {
* Use PrivateObject to force users to specify width and binaryPoint by name
*/
def fromBigInt(value: BigInt, binaryPoint: BinaryPoint = 0.BP): FixedPoint = {
apply(value, Width(), binaryPoint)
apply(value, UnknownWidth(), binaryPoint)
}

/** Create a FixedPoint literal with inferred width from BigInt.
* Use PrivateObject to force users to specify width and binaryPoint by name
*/
def fromBigInt(value: BigInt, width: Int, binaryPoint: Int): FixedPoint =
if (width == -1) {
apply(value, Width(), BinaryPoint(binaryPoint))
apply(value, UnknownWidth(), BinaryPoint(binaryPoint))
} else {
apply(value, Width(width), BinaryPoint(binaryPoint))
apply(value, KnownWidth(width), BinaryPoint(binaryPoint))
}

/** Create a FixedPoint literal with inferred width from Double.
Expand Down Expand Up @@ -109,7 +108,7 @@ object FixedPoint extends NumObject {

private[fixedpoint] def recreateWidth[T <: Data](d: T): Width = d.widthOption match {
case Some(w) => w.W
case None => Width()
case None => UnknownWidth()
}

/** Align all FixedPoints in a (possibly heterogeneous) sequence by width and binary point
Expand Down Expand Up @@ -162,7 +161,7 @@ object FixedPoint extends NumObject {

implicit class fromDoubleToLiteral(double: Double) {
def F(binaryPoint: BinaryPoint): FixedPoint = {
FixedPoint.fromDouble(double, Width(), binaryPoint)
FixedPoint.fromDouble(double, UnknownWidth(), binaryPoint)
}

def F(width: Width, binaryPoint: BinaryPoint): FixedPoint = {
Expand All @@ -172,7 +171,7 @@ object FixedPoint extends NumObject {

implicit class fromBigDecimalToLiteral(bigDecimal: BigDecimal) {
def F(binaryPoint: BinaryPoint): FixedPoint = {
FixedPoint.fromBigDecimal(bigDecimal, Width(), binaryPoint)
FixedPoint.fromBigDecimal(bigDecimal, UnknownWidth(), binaryPoint)
}

def F(width: Width, binaryPoint: BinaryPoint): FixedPoint = {
Expand All @@ -187,7 +186,6 @@ object FixedPoint extends NumObject {

sealed class FixedPoint private[fixedpoint] (width: Width, private var _inferredBinaryPoint: BinaryPoint)
extends Record
with AutoCloneType
with OpaqueType
with Num[FixedPoint]
with HasBinaryPoint {
Expand All @@ -196,6 +194,8 @@ sealed class FixedPoint private[fixedpoint] (width: Width, private var _inferred

def binaryPoint: BinaryPoint = _inferredBinaryPoint

override def litValue: BigInt = data.litValue

private def requireKnownBP(message: => Any = "Unknown binary point is not supported in this operation"): Unit = {
require(_inferredBinaryPoint.isInstanceOf[KnownBinaryPoint], message)
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/fixedpoint/ForceElementwiseConnect.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
package fixedpoint

import chisel3.{ChiselException, CompileOptions, Data, DontCare, Record}
import chisel3.internal.sourceinfo.SourceInfo
import chisel3.experimental.SourceInfo

import scala.reflect.ClassTag

Expand Down
15 changes: 10 additions & 5 deletions src/main/scala/fixedpoint/shadow/MuxDefs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

package fixedpoint.shadow

import chisel3.{Bits, Bool, Data, SourceInfoDoc, UInt}
import chisel3.{Bits, Bool, Data, EnumType, SourceInfoDoc, UInt}

object Mux extends SourceInfoDoc {
def apply[T <: Data](cond: Bool, con: T, alt: T): T = {
Expand Down Expand Up @@ -39,7 +39,7 @@ object PriorityMux {
def apply[T <: Data](sel: Seq[Bool], in: Seq[T]): T = chisel3.util.PriorityMux(sel, Util.processArgs(in))
def apply[T <: Data](sel: Bits, in: Seq[T]): T = chisel3.util.PriorityMux(sel, in)
}
//

///** Creates a cascade of n Muxs to search for a key value.
// *
// * @example {{{
Expand All @@ -54,12 +54,17 @@ object MuxLookup {
* @param mapping a sequence to search of keys and values
* @return the value found or the default if not
*/
def apply[S <: UInt, T <: Data](key: S, default: T, mapping: Seq[(S, T)]): T = {
def apply[T <: Data](key: UInt, default: T)(mapping: Seq[(UInt, T)]): T = {
val (proc_default, proc_mapping) = Util.processArgs(default, mapping)
chisel3.util.MuxLookup(key, proc_default, proc_mapping)
chisel3.util.MuxLookup(key, proc_default)(proc_mapping)
}

def apply[S <: EnumType, T <: Data](key: S, default: T)(mapping: Seq[(S, T)]): T = {
val (proc_default, proc_mapping) = Util.processArgs(default, mapping)
chisel3.util.MuxLookup(key, proc_default)(proc_mapping)
}
}
//

///** Given an association of values to enable signals, returns the first value with an associated
// * high enable signal.
// *
Expand Down
Loading

0 comments on commit e14b122

Please sign in to comment.