本文作为SpinalHDL学习笔记第四十一篇,介绍SpinalHDL中级示例。
目录:
2.串口
3.VGA
2.串口
UartCtrl
让我们编写 UartCtrl 来实例化 UartCtrlRx 和 UartCtrlTx 部分,生成时钟分频器逻辑,并将它们
相互连接。
class UartCtrl(g: UartCtrlGenerics=UartCtrlGenerics()) extends Component {
val io = new Bundle {
val config = in(UartCtrlConfig(g))
val write = slave(Stream(Bits(g.dataWidthMax bits)))
val read = master(Flow(Bits(g.dataWidthMax bits)))
val uart = master(Uart())
}
val tx = new UartCtrlTx(g)
val rx = new UartCtrlRx(g)
//Clock divider used by RX and TX
val clockDivider = new Area {
val counter = Reg(UInt(g.clockDividerWidth bits)) init 0
val tick = counter === 0
counter := counter - 1
when(tick) {
counter := io.config.clockDivider
}
}
tx.io.samplingTick := clockDivider.tick
rx.io.samplingTick := clockDivider.tick
tx.io.configFrame := io.config.frame
rx.io.configFrame := io.config.frame
tx.io.write << io.write
rx.io.read >> io.read
io.uart.txd <> tx.io.txd
io.uart.rxd <> rx.io.rxd
}
为了更简单地使用具有固定设置的 UART,我们引入了 UartCtrl 的伴生对象。这使我们能够以不同的参数集实例化 UartCtrl 组件,提供了额外的实例化方式。这里我们定义了 UartCtrlInitConfig ,用它保存那些无法在运行时配置的组件的设置。请注意,如果需要一个能在运行时进行配置的 UART,你仍然可以像所有其他组件一样(通过 val uart = new UartCtrl() )手动实例化 UartCtrl。
case class UartCtrlInitConfig(baudrate: Int = 0,
dataLength: Int = 1,
parity: UartParityType.E = null,
stop: UartStopType.E = null
) {
require(dataLength >= 1)
def initReg(reg : UartCtrlConfig): Unit = {
case class UartCtrlInitConfig(baudrate: Int = 0,
dataLength: Int = 1,
parity: UartParityType.E = null,
stop: UartStopType.E = null
) {
require(dataLength >= 1)
def initReg(reg : UartCtrlConfig): Unit = {
require(reg.isReg)
if(baudrate != 0) reg.clockDivider init((ClockDomain.current.f