SpinalHDL 1.9.4版本中的PackedBundle、PackedWordBundle的使用

聊一聊spinalhdl 1.9.4版本中的packedbundle、packedwordbundle的使用
位域的提取与封装     在逻辑设计里,但凡牵涉到协议,一般都避免不了协议字段的提取。以下面的一个简单协议为例:
这里256bit输入数据,包含了五个协议字段:
host_addr:64 bits
card_addr:64 bits
length:14 bits
sop:1 bits
eop:1 bits 
    在进行协议解析时,我们可能会定义如下数据类型:
case class descriptor() extends bundle{    val host_addr=uint(64 bits)    val card_addr=uint(64 bits)    val length=uint(14 bits)    val sop=bool()    val eop=bool()  override def assignfrombits(data:bits)={    host_addr.assignfrombits(data(0,64 bits))    card_addr.assignfrombits(data(64,64 bits))    length.assignfrombits(data(128,14 bits))    sop:=data(144)    eop:=data(145)  }  override def asbits():bits={    eop##sop##b(0,2 bits)##length##card_addr##host_addr  }}  
    在descriptor中,我们重写了assignfrombits()和asbits用于协议字段的提取与数据流的的封装.如此,我们在使用时即可在代码使用时使代码里尽可能的简洁明了:
在一个大型工程里,往往可能存在许多的协议定义,那么协议的提取与数据流封装就往往需要许多这种assignfrombits()和asbits的重写了,“繁重的”体力劳动。
    在spinalhdl 1.9.4版本中,引入了packedbundle、packedwordbundle两个组件(之前的版本略有bug)。从而能够避免这种重复的体力活。像上面的结构中,可以直接这么定义descriptor数据类型:
case class descriptor() extends packedbundle {  val host_addr=uint(64 bits).packfrom(0)  val card_addr=uint(64 bits).packfrom(64)  val length=uint(14 bits) //根据当前已使用的位域推断其对应的位域  val sop=bool().packfrom(128+16)  val eop=bool().packfrom(128+16+1)}  
   我们无需再override任何函数,仅需定义数据类型即可。在使用时:
通过unpack,可以从data_in中提取协议字段,通过packed方法,可以将协议字段按照位域封装成数据流。
》packedbundle
    在packedbundle中,为spinalhdl中的基础数据类型隐式扩展了datapositionenrich类。为其定义了用于位域绑定的函数:
def pack(range: range)
def pack(range: range, endianness: endianness = little)
def packfrom(pos: int)
def packto(pos: int)
    通过这几个函数,我们可以在使用时对定义的字段绑定位域。这里面在使用时更倾向于后面两种方式。对于packto与packfrom,下面的descriptor描述方式和上面的descriptor是等效的:
case class descriptor() extends packedbundle {  val host_addr=uint(64 bits).packto(63)  val card_addr=uint(64 bits).packto(127)  val length=uint(14 bits)  val sop=bool().packfrom(128+16)  val eop=bool().packfrom(128+16+1)}  
    而通过packedbundle中所提供的pack方法,可以用于将我们定义的数据类型封装成数据流:
def packed: bits
    而对于从数据流中提取协议字段,则可以通过unpack方法:
def unpack(bits: bits)
def unpack(bits: bits, hi: int, lo: int)
    第二个方法使用场景可能相对较少,感兴趣的可以去看源代码。
》packedwordbundle
    packedwordbundle是在packedbundle的基础上扩展而来,从而能够按照word进行位域绑定,使用相对简单,不再做额外赘述,参考例子:
》使用注意
    对于packedbundle、packedwordbundle,其有种c语言位域结构体的味道,可以方便的定义位域,减少重复性的开发工作。不过其中有一点是其允许位域重复,如下所示:
case class descriptor() extends packedbundle {  val host_addr=uint(64 bits).packto(63)  val card_addr=uint(64 bits).packto(63)  val length=uint(14 bits)  val sop=bool().packfrom(128+16)  val eop=bool().packfrom(128+16+1)}  
    将card_addr与host_addr绑定到相同的位置是允许的,在进行pack时由于last valid assignment win,host_addr将不会被使用。故在使用时需注意别重复绑定。


环境传感器在实际设计应用中应考虑哪些问题
报警电路的类型原理及问题分析
WiFi 6是什么,它有什么优势优点
大有可为!泰科协作机器人全面布局医疗健康行业
浅析电网干扰
SpinalHDL 1.9.4版本中的PackedBundle、PackedWordBundle的使用
呕吐毒素定量检测仪的功能都有哪些
SR控制器是能够提高效率的潜在解决方案
工业级的数据连接器具备哪些特点?看一下你知道几点
教大家怎么样才能在日常开发中减少bug
雅特力AT32 MCU「芯」势力崛起,驱动AIoT「芯」未来
三星股东炸了!既然支持分拆决议,该何去何从?
2018年中国智能音箱出货量将增长12倍 呈现三足鼎立的格局
SD-WAN是零售业的创收者
对于大多数科技行业来说 2018年是人工智能的清算年
看到这些人工智能实例你有没有惊叹
为什么ARM将会成为物联网时代的的引领者?
C/C++之面向对象编程思想3
MWC2023看点:中兴通讯十大无线新品及方案助力运营商建设全频段融合的5G网络
国内IC产业IDM龙头大厂何时现身