Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated reflective finding of declared vals in Bundles. #181

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/scala/Bundle.scala
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class Bundle(view_arg: Seq[String] = null)(implicit _params:Option[Parameters] =
val c = getClass();
var elts = ArrayBuffer[(String, Data)]();
val seen = ArrayBuffer[Object]();
for (m <- c.getMethods.sortWith(
for (m <- FindValAccessors(c).sortWith(
(x, y) => (x.getName() < y.getName())
)) {
val name = m.getName();
Expand All @@ -82,7 +82,7 @@ class Bundle(view_arg: Seq[String] = null)(implicit _params:Option[Parameters] =
val isInterface = classOf[Data].isAssignableFrom(rtype);

// TODO: SPLIT THIS OUT TO TOP LEVEL LIST
if( types.length == 0 && !isStatic(modifiers) && isInterface
if(!isStatic(modifiers) && isInterface
&& !(Bundle.keywords contains name)
&& (view == null || view.contains(name)) ) {
val o = m.invoke(this);
Expand Down
34 changes: 34 additions & 0 deletions src/main/scala/FindValAccessors.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package Chisel

import scala.collection.mutable.ArrayBuffer
import java.lang.reflect.Modifier._
import java.lang.reflect.Method

object FindValAccessors {

private def getValNames(c: Class[_]): ArrayBuffer[String] = {
val valNames = new ArrayBuffer[String]()
for (v <- c.getDeclaredFields) {
v.setAccessible(true)
valNames += v.getName
}
val sc = c.getSuperclass
if (sc != null) { valNames ++= getValNames(sc) }
valNames
}

def apply(c: Class[_]): ArrayBuffer[Method] = {
val valNames = getValNames(c)
val valAccessors = new ArrayBuffer[Method]()
for (m <- c.getDeclaredMethods) {
val ml = ArrayBuffer(m)
val name = m.getName()
val types = m.getParameterTypes()
if (types.length == 0 && valNames.contains(name)) {
valAccessors ++= ml
}
}
valAccessors
}

}
28 changes: 2 additions & 26 deletions src/main/scala/Module.scala
Original file line number Diff line number Diff line change
Expand Up @@ -407,29 +407,6 @@ abstract class Module(var clock: Clock = null, private[Chisel] var _reset: Bool
}
}

def getClassValNames(c: Class[_]): ArrayBuffer[String] = {
val valnames = new ArrayBuffer[String]()
for (v <- c.getDeclaredFields) {
v.setAccessible(true)
valnames += v.getName
}
val sc = c.getSuperclass
if (sc != null) { valnames ++= getClassValNames(sc) }
valnames
}

// Allow checking if a method name is also the name of a val -- reveals accessors
def getValNames = {
val valnames = new ArrayBuffer[String]()
valnames ++= getClassValNames(getClass)
valnames
}

object isValName {
val valnames = Module.this.getValNames
def apply(name: String) = valnames.contains(name)
}

// 1) name the component
// 2) name the IO
// 3) name and set the component of all statically declared nodes through introspection
Expand All @@ -441,13 +418,12 @@ abstract class Module(var clock: Clock = null, private[Chisel] var _reset: Bool
Since we call invoke() to get a proper instance of the correct type,
we have to insure the method is accessible, thus all fields
that will generate C++ or Verilog code must be made public. */
for (m <- getClass().getDeclaredMethods.sortWith(
for (m <- FindValAccessors(getClass()).sortWith(
(x, y) => (x.getName() < y.getName())
)) {
val name = m.getName();
val types = m.getParameterTypes();
if (types.length == 0 && isValName(name) // patch to avoid defs
&& isPublic(m.getModifiers())) {
if (isPublic(m.getModifiers())) {
val o = m.invoke(this);
o match {
case node: Node => {
Expand Down