joe 发表于 2021-8-24 14:08:49

rocketchip高级参数化机制--语法实验(4)

既然抽象类View不能在object config所在的包外面使用,那abstract class Parameters extends View
可不可以在外面使用呢?通过查看源代码,可以发现Parameters抽象类中的抽象方法是:
protected def chain(site:View,tail:View,pname:Field):Option
这种情况如果在外面实例化使用(extends之后),就和前面的View在外面使用是一样的语法情形,所以不需要实验
就可以知道结果。但有一个object Parameters伴生对象,它的
apply(f:(View,View,View) => PartialFunction):Parameters = new ParatialParameters(f)
所以说,外面使用Parameters只能通过Parameters的伴生对象的apply实例化对象了。
我们来做个实验:

父类View有一个API接口即抽象方法find,子类Parameters有另有一个API接口也是抽象方法chain,但在子类中实现了
父类中的find,只不过这个find的实现是使用了本类中的抽象方法chain,总体来说,父类和子类中的
API接口都交给孙类Config中来处理了。有一个代码现象要注意:在子类Parameters的伴生对象中有apply方法:
def apply(f:(View,View,View) => ParticalFunction):Parameters = new PartialParameters(f)
问题想法:是不是只要提供了一个f出来,用val p = Parameters(f)就可以实例化出来一个对象呢?
通过上面源码中new PartialParameters(f)感觉确实可以,也就是说,我可以将class PartialParameters这个类
做成我自己的类放到我的包中:
class MyPartialParameters(f: (View, View, View) => PartialFunction) extends Parameters {
protected def chain(site: View, tail: View, pname: Field) = {
    val g = f(site, this, tail)
    if (g.isDefinedAt(pname)) Some(g.apply(pname).asInstanceOf) else tail.find(pname, site)
}
}
结果还是同样的原因config造成的语法错误。所以这个new PartialParameters(f)只能是在config包中。

这种机制有什么好处呢?为什么不用list机制?还有没有其它机制???比如订阅模式?事件模式?责任链模式??
可能各种机制各有各的好处,而chisel针对芯片设计,它需要的功能其它机制不太好处理????

现在看来,需要明白f:(View,View,View) => PartialFunction以及Config的主构造参数P:Parameters来自哪里???
感觉这个p:Parameters参数只能来自object Parameters的apply,也就是说要理解上述f:(View,View,View) => PartialFunction
先看看config源码中的各个private class:
View的直接子类有TerminalView和ChainView,它们只需要实现View的抽象方法def find即可
TerminalView中:def find(pname:Field,site:View):Option = pnmae.default
也就是说在TerminalView中find直接获取pname这个Field的default(它就是主构造参数值)
ChainView子类带有二个主构造参数,一个是head:Parameters,代表参数头,另一个是tail:View,代表尾部View。
ChainView中:
def find(pname:Field,site:View):Option= head.chain(site,tail,pname)
上述TerminalView和ChainView涉及到的Parameters和View及Field的感觉就是:
视图View中有find抽象方法,Parameters参数列表有chain链抽象方法,
当然,Parameters是View的子类,View视图中的find通过Parameters参数列表中的抽象方法chain实现,
ChainView视图在查找的时候即其def find时候,调用头Parameters参数列表的chain方法

再来看Parameters相关的各个private子类:
private class ChainParameters(x:Parameters,y:Parameters) extends Parameters {
def chain(site:View,tail:View,pname:Field) = x.chain(site,new ChainView(y,tail),pname)
//也就是说,中间链chainParameters参数列表的chain方法是用主构造参数x的chain方法进行调用
//传入的还是site这个视图,新new出来的ChainView视以及待查的属性pname:Field
}
private class EmptyParameters extends Parameters {
def chain(site:View,tail:View,pname:Field) = tail.find(pname,site)
//空参数列表类EmptyParameters,它的抽象方法chain的实现过程是:
//尾视头tail调用这个视图类的find方法,从ChainView和TerminalView的find方法可知,
//从头Parameters到尾Parameters查属性Field
}
private class PartialParameters(f:(View,View,View) => PartialFunction) extends Parameters {
protected def chain(site:View,tail:View,pname:Field) = {
    val g = f(site,this,tail) //关键要搞明白这个函数的作用?返回偏函数PartialFunction作用?意义??
        if(g.isDefinedAt(pname)) Some(g.apply(pname).asInstanceOf) //偏函数中有这个pname处理则返回这个属性
        else tail.find(pname,site) //否则用尾视图View tail的find继续查找(传的参数是待查属性和站视图site View)
}
}
private class MapParameters(map:Map) extends Parameters {
protected def chain(site:View,tail:View,pname:Field) = {
    val g = map.get(pname)
        if(g.isDefined) Some(g.apply(pname).asInstanceOf)
        else tail.find(pname,site)
        //g的类型是Option],所以g.isDefined调用的是Option的def isDefined:Boolean
        //即这个Option中是否存在值即是否有Some(某个Field类型的值)值存在,
        //g.get获这个Some(某个Field]中的Field类型的值
        //然后用用asInstanceOf进行类型转换,也就获得属性值对象
        //否则用尾部tail这个View视图,调用尾部视图的find方法进一步查
        //当然,视图的find方法也是传的属性pname和site站点视图
}
}
对于各个参数列表类Parameters子类,总结来看:
链参数列表类ChainParameters通过主构造传来的x参数列表调用chain(站视图site,new ChainView(
y参数列表,tail尾视图)即构建一个新的链View(ChainView),pname属性)
即链参数列表类ChainParameters在chain调用过程中会构建新的chainView视图进行查找
空参数列表EmptyParameters的chain调用过程就是用尾部视图tail的find进行查找(参数为属性pname和站点视图site)
部分参数列表PartialParameters的chain调用过程就是先将主构造参数f进行函数调用,
它返回的是一个偏函数,如果这个偏函数中有处理属性,那么返回这个属性对象,
否则,用尾视图tail通过它的find(pname属性,site站点视图)继续查找

joe 发表于 2021-8-24 16:02:40

下一帖,模拟在芯片设计中是如何使用配置参数的。
页: [1]
查看完整版本: rocketchip高级参数化机制--语法实验(4)