summaryrefslogtreecommitdiff
path: root/chiselFrontend/src/main/scala/chisel3/core/UserModule.scala
diff options
context:
space:
mode:
authorJack Koenig2018-06-20 17:09:48 -0700
committerGitHub2018-06-20 17:09:48 -0700
commit980778b1874b93b7e2778eb0c8f666f9691176f1 (patch)
treea42175ff8a8b83e75e4e89eb98264b8cdc8ba584 /chiselFrontend/src/main/scala/chisel3/core/UserModule.scala
parent4cccd877c25116a1f0b90824aabfc689d7fe50ea (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.scala30
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