├── website
├── .gitmodules
├── project
│ ├── build.properties
│ ├── plugins.sbt
│ ├── Version.scala
│ └── Contributors.scala
├── travis-deploy-key.enc
├── docs
│ └── src
│ │ └── main
│ │ ├── resources
│ │ ├── json
│ │ │ ├── README.md
│ │ │ ├── smem_rw.json
│ │ │ └── smem_read_write.json
│ │ ├── microsite
│ │ │ └── img
│ │ │ │ ├── navbar_brand.png
│ │ │ │ ├── second_icon.png
│ │ │ │ ├── third_icon.png
│ │ │ │ ├── third_icon2x.png
│ │ │ │ ├── navbar_brand2x.png
│ │ │ │ ├── second_icon2x.png
│ │ │ │ ├── sidebar_brand.png
│ │ │ │ ├── jumbotron_pattern.png
│ │ │ │ ├── sidebar_brand2x.png
│ │ │ │ └── jumbotron_pattern2x.png
│ │ └── svg
│ │ │ └── Makefile
│ │ └── tut
│ │ ├── api
│ │ ├── chisel3
│ │ │ ├── 3.5
│ │ │ │ ├── .index.md.swp
│ │ │ │ └── index.md
│ │ │ └── latest
│ │ │ │ ├── .index.md.swp
│ │ │ │ └── index.md
│ │ └── index.md
│ │ ├── chisel3
│ │ └── index.md
│ │ └── doc
│ │ └── chisel-cheatsheet3.pdf
│ │ └── index.md
├── scripts
│ └── decrypt-keys.sh
├── .gitignore
├── .mergify.yml
└── Makefile
├── project
├── build.properties
└── plugins.sbt
├── .github
├── CODEOWNERS
├── configs
│ └── mergify_config.yml
├── workflows
│ ├── install-circt
│ │ └── action.yml
│ ├── install-espresso
│ │ └── action.yml
│ └── setup-oss-cad-suite
│ │ └── action.yml
└── ISSUE_TEMPLATE
│ ├── feature-request.md
│ └── bug-report.md
├── lib
├── javabdd-1.0b2.jar
└── jhoafparser-1.1.1.jar
├── docs-target
└── src
│ └── main
│ ├── resources
│ └── META-INF
│ │ └── services
│ │ └── mdoc.PostModifier
│ └── scala
│ └── chisel3
│ └── docs
│ └── VerilogMdocModifier.scala
├── src
├── main
│ ├── resources
│ │ ├── META-INF
│ │ │ └── services
│ │ │ │ └── firrtl.options.RegisteredLibrary
│ │ └── chisel3
│ │ │ └── Makefile
│ └── scala
│ │ ├── chisel3
│ │ ├── testers
│ │ │ ├── package.scala
│ │ │ └── BasicTester.scala
│ │ ├── util
│ │ │ ├── experimental
│ │ │ │ ├── getAnnotations.scala
│ │ │ │ └── decode
│ │ │ │ │ ├── DecodeTableAnnotation.scala
│ │ │ │ │ └── Minimizer.scala
│ │ │ ├── util.scala
│ │ │ ├── ImplicitConversions.scala
│ │ │ ├── GrayCode.scala
│ │ │ ├── Enum.scala
│ │ │ ├── CircuitMath.scala
│ │ │ ├── circt
│ │ │ │ └── SizeOf.scala
│ │ │ └── Cat.scala
│ │ ├── stage
│ │ │ ├── ChiselCli.scala
│ │ │ ├── phases
│ │ │ │ ├── DriverCompatibility.scala
│ │ │ │ ├── MaybeInjectingPhase.scala
│ │ │ │ ├── MaybeAspectPhase.scala
│ │ │ │ ├── MaybeFirrtlStage.scala
│ │ │ │ ├── AddImplicitOutputFile.scala
│ │ │ │ ├── AddImplicitOutputAnnotationFile.scala
│ │ │ │ ├── AspectPhase.scala
│ │ │ │ ├── AddSerializationAnnotations.scala
│ │ │ │ └── Elaborate.scala
│ │ │ ├── ChiselPhase.scala
│ │ │ ├── ChiselOptions.scala
│ │ │ └── package.scala
│ │ ├── internal
│ │ │ └── firrtl
│ │ │ │ └── Emitter.scala
│ │ ├── aop
│ │ │ ├── inspecting
│ │ │ │ └── InspectingAspect.scala
│ │ │ └── injecting
│ │ │ │ └── InjectStatement.scala
│ │ ├── verilog.scala
│ │ └── experimental
│ │ │ └── util
│ │ │ └── algorithm
│ │ │ └── Bitwise.scala
│ │ └── circt
│ │ ├── Implicits.scala
│ │ ├── Intrinisic.scala
│ │ └── stage
│ │ ├── phases
│ │ ├── AddFIRRTLInputFile.scala
│ │ └── Checks.scala
│ │ ├── CIRCTOptions.scala
│ │ └── package.scala
└── test
│ ├── resources
│ └── chisel3
│ │ ├── sourceroot1
│ │ └── Foo
│ │ ├── sourceroot2
│ │ └── Foo
│ │ ├── AnalogBlackBox.v
│ │ ├── VerilogVendingMachine.v
│ │ └── BlackBoxTest.v
│ └── scala
│ ├── testCHA
│ ├── bus
│ │ ├── common
│ │ │ ├── PeripheralsMap.scala
│ │ │ └── Transaction.scala
│ │ ├── tilelink
│ │ │ ├── TilelinkOpcodes.scala
│ │ │ ├── StallUnit.scala
│ │ │ ├── TilelinkConfig.scala
│ │ │ └── Harness.scala
│ │ ├── native
│ │ │ ├── NativeConfig.scala
│ │ │ └── NativeBus.scala
│ │ ├── wishbone
│ │ │ ├── PeripheralMap.scala
│ │ │ ├── WishboneConfig.scala
│ │ │ └── WishboneErr.scala
│ │ └── SVAtest.scala
│ ├── counter
│ │ ├── CounterFormalSpec.scala
│ │ └── Counter.scala
│ ├── GCD
│ │ └── GCDFormalSpec.scala
│ └── chiselbook
│ │ ├── Fifo
│ │ └── FifoSpec.scala
│ │ ├── Combinational
│ │ └── CombinationalTest.scala
│ │ └── Adder
│ │ └── AdderTest.scala
│ ├── chiselTests
│ ├── RangeSpec.scala
│ ├── EnumSpec.scala
│ ├── SourceLocatorSpec.scala
│ ├── ModuleExplicitResetSpec.scala
│ ├── PopCount.scala
│ ├── Stop.scala
│ ├── IntegerMathSpec.scala
│ ├── CustomBundle.scala
│ ├── LiteralToTargetSpec.scala
│ ├── experimental
│ │ └── hierarchy
│ │ │ └── Utils.scala
│ ├── RebindingSpec.scala
│ ├── BitwiseOps.scala
│ ├── PortSpec.scala
│ ├── Clock.scala
│ ├── MulLookup.scala
│ ├── Padding.scala
│ ├── WarningSpec.scala
│ ├── WireSpec.scala
│ ├── ParameterizedModule.scala
│ ├── AdderTree.scala
│ ├── stage
│ │ ├── ChiselOptionsViewSpec.scala
│ │ └── phases
│ │ │ ├── ElaborateSpec.scala
│ │ │ ├── AddImplicitOutputAnnotationFileSpec.scala
│ │ │ └── AddImplicitOutputFileSpec.scala
│ ├── EnableShiftRegister.scala
│ ├── TesterDriverSpec.scala
│ ├── util
│ │ ├── PipeSpec.scala
│ │ ├── PriorityMuxSpec.scala
│ │ └── BitPatSpec.scala
│ ├── Math.scala
│ ├── ChiselTestUtilitiesSpec.scala
│ ├── InstanceNameSpec.scala
│ ├── ImplicitConversionsSpec.scala
│ ├── ComplexAssign.scala
│ ├── GCD.scala
│ ├── IOCompatibility.scala
│ ├── MemorySearch.scala
│ ├── SwitchSpec.scala
│ ├── DontTouchSpec.scala
│ ├── NamedModuleTester.scala
│ ├── BundleWire.scala
│ ├── Decoder.scala
│ ├── OptionBundle.scala
│ ├── ToTargetSpec.scala
│ └── Tbl.scala
│ ├── cookbook
│ ├── CookbookSpec.scala
│ ├── VecOfBool2UInt.scala
│ ├── Bundle2UInt.scala
│ ├── UInt2Bundle.scala
│ ├── UInt2VecOfBool.scala
│ ├── RegOfVec.scala
│ └── FSM.scala
│ ├── examples
│ ├── ImplicitStateVendingMachine.scala
│ └── VendingMachineUtils.scala
│ └── chisel3
│ └── testers
│ └── TestUtils.scala
├── docs
└── src
│ ├── images
│ ├── chisel_01.png
│ ├── chisel_logo.png
│ ├── type_hierarchy.png
│ ├── Makefile
│ └── type_hierarchy.dot
│ ├── developers
│ ├── developers.md
│ ├── scaladoc.md
│ └── test-coverage.md
│ ├── appendix
│ └── appendix.md
│ ├── explanations
│ ├── supported-hardware.md
│ ├── functional-abstraction.md
│ ├── source-locators.md
│ └── explanations.md
│ ├── cookbooks
│ └── cookbooks.md
│ └── resources
│ └── resources.md
├── .scala-steward.conf
├── Syntax and Semantics of Sequence and Property Formulas.pdf
├── plugin
└── src
│ └── main
│ └── resources
│ └── scalac-plugin.xml
├── .scalafix.conf
├── .gitmodules
├── .gitignore
├── integration-tests
└── src
│ └── test
│ └── scala
│ └── chiselTests
│ └── util
│ ├── experimental
│ ├── minimizer
│ │ ├── QMCSpec.scala
│ │ └── EspressoSpec.scala
│ ├── BitPat.scala
│ └── algorithm
│ │ └── Bitwise.scala
│ └── GrayCodeTests.scala
├── core
└── src
│ └── main
│ ├── scala-2.12
│ └── scala
│ │ └── collection
│ │ └── immutable
│ │ └── package.scala
│ └── scala
│ └── chisel3
│ ├── experimental
│ ├── hierarchy
│ │ ├── core
│ │ │ ├── Underlying.scala
│ │ │ ├── IsInstantiable.scala
│ │ │ ├── IsClone.scala
│ │ │ └── IsLookupable.scala
│ │ ├── InstantiableClone.scala
│ │ ├── LibraryHooks.scala
│ │ ├── DefinitionClone.scala
│ │ ├── InstanceClone.scala
│ │ └── package.scala
│ ├── OpaqueType.scala
│ └── Attach.scala
│ ├── BoolFactory.scala
│ ├── SIntFactory.scala
│ ├── ModuleAspect.scala
│ ├── internal
│ ├── SourceInfoMacro.scala
│ └── BuilderContextCache.scala
│ ├── dontTouch.scala
│ ├── aop
│ └── Aspect.scala
│ ├── UIntFactory.scala
│ ├── IO.scala
│ ├── Clock.scala
│ └── Mux.scala
├── .scalafmt.conf
├── root-doc.txt
├── AdderProp1.sv
└── macros
└── src
└── main
└── scala
└── chisel3
└── SourceInfoDoc.scala
/website/.gitmodules:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.8.2
2 |
--------------------------------------------------------------------------------
/website/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.3.2
2 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @freechipsproject/chisel-reviewers
2 |
--------------------------------------------------------------------------------
/website/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | addSbtPlugin("com.47deg" % "sbt-microsites" % "1.3.2")
2 |
--------------------------------------------------------------------------------
/lib/javabdd-1.0b2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/lib/javabdd-1.0b2.jar
--------------------------------------------------------------------------------
/docs-target/src/main/resources/META-INF/services/mdoc.PostModifier:
--------------------------------------------------------------------------------
1 | chisel3.docs.VerilogMdocModifier
2 |
--------------------------------------------------------------------------------
/lib/jhoafparser-1.1.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/lib/jhoafparser-1.1.1.jar
--------------------------------------------------------------------------------
/src/main/resources/META-INF/services/firrtl.options.RegisteredLibrary:
--------------------------------------------------------------------------------
1 | chisel3.aop.AspectLibrary
2 |
--------------------------------------------------------------------------------
/docs/src/images/chisel_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/docs/src/images/chisel_01.png
--------------------------------------------------------------------------------
/website/travis-deploy-key.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/website/travis-deploy-key.enc
--------------------------------------------------------------------------------
/docs/src/images/chisel_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/docs/src/images/chisel_logo.png
--------------------------------------------------------------------------------
/docs/src/images/type_hierarchy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/docs/src/images/type_hierarchy.png
--------------------------------------------------------------------------------
/website/docs/src/main/resources/json/README.md:
--------------------------------------------------------------------------------
1 | These files were used to generate the waveforms used in documentation.
2 |
--------------------------------------------------------------------------------
/src/test/resources/chisel3/sourceroot1/Foo:
--------------------------------------------------------------------------------
1 | This is a fake source file
2 | It is used to test errors with a caret
3 | I am the file in sourceroot1
4 |
--------------------------------------------------------------------------------
/src/test/resources/chisel3/sourceroot2/Foo:
--------------------------------------------------------------------------------
1 | This is a fake source file
2 | It is used to test errors with a caret
3 | I am the file in sourceroot2
4 |
--------------------------------------------------------------------------------
/website/docs/src/main/tut/api/chisel3/3.5/.index.md.swp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/website/docs/src/main/tut/api/chisel3/3.5/.index.md.swp
--------------------------------------------------------------------------------
/.scala-steward.conf:
--------------------------------------------------------------------------------
1 | updates.ignore = [ { groupId = "edu.berkeley.cs", artifactId = "firrtl" } ]
2 | pullRequests.frequency = "0 0 1 * *" # The first of every month
3 |
--------------------------------------------------------------------------------
/Syntax and Semantics of Sequence and Property Formulas.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/Syntax and Semantics of Sequence and Property Formulas.pdf
--------------------------------------------------------------------------------
/website/docs/src/main/tut/api/chisel3/latest/.index.md.swp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/website/docs/src/main/tut/api/chisel3/latest/.index.md.swp
--------------------------------------------------------------------------------
/plugin/src/main/resources/scalac-plugin.xml:
--------------------------------------------------------------------------------
1 |
2 | chiselplugin
3 | chisel3.internal.plugin.ChiselPlugin
4 |
5 |
--------------------------------------------------------------------------------
/website/docs/src/main/resources/microsite/img/navbar_brand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/website/docs/src/main/resources/microsite/img/navbar_brand.png
--------------------------------------------------------------------------------
/website/docs/src/main/resources/microsite/img/second_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/website/docs/src/main/resources/microsite/img/second_icon.png
--------------------------------------------------------------------------------
/website/docs/src/main/resources/microsite/img/third_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/website/docs/src/main/resources/microsite/img/third_icon.png
--------------------------------------------------------------------------------
/website/docs/src/main/resources/microsite/img/third_icon2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/website/docs/src/main/resources/microsite/img/third_icon2x.png
--------------------------------------------------------------------------------
/website/docs/src/main/resources/microsite/img/navbar_brand2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/website/docs/src/main/resources/microsite/img/navbar_brand2x.png
--------------------------------------------------------------------------------
/website/docs/src/main/resources/microsite/img/second_icon2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/website/docs/src/main/resources/microsite/img/second_icon2x.png
--------------------------------------------------------------------------------
/website/docs/src/main/resources/microsite/img/sidebar_brand.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/website/docs/src/main/resources/microsite/img/sidebar_brand.png
--------------------------------------------------------------------------------
/website/docs/src/main/resources/microsite/img/jumbotron_pattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/website/docs/src/main/resources/microsite/img/jumbotron_pattern.png
--------------------------------------------------------------------------------
/website/docs/src/main/resources/microsite/img/sidebar_brand2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/website/docs/src/main/resources/microsite/img/sidebar_brand2x.png
--------------------------------------------------------------------------------
/website/docs/src/main/resources/microsite/img/jumbotron_pattern2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/iscas-tis/CHA/HEAD/website/docs/src/main/resources/microsite/img/jumbotron_pattern2x.png
--------------------------------------------------------------------------------
/website/docs/src/main/tut/api/chisel3/latest/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | redirect_to: https://javadoc.io/doc/edu.berkeley.cs/chisel3_2.13
3 | redirect_from: /api/latest/index.html
4 | ---
5 |
6 |
--------------------------------------------------------------------------------
/website/docs/src/main/tut/chisel3/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: docs
3 | title: "Chisel3"
4 | section: "chisel3"
5 | position: 1
6 | redirect_to: /chisel3/docs/introduction.html
7 | ---
8 |
--------------------------------------------------------------------------------
/.github/configs/mergify_config.yml:
--------------------------------------------------------------------------------
1 | # Configuration for generating .mergify.yml
2 | conditions:
3 | - status-success=all tests passed
4 | branches:
5 | - 3.3.x
6 | - 3.4.x
7 | - 3.5.x
8 |
--------------------------------------------------------------------------------
/website/docs/src/main/tut/doc/chisel-cheatsheet3.pdf/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | redirect_to: https://github.com/freechipsproject/chisel-cheatsheet/releases/latest/download/chisel_cheatsheet.pdf
3 | ---
4 |
--------------------------------------------------------------------------------
/.scalafix.conf:
--------------------------------------------------------------------------------
1 | rules = [
2 | # DisableSyntax
3 | # ExplicitResultTypes
4 | #LeakingImplicitClassVal
5 | RemoveUnused
6 | #NoAutoTupling
7 | #NoValInForComprehension
8 | #ProcedureSyntax
9 | ]
10 |
11 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/testers/package.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3
4 |
5 | /** The testers package provides the basic interface for chisel testers.
6 | */
7 | package object testers {}
8 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/bus/common/PeripheralsMap.scala:
--------------------------------------------------------------------------------
1 | package caravan.bus.common
2 | import chisel3._
3 | import chisel3.ChiselEnum
4 |
5 | object Peripherals extends ChiselEnum {
6 | val GPIO = Value(0.U)
7 | val DCCM = Value(1.U)
8 | }
9 |
--------------------------------------------------------------------------------
/docs/src/images/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: all
2 |
3 | sources = \
4 | type_hierarchy.dot
5 |
6 | all: $(sources:%.dot=%.svg) $(sources:%.dot=%.png)
7 |
8 | %.svg: %.dot
9 | dot -Tsvg $< -o $@
10 |
11 | %.png: %.dot
12 | dot -Tpng $< -o $@
13 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/bus/tilelink/TilelinkOpcodes.scala:
--------------------------------------------------------------------------------
1 | package caravan.bus.tilelink
2 |
3 | trait OpCodes {
4 | val Get = 4
5 | val AccessAckData = 1
6 | val PutFullData = 0
7 | val PutPartialData = 1
8 | val AccessAck = 0
9 | }
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "firrtl"]
2 | path = firrtl
3 | url = https://github.com/log-when/firrtl.git
4 | branch = testCHA
5 | [submodule "chiseltest"]
6 | path = chiseltest
7 | url = https://github.com/log-when/chiseltest.git
8 | branch = testCHA
9 |
--------------------------------------------------------------------------------
/website/scripts/decrypt-keys.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | openssl aes-256-cbc -K $encrypted_5a031e7fc265_key -iv $encrypted_5a031e7fc265_iv -in travis-deploy-key.enc -out travis-deploy-key -d
4 | chmod 600 travis-deploy-key
5 | cp travis-deploy-key ~/.ssh/id_rsa
6 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/bus/native/NativeConfig.scala:
--------------------------------------------------------------------------------
1 | package caravan.bus.native
2 |
3 | import caravan.bus.common.BusConfig
4 |
5 | case class NativeConfig
6 | (
7 | addressWidth: Int,
8 | dataWidth: Int,
9 | byteLane: Int = 4
10 | ) extends BusConfig
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | out/
2 | generated/
3 | /lib/firrtl.jar
4 | .classpath
5 | .idea
6 | .idea_modules/
7 | .project
8 | target/
9 | *.iml
10 | *.swp
11 | *.fir
12 | *.v
13 | *.json
14 | test_run_dir
15 | *~
16 | \#*\#
17 | .\#*
18 | .metals
19 | .bloop
20 | metals.sbt
21 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/bus/wishbone/PeripheralMap.scala:
--------------------------------------------------------------------------------
1 | // package caravan.bus.wishbone
2 | // import chisel3._
3 | // import chisel3.experimental.ChiselEnum
4 |
5 | // object Peripherals extends ChiselEnum {
6 | // val GPIO = Value(0.U)
7 | // val DCCM = Value(1.U)
8 | // }
9 |
--------------------------------------------------------------------------------
/website/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | *#*#
3 |
4 | target
5 | project/target
6 | build
7 | docs/src/main/tut/chisel3/docs/
8 |
9 | travis-deploy-key
10 | travis-deploy-key.pub
11 |
12 | test_run_dir
13 | *.anno.json
14 | *.v
15 | *.fir
16 | *.DS_STORE
17 | .idea
18 |
19 | docs/src/main/tut/contributors.md
20 |
--------------------------------------------------------------------------------
/website/docs/src/main/tut/api/chisel3/3.5/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | redirect_to: https://javadoc.io/doc/edu.berkeley.cs/chisel3_2.13/3.5
3 | redirect_from:
4 | - /api/3.5/index.html
5 | - /api/3.5.3/index.html
6 | - /api/3.5.2/index.html
7 | - /api/3.5.1/index.html
8 | - /api/3.5.0/index.html
9 | ---
10 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/util/experimental/getAnnotations.scala:
--------------------------------------------------------------------------------
1 | package chisel3.util.experimental
2 |
3 | import chisel3.internal.Builder
4 | import firrtl.AnnotationSeq
5 |
6 | object getAnnotations {
7 |
8 | /** Returns the global Annotations */
9 | def apply(): AnnotationSeq = Builder.annotationSeq
10 | }
11 |
--------------------------------------------------------------------------------
/docs/src/developers/developers.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: docs
3 | title: "Developers"
4 | section: "chisel3"
5 | ---
6 |
7 | # Developer Documentation
8 |
9 | Tips and tricks for Chisel developers:
10 |
11 | * [Embedding Chisel as an sbt subproject](sbt-subproject)
12 | * [Test Coverage](test-coverage)
13 | * [Developers Style Guide](style)
14 |
--------------------------------------------------------------------------------
/website/docs/src/main/tut/api/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: docs
3 | title: "Chisel API Documentation"
4 | section: "chisel3"
5 | ---
6 |
7 | ## Chisel API Documentation
8 |
9 | Please see the page about [Versioning](../chisel3/docs/appendix/versioning.html) for more information about major and minor versioning and binary compatibility.
10 |
11 | * [latest](latest)
12 | * [3.5](3.5/)
13 |
14 |
15 |
--------------------------------------------------------------------------------
/integration-tests/src/test/scala/chiselTests/util/experimental/minimizer/QMCSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests.util.experimental.minimizer
4 | import chisel3.util.experimental.decode.Minimizer
5 | import chisel3.util.experimental.decode.QMCMinimizer
6 |
7 | class QMCSpec extends MinimizerSpec {
8 | override def minimizer: Minimizer = QMCMinimizer
9 | }
10 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/RangeSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.experimental.ChiselRange
7 | import chisel3.internal.firrtl._
8 | import firrtl.ir.{Closed, Open}
9 | import org.scalatest.freespec.AnyFreeSpec
10 | import org.scalatest.matchers.should.Matchers
11 |
12 | class RangeSpec extends AnyFreeSpec with Matchers {}
13 |
--------------------------------------------------------------------------------
/integration-tests/src/test/scala/chiselTests/util/experimental/minimizer/EspressoSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests.util.experimental.minimizer
4 | import chisel3.util.experimental.decode.EspressoMinimizer
5 | import chisel3.util.experimental.decode.Minimizer
6 |
7 | class EspressoSpec extends MinimizerSpec {
8 | override def minimizer: Minimizer = EspressoMinimizer
9 | }
10 |
--------------------------------------------------------------------------------
/core/src/main/scala-2.12/scala/collection/immutable/package.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package scala.collection
4 |
5 | import scala.collection.immutable.ListMap
6 |
7 | package object immutable {
8 | val SeqMap = ListMap
9 | type SeqMap[K, +V] = ListMap[K, V]
10 |
11 | val VectorMap = ListMap
12 | type VectorMap[K, +V] = ListMap[K, V]
13 |
14 | val LazyList = Stream
15 | type LazyList[+A] = Stream[A]
16 | }
17 |
--------------------------------------------------------------------------------
/docs/src/appendix/appendix.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: docs
3 | title: "Appendix"
4 | section: "chisel3"
5 | ---
6 |
7 | # Appendix
8 |
9 | This section covers some less-common Chisel topics.
10 |
11 | * [Differences between Chisel3 and Chisel2](chisel3-vs-chisel2)
12 | * [Experimental Features](experimental-features)
13 | * [Upgrading from Scala 2.11](upgrading-from-scala-2-11)
14 | * [Upgrading from Chisel 3.4](upgrading-from-chisel-3-4)
15 | * [Versioning](versioning)
16 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/util/util.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3
4 |
5 | /** The util package provides extensions to core chisel for common hardware components and utility
6 | * functions
7 | */
8 | package object util {
9 |
10 | /** Synonyms, moved from main package object - maintain scope. */
11 | type ValidIO[+T <: Data] = chisel3.util.Valid[T]
12 | val ValidIO = chisel3.util.Valid
13 | val DecoupledIO = chisel3.util.Decoupled
14 | }
15 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/experimental/hierarchy/core/Underlying.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.experimental.hierarchy.core
4 |
5 | /** Represents the underlying implementation of a Definition or Instance */
6 | sealed trait Underlying[+T]
7 |
8 | /** A clone of a real implementation */
9 | final case class Clone[+T](isClone: IsClone[T]) extends Underlying[T]
10 |
11 | /** An actual implementation */
12 | final case class Proto[+T](proto: T) extends Underlying[T]
13 |
--------------------------------------------------------------------------------
/website/.mergify.yml:
--------------------------------------------------------------------------------
1 | queue_rules:
2 | - name: default
3 | conditions:
4 | - status-success=all tests passed
5 | pull_request_rules:
6 | - name: Automatic merge for Dependabot
7 | conditions:
8 | - author~=^dependabot(|-preview)\[bot\]$
9 | - status-success=all tests passed
10 | - '#changes-requested-reviews-by=0'
11 | - label!="DO NOT MERGE"
12 | actions:
13 | queue:
14 | name: default
15 | method: squash
16 | update_method: merge
17 |
--------------------------------------------------------------------------------
/src/main/scala/circt/Implicits.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package circt
4 |
5 | /** A collection of implicit classes to provide additional methods to existing types */
6 | object Implicits {
7 |
8 | /** Helpers for working with Boolean */
9 | implicit class BooleanImplicits(a: Boolean) {
10 |
11 | /** Construct an Option from a Boolean. */
12 | def option[A](b: => A): Option[A] =
13 | if (a)
14 | Some(b)
15 | else
16 | None
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/EnumSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.util.Enum
7 | import chisel3.testers.BasicTester
8 |
9 | class EnumSpec extends ChiselFlatSpec {
10 |
11 | "1-entry Enums" should "work" in {
12 | assertTesterPasses(new BasicTester {
13 | val onlyState :: Nil = Enum(1)
14 | val wire = WireDefault(onlyState)
15 | chisel3.assert(wire === onlyState)
16 | stop()
17 | })
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/docs/src/explanations/supported-hardware.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: docs
3 | title: "Supported Hardware"
4 | section: "chisel3"
5 | ---
6 |
7 | # Supported Hardware
8 |
9 | While Chisel focuses on binary logic, Chisel can support analog and tri-state wires with the `Analog` type - see [Datatypes in Chisel](data-types).
10 |
11 | We focus on binary logic designs as they constitute the vast majority of designs in practice. Tri-state logic are poorly supported standard industry flows and require special/controlled hard macros in order to be done.
12 |
--------------------------------------------------------------------------------
/docs/src/developers/scaladoc.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: docs
3 | title: "Scaladoc"
4 | section: "chisel3"
5 | ---
6 |
7 | ## Scaladoc
8 |
9 | We write inline documentation of code and public APIs using ScalaDoc.
10 |
11 | When creating a new feature, you can view the documentation you've written by building the ScalaDoc locally with sbt:
12 |
13 | ```
14 | sbt:chisel3> doc
15 | ```
16 |
17 | This will build the documentation in `target/scala-2.12/unidoc` or `target/scala-2.13/unidoc`, and you can view it by opening `unidoc/index.html` in your browser.
18 |
--------------------------------------------------------------------------------
/src/main/scala/circt/Intrinisic.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /** This has to be in a separate file and package to generate the correct class
4 | * in the annotation. This is supper annoying.
5 | */
6 |
7 | package circt
8 |
9 | import firrtl.annotations.SingleTargetAnnotation
10 | import firrtl.annotations.ModuleTarget
11 |
12 | case class Intrinsic(target: ModuleTarget, intrinsic: String) extends SingleTargetAnnotation[ModuleTarget] {
13 | def duplicate(newTarget: ModuleTarget) = this.copy(target = newTarget)
14 | }
15 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/experimental/hierarchy/InstantiableClone.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.experimental.hierarchy
4 |
5 | import chisel3.experimental.BaseModule
6 |
7 | /** @note If we are cloning a non-module, we need another object which has the proper _parent set!
8 | */
9 | trait InstantiableClone[T <: IsInstantiable] extends core.IsClone[T] {
10 | private[chisel3] def _innerContext: Hierarchy[_]
11 | private[chisel3] def getInnerContext: Option[BaseModule] = _innerContext.getInnerDataContext
12 | }
13 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/BoolFactory.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3
4 |
5 | import chisel3.internal.firrtl.{ULit, Width}
6 |
7 | trait BoolFactory {
8 |
9 | /** Creates an empty Bool.
10 | */
11 | def apply(): Bool = new Bool()
12 |
13 | /** Creates Bool literal.
14 | */
15 | protected[chisel3] def Lit(x: Boolean): Bool = {
16 | val result = new Bool()
17 | val lit = ULit(if (x) 1 else 0, Width(1))
18 | // Ensure we have something capable of generating a name.
19 | lit.bindLitArg(result)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/bus/wishbone/WishboneConfig.scala:
--------------------------------------------------------------------------------
1 | package caravan.bus.wishbone
2 |
3 | import caravan.bus.common.BusConfig
4 |
5 | // no tag support
6 | case class WishboneConfig
7 | (
8 | /**
9 | * addressWidth: the address width in bits
10 | * dataWidth: the data width in bits
11 | * granularity: the minimal data transfer size over the bus
12 | * waitState: whether the host can produce wait states during the bus transfer cycle
13 | */
14 | addressWidth: Int,
15 | dataWidth: Int,
16 | granularity: Int = 8,
17 | waitState: Boolean = false
18 | ) extends BusConfig
19 |
20 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/SourceLocatorSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 |
7 | class SourceLocatorSpec extends ChiselFunSpec with Utils {
8 | describe("(0) Relative source paths") {
9 | it("(0.a): are emitted by default relative to `user-dir`") {
10 | class Top extends Module {
11 | val w = WireInit(UInt(1.W), 0.U)
12 | }
13 | val chirrtl = circt.stage.ChiselStage.emitCHIRRTL(new Top)
14 | chirrtl should include("@[src/test/scala/chiselTests/SourceLocatorSpec.scala")
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/website/docs/src/main/resources/json/smem_rw.json:
--------------------------------------------------------------------------------
1 |
2 | {
3 | signal: [
4 | ['in',
5 | {name: 'clk', wave: 'p......'},
6 | {name: 'addr', wave: 'x=x.=x.', data:['waddr','raddr'], phase: 0.5},
7 | {name: 'en', wave: '010.10.', phase: 0.5},
8 | {name: 'wmode', wave: '010....', phase: 0.5},
9 | {name: 'wdata', wave: 'x=x....', data:['wdata'], phase: 0.5},
10 | {name: 'wmask', wave: 'x=x....', data:['wmask'], phase: 0.5},
11 | ],
12 | ['out',
13 | {name: 'rdata', wave: 'x....=x', data:['rdata'], phase: 0.5},
14 | ]
15 | ],
16 | head:{
17 | tick:0,
18 | },
19 | config: { hscale: 2 }
20 | }
21 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/experimental/hierarchy/core/IsInstantiable.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.experimental.hierarchy.core
4 |
5 | /** While this is public, it is not recommended for users to extend directly.
6 | * Instead, use the [[instantiable]] annotation on your trait or class.
7 | *
8 | * This trait indicates whether a class can be returned from an Instance.
9 | */
10 | trait IsInstantiable
11 |
12 | object IsInstantiable {
13 | implicit class IsInstantiableExtensions[T <: IsInstantiable](i: T) {
14 | def toInstance: Instance[T] = new Instance(Proto(i))
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/website/docs/src/main/resources/json/smem_read_write.json:
--------------------------------------------------------------------------------
1 | {
2 | signal: [
3 | ['in',
4 | {name: 'clk', wave: 'p......'},
5 | {name: 'waddr', wave: 'x=x....', data:['waddr'], phase: 0.5},
6 | {name: 'raddr', wave: 'x...=x.', data:['raddr'], phase: 0.5},
7 | {name: 'en', wave: '010.10.', phase: 0.5},
8 | {name: 'wdata', wave: 'x=x....', data:['wdata'], phase: 0.5},
9 | {name: 'wmask', wave: 'x=x....', data:['wmask'], phase: 0.5},
10 | ],
11 | ['out',
12 | {name: 'rdata', wave: 'x....=x', data:['rdata'], phase: 0.5},
13 | ]
14 | ],
15 | head:{
16 | tick:0,
17 | },
18 | config: { hscale: 2 }
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/src/test/resources/chisel3/AnalogBlackBox.v:
--------------------------------------------------------------------------------
1 |
2 | module AnalogReaderBlackBox(
3 | inout [31:0] bus,
4 | output [31:0] out
5 | );
6 | assign bus = 32'dz;
7 | assign out = bus;
8 | endmodule
9 |
10 | module AnalogWriterBlackBox(
11 | inout [31:0] bus,
12 | input [31:0] in
13 | );
14 | assign bus = in;
15 | endmodule
16 |
17 | module AnalogBlackBox #(
18 | parameter index=0
19 | ) (
20 | inout [31:0] bus,
21 | input port_0_in_valid,
22 | input [31:0] port_0_in_bits,
23 | output [31:0] port_0_out
24 | );
25 | assign port_0_out = bus;
26 | assign bus = (port_0_in_valid)? port_0_in_bits + index : 32'dZ;
27 | endmodule
28 |
--------------------------------------------------------------------------------
/docs/src/cookbooks/cookbooks.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: docs
3 | title: "Cookbooks"
4 | section: "chisel3"
5 | ---
6 |
7 | # Cookbooks
8 |
9 | Welcome to the Chisel Cookbooks, where we capture frequently-used design patterns or troubleshooting questions.
10 | If you have any requests or examples to share,
11 | please [file an issue](https://github.com/chipsalliance/chisel3/issues/new) and let us know!
12 |
13 | * [General Cookbooks](cookbook)
14 | * [Verilog vs. Chisel Side-by-Side](verilog-vs-chisel)
15 | * [Naming Cookbook](naming)
16 | * [Troubleshooting Guide](troubleshooting)
17 | * [Hierarchy Cookbook](hierarchy)
18 | * [DataView Cookbook](dataview)
19 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/util/ImplicitConversions.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.util
4 |
5 | import chisel3._
6 |
7 | import scala.language.implicitConversions
8 |
9 | /** Implicit conversions to automatically convert [[scala.Boolean]] and [[scala.Int]] to [[Bool]]
10 | * and [[UInt]] respectively
11 | */
12 | object ImplicitConversions {
13 | // The explicit fromIntToLiteral resolves an ambiguous conversion between fromIntToLiteral and
14 | // UInt.asUInt.
15 | implicit def intToUInt(x: Int): UInt = chisel3.fromIntToLiteral(x).asUInt
16 | implicit def booleanToBool(x: Boolean): Bool = x.B
17 | }
18 |
--------------------------------------------------------------------------------
/.scalafmt.conf:
--------------------------------------------------------------------------------
1 | version = 2.6.4
2 |
3 | maxColumn = 120
4 | align = most
5 | continuationIndent.defnSite = 2
6 | assumeStandardLibraryStripMargin = true
7 | docstrings = ScalaDoc
8 | lineEndings = preserve
9 | includeCurlyBraceInSelectChains = false
10 | danglingParentheses = true
11 |
12 | align.tokens.add = [
13 | {
14 | code = ":"
15 | }
16 | ]
17 |
18 | newlines.alwaysBeforeCurlyBraceLambdaParams = false
19 | newlines.alwaysBeforeMultilineDef = false
20 | newlines.implicitParamListModifierForce = [before]
21 |
22 | verticalMultiline.atDefnSite = true
23 |
24 | optIn.annotationNewlines = true
25 |
26 | rewrite.rules = [SortImports, PreferCurlyFors, AvoidInfix]
27 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/stage/ChiselCli.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.stage
4 |
5 | import firrtl.options.Shell
6 | import scala.annotation.nowarn
7 |
8 | @nowarn("cat=deprecation&msg=WarnReflectiveNamingAnnotation")
9 | trait ChiselCli { this: Shell =>
10 | parser.note("Chisel Front End Options")
11 | Seq(
12 | NoRunFirrtlCompilerAnnotation,
13 | PrintFullStackTraceAnnotation,
14 | ThrowOnFirstErrorAnnotation,
15 | WarningsAsErrorsAnnotation,
16 | SourceRootAnnotation,
17 | WarnReflectiveNamingAnnotation,
18 | ChiselOutputFileAnnotation,
19 | ChiselGeneratorAnnotation
20 | )
21 | .foreach(_.addOptions(parser))
22 | }
23 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/bus/native/NativeBus.scala:
--------------------------------------------------------------------------------
1 | package caravan.bus.native
2 |
3 | import caravan.bus.common.{AbstrRequest, AbstrResponse}
4 | import chisel3._
5 |
6 | class NativeRequest(implicit val config: NativeConfig) extends AbstrRequest {
7 | override val addrRequest: UInt = UInt(config.addressWidth.W)
8 | override val dataRequest: UInt = UInt(config.dataWidth.W)
9 | override val activeByteLane: UInt = UInt(config.byteLane.W)
10 | override val isWrite: Bool = Bool()
11 | }
12 |
13 | class NativeResponse(implicit val config: NativeConfig) extends AbstrResponse {
14 | override val dataResponse: UInt = UInt(config.dataWidth.W)
15 | override val error: Bool = Bool()
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/stage/phases/DriverCompatibility.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.stage.phases
4 |
5 | import firrtl.annotations.Annotation
6 | import firrtl.options.Phase
7 |
8 | /** This formerly provided components of a compatibility wrapper around Chisel's removed `chisel3.Driver`.
9 | *
10 | * This object formerly included [[firrtl.options.Phase Phase]]s that generate [[firrtl.annotations.Annotation]]s
11 | * derived from the deprecated `firrtl.stage.phases.DriverCompatibility.TopNameAnnotation`.
12 | */
13 | @deprecated("This object contains no public members. This will be removed in Chisel 3.6.", "Chisel 3.5")
14 | object DriverCompatibility
15 |
--------------------------------------------------------------------------------
/src/test/scala/cookbook/CookbookSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package cookbook
4 |
5 | import chisel3._
6 | import chisel3.util._
7 | import chisel3.testers.BasicTester
8 |
9 | import chiselTests.ChiselFlatSpec
10 |
11 | /** Tester for concise cookbook tests
12 | *
13 | * Provides a length of test after which the test will pass
14 | */
15 | abstract class CookbookTester(length: Int) extends BasicTester {
16 | require(length >= 0, "Simulation length must be non-negative!")
17 |
18 | val (cycle, done) = Counter(true.B, length + 1) // + 1 cycle because done is actually wrap
19 | when(done) { stop() }
20 | }
21 |
22 | abstract class CookbookSpec extends ChiselFlatSpec
23 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/util/GrayCode.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.util
4 |
5 | import chisel3._
6 |
7 | object BinaryToGray {
8 |
9 | /** Turns a binary number into gray code. */
10 | def apply(in: UInt): UInt = in ^ (in >> 1)
11 | }
12 |
13 | object GrayToBinary {
14 |
15 | /** Inverts the [[BinaryToGray]] operation. */
16 | def apply(in: UInt, width: Int): UInt = apply(in(width - 1, 0))
17 |
18 | /** Inverts the [[BinaryToGray]] operation. */
19 | def apply(in: UInt): UInt = if (in.getWidth < 2) { in }
20 | else {
21 | val bits = in.getWidth - 2 to 0 by -1
22 | Cat(bits.scanLeft(in.head(1)) { case (prev, ii) => prev ^ in(ii) })
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/website/project/Version.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE for license details.
2 |
3 | object Version {
4 |
5 | sealed trait Branch { def serialize: String }
6 |
7 | case class SemanticVersion(major: Int, minor: Int, patch: Int) extends Branch {
8 | def serialize: String = s"v$major.$minor.$patch"
9 | }
10 |
11 | case object Master extends Branch {
12 | def serialize: String = "master"
13 | }
14 |
15 | sealed trait Repository {
16 | def serialize: String
17 | def url: String
18 | }
19 |
20 | case class GitHubRepository(owner: String, repo: String) extends Repository {
21 | def serialize: String = s"github.com:$owner/$repo"
22 | def url: String = s"https://$serialize"
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/scala/cookbook/VecOfBool2UInt.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package cookbook
4 |
5 | import chisel3._
6 |
7 | /* ### How do I create a UInt from a Vec of Bool?
8 | *
9 | * Use the builtin function asUInt
10 | */
11 | class VecOfBool2UInt extends CookbookTester(1) {
12 | // Example
13 | val vec = VecInit(true.B, false.B, true.B, true.B)
14 | val uint = vec.asUInt
15 | printf(p"$uint") // 13
16 |
17 | /* Test
18 | *
19 | * (remember leftmost Bool in Vec is low order bit)
20 | */
21 | assert(0xd.U === uint)
22 | }
23 |
24 | class VecOfBool2UIntSpec extends CookbookSpec {
25 | "VecOfBool2UInt" should "work" in {
26 | assertTesterPasses { new VecOfBool2UInt }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/.github/workflows/install-circt/action.yml:
--------------------------------------------------------------------------------
1 | name: Install CIRCT
2 |
3 | inputs:
4 | version:
5 | description: 'version to install'
6 | required: false
7 | default: 'firtool-1.31.0'
8 |
9 | runs:
10 | using: composite
11 | steps:
12 | - id: cache-circt
13 | uses: actions/cache@v3
14 | with:
15 | path: circt
16 | key: circt-${{ runner.os }}-${{ inputs.version }}
17 |
18 | - shell: bash
19 | if: steps.cache-circt.outputs.cache-hit != 'true'
20 | run: |
21 | mkdir circt
22 | wget -q -O - https://github.com/llvm/circt/releases/download/${{ inputs.version }}/circt-bin-ubuntu-20.04.tar.gz | tar -zx -C circt/
23 |
24 | - shell: bash
25 | run: echo "$(pwd)/circt/bin" >> $GITHUB_PATH
26 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/ModuleExplicitResetSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import circt.stage.ChiselStage
6 |
7 | import scala.annotation.nowarn
8 |
9 | @nowarn("msg=Chisel compatibility mode is deprecated")
10 | class ModuleExplicitResetSpec extends ChiselFlatSpec {
11 |
12 | "A Module with an explicit reset in compatibility mode" should "elaborate" in {
13 | import Chisel._
14 | val myReset = true.B
15 | class ModuleExplicitReset(reset: Bool) extends Module(_reset = reset) {
16 | val io = new Bundle {
17 | val done = Bool(OUTPUT)
18 | }
19 |
20 | io.done := false.B
21 | }
22 |
23 | ChiselStage.elaborate {
24 | new ModuleExplicitReset(myReset)
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/bus/tilelink/StallUnit.scala:
--------------------------------------------------------------------------------
1 | package caravan.bus.tilelink
2 |
3 | import chisel3._
4 |
5 | // Module to Stall the Response one Cycle
6 |
7 | class stallUnit extends Module {
8 |
9 | implicit val config = TilelinkConfig()
10 |
11 | val io = IO(new Bundle{
12 | val bundle_in = Input(new TilelinkSlave)
13 | val valid_in = Input(UInt(1.W))
14 | val bundle_out = Output(new TilelinkSlave)
15 | val valid_out = Output(UInt(1.W))
16 | })
17 |
18 |
19 |
20 | val bundle_reg = RegInit(0.U.asTypeOf(new TilelinkSlave))
21 | val valid_reg = RegInit(0.U(1.W))
22 |
23 | bundle_reg := io.bundle_in
24 | valid_reg := io.valid_in
25 |
26 | io.bundle_out := bundle_reg
27 | io.valid_out := valid_reg
28 | }
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/PopCount.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.util.PopCount
7 | import chisel3.testers.BasicTester
8 |
9 | class PopCountTester(n: Int) extends BasicTester {
10 | val x = RegInit(0.U(n.W))
11 | x := x + 1.U
12 | when(RegNext(x === ~0.U(n.W))) { stop() }
13 |
14 | val result = PopCount(x.asBools)
15 | val expected = x.asBools.foldLeft(0.U)(_ +& _)
16 | assert(result === expected)
17 |
18 | require(result.getWidth == BigInt(n).bitLength)
19 | }
20 |
21 | class PopCountSpec extends ChiselPropSpec {
22 | property("Mul lookup table should return the correct result") {
23 | forAll(smallPosInts) { (n: Int) => assertTesterPasses { new PopCountTester(n) } }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/test/scala/cookbook/Bundle2UInt.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package cookbook
4 |
5 | import chisel3._
6 |
7 | /* ### How do I create a UInt from an instance of a Bundle?
8 | *
9 | * Call asUInt on the Bundle instance
10 | */
11 | class Bundle2UInt extends CookbookTester(1) {
12 | // Example
13 | class MyBundle extends Bundle {
14 | val foo = UInt(4.W)
15 | val bar = UInt(4.W)
16 | }
17 | val bundle = Wire(new MyBundle)
18 | bundle.foo := 0xc.U
19 | bundle.bar := 0x3.U
20 | val uint = bundle.asUInt
21 | printf(p"$uint") // 195
22 |
23 | // Test
24 | assert(uint === 0xc3.U)
25 | }
26 |
27 | class Bundle2UIntSpec extends CookbookSpec {
28 | "Bundle2UInt" should "work" in {
29 | assertTesterPasses { new Bundle2UInt }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/Stop.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.testers.BasicTester
7 |
8 | class StopTester() extends BasicTester {
9 | stop()
10 | }
11 |
12 | class StopImmediatelyTester extends BasicTester {
13 | val cycle = RegInit(0.asUInt(4.W))
14 | cycle := cycle + 1.U
15 | when(cycle === 4.U) {
16 | stop()
17 | }
18 | assert(cycle =/= 5.U, "Simulation did not exit upon executing stop()")
19 | }
20 |
21 | class StopSpec extends ChiselFlatSpec {
22 | "stop()" should "stop and succeed the testbench" in {
23 | assertTesterPasses { new StopTester }
24 | }
25 |
26 | it should "end the simulation immediately" in {
27 | assertTesterPasses { new StopImmediatelyTester }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/stage/phases/MaybeInjectingPhase.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.stage.phases
4 |
5 | import chisel3.aop.injecting.{InjectStatement, InjectingPhase}
6 | import firrtl.AnnotationSeq
7 | import firrtl.options.Phase
8 |
9 | /** Run `InjectingPhase` if a `InjectStatement` is present.
10 | */
11 | class MaybeInjectingPhase extends Phase {
12 | override def prerequisites = Seq.empty
13 | override def optionalPrerequisites = Seq.empty
14 | override def optionalPrerequisiteOf = Seq.empty
15 | override def invalidates(a: Phase) = false
16 | def transform(annotations: AnnotationSeq): AnnotationSeq = annotations.collectFirst {
17 | case _: InjectStatement => new InjectingPhase().transform(annotations)
18 | }.getOrElse(annotations)
19 | }
20 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/IntegerMathSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.testers.BasicTester
7 |
8 | class IntegerMathTester extends BasicTester {
9 |
10 | //TODO: Add more operators
11 |
12 | /* absolute values tests */
13 |
14 | val uint = 3.U(4.W)
15 | val sint = (-3).S
16 | val sintpos = 3.S
17 | val wrongSIntPos = 4.S
18 |
19 | assert(uint.abs === uint)
20 | assert(sint.abs === sintpos)
21 | assert(sintpos.abs === sintpos)
22 |
23 | assert(sint.abs =/= wrongSIntPos)
24 |
25 | stop()
26 | }
27 |
28 | class IntegerMathSpec extends ChiselPropSpec {
29 | property("All integer ops should return the correct result") {
30 | assertTesterPasses { new IntegerMathTester }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/.github/workflows/install-espresso/action.yml:
--------------------------------------------------------------------------------
1 | name: Install Espresso
2 |
3 | inputs:
4 | version:
5 | description: 'version to install'
6 | required: false
7 | default: '2.4'
8 |
9 | runs:
10 | using: composite
11 | steps:
12 | - id: cache-espresso
13 | uses: actions/cache@v3
14 | with:
15 | path: /usr/local/bin/espresso
16 | key: espresso-${{ runner.os }}-${{ inputs.version }}
17 |
18 | - shell: bash
19 | if: steps.cache-espresso.outputs.cache-hit != 'true'
20 | run: |
21 | cd /tmp
22 | wget -q https://github.com/chipsalliance/espresso/releases/download/v${{ inputs.version }}/x86_64-linux-gnu-espresso
23 | chmod +x x86_64-linux-gnu-espresso
24 | sudo mv x86_64-linux-gnu-espresso /usr/local/bin/espresso
25 | espresso || true
26 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/SIntFactory.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3
4 |
5 | import chisel3.internal.firrtl.{IntervalRange, SLit, Width}
6 |
7 | trait SIntFactory {
8 |
9 | /** Create an SInt type with inferred width. */
10 | def apply(): SInt = apply(Width())
11 |
12 | /** Create a SInt type or port with fixed width. */
13 | def apply(width: Width): SInt = new SInt(width)
14 |
15 | /** Create a SInt with the specified range */
16 | def apply(range: IntervalRange): SInt = {
17 | apply(range.getWidth)
18 | }
19 |
20 | /** Create an SInt literal with specified width. */
21 | protected[chisel3] def Lit(value: BigInt, width: Width): SInt = {
22 | val lit = SLit(value, width)
23 | val result = new SInt(lit.width)
24 | lit.bindLitArg(result)
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/website/docs/src/main/resources/svg/Makefile:
--------------------------------------------------------------------------------
1 | buildDir = ../microsite/img
2 |
3 | images = \
4 | navbar_brand.png \
5 | navbar_brand2x.png \
6 | sidebar_brand.png \
7 | sidebar_brand2x.png
8 |
9 | .PHONY: all
10 |
11 | all: $(images:%=$(buildDir)/%)
12 |
13 | $(buildDir)/navbar_brand.png: chisel-tool.svg
14 | inkscape --export-area-page --export-width=44 --export-height=44 $< --export-png=$@
15 |
16 | $(buildDir)/navbar_brand2x.png: chisel-tool.svg
17 | inkscape --export-area-page --export-width=88 --export-height=88 $< --export-png=$@
18 |
19 | $(buildDir)/sidebar_brand.png: chisel-tool.svg
20 | inkscape --export-area-page --export-width=36 --export-height=36 $< --export-png=$@
21 |
22 | $(buildDir)/sidebar_brand2x.png: chisel-tool.svg
23 | inkscape --export-area-page --export-width=72 --export-height=72 $< --export-png=$@
24 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/CustomBundle.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.experimental.requireIsChiselType
7 | import chisel3.reflect.DataMirror
8 | import scala.collection.immutable.ListMap
9 |
10 | // An example of how Record might be extended
11 | // In this case, CustomBundle is a Record constructed from a Tuple of (String, Data)
12 | // it is a possible implementation of a programmatic "Bundle"
13 | // (and can by connected to MyBundle below)
14 | final class CustomBundle(elts: (String, Data)*) extends Record {
15 | val elements = ListMap(elts.map {
16 | case (field, elt) =>
17 | requireIsChiselType(elt)
18 | field -> DataMirror.internal.chiselTypeClone(elt)
19 | }: _*)
20 | def apply(elt: String): Data = elements(elt)
21 | }
22 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/LiteralToTargetSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import circt.stage.ChiselStage
7 | import org.scalatest.freespec.AnyFreeSpec
8 | import org.scalatest.matchers.should.Matchers
9 |
10 | class LiteralToTargetSpec extends AnyFreeSpec with Matchers {
11 |
12 | "Literal Data should fail to be converted to ReferenceTarget" in {
13 |
14 | (the[ChiselException] thrownBy {
15 |
16 | class Bar extends RawModule {
17 | val a = 1.U
18 | }
19 |
20 | class Foo extends RawModule {
21 | val bar = Module(new Bar)
22 | bar.a.toTarget
23 | }
24 |
25 | ChiselStage.elaborate(new Foo)
26 | } should have).message("Illegal component name: UInt<1>(\"h01\") (note: literals are illegal)")
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/test/scala/cookbook/UInt2Bundle.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package cookbook
4 |
5 | import chisel3._
6 |
7 | /* ### How do I create a Bundle from a UInt?
8 | *
9 | * On an instance of the Bundle, call the method fromBits with the UInt as the argument
10 | */
11 | class UInt2Bundle extends CookbookTester(1) {
12 | // Example
13 | class MyBundle extends Bundle {
14 | val foo = UInt(4.W)
15 | val bar = UInt(4.W)
16 | }
17 | val uint = 0xb4.U
18 | val bundle = uint.asTypeOf(new MyBundle)
19 | printf(p"$bundle") // Bundle(foo -> 11, bar -> 4)
20 |
21 | // Test
22 | assert(bundle.foo === 0xb.U)
23 | assert(bundle.bar === 0x4.U)
24 | }
25 |
26 | class UInt2BundleSpec extends CookbookSpec {
27 | "UInt2Bundle" should "work" in {
28 | assertTesterPasses { new UInt2Bundle }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/test/scala/cookbook/UInt2VecOfBool.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package cookbook
4 |
5 | import chisel3._
6 |
7 | /* ### How do I create a Vec of Bools from a UInt?
8 | *
9 | * Use the builtin function [[chisel3.Bits.asBools]] to create a Scala Seq of Bool,
10 | * then wrap the resulting Seq in Vec(...)
11 | */
12 | class UInt2VecOfBool extends CookbookTester(1) {
13 | // Example
14 | val uint = 0xc.U
15 | val vec = VecInit(uint.asBools)
16 | printf(p"$vec") // Vec(0, 0, 1, 1)
17 |
18 | // Test
19 | assert(vec(0) === false.B)
20 | assert(vec(1) === false.B)
21 | assert(vec(2) === true.B)
22 | assert(vec(3) === true.B)
23 | }
24 |
25 | class UInt2VecOfBoolSpec extends CookbookSpec {
26 | "UInt2VecOfBool" should "work" in {
27 | assertTesterPasses { new UInt2VecOfBool }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.stage.phases
4 |
5 | import chisel3.aop.Aspect
6 | import firrtl.AnnotationSeq
7 | import firrtl.options.{Dependency, Phase}
8 |
9 | /** Run [[AspectPhase]] if a [[chisel3.aop.Aspect]] is present.
10 | */
11 | class MaybeAspectPhase extends Phase {
12 |
13 | override def prerequisites = Seq(Dependency[Elaborate])
14 | override def optionalPrerequisites = Seq.empty
15 | override def optionalPrerequisiteOf = Seq.empty
16 | override def invalidates(a: Phase) = false
17 |
18 | def transform(annotations: AnnotationSeq): AnnotationSeq = {
19 | if (annotations.collectFirst { case a: Aspect[_] => annotations }.isDefined) {
20 | new AspectPhase().transform(annotations)
21 | } else annotations
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/experimental/hierarchy/Utils.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests.experimental.hierarchy
4 |
5 | import _root_.firrtl.annotations._
6 | import chiselTests.ChiselRunners
7 | import org.scalatest.matchers.should.Matchers
8 |
9 | trait Utils extends ChiselRunners with chiselTests.Utils with Matchers {
10 | // TODO promote to standard API (in FIRRTL) and perhaps even implement with a macro
11 | implicit class Str2RefTarget(str: String) {
12 | def rt: ReferenceTarget = Target.deserialize(str).asInstanceOf[ReferenceTarget]
13 | def it: InstanceTarget = Target.deserialize(str).asInstanceOf[InstanceTarget]
14 | def mt: ModuleTarget = Target.deserialize(str).asInstanceOf[ModuleTarget]
15 | def ct: CircuitTarget = Target.deserialize(str).asInstanceOf[CircuitTarget]
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/root-doc.txt:
--------------------------------------------------------------------------------
1 | This is the documentation for Chisel.
2 |
3 | == Package structure ==
4 |
5 | The [[chisel3]] package presents the public API of Chisel.
6 | It contains the concrete core types [[chisel3.UInt `UInt`]], [[chisel3.SInt `SInt`]], [[chisel3.Bool `Bool`]], [[chisel3.experimental.FixedPoint `FixedPoint`]], [[chisel3.Clock `Clock`]], and [[chisel3.Reg `Reg`]],
7 | the abstract types [[chisel3.Bits `Bits`]], [[chisel3.Aggregate `Aggregate`]], and [[chisel3.Data `Data`]],
8 | and the aggregate types [[chisel3.Bundle `Bundle`]] and [[chisel3.Vec `Vec`]].
9 |
10 | The [[Chisel]] package is a compatibility layer that attempts to provide chisel2 compatibility in chisel3.
11 |
12 | Utility objects and methods are found in the [[chisel3.util `util`]] package.
13 |
14 | The [[chisel3.testers `testers`]] package defines the basic interface for chisel testers.
15 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/internal/firrtl/Emitter.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.internal.firrtl
4 |
5 | import scala.collection.immutable.LazyList // Needed for 2.12 alias
6 | import firrtl.ir.Serializer
7 |
8 | private[chisel3] object Emitter {
9 | def emit(circuit: Circuit): String = {
10 | val fcircuit = Converter.convertLazily(circuit)
11 | Serializer.serialize(fcircuit)
12 | }
13 |
14 | def emitLazily(circuit: Circuit): Iterable[String] = new Iterable[String] {
15 | def iterator = {
16 | val prelude = Iterator(s"circuit ${circuit.name} :\n")
17 | val modules = circuit.components.iterator.map(Converter.convert)
18 | val moduleStrings = modules.flatMap { m =>
19 | Serializer.lazily(m, 1) ++ Seq("\n\n")
20 | }
21 | prelude ++ moduleStrings
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/experimental/hierarchy/core/IsClone.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.experimental.hierarchy.core
4 |
5 | /** Represents a clone of an underlying object. This is used to support CloneModuleAsRecord and Instance/Definition.
6 | *
7 | * @note We don't actually "clone" anything in the traditional sense but is a placeholder so we lazily clone internal state
8 | */
9 | trait IsClone[+T] {
10 | // Underlying object of which this is a clone of
11 | private[chisel3] def getProto: T
12 |
13 | /** Determines whether another object is a clone of the same underlying proto
14 | *
15 | * @param a
16 | */
17 | def hasSameProto(a: Any): Boolean = {
18 | val aProto = a match {
19 | case x: IsClone[_] => x.getProto
20 | case o => o
21 | }
22 | this == aProto || getProto == aProto
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/counter/CounterFormalSpec.scala:
--------------------------------------------------------------------------------
1 | package counter
2 |
3 | import org.scalatest.flatspec._
4 | import org.scalatest.matchers.should._
5 | import chiseltest._
6 | import chiseltest.formal._
7 | import chisel3._
8 |
9 | class CounterFormalSpec extends AnyFlatSpec with ChiselScalatestTester with Formal {
10 | // println(new (chisel3.stage.ChiselStage).emitSystemVerilog(new CounterProp1(4)))
11 | behavior of "CounterProp"
12 | it should "pass" in {
13 | // verify(new Counter(4), Seq(BoundedCheck(100), BtormcEngineAnnotation))
14 | println(new (chisel3.stage.ChiselStage).emitSystemVerilog(new Counter(4)))
15 | //verify(new GCD(), Seq(BoundedCheck(20), BtormcEngineAnnotation) )
16 | //verify(new CounterProp1(4), Seq(BoundedCheck(20), BtormcEngineAnnotation))
17 | //verify(new CounterProp2(4), Seq(BoundedCheck(20), BtormcEngineAnnotation))
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/RebindingSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import circt.stage.ChiselStage
7 |
8 | class RebindingSpec extends ChiselFlatSpec with Utils {
9 | "Rebinding a literal" should "fail" in {
10 | a[BindingException] should be thrownBy extractCause[BindingException] {
11 | ChiselStage.elaborate {
12 | new Module {
13 | val io = IO(new Bundle {
14 | val a = 4.U
15 | })
16 | }
17 | }
18 | }
19 | }
20 |
21 | "Rebinding a hardware type" should "fail" in {
22 | a[BindingException] should be thrownBy extractCause[BindingException] {
23 | ChiselStage.elaborate {
24 | new Module {
25 | val io = IO(new Bundle {
26 | val a = Reg(UInt(32.W))
27 | })
28 | }
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/.github/workflows/setup-oss-cad-suite/action.yml:
--------------------------------------------------------------------------------
1 | name: Setup OSS CAD Suite
2 |
3 | inputs:
4 | version:
5 | description: 'version to install'
6 | required: false
7 | default: '2021-11-09'
8 |
9 | runs:
10 | using: composite
11 | steps:
12 | - id: cache-oss-cad-suite
13 | uses: actions/cache@v3
14 | with:
15 | path: oss-cad-suite
16 | key: oss-cad-suite-${{ runner.os }}-${{ inputs.version }}
17 |
18 | - shell: bash
19 | if: steps.cache-oss-cad-suite.outputs.cache-hit != 'true'
20 | run: |
21 | VERSION=${{ inputs.version }}
22 | ARTIFACT=oss-cad-suite-linux-x64-$(echo $VERSION | tr -d '-')
23 | wget -q -O - https://github.com/YosysHQ/oss-cad-suite-build/releases/download/${VERSION}/${ARTIFACT}.tgz | tar -zx
24 |
25 | # Add the CAD Suite to the PATH
26 | - shell: bash
27 | run: echo "$(pwd)/oss-cad-suite/bin" >> $GITHUB_PATH
28 |
29 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/stage/phases/MaybeFirrtlStage.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.stage.phases
4 |
5 | import chisel3.stage.NoRunFirrtlCompilerAnnotation
6 |
7 | import firrtl.AnnotationSeq
8 | import firrtl.options.{Dependency, Phase}
9 | import firrtl.stage.FirrtlStage
10 |
11 | /** Run [[firrtl.stage.FirrtlStage]] if a [[chisel3.stage.NoRunFirrtlCompilerAnnotation]] is not present.
12 | */
13 | class MaybeFirrtlStage extends Phase {
14 |
15 | override def prerequisites = Seq(Dependency[Convert])
16 | override def optionalPrerequisites = Seq.empty
17 | override def optionalPrerequisiteOf = Seq.empty
18 | override def invalidates(a: Phase) = false
19 |
20 | def transform(annotations: AnnotationSeq): AnnotationSeq = annotations.collectFirst {
21 | case NoRunFirrtlCompilerAnnotation => annotations
22 | }.getOrElse { (new FirrtlStage).transform(annotations) }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/resources/chisel3/Makefile:
--------------------------------------------------------------------------------
1 | # Chisel parallel make template.
2 |
3 | HFILES = @HFILES@
4 | ONCEONLY = @ONCEONLY@
5 | UNOPTIMIZED = @UNOPTIMIZED@
6 | OPTIMIZED = @OPTIMIZED@
7 |
8 | EXEC = @EXEC@
9 | OPTIM0 = @OPTIM0@
10 | OPTIM1 = @OPTIM1@
11 | OPTIM2 = @OPTIM2@
12 | CPPFLAGS = @CPPFLAGS@
13 | CXXFLAGS = @CXXFLAGS@
14 | LDFLAGS = @LDFLAGS@
15 | CXX = @CXX@
16 |
17 | default: $(EXEC)
18 |
19 | clean:
20 | $(RM) $(EXEC) $(ONCEONLY) $(UNOPTIMIZED) $(OPTIMIZED)
21 |
22 | $(ONCEONLY) $(UNOPTIMIZED) $(OPTIMIZED): $(HFILES)
23 |
24 | $(EXEC): $(ONCEONLY) $(UNOPTIMIZED) $(OPTIMIZED) Makefile
25 | $(CXX) -o $@ $(filter-out Makefile,$^)
26 |
27 | $(ONCEONLY): %.o: %.cpp
28 | $(CXX) -c -o $@ $(OPTIM0) $(CPPFLAGS) $(CXXFLAGS) $<
29 |
30 | $(UNOPTIMIZED): %.o: %.cpp
31 | $(CXX) -c -o $@ $(OPTIM1) $(CPPFLAGS) $(CXXFLAGS) $<
32 |
33 | $(OPTIMIZED): %.o: %.cpp
34 | $(CXX) -c -o $@ $(OPTIM2) $(CPPFLAGS) $(CXXFLAGS) $<
35 |
--------------------------------------------------------------------------------
/src/main/scala/circt/stage/phases/AddFIRRTLInputFile.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package circt.stage.phases
4 |
5 | import firrtl.AnnotationSeq
6 | import firrtl.options.{Dependency, Phase}
7 | import firrtl.stage.{FirrtlCircuitAnnotation, FirrtlFileAnnotation}
8 |
9 | import chisel3.stage.CircuitSerializationAnnotation
10 |
11 | private[stage] class AddFIRRTLInputFile extends Phase {
12 |
13 | override def prerequisites = Seq.empty
14 | override def optionalPrerequisites = Seq.empty
15 | override def optionalPrerequisiteOf = Seq(Dependency[circt.stage.CIRCTStage])
16 | override def invalidates(a: Phase) = false
17 |
18 | override def transform(annotations: AnnotationSeq): AnnotationSeq = annotations.flatMap {
19 | case a: CircuitSerializationAnnotation => Some(FirrtlFileAnnotation(a.filename(annotations).toString))
20 | case a: FirrtlCircuitAnnotation => None
21 | case a => Some(a)
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/ModuleAspect.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3
4 |
5 | import chisel3.internal.{Builder, PseudoModule}
6 |
7 | /** Used by Chisel Aspects to inject Chisel code into modules, after they have been elaborated.
8 | * This is an internal API - don't use!
9 | *
10 | * It adds itself as an aspect to the module, which allows proper checking of connection and binding legality.
11 | *
12 | * @param module Module for which this object is an aspect of
13 | * @param moduleCompileOptions
14 | */
15 | abstract class ModuleAspect private[chisel3] (module: RawModule)(implicit moduleCompileOptions: CompileOptions)
16 | extends RawModule
17 | with PseudoModule {
18 |
19 | Builder.addAspect(module, this)
20 |
21 | override def circuitName: String = module.toTarget.circuit
22 |
23 | override def desiredName: String = module.name
24 |
25 | override val _namespace = module._namespace
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/BitwiseOps.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.testers.BasicTester
7 |
8 | class BitwiseOpsTester(w: Int, _a: Int, _b: Int) extends BasicTester {
9 | val mask = (1 << w) - 1
10 | val a = _a.asUInt(w.W)
11 | val b = _b.asUInt(w.W)
12 | assert(~a === (mask & ~_a).asUInt)
13 | assert((a & b) === (_a & _b).asUInt)
14 | assert((a | b) === (_a | _b).asUInt)
15 | assert((a ^ b) === (_a ^ _b).asUInt)
16 | assert((a.orR) === (_a != 0).asBool)
17 | assert((a.andR) === (s"%${w}s".format(BigInt(_a).toString(2)).foldLeft(true)(_ && _ == '1')).asBool)
18 | stop()
19 | }
20 |
21 | class BitwiseOpsSpec extends ChiselPropSpec {
22 | property("All bit-wise ops should return the correct result") {
23 | forAll(safeUIntPair) {
24 | case (w: Int, a: Int, b: Int) =>
25 | assertTesterPasses { new BitwiseOpsTester(w, a, b) }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/aop/inspecting/InspectingAspect.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.aop.inspecting
4 |
5 | import chisel3.RawModule
6 | import chisel3.aop.Aspect
7 | import firrtl.AnnotationSeq
8 |
9 | /** Use for inspecting an elaborated design and printing out results
10 | *
11 | * @param inspect Given top-level design, print things and return nothing
12 | * @tparam T Type of top-level module
13 | */
14 | case class InspectingAspect[T <: RawModule](inspect: T => Unit) extends InspectorAspect[T](inspect)
15 |
16 | /** Extend to make custom inspections of an elaborated design and printing out results
17 | *
18 | * @param inspect Given top-level design, print things and return nothing
19 | * @tparam T Type of top-level module
20 | */
21 | abstract class InspectorAspect[T <: RawModule](inspect: T => Unit) extends Aspect[T] {
22 | override def toAnnotation(top: T): AnnotationSeq = {
23 | inspect(top)
24 | Nil
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/bus/tilelink/TilelinkConfig.scala:
--------------------------------------------------------------------------------
1 | package caravan.bus.tilelink
2 |
3 | import caravan.bus.common.BusConfig
4 |
5 |
6 | case class TilelinkConfig
7 | (
8 |
9 | /*
10 |
11 | w => Width of the data bus in bytes. || DUW => width of device user bits, default 4
12 | a => Width of each address field in bits. || AW => width of address bus, default 32
13 | z => Width of each size field in bits. || SZW => size width, covers 2^(x) <= DBW; (2 bit for 4B)
14 | o => Number of bits needed to disambiguate per-link master sources. || AIW => width of address source (ID) bus, default 8
15 | i => Number of bits needed to disambiguate per-link slave sinks. || DIW => width of sink bits, default 1
16 |
17 | */
18 |
19 | val w: Int = 4,
20 | val a: Int = 32,
21 | val z: Int = 2,
22 | val o: Int = 8,
23 | val i: Int = 1,
24 |
25 | ) extends BusConfig
26 |
27 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/util/experimental/decode/DecodeTableAnnotation.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.util.experimental.decode
4 |
5 | import firrtl.annotations.{Annotation, ReferenceTarget, SingleTargetAnnotation}
6 |
7 | /** DecodeTableAnnotation used to store a decode result for a specific [[TruthTable]].
8 | * This is useful for saving large [[TruthTable]] during a elaboration time.
9 | *
10 | * @note user should manage the correctness of [[minimizedTable]].
11 | *
12 | * @param target output wire of a decoder.
13 | * @param truthTable input [[TruthTable]] encoded in a serialized [[TruthTable]].
14 | * @param minimizedTable minimized [[truthTable]] encoded in a serialized [[TruthTable]].
15 | */
16 | case class DecodeTableAnnotation(
17 | target: ReferenceTarget,
18 | truthTable: String,
19 | minimizedTable: String)
20 | extends SingleTargetAnnotation[ReferenceTarget] {
21 | override def duplicate(n: ReferenceTarget): Annotation = this.copy(target = n)
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/stage/ChiselPhase.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.stage
4 |
5 | import firrtl.options.{Dependency, Phase, PhaseManager}
6 | import firrtl.options.phases.DeletedWrapper
7 |
8 | private[chisel3] class ChiselPhase extends PhaseManager(ChiselPhase.targets) {
9 |
10 | override val wrappers = Seq((a: Phase) => DeletedWrapper(a))
11 |
12 | }
13 |
14 | private[chisel3] object ChiselPhase {
15 |
16 | val targets: Seq[PhaseManager.PhaseDependency] =
17 | Seq(
18 | Dependency[chisel3.stage.phases.Checks],
19 | Dependency[chisel3.stage.phases.AddImplicitOutputFile],
20 | Dependency[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
21 | Dependency[chisel3.stage.phases.MaybeAspectPhase],
22 | Dependency[chisel3.stage.phases.AddSerializationAnnotations],
23 | Dependency[chisel3.stage.phases.Convert],
24 | Dependency[chisel3.stage.phases.MaybeInjectingPhase],
25 | Dependency[chisel3.stage.phases.MaybeFirrtlStage]
26 | )
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/PortSpec.scala:
--------------------------------------------------------------------------------
1 | package chiselTests
2 |
3 | import chisel3._
4 | import circt.stage.ChiselStage
5 |
6 | class PortSpec extends ChiselFreeSpec {
7 |
8 | class DummyIO extends Bundle {
9 | val foo = Input(Bool())
10 | val bar = Input(UInt(8.W))
11 | }
12 |
13 | class Dummy extends Module {
14 | val in = IO(new DummyIO)
15 | val out = IO(Output(Bool()))
16 | out := in.foo.asUInt + in.bar
17 | }
18 |
19 | "Ports now have source locators" in {
20 | val chirrtl = ChiselStage.emitCHIRRTL(new Dummy)
21 | // Automatic clock and reset coming from Module do not get source locators
22 | chirrtl should include("input clock : Clock")
23 | chirrtl should include("input reset : UInt<1>")
24 | // other ports get source locators
25 | chirrtl should include(
26 | "output in : { flip foo : UInt<1>, flip bar : UInt<8>} @[src/test/scala/chiselTests/PortSpec.scala"
27 | )
28 | chirrtl should include("output out : UInt<1> @[src/test/scala/chiselTests/PortSpec.scala")
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/internal/SourceInfoMacro.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.internal.sourceinfo
4 |
5 | import scala.language.experimental.macros
6 | import scala.reflect.macros.blackbox.Context
7 |
8 | /** Provides a macro that returns the source information at the invocation point.
9 | */
10 | @deprecated("Public APIs in chisel3.internal are deprecated", "Chisel 3.6")
11 | object SourceInfoMacro {
12 | def generate_source_info(c: Context): c.Tree = {
13 | import c.universe._
14 | val p = c.enclosingPosition
15 |
16 | val userDir = sys.props.get("user.dir") // Figure out what to do if not provided
17 | val projectRoot = sys.props.get("chisel.project.root")
18 | val root = projectRoot.orElse(userDir)
19 |
20 | val path = root.map(r => p.source.file.canonicalPath.stripPrefix(r)).getOrElse(p.source.file.name)
21 | val pathNoStartingSlash = if (path(0) == '/') path.tail else path
22 |
23 | q"_root_.chisel3.experimental.SourceLine($pathNoStartingSlash, ${p.line}, ${p.column})"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature Request
3 | about: Request a new feature or change in functionality in chisel3
4 | ---
5 |
6 |
7 |
8 | **Type of issue**: Feature Request
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Include detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. Stack Overflow, gitter, [Scastie](https://scastie.scala-lang.org/KtzZQ3nFTea9KoNh0tRqtg).
21 |
22 | **What is the use case for implementing this feature?**
23 |
--------------------------------------------------------------------------------
/src/test/scala/examples/ImplicitStateVendingMachine.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package examples
4 |
5 | import chiselTests.ChiselFlatSpec
6 | import chisel3._
7 |
8 | // Vending machine implemented with an implicit state machine
9 | class ImplicitStateVendingMachine extends SimpleVendingMachine {
10 | // We let the value of nickel be 1 and dime be 2 for efficiency reasons
11 | val value = RegInit(0.asUInt(3.W))
12 | val incValue = WireDefault(0.asUInt(3.W))
13 | val doDispense = value >= 4.U // 4 * nickel as 1 == $0.20
14 |
15 | when(doDispense) {
16 | value := 0.U // No change given
17 | }.otherwise {
18 | value := value + incValue
19 | }
20 |
21 | when(io.nickel) { incValue := 1.U }
22 | when(io.dime) { incValue := 2.U }
23 |
24 | io.dispense := doDispense
25 | }
26 |
27 | class ImplicitStateVendingMachineSpec extends ChiselFlatSpec {
28 | "An vending machine implemented with implicit state" should "work" in {
29 | assertTesterPasses { new SimpleVendingMachineTester(new ImplicitStateVendingMachine) }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/docs/src/developers/test-coverage.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: docs
3 | title: "Test Coverage"
4 | section: "chisel3"
5 | ---
6 |
7 | # Test Coverage
8 |
9 | ## Test Coverage Setup
10 |
11 | Chisel's sbt build instructions contain the requisite plug-in (sbt-scoverage) for generating test coverage information. Please see the [sbt-scoverage web page](https://github.com/scoverage/sbt-scoverage) for details on the plug-in.
12 | The tests themselves are found in `src/test/scala`.
13 |
14 | ## Generating A Test Coverage Report
15 |
16 | Use the following sequence of sbt commands to generate a test coverage report:
17 | ```
18 | sbt clean coverage test
19 | sbt coverageReport
20 | ```
21 | The coverage reports should be found in `target/scala-x.yy/scoverage-report/{scoverage.xml,index.html}` where `x.yy` corresponds to the version of Scala used to compile Firrtl and the tests.
22 | `scoverage.xml` is useful if you want to analyze the results programmatically.
23 | `index.html` is designed for navigation with a web browser, allowing one to drill down to invidual statements covered (or not) by the tests.
24 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/Clock.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.testers.BasicTester
7 | import circt.stage.ChiselStage
8 |
9 | class ClockAsUIntTester extends BasicTester {
10 | assert(true.B.asClock.asUInt === 1.U)
11 | assert(true.B.asClock.asBool === true.B)
12 | stop()
13 | }
14 |
15 | class WithClockAndNoReset extends RawModule {
16 | val clock1 = IO(Input(Clock()))
17 | val clock2 = IO(Input(Clock()))
18 | val in = IO(Input(Bool()))
19 | val out = IO(Output(Bool()))
20 | val a = withClock(clock2) {
21 | RegNext(in)
22 | }
23 |
24 | out := a
25 | }
26 |
27 | class ClockSpec extends ChiselPropSpec {
28 | property("Bool.asClock.asUInt should pass a signal through unaltered") {
29 | assertTesterPasses { new ClockAsUIntTester }
30 | }
31 |
32 | property("Should be able to use withClock in a module with no reset") {
33 | val circuit = ChiselStage.emitCHIRRTL(new WithClockAndNoReset)
34 | circuit.contains("reg a : UInt<1>, clock2") should be(true)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/MulLookup.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.testers.BasicTester
7 |
8 | class MulLookup(val w: Int) extends Module {
9 | val io = IO(new Bundle {
10 | val x = Input(UInt(w.W))
11 | val y = Input(UInt(w.W))
12 | val z = Output(UInt((2 * w).W))
13 | })
14 | val tbl = VecInit(
15 | for {
16 | i <- 0 until 1 << w
17 | j <- 0 until 1 << w
18 | } yield (i * j).asUInt((2 * w).W)
19 | )
20 | io.z := tbl(((io.x << w) | io.y))
21 | }
22 |
23 | class MulLookupTester(w: Int, x: Int, y: Int) extends BasicTester {
24 | val dut = Module(new MulLookup(w))
25 | dut.io.x := x.asUInt
26 | dut.io.y := y.asUInt
27 | assert(dut.io.z === (x * y).asUInt)
28 | stop()
29 | }
30 |
31 | class MulLookupSpec extends ChiselPropSpec {
32 |
33 | property("Mul lookup table should return the correct result") {
34 | forAll(smallPosInts, smallPosInts) { (x: Int, y: Int) =>
35 | assertTesterPasses { new MulLookupTester(3, x, y) }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/counter/Counter.scala:
--------------------------------------------------------------------------------
1 | // package counter
2 |
3 | // import scala.reflect.runtime.{universe => ru}
4 | // import chisel3._
5 | // import chiseltest._
6 | // import chiseltest.formal._
7 | // import chiseltest.formal.chaAnno._
8 | // import chisel3.experimental.{ChiselAnnotation,annotate,RunFirrtlTransform}
9 | // import firrtl.annotations.{Annotation, ReferenceTarget, SingleTargetAnnotation, Target,MultiTargetAnnotation}
10 | // import scala.language.reflectiveCalls
11 |
12 | // class Counter(width: Int) extends Module {
13 | // val io = IO(new Bundle {
14 | // //val en = Input(Bool())
15 | // val dout = Output(UInt(width.W))
16 | // val ts = Output(Bool())
17 | // })
18 | // val countReg = RegInit(0.U(width.W))
19 | // val ccountReg = RegInit(0.U(width.W))
20 | // countReg := countReg + 1.U
21 |
22 | // io.ts := countReg(0)
23 | // // assert(countReg(0))
24 | // // chaAssume(this,"G bs")
25 | // // chaAssert(this,"bs |-> ##[0:8] ts")
26 | // // chaAssert(this, "G (bs ##[1:$] ts)[*2:3] U (X (bs |-> F ts))")
27 | // io.dout := countReg
28 | // }
29 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug-report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug Report
3 | about: Report a problem you experienced with chisel3
4 | ---
5 |
6 |
7 |
10 | **Type of issue**: Bug Report
11 |
12 | **Please provide the steps to reproduce the problem:**
13 |
14 | **What is the current behavior?**
15 |
16 | **What is the expected behavior?**
17 |
18 | **Please tell us about your environment:**
19 |
23 |
24 | **Other Information**
25 |
26 |
27 | **What is the use case for changing the behavior?**
28 |
--------------------------------------------------------------------------------
/docs-target/src/main/scala/chisel3/docs/VerilogMdocModifier.scala:
--------------------------------------------------------------------------------
1 | package chisel3.docs
2 |
3 | import java.nio.file.Files
4 | import java.nio.file.Paths
5 | import mdoc._
6 | import scala.meta.inputs.Position
7 |
8 | /** Custom modifier for rendering Chisel-generated Verilog
9 | *
10 | * See chisel3/docs/README.md for use
11 | */
12 | class VerilogMdocModifier extends PostModifier {
13 | val name = "verilog"
14 | def process(ctx: PostModifierContext): String = {
15 | val result =
16 | ctx.variables.foldLeft(Option("")) {
17 | case (Some(acc), variable) if variable.staticType == "String" =>
18 | Some(acc + variable.runtimeValue)
19 | case (Some(_), badVar) =>
20 | ctx.reporter.error(
21 | badVar.pos,
22 | s"""type mismatch:
23 | |expected: String
24 | |received: ${badVar.runtimeValue}""".stripMargin
25 | )
26 | None
27 | case (None, _) => None
28 | }
29 | result match {
30 | case Some(content) => s"```verilog\n$content```\n"
31 | case None => ""
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/aop/injecting/InjectStatement.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.aop.injecting
4 |
5 | import chisel3.stage.phases.AspectPhase
6 | import firrtl.annotations.{Annotation, ModuleTarget, NoTargetAnnotation, SingleTargetAnnotation}
7 |
8 | /** Contains all information needed to inject statements into a module
9 | *
10 | * Generated when a [[InjectingAspect]] is consumed by a `AspectPhase`
11 | * Consumed by [[InjectingPhase]]
12 | *
13 | * @param module Module to inject code into at the end of the module
14 | * @param s Statements to inject
15 | * @param modules Additional modules that may be instantiated by s
16 | * @param annotations Additional annotations that should be passed down compiler
17 | */
18 | case class InjectStatement(
19 | module: ModuleTarget,
20 | s: firrtl.ir.Statement,
21 | modules: Seq[firrtl.ir.DefModule],
22 | annotations: Seq[Annotation])
23 | extends SingleTargetAnnotation[ModuleTarget] {
24 | val target: ModuleTarget = module
25 | override def duplicate(n: ModuleTarget): Annotation = this.copy(module = n)
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/Padding.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import circt.stage.ChiselStage
7 |
8 | class Padder extends Module {
9 | val io = IO(new Bundle {
10 | val a = Input(UInt(4.W))
11 | val asp = Output(SInt(8.W))
12 | val aup = Output(UInt(8.W))
13 | })
14 | io.asp := io.a.asSInt
15 | io.aup := io.a.asUInt
16 | }
17 |
18 | /*
19 | class PadsTester(c: Pads) extends Tester(c) {
20 | def pads(x: BigInt, s: Int, w: Int) = {
21 | val sign = (x & (1 << (s-1)))
22 | val wmask = (1 << w) - 1
23 | val bmask = (1 << s) - 1
24 | if (sign == 0) x else ((~bmask | x) & wmask)
25 | }
26 | for (t <- 0 until 16) {
27 | val test_a = rnd.nextInt(1 << 4)
28 | poke(c.io.a, test_a)
29 | step(1)
30 | expect(c.io.asp, pads(test_a, 4, 8))
31 | expect(c.io.aup, test_a)
32 | }
33 | }
34 | */
35 |
36 | class PadderSpec extends ChiselPropSpec {
37 |
38 | property("Padder should elaborate") {
39 | ChiselStage.elaborate { new Padder }
40 | }
41 |
42 | ignore("PadderTester should return the correct result") {}
43 | }
44 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/experimental/OpaqueType.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.experimental
4 |
5 | import chisel3._
6 |
7 | /** Indicates if this Record represents an "Opaque Type"
8 | *
9 | * Opaque types provide a mechanism for user-defined types
10 | * that do not impose any "boxing" overhead in the emitted FIRRTL and Verilog.
11 | * You can think about an opaque type Record as a box around
12 | * a single element that only exists at Chisel elaboration time.
13 | * Put another way, if this trait is mixed into a Record,
14 | * the Record may only contain a single element with an empty name
15 | * and there will be no `_` in the name for that element in the emitted Verilog.
16 | *
17 | * @see RecordSpec in Chisel's tests for example usage and expected output
18 | */
19 | trait OpaqueType { self: Record =>
20 |
21 | /** If set to true, indicates that this Record is an OpaqueType
22 | *
23 | * Users can override this if they need more dynamic control over the behavior for when
24 | * instances of this type are considered opaque
25 | */
26 | def opaqueType: Boolean = true
27 | }
28 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/experimental/hierarchy/core/IsLookupable.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.experimental.hierarchy.core
4 |
5 | /** A User-extendable trait to mark metadata-containers, e.g. parameter case classes, as valid to return unchanged
6 | * from an instance.
7 | *
8 | * This should only be true of the metadata returned is identical for ALL instances!
9 | *
10 | * @example For instances of the same proto, metadata or other construction parameters
11 | * may be useful to access outside of the instance construction. For parameters that are
12 | * the same for all instances, we should mark it as IsLookupable
13 | * {{{
14 | * case class Params(debugMessage: String) extends IsLookupable
15 | * class MyModule(p: Params) extends Module {
16 | * printf(p.debugMessage)
17 | * }
18 | * val myParams = Params("Hello World")
19 | * val definition = Definition(new MyModule(myParams))
20 | * val i0 = Instance(definition)
21 | * val i1 = Instance(definition)
22 | * require(i0.p == i1.p) // p is only accessable because it extends IsLookupable
23 | * }}}
24 | */
25 | trait IsLookupable
26 |
--------------------------------------------------------------------------------
/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | resolvers += Resolver.url("scalasbt", new URL("https://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases"))(
2 | Resolver.ivyStylePatterns
3 | )
4 |
5 | resolvers += Classpaths.sbtPluginReleases
6 |
7 | resolvers += "jgit-repo".at("https://download.eclipse.org/jgit/maven")
8 |
9 | addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.9.3")
10 |
11 | addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.4.1")
12 |
13 | addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0")
14 |
15 | addSbtPlugin("com.github.sbt" % "sbt-unidoc" % "0.5.0")
16 |
17 | addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.15")
18 |
19 | addSbtPlugin("com.thoughtworks.sbt-api-mappings" % "sbt-api-mappings" % "3.0.2")
20 |
21 | addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.3.6")
22 |
23 | addSbtPlugin("com.eed3si9n" % "sbt-sriracha" % "0.1.0")
24 |
25 | addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.1.1")
26 |
27 | addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.11")
28 |
29 | addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.0")
30 |
31 | // From FIRRTL for building from source
32 | addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.33")
33 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/GCD/GCDFormalSpec.scala:
--------------------------------------------------------------------------------
1 | package testCHA.GCD
2 |
3 | import org.scalatest.flatspec._
4 | import org.scalatest.matchers.should._
5 | import chiseltest._
6 | import chiseltest.formal._
7 | import chiseltest.formal.chaAnno._
8 | import chisel3._
9 |
10 | class DecoupledGcdProp1(bitWidth: Int) extends DecoupledGcd(bitWidth){
11 | val nBusy = !busy
12 | val temp = output.valid
13 | // val busy = !s1.input.ready
14 | // assert(nBusy1)
15 | chaAssert(this,"busy |-> ##[1:16] nBusy")
16 | // chaAssert(this,"busy")
17 | // chaAssume(this,"F temp")
18 | // chaAssume(this,"temp")
19 | // chaAssert(this,"temp |-> F nBusy1")
20 | // chaAssert(this,"busy |-> temp")
21 | // chaAssert(this,"busy |-> ##[1:15] nBusy")
22 | // chaAnno.makeCHAAnno(this.reset, ap(busy) |-> ###(1,15) ap(!busy))
23 | }
24 |
25 | class DecoupledGcdSpec extends AnyFlatSpec with ChiselScalatestTester with Formal {
26 | // println(new (chisel3.stage.ChiselStage).emitSystemVerilog(new DecoupledGcdProp1(4)))
27 | behavior of "DecoupledGcd"
28 | it should "pass" in {
29 | verify(new DecoupledGcdProp1(4), Seq(BoundedCheck(20), PonoEngineAnnotation))
30 | }
31 | }
--------------------------------------------------------------------------------
/src/test/scala/testCHA/chiselbook/Fifo/FifoSpec.scala:
--------------------------------------------------------------------------------
1 | package testCHA.chiselbook.fifo
2 |
3 | import org.scalatest.flatspec._
4 | import org.scalatest.matchers.should._
5 | import chiseltest._
6 | import chiseltest.formal._
7 | import chiseltest.formal.chaAnno._
8 | import chisel3._
9 |
10 | class CombFifoProp[T <: Data](gen: T, depth: Int) extends CombFifo(gen: T, depth: Int){
11 | val nBusy1 = memFifo.io.deq.valid
12 | // val busy = !s1.input.ready
13 | // assert(nBusy1)
14 | // chaAssert(this,"busy |-> ##[1:15] nBusy")
15 | // chaAssert(this,"busy |-> ##[1:16] nBusy1")
16 | // chaAssume(this,"G busy U busy")
17 | chaAssert(this,"nBusy1 |-> F nBusy1")
18 | // chaAssert(this,"busy |-> ##[1:15] nBusy")
19 | // chaAnno.makeCHAAnno(this.reset, ap(busy) |-> ###(1,15) ap(!busy))
20 | }
21 |
22 | class CombFifoPropSpec extends AnyFlatSpec with ChiselScalatestTester with Formal {
23 | println(new (chisel3.stage.ChiselStage).emitSystemVerilog(new CombFifoProp(UInt(16.W), 4)))
24 | // behavior of "DecoupledGcd"
25 | // it should "pass" in {
26 | // verify(new CombFifoProp(UInt(16.W), 4)), Seq(KInductionCheck(50), PonoEngineAnnotation))
27 | // }
28 | }
--------------------------------------------------------------------------------
/docs/src/resources/resources.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: docs
3 | title: "Resources and References"
4 | section: "chisel3"
5 | ---
6 |
7 | # Chisel Resources
8 |
9 | The *best resource* to learn about Chisel is the [**online Chisel Bootcamp**](https://mybinder.org/v2/gh/freechipsproject/chisel-bootcamp/master). This runs in your browser and assumes no prior Scala knowledge. (You may also run this locally via the [backing chisel-bootcamp GitHub repository](https://github.com/freechipsproject/chisel-bootcamp).)
10 |
11 | When you're ready to build your own circuits in Chisel, **we recommend starting from the [Chisel Template](https://github.com/freechipsproject/chisel-template) repository**, which provides a pre-configured project, example design, and testbench. Follow the [chisel-template readme](https://github.com/freechipsproject/chisel-template) to get started.
12 |
13 | The following additional resources and references may be useful:
14 |
15 | - [Chisel Cheatsheet](https://github.com/freechipsproject/chisel-cheatsheet/releases/latest/download/chisel_cheatsheet.pdf)
16 | - [Digital Design With Chisel](https://github.com/schoeberl/chisel-book)
17 | - [Frequently Asked Questions](faqs)
18 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/stage/phases/AddImplicitOutputFile.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.stage.phases
4 |
5 | import firrtl.AnnotationSeq
6 | import firrtl.options.{Dependency, Phase}
7 |
8 | import chisel3.stage.{ChiselCircuitAnnotation, ChiselOutputFileAnnotation}
9 |
10 | /** Add a output file for a Chisel circuit, derived from the top module in the circuit, if no
11 | * [[ChiselOutputFileAnnotation]] already exists.
12 | */
13 | class AddImplicitOutputFile extends Phase {
14 |
15 | override def prerequisites = Seq(Dependency[Elaborate])
16 | override def optionalPrerequisites = Seq.empty
17 | override def optionalPrerequisiteOf = Seq.empty
18 | override def invalidates(a: Phase) = false
19 |
20 | def transform(annotations: AnnotationSeq): AnnotationSeq =
21 | annotations.collectFirst { case _: ChiselOutputFileAnnotation => annotations }.getOrElse {
22 |
23 | val x: Option[AnnotationSeq] = annotations.collectFirst {
24 | case a: ChiselCircuitAnnotation =>
25 | ChiselOutputFileAnnotation(a.circuit.name) +: annotations
26 | }
27 |
28 | x.getOrElse(annotations)
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/docs/src/explanations/functional-abstraction.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: docs
3 | title: "Functional Abstraction"
4 | section: "chisel3"
5 | ---
6 |
7 | # Functional Abstraction
8 |
9 | We can define functions to factor out a repeated piece of logic that
10 | we later reuse multiple times in a design. For example, we can wrap
11 | up our earlier example of a simple combinational logic block as
12 | follows:
13 |
14 | ```scala mdoc:invisible
15 | import chisel3._
16 | ```
17 |
18 | ```scala mdoc:silent
19 | def clb(a: UInt, b: UInt, c: UInt, d: UInt): UInt =
20 | (a & b) | (~c & d)
21 | ```
22 |
23 | where ```clb``` is the function which takes ```a```, ```b```,
24 | ```c```, ```d``` as arguments and returns a wire to the output of a
25 | boolean circuit. The ```def``` keyword is part of Scala and
26 | introduces a function definition, with each argument followed by a colon then
27 | its type, and the function return type given after the colon following the
28 | argument list. The equals (`=`) sign separates the function argument list
29 | from the function definition.
30 |
31 | We can then use the block in another circuit as follows:
32 | ```scala mdoc:silent
33 | val out = clb(a,b,c,d)
34 | ```
35 |
--------------------------------------------------------------------------------
/docs/src/explanations/source-locators.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: docs
3 | title: "Source Locators"
4 | section: "chisel3"
5 | ---
6 |
7 | # Source Locators
8 |
9 | When elaborating a Chisel design and emitting a FIRRTL file or Verilog file, Chisel will automatically
10 | add source locators which refer back to the Scala file containing the corresponding Chisel code.
11 |
12 | In a FIRRTL file, it looks like this:
13 |
14 | ```
15 | wire w : UInt<3> @[src/main/scala/MyProject/MyFile.scala 1210:21]
16 | ```
17 |
18 | In a Verilog file, it looks like this:
19 |
20 | ```verilog
21 | wire [2:0] w; // @[src/main/scala/MyProject/MyFile.scala 1210:21]
22 | ```
23 |
24 | By default, the file's relative path to where the JVM is invoked is included.
25 | To change where the relative path is computed, set the Java system property `-Dchisel.project.root=/absolute/path/to/root`.
26 | This option can be directly passed to sbt (`sbt -Dchisel.project.root=/absolute/path/to/root`).
27 | Setting the value in the `build.sbt` file won't work because it needs to be passed to the JVM that invokes sbt (not the other way around).
28 | We expect this only relevant for publishing versions which may want more customization.
29 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/bus/SVAtest.scala:
--------------------------------------------------------------------------------
1 | // updated dependency by log-when
2 | package wishbone
3 | import caravan.bus.wishbone.{Harness, WishboneConfig, WBResponse, WBRequest, WishboneHost}
4 | import org.scalatest.flatspec._
5 | import org.scalatest.matchers.should._
6 | import chiseltest._
7 | import chiseltest.formal._
8 | import chisel3._
9 | import org.scalatest.freespec._
10 | import chiseltest.formal.chaAnno._
11 |
12 | // necessary to import
13 |
14 |
15 | class WishboneHostProp(implicit config: WishboneConfig) extends WishboneHost()(config)
16 | {
17 | val cyc_o = io.wbMasterTransmitter.bits.cyc
18 | val stb_o = io.wbMasterTransmitter.bits.stb
19 | val ack_i = io.wbSlaveReceiver.bits.ack
20 | val err_i = io.wbSlaveReceiver.bits.err
21 | //it is allowed to get ack in the same cycle with stb
22 | chaAssert(this, "stb_o |-> ( stb_o U ack_i || err_i) || G stb_o" )
23 | }
24 |
25 | class WishboneHostTest2 extends AnyFlatSpec with ChiselScalatestTester with Formal {
26 |
27 | implicit val config = WishboneConfig(10, 32)
28 | behavior of "WishboneHost"
29 | it should "pass" in {
30 | verify(new WishboneHostProp(), Seq(BoundedCheck(100), BtormcEngineAnnotation))
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/util/Enum.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /** Enum generators, allowing circuit constants to have more meaningful names.
4 | */
5 |
6 | package chisel3.util
7 |
8 | import chisel3._
9 |
10 | /** Defines a set of unique UInt constants
11 | *
12 | * Unpack with a list to specify an enumeration. Usually used with [[switch]] to describe a finite
13 | * state machine.
14 | *
15 | * @example {{{
16 | * val state_on :: state_off :: Nil = Enum(2)
17 | * val current_state = WireDefault(state_off)
18 | * switch (current_state) {
19 | * is (state_on) {
20 | * ...
21 | * }
22 | * is (state_off) {
23 | * ...
24 | * }
25 | * }
26 | * }}}
27 | */
28 | trait Enum {
29 |
30 | /** Returns a sequence of Bits subtypes with values from 0 until n. Helper method. */
31 | protected def createValues(n: Int): Seq[UInt] =
32 | (0 until n).map(_.U((1.max(log2Ceil(n))).W))
33 |
34 | /** Returns n unique UInt values
35 | *
36 | * @param n Number of unique UInt constants to enumerate
37 | * @return Enumerated constants
38 | */
39 | def apply(n: Int): List[UInt] = createValues(n).toList
40 | }
41 |
42 | object Enum extends Enum
43 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/stage/phases/AddImplicitOutputAnnotationFile.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.stage.phases
4 |
5 | import chisel3.stage.ChiselCircuitAnnotation
6 | import firrtl.AnnotationSeq
7 | import firrtl.options.{Dependency, OutputAnnotationFileAnnotation, Phase}
8 |
9 | /** Adds an [[firrtl.options.OutputAnnotationFileAnnotation]] if one does not exist. This replicates old behavior where
10 | * an output annotation file was always written.
11 | */
12 | class AddImplicitOutputAnnotationFile extends Phase {
13 |
14 | override def prerequisites = Seq(Dependency[Elaborate])
15 | override def optionalPrerequisites = Seq.empty
16 | override def optionalPrerequisiteOf = Seq.empty
17 | override def invalidates(a: Phase) = false
18 |
19 | def transform(annotations: AnnotationSeq): AnnotationSeq = annotations.collectFirst {
20 | case _: OutputAnnotationFileAnnotation => annotations
21 | }.getOrElse {
22 |
23 | val x: Option[AnnotationSeq] = annotations.collectFirst {
24 | case a: ChiselCircuitAnnotation =>
25 | OutputAnnotationFileAnnotation(a.circuit.name) +: annotations
26 | }
27 |
28 | x.getOrElse(annotations)
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/integration-tests/src/test/scala/chiselTests/util/experimental/BitPat.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests.util.experimental
4 |
5 | import chisel3._
6 | import chiseltest._
7 | import chiseltest.formal._
8 | import scala.util.Random
9 | import org.scalatest.flatspec.AnyFlatSpec
10 | import chisel3.util.experimental.BitSet
11 |
12 | class BitSetRangeTestModule(start: BigInt, length: BigInt, width: Int) extends Module {
13 | val input = IO(Input(UInt(width.W)))
14 |
15 | val range = BitSet.fromRange(start, length, width)
16 | val testee = range.matches(input)
17 | val ref = input >= start.U && input < (start + length).U
18 |
19 | assert(testee === ref)
20 | }
21 |
22 | class BitSetRangeTest extends AnyFlatSpec with ChiselScalatestTester with Formal {
23 | val rng = new Random(0x19260817)
24 | val cases = 128
25 | "BitSet.fromRange" should "be formally equivalent with bound checks" in {
26 | for (i <- 1 to cases) {
27 | val a = rng.nextLong() & Long.MaxValue
28 | val b = rng.nextLong() & Long.MaxValue
29 | val start = a.min(b)
30 | val len = a.max(b) - start + 1
31 | verify(new BitSetRangeTestModule(start, len, 64), Seq(BoundedCheck(1)))
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/test/scala/cookbook/RegOfVec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package cookbook
4 |
5 | import chisel3._
6 |
7 | /* ### How do I create a Reg of type Vec?
8 | *
9 | * For information, please see the API documentation for Vec
10 | * (https://chisel.eecs.berkeley.edu/api/index.html#chisel3.Vec)
11 | */
12 | class RegOfVec extends CookbookTester(2) {
13 | // Reg of Vec of 32-bit UInts without initialization
14 | val regOfVec = Reg(Vec(4, UInt(32.W)))
15 | regOfVec(0) := 123.U // a couple of assignments
16 | regOfVec(2) := regOfVec(0)
17 |
18 | // Reg of Vec of 32-bit UInts initialized to zero
19 | // Note that Seq.fill constructs 4 32-bit UInt literals with the value 0
20 | // Vec(...) then constructs a Wire of these literals
21 | // The Reg is then initialized to the value of the Wire (which gives it the same type)
22 | val initRegOfVec = RegInit(VecInit(Seq.fill(4)(0.U(32.W))))
23 |
24 | // Simple test (cycle comes from superclass)
25 | when(cycle === 2.U) { assert(regOfVec(2) === 123.U) }
26 | for (elt <- initRegOfVec) { assert(elt === 0.U) }
27 | }
28 |
29 | class RegOfVecSpec extends CookbookSpec {
30 | "RegOfVec" should "work" in {
31 | assertTesterPasses { new RegOfVec }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/stage/phases/AspectPhase.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.stage.phases
4 |
5 | import chisel3.aop.Aspect
6 | import chisel3.RawModule
7 | import chisel3.stage.DesignAnnotation
8 | import firrtl.AnnotationSeq
9 | import firrtl.options.Phase
10 |
11 | import scala.collection.mutable
12 |
13 | /** Phase that consumes all Aspects and calls their toAnnotationSeq methods.
14 | *
15 | * Consumes the [[chisel3.stage.DesignAnnotation]] and converts every `Aspect` into their annotations prior to executing FIRRTL
16 | */
17 | class AspectPhase extends Phase {
18 | def transform(annotations: AnnotationSeq): AnnotationSeq = {
19 | var dut: Option[RawModule] = None
20 | val aspects = mutable.ArrayBuffer[Aspect[_]]()
21 |
22 | val remainingAnnotations = annotations.flatMap {
23 | case DesignAnnotation(d) =>
24 | dut = Some(d)
25 | Nil
26 | case a: Aspect[_] =>
27 | aspects += a
28 | Nil
29 | case other => Seq(other)
30 | }
31 | if (dut.isDefined) {
32 | val newAnnotations = aspects.flatMap { _.resolveAspect(dut.get, remainingAnnotations) }
33 | remainingAnnotations ++ newAnnotations
34 | } else annotations
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/WarningSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import circt.stage.ChiselStage
7 | import chisel3.util._
8 |
9 | class WarningSpec extends ChiselFlatSpec with Utils {
10 | behavior.of("Warnings")
11 |
12 | object MyEnum extends ChiselEnum {
13 | val e0, e1, e2 = Value
14 | }
15 |
16 | class MyModule extends Module {
17 | val in = IO(Input(UInt(2.W)))
18 | val out1 = IO(Output(MyEnum()))
19 | val out2 = IO(Output(MyEnum()))
20 | def func(out: EnumType): Unit = {
21 | out := MyEnum(in)
22 | }
23 | func(out1)
24 | func(out2)
25 | }
26 |
27 | "Warnings" should "be de-duplicated" in {
28 | val (log, _) = grabLog(ChiselStage.elaborate(new MyModule))
29 | def countSubstring(s: String, sub: String) =
30 | s.sliding(sub.length).count(_ == sub)
31 | countSubstring(log, "Casting non-literal UInt") should be(1)
32 | }
33 |
34 | "Warnings" should "be treated as errors with warningsAsErrors" in {
35 | a[ChiselException] should be thrownBy extractCause[ChiselException] {
36 | val args = Array("--warnings-as-errors")
37 | ChiselStage.emitCHIRRTL(new MyModule, args)
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/WireSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import circt.stage.ChiselStage
7 |
8 | class WireSpec extends ChiselFlatSpec {
9 | "WireDefault.apply" should "work" in {
10 | assertCompiles("WireDefault(UInt(4.W), 2.U)")
11 | }
12 | it should "allow DontCare" in {
13 | assertCompiles("WireDefault(UInt(4.W), DontCare)")
14 | }
15 | it should "not allow DontCare to affect type inference" in {
16 | assertCompiles("val x: UInt = WireDefault(UInt(4.W), DontCare)")
17 | }
18 | it should "not allow init argument to affect type inference" in {
19 | assertDoesNotCompile("val x: UInt = WireDefault(UInt(4.W), 2.S)")
20 | }
21 | it should "have source locator information on wires" in {
22 | class Dummy extends chisel3.Module {
23 | val in = IO(Input(Bool()))
24 | val out = IO(Output(Bool()))
25 |
26 | val wire = WireInit(Bool(), true.B)
27 | val wire2 = Wire(Bool())
28 | wire2 := in
29 | out := in & wire & wire2
30 | }
31 |
32 | val chirrtl = ChiselStage.emitCHIRRTL(new Dummy)
33 | chirrtl should include("wire wire : UInt<1>")
34 | chirrtl should include("wire wire2 : UInt<1>")
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/util/CircuitMath.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | /** Circuit-land math operations.
4 | */
5 |
6 | package chisel3.util
7 |
8 | import chisel3._
9 |
10 | /** Returns the base-2 integer logarithm of an UInt.
11 | *
12 | * @note The result is truncated, so e.g. Log2(13.U) === 3.U
13 | *
14 | * @example {{{
15 | * Log2(8.U) // evaluates to 3.U
16 | * Log2(13.U) // evaluates to 3.U (truncation)
17 | * Log2(myUIntWire)
18 | * }}}
19 | */
20 | object Log2 {
21 |
22 | /** Returns the base-2 integer logarithm of the least-significant `width` bits of an UInt.
23 | */
24 | def apply(x: Bits, width: Int): UInt = {
25 | if (width < 2) {
26 | 0.U
27 | } else if (width == 2) {
28 | x(1)
29 | } else if (width <= divideAndConquerThreshold) {
30 | Mux(x(width - 1), (width - 1).asUInt, apply(x, width - 1))
31 | } else {
32 | val mid = 1 << (log2Ceil(width) - 1)
33 | val hi = x(width - 1, mid)
34 | val lo = x(mid - 1, 0)
35 | val useHi = hi.orR
36 | Cat(useHi, Mux(useHi, Log2(hi, width - mid), Log2(lo, mid)))
37 | }
38 | }
39 |
40 | def apply(x: Bits): UInt = apply(x, x.getWidth)
41 |
42 | private def divideAndConquerThreshold = 4
43 | }
44 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/ParameterizedModule.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.testers.BasicTester
7 |
8 | class ParameterizedModule(invert: Boolean) extends Module {
9 | val io = IO(new Bundle {
10 | val in = Input(Bool())
11 | val out = Output(Bool())
12 | })
13 | if (invert) {
14 | io.out := !io.in
15 | } else {
16 | io.out := io.in
17 | }
18 | }
19 |
20 | /** A simple test to check Module deduplication doesn't affect correctness (two
21 | * modules with the same name but different contents aren't aliased). Doesn't
22 | * check that deduplication actually happens, though.
23 | */
24 | class ParameterizedModuleTester() extends BasicTester {
25 | val invert = Module(new ParameterizedModule(true))
26 | val noninvert = Module(new ParameterizedModule(false))
27 |
28 | invert.io.in := true.B
29 | noninvert.io.in := true.B
30 | assert(invert.io.out === false.B)
31 | assert(noninvert.io.out === true.B)
32 |
33 | stop()
34 | }
35 |
36 | class ParameterizedModuleSpec extends ChiselFlatSpec {
37 | "Different parameterized modules" should "have different behavior" in {
38 | assertTesterPasses(new ParameterizedModuleTester())
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/AdderTree.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.testers.BasicTester
7 |
8 | class AdderTree[T <: Bits with Num[T]](genType: T, vecSize: Int) extends Module {
9 | val io = IO(new Bundle {
10 | val numIn = Input(Vec(vecSize, genType))
11 | val numOut = Output(genType)
12 | })
13 | io.numOut := io.numIn.reduceTree((a: T, b: T) => (a + b))
14 | }
15 |
16 | class AdderTreeTester(bitWidth: Int, numsToAdd: List[Int]) extends BasicTester {
17 | val genType = UInt(bitWidth.W)
18 | val dut = Module(new AdderTree(genType, numsToAdd.size))
19 | dut.io.numIn := VecInit(numsToAdd.map(x => x.asUInt(bitWidth.W)))
20 | val sumCorrect = dut.io.numOut === (numsToAdd.reduce(_ + _) % (1 << bitWidth)).asUInt(bitWidth.W)
21 | assert(sumCorrect)
22 | stop()
23 | }
24 |
25 | class AdderTreeSpec extends ChiselPropSpec {
26 | property("All numbers should be added correctly by an Adder Tree") {
27 | forAll(safeUIntN(20)) {
28 | case (w: Int, v: List[Int]) => {
29 | whenever(v.size > 0 && w > 0) {
30 | assertTesterPasses { new AdderTreeTester(w, v.map(x => math.abs(x) % (1 << w)).toList) }
31 | }
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/test/resources/chisel3/VerilogVendingMachine.v:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | // A simple Verilog FSM vending machine implementation
4 | module VerilogVendingMachine(
5 | input clock,
6 | input reset,
7 | input nickel,
8 | input dime,
9 | output dispense
10 | );
11 | parameter sIdle = 3'd0, s5 = 3'd1, s10 = 3'd2, s15 = 3'd3, sOk = 3'd4;
12 | reg [2:0] state;
13 |
14 | assign dispense = (state == sOk) ? 1'd1 : 1'd0;
15 |
16 | always @(posedge clock) begin
17 | if (reset) begin
18 | state <= sIdle;
19 | end else begin
20 | case (state)
21 | sIdle: begin
22 | if (nickel) state <= s5;
23 | else if (dime) state <= s10;
24 | else state <= state;
25 | end
26 | s5: begin
27 | if (nickel) state <= s10;
28 | else if (dime) state <= s15;
29 | else state <= state;
30 | end
31 | s10: begin
32 | if (nickel) state <= s15;
33 | else if (dime) state <= sOk;
34 | else state <= state;
35 | end
36 | s15: begin
37 | if (nickel) state <= sOk;
38 | else if (dime) state <= sOk;
39 | else state <= state;
40 | end
41 | sOk: begin
42 | state <= sIdle;
43 | end
44 | endcase
45 | end
46 | end
47 | endmodule
48 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/testers/BasicTester.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.testers
4 | import chisel3._
5 |
6 | import scala.language.experimental.macros
7 |
8 | import chisel3.internal.Builder.pushCommand
9 | import chisel3.internal.firrtl._
10 | import chisel3.experimental.SourceInfo
11 |
12 | class BasicTester extends Module() {
13 | // The testbench has no IOs, rather it should communicate using printf, assert, and stop.
14 | val io = IO(new Bundle() {})
15 |
16 | def popCount(n: Long): Int = n.toBinaryString.count(_ == '1')
17 |
18 | /** Ends the test reporting success.
19 | *
20 | * Does not fire when in reset (defined as the encapsulating Module's
21 | * reset). If your definition of reset is not the encapsulating Module's
22 | * reset, you will need to gate this externally.
23 | */
24 | def stop()(implicit sourceInfo: SourceInfo): Unit = chisel3.stop()
25 |
26 | /** The finish method provides a hook that subclasses of BasicTester can use to
27 | * alter a circuit after their constructor has been called.
28 | * For example, a specialized tester subclassing BasicTester could override finish in order to
29 | * add flow control logic for a decoupled io port of a device under test
30 | */
31 | def finish(): Unit = {}
32 | }
33 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/stage/ChiselOptionsViewSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests.stage
4 |
5 | import firrtl.options.Viewer.view
6 | import firrtl.RenameMap
7 |
8 | import chisel3.stage._
9 | import chisel3.internal.firrtl.Circuit
10 | import org.scalatest.flatspec.AnyFlatSpec
11 | import org.scalatest.matchers.should.Matchers
12 |
13 | class ChiselOptionsViewSpec extends AnyFlatSpec with Matchers {
14 |
15 | behavior.of(ChiselOptionsView.getClass.getName)
16 |
17 | it should "construct a view from an AnnotationSeq" in {
18 | val bar = Circuit("bar", Seq.empty, Seq.empty, RenameMap())
19 | val annotations = Seq(
20 | NoRunFirrtlCompilerAnnotation,
21 | PrintFullStackTraceAnnotation,
22 | ChiselOutputFileAnnotation("foo"),
23 | ChiselCircuitAnnotation(bar)
24 | )
25 | val out = view[ChiselOptions](annotations)
26 |
27 | info("runFirrtlCompiler was set to false")
28 | out.runFirrtlCompiler should be(false)
29 |
30 | info("printFullStackTrace was set to true")
31 | out.printFullStackTrace should be(true)
32 |
33 | info("outputFile was set to 'foo'")
34 | out.outputFile should be(Some("foo"))
35 |
36 | info("chiselCircuit was set to circuit 'bar'")
37 | out.chiselCircuit should be(Some(bar))
38 |
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/test/scala/examples/VendingMachineUtils.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package examples
4 |
5 | import scala.collection.mutable
6 |
7 | /* Useful utilities for testing vending machines */
8 | object VendingMachineUtils {
9 | abstract class Coin(val name: String, val value: Int)
10 | // US Coins
11 | case object Penny extends Coin("penny", 1)
12 | case object Nickel extends Coin("nickel", 5)
13 | case object Dime extends Coin("dime", 10)
14 | case object Quarter extends Coin("quarter", 25)
15 |
16 | // Harry Potter Coins
17 | case object Knut extends Coin("knut", Penny.value * 2) // Assuming 1 Knut is worth $0.02
18 | case object Sickle extends Coin("sickle", Knut.value * 29)
19 | case object Galleon extends Coin("galleon", Sickle.value * 17)
20 |
21 | def getExpectedResults(inputs: Seq[Option[Coin]], sodaCost: Int): Seq[Boolean] = {
22 | var value = 0
23 | val outputs = mutable.ArrayBuffer.empty[Boolean]
24 | for (input <- inputs) {
25 | val incValue = input match {
26 | case Some(coin) => coin.value
27 | case None => 0
28 | }
29 | if (value >= sodaCost) {
30 | outputs.append(true)
31 | value = 0
32 | } else {
33 | outputs.append(false)
34 | value += incValue
35 | }
36 | }
37 | outputs.toSeq
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/integration-tests/src/test/scala/chiselTests/util/experimental/algorithm/Bitwise.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | import chisel3._
4 | import chisel3.util._
5 | import chiseltest._
6 | import chiseltest.formal._
7 | import org.scalatest.flatspec.AnyFlatSpec
8 | import scala.math.min
9 |
10 | class ScanLeftOrTestModule(width: Int) extends Module {
11 | val input = IO(Input(UInt(width.W)))
12 |
13 | var lsb = false.B
14 | val vec = for (b <- input.asBools) yield {
15 | val cur = b || lsb
16 | lsb = cur
17 | cur
18 | }
19 | val ref = VecInit(vec).asUInt
20 |
21 | val testee = scanLeftOr(input)
22 |
23 | assert(testee === ref)
24 | }
25 |
26 | class ScanRightOrTestModule(width: Int) extends Module {
27 | val input = IO(Input(UInt(width.W)))
28 |
29 | val ref = Reverse(scanLeftOr(Reverse(input)))
30 | val testee = scanRightOr(input)
31 |
32 | assert(testee === ref)
33 | }
34 |
35 | class scanOrTest extends AnyFlatSpec with ChiselScalatestTester with Formal {
36 | "scanLeftOr" should "compute correctly" in {
37 | for (i <- 1 to 16) {
38 | verify(new ScanLeftOrTestModule(i), Seq(BoundedCheck(1)))
39 | }
40 | }
41 |
42 | "scanRightOr" should "compute correctly" in {
43 | for (i <- 1 to 16) {
44 | verify(new ScanRightOrTestModule(i), Seq(BoundedCheck(1)))
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/bus/common/Transaction.scala:
--------------------------------------------------------------------------------
1 | package caravan.bus.common
2 | import chisel3._
3 |
4 | /**
5 | * This abstract class provides a template for other protocols to implement the transaction wires.
6 | * This is used as a template for e.g when the core wants to communicate with the memory or with the peripheral registers.
7 | * It will set these signals up in order to talk to the Host adapter of the relevant bus protocol
8 | */
9 | abstract class AbstrRequest extends Bundle {
10 | val addrRequest: UInt
11 | val dataRequest: UInt
12 | val activeByteLane: UInt
13 | val isWrite: Bool
14 | }
15 |
16 | abstract class AbstrResponse extends Bundle {
17 | val dataResponse: UInt
18 | val error: Bool
19 | }
20 |
21 | /** The BusHost and BusDevice bundle classes
22 | * are common classes that each protocol's
23 | * Master and Slave bundles will extend (beneficial for type parameterization) */
24 | class BusHost extends Bundle
25 | class BusDevice extends Bundle
26 |
27 | /** The HostAdapter and DeviceAdapter is a class from which each host/device adapter
28 | * of a specific bus protocol will extend (beneficial for switch) */
29 | abstract class DeviceAdapter extends Module
30 | abstract class HostAdapter extends Module
31 |
32 | // created a trait so that each specific bus protocol
33 | // can extend from it (beneficial for type paremterization)
34 | trait BusConfig
--------------------------------------------------------------------------------
/src/test/scala/testCHA/chiselbook/Combinational/CombinationalTest.scala:
--------------------------------------------------------------------------------
1 | package testCHA.chiselbook.CombinationalTest
2 |
3 | import org.scalatest.flatspec._
4 | import org.scalatest.matchers.should._
5 | import chiseltest._
6 | import chiseltest.formal._
7 | import chiseltest.formal.chaAnno._
8 | import chisel3._
9 |
10 | class CombWhen2UntestedProp() extends CombWhen2Untested(){
11 |
12 | when (coinSum >= price) {
13 | assert(enoughMoney)
14 | chaAssert(this,"enoughMoney |-> F enoughMoney")
15 | }
16 |
17 |
18 | // for (i <- 0 until bitWidth) {
19 | // val ai = (io_a & (1.asUInt << i))(0) .asBool
20 | // val bi = (io_b & (1.asUInt << i))(0) .asBool
21 | // // chaAssert(this,"bi |-> F ai")
22 | // assert(ai)
23 | // }
24 |
25 |
26 | }
27 |
28 | class CombWhen2UntestedPropSpec extends AnyFlatSpec with ChiselScalatestTester with Formal {
29 | println(new (chisel3.stage.ChiselStage).emitSystemVerilog(new CombWhen2UntestedProp()))
30 | // behavior of "AdderProp1"
31 | // it should "pass" in {
32 | // verify(new AdderProp1(4), Seq(BoundedCheck(100), BtormcEngineAnnotation))
33 | // //verify(new GCD(), Seq(BoundedCheck(20), BtormcEngineAnnotation) )
34 | // //verify(new CounterProp1(4), Seq(BoundedCheck(20), BtormcEngineAnnotation))
35 | // //verify(new CounterProp2(4), Seq(BoundedCheck(20), BtormcEngineAnnotation))
36 | // }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/verilog.scala:
--------------------------------------------------------------------------------
1 | package chisel3
2 |
3 | import chisel3.stage.ChiselStage
4 | import firrtl.AnnotationSeq
5 |
6 | object getVerilogString {
7 |
8 | /**
9 | * Returns a string containing the Verilog for the module specified by
10 | * the target.
11 | *
12 | * @param gen the module to be converted to Verilog
13 | * @return a string containing the Verilog for the module specified by
14 | * the target
15 | */
16 | def apply(gen: => RawModule): String = ChiselStage.emitVerilog(gen)
17 |
18 | /**
19 | * Returns a string containing the Verilog for the module specified by
20 | * the target accepting arguments and annotations
21 | *
22 | * @param gen the module to be converted to Verilog
23 | * @param args arguments to be passed to the compiler
24 | * @param annotations annotations to be passed to the compiler
25 | * @return a string containing the Verilog for the module specified by
26 | * the target
27 | */
28 | def apply(gen: => RawModule, args: Array[String] = Array.empty, annotations: AnnotationSeq = Seq.empty): String =
29 | (new ChiselStage).emitVerilog(gen, args, annotations)
30 | }
31 |
32 | object emitVerilog {
33 | def apply(gen: => RawModule, args: Array[String] = Array.empty, annotations: AnnotationSeq = Seq.empty): Unit = {
34 | (new ChiselStage).emitVerilog(gen, args, annotations)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/scala/circt/stage/CIRCTOptions.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package circt.stage
4 |
5 | import java.io.File
6 |
7 | /** Options associated with CIRCT
8 | *
9 | * @param inputFile the name of an input FIRRTL IR file
10 | * @param outputFile the name of the file where the result will be written, if not split
11 | * @param preserveAggregate causes CIRCT to not lower aggregate FIRRTL IR types
12 | * @param target the specific IR or language target that CIRCT should compile to
13 | */
14 | class CIRCTOptions private[stage] (
15 | val inputFile: Option[File] = None,
16 | val outputFile: Option[File] = None,
17 | val preserveAggregate: Option[PreserveAggregate.Type] = None,
18 | val target: Option[CIRCTTarget.Type] = None,
19 | val firtoolOptions: Seq[String] = Seq.empty,
20 | val splitVerilog: Boolean = false) {
21 |
22 | private[stage] def copy(
23 | inputFile: Option[File] = inputFile,
24 | outputFile: Option[File] = outputFile,
25 | preserveAggregate: Option[PreserveAggregate.Type] = preserveAggregate,
26 | target: Option[CIRCTTarget.Type] = target,
27 | firtoolOptions: Seq[String] = firtoolOptions,
28 | splitVerilog: Boolean = splitVerilog
29 | ): CIRCTOptions = new CIRCTOptions(inputFile, outputFile, preserveAggregate, target, firtoolOptions, splitVerilog)
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/scala/circt/stage/package.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package circt
4 |
5 | import circt.stage.{CIRCTOption, CIRCTTargetAnnotation, PreserveAggregate}
6 |
7 | import firrtl.AnnotationSeq
8 | import firrtl.options.OptionsView
9 | import firrtl.stage.{FirrtlFileAnnotation, FirrtlOption, OutputFileAnnotation}
10 |
11 | import java.io.File
12 |
13 | package object stage {
14 |
15 | implicit object CIRCTOptionsView extends OptionsView[CIRCTOptions] {
16 |
17 | def view(annotations: AnnotationSeq): CIRCTOptions =
18 | annotations.collect {
19 | case a: CIRCTOption => a
20 | case a: FirrtlOption => a
21 | case a: FirrtlFileAnnotation => a
22 | }
23 | .foldLeft(new CIRCTOptions()) { (acc, c) =>
24 | c match {
25 | case FirrtlFileAnnotation(a) => acc.copy(inputFile = Some(new File(a)))
26 | case OutputFileAnnotation(a) => acc.copy(outputFile = Some(new File(a)))
27 | case CIRCTTargetAnnotation(a) => acc.copy(target = Some(a))
28 | case PreserveAggregate(a) => acc.copy(preserveAggregate = Some(a))
29 | case FirtoolOption(a) => acc.copy(firtoolOptions = acc.firtoolOptions :+ a)
30 | case SplitVerilog => acc.copy(splitVerilog = true)
31 | case _ => acc
32 | }
33 | }
34 |
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/stage/ChiselOptions.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.stage
4 |
5 | import chisel3.internal.firrtl.Circuit
6 | import java.io.File
7 |
8 | class ChiselOptions private[stage] (
9 | val runFirrtlCompiler: Boolean = true,
10 | val printFullStackTrace: Boolean = false,
11 | val throwOnFirstError: Boolean = false,
12 | val warningsAsErrors: Boolean = false,
13 | val outputFile: Option[String] = None,
14 | val chiselCircuit: Option[Circuit] = None,
15 | val sourceRoots: Vector[File] = Vector.empty) {
16 |
17 | private[stage] def copy(
18 | runFirrtlCompiler: Boolean = runFirrtlCompiler,
19 | printFullStackTrace: Boolean = printFullStackTrace,
20 | throwOnFirstError: Boolean = throwOnFirstError,
21 | warningsAsErrors: Boolean = warningsAsErrors,
22 | outputFile: Option[String] = outputFile,
23 | chiselCircuit: Option[Circuit] = chiselCircuit,
24 | sourceRoots: Vector[File] = sourceRoots
25 | ): ChiselOptions = {
26 |
27 | new ChiselOptions(
28 | runFirrtlCompiler = runFirrtlCompiler,
29 | printFullStackTrace = printFullStackTrace,
30 | throwOnFirstError = throwOnFirstError,
31 | warningsAsErrors = warningsAsErrors,
32 | outputFile = outputFile,
33 | chiselCircuit = chiselCircuit,
34 | sourceRoots = sourceRoots
35 | )
36 |
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/EnableShiftRegister.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 | import chisel3._
5 | import circt.stage.ChiselStage
6 |
7 | class EnableShiftRegister extends Module {
8 | val io = IO(new Bundle {
9 | val in = Input(UInt(4.W))
10 | val shift = Input(Bool())
11 | val out = Output(UInt(4.W))
12 | })
13 | val r0 = RegInit(0.U(4.W))
14 | val r1 = RegInit(0.U(4.W))
15 | val r2 = RegInit(0.U(4.W))
16 | val r3 = RegInit(0.U(4.W))
17 | when(io.shift) {
18 | r0 := io.in
19 | r1 := r0
20 | r2 := r1
21 | r3 := r2
22 | }
23 | io.out := r3
24 | }
25 |
26 | /*
27 | class EnableShiftRegisterTester(c: EnableShiftRegister) extends Tester(c) {
28 | val reg = Array.fill(4){ 0 }
29 | for (t <- 0 until 16) {
30 | val in = rnd.nextInt(16)
31 | val shift = rnd.nextInt(2)
32 | println("SHIFT " + shift + " IN " + in)
33 | poke(c.io.in, in)
34 | poke(c.io.shift, shift)
35 | step(1)
36 | if (shift == 1) {
37 | for (i <- 3 to 1 by -1)
38 | reg(i) = reg(i-1)
39 | reg(0) = in
40 | }
41 | expect(c.io.out, reg(3))
42 | }
43 | }
44 | */
45 |
46 | class EnableShiftRegisterSpec extends ChiselPropSpec {
47 |
48 | property("EnableShiftRegister should elaborate") {
49 | ChiselStage.elaborate { new EnableShiftRegister }
50 | }
51 |
52 | ignore("EnableShiftRegisterTester should return the correct result") {}
53 | }
54 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/TesterDriverSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.testers.BasicTester
7 | import chisel3.util._
8 |
9 | /** Extend BasicTester with a simple circuit and finish method. TesterDriver will call the
10 | * finish method after the FinishTester's constructor has completed, which will alter the
11 | * circuit after the constructor has finished.
12 | */
13 | class FinishTester extends BasicTester {
14 | val test_wire_width = 2
15 | val test_wire_override_value = 3
16 |
17 | val counter = Counter(1)
18 |
19 | when(counter.inc()) {
20 | stop()
21 | }
22 |
23 | val test_wire = WireDefault(1.U(test_wire_width.W))
24 |
25 | // though we just set test_wire to 1, the assert below will pass because
26 | // the finish will change its value
27 | assert(test_wire === test_wire_override_value.asUInt)
28 |
29 | /** In finish we use last connect semantics to alter the test_wire in the circuit
30 | * with a new value
31 | */
32 | override def finish(): Unit = {
33 | test_wire := test_wire_override_value.asUInt
34 | }
35 | }
36 |
37 | class TesterDriverSpec extends ChiselFlatSpec {
38 | "TesterDriver calls BasicTester's finish method which" should
39 | "allow modifications of test circuit after the tester's constructor is done" in {
40 | assertTesterPasses {
41 | new FinishTester
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/util/PipeSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests.util
4 |
5 | import chisel3._
6 | import chisel3.util.{Pipe, Valid}
7 | import chiselTests.ChiselFlatSpec
8 | import circt.stage.ChiselStage.emitCHIRRTL
9 |
10 | class PipeSpec extends ChiselFlatSpec {
11 | behavior.of("Pipe")
12 |
13 | it should "Have decent names for Pipe(2)" in {
14 | class MyModule extends Module {
15 | val foo = IO(Input(Valid(UInt(8.W))))
16 | val bar = IO(Output(Valid(UInt(8.W))))
17 | bar := Pipe(foo.valid, bar.bits, 2)
18 | }
19 | val chirrtl = emitCHIRRTL(new MyModule)
20 | chirrtl should include("reg bar_pipe_v")
21 | chirrtl should include("reg bar_pipe_pipe_v")
22 | chirrtl should include("wire bar_pipe_pipe_out")
23 | chirrtl should include("bar_pipe_pipe_out.valid <= bar_pipe_pipe_v")
24 | chirrtl should include("bar <= bar_pipe_pipe_out")
25 | }
26 |
27 | it should "Have decent names for Pipe(0)" in {
28 | class MyModule extends Module {
29 | val foo = IO(Input(Valid(UInt(8.W))))
30 | val bar = IO(Output(Valid(UInt(8.W))))
31 | bar := Pipe(foo.valid, foo.bits, 0)
32 | }
33 | val chirrtl = emitCHIRRTL(new MyModule)
34 | (chirrtl should not).include("pipe")
35 | chirrtl should include("wire bar_out")
36 | chirrtl should include("bar_out.valid <= foo.valid")
37 | chirrtl should include("bar <= bar_out")
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/Math.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | class Math extends ChiselPropSpec {
6 | import chisel3.util._
7 |
8 | property("unsignedBitLength is computed correctly") {
9 | forAll(safeUIntWidth) {
10 | case (width: Int) =>
11 | for (offset <- List(-1, 0, 1)) {
12 | val n = (1 << width) + offset
13 | if (n >= 0) {
14 | val d = unsignedBitLength(n)
15 | val t = if (n == 0) 0 else if (offset < 0) width else width + 1
16 | d shouldEqual (t)
17 | }
18 | }
19 | }
20 | }
21 |
22 | property("signedBitLength is computed correctly") {
23 | forAll(safeUIntWidth) {
24 | case (width: Int) =>
25 | for (offset <- List(-1, 0, 1)) {
26 | for (mult <- List(-1, +1)) {
27 | val n = ((1 << (width - 1)) + offset) * mult
28 | val d = signedBitLength(n)
29 | val t = n match {
30 | case -2 => 2
31 | case -1 => 1
32 | case 0 => 0
33 | case 1 => 2
34 | case 2 => 3
35 | case _ =>
36 | if (n > 0) {
37 | if (offset < 0) width else width + 1
38 | } else {
39 | if (offset > 0) width + 1 else width
40 | }
41 | }
42 | d shouldEqual (t)
43 | }
44 | }
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/chiselbook/Adder/AdderTest.scala:
--------------------------------------------------------------------------------
1 | package testCHA.chiselbook.adder
2 |
3 | import org.scalatest.flatspec._
4 | import org.scalatest.matchers.should._
5 | import chiseltest._
6 | import chiseltest.formal._
7 | import chiseltest.formal.chaAnno._
8 | import chisel3._
9 |
10 | class AdderProp1(bitWidth: Int) extends CarryRippleAdder(bitWidth){
11 | val io_a = io.a
12 | val io_b = io.b
13 | val io_cin = io.cin
14 | val io_c = io.c
15 | val io_cout = io.cout
16 |
17 |
18 | // for (i <- 0 until bitWidth) {
19 | // val ai = (io_a & (1.asUInt << i))(0) .asBool
20 | // val bi = (io_b & (1.asUInt << i))(0) .asBool
21 | // // chaAssert(this,"bi |-> F ai")
22 | // assert(ai)
23 | // }
24 |
25 | val ai = (io_a & (1.asUInt << 1))(0) .asBool
26 | val bi = (io_b & (1.asUInt << 1))(0) .asBool
27 | chaAssert(this,"bi |-> F ai")
28 |
29 | }
30 |
31 | class AdderFormalSpec extends AnyFlatSpec with ChiselScalatestTester with Formal {
32 | println(new (chisel3.stage.ChiselStage).emitSystemVerilog(new AdderProp1(4)))
33 | // behavior of "AdderProp1"
34 | // it should "pass" in {
35 | // verify(new AdderProp1(4), Seq(BoundedCheck(100), BtormcEngineAnnotation))
36 | // //verify(new GCD(), Seq(BoundedCheck(20), BtormcEngineAnnotation) )
37 | // //verify(new CounterProp1(4), Seq(BoundedCheck(20), BtormcEngineAnnotation))
38 | // //verify(new CounterProp2(4), Seq(BoundedCheck(20), BtormcEngineAnnotation))
39 | // }
40 | }
41 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/ChiselTestUtilitiesSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import org.scalatest.exceptions.TestFailedException
7 |
8 | class ChiselTestUtilitiesSpec extends ChiselFlatSpec {
9 | // Who tests the testers?
10 | "assertKnownWidth" should "error when the expected width is wrong" in {
11 | intercept[TestFailedException] {
12 | assertKnownWidth(7) {
13 | Wire(UInt(8.W))
14 | }
15 | }
16 | }
17 |
18 | it should "error when the width is unknown" in {
19 | intercept[ChiselException] {
20 | assertKnownWidth(7) {
21 | Wire(UInt())
22 | }
23 | }
24 | }
25 |
26 | it should "work if the width is correct" in {
27 | assertKnownWidth(8) {
28 | Wire(UInt(8.W))
29 | }
30 | }
31 |
32 | "assertInferredWidth" should "error if the width is known" in {
33 | intercept[TestFailedException] {
34 | assertInferredWidth(8) {
35 | Wire(UInt(8.W))
36 | }
37 | }
38 | }
39 |
40 | it should "error if the expected width is wrong" in {
41 | a[TestFailedException] shouldBe thrownBy {
42 | assertInferredWidth(8) {
43 | val w = Wire(UInt())
44 | w := 2.U(2.W)
45 | w
46 | }
47 | }
48 | }
49 |
50 | it should "pass if the width is correct" in {
51 | assertInferredWidth(4) {
52 | val w = Wire(UInt())
53 | w := 2.U(4.W)
54 | w
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/docs/src/images/type_hierarchy.dot:
--------------------------------------------------------------------------------
1 | digraph TypeHierarchy {
2 | graph [rankdir=BT bgcolor="transparent"]
3 | { node [style=filled,shape=box]
4 | { node [fillcolor="#f7fbff"]
5 | Data
6 | Element
7 | Bits Num
8 | Aggregate
9 | VecLike
10 | "Chisel Internal"
11 | }
12 | { node [fillcolor="#e5f5e0"]
13 | Bool UInt SInt
14 | FixedPoint Interval
15 | Analog
16 | Clock
17 | Reset
18 | AsyncReset
19 | Record
20 | Bundle
21 | Vec
22 | "Chisel Types"
23 | }
24 | { node [fillcolor="#fcbba1"]
25 | "User Types"
26 | Ellipsis [label="..."]
27 | }
28 |
29 | subgraph cluster_data_hierarchy {
30 | color=transparent
31 | Element
32 | Bits Num
33 | Reset Clock Analog
34 | UInt SInt FixedPoint Interval
35 | Bool
36 | color=transparent
37 | Aggregate
38 | VecLike
39 | Record
40 | Bundle
41 | Vec
42 |
43 | {Aggregate Element} -> Data
44 | {Bits Reset Clock Analog} -> Element
45 | {UInt SInt FixedPoint Interval} -> {Bits Num}
46 | Bool -> {UInt Reset}
47 | Ellipsis -> Bundle
48 | Ellipsis -> Record -> Aggregate
49 | Bundle -> Record
50 | Vec -> {Aggregate VecLike}
51 | AsyncReset -> {Element Reset}
52 | }
53 | subgraph cluster_legend {
54 | label=Legend
55 | "User Types" -> "Chisel Types" -> "Chisel Internal"
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/dontTouch.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3
4 |
5 | import chisel3.experimental.{annotate, requireIsHardware, ChiselAnnotation}
6 | import firrtl.transforms.DontTouchAnnotation
7 |
8 | /** Marks that a signal is an optimization barrier to Chisel and the FIRRTL compiler. This has the effect of
9 | * guaranteeing that a signal will not be removed.
10 | *
11 | * @example {{{
12 | * class MyModule extends Module {
13 | * val io = IO(new Bundle {
14 | * val a = Input(UInt(32.W))
15 | * val b = Output(UInt(32.W))
16 | * })
17 | * io.b := io.a
18 | * val dead = io.a +% 1.U // normally dead would be pruned by DCE
19 | * dontTouch(dead) // Marking it as such will preserve it
20 | * }
21 | * }}}
22 | * @note Because this is an optimization barrier, constants will not be propagated through a signal marked as
23 | * dontTouch.
24 | */
25 | object dontTouch {
26 |
27 | /** Mark a signal as an optimization barrier to Chisel and FIRRTL.
28 | *
29 | * @note Requires the argument to be bound to hardware
30 | * @param data The signal to be marked
31 | * @return Unmodified signal `data`
32 | */
33 | def apply[T <: Data](data: T)(implicit compileOptions: CompileOptions): T = {
34 | if (compileOptions.checkSynthesizable) {
35 | requireIsHardware(data, "Data marked dontTouch")
36 | }
37 | annotate(new ChiselAnnotation { def toFirrtl = DontTouchAnnotation(data.toNamed) })
38 | data
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/internal/BuilderContextCache.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.internal
4 |
5 | import scala.collection.mutable
6 |
7 | private[chisel3] object BuilderContextCache {
8 |
9 | /** Users of the [[BuilderContextCache]] must use a subclass of this type as a map key */
10 | abstract class Key[A]
11 |
12 | private[internal] def empty = new BuilderContextCache
13 | }
14 |
15 | import BuilderContextCache.Key
16 |
17 | /** Internal data structure for caching things during elaboration */
18 | private[chisel3] class BuilderContextCache private () {
19 | private val cache = mutable.HashMap.empty[Key[_], Any]
20 |
21 | /** Return the value associated with a key if present in the cache */
22 | def get[A](key: Key[A]): Option[A] = cache.get(key).map(_.asInstanceOf[A])
23 |
24 | /** Returns the value associated with a key, or a default value if the key is not contained in the map. */
25 | def getOrElse[A](key: Key[A], default: => A): A = cache.getOrElse(key, default).asInstanceOf[A]
26 |
27 | /** If a given key is already in the map, return the value
28 | *
29 | * Otherwise, update the map with the default value and return it.
30 | */
31 | def getOrElseUpdate[A](key: Key[A], default: => A): A = cache.getOrElseUpdate(key, default).asInstanceOf[A]
32 |
33 | /** Adds a new key/value pair to this map and optionally returns previously bound value. */
34 | def put[A](key: Key[A], value: A): Option[A] = cache.put(key, value).map(_.asInstanceOf[A])
35 | }
36 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/stage/phases/ElaborateSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests.stage.phases
4 |
5 | import chisel3._
6 | import chisel3.stage.{ChiselCircuitAnnotation, ChiselGeneratorAnnotation}
7 | import chisel3.stage.phases.Elaborate
8 |
9 | import firrtl.options.Phase
10 | import org.scalatest.flatspec.AnyFlatSpec
11 | import org.scalatest.matchers.should.Matchers
12 |
13 | class ElaborateSpec extends AnyFlatSpec with Matchers {
14 |
15 | class Foo extends Module {
16 | override def desiredName: String = "Foo"
17 | val io = IO(new Bundle {
18 | val in = Input(Bool())
19 | val out = Output(Bool())
20 | })
21 |
22 | io.out := ~io.in
23 | }
24 |
25 | class Bar extends Foo {
26 | override def desiredName: String = "Bar"
27 | }
28 |
29 | class Fixture { val phase: Phase = new Elaborate }
30 |
31 | behavior.of(classOf[Elaborate].toString)
32 |
33 | it should "expand ChiselGeneratorAnnotations into ChiselCircuitAnnotations and delete originals" in new Fixture {
34 | val annotations = Seq(ChiselGeneratorAnnotation(() => new Foo), ChiselGeneratorAnnotation(() => new Bar))
35 | val out = phase.transform(annotations)
36 |
37 | info("original annotations removed")
38 | out.collect { case a: ChiselGeneratorAnnotation => a } should be(empty)
39 |
40 | info("circuits created with the expected names")
41 | out.collect { case a: ChiselCircuitAnnotation => a.circuit.name } should be(Seq("Foo", "Bar"))
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/util/experimental/decode/Minimizer.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.util.experimental.decode
4 |
5 | abstract class Minimizer {
6 |
7 | /** Minimize a multi-input multi-output logic function given by the truth table `table`, with function output values
8 | * on unspecified inputs treated as `default`, and return a minimized PLA-like representation of the function.
9 | *
10 | * Each bit of `table[]._1` encodes one 1-bit input variable of the logic function, and each bit of `default` and
11 | * `table[]._2` represents one 1-bit output value of the function.
12 | *
13 | * @param table Truth table, can have don't cares in both inputs and outputs, specified as [(inputs, outputs), ...]
14 | * @return Minimized truth table, [(inputs, outputs), ...]
15 | *
16 | * @example {{{
17 | * minimize(BitPat("b?"), Seq(
18 | * (BitPat("b000"), BitPat("b0")),
19 | * // (BitPat("b001"), BitPat("b?")), // same as default, can be omitted
20 | * // (BitPat("b010"), BitPat("b?")), // same as default, can be omitted
21 | * (BitPat("b011"), BitPat("b0")),
22 | * (BitPat("b100"), BitPat("b1")),
23 | * (BitPat("b101"), BitPat("b1")),
24 | * (BitPat("b110"), BitPat("b0")),
25 | * (BitPat("b111"), BitPat("b1")),
26 | * ))
27 | * }}}
28 | */
29 | def minimize(table: TruthTable): TruthTable
30 | }
31 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/InstanceNameSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import circt.stage.ChiselStage
7 | import chisel3.util.Queue
8 |
9 | class InstanceNameModule extends Module {
10 | val io = IO(new Bundle {
11 | val foo = Input(UInt(32.W))
12 | val bar = Output(UInt(32.W))
13 | })
14 | val x = 3.U
15 | val y = UInt(8.W)
16 | val z = new Bundle {
17 | val foo = UInt(8.W)
18 | }
19 |
20 | val q = Module(new Queue(UInt(32.W), 4))
21 |
22 | io.bar := io.foo + x
23 | }
24 |
25 | class InstanceNameSpec extends ChiselFlatSpec {
26 | behavior.of("instanceName")
27 | val moduleName = "InstanceNameModule"
28 | var m: InstanceNameModule = _
29 | ChiselStage.elaborate { m = new InstanceNameModule; m }
30 |
31 | it should "work with module IO" in {
32 | val io = m.io.pathName
33 | assert(io == moduleName + ".io")
34 | }
35 |
36 | it should "work for literals" in {
37 | val x = m.x.pathName
38 | assert(x == moduleName + ".UInt<2>(\"h03\")")
39 | }
40 |
41 | it should "NOT work for non-hardware values" in {
42 | a[ChiselException] shouldBe thrownBy { m.y.pathName }
43 | a[ChiselException] shouldBe thrownBy { m.z.pathName }
44 | }
45 |
46 | it should "NOT work for non-hardware bundle elements" in {
47 | a[ChiselException] shouldBe thrownBy { m.z.foo.pathName }
48 | }
49 |
50 | it should "work with modules" in {
51 | val q = m.q.pathName
52 | assert(q == moduleName + ".q")
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/stage/package.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3
4 |
5 | import firrtl._
6 | import firrtl.options.OptionsView
7 |
8 | import chisel3.internal.firrtl.{Circuit => ChiselCircuit}
9 | import chisel3.stage.CircuitSerializationAnnotation.FirrtlFileFormat
10 |
11 | import scala.annotation.nowarn
12 |
13 | package object stage {
14 |
15 | final val pleaseSwitchToCIRCT = deprecatedMFCMessage + " Please switch to circt.stage.ChiselStage."
16 |
17 | @nowarn("cat=deprecation&msg=WarnReflectiveNamingAnnotation")
18 | implicit object ChiselOptionsView extends OptionsView[ChiselOptions] {
19 |
20 | def view(options: AnnotationSeq): ChiselOptions = options.collect { case a: ChiselOption => a }
21 | .foldLeft(new ChiselOptions()) { (c, x) =>
22 | x match {
23 | case NoRunFirrtlCompilerAnnotation => c.copy(runFirrtlCompiler = false)
24 | case PrintFullStackTraceAnnotation => c.copy(printFullStackTrace = true)
25 | case ThrowOnFirstErrorAnnotation => c.copy(throwOnFirstError = true)
26 | case WarningsAsErrorsAnnotation => c.copy(warningsAsErrors = true)
27 | case WarnReflectiveNamingAnnotation => c // Do nothing, ignored
28 | case ChiselOutputFileAnnotation(f) => c.copy(outputFile = Some(f))
29 | case ChiselCircuitAnnotation(a) => c.copy(chiselCircuit = Some(a))
30 | case SourceRootAnnotation(s) => c.copy(sourceRoots = c.sourceRoots :+ s)
31 | }
32 | }
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/experimental/Attach.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.experimental
4 |
5 | import chisel3.{ChiselException, RawModule}
6 | import chisel3.internal._
7 | import chisel3.internal.Builder.pushCommand
8 | import chisel3.internal.firrtl._
9 |
10 | object attach {
11 | // Exceptions that can be generated by attach
12 | case class AttachException(message: String) extends ChiselException(message)
13 | def ConditionalAttachException: AttachException =
14 | AttachException(": Conditional attach is not allowed!")
15 |
16 | // Actual implementation
17 | private[chisel3] def impl(elts: Seq[Analog], contextModule: RawModule)(implicit sourceInfo: SourceInfo): Unit = {
18 | if (Builder.whenDepth != 0) throw ConditionalAttachException
19 |
20 | // TODO Check that references are valid and can be attached
21 |
22 | pushCommand(Attach(sourceInfo, elts.map(_.lref)))
23 | }
24 |
25 | /** Create an electrical connection between [[Analog]] components
26 | *
27 | * @param elts The components to attach
28 | *
29 | * @example
30 | * {{{
31 | * val a1 = Wire(Analog(32.W))
32 | * val a2 = Wire(Analog(32.W))
33 | * attach(a1, a2)
34 | * }}}
35 | */
36 | def apply(elts: Analog*)(implicit sourceInfo: SourceInfo): Unit = {
37 | try {
38 | impl(elts, Builder.forcedUserModule)
39 | } catch {
40 | case AttachException(message) =>
41 | throwException(elts.mkString("Attaching (", ", ", s") failed @$message"))
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/util/PriorityMuxSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests.util
4 |
5 | import chisel3._
6 | import chisel3.testers.BasicTester
7 | import chisel3.util.{Counter, PriorityMux}
8 | import chiselTests.ChiselFlatSpec
9 | import circt.stage.ChiselStage.emitCHIRRTL
10 |
11 | class PriorityMuxTester extends BasicTester {
12 |
13 | val sel = Wire(UInt(3.W))
14 | sel := 0.U // default
15 |
16 | val elts = Seq(5.U, 6.U, 7.U)
17 | val muxed = PriorityMux(sel, elts)
18 |
19 | // Priority is given to lowest order bit
20 | val tests = Seq(
21 | 1.U -> elts(0),
22 | 2.U -> elts(1),
23 | 3.U -> elts(0),
24 | 4.U -> elts(2),
25 | 5.U -> elts(0),
26 | 6.U -> elts(1),
27 | 7.U -> elts(0)
28 | )
29 | val (cycle, done) = Counter(0 until tests.size + 1)
30 |
31 | for (((in, out), idx) <- tests.zipWithIndex) {
32 | when(cycle === idx.U) {
33 | sel := in
34 | assert(muxed === out)
35 | }
36 | }
37 |
38 | when(done) {
39 | stop()
40 | }
41 | }
42 |
43 | class PriorityMuxSpec extends ChiselFlatSpec {
44 | behavior.of("PriorityMux")
45 |
46 | it should "be functionally correct" in {
47 | assertTesterPasses(new PriorityMuxTester)
48 | }
49 |
50 | it should "be stack safe" in {
51 | emitCHIRRTL(new RawModule {
52 | val n = 1 << 15
53 | val in = IO(Input(Vec(n, UInt(8.W))))
54 | val sel = IO(Input(UInt(n.W)))
55 | val out = IO(Output(UInt(8.W)))
56 | out := PriorityMux(sel, in)
57 | })
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/experimental/hierarchy/LibraryHooks.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.experimental.hierarchy
4 |
5 | import chisel3.experimental.hierarchy.core.Underlying
6 | import scala.annotation.implicitNotFound
7 |
8 | @implicitNotFound("These functions are only for building hierarchy-compatible Chisel libraries! Users beware!")
9 | // DO NOT extend unless you know what you are doing!!!!!! Not for the casual user!
10 | trait InsideHierarchyLibraryExtension
11 |
12 | // Collection of public functions to give non-core-Chisel libraries the ability to build integrations with
13 | // the experimental hierarchy package
14 | object LibraryHooks {
15 |
16 | /** Builds a new instance given a definition and function to create a new instance-specific Underlying, from the
17 | * definition's Underlying
18 | * @note Implicitly requires being inside a Hierarchy Library Extension
19 | */
20 | def buildInstance[A](
21 | definition: Definition[A],
22 | createUnderlying: Underlying[A] => Underlying[A]
23 | )(
24 | implicit inside: InsideHierarchyLibraryExtension
25 | ): Instance[A] = {
26 | new Instance(createUnderlying(definition.underlying))
27 | }
28 |
29 | /** Builds a new definition given an Underlying implementation
30 | * @note Implicitly requires being inside a Hierarchy Library Extension
31 | */
32 | def buildDefinition[A](underlying: Underlying[A])(implicit inside: InsideHierarchyLibraryExtension): Definition[A] = {
33 | new Definition(underlying)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/integration-tests/src/test/scala/chiselTests/util/GrayCodeTests.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests.util
4 |
5 | import chisel3._
6 | import chisel3.util._
7 | import chiseltest._
8 | import chiseltest.formal._
9 | import org.scalatest.flatspec.AnyFlatSpec
10 |
11 | class GrayCodeTests extends AnyFlatSpec with ChiselScalatestTester with Formal {
12 | behavior.of("GrayCode")
13 |
14 | val Widths = Seq(1, 2, 3, 5, 8, 17, 65)
15 | Widths.foreach { w =>
16 | it should s"maintain identity (width=$w)" in {
17 | verify(new GrayCodeIdentityCheck(w), Seq(BoundedCheck(1)))
18 | }
19 |
20 | it should s"ensure hamming distance of one (width=$w)" in {
21 | verify(new GrayCodeHammingCheck(w), Seq(BoundedCheck(1)))
22 | }
23 | }
24 | }
25 |
26 | /** Checks that when we go from binary -> gray -> binary the result is always the same as the input. */
27 | private class GrayCodeIdentityCheck(width: Int) extends Module {
28 | val in = IO(Input(UInt(width.W)))
29 | val gray = BinaryToGray(in)
30 | val out = GrayToBinary(gray)
31 | assert(in === out, "%b -> %b -> %b", in, gray, out)
32 | }
33 |
34 | /** Checks that if we increment the binary number, the gray code equivalent only changes by one bit. */
35 | private class GrayCodeHammingCheck(width: Int) extends Module {
36 | val a = IO(Input(UInt(width.W)))
37 | val b = a + 1.U
38 | val aGray = BinaryToGray(a)
39 | val bGray = BinaryToGray(b)
40 | val hamming = PopCount(aGray ^ bGray)
41 | assert(hamming === 1.U, "%b ^ %b = %b", aGray, bGray, hamming)
42 | }
43 |
--------------------------------------------------------------------------------
/src/test/resources/chisel3/BlackBoxTest.v:
--------------------------------------------------------------------------------
1 | module BlackBoxInverter(
2 | input [0:0] in,
3 | output [0:0] out
4 | );
5 | assign out = !in;
6 | endmodule
7 |
8 | module BlackBoxPassthrough(
9 | input [0:0] in,
10 | output [0:0] out
11 | );
12 | assign out = in;
13 | endmodule
14 |
15 | module BlackBoxPassthrough2(
16 | input [0:0] in,
17 | output [0:0] out
18 | );
19 | assign out = in;
20 | endmodule
21 |
22 | module BlackBoxMinus(
23 | input [15:0] in1,
24 | input [15:0] in2,
25 | output [15:0] out
26 | );
27 | assign out = in1 + in2;
28 | endmodule
29 |
30 | module BlackBoxRegister(
31 | input [0:0] clock,
32 | input [0:0] in,
33 | output [0:0] out
34 | );
35 | reg [0:0] register;
36 | always @(posedge clock) begin
37 | register <= in;
38 | end
39 | assign out = register;
40 | endmodule
41 |
42 | module BlackBoxConstant #(
43 | parameter int WIDTH=1,
44 | parameter int VALUE=1
45 | ) (
46 | output [WIDTH-1:0] out
47 | );
48 | assign out = VALUE;
49 | endmodule
50 |
51 | module BlackBoxStringParam #(
52 | parameter string STRING = "zero"
53 | ) (
54 | output [31:0] out
55 | );
56 | assign out = (STRING == "one" )? 1 :
57 | (STRING == "two" )? 2 : 0;
58 | endmodule
59 |
60 | module BlackBoxRealParam #(
61 | parameter real REAL = 0.0
62 | ) (
63 | output [63:0] out
64 | );
65 | assign out = $realtobits(REAL);
66 | endmodule
67 |
68 | module BlackBoxTypeParam #(
69 | parameter type T = bit
70 | ) (
71 | output T out
72 | );
73 | assign out = 32'hdeadbeef;
74 | endmodule
75 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/ImplicitConversionsSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 |
7 | class ImplicitConversionsSpec extends ChiselFlatSpec {
8 | ".data on arbitrary Data objects" should "not work" in {
9 | assertTypeError("UInt(8.W).data")
10 | assertTypeError("8.S.data")
11 | assertTypeError("(new Bundle {}).data")
12 | assertTypeError("VecInit(1.U).data")
13 | }
14 |
15 | ".target on arbitrary Data objects" should "not work" in {
16 | assertTypeError("UInt(8.W).target")
17 | assertTypeError("8.S.target")
18 | assertTypeError("(new Bundle {}).target")
19 | assertTypeError("VecInit(1.U).target")
20 | }
21 |
22 | ".x on Strings and Numerical values" should "not work" in {
23 | assertTypeError("3.x")
24 | assertTypeError("3L.x")
25 | assertTypeError("BigInt(-4).x")
26 | assertTypeError("false.x")
27 | assertTypeError(""""a".x""")
28 | }
29 |
30 | ".bigint on Strings and Numerical values" should "not work" in {
31 | assertTypeError("3.bigint")
32 | assertTypeError("3L.bigint")
33 | assertTypeError("BigInt(-4).bigint")
34 | assertTypeError("false.bigint")
35 | assertTypeError(""""a".bigint""")
36 | }
37 |
38 | ".target on DecoupledIO" should "not work" in {
39 | import chisel3.util._
40 | assertTypeError("Decoupled(UInt(8.W)).target")
41 | }
42 |
43 | "X.B for X not in [0,1]" should "throw an exception, even outside hardware context" in {
44 | a[ChiselException] should be thrownBy {
45 | 65.B
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/scala/chisel3/testers/TestUtils.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.testers
4 |
5 | import chisel3.RawModule
6 | import chisel3.stage.ChiselGeneratorAnnotation
7 | import chisel3.testers.TesterDriver.Backend
8 | import circt.stage.{CIRCTTarget, CIRCTTargetAnnotation, ChiselStage}
9 | import firrtl.AnnotationSeq
10 | import firrtl.annotations.Annotation
11 | import firrtl.ir.Circuit
12 | import firrtl.options.{Dependency, TargetDirAnnotation}
13 | import firrtl.stage.FirrtlCircuitAnnotation
14 | import firrtl.util.BackendCompilationUtilities.createTestDirectory
15 | import org.scalatest.Assertions.fail
16 |
17 | object TestUtils {
18 | // Useful because TesterDriver.Backend is chisel3 package private
19 | def containsBackend(annos: AnnotationSeq): Boolean =
20 | annos.collectFirst { case b: Backend => b }.isDefined
21 |
22 | // This used for backward support of test that rely on chisel3 chirrtl generation and access to the annotations
23 | // produced by it. New tests should not utilize this or getFirrtlAndAnnos
24 | def getChirrtlAndAnnotations(gen: => RawModule, annos: AnnotationSeq = Seq()): (Circuit, Seq[Annotation]) = {
25 | val dir = createTestDirectory(this.getClass.getSimpleName).toString
26 | val processedAnnos = (new ChiselStage).execute(
27 | Array("--target-dir", dir, "--target", "chirrtl"),
28 | ChiselGeneratorAnnotation(() => gen) +: annos
29 | )
30 |
31 | val circuit = processedAnnos.collectFirst {
32 | case FirrtlCircuitAnnotation(a) => a
33 | }.get
34 | (circuit, processedAnnos)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/docs/src/explanations/explanations.md:
--------------------------------------------------------------------------------
1 | ---
2 | layout: docs
3 | title: "Explanations"
4 | section: "chisel3"
5 | ---
6 |
7 | # Explanations
8 |
9 | Explanation documentation gives background and context.
10 | They can also explain why things are so - design decisions,
11 | historical reasons, technical constraints.
12 |
13 | If you are just getting started with Chisel, we suggest you
14 | read these documents in the following order:
15 |
16 | * [Motivation](motivation)
17 | * [Supported Hardware](supported-hardware)
18 | * [Data Types](data-types)
19 | * [DataView](dataview)
20 | * [Bundles and Vecs](bundles-and-vecs)
21 | * [Combinational Circuits](combinational-circuits)
22 | * [Operators](operators)
23 | * [Width Inference](width-inference)
24 | * [Functional Abstraction](functional-abstraction)
25 | * [Ports](ports)
26 | * [Modules](modules)
27 | * [Sequential Circuits](sequential-circuits)
28 | * [Memories](memories)
29 | * [Interfaces and Connections](interfaces-and-connections)
30 | * [Black Boxes](blackboxes)
31 | * [Enumerations](chisel-enum)
32 | * [Functional Module Creation](functional-module-creation)
33 | * [Muxes and Input Selection](muxes-and-input-selection)
34 | * [Multiple Clock Domains](multi-clock)
35 | * [Reset](reset)
36 | * [Polymorphism and Paramterization](polymorphism-and-parameterization)
37 | * [Printing in Chisel](printing)
38 | * [Naming](naming)
39 | * [Unconnected Wires](unconnected-wires)
40 | * [Annotations](annotations)
41 | * [Deep Dive into Connection Operators](connection-operators)
42 | * [Chisel Type vs Scala Type](chisel-type-vs-scala-type)
43 | * [Connectable Operators](connectable)
44 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/ComplexAssign.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.testers.BasicTester
7 | import chisel3.util._
8 |
9 | class Complex[T <: Data](val re: T, val im: T) extends Bundle
10 |
11 | class ComplexAssign(w: Int) extends Module {
12 | val io = IO(new Bundle {
13 | val e = Input(Bool())
14 | val in = Input(new Complex(UInt(w.W), UInt(w.W)))
15 | val out = Output(new Complex(UInt(w.W), UInt(w.W)))
16 | })
17 | when(io.e) {
18 | val tmp = Wire(new Complex(UInt(w.W), UInt(w.W)))
19 | tmp := io.in
20 | io.out.re := tmp.re
21 | io.out.im := tmp.im
22 | }.otherwise {
23 | io.out.re := 0.U
24 | io.out.im := 0.U
25 | }
26 | }
27 |
28 | class ComplexAssignTester(enList: List[Boolean], re: Int, im: Int) extends BasicTester {
29 | val (cnt, wrap) = Counter(true.B, enList.size)
30 | val dut = Module(new ComplexAssign(32))
31 | dut.io.in.re := re.asUInt
32 | dut.io.in.im := im.asUInt
33 | dut.io.e := VecInit(enList.map(_.asBool))(cnt)
34 | val re_correct = dut.io.out.re === Mux(dut.io.e, dut.io.in.re, 0.U)
35 | val im_correct = dut.io.out.im === Mux(dut.io.e, dut.io.in.im, 0.U)
36 | assert(re_correct && im_correct)
37 | when(wrap) {
38 | stop()
39 | }
40 | }
41 |
42 | class ComplexAssignSpec extends ChiselPropSpec {
43 | property("All complex assignments should return the correct result") {
44 | forAll(enSequence(2), safeUInts, safeUInts) { (en: List[Boolean], re: Int, im: Int) =>
45 | assertTesterPasses { new ComplexAssignTester(en, re, im) }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/experimental/hierarchy/DefinitionClone.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.experimental.hierarchy
4 |
5 | import chisel3.experimental.BaseModule
6 | import chisel3.internal.{HasId, PseudoModule}
7 | import chisel3.internal.firrtl.{Component, Ref}
8 | import chisel3.CompileOptions
9 |
10 | /** Represents a Definition root module, when accessing something from a definition
11 | *
12 | * @note This is necessary to distinguish between the toTarget behavior for a Module returned from a Definition,
13 | * versus a normal Module. A normal Module.toTarget will always return a local target. If calling toTarget
14 | * on a Module returned from a Definition (and thus wrapped in an Instance), we need to return the non-local
15 | * target whose root is the Definition. This DefinitionClone is used to represent the root parent of the
16 | * InstanceClone (which represents the returned module).
17 | */
18 | private[chisel3] class DefinitionClone[T <: BaseModule](val getProto: T) extends PseudoModule with core.IsClone[T] {
19 | override def toString = s"DefinitionClone(${getProto})"
20 | // No addition components are generated
21 | private[chisel3] def generateComponent(): Option[Component] = None
22 | // Do not call default addId function, which may modify a module that is already "closed"
23 | override def addId(d: HasId): Unit = ()
24 | // Necessary for toTarget to work
25 | private[chisel3] def initializeInParent(parentCompileOptions: CompileOptions): Unit = ()
26 | // Module name is the same as proto's module name
27 | override def desiredName: String = getProto.name
28 | }
29 |
--------------------------------------------------------------------------------
/AdderProp1.sv:
--------------------------------------------------------------------------------
1 | module AdderProp1(
2 | input clock,
3 | input reset,
4 | input [3:0] io_a, // @[src/test/scala/testSVA/chiselbook/Adder/Adders.scala 7:14]
5 | input [3:0] io_b, // @[src/test/scala/testSVA/chiselbook/Adder/Adders.scala 7:14]
6 | input io_cin, // @[src/test/scala/testSVA/chiselbook/Adder/Adders.scala 7:14]
7 | output [3:0] io_c, // @[src/test/scala/testSVA/chiselbook/Adder/Adders.scala 7:14]
8 | output io_cout // @[src/test/scala/testSVA/chiselbook/Adder/Adders.scala 7:14]
9 | );
10 | wire [4:0] _res_T = io_a + io_b; // @[src/test/scala/testSVA/chiselbook/Adder/Adders.scala 26:18]
11 | wire [4:0] _GEN_0 = {{4'd0}, io_cin}; // @[src/test/scala/testSVA/chiselbook/Adder/Adders.scala 26:26]
12 | wire [4:0] res = _res_T + _GEN_0; // @[src/test/scala/testSVA/chiselbook/Adder/Adders.scala 26:26]
13 | wire [3:0] _ai_T_1 = io_a & 4'h2; // @[src/test/scala/testSVA/chiselbook/Adder/AdderTest.scala 25:18]
14 | wire ai = _ai_T_1[0]; // @[src/test/scala/testSVA/chiselbook/Adder/AdderTest.scala 25:41]
15 | wire [3:0] _bi_T_1 = io_b & 4'h2; // @[src/test/scala/testSVA/chiselbook/Adder/AdderTest.scala 26:18]
16 | wire bi = _bi_T_1[0]; // @[src/test/scala/testSVA/chiselbook/Adder/AdderTest.scala 26:41]
17 | wire en = ~reset; // @[chiseltest/src/main/scala/chiseltest/formal/svaAnno.scala 460:14]
18 | assign io_c = res[3:0]; // @[src/test/scala/testSVA/chiselbook/Adder/Adders.scala 27:17]
19 | assign io_cout = res[4]; // @[src/test/scala/testSVA/chiselbook/Adder/Adders.scala 28:17]
20 | always @(posedge clock) begin
21 | if (en) begin
22 | assert(bi |-> (eventually(ai)) )
23 | end
24 | end
25 | endmodule
26 |
--------------------------------------------------------------------------------
/website/project/Contributors.scala:
--------------------------------------------------------------------------------
1 | // See LICENSE for license details.
2 |
3 | import Version.GitHubRepository
4 |
5 | object Contributors {
6 |
7 | import github4s.Github
8 | import github4s.Github._
9 | import github4s.domain.User
10 |
11 | import java.util.concurrent.Executors
12 |
13 | import cats.effect.{Blocker, ContextShift, IO}
14 | import org.http4s.client.{Client, JavaNetClientBuilder}
15 |
16 | import scala.concurrent.ExecutionContext.global
17 |
18 | val httpClient: Client[IO] = {
19 | val blockingPool = Executors.newFixedThreadPool(5)
20 | val blocker = Blocker.liftExecutorService(blockingPool)
21 | implicit val cs: ContextShift[IO] = IO.contextShift(global)
22 | JavaNetClientBuilder[IO](blocker).create // use BlazeClientBuilder for production use
23 | }
24 |
25 | val token: Option[String] = sys.env.get("GITHUB_TOKEN")
26 |
27 | def contributors(repo: GitHubRepository): List[User] =
28 | Github[IO](httpClient, token)
29 | .repos
30 | .listContributors(repo.owner, repo.repo)
31 | .unsafeRunSync()
32 | .result match {
33 | case Left(e) => throw new Exception(
34 | s"Unable to fetch contributors for ${repo.serialize}. Did you misspell it? Did the repository move?" +
35 | s" Is access token defined: ${token.isDefined}? Original exception: ${e.getMessage}"
36 | )
37 | case Right(r) => r
38 | }
39 |
40 | def contributorsMarkdown(contributors: Seq[(String, String)]): String =
41 | contributors
42 | .sortBy(_._1.toLowerCase)
43 | .map { case (login, html_url) => s"- [`@${login}`](${html_url})" }
44 | .mkString("\n")
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/GCD.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.testers.BasicTester
7 | import circt.stage.ChiselStage
8 |
9 | class GCD extends Module {
10 | val io = IO(new Bundle {
11 | val a = Input(UInt(32.W))
12 | val b = Input(UInt(32.W))
13 | val e = Input(Bool())
14 | val z = Output(UInt(32.W))
15 | val v = Output(Bool())
16 | })
17 | val x = Reg(UInt(32.W))
18 | val y = Reg(UInt(32.W))
19 | when(x > y) { x := x -% y }.otherwise { y := y -% x }
20 | when(io.e) { x := io.a; y := io.b }
21 | io.z := x
22 | io.v := y === 0.U
23 | }
24 |
25 | class GCDTester(a: Int, b: Int, z: Int) extends BasicTester {
26 | val dut = Module(new GCD)
27 | val first = RegInit(true.B)
28 | dut.io.a := a.U
29 | dut.io.b := b.U
30 | dut.io.e := first
31 | when(first) { first := false.B }
32 | when(!first && dut.io.v) {
33 | assert(dut.io.z === z.U)
34 | stop()
35 | }
36 | }
37 |
38 | class GCDSpec extends ChiselPropSpec {
39 |
40 | //TODO: use generators and this function to make z's
41 | def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
42 |
43 | val gcds = Table(
44 | ("a", "b", "z"), // First tuple defines column names
45 | (64, 48, 16), // Subsequent tuples define the data
46 | (12, 9, 3),
47 | (48, 64, 16)
48 | )
49 |
50 | property("GCD should elaborate") {
51 | ChiselStage.elaborate { new GCD }
52 | }
53 |
54 | property("GCDTester should return the correct result") {
55 | forAll(gcds) { (a: Int, b: Int, z: Int) =>
56 | assertTesterPasses { new GCDTester(a, b, z) }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/IOCompatibility.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import circt.stage.ChiselStage
7 | import org.scalatest.matchers.should.Matchers
8 |
9 | class IOCSimpleIO extends Bundle {
10 | val in = Input(UInt(32.W))
11 | val out = Output(UInt(32.W))
12 | }
13 |
14 | class IOCPlusOne extends Module {
15 | val io = IO(new IOCSimpleIO)
16 | io.out := io.in + 1.U
17 | }
18 |
19 | class IOCModuleVec(val n: Int) extends Module {
20 | val io = IO(new Bundle {
21 | val ins = Vec(n, Input(UInt(32.W)))
22 | val outs = Vec(n, Output(UInt(32.W)))
23 | })
24 | val pluses = VecInit(Seq.fill(n) { Module(new IOCPlusOne).io })
25 | for (i <- 0 until n) {
26 | pluses(i).in := io.ins(i)
27 | io.outs(i) := pluses(i).out
28 | }
29 | }
30 |
31 | class IOCModuleWire extends Module {
32 | val io = IO(new IOCSimpleIO)
33 | val inc = Wire(chiselTypeOf(Module(new IOCPlusOne).io))
34 | inc.in := io.in
35 | io.out := inc.out
36 | }
37 |
38 | class IOCompatibilitySpec extends ChiselPropSpec with Matchers with Utils {
39 |
40 | property("IOCModuleVec should elaborate") {
41 | ChiselStage.elaborate { new IOCModuleVec(2) }
42 | }
43 |
44 | property("IOCModuleWire should elaborate") {
45 | ChiselStage.elaborate { new IOCModuleWire }
46 | }
47 |
48 | class IOUnwrapped extends Module {
49 | val io = new IOCSimpleIO
50 | io.out := io.in
51 | }
52 |
53 | property("Unwrapped IO should generate an exception") {
54 | a[BindingException] should be thrownBy extractCause[BindingException] {
55 | ChiselStage.elaborate(new IOUnwrapped)
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/MemorySearch.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import circt.stage.ChiselStage
7 |
8 | class MemorySearch extends Module {
9 | val io = IO(new Bundle {
10 | val target = Input(UInt(4.W))
11 | val en = Input(Bool())
12 | val done = Output(Bool())
13 | val address = Output(UInt(3.W))
14 | })
15 | val vals = Array(0, 4, 15, 14, 2, 5, 13)
16 | val index = RegInit(0.U(3.W))
17 | val elts = VecInit(vals.toIndexedSeq.map(_.asUInt(4.W)))
18 | // val elts = Mem(UInt(32.W), 8) TODO ????
19 | val elt = elts(index)
20 | val end = !io.en && ((elt === io.target) || (index === 7.U))
21 | when(io.en) {
22 | index := 0.U
23 | }.elsewhen(!end) {
24 | index := index +% 1.U
25 | }
26 | io.done := end
27 | io.address := index
28 | }
29 |
30 | /*
31 | class MemorySearchTester(c: MemorySearch) extends Tester(c) {
32 | val list = c.vals
33 | val n = 8
34 | val maxT = n * (list.length + 3)
35 | for (k <- 0 until n) {
36 | val target = rnd.nextInt(16)
37 | poke(c.io.en, 1)
38 | poke(c.io.target, target)
39 | step(1)
40 | poke(c.io.en, 0)
41 | do {
42 | step(1)
43 | } while (peek(c.io.done) == 0 && t < maxT)
44 | val addr = peek(c.io.address).toInt
45 | expect(addr == list.length || list(addr) == target,
46 | "LOOKING FOR " + target + " FOUND " + addr)
47 | }
48 | }
49 | */
50 |
51 | class MemorySearchSpec extends ChiselPropSpec {
52 |
53 | property("MemorySearch should elaborate") {
54 | ChiselStage.elaborate { new EnableShiftRegister }
55 | }
56 |
57 | ignore("MemorySearch should return the correct result") {}
58 | }
59 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/stage/phases/AddImplicitOutputAnnotationFileSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests.stage.phases
4 |
5 | import chisel3.RawModule
6 | import chisel3.stage.ChiselGeneratorAnnotation
7 | import chisel3.stage.phases.{AddImplicitOutputAnnotationFile, Elaborate}
8 |
9 | import firrtl.AnnotationSeq
10 | import firrtl.options.{OutputAnnotationFileAnnotation, Phase}
11 | import org.scalatest.flatspec.AnyFlatSpec
12 | import org.scalatest.matchers.should.Matchers
13 |
14 | class AddImplicitOutputAnnotationFileSpec extends AnyFlatSpec with Matchers {
15 |
16 | class Foo extends RawModule { override val desiredName = "Foo" }
17 |
18 | class Fixture { val phase: Phase = new AddImplicitOutputAnnotationFile }
19 |
20 | behavior.of(classOf[AddImplicitOutputAnnotationFile].toString)
21 |
22 | it should "not override an existing OutputAnnotationFileAnnotation" in new Fixture {
23 | val annotations: AnnotationSeq =
24 | Seq(ChiselGeneratorAnnotation(() => new Foo), OutputAnnotationFileAnnotation("Bar"))
25 |
26 | Seq(new Elaborate, phase)
27 | .foldLeft(annotations)((a, p) => p.transform(a))
28 | .collect { case a: OutputAnnotationFileAnnotation => a.file }
29 | .toSeq should be(Seq("Bar"))
30 | }
31 |
32 | it should "generate an OutputAnnotationFileAnnotation from a ChiselCircuitAnnotation" in new Fixture {
33 | val annotations: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new Foo))
34 |
35 | Seq(new Elaborate, phase)
36 | .foldLeft(annotations)((a, p) => p.transform(a))
37 | .collect { case a: OutputAnnotationFileAnnotation => a.file }
38 | .toSeq should be(Seq("Foo"))
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/SwitchSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.util.{is, switch}
7 | import circt.stage.ChiselStage
8 |
9 | class SwitchSpec extends ChiselFlatSpec with Utils {
10 | "switch" should "require literal conditions" in {
11 | a[java.lang.IllegalArgumentException] should be thrownBy extractCause[IllegalArgumentException] {
12 | ChiselStage.elaborate(new Module {
13 | val io = IO(new Bundle {})
14 | val state = RegInit(0.U)
15 | val wire = WireDefault(0.U)
16 | switch(state) {
17 | is(wire) { state := 1.U }
18 | }
19 | })
20 | }
21 | }
22 | it should "require mutually exclusive conditions" in {
23 | a[java.lang.IllegalArgumentException] should be thrownBy extractCause[IllegalArgumentException] {
24 | ChiselStage.elaborate(new Module {
25 | val io = IO(new Bundle {})
26 | val state = RegInit(0.U)
27 | switch(state) {
28 | is(0.U) { state := 1.U }
29 | is(1.U) { state := 2.U }
30 | is(0.U) { state := 3.U }
31 | }
32 | })
33 | }
34 | }
35 | it should "provide useful source locators" in {
36 | val chirrtl = ChiselStage.emitCHIRRTL(new Module {
37 | val io = IO(new Bundle {
38 | val in = Input(UInt(2.W))
39 | val out = Output(UInt(2.W))
40 | })
41 |
42 | io.out := 0.U
43 | switch(io.in) {
44 | is(0.U) { io.out := 3.U }
45 | is(1.U) { io.out := 0.U }
46 | is(2.U) { io.out := 1.U }
47 | is(3.U) { io.out := 3.U }
48 | }
49 | })
50 |
51 | (chirrtl should not).include("Conditional.scala")
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/test/scala/cookbook/FSM.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package cookbook
4 |
5 | import chisel3._
6 | import chisel3.util._
7 |
8 | /* ### How do I create a finite state machine?
9 | *
10 | * Use ChiselEnum to construct the states and switch & is to construct the FSM
11 | * control logic
12 | */
13 |
14 | class DetectTwoOnes extends Module {
15 | val io = IO(new Bundle {
16 | val in = Input(Bool())
17 | val out = Output(Bool())
18 | })
19 |
20 | object State extends ChiselEnum {
21 | val sNone, sOne1, sTwo1s = Value
22 | }
23 |
24 | val state = RegInit(State.sNone)
25 |
26 | io.out := (state === State.sTwo1s)
27 |
28 | switch(state) {
29 | is(State.sNone) {
30 | when(io.in) {
31 | state := State.sOne1
32 | }
33 | }
34 | is(State.sOne1) {
35 | when(io.in) {
36 | state := State.sTwo1s
37 | }.otherwise {
38 | state := State.sNone
39 | }
40 | }
41 | is(State.sTwo1s) {
42 | when(!io.in) {
43 | state := State.sNone
44 | }
45 | }
46 | }
47 | }
48 |
49 | class DetectTwoOnesTester extends CookbookTester(10) {
50 |
51 | val dut = Module(new DetectTwoOnes)
52 |
53 | // Inputs and expected results
54 | val inputs: Vec[Bool] = VecInit(false.B, true.B, false.B, true.B, true.B, true.B, false.B, true.B, true.B, false.B)
55 | val expected: Vec[Bool] =
56 | VecInit(false.B, false.B, false.B, false.B, false.B, true.B, true.B, false.B, false.B, true.B)
57 |
58 | dut.io.in := inputs(cycle)
59 | assert(dut.io.out === expected(cycle))
60 | }
61 |
62 | class FSMSpec extends CookbookSpec {
63 | "DetectTwoOnes" should "work" in {
64 | assertTesterPasses { new DetectTwoOnesTester }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/experimental/hierarchy/InstanceClone.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.experimental.hierarchy
4 |
5 | import chisel3.experimental.BaseModule
6 | import chisel3.internal.PseudoModule
7 | import chisel3.internal.firrtl.{Component, Ref}
8 | import chisel3.CompileOptions
9 |
10 | /** Represents a module viewed from a different instance context.
11 | *
12 | * @note Why do we need both ModuleClone and InstanceClone? If we are annotating a reference in a module-clone,
13 | * all submodules must be also be 'cloned' so the toTarget can be computed properly. However, we don't need separate
14 | * connectable ports for this instance; all that's different from the proto is the parent.
15 | *
16 | * @note In addition, the instance name of an InstanceClone is going to be the SAME as the proto, but this is not true
17 | * for ModuleClone.
18 | */
19 | private[chisel3] final class InstanceClone[T <: BaseModule](val getProto: T, val instName: () => String)
20 | extends PseudoModule
21 | with core.IsClone[T] {
22 | override def toString = s"InstanceClone(${getProto})"
23 | // No addition components are generated
24 | private[chisel3] def generateComponent(): Option[Component] = None
25 | // Necessary for toTarget to work
26 | private[chisel3] def setAsInstanceRef(): Unit = { this.setRef(Ref(instName())) }
27 | // This module doesn't acutally exist in the FIRRTL so no initialization to do
28 | private[chisel3] def initializeInParent(parentCompileOptions: CompileOptions): Unit = ()
29 | // Instance name is the same as proto's instance name
30 | override def instanceName = instName()
31 | // Module name is the same as proto's module name
32 | override def desiredName: String = getProto.name
33 | }
34 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/aop/Aspect.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.aop
4 |
5 | import chisel3.RawModule
6 | import firrtl.annotations.{Annotation, NoTargetAnnotation}
7 | import firrtl.options.Unserializable
8 | import firrtl.AnnotationSeq
9 |
10 | /** Represents an aspect of a Chisel module, by specifying
11 | * what behavior should be done to instance, via the FIRRTL Annotation Mechanism
12 | * @tparam T Type of top-level module
13 | */
14 | abstract class Aspect[T <: RawModule] extends Annotation with Unserializable with NoTargetAnnotation {
15 |
16 | /** variable to save [[AnnotationSeq]] from [[chisel3.stage.phases.AspectPhase]]
17 | * to be used at [[chisel3.aop.injecting.InjectorAspect]], exposes annotations to [[chisel3.internal.DynamicContext]]
18 | */
19 | private[aop] var annotationsInAspect: AnnotationSeq = Seq()
20 |
21 | /** Convert this Aspect to a seq of FIRRTL annotation
22 | * @param top
23 | * @return
24 | */
25 | def toAnnotation(top: T): AnnotationSeq
26 |
27 | /** Called by [[chisel3.stage.phases.AspectPhase]] to resolve this Aspect into annotations
28 | * @param top
29 | * @return
30 | */
31 | private[chisel3] def resolveAspect(top: RawModule, remainingAnnotations: AnnotationSeq): AnnotationSeq = {
32 | annotationsInAspect = remainingAnnotations
33 | toAnnotation(top.asInstanceOf[T])
34 | }
35 | }
36 |
37 | /** Holds utility functions for Aspect stuff */
38 | object Aspect {
39 |
40 | /** Converts elaborated Chisel components to FIRRTL modules
41 | * @param chiselIR
42 | * @return
43 | */
44 | def getFirrtl(chiselIR: chisel3.internal.firrtl.Circuit): firrtl.ir.Circuit = {
45 | chisel3.internal.firrtl.Converter.convert(chiselIR)
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/util/BitPatSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests.util
4 |
5 | import chisel3.util.BitPat
6 | import circt.stage.ChiselStage
7 | import org.scalatest.flatspec.AnyFlatSpec
8 | import org.scalatest.matchers.should.Matchers
9 |
10 | class BitPatSpec extends AnyFlatSpec with Matchers {
11 | behavior.of(classOf[BitPat].toString)
12 |
13 | it should "convert a BitPat to readable form" in {
14 | val testPattern = "0" * 32 + "1" * 32 + "?" * 32 + "?01" * 32
15 | BitPat("b" + testPattern).toString should be(s"BitPat($testPattern)")
16 | }
17 |
18 | it should "convert a BitPat to raw form" in {
19 | val testPattern = "0" * 32 + "1" * 32 + "?" * 32 + "?01" * 32
20 | BitPat("b" + testPattern).rawString should be(testPattern)
21 | }
22 |
23 | it should "not fail if BitPat width is 0" in {
24 | intercept[IllegalArgumentException] { BitPat("b") }
25 | }
26 |
27 | it should "concat BitPat via ##" in {
28 | (BitPat.Y(4) ## BitPat.dontCare(3) ## BitPat.N(2)).toString should be(s"BitPat(1111???00)")
29 | }
30 |
31 | it should "throw when BitPat apply to a Hardware" in {
32 | intercept[java.lang.IllegalArgumentException] {
33 | ChiselStage.emitCHIRRTL(new chisel3.Module {
34 | BitPat(chisel3.Reg(chisel3.Bool()))
35 | })
36 | }
37 | }
38 |
39 | it should "index and return new BitPat" in {
40 | val b = BitPat("b1001???")
41 | b(0) should be(BitPat.dontCare(1))
42 | b(6) should be(BitPat.Y())
43 | b(5) should be(BitPat.N())
44 | }
45 |
46 | it should "slice and return new BitPat" in {
47 | val b = BitPat("b1001???")
48 | b(2, 0) should be(BitPat("b???"))
49 | b(4, 3) should be(BitPat("b01"))
50 | b(6, 6) should be(BitPat("b1"))
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/DontTouchSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import circt.stage.ChiselStage
7 |
8 | class HasDeadCodeChild(withDontTouch: Boolean) extends Module {
9 | val io = IO(new Bundle {
10 | val a = Input(UInt(32.W))
11 | val b = Output(UInt(32.W))
12 | val c = Output(Vec(2, UInt(32.W)))
13 | })
14 | io.b := io.a
15 | io.c := DontCare
16 | if (withDontTouch) {
17 | dontTouch(io.c)
18 | }
19 | }
20 |
21 | class HasDeadCode(withDontTouch: Boolean) extends Module {
22 | val io = IO(new Bundle {
23 | val a = Input(UInt(32.W))
24 | val b = Output(UInt(32.W))
25 | })
26 | val inst = Module(new HasDeadCodeChild(withDontTouch))
27 | inst.io.a := io.a
28 | io.b := inst.io.b
29 | val dead = WireDefault(io.a + 1.U)
30 | if (withDontTouch) {
31 | dontTouch(dead)
32 | }
33 | }
34 |
35 | class DontTouchSpec extends ChiselFlatSpec with Utils {
36 | val deadSignals = List(
37 | "io_c_0",
38 | "io_c_1",
39 | "dead"
40 | )
41 | "Dead code" should "be removed by default" in {
42 | val verilog = compile(new HasDeadCode(false))
43 | for (signal <- deadSignals) {
44 | (verilog should not).include(signal)
45 | }
46 | }
47 | it should "NOT be removed if marked dontTouch" in {
48 | val verilog = compile(new HasDeadCode(true))
49 | for (signal <- deadSignals) {
50 | verilog should include(signal)
51 | }
52 | }
53 | "Dont touch" should "only work on bound hardware" in {
54 | a[chisel3.BindingException] should be thrownBy extractCause[BindingException] {
55 | ChiselStage.elaborate(new Module {
56 | val io = IO(new Bundle {})
57 | dontTouch(new Bundle { val a = UInt(32.W) })
58 | })
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/NamedModuleTester.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.experimental.AffectsChiselPrefix
7 |
8 | import scala.collection.mutable.ListBuffer
9 |
10 | trait NamedModuleTester extends Module with AffectsChiselPrefix {
11 | val expectedNameMap = ListBuffer[(InstanceId, String)]()
12 | val expectedModuleNameMap = ListBuffer[(Module, String)]()
13 |
14 | /** Expects some name for a node that is propagated to FIRRTL.
15 | * The node is returned allowing this to be called inline.
16 | */
17 | def expectName[T <: InstanceId](node: T, fullName: String): T = {
18 | expectedNameMap += ((node, fullName))
19 | node
20 | }
21 |
22 | /** Expects some name for a module declaration that is propagated to FIRRTL.
23 | * The node is returned allowing this to be called inline.
24 | */
25 | def expectModuleName[T <: Module](node: T, fullName: String): T = {
26 | expectedModuleNameMap += ((node, fullName))
27 | node
28 | }
29 |
30 | /** After this module has been elaborated, returns a list of (node, expected name, actual name)
31 | * that did not match expectations.
32 | * Returns an empty list if everything was fine.
33 | */
34 | def getNameFailures(): List[(InstanceId, String, String)] = {
35 | val failures = ListBuffer[(InstanceId, String, String)]()
36 | for ((ref, expectedName) <- expectedNameMap) {
37 | if (ref.instanceName != expectedName) {
38 | failures += ((ref, expectedName, ref.instanceName))
39 | }
40 | }
41 | for ((mod, expectedModuleName) <- expectedModuleNameMap) {
42 | if (mod.name != expectedModuleName) {
43 | failures += ((mod, expectedModuleName, mod.name))
44 | }
45 | }
46 | failures.toList
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/bus/tilelink/Harness.scala:
--------------------------------------------------------------------------------
1 | package caravan.bus.tilelink
2 | import caravan.bus.common.{AddressMap, BusDecoder, DeviceAdapter, Switch1toN, DummyMemController}
3 | import chisel3._
4 | import chisel3.experimental.ChiselEnum
5 | import chisel3.stage.ChiselStage
6 | import chisel3.util.{Cat, Decoupled, MuxLookup}
7 | import chisel3.util.experimental.loadMemoryFromFile
8 |
9 |
10 | class Harness/*(programFile: Option[String])*/(implicit val config: TilelinkConfig) extends Module {
11 | val io = IO(new Bundle {
12 | val valid = Input(Bool())
13 | val addrReq = Input(UInt(config.a.W))
14 | val dataReq = Input(UInt((config.w * 8).W))
15 | val byteLane = Input(UInt(config.w.W))
16 | val isWrite = Input(Bool())
17 |
18 | val validResp = Output(Bool())
19 | val dataResp = Output(UInt(32.W))
20 | })
21 |
22 | implicit val request = new TLRequest()
23 | implicit val response = new TLResponse()
24 |
25 | val tlHost = Module(new TilelinkHost())
26 | val tlSlave = Module(new TilelinkDevice())
27 | val memCtrl = Module(new DummyMemController())
28 |
29 | tlHost.io.rspOut.ready := true.B // IP always ready to accept data from wb host
30 |
31 | tlHost.io.tlMasterTransmitter <> tlSlave.io.tlMasterReceiver
32 | tlSlave.io.tlSlaveTransmitter <> tlHost.io.tlSlaveReceiver
33 |
34 | tlHost.io.reqIn.valid := Mux(tlHost.io.reqIn.ready, io.valid, false.B)
35 | tlHost.io.reqIn.bits.addrRequest := io.addrReq
36 | tlHost.io.reqIn.bits.dataRequest := io.dataReq
37 | tlHost.io.reqIn.bits.activeByteLane := io.byteLane
38 | tlHost.io.reqIn.bits.isWrite := io.isWrite
39 |
40 |
41 |
42 | tlSlave.io.reqOut <> memCtrl.io.req
43 | tlSlave.io.rspIn <> memCtrl.io.rsp
44 |
45 | io.dataResp := tlHost.io.rspOut.bits.dataResponse
46 | io.validResp := tlHost.io.rspOut.valid
47 |
48 | }
49 |
50 |
51 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/util/circt/SizeOf.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.util.circt
4 |
5 | import scala.util.hashing.MurmurHash3
6 |
7 | import chisel3._
8 | import chisel3.experimental.{annotate, ChiselAnnotation, ExtModule}
9 | import chisel3.internal.{Builder, BuilderContextCache}
10 |
11 | import circt.Intrinsic
12 |
13 | // We have to unique designedName per type, be we can't due to name conflicts
14 | // on bundles. Thus we use a globally unique id.
15 | private object SizeOfGlobalIDGen {
16 | private case object CacheKey extends BuilderContextCache.Key[Int]
17 | def getID() = {
18 | val oldID = Builder.contextCache.getOrElse(CacheKey, 0)
19 | Builder.contextCache.put(CacheKey, oldID + 1)
20 | oldID
21 | }
22 | }
23 |
24 | /** Create a module with a parameterized type which returns the size of the type
25 | * as a compile-time constant. This lets you write code which depends on the
26 | * results of type inference.
27 | */
28 | private class SizeOfIntrinsic[T <: Data](gen: T) extends ExtModule {
29 | val i = IO(Input(gen));
30 | val size = IO(Output(UInt(32.W)))
31 | annotate(new ChiselAnnotation {
32 | override def toFirrtl =
33 | Intrinsic(toTarget, "circt.sizeof")
34 | })
35 | override val desiredName = "SizeOf_" + SizeOfGlobalIDGen.getID()
36 | }
37 |
38 | object SizeOf {
39 |
40 | /** Creates an intrinsic which returns the size of a type. The returned size
41 | * is after width inference, so you can use this to compute expressions based
42 | * on the inferred size of types.
43 | *
44 | * @example {{{
45 | * val a = Wire(UInt())
46 | * a := 1 << (SizeOf(a) - 1)
47 | * }}}
48 | */
49 | def apply[T <: Data](gen: T): Data = {
50 | val sizeOfInst = Module(new SizeOfIntrinsic(chiselTypeOf(gen)))
51 | sizeOfInst.i := gen
52 | sizeOfInst.size
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/test/scala/testCHA/bus/wishbone/WishboneErr.scala:
--------------------------------------------------------------------------------
1 | package caravan.bus.wishbone
2 | import chisel3._
3 | import chisel3.stage.ChiselStage
4 | import chisel3.util.{Decoupled, Fill}
5 |
6 | class WishboneErr(implicit val config: WishboneConfig) extends Module {
7 | val io = IO(new Bundle {
8 | val wbSlaveTransmitter = Decoupled(new WishboneSlave())
9 | val wbMasterReceiver = Flipped(Decoupled(new WishboneMaster()))
10 | })
11 |
12 | def fire: Bool = io.wbMasterReceiver.valid && io.wbMasterReceiver.bits.cyc && io.wbMasterReceiver.bits.stb
13 |
14 | val ackReg = RegInit(false.B)
15 | val dataReg = RegInit(0.U)
16 | val errReg = RegInit(false.B)
17 | val validReg = RegInit(false.B)
18 | /** FIXME: Assuming wishbone slave is always ready to accept master req */
19 | io.wbMasterReceiver.ready := true.B
20 |
21 | when(fire) {
22 | // a valid request from the host. The decoder pointed to us which means there was a wrong address given by the user
23 | // for writes we are going to ignore them completely.
24 | // for reads we are going to signal an err out and send all FFFs.
25 | errReg := true.B
26 | validReg := true.B
27 | when(io.wbMasterReceiver.bits.we) {
28 | // WRITE
29 | dataReg := DontCare
30 | } .otherwise {
31 | // READ
32 | dataReg := Fill(config.dataWidth/4, "hf".U)
33 | }
34 |
35 | } .otherwise {
36 | // no valid request from the host
37 | dataReg := 0.U
38 | errReg := false.B
39 | validReg := false.B
40 | }
41 |
42 | io.wbSlaveTransmitter.valid := validReg
43 | io.wbSlaveTransmitter.bits.ack := ackReg
44 | io.wbSlaveTransmitter.bits.dat := dataReg
45 | io.wbSlaveTransmitter.bits.err := errReg
46 |
47 | }
48 |
49 | object WishboneErrDriver extends App {
50 | implicit val config = WishboneConfig(10, 32)
51 | println((new ChiselStage).emitVerilog(new WishboneErr()))
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/stage/phases/AddSerializationAnnotations.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.stage.phases
4 |
5 | import firrtl.AnnotationSeq
6 | import firrtl.options.{Dependency, Phase}
7 | import firrtl.options.Viewer.view
8 |
9 | import chisel3.stage._
10 | import chisel3.stage.CircuitSerializationAnnotation._
11 | import chisel3.ChiselException
12 |
13 | /** Adds [[stage.CircuitSerializationAnnotation]]s based on [[ChiselOutputFileAnnotation]]
14 | */
15 | class AddSerializationAnnotations extends Phase {
16 |
17 | override def prerequisites = Seq(Dependency[Elaborate], Dependency[AddImplicitOutputFile])
18 | override def optionalPrerequisites = Seq.empty
19 | override def optionalPrerequisiteOf = Seq.empty
20 | override def invalidates(a: Phase) = false
21 |
22 | def transform(annotations: AnnotationSeq): AnnotationSeq = {
23 | val chiselOptions = view[ChiselOptions](annotations)
24 | val circuit = chiselOptions.chiselCircuit.getOrElse {
25 | throw new ChiselException(
26 | s"Unable to locate the elaborated circuit, did ${classOf[Elaborate].getName} run correctly"
27 | )
28 | }
29 | val baseFilename = chiselOptions.outputFile.getOrElse(circuit.name)
30 |
31 | val (filename, format) = baseFilename match {
32 | case _ if baseFilename.endsWith(".pb") =>
33 | logger.warn(
34 | """[warn] Protobuf emission is deprecated in Chisel 3.6 and unsupported by the MFC. Change to an output file which does not include a ".pb" suffix. This behavior will change in Chisel 5 to emit FIRRTL text even if you provide a ".pb" suffix."""
35 | )
36 | (baseFilename.stripSuffix(".pb"), ProtoBufFileFormat)
37 | case _ => (baseFilename.stripSuffix(".fir"), FirrtlFileFormat)
38 | }
39 |
40 | CircuitSerializationAnnotation(circuit, filename, format) +: annotations
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/BundleWire.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 | import chisel3._
5 | import chisel3.testers.BasicTester
6 |
7 | class Coord extends Bundle {
8 | val x = UInt(32.W)
9 | val y = UInt(32.W)
10 | }
11 |
12 | class BundleWire(n: Int) extends Module {
13 | val io = IO(new Bundle {
14 | val in = Input(new Coord)
15 | val outs = Output(Vec(n, new Coord))
16 | })
17 | val coords = Wire(Vec(n, new Coord))
18 | for (i <- 0 until n) {
19 | coords(i) := io.in
20 | io.outs(i) := coords(i)
21 | }
22 | }
23 |
24 | class BundleToUnitTester extends BasicTester {
25 | val bundle1 = Wire(new Bundle {
26 | val a = UInt(4.W)
27 | val b = UInt(4.W)
28 | })
29 | val bundle2 = Wire(new Bundle {
30 | val a = UInt(2.W)
31 | val b = UInt(6.W)
32 | })
33 |
34 | // 0b00011011 split as 0001 1011 and as 00 011011
35 | bundle1.a := 1.U
36 | bundle1.b := 11.U
37 | bundle2.a := 0.U
38 | bundle2.b := 27.U
39 |
40 | assert(bundle1.asUInt === bundle2.asUInt)
41 |
42 | stop()
43 | }
44 |
45 | class BundleWireTester(n: Int, x: Int, y: Int) extends BasicTester {
46 | val dut = Module(new BundleWire(n))
47 | dut.io.in.x := x.asUInt
48 | dut.io.in.y := y.asUInt
49 | for (elt <- dut.io.outs) {
50 | assert(elt.x === x.asUInt)
51 | assert(elt.y === y.asUInt)
52 | }
53 | stop()
54 | }
55 |
56 | class BundleWireSpec extends ChiselPropSpec {
57 |
58 | property("All vec elems should match the inputs") {
59 | forAll(vecSizes, safeUInts, safeUInts) { (n: Int, x: Int, y: Int) =>
60 | assertTesterPasses { new BundleWireTester(n, x, y) }
61 | }
62 | }
63 | }
64 |
65 | class BundleToUIntSpec extends ChiselPropSpec {
66 | property("Bundles with same data but different, underlying elements should compare as UInt") {
67 | assertTesterPasses(new BundleToUnitTester)
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/stage/phases/AddImplicitOutputFileSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests.stage.phases
4 |
5 | import chisel3.RawModule
6 | import chisel3.stage.{ChiselGeneratorAnnotation, ChiselOutputFileAnnotation}
7 | import chisel3.stage.phases.{AddImplicitOutputFile, Elaborate}
8 |
9 | import firrtl.AnnotationSeq
10 | import firrtl.options.{Phase, StageOptions, TargetDirAnnotation}
11 | import firrtl.options.Viewer.view
12 | import org.scalatest.flatspec.AnyFlatSpec
13 | import org.scalatest.matchers.should.Matchers
14 |
15 | class AddImplicitOutputFileSpec extends AnyFlatSpec with Matchers {
16 |
17 | class Foo extends RawModule { override val desiredName = "Foo" }
18 |
19 | class Fixture { val phase: Phase = new AddImplicitOutputFile }
20 |
21 | behavior.of(classOf[AddImplicitOutputFile].toString)
22 |
23 | it should "not override an existing ChiselOutputFileAnnotation" in new Fixture {
24 | val annotations: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new Foo), ChiselOutputFileAnnotation("Bar"))
25 |
26 | Seq(new Elaborate, phase)
27 | .foldLeft(annotations)((a, p) => p.transform(a))
28 | .collect { case a: ChiselOutputFileAnnotation => a.file }
29 | .toSeq should be(Seq("Bar"))
30 | }
31 |
32 | it should "generate a ChiselOutputFileAnnotation from a ChiselCircuitAnnotation" in new Fixture {
33 | val annotations: AnnotationSeq = Seq(ChiselGeneratorAnnotation(() => new Foo), TargetDirAnnotation("test_run_dir"))
34 |
35 | Seq(new Elaborate, phase)
36 | .foldLeft(annotations)((a, p) => p.transform(a))
37 | .collect { case a: ChiselOutputFileAnnotation => a.file }
38 | .toSeq should be(Seq("Foo"))
39 | }
40 |
41 | it should "do nothing to an empty annotation sequence" in new Fixture {
42 | phase.transform(AnnotationSeq(Seq.empty)).toSeq should be(empty)
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/UIntFactory.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3
4 |
5 | import chisel3.internal.firrtl.{IntervalRange, KnownWidth, ULit, UnknownWidth, Width}
6 | import firrtl.Utils
7 | import firrtl.constraint.IsKnown
8 | import firrtl.ir.{Closed, IntWidth, Open}
9 |
10 | // This is currently a factory because both Bits and UInt inherit it.
11 | trait UIntFactory {
12 |
13 | /** Create a UInt type with inferred width. */
14 | def apply(): UInt = apply(Width())
15 |
16 | /** Create a UInt port with specified width. */
17 | def apply(width: Width): UInt = new UInt(width)
18 |
19 | /** Create a UInt literal with specified width. */
20 | protected[chisel3] def Lit(value: BigInt, width: Width): UInt = {
21 | val lit = ULit(value, width)
22 | val result = new UInt(lit.width)
23 | // Bind result to being an Literal
24 | lit.bindLitArg(result)
25 | }
26 |
27 | /** Create a UInt with the specified range, validate that range is effectively > 0
28 | */
29 | def apply(range: IntervalRange): UInt = {
30 | // Check is only done against lower bound because range will already insist that range high >= low
31 | range.lowerBound match {
32 | case Closed(bound) if bound < 0 =>
33 | throw new ChiselException(s"Attempt to create UInt with closed lower bound of $bound, must be > 0")
34 | case Open(bound) if bound < -1 =>
35 | throw new ChiselException(s"Attempt to create UInt with open lower bound of $bound, must be > -1")
36 | case _ =>
37 | }
38 |
39 | // because this is a UInt we don't have to take into account the lower bound
40 | val newWidth = if (range.upperBound.isInstanceOf[IsKnown]) {
41 | KnownWidth(Utils.getUIntWidth(range.maxAdjusted.get).max(1)) // max(1) handles range"[0,0]"
42 | } else {
43 | UnknownWidth()
44 | }
45 |
46 | apply(newWidth)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/IO.scala:
--------------------------------------------------------------------------------
1 | package chisel3
2 |
3 | import chisel3.internal.requireIsChiselType // Fix ambiguous import
4 | import chisel3.internal.Builder
5 | import chisel3.experimental.SourceInfo
6 |
7 | object IO {
8 |
9 | /** Constructs a port for the current Module
10 | *
11 | * This must wrap the datatype used to set the io field of any Module.
12 | * i.e. All concrete modules must have defined io in this form:
13 | * [lazy] val io[: io type] = IO(...[: io type])
14 | *
15 | * Items in [] are optional.
16 | *
17 | * The granted iodef must be a chisel type and not be bound to hardware.
18 | *
19 | * Also registers a Data as a port, also performing bindings. Cannot be called once ports are
20 | * requested (so that all calls to ports will return the same information).
21 | * Internal API.
22 | */
23 | def apply[T <: Data](iodef: => T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): T = {
24 | val module = Module.currentModule.get // Impossible to fail
25 | require(!module.isClosed, "Can't add more ports after module close")
26 | val prevId = Builder.idGen.value
27 | val data = iodef // evaluate once (passed by name)
28 | requireIsChiselType(data, "io type")
29 |
30 | // Clone the IO so we preserve immutability of data types
31 | // Note: we don't clone if the data is fresh (to avoid unnecessary clones)
32 | val iodefClone =
33 | if (!data.mustClone(prevId)) data
34 | else
35 | try {
36 | data.cloneTypeFull
37 | } catch {
38 | // For now this is going to be just a deprecation so we don't suddenly break everyone's code
39 | case e: AutoClonetypeException =>
40 | Builder.deprecated(e.getMessage, Some(s"${data.getClass}"))
41 | data
42 | }
43 | module.bindIoInPlace(iodefClone)
44 | iodefClone
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/Clock.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3
4 |
5 | import scala.language.experimental.macros
6 | import chisel3.experimental.SourceInfo
7 | import chisel3.internal.Builder.pushOp
8 | import chisel3.internal.firrtl._
9 | import chisel3.internal.sourceinfo._
10 | import chisel3.internal.firrtl.PrimOp.AsUIntOp
11 |
12 | object Clock {
13 | def apply(): Clock = new Clock
14 | }
15 |
16 | // TODO: Document this.
17 | sealed class Clock(private[chisel3] val width: Width = Width(1)) extends Element {
18 | override def toString: String = stringAccessor("Clock")
19 |
20 | def cloneType: this.type = Clock().asInstanceOf[this.type]
21 |
22 | private[chisel3] def typeEquivalent(that: Data): Boolean =
23 | this.getClass == that.getClass
24 |
25 | override def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit =
26 | that match {
27 | case _: Clock | DontCare => super.connect(that)(sourceInfo, connectCompileOptions)
28 | case _ => super.badConnect(that)(sourceInfo)
29 | }
30 |
31 | override def litOption: Option[BigInt] = None
32 |
33 | /** Not really supported */
34 | def toPrintable: Printable = PString("CLOCK")
35 |
36 | /** Returns the contents of the clock wire as a [[Bool]]. */
37 | final def asBool: Bool = macro SourceInfoTransform.noArg
38 |
39 | def do_asBool(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Bool = this.asUInt.asBool
40 |
41 | override def do_asUInt(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): UInt = pushOp(
42 | DefPrim(sourceInfo, UInt(this.width), AsUIntOp, ref)
43 | )
44 | private[chisel3] override def connectFromBits(
45 | that: Bits
46 | )(
47 | implicit sourceInfo: SourceInfo,
48 | compileOptions: CompileOptions
49 | ): Unit = {
50 | this := that.asBool.asClock
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/main/scala/circt/stage/phases/Checks.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package circt.stage.phases
4 |
5 | import circt.stage.CIRCTTargetAnnotation
6 |
7 | import firrtl.{AnnotationSeq, EmitAllModulesAnnotation, Emitter, SystemVerilogEmitter}
8 | import firrtl.annotations.Annotation
9 | import firrtl.options.{Dependency, OptionsException, Phase, TargetDirAnnotation}
10 | import firrtl.stage.OutputFileAnnotation
11 |
12 | /** Check properties of an [[firrtl.AnnotationSeq!]] to look for errors before running CIRCT. */
13 | class Checks extends Phase {
14 |
15 | override def prerequisites = Seq.empty
16 | override def optionalPrerequisiteOf = Seq(Dependency[circt.stage.phases.CIRCT])
17 | override def invalidates(a: Phase) = false
18 |
19 | override def transform(annotations: AnnotationSeq): AnnotationSeq = {
20 | val target, outputFile, split, targetDir = collection.mutable.ArrayBuffer[Annotation]()
21 |
22 | annotations.foreach {
23 | case a: OutputFileAnnotation => outputFile += a
24 | case a: EmitAllModulesAnnotation => split += a
25 | case a: TargetDirAnnotation => targetDir += a
26 | case a: CIRCTTargetAnnotation => target += a
27 | case _ =>
28 | }
29 | if ((split.size > 0) && (outputFile.size != 0)) {
30 | throw new OptionsException("Cannot specify both an OutputFileAnnotation and an EmitAllModulesAnnotation")
31 | }
32 | if ((split.size == 0) && (outputFile.size != 1)) {
33 | throw new OptionsException("An output file must be specified")
34 | }
35 |
36 | if ((split.size > 0) && (targetDir.size != 1)) {
37 | throw new OptionsException("If EmitAllModulesAnnotation is specified one TargetDirAnnotation is needed")
38 | }
39 |
40 | if (target.size != 1) {
41 | throw new OptionsException("Exactly one CIRCT target must be specified")
42 | }
43 |
44 | annotations
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/Decoder.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import org.scalacheck._
6 |
7 | import chisel3._
8 | import chisel3.testers.BasicTester
9 | import chisel3.util._
10 |
11 | class Decoder(bitpats: List[String]) extends Module {
12 | val io = IO(new Bundle {
13 | val inst = Input(UInt(32.W))
14 | val matched = Output(Bool())
15 | })
16 | io.matched := VecInit(bitpats.map(BitPat(_) === io.inst)).reduce(_ || _)
17 | }
18 |
19 | class DecoderTester(pairs: List[(String, String)]) extends BasicTester {
20 | val (insts, bitpats) = pairs.unzip
21 | val (cnt, wrap) = Counter(true.B, pairs.size)
22 | val dut = Module(new Decoder(bitpats))
23 | dut.io.inst := VecInit(insts.map(_.asUInt))(cnt)
24 | when(!dut.io.matched) {
25 | assert(cnt === 0.U)
26 | stop()
27 | }
28 | when(wrap) {
29 | stop()
30 | }
31 | }
32 |
33 | class DecoderSpec extends ChiselPropSpec {
34 |
35 | // Use a single Int to make both a specific instruction and a BitPat that will match it
36 | val bitpatPair = for (seed <- Arbitrary.arbitrary[Int]) yield {
37 | val rnd = new scala.util.Random(seed)
38 | val bs = seed.toBinaryString
39 | val bp = bs.map(if (rnd.nextBoolean()) _ else "?")
40 |
41 | // The following randomly throws in white space and underscores which are legal and ignored.
42 | val bpp = bp.map { a =>
43 | if (rnd.nextBoolean()) {
44 | a.toString
45 | } else {
46 | a.toString + (if (rnd.nextBoolean()) "_" else " ")
47 | }
48 | }.mkString
49 |
50 | ("b" + bs, "b" + bpp)
51 | }
52 | private def nPairs(n: Int) = Gen.containerOfN[List, (String, String)](n, bitpatPair)
53 |
54 | property("BitPat wildcards should be usable in decoding") {
55 | forAll(nPairs(4)) { (pairs: List[(String, String)]) =>
56 | assertTesterPasses { new DecoderTester(pairs) }
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/website/Makefile:
--------------------------------------------------------------------------------
1 | buildDir ?= build
2 | subprojects = $(buildDir)/subprojects
3 | docs = $(buildDir)/docs
4 | chisel3 = ../
5 |
6 | www-docs = \
7 | $(shell find $(chisel3)/docs/ -name "*.md")
8 |
9 | www-src = \
10 | $(shell find docs/src/main/resources) \
11 | docs/src/main/tut/chisel3/docs \
12 | docs/src/main/tut/chisel3/index.md \
13 | $(chisel3)/README.md
14 |
15 | # Get the latest version of some sequence of version strings
16 | # Usage: $(call getTags,$(foo))
17 | define latest
18 | $(shell echo $(1) | tr " " "\n" | sort -Vr | head -n1 | sed 's/^v//')
19 | endef
20 |
21 |
22 | .PHONY: all clean mrproper publish serve
23 | .PRECIOUS: \
24 | $(subprojects)/chisel3/%/.git $(subprojects)/chisel3/%/target/scala-$(scalaVersion)/unidoc/index.html
25 |
26 | # Build the site into the default directory (docs/target/site)
27 | all: docs/target/site/index.html
28 |
29 | # Remove the output of all build targets
30 | clean:
31 | rm -rf docs/target docs/src/main/tut/contributors.md docs/src/main/tut/chisel3/docs
32 |
33 | # Remove everything
34 | mrproper:
35 | rm -rf $(buildDir) target project/target
36 |
37 | # Publish Microsite
38 | publish: all
39 | sbt docs/ghpagesPushSite
40 |
41 | # Start a Jekyll server for the site
42 | serve: all
43 | (cd docs/target/site && jekyll serve)
44 |
45 | # Build the sbt-microsite
46 | docs/target/site/index.html: build.sbt docs/src/main/tut/contributors.md $(www-src)
47 | sbt docs/makeMicrosite
48 |
49 | # Determine contributors
50 | docs/src/main/tut/contributors.md: build.sbt
51 | sbt contributors/determineContributors
52 |
53 | # Build docs in subproject with a specific tag.
54 | # This command is brittle as it assumes chisel3 is up one dir from here in the path to where
55 | # we want to put the website docs.
56 | docs/src/main/tut/chisel3/docs: $(chisel3)/docs/ $(www-docs)
57 | (cd $(chisel3) && sbt docs/mdoc && cp -r docs/generated website/docs/src/main/tut/chisel3/docs)
58 |
59 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/OptionBundle.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.testers.BasicTester
7 | import circt.stage.ChiselStage
8 |
9 | class OptionBundle(val hasIn: Boolean) extends Bundle {
10 | val in = if (hasIn) {
11 | Some(Input(Bool()))
12 | } else {
13 | None
14 | }
15 | val out = Output(Bool())
16 | }
17 |
18 | class OptionBundleModule(val hasIn: Boolean) extends Module {
19 | val io = IO(new OptionBundle(hasIn))
20 | if (hasIn) {
21 | io.out := io.in.get
22 | } else {
23 | io.out := false.B
24 | }
25 | }
26 |
27 | class SomeOptionBundleTester(expected: Boolean) extends BasicTester {
28 | val mod = Module(new OptionBundleModule(true))
29 | mod.io.in.get := expected.asBool
30 | assert(mod.io.out === expected.asBool)
31 | stop()
32 | }
33 |
34 | class NoneOptionBundleTester() extends BasicTester {
35 | val mod = Module(new OptionBundleModule(false))
36 | assert(mod.io.out === false.B)
37 | stop()
38 | }
39 |
40 | class InvalidOptionBundleTester() extends BasicTester {
41 | val mod = Module(new OptionBundleModule(false))
42 | mod.io.in.get := true.B
43 | assert(false.B)
44 | stop()
45 | }
46 |
47 | class OptionBundleSpec extends ChiselFlatSpec with Utils {
48 | "A Bundle with an Option field" should "work properly if the Option field is not None" in {
49 | assertTesterPasses { new SomeOptionBundleTester(true) }
50 | assertTesterPasses { new SomeOptionBundleTester(false) }
51 | }
52 |
53 | "A Bundle with an Option field" should "compile if the Option field is None" in {
54 | assertTesterPasses { new NoneOptionBundleTester() }
55 | }
56 |
57 | "A Bundle with an Option field" should "assert out accessing a None Option field" in {
58 | a[Exception] should be thrownBy extractCause[Exception] {
59 | ChiselStage.elaborate { new InvalidOptionBundleTester() }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/ToTargetSpec.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import circt.stage.ChiselStage
7 |
8 | class ToTargetSpec extends ChiselFlatSpec with Utils {
9 |
10 | var m: InstanceNameModule = _
11 | ChiselStage.elaborate { m = new InstanceNameModule; m }
12 |
13 | val mn = "InstanceNameModule"
14 | val top = s"~$mn|$mn"
15 |
16 | behavior.of(".toTarget")
17 |
18 | val deprecationMsg = "Accessing the .instanceName or .toTarget of non-hardware Data is deprecated"
19 |
20 | it should "work with module IO" in {
21 | val io = m.io.toTarget.toString
22 | assert(io == s"$top>io")
23 | }
24 |
25 | it should "not work for literals" in {
26 | a[ChiselException] shouldBe thrownBy {
27 | m.x.toTarget.toString
28 | }
29 | }
30 |
31 | it should "NOT work for non-hardware values" in {
32 | a[ChiselException] shouldBe thrownBy { m.y.toTarget }
33 | a[ChiselException] shouldBe thrownBy { m.z.toTarget }
34 | }
35 |
36 | it should "NOT work for non-hardware bundle elements" in {
37 | a[ChiselException] shouldBe thrownBy { m.z.foo.toTarget }
38 | }
39 |
40 | it should "work with modules" in {
41 | val q = m.q.toTarget.toString
42 | assert(q == s"~$mn|Queue")
43 | }
44 |
45 | it should "error on non-hardware types and provide information" in {
46 | class Example extends Module {
47 | val tpe = UInt(8.W)
48 |
49 | val in = IO(Input(tpe))
50 | val out = IO(Output(tpe))
51 | out := in
52 | }
53 |
54 | val e = the[ChiselException] thrownBy extractCause[ChiselException] {
55 | var e: Example = null
56 | circt.stage.ChiselStage.elaborate { e = new Example; e }
57 | e.tpe.toTarget
58 | }
59 | e.getMessage should include(
60 | "You cannot access the .instanceName or .toTarget of non-hardware Data: 'tpe', in module 'Example'"
61 | )
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/experimental/util/algorithm/Bitwise.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.util
4 |
5 | import chisel3._
6 |
7 | /** Map each bit to the logical OR of itself and all bits with lower index
8 | *
9 | * Here `scanLeft` means "start from the left and iterate to the right, where left is the lowest index", a common operation on arrays and lists.
10 | * @example {{{
11 | * scanLeftOr("b00001000".U(8.W)) // Returns "b11111000".U
12 | * scanLeftOr("b00010100".U(8.W)) // Returns "b11111100".U
13 | * scanLeftOr("b00000000".U(8.W)) // Returns "b00000000".U
14 | * }}}
15 | */
16 | object scanLeftOr {
17 | def apply(data: UInt): UInt = {
18 | val width = data.widthOption match {
19 | case Some(w) => w
20 | case None => throw new IllegalArgumentException("Cannot call scanLeftOr on data with unknown width.")
21 | }
22 |
23 | def helper(s: Int, x: UInt): UInt =
24 | if (s >= width) x else helper(s + s, x | (x << s)(width - 1, 0))
25 | helper(1, data)(width - 1, 0)
26 | }
27 | }
28 |
29 | /** Map each bit to the logical OR of itself and all bits with higher index
30 | *
31 | * Here `scanRight` means "start from the right and iterate to the left, where right is the highest index", a common operation on arrays and lists.
32 | * @example {{{
33 | * scanRightOr("b00001000".U) // Returns "b00001111".U
34 | * scanRightOr("b00010100".U) // Returns "b00011111".U
35 | * scanRightOr("b00000000".U) // Returns "b00000000".U
36 | * }}}
37 | */
38 | object scanRightOr {
39 | def apply(data: UInt): UInt = {
40 | val width = data.widthOption match {
41 | case Some(w) => w
42 | case None => throw new IllegalArgumentException("Cannot call scanRightOr on data with unknown width.")
43 | }
44 | def helper(s: Int, x: UInt): UInt =
45 | if (s >= width) x else helper(s + s, x | (x >> s))
46 | helper(1, data)(width - 1, 0)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/util/Cat.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.util
4 |
5 | import scala.language.experimental.macros
6 |
7 | import chisel3._
8 | import chisel3.experimental.SourceInfo
9 | import chisel3.internal.sourceinfo.SourceInfoTransform
10 |
11 | /** Concatenates elements of the input, in order, together.
12 | *
13 | * @example {{{
14 | * Cat("b101".U, "b11".U) // equivalent to "b101 11".U
15 | * Cat(myUIntWire0, myUIntWire1)
16 | *
17 | * Cat(Seq("b101".U, "b11".U)) // equivalent to "b101 11".U
18 | * Cat(mySeqOfBits)
19 | * }}}
20 | */
21 | object Cat {
22 |
23 | /** Concatenates the argument data elements, in argument order, together. The first argument
24 | * forms the most significant bits, while the last argument forms the least significant bits.
25 | */
26 | def apply[T <: Bits](a: T, r: T*): UInt = macro SourceInfoTransform.arArg
27 |
28 | /** @group SourceInfoTransformMacro */
29 | def do_apply[T <: Bits](a: T, r: T*)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
30 | _apply_impl(a :: r.toList)
31 |
32 | /** Concatenates the data elements of the input sequence, in reverse sequence order, together.
33 | * The first element of the sequence forms the most significant bits, while the last element
34 | * in the sequence forms the least significant bits.
35 | *
36 | * Equivalent to r(0) ## r(1) ## ... ## r(n-1).
37 | * @note This returns a `0.U` if applied to a zero-element `Vec`.
38 | */
39 | def apply[T <: Bits](r: Seq[T]): UInt = macro SourceInfoTransform.rArg
40 |
41 | /** @group SourceInfoTransformMacro */
42 | def do_apply[T <: Bits](r: Seq[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
43 | _apply_impl(r)
44 |
45 | private def _apply_impl[T <: Bits](r: Seq[T])(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): UInt =
46 | SeqUtils.asUInt(r.reverse)
47 | }
48 |
--------------------------------------------------------------------------------
/src/main/scala/chisel3/stage/phases/Elaborate.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3.stage.phases
4 |
5 | import chisel3.Module
6 | import chisel3.internal.ExceptionHelpers.ThrowableHelpers
7 | import chisel3.internal.{Builder, DynamicContext}
8 | import chisel3.stage.{
9 | ChiselCircuitAnnotation,
10 | ChiselGeneratorAnnotation,
11 | ChiselOptions,
12 | DesignAnnotation,
13 | ThrowOnFirstErrorAnnotation
14 | }
15 | import firrtl.AnnotationSeq
16 | import firrtl.options.Phase
17 | import firrtl.options.Viewer.view
18 |
19 | /** Elaborate all [[chisel3.stage.ChiselGeneratorAnnotation]]s into [[chisel3.stage.ChiselCircuitAnnotation]]s.
20 | */
21 | class Elaborate extends Phase {
22 |
23 | override def prerequisites = Seq.empty
24 | override def optionalPrerequisites = Seq.empty
25 | override def optionalPrerequisiteOf = Seq.empty
26 | override def invalidates(a: Phase) = false
27 |
28 | def transform(annotations: AnnotationSeq): AnnotationSeq = annotations.flatMap {
29 | case ChiselGeneratorAnnotation(gen) =>
30 | val chiselOptions = view[ChiselOptions](annotations)
31 | try {
32 | val context =
33 | new DynamicContext(
34 | annotations,
35 | chiselOptions.throwOnFirstError,
36 | chiselOptions.warningsAsErrors,
37 | chiselOptions.sourceRoots
38 | )
39 | val (circuit, dut) =
40 | Builder.build(Module(gen()), context)
41 | Seq(ChiselCircuitAnnotation(circuit), DesignAnnotation(dut))
42 | } catch {
43 | /* if any throwable comes back and we're in "stack trace trimming" mode, then print an error and trim the stack trace
44 | */
45 | case scala.util.control.NonFatal(a) =>
46 | if (!chiselOptions.printFullStackTrace) {
47 | a.trimStackTraceToUserCode()
48 | }
49 | throw (a)
50 | }
51 | case a => Some(a)
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/Mux.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3
4 |
5 | import scala.language.experimental.macros
6 |
7 | import chisel3.internal._
8 | import chisel3.internal.Builder.pushOp
9 | import chisel3.experimental.{requireIsHardware, SourceInfo}
10 | import chisel3.internal.sourceinfo.MuxTransform
11 | import chisel3.internal.firrtl._
12 | import chisel3.internal.firrtl.PrimOp._
13 |
14 | object Mux extends SourceInfoDoc {
15 |
16 | /** Creates a mux, whose output is one of the inputs depending on the
17 | * value of the condition.
18 | *
19 | * @param cond condition determining the input to choose
20 | * @param con the value chosen when `cond` is true
21 | * @param alt the value chosen when `cond` is false
22 | * @example
23 | * {{{
24 | * val muxOut = Mux(data_in === 3.U, 3.U(4.W), 0.U(4.W))
25 | * }}}
26 | */
27 | def apply[T <: Data](cond: Bool, con: T, alt: T): T = macro MuxTransform.apply[T]
28 |
29 | /** @group SourceInfoTransformMacro */
30 | def do_apply[T <: Data](
31 | cond: Bool,
32 | con: T,
33 | alt: T
34 | )(
35 | implicit sourceInfo: SourceInfo,
36 | compileOptions: CompileOptions
37 | ): T = {
38 | requireIsHardware(cond, "mux condition")
39 | requireIsHardware(con, "mux true value")
40 | requireIsHardware(alt, "mux false value")
41 | val d = cloneSupertype(Seq(con, alt), "Mux")
42 | val conRef = con match { // this matches chisel semantics (DontCare as object) to firrtl semantics (invalidate)
43 | case DontCare =>
44 | val dcWire = Wire(d)
45 | dcWire := DontCare
46 | dcWire.ref
47 | case _ => con.ref
48 | }
49 | val altRef = alt match {
50 | case DontCare =>
51 | val dcWire = Wire(d)
52 | dcWire := DontCare
53 | dcWire.ref
54 | case _ => alt.ref
55 | }
56 | pushOp(DefPrim(sourceInfo, d, MultiplexOp, cond.ref, conRef, altRef))
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/core/src/main/scala/chisel3/experimental/hierarchy/package.scala:
--------------------------------------------------------------------------------
1 | package chisel3.experimental
2 |
3 | package object hierarchy {
4 |
5 | /** Classes or traits which will be used with the [[Definition]] + [[Instance]] api should be marked
6 | * with the [[instantiable]] annotation at the class/trait definition.
7 | *
8 | * @example {{{
9 | * @instantiable
10 | * class MyModule extends Module {
11 | * ...
12 | * }
13 | *
14 | * val d = Definition(new MyModule)
15 | * val i0 = Instance(d)
16 | * val i1 = Instance(d)
17 | * }}}
18 | */
19 | class instantiable extends chisel3.internal.instantiable
20 |
21 | /** Classes marked with [[instantiable]] can have their vals marked with the [[public]] annotation to
22 | * enable accessing these values from a [[Definition]] or [[Instance]] of the class.
23 | *
24 | * Only vals of the the following types can be marked [[public]]:
25 | * 1. IsInstantiable
26 | * 2. IsLookupable
27 | * 3. Data
28 | * 4. BaseModule
29 | * 5. Iterable/Option containing a type that meets these requirements
30 | * 6. Basic type like String, Int, BigInt etc.
31 | *
32 | * @example {{{
33 | * @instantiable
34 | * class MyModule extends Module {
35 | * @public val in = IO(Input(UInt(3.W)))
36 | * @public val out = IO(Output(UInt(3.W)))
37 | * ..
38 | * }
39 | *
40 | * val d = Definition(new MyModule)
41 | * val i0 = Instance(d)
42 | * val i1 = Instance(d)
43 | *
44 | * i1.in := i0.out
45 | * }}}
46 | */
47 | class public extends chisel3.internal.public
48 |
49 | type Instance[P] = core.Instance[P]
50 | val Instance = core.Instance
51 | type Definition[P] = core.Definition[P]
52 | val Definition = core.Definition
53 | type Hierarchy[P] = core.Hierarchy[P]
54 | val Hierarchy = core.Hierarchy
55 | type IsInstantiable = core.IsInstantiable
56 | type IsLookupable = core.IsLookupable
57 | }
58 |
--------------------------------------------------------------------------------
/src/test/scala/chiselTests/Tbl.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chiselTests
4 |
5 | import chisel3._
6 | import chisel3.testers.BasicTester
7 | import chisel3.util._
8 |
9 | class Tbl(w: Int, n: Int) extends Module {
10 | val io = IO(new Bundle {
11 | val wi = Input(UInt(log2Ceil(n).W))
12 | val ri = Input(UInt(log2Ceil(n).W))
13 | val we = Input(Bool())
14 | val d = Input(UInt(w.W))
15 | val o = Output(UInt(w.W))
16 | })
17 | val m = Mem(n, UInt(w.W))
18 | io.o := m(io.ri)
19 | when(io.we) {
20 | m(io.wi) := io.d
21 | when(io.ri === io.wi) {
22 | io.o := io.d
23 | }
24 | }
25 | }
26 |
27 | class TblTester(w: Int, n: Int, idxs: List[Int], values: List[Int]) extends BasicTester {
28 | val (cnt, wrap) = Counter(true.B, idxs.size)
29 | val dut = Module(new Tbl(w, n))
30 | val vvalues = VecInit(values.map(_.asUInt))
31 | val vidxs = VecInit(idxs.map(_.asUInt))
32 | val prev_idx = vidxs(cnt - 1.U)
33 | val prev_value = vvalues(cnt - 1.U)
34 | dut.io.wi := vidxs(cnt)
35 | dut.io.ri := prev_idx
36 | dut.io.we := true.B //TODO enSequence
37 | dut.io.d := vvalues(cnt)
38 | when(cnt > 0.U) {
39 | when(prev_idx === vidxs(cnt)) {
40 | assert(dut.io.o === vvalues(cnt))
41 | }.otherwise {
42 | assert(dut.io.o === prev_value)
43 | }
44 | }
45 | when(wrap) {
46 | stop()
47 | }
48 | }
49 |
50 | class TblSpec extends ChiselPropSpec {
51 | property("All table reads should return the previous write") {
52 | forAll(safeUIntPairN(8)) {
53 | case (w: Int, pairs: List[(Int, Int)]) =>
54 | // Provide an appropriate whenever clause.
55 | // ScalaTest will try and shrink the values on error to determine the smallest values that cause the error.
56 | whenever(w > 0 && pairs.length > 0) {
57 | val (idxs, values) = pairs.unzip
58 | assertTesterPasses { new TblTester(w, 1 << w, idxs, values) }
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/macros/src/main/scala/chisel3/SourceInfoDoc.scala:
--------------------------------------------------------------------------------
1 | // SPDX-License-Identifier: Apache-2.0
2 |
3 | package chisel3
4 |
5 | /** Provides ScalaDoc information for "hidden" `do_*` methods
6 | *
7 | * Mix this into classes/objects that have `do_*` methods to get access to the shared `SourceInfoTransformMacro`
8 | * ScalaDoc group and the lengthy `groupdesc` below.
9 | *
10 | * @groupdesc SourceInfoTransformMacro
11 | *
12 | *
13 | * '''These internal methods are not part of the public-facing API!'''
14 | *
15 | *
16 | *
17 | * The equivalent public-facing methods do not have the `do_` prefix or have the same name. Use and look at the
18 | * documentation for those. If you want left shift, use `<<`, not `do_<<`. If you want conversion to a
19 | * [[scala.collection.Seq Seq]] of [[Bool]]s look at the `asBools` above, not the one below. Users can safely ignore
20 | * every method in this group!
21 | *
22 | * 🐉🐉🐉 '''Here be dragons...''' 🐉🐉🐉
23 | *
24 | *
25 | *
26 | * These `do_X` methods are used to enable both implicit passing of SourceInfo and [[chisel3.CompileOptions]]
27 | * while also supporting chained apply methods. In effect all "normal" methods that you, as a user, will use in your
28 | * designs, are converted to their "hidden", `do_*`, via macro transformations. Without using macros here, only one
29 | * of the above wanted behaviors is allowed (implicit passing and chained applies)---the compiler interprets a
30 | * chained apply as an explicit 'implicit' argument and will throw type errors.
31 | *
32 | * The "normal", public-facing methods then take no SourceInfo. However, a macro transforms this public-facing method
33 | * into a call to an internal, hidden `do_*` that takes an explicit SourceInfo by inserting an
34 | * `implicitly[SourceInfo]` as the explicit argument.
35 | *
36 | * @groupprio SourceInfoTransformMacro 1001
37 | */
38 | trait SourceInfoDoc
39 |
--------------------------------------------------------------------------------