├── .github ├── CODEOWNERS ├── ISSUE_TEMPLATE │ ├── bug-report.md │ └── feature-request.md ├── PULL_REQUEST_TEMPLATE.md ├── configs │ └── mergify_config.yml └── workflows │ ├── install-circt │ └── action.yml │ ├── install-espresso │ └── action.yml │ ├── setup-oss-cad-suite │ └── action.yml │ └── test.yml ├── .gitignore ├── .gitmodules ├── .mergify.yml ├── .scala-steward.conf ├── .scalafix.conf ├── .scalafmt.conf ├── AdderProp1.sv ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── ROADMAP.md ├── SETUP.md ├── Syntax and Semantics of Sequence and Property Formulas.pdf ├── build.sbt ├── build.sc ├── build └── firrtl_black_box_resource_files.f ├── core └── src │ └── main │ ├── scala-2.12 │ └── scala │ │ └── collection │ │ └── immutable │ │ └── package.scala │ └── scala │ └── chisel3 │ ├── Aggregate.scala │ ├── Annotation.scala │ ├── Bits.scala │ ├── BlackBox.scala │ ├── BoolFactory.scala │ ├── ChiselEnum.scala │ ├── Clock.scala │ ├── CompileOptions.scala │ ├── Data.scala │ ├── Element.scala │ ├── IO.scala │ ├── Mem.scala │ ├── Module.scala │ ├── ModuleAspect.scala │ ├── MultiClock.scala │ ├── Mux.scala │ ├── Num.scala │ ├── Printable.scala │ ├── Printf.scala │ ├── RawModule.scala │ ├── Reg.scala │ ├── SIntFactory.scala │ ├── SeqUtils.scala │ ├── UIntFactory.scala │ ├── VerificationStatement.scala │ ├── When.scala │ ├── aop │ └── Aspect.scala │ ├── connectable │ ├── Alignment.scala │ ├── Connectable.scala │ ├── Connection.scala │ └── package.scala │ ├── dontTouch.scala │ ├── experimental │ ├── Analog.scala │ ├── Attach.scala │ ├── EnumAnnotations.scala │ ├── OpaqueType.scala │ ├── SerializableModuleGenerator.scala │ ├── SourceInfo.scala │ ├── Trace.scala │ ├── dataview │ │ ├── ChiselSubtypeOf.scala │ │ ├── DataProduct.scala │ │ ├── DataView.scala │ │ └── package.scala │ ├── hierarchy │ │ ├── DefinitionClone.scala │ │ ├── InstanceClone.scala │ │ ├── InstantiableClone.scala │ │ ├── Instantiate.scala │ │ ├── LibraryHooks.scala │ │ ├── ModuleClone.scala │ │ ├── core │ │ │ ├── Definition.scala │ │ │ ├── Hierarchy.scala │ │ │ ├── Instance.scala │ │ │ ├── IsClone.scala │ │ │ ├── IsInstantiable.scala │ │ │ ├── IsLookupable.scala │ │ │ ├── Lookupable.scala │ │ │ └── Underlying.scala │ │ └── package.scala │ ├── package.scala │ └── prefix.scala │ ├── internal │ ├── BiConnect.scala │ ├── Binding.scala │ ├── Builder.scala │ ├── BuilderContextCache.scala │ ├── Error.scala │ ├── MonoConnect.scala │ ├── Namer.scala │ ├── SourceInfo.scala │ ├── SourceInfoMacro.scala │ ├── firrtl │ │ ├── Converter.scala │ │ └── IR.scala │ ├── package.scala │ └── plugin │ │ └── package.scala │ ├── package.scala │ └── reflect │ └── DataMirror.scala ├── docs-target └── src │ └── main │ ├── resources │ └── META-INF │ │ └── services │ │ └── mdoc.PostModifier │ └── scala │ └── chisel3 │ └── docs │ └── VerilogMdocModifier.scala ├── docs ├── README.md └── src │ ├── appendix │ ├── appendix.md │ ├── chisel3-vs-chisel2.md │ ├── experimental-features.md │ ├── upgrading-from-chisel-3-4.md │ ├── upgrading-from-scala-2-11.md │ └── versioning.md │ ├── cookbooks │ ├── cookbook.md │ ├── cookbooks.md │ ├── dataview.md │ ├── hierarchy.md │ ├── naming.md │ ├── serialization.md │ ├── troubleshooting.md │ └── verilog-vs-chisel.md │ ├── developers │ ├── developers.md │ ├── sbt-subproject.md │ ├── scaladoc.md │ ├── style.md │ └── test-coverage.md │ ├── explanations │ ├── annotations.md │ ├── blackboxes.md │ ├── bundles-and-vecs.md │ ├── chisel-enum.md │ ├── chisel-type-vs-scala-type.md │ ├── combinational-circuits.md │ ├── connectable.md │ ├── connection-operators.md │ ├── data-types.md │ ├── dataview.md │ ├── decoder.md │ ├── explanations.md │ ├── functional-abstraction.md │ ├── functional-module-creation.md │ ├── interfaces-and-connections.md │ ├── memories.md │ ├── modules.md │ ├── motivation.md │ ├── multi-clock.md │ ├── muxes-and-input-selection.md │ ├── naming.md │ ├── operators.md │ ├── polymorphism-and-parameterization.md │ ├── ports.md │ ├── printing.md │ ├── reset.md │ ├── sequential-circuits.md │ ├── source-locators.md │ ├── supported-hardware.md │ ├── unconnected-wires.md │ └── width-inference.md │ ├── images │ ├── Makefile │ ├── chisel_01.png │ ├── chisel_logo.png │ ├── chisel_logo.svg │ ├── connection-operators-experiment.svg │ ├── fir_filter.svg │ ├── type_hierarchy.dot │ ├── type_hierarchy.png │ ├── type_hierarchy.svg │ └── vec-forall.svg │ ├── introduction.md │ └── resources │ ├── faqs.md │ └── resources.md ├── integration-tests └── src │ └── test │ └── scala │ ├── chisel3 │ └── std │ │ └── BarrelShifter.scala │ ├── chiselTest │ └── MemFormalSpec.scala │ └── chiselTests │ └── util │ ├── GrayCodeTests.scala │ └── experimental │ ├── BitPat.scala │ ├── DecoderSpec.scala │ ├── algorithm │ └── Bitwise.scala │ └── minimizer │ ├── EspressoSpec.scala │ ├── MinimizerSpec.scala │ └── QMCSpec.scala ├── lib ├── javabdd-1.0b2.jar └── jhoafparser-1.1.1.jar ├── macros └── src │ └── main │ └── scala │ └── chisel3 │ ├── SourceInfoDoc.scala │ └── internal │ ├── InstantiableMacro.scala │ ├── RangeTransform.scala │ ├── RuntimeDeprecationTransform.scala │ ├── naming │ └── NamingAnnotations.scala │ └── sourceinfo │ └── SourceInfoTransform.scala ├── plugin ├── README.md └── src │ └── main │ ├── resources │ └── scalac-plugin.xml │ └── scala │ └── chisel3 │ └── internal │ └── plugin │ ├── BundleComponent.scala │ ├── ChiselComponent.scala │ ├── ChiselPlugin.scala │ └── DeprecateSFCComponent.scala ├── project ├── build.properties └── plugins.sbt ├── root-doc.txt ├── src ├── main │ ├── resources │ │ ├── META-INF │ │ │ └── services │ │ │ │ └── firrtl.options.RegisteredLibrary │ │ └── chisel3 │ │ │ ├── Makefile │ │ │ └── top.cpp │ └── scala │ │ ├── chisel3 │ │ ├── Driver.scala │ │ ├── aop │ │ │ ├── AspectLibrary.scala │ │ │ ├── Select.scala │ │ │ ├── injecting │ │ │ │ ├── InjectStatement.scala │ │ │ │ ├── InjectingAspect.scala │ │ │ │ └── InjectingPhase.scala │ │ │ └── inspecting │ │ │ │ └── InspectingAspect.scala │ │ ├── compatibility.scala │ │ ├── experimental │ │ │ ├── conversions │ │ │ │ └── package.scala │ │ │ └── util │ │ │ │ └── algorithm │ │ │ │ └── Bitwise.scala │ │ ├── internal │ │ │ └── firrtl │ │ │ │ └── Emitter.scala │ │ ├── stage │ │ │ ├── ChiselAnnotations.scala │ │ │ ├── ChiselCli.scala │ │ │ ├── ChiselOptions.scala │ │ │ ├── ChiselPhase.scala │ │ │ ├── ChiselStage.scala │ │ │ ├── package.scala │ │ │ └── phases │ │ │ │ ├── AddImplicitOutputAnnotationFile.scala │ │ │ │ ├── AddImplicitOutputFile.scala │ │ │ │ ├── AddSerializationAnnotations.scala │ │ │ │ ├── AspectPhase.scala │ │ │ │ ├── Checks.scala │ │ │ │ ├── Convert.scala │ │ │ │ ├── DriverCompatibility.scala │ │ │ │ ├── Elaborate.scala │ │ │ │ ├── Emitter.scala │ │ │ │ ├── MaybeAspectPhase.scala │ │ │ │ ├── MaybeFirrtlStage.scala │ │ │ │ └── MaybeInjectingPhase.scala │ │ ├── testers │ │ │ ├── BasicTester.scala │ │ │ ├── TesterDriver.scala │ │ │ └── package.scala │ │ ├── util │ │ │ ├── Arbiter.scala │ │ │ ├── BitPat.scala │ │ │ ├── Bitwise.scala │ │ │ ├── BlackBoxUtils.scala │ │ │ ├── Cat.scala │ │ │ ├── CircuitMath.scala │ │ │ ├── Conditional.scala │ │ │ ├── Counter.scala │ │ │ ├── Decoupled.scala │ │ │ ├── Enum.scala │ │ │ ├── ExtModuleUtils.scala │ │ │ ├── GrayCode.scala │ │ │ ├── ImplicitConversions.scala │ │ │ ├── Lookup.scala │ │ │ ├── Math.scala │ │ │ ├── MixedVec.scala │ │ │ ├── Mux.scala │ │ │ ├── OneHot.scala │ │ │ ├── Reg.scala │ │ │ ├── Valid.scala │ │ │ ├── circt │ │ │ │ └── SizeOf.scala │ │ │ ├── experimental │ │ │ │ ├── BoringUtils.scala │ │ │ │ ├── ForceNames.scala │ │ │ │ ├── Inline.scala │ │ │ │ ├── LoadMemoryTransform.scala │ │ │ │ ├── decode │ │ │ │ │ ├── DecodeTableAnnotation.scala │ │ │ │ │ ├── DecoderBundle.scala │ │ │ │ │ ├── EspressoMinimizer.scala │ │ │ │ │ ├── Minimizer.scala │ │ │ │ │ ├── QMCMinimizer.scala │ │ │ │ │ ├── TruthTable.scala │ │ │ │ │ └── decoder.scala │ │ │ │ ├── getAnnotations.scala │ │ │ │ └── group.scala │ │ │ ├── pla.scala │ │ │ ├── random │ │ │ │ ├── FibonacciLFSR.scala │ │ │ │ ├── GaloisLFSR.scala │ │ │ │ ├── LFSR.scala │ │ │ │ └── PRNG.scala │ │ │ └── util.scala │ │ └── verilog.scala │ │ └── circt │ │ ├── Implicits.scala │ │ ├── Intrinisic.scala │ │ └── stage │ │ ├── Annotations.scala │ │ ├── CIRCTOptions.scala │ │ ├── CIRCTStage.scala │ │ ├── ChiselStage.scala │ │ ├── package.scala │ │ └── phases │ │ ├── AddFIRRTLInputFile.scala │ │ ├── CIRCT.scala │ │ └── Checks.scala └── test │ ├── resources │ └── chisel3 │ │ ├── AnalogBlackBox.v │ │ ├── BlackBoxTest.v │ │ ├── VerilogVendingMachine.v │ │ ├── sourceroot1 │ │ └── Foo │ │ └── sourceroot2 │ │ └── Foo │ └── scala │ ├── chisel3 │ ├── internal │ │ ├── NameCollisionSpec.scala │ │ └── NamespaceSpec.scala │ └── testers │ │ └── TestUtils.scala │ ├── chiselTests │ ├── AdderTree.scala │ ├── AnalogIntegrationSpec.scala │ ├── AnalogSpec.scala │ ├── AnnotatingDiamondSpec.scala │ ├── AnnotationNoDedup.scala │ ├── AsTypeOfTester.scala │ ├── Assert.scala │ ├── AsyncResetSpec.scala │ ├── AutoClonetypeSpec.scala │ ├── AutoNestedCloneSpec.scala │ ├── BetterNamingTests.scala │ ├── BitwiseOps.scala │ ├── BlackBox.scala │ ├── BlackBoxImpl.scala │ ├── BoringUtilsSpec.scala │ ├── BulkConnectSpec.scala │ ├── BundleElementsSpec.scala │ ├── BundleLiteralSpec.scala │ ├── BundleSpec.scala │ ├── BundleWire.scala │ ├── ChiselEnum.scala │ ├── ChiselSpec.scala │ ├── ChiselTestUtilitiesSpec.scala │ ├── Clock.scala │ ├── CloneModuleSpec.scala │ ├── CompatibilityInteroperabilitySpec.scala │ ├── CompatibilitySpec.scala │ ├── CompileOptionsTest.scala │ ├── ComplexAssign.scala │ ├── ConnectSpec.scala │ ├── ConnectableSpec.scala │ ├── Counter.scala │ ├── CustomBundle.scala │ ├── DataEqualitySpec.scala │ ├── DataPrint.scala │ ├── Decoder.scala │ ├── DecoupledSpec.scala │ ├── DedupSpec.scala │ ├── Direction.scala │ ├── DontTouchSpec.scala │ ├── EnableShiftRegister.scala │ ├── EnumSpec.scala │ ├── ExtModule.scala │ ├── ExtModuleImpl.scala │ ├── GCD.scala │ ├── Harness.scala │ ├── IOCompatibility.scala │ ├── IllegalRefSpec.scala │ ├── ImplicitConversionsSpec.scala │ ├── InlineSpec.scala │ ├── InstanceNameSpec.scala │ ├── IntegerMathSpec.scala │ ├── IntervalRangeSpec.scala │ ├── InvalidateAPISpec.scala │ ├── LazyCloneSpec.scala │ ├── LiteralExtractorSpec.scala │ ├── LiteralToTargetSpec.scala │ ├── LoadMemoryFromFileSpec.scala │ ├── Math.scala │ ├── Mem.scala │ ├── MemorySearch.scala │ ├── MixedVecSpec.scala │ ├── Module.scala │ ├── ModuleExplicitResetSpec.scala │ ├── MulLookup.scala │ ├── MultiAssign.scala │ ├── MultiClockSpec.scala │ ├── MuxSpec.scala │ ├── NamedModuleTester.scala │ ├── NewAnnotationsSpec.scala │ ├── OneHotMuxSpec.scala │ ├── OptionBundle.scala │ ├── Padding.scala │ ├── ParameterizedModule.scala │ ├── PopCount.scala │ ├── PortSpec.scala │ ├── PrintableSpec.scala │ ├── Printf.scala │ ├── QueueFlushSpec.scala │ ├── QueueSpec.scala │ ├── RangeSpec.scala │ ├── RawModuleSpec.scala │ ├── RebindingSpec.scala │ ├── RecordSpec.scala │ ├── ReduceTreeSpec.scala │ ├── Reg.scala │ ├── ResetSpec.scala │ ├── Risc.scala │ ├── SIntOps.scala │ ├── ScalaIntervalSimulatorTest.scala │ ├── SourceLocatorSpec.scala │ ├── Stack.scala │ ├── Stop.scala │ ├── SwitchSpec.scala │ ├── Tbl.scala │ ├── TesterDriverSpec.scala │ ├── ToTargetSpec.scala │ ├── UIntOps.scala │ ├── Util.scala │ ├── Vec.scala │ ├── VecLiteralSpec.scala │ ├── VecToTargetSpec.scala │ ├── VectorPacketIO.scala │ ├── VerificationSpec.scala │ ├── WarningSpec.scala │ ├── When.scala │ ├── WidthSpec.scala │ ├── WireSpec.scala │ ├── aop │ │ ├── InjectionSpec.scala │ │ └── SelectSpec.scala │ ├── experimental │ │ ├── DataView.scala │ │ ├── DataViewIntegrationSpec.scala │ │ ├── DataViewTargetSpec.scala │ │ ├── FlatIOSpec.scala │ │ ├── ForceNames.scala │ │ ├── GroupSpec.scala │ │ ├── ModuleDataProductSpec.scala │ │ ├── ProgrammaticPortsSpec.scala │ │ ├── SerializableModuleGeneratorSpec.scala │ │ ├── TraceSpec.scala │ │ ├── Tuple.scala │ │ └── hierarchy │ │ │ ├── Annotations.scala │ │ │ ├── DefinitionSpec.scala │ │ │ ├── Examples.scala │ │ │ ├── InstanceSpec.scala │ │ │ ├── InstantiateSpec.scala │ │ │ ├── SeparateElaborationSpec.scala │ │ │ └── Utils.scala │ ├── naming │ │ ├── NamePluginSpec.scala │ │ └── PrefixSpec.scala │ ├── reflect │ │ └── DataMirrorSpec.scala │ ├── stage │ │ ├── ChiselAnnotationsSpec.scala │ │ ├── ChiselMainSpec.scala │ │ ├── ChiselOptionsViewSpec.scala │ │ ├── ChiselStageSpec.scala │ │ └── phases │ │ │ ├── AddImplicitOutputAnnotationFileSpec.scala │ │ │ ├── AddImplicitOutputFileSpec.scala │ │ │ ├── AddSerializationAnnotationsSpec.scala │ │ │ ├── ChecksSpec.scala │ │ │ ├── ConvertSpec.scala │ │ │ ├── ElaborateSpec.scala │ │ │ └── EmitterSpec.scala │ └── util │ │ ├── BitPatSpec.scala │ │ ├── BitSetSpec.scala │ │ ├── BitwiseSpec.scala │ │ ├── CatSpec.scala │ │ ├── PipeSpec.scala │ │ ├── PriorityMuxSpec.scala │ │ ├── RegSpec.scala │ │ ├── SizeOfSpec.scala │ │ ├── experimental │ │ ├── DecoderTableSpec.scala │ │ ├── PlaSpec.scala │ │ └── TruthTableSpec.scala │ │ └── random │ │ ├── LFSRSpec.scala │ │ └── PRNGSpec.scala │ ├── circtTests │ └── stage │ │ ├── CIRCTStageSpec.scala │ │ └── ChiselStageSpec.scala │ ├── cookbook │ ├── Bundle2UInt.scala │ ├── CookbookSpec.scala │ ├── FSM.scala │ ├── RegOfVec.scala │ ├── UInt2Bundle.scala │ ├── UInt2VecOfBool.scala │ └── VecOfBool2UInt.scala │ ├── examples │ ├── ImplicitStateVendingMachine.scala │ ├── SimpleVendingMachine.scala │ ├── VendingMachineGenerator.scala │ └── VendingMachineUtils.scala │ └── testCHA │ ├── GCD │ ├── GCD.scala │ └── GCDFormalSpec.scala │ ├── bus │ ├── SVAtest.scala │ ├── common │ │ ├── BusDecoder.scala │ │ ├── DummyMemory.scala │ │ ├── PeripheralsMap.scala │ │ ├── Switch1toN.scala │ │ └── Transaction.scala │ ├── native │ │ ├── NativeBus.scala │ │ └── NativeConfig.scala │ ├── tilelink │ │ ├── Harness.scala │ │ ├── StallUnit.scala │ │ ├── SwitchHarness.scala │ │ ├── TilelinkBus.scala │ │ ├── TilelinkConfig.scala │ │ ├── TilelinkDevice.scala │ │ ├── TilelinkErr.scala │ │ ├── TilelinkHost.scala │ │ └── TilelinkOpcodes.scala │ └── wishbone │ │ ├── Harness.scala │ │ ├── PeripheralMap.scala │ │ ├── WishboneBus.scala │ │ ├── WishboneConfig.scala │ │ ├── WishboneDevice.scala │ │ ├── WishboneErr.scala │ │ └── WishboneHost.scala │ ├── chiselbook │ ├── Adder │ │ ├── AdderTest.scala │ │ └── Adders.scala │ ├── Combinational │ │ ├── Combinational.scala │ │ └── CombinationalTest.scala │ └── Fifo │ │ ├── Fifo.scala │ │ └── FifoSpec.scala │ └── counter │ ├── Counter.scala │ ├── CounterFormal.scala │ ├── CounterFormalSpec.scala │ └── Counter_back.scala ├── stdlib └── src │ └── main │ └── scala │ └── chisel3 │ └── std │ └── BarrelShifter.scala └── website ├── .gitignore ├── .gitmodules ├── .mergify.yml ├── LICENSE ├── Makefile ├── README.md ├── build.sbt ├── docs └── src │ └── main │ ├── resources │ ├── json │ │ ├── README.md │ │ ├── smem_read_write.json │ │ └── smem_rw.json │ ├── microsite │ │ ├── data │ │ │ └── menu.yml │ │ └── img │ │ │ ├── jumbotron_pattern.png │ │ │ ├── jumbotron_pattern2x.png │ │ │ ├── navbar_brand.png │ │ │ ├── navbar_brand2x.png │ │ │ ├── second_icon.png │ │ │ ├── second_icon2x.png │ │ │ ├── sidebar_brand.png │ │ │ ├── sidebar_brand2x.png │ │ │ ├── third_icon.png │ │ │ └── third_icon2x.png │ └── svg │ │ ├── Makefile │ │ ├── chisel-jumbotron.svg │ │ ├── chisel-tool-icon-inverted.svg │ │ ├── chisel-tool-icon.svg │ │ ├── chisel-tool.svg │ │ └── firrtl-tech.svg │ └── tut │ ├── api │ ├── chisel3 │ │ ├── 3.5 │ │ │ ├── .index.md.swp │ │ │ └── index.md │ │ └── latest │ │ │ ├── .index.md.swp │ │ │ └── index.md │ └── index.md │ ├── chisel3 │ └── index.md │ ├── community.md │ └── doc │ └── chisel-cheatsheet3.pdf │ └── index.md ├── project ├── Contributors.scala ├── Version.scala ├── build.properties └── plugins.sbt ├── scripts └── decrypt-keys.sh └── travis-deploy-key.enc /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @freechipsproject/chisel-reviewers 2 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.scala-steward.conf: -------------------------------------------------------------------------------- 1 | updates.ignore = [ { groupId = "edu.berkeley.cs", artifactId = "firrtl" } ] 2 | pullRequests.frequency = "0 0 1 * *" # The first of every month 3 | -------------------------------------------------------------------------------- /.scalafix.conf: -------------------------------------------------------------------------------- 1 | rules = [ 2 | # DisableSyntax 3 | # ExplicitResultTypes 4 | #LeakingImplicitClassVal 5 | RemoveUnused 6 | #NoAutoTupling 7 | #NoValInForComprehension 8 | #ProcedureSyntax 9 | ] 10 | 11 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Syntax and Semantics of Sequence and Property Formulas.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/Syntax and Semantics of Sequence and Property Formulas.pdf -------------------------------------------------------------------------------- /build/firrtl_black_box_resource_files.f: -------------------------------------------------------------------------------- 1 | /home/merlin/Documents/chisel3/build/BlackBoxSwap.v 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /docs-target/src/main/resources/META-INF/services/mdoc.PostModifier: -------------------------------------------------------------------------------- 1 | chisel3.docs.VerilogMdocModifier 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /docs/src/images/chisel_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/docs/src/images/chisel_01.png -------------------------------------------------------------------------------- /docs/src/images/chisel_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/docs/src/images/chisel_logo.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /docs/src/images/type_hierarchy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/docs/src/images/type_hierarchy.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/javabdd-1.0b2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/lib/javabdd-1.0b2.jar -------------------------------------------------------------------------------- /lib/jhoafparser-1.1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/lib/jhoafparser-1.1.1.jar -------------------------------------------------------------------------------- /plugin/src/main/resources/scalac-plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | chiselplugin 3 | chisel3.internal.plugin.ChiselPlugin 4 | 5 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.8.2 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/resources/META-INF/services/firrtl.options.RegisteredLibrary: -------------------------------------------------------------------------------- 1 | chisel3.aop.AspectLibrary 2 | -------------------------------------------------------------------------------- /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/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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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/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/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 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/website/.gitmodules -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /website/docs/src/main/resources/json/README.md: -------------------------------------------------------------------------------- 1 | These files were used to generate the waveforms used in documentation. 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /website/docs/src/main/resources/microsite/img/jumbotron_pattern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/website/docs/src/main/resources/microsite/img/jumbotron_pattern.png -------------------------------------------------------------------------------- /website/docs/src/main/resources/microsite/img/jumbotron_pattern2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/website/docs/src/main/resources/microsite/img/jumbotron_pattern2x.png -------------------------------------------------------------------------------- /website/docs/src/main/resources/microsite/img/navbar_brand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/website/docs/src/main/resources/microsite/img/navbar_brand.png -------------------------------------------------------------------------------- /website/docs/src/main/resources/microsite/img/navbar_brand2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/website/docs/src/main/resources/microsite/img/navbar_brand2x.png -------------------------------------------------------------------------------- /website/docs/src/main/resources/microsite/img/second_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/website/docs/src/main/resources/microsite/img/second_icon.png -------------------------------------------------------------------------------- /website/docs/src/main/resources/microsite/img/second_icon2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/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/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/website/docs/src/main/resources/microsite/img/sidebar_brand.png -------------------------------------------------------------------------------- /website/docs/src/main/resources/microsite/img/sidebar_brand2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/website/docs/src/main/resources/microsite/img/sidebar_brand2x.png -------------------------------------------------------------------------------- /website/docs/src/main/resources/microsite/img/third_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/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/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/website/docs/src/main/resources/microsite/img/third_icon2x.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /website/docs/src/main/tut/api/chisel3/3.5/.index.md.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/website/docs/src/main/tut/api/chisel3/3.5/.index.md.swp -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /website/docs/src/main/tut/api/chisel3/latest/.index.md.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/website/docs/src/main/tut/api/chisel3/latest/.index.md.swp -------------------------------------------------------------------------------- /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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /website/project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.3.2 2 | -------------------------------------------------------------------------------- /website/project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.47deg" % "sbt-microsites" % "1.3.2") 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /website/travis-deploy-key.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iscas-tis/CHA/e0bdb577d826f5eb62e04c3dc300ef7c006d3d6f/website/travis-deploy-key.enc --------------------------------------------------------------------------------