joe 发表于 2021-9-9 08:21:28

uart(1)


import chisel3._
import chisel3.util._
class UartIO extends DecoupledIO(UInt(8.W)) { //具有valid,ready,bits的Bundle
override def cloneType: UartIO.this.type = new UartIO().asInstanceOf
}

/**
* 没有缓冲区的只有valid/ready控制信号的TX
* @param frequency 频率
* @param baudRate 波特率
*/
class Tx(frequency:Int,baudRate:Int) extends Module {
val io = IO(new Bundle {
    val txd = Output(UInt(1.W)) //串口的txd线
    val deq = Flipped(new UartIO)
})
val BIT_CNT = ((frequency + baudRate / 2) / baudRate -1).asUInt() //按baudRate速率传一bit所需要的时钟周期数据,也就是波特率分频计数器值
val shiftReg = RegInit(0x7ff.U)//2047共11bit
val cntReg = RegInit(0.U(20.W))
val bitsReg = RegInit(0.U(4.W))
io.deq.ready := (cntReg === 0.U) && (bitsReg === 0.U)
io.txd := shiftReg(0) //取寄存器shiftReg的第0位
when(cntReg === 0.U) {
    cntReg := BIT_CNT
    when(bitsReg =/= 0.U) {
      val shift = shiftReg >> 1
      shiftReg := Cat(1.U,shift(9,0))
      bitsReg := bitsReg - 1.U
    } .otherwise {
      when(io.deq.valid) { //收到数据有效valid
      shiftReg := Cat(Cat(3.U,io.deq.bits),0.U) // two stop bits, data, one start bit
      bitsReg := 11.U
      } .otherwise {
      shiftReg := 0x7ff.U
      }
    }
}.otherwise {
    cntReg := cntReg - 1.U
}
}
//带有valid/ready的单个字节缓冲区
class Buffer extends Module {
val io = IO(new Bundle {
    val enq = Flipped(new UartIO)
    val deq = new UartIO
})
val empty :: full :: Nil = Enum(2)
val stateReg = RegInit(empty)
val dataReg = RegInit(0.U(8.W))
when(stateReg === empty){ //empty状态
    when(io.enq.valid) { //enq的上游master发来valid数据有效指示
      dataReg := io.enq.bits //用寄存器dataReg接收数据
      stateReg := full
    }
}.otherwise { //full状态
    when(io.deq.ready) { //deq的下游slave发出了ready信号表示已经准备好接收数据
      stateReg := empty //状态迁回到empty
    }
}
io.deq.bits := dataReg
io.enq.ready := stateReg === empty //空就给enq的上游master发出ready信号
io.deq.valid := stateReg === full //满就给deq的下游slave发出valid数据有效
}
class BufferedTx(frequency:Int,baudRate:Int) extends Module {
val io = IO(new Bundle {
    val txd = Output(UInt(1.W))
    val deq = Flipped(new UartIO)
})
val tx = Module(new Tx(frequency,baudRate))
val buf = Module(new Buffer)
buf.io.enq <> io.deq //父子模块级连 input连input,output连output 父输出值:=子输出值 子输入值:=父输入值
tx.io.deq <> buf.io.deq //
//在chisel中如果上下级模块连,左右两边都是output或input类型,则下面语法不正确:
//in.txt := tx.io.txd,特别是当书写到tx.io.之后IDE不会提示有txd
//只有用整体连接,比如下面:
io.txd <> tx.io.txd   //父子级连,output连output
}

页: [1]
查看完整版本: uart(1)