spinal HDL - 03 - Spinal HDL数据类型 - 复合数据类型(一)

简介: spinal HDL - 03 - Spinal HDL数据类型 - 复合数据类型

写在前面


本文主要介绍了spinal HDL语言的复合数据类型,主要对Bundle、Vec进行介绍,同时对UFix/SFix进行了介绍。

Bundle


Bundle是复合类型,根据单个名称定义了一组命名的信号的(任何SpinalHDL基本类型)。Bundle可用于对数据结构、总线和接口进行建模。

声明


声明包的语法如下

case class myBundle extends Bundle {
  val bundleItem0 = AnyType
  val bundleItem1 = AnyType
  val bundleItemN = AnyType
}

例如,一个包含颜色的包可以定义为:

case class Color(channelWidth: Int) extends Bundle {
  val r, g, b = UInt(channelWidth bits)
}

运算操作


以下运算符可用于该Bundle类型:

Operator Description Return type
x === y 相等 Bool
x =/= y 不相等 Bool

类型转换


Operator Description Return
x.asBits 二进制转换为Bits Bits(w(x) bits)
val color1 = Color(8)
val myBits := color1.asBits

将 Bits 转换回 Bundle


.assignFromBits操作可以被看作是.asBits相反的操作。

Operator Description Return
x.assignFromBits(y) 转换Bits (y) 为 Bundle(x) Unit
x.assignFromBits(y, hi, lo) 转换 Bits (y) 为 Bundle(x)具有高/低边界 Unit

以下示例将名为 CommonDataBus 的 Bundle 保存到循环缓冲区(第 3 方内存)中,稍后读取位并将它们转换回 CommonDataBus 格式。

image.png

case class TestBundle () extends Component {
  val io = new Bundle {
    val we      = in     Bool()
    val addrWr  = in     UInt (7 bits)
    val dataIn  = slave  (CommonDataBus())
    val addrRd  = in     UInt (7 bits)
    val dataOut = master (CommonDataBus())
  }
  val mm = Ram3rdParty_1w_1rs (G_DATA_WIDTH = io.dataIn.getBitsWidth,
                               G_ADDR_WIDTH = io.addrWr.getBitsWidth,
                               G_VENDOR     = "Intel_Arria10_M20K")
  mm.io.clk_in    := clockDomain.readClockWire
  mm.io.clk_out   := clockDomain.readClockWire
  mm.io.we        := io.we
  mm.io.addr_wr   := io.addrWr.asBits
  mm.io.d         := io.dataIn.asBits
  mm.io.addr_rd   := io.addrRd.asBits
  io.dataOut.assignFromBits(mm.io.q)
}

IO方向


在组件的 IO 定义中定义 Bundle 时,需要指定其方向。

如果 bundle 的所有元素都在同一个方向,你可以使用 in(MyBundle()) 或 out(MyBundle())。

val io = new Bundle {
  val input  = in (Color(8))
  val output = out(Color(8))
}

master/slave


如果您的接口遵循主/从拓扑,则可以使用 IMasterSlave 特性。 然后你必须实现函数 def asMaster(): Unit 来从 master 的角度设置每个元素的方向。 然后你可以在 IO 定义中使用 master(MyBundle()) 和 slave(MyBundle()) 语法。

case class HandShake(payloadWidth: Int) extends Bundle with IMasterSlave {
  val valid   = Bool()
  val ready   = Bool()
  val payload = Bits(payloadWidth bits)
  // You have to implement this asMaster function.
  // This function should set the direction of each signals from an master point of view
  override def asMaster(): Unit = {
    out(valid, payload)
    in(ready)
  }
}
val io = new Bundle {
  val input  = slave(HandShake(8))
  val output = master(HandShake(8))
}

Vec


Vec 是一种复合类型,它在单个名称下定义一组索引信号(任何 SpinalHDL 基本类型)。

声明


Declaration Description
Vec(type: Data, size: Int) 创建一个能够容纳“数据”类型的“大小”元素的向量
Vec(x, y, …) 创建一个向量,其中索引指向提供的元素。此构造函数支持混合元素宽度。

示例

// Create a vector of 2 signed integers
val myVecOfSInt = Vec(SInt(8 bits), 2)
myVecOfSInt(0) := 2
myVecOfSInt(1) := myVecOfSInt(0) + 3
// Create a vector of 3 different type elements
val myVecOfMixedUInt = Vec(UInt(3 bits), UInt(5 bits), UInt(8 bits))
val x, y, z = UInt(8 bits)
val myVecOf_xyz_ref = Vec(x, y, z)
// Iterate on a vector
for(element <- myVecOf_xyz_ref) {
  element := 0   // Assign x, y, z with the value 0
}
// Map on vector
myVecOfMixedUInt.map(_ := 0) // Assign all elements with value 0
// Assign 3 to the first element of the vector
myVecOf_xyz_ref(1) := 3

