risc-v中文社区

 找回密码
 立即注册
查看: 1002|回复: 0

[原创] uart(1)

[复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2021-9-9 08:21:28 | 显示全部楼层 |阅读模式

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[this.type]
}

/**
  * 没有缓冲区的只有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
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-5-3 04:03 , Processed in 0.027576 second(s), 29 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表