2016-11-28 01:16:37 +01:00
|
|
|
// See LICENSE.SiFive for license details.
|
|
|
|
|
2017-07-07 19:48:16 +02:00
|
|
|
package freechips.rocketchip.config
|
2016-11-18 23:03:07 +01:00
|
|
|
|
|
|
|
class Field[T]
|
|
|
|
|
|
|
|
abstract class View {
|
2016-11-24 03:06:33 +01:00
|
|
|
final def apply[T](pname: Field[T]): T = apply(pname, this)
|
|
|
|
final def apply[T](pname: Field[T], site: View): T = find(pname, site).asInstanceOf[T]
|
2016-11-18 23:03:07 +01:00
|
|
|
|
|
|
|
protected[config] def find(pname: Any, site: View): Any
|
|
|
|
}
|
|
|
|
|
|
|
|
abstract class Parameters extends View {
|
2017-01-13 23:41:19 +01:00
|
|
|
final def ++ (x: Parameters): Parameters = new ChainParameters(this, x)
|
|
|
|
final def alter(f: (View, View, View) => PartialFunction[Any,Any]): Parameters = Parameters(f) ++ this
|
|
|
|
final def alterPartial(f: PartialFunction[Any,Any]): Parameters = Parameters((_,_,_) => f) ++ this
|
2016-11-18 23:03:07 +01:00
|
|
|
|
|
|
|
protected[config] def chain(site: View, tail: View, pname: Any): Any
|
|
|
|
protected[config] def find(pname: Any, site: View) = chain(site, new TerminalView, pname)
|
|
|
|
}
|
|
|
|
|
|
|
|
object Parameters {
|
2017-01-13 23:41:19 +01:00
|
|
|
def empty: Parameters = new EmptyParameters
|
|
|
|
def apply(f: (View, View, View) => PartialFunction[Any,Any]): Parameters = new PartialParameters(f)
|
2016-11-18 23:03:07 +01:00
|
|
|
def root(p: Parameters) = p
|
|
|
|
}
|
|
|
|
|
|
|
|
class Config(p: Parameters) extends Parameters {
|
2017-01-13 23:41:19 +01:00
|
|
|
def this(f: (View, View, View) => PartialFunction[Any,Any]) = this(Parameters(f))
|
2016-11-18 23:03:07 +01:00
|
|
|
|
|
|
|
protected[config] def chain(site: View, tail: View, pname: Any) = p.chain(site, tail, pname)
|
|
|
|
override def toString = this.getClass.getSimpleName
|
|
|
|
def toInstance = this
|
|
|
|
}
|
|
|
|
|
|
|
|
// Internal implementation:
|
|
|
|
|
|
|
|
private class TerminalView extends View {
|
|
|
|
private class Unusable
|
|
|
|
def find(pname: Any, site: View): Any = pname match { case x: Unusable => () }
|
|
|
|
}
|
|
|
|
|
|
|
|
private class ChainView(head: Parameters, tail: View) extends View {
|
|
|
|
def find(pname: Any, site: View) = head.chain(site, tail, pname)
|
|
|
|
}
|
|
|
|
|
|
|
|
private class ChainParameters(x: Parameters, y: Parameters) extends Parameters {
|
|
|
|
def chain(site: View, tail: View, pname: Any) = x.chain(site, new ChainView(y, tail), pname)
|
|
|
|
}
|
|
|
|
|
|
|
|
private class EmptyParameters extends Parameters {
|
|
|
|
def chain(site: View, tail: View, pname: Any) = tail.find(pname, site)
|
|
|
|
}
|
|
|
|
|
2017-01-13 23:41:19 +01:00
|
|
|
private class PartialParameters(f: (View, View, View) => PartialFunction[Any,Any]) extends Parameters {
|
2016-11-18 23:03:07 +01:00
|
|
|
protected[config] def chain(site: View, tail: View, pname: Any) = {
|
2017-01-13 23:41:19 +01:00
|
|
|
val g = f(site, this, tail)
|
|
|
|
if (g.isDefinedAt(pname)) g.apply(pname) else tail.find(pname, site)
|
2016-11-18 23:03:07 +01:00
|
|
|
}
|
|
|
|
}
|