X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmain%2Fscala%2Fdevices%2Fuart%2FUART.scala;h=449f897819a57427a8a8e978569df70745bebe2b;hb=4fcf349adb9e66ea7d8cc5394de5d3e0a2340985;hp=68b47feff5ec2215166d6009326d1fe976c00fb8;hpb=7916ef5249c72a3a84c599d123760f4d716de58a;p=sifive-blocks.git diff --git a/src/main/scala/devices/uart/UART.scala b/src/main/scala/devices/uart/UART.scala index 68b47fe..449f897 100644 --- a/src/main/scala/devices/uart/UART.scala +++ b/src/main/scala/devices/uart/UART.scala @@ -2,18 +2,19 @@ package sifive.blocks.devices.uart import Chisel._ -import config._ -import regmapper._ -import uncore.tilelink2._ -import junctions._ -import util._ -import rocketchip.PeripheryBusConfig +import chisel3.experimental.MultiIOModule +import freechips.rocketchip.config.Parameters +import freechips.rocketchip.regmapper._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util._ + import sifive.blocks.util.{NonBlockingEnqueue, NonBlockingDequeue} -case class UARTConfig( +case class UARTParams( address: BigInt, dataBits: Int = 8, stopBits: Int = 2, + divisorInit: Int = 0, divisorBits: Int = 16, oversample: Int = 4, nSamples: Int = 3, @@ -21,23 +22,25 @@ case class UARTConfig( nRxEntries: Int = 8) trait HasUARTParameters { - val c: UARTConfig - val uartDataBits = c.dataBits - val uartStopBits = c.stopBits - val uartDivisorBits = c.divisorBits + def c: UARTParams + def uartDataBits = c.dataBits + def uartStopBits = c.stopBits + def uartDivisorInit = c.divisorInit + def uartDivisorBits = c.divisorBits - val uartOversample = c.oversample - val uartOversampleFactor = 1 << uartOversample - val uartNSamples = c.nSamples + def uartOversample = c.oversample + def uartOversampleFactor = 1 << uartOversample + def uartNSamples = c.nSamples - val uartNTxEntries = c.nTxEntries - val uartNRxEntries = c.nRxEntries + def uartNTxEntries = c.nTxEntries + def uartNRxEntries = c.nRxEntries + require(uartDivisorInit != 0) // should have been initialized during instantiation require(uartDivisorBits > uartOversample) require(uartOversampleFactor > uartNSamples) } -abstract class UARTModule(val c: UARTConfig)(implicit val p: Parameters) +abstract class UARTModule(val c: UARTParams)(implicit val p: Parameters) extends Module with HasUARTParameters class UARTPortIO extends Bundle { @@ -45,17 +48,11 @@ class UARTPortIO extends Bundle { val rxd = Bool(INPUT) } -trait MixUARTParameters { - val params: (UARTConfig, Parameters) - val c = params._1 - implicit val p = params._2 -} - -trait UARTTopBundle extends Bundle with MixUARTParameters with HasUARTParameters { +trait HasUARTTopBundleContents extends Bundle { val port = new UARTPortIO } -class UARTTx(c: UARTConfig)(implicit p: Parameters) extends UARTModule(c)(p) { +class UARTTx(c: UARTParams)(implicit p: Parameters) extends UARTModule(c)(p) { val io = new Bundle { val en = Bool(INPUT) val in = Decoupled(Bits(width = uartDataBits)).flip @@ -73,10 +70,14 @@ class UARTTx(c: UARTConfig)(implicit p: Parameters) extends UARTModule(c)(p) { val out = Reg(init = Bits(1, 1)) io.out := out + val plusarg_tx = PlusArg("uart_tx", 1, "Enable/disable the TX to speed up simulation").orR + val busy = (counter =/= UInt(0)) io.in.ready := io.en && !busy when (io.in.fire()) { - printf("%c", io.in.bits) + printf("UART TX (%x): %c\n", io.in.bits, io.in.bits) + } + when (io.in.fire() && plusarg_tx) { shifter := Cat(io.in.bits, Bits(0, 1)) counter := Mux1H((0 until uartStopBits).map(i => (io.nstop === UInt(i)) -> UInt(n + i + 1))) @@ -91,7 +92,7 @@ class UARTTx(c: UARTConfig)(implicit p: Parameters) extends UARTModule(c)(p) { } } -class UARTRx(c: UARTConfig)(implicit p: Parameters) extends UARTModule(c)(p) { +class UARTRx(c: UARTParams)(implicit p: Parameters) extends UARTModule(c)(p) { val io = new Bundle { val en = Bool(INPUT) val in = Bits(INPUT, 1) @@ -116,7 +117,7 @@ class UARTRx(c: UARTConfig)(implicit p: Parameters) extends UARTModule(c)(p) { } val sample = Reg(Bits(width = uartNSamples)) - val voter = new Majority(sample.toBools.toSet) + val voter = Majority(sample.toBools.toSet) when (pulse) { sample := Cat(sample, io.in) } @@ -164,7 +165,7 @@ class UARTRx(c: UARTConfig)(implicit p: Parameters) extends UARTModule(c)(p) { busy := Bool(true) when (expire) { sched := Bool(true) - when (voter.out) { + when (voter) { state := s_idle } .otherwise { state := s_data @@ -181,7 +182,7 @@ class UARTRx(c: UARTConfig)(implicit p: Parameters) extends UARTModule(c)(p) { state := s_idle valid := Bool(true) } .otherwise { - shifter := Cat(voter.out, shifter >> 1) + shifter := Cat(voter, shifter >> 1) sched := Bool(true) } } @@ -198,17 +199,19 @@ class UARTInterrupts extends Bundle { val txwm = Bool() } -trait UARTTopModule extends Module with MixUARTParameters with HasUARTParameters with HasRegMap { - val io: UARTTopBundle +trait HasUARTTopModuleContents extends MultiIOModule with HasUARTParameters with HasRegMap { + val io: HasUARTTopBundleContents + implicit val p: Parameters + def params: UARTParams + def c = params - val txm = Module(new UARTTx(c)) + val txm = Module(new UARTTx(params)) val txq = Module(new Queue(txm.io.in.bits, uartNTxEntries)) - val rxm = Module(new UARTRx(c)) + val rxm = Module(new UARTRx(params)) val rxq = Module(new Queue(rxm.io.out.bits, uartNRxEntries)) - val divinit = 542 // (62.5MHz / 115200) - val div = Reg(init = UInt(divinit, uartDivisorBits)) + val div = Reg(init = UInt(uartDivisorInit, uartDivisorBits)) private val stopCountBits = log2Up(uartStopBits) private val txCountBits = log2Floor(uartNTxEntries) + 1 @@ -262,14 +265,8 @@ trait UARTTopModule extends Module with MixUARTParameters with HasUARTParameters ) } -class Majority(in: Set[Bool]) { - private val n = (in.size >> 1) + 1 - private val clauses = in.subsets(n).map(_.reduce(_ && _)) - val out = clauses.reduce(_ || _) -} - -// Magic TL2 Incantation to create a TL2 Slave -class UART(c: UARTConfig)(implicit val p: Parameters) - extends TLRegisterRouter(c.address, interrupts = 1, beatBytes = p(PeripheryBusConfig).beatBytes)( - new TLRegBundle((c, p), _) with UARTTopBundle)( - new TLRegModule((c, p), _, _) with UARTTopModule) +// Magic TL2 Incantation to create a TL2 UART +class TLUART(w: Int, c: UARTParams)(implicit p: Parameters) + extends TLRegisterRouter(c.address, "serial", Seq("sifive,uart0"), interrupts = 1, beatBytes = w)( + new TLRegBundle(c, _) with HasUARTTopBundleContents)( + new TLRegModule(c, _, _) with HasUARTTopModuleContents)