• Chisel3


     
    介绍创建模块判断逻辑的when命令。
     
    1. when/elsewhen/otherwise
     
    伴生对象when中的工厂方法,会创建一个WhenContext:
     
    WhenContext含有方法elsewhen/otherwise:
    他们又各自创建一个新的WhenContext。
     
    WhenContext的构造方法在类体中:
     
    when(cond){...}
     
    a. firrtlDepth是判断的深度:when()时为0,elsewhen时即为1;所以当其大于0,则表明已经是一个else判断了,需要添加一条AltBegin命令;
    b. cond是一个Option,包裹着一个无参但返回Bool的函数。when/elsewhen中有,otherwise中为None。所以when/elsewhen中会添加一条WhenBegin命令,而otherwise中则无。
    c. Builder.whenDepth表示when嵌套的深度,第一层when为0,其block中的when的嵌套深度则为1。
    d. block是一个call-by-name参数,如同一个无参带返回的函数,第一次使用时调用。就是花括号括住的那段代码。其中可以有另一个when结构,所以在执行block之前和之后,需要对Builder.whenDepth进行处理。
    e. 如果是when/elsewhen,则添加WhenEnd命令;如果是otherwise,即cond为空,则添加OtherwiseEnd命令;
     
     
    2. unless
     
    unless基于when实现:
     
    3. switch/is
     
    switch/is使用Scala的宏实现:
    宏是为了支持switch(state) {...}的写法。最终会把这个结构转换成为一个SwitchContext。
    1) Tree为AST,即Abstract Syntax Tree,抽象语法树。cond为state,x为{...}这个代码块对应的AST。
    2) {...}中为一系列的 is(s){...},val q"..$body" = x 把x对应的列表,赋值给body,所以body是一个tree的列表,每个tree,是一个is(s){...}的结构;
    3) q"""new SwitchContext($cond, None, Set.empty)""" 相当于调用new SwitchContext(cond, None, Set.empty) 返回一个SwithContext;
    4) body.foldLeft(z)(op),意为把body中的元素从左边开始逐个带入op运算,亦即每次折叠一个元素,最终返回一个结果。op接收两个参数,第一个参数为前一次折叠结果,第二个为下一个要折叠的元素。第一次op运算时,使用默认的z作为前一次的折叠结果。
     
    a. 这里的z为new SwitchContext(cond, None, Set.empty) 创建的SwitchContext,而op为:
    所以,最后返回的是一个SwitchContext。
     
    b. op的两个参数为acc, tree,acc为前一次的折叠结果SwitchContext,tree为下一个待折叠的is(s){...};
     
    c. tree是一个is(){}调用,定义为:
    其只是一个占位符,方法实现只是一个简单的判断,并没有具体的实现。
     
    d. case q"chisel3.util.is.apply( ..$params )( ..$body )" 取出is(s,s,s,s,s){...} 中的states作为params,而{...}作为代码块body;
     
    e. q"$acc.is( ..$params )( ..$body )" 调用acc(SwitchContext)的is方法,并传入两个参数列表:
     
    总结下来,过程就是首先创建一个SwitchContext类的对象,然后逐个调用其is方法,最后返回一个SwitchContext对象;
     
    5) 返回最后的折叠结果,也就是一个SwitchContext对象:q"""{ $res }"""
     
     
    SwitchContext的实现如下:
    其基于WhenContext:
    a. 状态v和已有的状态值需要互斥,亦即不能存在多个相同的状态值判断;
    b. 如果v是多个状态,则只需要有一个为真即可:def p = v.map(_.asUInt === cond.asUInt).reduce(_||_)
    c. 如果是第一个is(s)判断,则使用when(),如果是后续的is(s)判断,则使用elsewhen:
     
     
     
     
  • 相关阅读:
    [Javascript] 面向对象编程思想
    [Javascript] “||”和“&&”的灵活运用
    [Java] HashMap、TreeMap、Hashtable排序
    [Java] 多个Map的性能比较(TreeMap、HashMap、ConcurrentSkipListMap)
    [Java] 集合类(List、Set、Map的基本使用)
    [Java] Map 集合类简介
    [Javascript,JSON] JQuery处理json与ajax返回JSON实例
    [PHP] Eclipse开发PHP环境配置
    nginx的 CPU参数worker_processes和worker_cpu_affinity使用说明
    【HTTP 2】启用 HTTP 2(Starting HTTP/2)
  • 原文地址:https://www.cnblogs.com/wjcdx/p/10224276.html
Copyright © 2020-2023  润新知