diff options
| author | Jack Koenig | 2018-06-20 17:09:48 -0700 |
|---|---|---|
| committer | GitHub | 2018-06-20 17:09:48 -0700 |
| commit | 980778b1874b93b7e2778eb0c8f666f9691176f1 (patch) | |
| tree | a42175ff8a8b83e75e4e89eb98264b8cdc8ba584 /chiselFrontend/src/main/scala/chisel3/core/UserModule.scala | |
| parent | 4cccd877c25116a1f0b90824aabfc689d7fe50ea (diff) | |
Programmatic Port Creation (#833)
Add chisel3.experimental.IO for programmatic port creation in Raw and
MultiIOModules. suggestName is required to name ports that cannot be
named by reflection. Two ports cannot be given the same name.
Diffstat (limited to 'chiselFrontend/src/main/scala/chisel3/core/UserModule.scala')
| -rw-r--r-- | chiselFrontend/src/main/scala/chisel3/core/UserModule.scala | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/chiselFrontend/src/main/scala/chisel3/core/UserModule.scala b/chiselFrontend/src/main/scala/chisel3/core/UserModule.scala index 17b8a09e..831b3707 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/UserModule.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/UserModule.scala @@ -38,6 +38,22 @@ abstract class UserModule(implicit moduleCompileOptions: CompileOptions) val compileOptions = moduleCompileOptions + private[chisel3] def namePorts(names: HashMap[HasId, String]): Unit = { + for (port <- getModulePorts) { + port.suggestedName.orElse(names.get(port)) match { + case Some(name) => + if (_namespace.contains(name)) { + Builder.error(s"""Unable to name port $port to "$name" in $this,""" + + " name is already taken by another port!") + } + port.setRef(ModuleIO(this, _namespace.name(name))) + case None => Builder.error(s"Unable to name port $port in $this, " + + "try making it a public field of the Module") + } + } + } + + private[core] override def generateComponent(): Component = { require(!_closed, "Can't generate module more than once") _closed = true @@ -45,10 +61,7 @@ abstract class UserModule(implicit moduleCompileOptions: CompileOptions) val names = nameIds(classOf[UserModule]) // Ports get first naming priority, since they are part of a Module's IO spec - for (port <- getModulePorts) { - require(names.contains(port), s"Unable to name port $port in $this") - port.setRef(ModuleIO(this, _namespace.name(names(port)))) - } + namePorts(names) // Then everything else gets named for ((node, name) <- names) { @@ -170,6 +183,15 @@ abstract class LegacyModule(implicit moduleCompileOptions: CompileOptions) names } + private[chisel3] override def namePorts(names: HashMap[HasId, String]): Unit = { + for (port <- getModulePorts) { + // This should already have been caught + if (!names.contains(port)) throwException(s"Unable to name port $port in $this") + val name = names(port) + port.setRef(ModuleIO(this, _namespace.name(name))) + } + } + private[core] override def generateComponent(): Component = { _compatAutoWrapPorts() // pre-IO(...) compatibility hack |