运算操作


以下运算符可用于该Vec类型:

比较操作


Operator Description Return type
x === y 相等 Bool
x =/= y 不相等 Bool

示例

// Create a vector of 2 signed integers
val vec2 = Vec(SInt(8 bits), 2)
val vec1 = Vec(SInt(8 bits), 2)
myBool := vec2 === vec1  // Compare all elements

类型转换


Operator Description Return
x.asBits 二进制转化为Bits Bits(w(x) bits)

示例

// Create a vector of 2 signed integers
val vec1 = Vec(SInt(8 bits), 2)
myBits_16bits := vec1.asBits

其他


Operator Description Return
x.getBitsWidth 返回 Vec 的完整大小 Int

示例

// Create a vector of 2 signed integers
val vec1 = Vec(SInt(8 bits), 2)
println(vec1.getBitsWidth) // 16


目录
相关文章
|
4月前
|
XML 安全 网络架构
深度对比SOAP与HTTP协议:详细理解它们的工作原理和差异
在设计服务和系统交云策略时,考虑到上述差异是至关重要的。SOAP适合需要高安全性、可靠性和事务支持的企业级应用。而HTTP适合Web界面浏览、RESTful服务和需要快速响应的轻量级通信。根据具体需求和上下文,开发者可以选择合适的协议以实现最优的系统性能和用户体验。
476 0
|
设计模式 Java 调度
JUC线程池: ScheduledThreadPoolExecutor详解
`ScheduledThreadPoolExecutor`是Java标准库提供的一个强大的定时任务调度工具,它让并发编程中的任务调度变得简单而可靠。这个类的设计兼顾了灵活性与功能性,使其成为实现复杂定时任务逻辑的理想选择。不过,使用时仍需留意任务的执行时间以及系统的实际响应能力,以避免潜在的调度问题影响应用程序的行为。
217 1
|
10月前
|
SQL 人工智能 数据管理
跨云数据管理平台DMS:构建Data+AI的企业智能Data Mesh
跨云数据管理平台DMS助力企业构建智能Data Mesh,实现Data+AI的统一管理。DMS提供开放式元数据服务OneMeta、一站式智能开发平台和云原生AI数据平台,支持多模数据管理和高效的数据处理。结合PolarDB、AnalyticDB等核心引擎,DMS在多个垂直场景中展现出显著优势,如智能营销和向量搜索,提升业务效率和准确性。通过DataOps和MLOps的融合,DMS为企业提供了从数据到AI模型的全生命周期管理,推动数据驱动的业务创新。
700 0
|
数据库连接 API Apache
(二)Open Stack(M)----Keystone安装和配置(上)
(二)Open Stack(M)----Keystone安装和配置(上)
429 0
|
前端开发 JavaScript Android开发
【Uniapp 专栏】分析 Uniapp 与其他前端框架的异同
【5月更文挑战第16天】Uniapp是一个基于Vue.js的跨平台前端框架,能将代码编译成iOS、Android、H5等多个平台应用,简化跨平台开发。相比React和Angular,Uniapp更适合移动应用,减少平台适配工作。Vue.js的组件化和灵活性在Uniapp中得到延伸,增加了移动端特性。而Flutter性能优越,但学习成本高。开发者应根据项目需求和技术栈选择合适的框架。
495 4
【Uniapp 专栏】分析 Uniapp 与其他前端框架的异同
|
机器学习/深度学习 计算机视觉
YOLOv8改进 | 卷积模块 | 用坐标卷积CoordConv替换Conv
💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡
|
BI Linux 数据安全/隐私保护
忘了 iOS(iPad、IPhone) 设备上的「屏幕使用时间」密码怎么办?找回屏幕密码
忘了 iOS(iPad、IPhone) 设备上的「屏幕使用时间」密码怎么办?找回屏幕密码
498 0
|
存储 运维 算法
社交软件红包技术解密(十三):微信团队首次揭秘微信红包算法,为何你抢到的是0.01元
本文中,我们将介绍几种主流的IM红包分配算法,相信聪明的你一定能从中窥见微信红包技术实现的一些奥秘。
355 0
|
弹性计算 安全 Linux
阿里云Linux服务器安装宝塔面板详细教程(2023年)
阿里云Linux服务器安装宝塔面板详细教程(2023年)阿里云服务器网以CentOS操作系统为例,安装宝塔Linux面板,先远程连接到云服务器,然后执行宝塔面板安装命令,系统会自动安装宝塔面板,安装完成后会返回面板地址、账号和密码,然后在安全组开通宝塔面板端口号
1411 0