Overview Instance 从DSL层面,一个component内包含两种语句statement
,
Declaration:声明,对应于出现的各个Data
Assignment:赋值,除了声明Data、子模块外的,所有语句均作为表达式的容器 ExpressionContainer
Tree:控制流
断言:
语句和实际写在scala里的一个语句不同。Scala语句,往往嵌套多个Spinal语句。
语句作为容器,装载不同类型的表达式 Expression
数据:直接对应表达式中涉及的Data
操作符:逻辑计算的各种一元、二元操作符 Operator
;操作符同样是 表达式容器,包含其涉及的操作数。
Operation 遍历
foreach,遍历容器内的元素,但只迭代一级
walk,迭代至最底层
置换
remap,将一个Expression
,通过一个function映射到新的一个Expression
删除
语句容器 ScopeStatement
每个语句都处于一个 parentScope
中,这样一个Scope,以 ScopeStatement
的形式出现。
定义:class ScopeStatement(var parentStatement: TreeStatement)
每个Component
都有一个 dslBody
作为其Scope,容纳Statement。每个 dslBody
的parentStatement
都是null,因为其直接是模块第一层容器。Scope也包含一个指向其Component的引用 component
。
When
、Switch
语句也可以张开一个Scope,在 dslBody
的基础上。相当于入栈 一个新的Scope。
Scope以环形链表来组织其内部的语句,每个scope有一个 head
和 last
指针,指向链表头尾两条语句。其以 prepend
和 append
的方法来插入语句。语句作为链表的节点,有 nextScopeStatement
和 lastScopeStatement
两个引用来指向其上一个和下一个节点语句。语句的 parentScope
指向自己所属的Scope。
当一条语句写在一个Scope内时,其首先会把自己加入到当前Scope中。如BaseType
,就是这么做的
1 2 3 4 DslScopeStack .get match { case null => case scope => scope.append(this ) }
Scope提供迭代语句的迭代器方法,以及foreach和walk的迭代方法。进一步,可以只迭代 DeclarationStatement
。
表达式容器 仅仅提供容器基本操作。
一级遍历 遍历内部表达式,仅仅一级遍历,不会对内部表达式做进一步遍历。
1 2 def foreachExpression(func: (Expression) => Unit): Unit def foreachDrivingExpression(func: (Expression) => Unit): Unit = foreachExpression(func)
全部遍历 遍历内部表达式,直至最底层。
def walkExpression(func: (Expression) => Unit): Unit
def walkExpressionPostorder(func: (Expression) => Unit): Unit
def walkDrivingExpressions(func: (Expression) => Unit): Unit
置换元素 给一个置换函数,可以将容器内的表达式根据函数置换为新的表达式。
1 2 def remapExpressions(func: (Expression) => Expression): Unit def remapDrivingExpressions(func: (Expression) => Expression): Unit = remapExpressions(func)
遍历置换 遍历的同时,做置换。
def walkRemapExpressions(func: (Expression) => Expression): Unit
def walkRemapDrivingExpressions(func: (Expression) => Expression): Unit
表达式 Expression
定义,继承BaseNode,一个表达式自己也是表达式容器。
trait Expression extends BaseNode with ExpressionContainer
覆写了foreachDrivingExpression
。
数据 这里的数据,不是 Data
数字信号 BaseType
即Spinal最基本,最单元的几种数据类型,Bool、BitVector、枚举、结构体。
注意到,数字信号本身即是表达式,也是一条声明语句。
模拟信号 AnalogDriver
包含一个data expression,一个enable expression。因此遍历和置换操作就发生在这两个表达式上。
字面值 Literal
各种数据类型的字面值。数字信号的字面量。表达式遍历和置换操作被取消。
修饰符 Modifier
是Expression 的别名,包括下面两种:
类型转换, Cast
在不同的基本数据类型之间做类型转换。包含一个 input
,遍历和置换发生在input
操作符 ,Operator
也是Expression 的别名。进一步分为:
一元,常数:两个实现基本一样,只包含一个 source
表达式。
二元:包含 left
和 right
两个子表达式。
多选符 ,Multiplexer
包含一个选择表达式 select
和待选的表达式数组 inputs
二选符 ,BinaryMultiplexer
包含一个条件 cond
, 以及两个带选项, whenTrue
和 whenFalse
访问符 ,SubAccess
取出bitvector中的一个bitfiled,其首先包含被访问的 source
。和赋值类似,访问操作可以是静态的和动态的,可以访问一个bit或者一段bitfield。
静态访问 Fixed,访问的位置固定
Bit access:包含固定整数 bitId
Range access:包含固定整数 hi
, lo
动态访问 Floating,访问的位置由表达式指定
Bit access: 包含 bitId
表达式
Range access:包含 offset
表达式,以及固定整数 size
。
位宽 Resize
不同数据类型的位宽调整。包含被调节位宽的 input
赋值AssignmentExpression
赋值分为两种,静态索引和动态索引。BitVectorAssignmentExpression
直接 继承 AssignmentExpression
,包含被赋值的数据 out
。因此迭代映射均作用在 out
上面。而对 driving expression的处理则被取消。
Fixed,除开包含 out
外
BitAssignmentFixed
, 包含一个index来选择一个bit
RangedAssignmentFixed
, 包含hi和lo来选择一个bit field
Floating,除开包含 out
外,
BitAssignmentFloating
, 还包含 bitId
表达式用来索引一个单独的bit
RangedAssignmentFixed
, 还包含 offset
表达式用来索引一个范围
语句 Statement
定义
trait Statement extends ExpressionContainer with ContextUser with ScalaLocated with BaseNode
方法:删除自己
语句安排为两个分类,TreeStatement
和 LeafStatement
Leaf 直接继承Statement
。几种最底层的语句,
DeclarationStatement
, 数据节点
数据节点对foreach、remap子表达式的操作进行了覆写,这两种操作被无效了,因为它们没有子表达式。
AssignmentStatement
,赋值连接
赋值包含 target
和 source
两个表达式。
Tree 继承Statement,但自己同样包含语句的容器 ScopeStatement
,区分为两种
WhenStatement
, 包含两个语句子容器 whenTrue
和 whenFalse
,以及作为条件表达式的 cond
。
SwitchStatement
,包含 value
表达式,以及多个 SwitchStatementElement
。每个 SwitchStatementElement
包含一个 key
表达式,和一个语句子容器 scopeStatement
。
Tree意味着包含子tree,最后到leaf。因此额外提供针对语句的遍历操作(依赖Scope的遍历) :
def foreachStatements(func: Statement => Unit)
def walkStatements(func : Statement => Unit): Unit
也有进一步,只针对leaf的遍历:
def walkLeafStatements(func: LeafStatement => Unit): Unit
更进一步,只针对leaf中的非memory port:
def foreachDeclarations(func: DeclarationStatement => Unit): Unit
def walkDeclarations(func: DeclarationStatement => Unit): Unit