├── .gitignore ├── README.md ├── build.sbt ├── build.sc ├── build.sh ├── project ├── build.properties └── plugins.sbt ├── scalastyle-config.xml ├── scalastyle-test-config.xml └── src ├── main └── scala │ └── gcd │ └── GCD.scala └── test └── scala └── gcd └── GCDTester.scala /.gitignore: -------------------------------------------------------------------------------- 1 | ### Project Specific stuff 2 | test_run_dir/* 3 | _temphelper.scala 4 | ### XilinxISE template 5 | # intermediate build files 6 | *.bgn 7 | *.bit 8 | *.bld 9 | *.cmd_log 10 | *.drc 11 | *.ll 12 | *.lso 13 | *.msd 14 | *.msk 15 | *.ncd 16 | *.ngc 17 | *.ngd 18 | *.ngr 19 | *.pad 20 | *.par 21 | *.pcf 22 | *.prj 23 | *.ptwx 24 | *.rbb 25 | *.rbd 26 | *.stx 27 | *.syr 28 | *.twr 29 | *.twx 30 | *.unroutes 31 | *.ut 32 | *.xpi 33 | *.xst 34 | *_bitgen.xwbt 35 | *_envsettings.html 36 | *_map.map 37 | *_map.mrp 38 | *_map.ngm 39 | *_map.xrpt 40 | *_ngdbuild.xrpt 41 | *_pad.csv 42 | *_pad.txt 43 | *_par.xrpt 44 | *_summary.html 45 | *_summary.xml 46 | *_usage.xml 47 | *_xst.xrpt 48 | 49 | # project-wide generated files 50 | *.gise 51 | par_usage_statistics.html 52 | usage_statistics_webtalk.html 53 | webtalk.log 54 | webtalk_pn.xml 55 | 56 | # generated folders 57 | iseconfig/ 58 | xlnx_auto_0_xdb/ 59 | xst/ 60 | _ngo/ 61 | _xmsgs/ 62 | ### Eclipse template 63 | *.pydevproject 64 | .metadata 65 | .gradle 66 | bin/ 67 | tmp/ 68 | *.tmp 69 | *.bak 70 | *.swp 71 | *~.nib 72 | local.properties 73 | .settings/ 74 | .loadpath 75 | 76 | # Eclipse Core 77 | .project 78 | 79 | # External tool builders 80 | .externalToolBuilders/ 81 | 82 | # Locally stored "Eclipse launch configurations" 83 | *.launch 84 | 85 | # CDT-specific 86 | .cproject 87 | 88 | # JDT-specific (Eclipse Java Development Tools) 89 | .classpath 90 | 91 | # Java annotation processor (APT) 92 | .factorypath 93 | 94 | # PDT-specific 95 | .buildpath 96 | 97 | # sbteclipse plugin 98 | .target 99 | 100 | # TeXlipse plugin 101 | .texlipse 102 | ### C template 103 | # Object files 104 | *.o 105 | *.ko 106 | *.obj 107 | *.elf 108 | 109 | # Precompiled Headers 110 | *.gch 111 | *.pch 112 | 113 | # Libraries 114 | *.lib 115 | *.a 116 | *.la 117 | *.lo 118 | 119 | # Shared objects (inc. Windows DLLs) 120 | *.dll 121 | *.so 122 | *.so.* 123 | *.dylib 124 | 125 | # Executables 126 | *.exe 127 | *.out 128 | *.app 129 | *.i*86 130 | *.x86_64 131 | *.hex 132 | 133 | # Debug files 134 | *.dSYM/ 135 | ### SBT template 136 | # Simple Build Tool 137 | # http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control 138 | 139 | target/ 140 | lib_managed/ 141 | src_managed/ 142 | project/boot/ 143 | .history 144 | .cache 145 | ### Emacs template 146 | # -*- mode: gitignore; -*- 147 | *~ 148 | \#*\# 149 | /.emacs.desktop 150 | /.emacs.desktop.lock 151 | *.elc 152 | auto-save-list 153 | tramp 154 | .\#* 155 | 156 | # Org-mode 157 | .org-id-locations 158 | *_archive 159 | 160 | # flymake-mode 161 | *_flymake.* 162 | 163 | # eshell files 164 | /eshell/history 165 | /eshell/lastdir 166 | 167 | # elpa packages 168 | /elpa/ 169 | 170 | # reftex files 171 | *.rel 172 | 173 | # AUCTeX auto folder 174 | /auto/ 175 | 176 | # cask packages 177 | .cask/ 178 | ### Vim template 179 | [._]*.s[a-w][a-z] 180 | [._]s[a-w][a-z] 181 | *.un~ 182 | Session.vim 183 | .netrwhist 184 | *~ 185 | ### JetBrains template 186 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio 187 | 188 | *.iml 189 | 190 | ## Directory-based project format: 191 | .idea/ 192 | # if you remove the above rule, at least ignore the following: 193 | 194 | # User-specific stuff: 195 | # .idea/workspace.xml 196 | # .idea/tasks.xml 197 | # .idea/dictionaries 198 | 199 | # Sensitive or high-churn files: 200 | # .idea/dataSources.ids 201 | # .idea/dataSources.xml 202 | # .idea/sqlDataSources.xml 203 | # .idea/dynamic.xml 204 | # .idea/uiDesigner.xml 205 | 206 | # Gradle: 207 | # .idea/gradle.xml 208 | # .idea/libraries 209 | 210 | # Mongo Explorer plugin: 211 | # .idea/mongoSettings.xml 212 | 213 | ## File-based project format: 214 | *.ipr 215 | *.iws 216 | 217 | ## Plugin-specific files: 218 | 219 | # IntelliJ 220 | /out/ 221 | 222 | # mpeltonen/sbt-idea plugin 223 | .idea_modules/ 224 | 225 | # JIRA plugin 226 | atlassian-ide-plugin.xml 227 | 228 | # Crashlytics plugin (for Android Studio and IntelliJ) 229 | com_crashlytics_export_strings.xml 230 | crashlytics.properties 231 | crashlytics-build.properties 232 | ### C++ template 233 | # Compiled Object files 234 | *.slo 235 | *.lo 236 | *.o 237 | *.obj 238 | 239 | # Precompiled Headers 240 | *.gch 241 | *.pch 242 | 243 | # Compiled Dynamic libraries 244 | *.so 245 | *.dylib 246 | *.dll 247 | 248 | # Fortran module files 249 | *.mod 250 | 251 | # Compiled Static libraries 252 | *.lai 253 | *.la 254 | *.a 255 | *.lib 256 | 257 | # Executables 258 | *.exe 259 | *.out 260 | *.app 261 | ### OSX template 262 | .DS_Store 263 | .AppleDouble 264 | .LSOverride 265 | 266 | # Icon must end with two \r 267 | Icon 268 | 269 | # Thumbnails 270 | ._* 271 | 272 | # Files that might appear in the root of a volume 273 | .DocumentRevisions-V100 274 | .fseventsd 275 | .Spotlight-V100 276 | .TemporaryItems 277 | .Trashes 278 | .VolumeIcon.icns 279 | 280 | # Directories potentially created on remote AFP share 281 | .AppleDB 282 | .AppleDesktop 283 | Network Trash Folder 284 | Temporary Items 285 | .apdisk 286 | ### Xcode template 287 | # Xcode 288 | # 289 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 290 | 291 | ## Build generated 292 | build/ 293 | DerivedData 294 | 295 | ## Various settings 296 | *.pbxuser 297 | !default.pbxuser 298 | *.mode1v3 299 | !default.mode1v3 300 | *.mode2v3 301 | !default.mode2v3 302 | *.perspectivev3 303 | !default.perspectivev3 304 | xcuserdata 305 | 306 | ## Other 307 | *.xccheckout 308 | *.moved-aside 309 | *.xcuserstate 310 | ### Scala template 311 | *.class 312 | *.log 313 | 314 | # sbt specific 315 | .cache 316 | .history 317 | .lib/ 318 | dist/* 319 | target/ 320 | lib_managed/ 321 | src_managed/ 322 | project/boot/ 323 | project/plugins/project/ 324 | 325 | # Scala-IDE specific 326 | .scala_dependencies 327 | .worksheet 328 | ### Java template 329 | *.class 330 | 331 | # Mobile Tools for Java (J2ME) 332 | .mtj.tmp/ 333 | 334 | # Package Files # 335 | *.jar 336 | *.war 337 | *.ear 338 | 339 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 340 | hs_err_pid* 341 | 342 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Chisel Project Template 2 | ======================= 3 | 4 | Lightweight/minimalistic version of the [Chisel template](https://github.com/ucb-bar/chisel-template). 5 | 6 | Uses [Verilator](https://github.com/freechipsproject/chisel3#ubuntu-like-linux) for Verilog simulations by default. Edit the tester in `src/test/scala/gcd/GCDTester.scala` to remove Verilator as a backend if this is undesirable. 7 | 8 | Contents at a glance: 9 | 10 | * `.gitignore` - helps Git ignore junk like generated files, build products, and temporary files. 11 | * `build.sbt` - instructs sbt to build the Chisel project 12 | * `build.sc` - instructs mill to build the Chisel project 13 | * `project/build.properties` - sets the sbt version 14 | * `src/main/scala/gcd/GCD.scala` - GCD source file 15 | * `src/test/scala/gcd/GCDTester.scala` - GCD tester 16 | * `project/plugins.sbt` - enables warnings (optional) 17 | * `scalastyle-*` - helps IDEs/code linters check for best coding practices (optional) 18 | 19 | Feel free to rename or delete `src/main/scala/gcd/GCD.scala` and `src/test/scala/gcd/GCDTester.scala` or use them as a reference/template. 20 | 21 | To run all tests in this design (recommended for test-driven development): 22 | 23 | For mill 0.6.0+: 24 | ```bash 25 | mill chiselModule.test 26 | ``` 27 | 28 | For sbt: 29 | ```bash 30 | sbt test 31 | ``` 32 | 33 | To generate Verilog for a module without parameters, run `./build.sh `. 34 | The package for a module is specified by the line beginning with `package` - e.g. `package gcd`. 35 | 36 | ```bash 37 | ./build.sh gcd GCD 38 | ``` 39 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | def scalacOptionsVersion(scalaVersion: String): Seq[String] = { 2 | Seq() ++ { 3 | // If we're building with Scala > 2.11, enable the compile option 4 | // switch to support our anonymous Bundle definitions: 5 | // https://github.com/scala/bug/issues/10047 6 | CrossVersion.partialVersion(scalaVersion) match { 7 | case Some((2, scalaMajor: Long)) if scalaMajor < 12 => Seq() 8 | case _ => Seq("-Xsource:2.11") 9 | } 10 | } 11 | } 12 | 13 | def javacOptionsVersion(scalaVersion: String): Seq[String] = { 14 | Seq() ++ { 15 | // Scala 2.12 requires Java 8. We continue to generate 16 | // Java 7 compatible code for Scala 2.11 17 | // for compatibility with old clients. 18 | CrossVersion.partialVersion(scalaVersion) match { 19 | case Some((2, scalaMajor: Long)) if scalaMajor < 12 => 20 | Seq("-source", "1.7", "-target", "1.7") 21 | case _ => 22 | Seq("-source", "1.8", "-target", "1.8") 23 | } 24 | } 25 | } 26 | 27 | name := "chisel-module-template-lite" 28 | 29 | version := "3.2.+" 30 | 31 | scalaVersion := "2.12.10" 32 | 33 | crossScalaVersions := Seq("2.11.12", "2.12.10") 34 | 35 | resolvers ++= Seq( 36 | Resolver.sonatypeRepo("snapshots"), 37 | Resolver.sonatypeRepo("releases") 38 | ) 39 | 40 | // Provide a managed dependency on X if -DXVersion="" is supplied on the command line. 41 | val defaultVersions = Map( 42 | "chisel3" -> "3.2.+", 43 | "chisel-iotesters" -> "1.3.+" 44 | ) 45 | 46 | libraryDependencies ++= (Seq("chisel3","chisel-iotesters").map { 47 | dep: String => "edu.berkeley.cs" %% dep % sys.props.getOrElse(dep + "Version", defaultVersions(dep)) }) 48 | 49 | scalacOptions ++= scalacOptionsVersion(scalaVersion.value) 50 | 51 | javacOptions ++= javacOptionsVersion(scalaVersion.value) 52 | -------------------------------------------------------------------------------- /build.sc: -------------------------------------------------------------------------------- 1 | // Works with mill 0.6.0 2 | import mill._, scalalib._ 3 | import coursier.MavenRepository 4 | 5 | /** 6 | * Scala 2.12 module that is source-compatible with 2.11. 7 | * This is due to Chisel's use of structural types. See 8 | * https://github.com/freechipsproject/chisel3/issues/606 9 | */ 10 | trait HasXsource211 extends ScalaModule { 11 | override def scalacOptions = T { 12 | super.scalacOptions() ++ Seq( 13 | "-deprecation", 14 | "-unchecked", 15 | "-Xsource:2.11" 16 | ) 17 | } 18 | } 19 | 20 | trait HasChisel3 extends ScalaModule { 21 | override def ivyDeps = Agg( 22 | ivy"edu.berkeley.cs::chisel3:3.2.+" 23 | ) 24 | // These lines are needed to use snapshot version of Chisel. 25 | def repositories = super.repositories ++ Seq( 26 | MavenRepository("https://oss.sonatype.org/content/repositories/snapshots") 27 | ) 28 | } 29 | 30 | trait HasChiselTests extends CrossSbtModule { 31 | object test extends Tests { 32 | override def ivyDeps = Agg( 33 | ivy"org.scalatest::scalatest:3.0.4", 34 | ivy"edu.berkeley.cs::chisel-iotesters:1.3+" 35 | ) 36 | // These lines are needed to use snapshot version of Chisel. 37 | def repositories = super.repositories ++ Seq( 38 | MavenRepository("https://oss.sonatype.org/content/repositories/snapshots") 39 | ) 40 | def testFrameworks = Seq("org.scalatest.tools.Framework") 41 | } 42 | } 43 | 44 | trait HasMacroParadise extends ScalaModule { 45 | // Enable macro paradise for @chiselName et al 46 | val macroPlugins = Agg(ivy"org.scalamacros:::paradise:2.1.0") 47 | def scalacPluginIvyDeps = macroPlugins 48 | def compileIvyDeps = macroPlugins 49 | } 50 | 51 | object chiselModule extends CrossSbtModule with HasChisel3 with HasChiselTests with HasXsource211 with HasMacroParadise { 52 | def crossScalaVersion = "2.12.10" 53 | } 54 | 55 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Helper script to elaborate a Chisel module that has no parameters. 3 | 4 | set -e 5 | 6 | package="$1" 7 | module="$2" 8 | if [ -z "$module" ]; then 9 | echo "Usage: ./build.sh " 10 | echo "For example, gcd.GCD can be elaborated using ./build.sh gcd GCD" 11 | exit 1 12 | fi 13 | 14 | cat < _temphelper.scala 15 | package _temphelper 16 | object Elaborate extends App { 17 | chisel3.Driver.execute(args, () => new ${package}.${module}()) 18 | } 19 | EOF 20 | 21 | echo "Elaborating module ${module}..." 22 | sbt "runMain _temphelper.Elaborate" 23 | echo "Elaborated Verilog available at ${module}.v" 24 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version = 1.1.1 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | logLevel := Level.Warn -------------------------------------------------------------------------------- /scalastyle-config.xml: -------------------------------------------------------------------------------- 1 | 2 | Scalastyle standard configuration 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | No lines ending with a ; 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | |\|\||&&|:=|<>|<=|>=|!=|===|<<|>>|##|unary_(~|\-%?|!))$]]> 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /scalastyle-test-config.xml: -------------------------------------------------------------------------------- 1 | 2 | Scalastyle configuration for Chisel3 unit tests 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | No lines ending with a ; 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | |\|\||&&|:=|<>|<=|>=|!=|===|<<|>>|##|unary_(~|\-%?|!))$]]> 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /src/main/scala/gcd/GCD.scala: -------------------------------------------------------------------------------- 1 | // See README.md for license details. 2 | 3 | package gcd 4 | 5 | import chisel3._ 6 | 7 | /** 8 | * Compute GCD using subtraction method. 9 | * Subtracts the smaller from the larger until register y is zero. 10 | * value in register x is then the GCD 11 | */ 12 | class GCD extends Module { 13 | val io = IO(new Bundle { 14 | val value1 = Input(UInt(16.W)) 15 | val value2 = Input(UInt(16.W)) 16 | val loadingValues = Input(Bool()) 17 | val outputGCD = Output(UInt(16.W)) 18 | val outputValid = Output(Bool()) 19 | }) 20 | 21 | val x = Reg(UInt()) 22 | val y = Reg(UInt()) 23 | 24 | when(x > y) { x := x - y } 25 | .otherwise { y := y - x } 26 | 27 | when(io.loadingValues) { 28 | x := io.value1 29 | y := io.value2 30 | } 31 | 32 | io.outputGCD := x 33 | io.outputValid := y === 0.U 34 | } 35 | -------------------------------------------------------------------------------- /src/test/scala/gcd/GCDTester.scala: -------------------------------------------------------------------------------- 1 | package gcd.test 2 | 3 | import gcd._ 4 | 5 | import chisel3.iotesters 6 | import chisel3.iotesters.{ChiselFlatSpec, Driver, PeekPokeTester} 7 | 8 | class GCDUnitTester(c: GCD) extends PeekPokeTester(c) { 9 | /** 10 | * Compute the gcd and the number of steps it should take to do it. 11 | * 12 | * @param a positive integer 13 | * @param b positive integer 14 | * @return the GCD of a and b, and how many steps it took 15 | */ 16 | def computeGcd(a: Int, b: Int): (Int, Int) = { 17 | var x = a 18 | var y = b 19 | var depth = 1 20 | while(y > 0) { 21 | if (x > y) { 22 | x -= y 23 | } 24 | else { 25 | y -= x 26 | } 27 | depth += 1 28 | } 29 | (x, depth) 30 | } 31 | 32 | private val gcd = c 33 | 34 | for(i <- 1 to 40 by 3) { 35 | for (j <- 1 to 40 by 7) { 36 | poke(gcd.io.value1, i) 37 | poke(gcd.io.value2, j) 38 | poke(gcd.io.loadingValues, 1) 39 | step(1) 40 | poke(gcd.io.loadingValues, 0) 41 | 42 | val (expected_gcd, steps) = computeGcd(i, j) 43 | 44 | step(steps - 1) // -1 is because we step(1) already to toggle the enable 45 | expect(gcd.io.outputGCD, expected_gcd) 46 | expect(gcd.io.outputValid, 1) 47 | } 48 | } 49 | } 50 | 51 | /** 52 | * This is a trivial example of how to run this Specification 53 | * From within sbt use: 54 | * {{{ 55 | * testOnly example.test.GCDTester 56 | * }}} 57 | * From a terminal shell use: 58 | * {{{ 59 | * sbt 'testOnly example.test.GCDTester' 60 | * }}} 61 | */ 62 | class GCDTester extends ChiselFlatSpec { 63 | // Disable this until we fix isCommandAvailable to swallow stderr along with stdout 64 | private val backendNames = Array("firrtl", "verilator") 65 | for ( backendName <- backendNames ) { 66 | "GCD" should s"calculate proper greatest common denominator (with $backendName)" in { 67 | Driver(() => new GCD, backendName) { 68 | c => new GCDUnitTester(c) 69 | } should be (true) 70 | } 71 | } 72 | } 73 | --------------------------------------------------------------------------------