VHDL 等效语法

实体和架构

在 SpinalHDL 中,VHDL 实体和架构都在 Component 内定义。

这是一个具有 3 个输入(abc)和一个输出(result)的组件。该组件还有一个 offset 构造参数(类似于 VHDL generic)。

case class MyComponent(offset: Int) extends Component {
  val io = new Bundle{
    val a, b, c = in UInt(8 bits)
    val result  = out UInt(8 bits)
  }
  io.result := a + b + c + offset
}

然后实例化该组件,您不需要绑定它:

case class TopLevel extends Component {
  ...
  val mySubComponent = MyComponent(offset = 5)

  ...

  mySubComponent.io.a := 1
  mySubComponent.io.b := 2
  mySubComponent.io.c := 3
  ??? := mySubComponent.io.result

  ...
}

数据类型

SpinalHDL 与 VHDL 相似的数据类型:

VHDL

SpinalHDL

std_logic

Bool

std_logic_vector

unsigned

UInt

signed

SInt

在 VHDL 中,要定义 8 位 unsigned ,您必须给出位范围 unsigned(7 downto 0)
而在 SpinalHDL 中,您只需提供位数 UInt(8 bits)

VHDL

SpinalHDL

records

Bundle

array

Vec

enum

SpinalEnum

这是 SpinalHDL Bundle 定义的示例。 channelWidth 是一个构造参数,类似于 VHDL 泛型,但用于数据结构:

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

例如,要实例化一个 Bundle,您需要这样写 val myColor = RGB(channelWidth=8)

信号

这是一个关于信号实例化的示例:

case class MyComponent(offset: Int) extends Component {
  val io = new Bundle {
    val a, b, c = UInt(8 bits)
    val result  = UInt(8 bits)
  }
  val ab = UInt(8 bits)
  ab := a + b

  val abc = ab + c            // You can define a signal directly with its value
  io.result := abc + offset
}

赋值

在 SpinalHDL 中,:= 赋值运算符相当于 VHDL 信号赋值 (<=):

val myUInt = UInt(8 bits)
myUInt := 6

在 VHDL 中,条件赋值通过使用 if/case 语句来完成:

val clear   = Bool()
val counter = Reg(UInt(8 bits))

when(clear) {
  counter := 0
}.elsewhen(counter === 76) {
  counter := 79
}.otherwise {
  counter(7) := ! counter(7)
}

switch(counter) {
  is(42) {
    counter := 65
  }
  default {
    counter := counter + 1
  }
}

字面量(Literals)

与 VHDL 中的字面量略有不同:

val myBool = Bool()
myBool := False
myBool := True
myBool := Bool(4 > 7)

val myUInt = UInt(8 bits)
myUInt := "0001_1100"
myUInt := "xEE"
myUInt := 42
myUInt := U(54,8 bits)
myUInt := ((3 downto 0) -> myBool, default -> true)
when(myUInt === U(myUInt.range -> true)) {
  myUInt(3) := False
}

寄存器

在 SpinalHDL 中,寄存器是显式指定的,而在 VHDL 中寄存器是推断的。以下是 SpinalHDL 寄存器的示例:

val counter = Reg(UInt(8 bits))  init(0)
counter := counter + 1   // Count up each cycle

// init(0) means that the register should be initialized to zero when a reset occurs

过程块

过程块是一种仿真功能,对于设计 RTL 来说是不必要的。这就是为什么 SpinalHDL 不包含任何类似于过程块的功能,并且您可以在您想要的位置分配您想要的内容。

val cond = Bool()
val myCombinatorial = Bool()
val myRegister = UInt(8 bits)

myCombinatorial := False
when(cond) {
  myCombinatorial := True
  myRegister = myRegister + 1
}