一个简单的例子
以下是来自 入门 仓库的简单硬件描述。
case class MyTopLevel() extends Component {
val io = new Bundle {
val cond0 = in port Bool()
val cond1 = in port Bool()
val flag = out port Bool()
val state = out port UInt(8 bits)
}
val counter = Reg(UInt(8 bits)) init 0
when(io.cond0) {
counter := counter + 1
}
io.state := counter
io.flag := (counter === 0) | io.cond1
}
它在本节中被分成多个块进行解释。
Component
首先,这里有一个 SpinalHDL Component
的结构。
组件是一段逻辑,可以根据需要多次实例化(粘贴),外部仅可通过输入和输出信号(io)对其访问。
case class MyTopLevel() extends Component {
val io = new Bundle {
// port definitions go here
}
// component logic goes here
}
MyTopLevel
是组件的名称。
在 SpinalHDL 中,组件使用 UpperCamelCase
(驼峰命名法)。
备注
请参阅 组件 了解更多信息。
端口
然后,定义端口。
val cond0 = in port Bool()
val cond1 = in port Bool()
val flag = out port Bool()
val state = out port UInt(8 bits)
方向:
cond0
和cond1
是输入端口flag
和state
是输出端口
类型:
cond0
、cond1
和flag
各为一个比特(3 条单独的线)state
是一个8位无符号整数(用一组8根线来表示一个无符号整数)
备注
此语法仅自 SpinalHDL 1.8 起可用,请参阅 输入/输出定义 了解旧语法和更多信息。
内部逻辑
最后,还有组件的逻辑:
val counter = Reg(UInt(8 bits)) init(0)
when(io.cond0) {
counter := counter + 1
}
io.state := counter
io.flag := (counter === 0) | io.cond1
counter
是一个包含 8 位无符号整数的寄存器,初始值为 0。更改寄存器状态的赋值仅可在下一个时钟采样后回读。
然后描述一个条件规则:当输入 cond0
(位于“io”线束中)被置1时,counter
加一,否则 counter
保持其值在最后一条规则中设置的值。但是,您可能会说,如果没有给出前置规则呢?对一个简单的**信号**来说,它将成为一个锁存器,并触发一个错误。但这里的 counter
是一个寄存器,所以它有一个默认值,没有其他规则,它就保持初始值。
这里创建了一个多路复用器: counter
寄存器的输入可以是其输出或其输出加一,这取决于 io.cond0
的值。
然后描述无条件规则(赋值):
输出端口
state
连接到寄存器counter
的输出。输出端口
flag
是输入信号cond1
与另一信号之间的or
门的输出,该信号在counter
信号等于0时为真,否则为假。
备注
有关更多信息,请参阅 语义 。