通过继承Bundle,在SpinalHDL中我们可以定义各种各样的复合数据类型。今天,关于Bundle的几个容易被忽略的点,一同来看下。 》Bundle 个人在使用SpinalHDL来描述电路时,凡是牵涉到需要定义多种类型为一组信号(比如Axi4总线)时,一般均会通过扩展Bundle来进行总线的定义。这里为简单起见,定义如下的port:
这里在port中,定义了两个8bit位宽的data0,data1两个UInt信号以及为该方法定义了一个sum求和函数,文中针对该总线进行功能描述。而就SpinalHDL中关于代码描述的一些建议,在之前的文章中也有提及:《SpinalHDL代码组织结构之Component》 》assignFromBits 当你的接口定义即成了Bundle时,你所定义的所有信号都存储在一个elements的ArrayBuffer中。而在Bundle里,其定义了assignFromBits函数,可以用Bits信号给这种复合类型接口进行赋值:
去看他的逻辑实现其实很简单,其实现就是将你在Bundle中定义的信号按照你信号定义的顺序依次从Bits信号的低比特位置依次获取值。这使得在某些场景下信号的赋值变得十分便捷:
这里只是一个简单的求和电路,通过assignFromBits来对dataBus中的data0,data1进行赋值,其顺序为:
》asBits asBits方法与上面的assignFromBits功能相反,能够让我们快速的将复合类型快速填充到信号Bits信号中去:
其实现也是一样,先定义的信号会放在低位:
》比较判断 对于复合数据类型场景,SpinalHDL也定义了比较操作符===和=/=,用于两个总线端口是否完全匹配:
这避免了我们手动去一一对比判定,这里的实现等效于:
》getZero 对于复合数据类型,当我们需要将所有的信号统一赋值为0时可以调用getZero方法:
这里电路描述当sel为高电平时,输入输出直连,否则所有的输出端口均赋值为0。通过getZero,避免了在复合数据类型中手动一一赋值的麻烦。当然,你也可以这么来写达到相同的效果:
》写在最后 当你觉得有一个功能在SpinalHDL中描述起来很费劲时,大概率是你没找对方法~
原作者:玉骐
|