risc-v中文社区

 找回密码
 立即注册
查看: 1112|回复: 1

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

[复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-8-24 14:08:49 | 显示全部楼层 |阅读模式
既然抽象类View不能在object config所在的包外面使用,那abstract class Parameters extends View
可不可以在外面使用呢?通过查看源代码,可以发现Parameters抽象类中的抽象方法是:
protected[config] def chain[T](site:View,tail:View,pname:Field[T]):Option[T]
这种情况如果在外面实例化使用(extends之后),就和前面的View在外面使用是一样的语法情形,所以不需要实验
就可以知道结果。但有一个object Parameters伴生对象,它的
apply(fView,View,View) => PartialFunction[Any,Any])arameters = new ParatialParameters(f)
所以说,外面使用Parameters只能通过Parameters的伴生对象的apply实例化对象了。
我们来做个实验:

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

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

现在看来,需要明白fView,View,View) => PartialFunction[Any,Any]以及Config的主构造参数Parameters来自哪里???
感觉这个parameters参数只能来自object Parameters的apply,也就是说要理解上述fView,View,View) => PartialFunction[Any,Any]
先看看config源码中的各个private class:
View的直接子类有TerminalView和ChainView,它们只需要实现View的抽象方法def find[T]即可
TerminalView中:def find[T](pname:Field[T],site:View):Option[T] = pnmae.default
也就是说在TerminalView中find直接获取pname这个Field[T]的default(它就是主构造参数值)
ChainView子类带有二个主构造参数,一个是headarameters,代表参数头,另一个是tail:View,代表尾部View。
ChainView中:
def find[T](pname:Field[T],site:View):Option[T]= 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(xarameters,yarameters) extends Parameters {
  def chain[T](site:View,tail:View,pname:Field[T]) = x.chain(site,new ChainView(y,tail),pname)
  //也就是说,中间链chainParameters参数列表的chain方法是用主构造参数x的chain方法进行调用
  //传入的还是site这个视图,新new出来的ChainView视以及待查的属性pname:Field[T]
}
private class EmptyParameters extends Parameters {
  def chain[T](site:View,tail:View,pname:Field[T]) = tail.find(pname,site)
  //空参数列表类EmptyParameters,它的抽象方法chain的实现过程是:
  //尾视头tail调用这个视图类的find方法,从ChainView和TerminalView的find方法可知,
  //从头Parameters到尾Parameters查属性Field[T]  
}
private class PartialParameters(fView,View,View) => PartialFunction[Any,Any]) extends Parameters {
  protected[config] def chain[T](site:View,tail:View,pname:Field[T]) = {
    val g = f(site,this,tail) //关键要搞明白这个函数的作用?返回偏函数PartialFunction[Any,Any]作用?意义??
        if(g.isDefinedAt(pname)) Some(g.apply(pname).asInstanceOf[T]) //偏函数中有这个pname处理则返回这个属性
        else tail.find(pname,site) //否则用尾视图View tail的find继续查找(传的参数是待查属性和站视图site View)
  }
}
private class MapParameters(map:Map[Any,Any]) extends Parameters {
  protected[config] def chain(site:View,tail:View,pname:Field[T]) = {
    val g = map.get(pname)
        if(g.isDefined) Some(g.apply(pname).asInstanceOf[T])
        else tail.find(pname,site)
        //g的类型是Option[Field[T]],所以g.isDefined调用的是Option的def isDefined:Boolean
        //即这个Option中是否存在值即是否有Some(某个Field[T]类型的值)值存在,
        //g.get获这个Some(某个Field[T]]中的Field[T]类型的值
        //然后用用asInstanceOf[T]进行类型转换,也就获得属性值对象
        //否则用尾部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站点视图)继续查找

回复

使用道具 举报

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
 楼主| 发表于 2021-8-24 16:02:40 | 显示全部楼层
下一帖,模拟在芯片设计中是如何使用配置参数的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-4-29 07:03 , Processed in 0.015598 second(s), 17 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表