Merge remote-tracking branch 'origin/master' into typed_pad_ctrl
authorMegan Wachs <megan@sifive.com>
Mon, 24 Jul 2017 16:17:53 +0000 (09:17 -0700)
committerMegan Wachs <megan@sifive.com>
Mon, 24 Jul 2017 17:11:52 +0000 (10:11 -0700)
13 files changed:
src/main/scala/devices/gpio/GPIO.scala
src/main/scala/devices/gpio/GPIOPeriphery.scala
src/main/scala/devices/gpio/GPIOPins.scala [new file with mode: 0644]
src/main/scala/devices/gpio/JTAG.scala
src/main/scala/devices/i2c/I2C.scala
src/main/scala/devices/i2c/I2CPeriphery.scala
src/main/scala/devices/i2c/I2CPins.scala
src/main/scala/devices/mockaon/MockAONWrapper.scala
src/main/scala/devices/pinctrl/PinCtrl.scala [new file with mode: 0644]
src/main/scala/devices/pwm/PWMPeriphery.scala
src/main/scala/devices/spi/SPIPeriphery.scala
src/main/scala/devices/spi/SPIPins.scala
src/main/scala/devices/uart/UARTPeriphery.scala

index ae468cec2f909bb8511ea786092ef9ce7c484c7b..e7a48299d132df91965224608386f61812b810f4 100644 (file)
@@ -2,6 +2,7 @@
 package sifive.blocks.devices.gpio
 
 import Chisel._
+import sifive.blocks.devices.pinctrl.{PinCtrl, Pin, BasePin, EnhancedPin, EnhancedPinCtrl}
 import freechips.rocketchip.config.Parameters
 import freechips.rocketchip.regmapper._
 import freechips.rocketchip.tilelink._
@@ -9,28 +10,18 @@ import freechips.rocketchip.util.{AsyncResetRegVec, GenericParameterizedBundle}
 
 case class GPIOParams(address: BigInt, width: Int, includeIOF: Boolean = false)
 
-// YAGNI: Make the PUE, DS, and
-// these also optionally HW controllable.
-// This is the base class of things you "always"
-// want to control from a HW block.
-class GPIOCtrl extends Bundle {
-  val oval = Bool()
-  val oe   = Bool()
-  val ie   = Bool()
-}
-
-// This is the actual IOF interface.
+// This is the actual IOF interface.pa
 // Add a valid bit to indicate whether
 // there is something actually connected
 // to this.
-class GPIOPinIOFCtrl extends GPIOCtrl {
+class IOFCtrl extends PinCtrl {
   val valid = Bool()
 }
 
 // By default,
-object GPIOPinIOFCtrl {
-  def apply(): GPIOPinIOFCtrl = {
-    val iof = Wire(new GPIOPinIOFCtrl())
+object IOFCtrl {
+  def apply(): IOFCtrl = {
+    val iof = Wire(new IOFCtrl())
     iof.valid := Bool(false)
     iof.oval  := Bool(false)
     iof.oe    := Bool(false)
@@ -39,53 +30,42 @@ object GPIOPinIOFCtrl {
   }
 }
 
-// This is the control for a physical
-// Pad.
-
-class GPIOPinCtrl extends GPIOCtrl {
-  val pue  = Bool() // Pull-up Enable
-  val ds   = Bool() // Drive Strength
-}
-
-object GPIOPinCtrl {
-  def apply(): GPIOPinCtrl = {
-    val pin = Wire(new GPIOPinCtrl())
-    pin.oval := Bool(false)
-    pin.oe   := Bool(false)
-    pin.pue  := Bool(false)
-    pin.ds   := Bool(false)
-    pin.ie   := Bool(false)
-    pin
-  }
-}
-
 // Package up the inputs and outputs
 // for the IOF
-class GPIOPinIOF extends Bundle {
-  val i = new Bundle {
-    val ival = Bool(INPUT)
+class IOFPin extends Pin {
+  val o  = new IOFCtrl().asOutput
+
+  def default(): Unit = {
+    this.o.oval  := Bool(false)
+    this.o.oe    := Bool(false)
+    this.o.ie    := Bool(false)
+    this.o.valid := Bool(false)
+  }
+
+  def inputPin(pue: Bool = Bool(false) /*ignored*/): Bool = {
+    this.o.oval := Bool(false)
+    this.o.oe   := Bool(false)
+    this.o.ie   := Bool(true)
+    this.i.ival
+  }
+  def outputPin(signal: Bool,
+    pue: Bool = Bool(false), /*ignored*/
+    ds: Bool = Bool(false), /*ignored*/
+    ie: Bool = Bool(false)
+  ): Unit = {
+    this.o.oval := signal
+    this.o.oe   := Bool(true)
+    this.o.ie   := ie
   }
-  val o = new GPIOPinIOFCtrl().asOutput
 }
 
 // Connect both the i and o side of the pin,
 // and drive the valid signal for the IOF.
-object GPIOPinToIOF {
-
-  def apply (pin: GPIOPin, iof: GPIOPinIOF): Unit = {
+object BasePinToIOF {
+  def apply(pin: BasePin, iof: IOFPin): Unit = {
     iof <> pin
     iof.o.valid := Bool(true)
   }
-
-}
-
-// Package up the inputs and outputs
-// for the Pin
-class GPIOPin extends Bundle {
-  val i = new Bundle {
-    val ival = Bool(INPUT)
-  }
-  val o = new GPIOPinCtrl().asOutput
 }
 
 // This is sort of weird because
@@ -94,9 +74,9 @@ class GPIOPin extends Bundle {
 // outside of RocketChipTop.
 
 class GPIOPortIO(c: GPIOParams) extends GenericParameterizedBundle(c) {
-  val pins = Vec(c.width, new GPIOPin)
-  val iof_0 = if (c.includeIOF) Some(Vec(c.width, new GPIOPinIOF).flip) else None
-  val iof_1 = if (c.includeIOF) Some(Vec(c.width, new GPIOPinIOF).flip) else None
+  val pins = Vec(c.width, new EnhancedPin())
+  val iof_0 = if (c.includeIOF) Some(Vec(c.width, new IOFPin).flip) else None
+  val iof_1 = if (c.includeIOF) Some(Vec(c.width, new IOFPin).flip) else None
 }
 
 // It would be better if the IOF were here and
@@ -183,15 +163,14 @@ trait HasGPIOModuleContents extends Module with HasRegMap {
   // Actual Pinmux
   // -------------------------------------------------
 
-  val swPinCtrl = Wire(Vec(c.width, new GPIOPinCtrl()))
+  val swPinCtrl = Wire(Vec(c.width, new EnhancedPinCtrl()))
 
   // This strips off the valid.
-  val iof0Ctrl = Wire(Vec(c.width, new GPIOCtrl()))
-  val iof1Ctrl = Wire(Vec(c.width, new GPIOCtrl()))
-
-  val iofCtrl = Wire(Vec(c.width, new GPIOCtrl()))
-  val iofPlusSwPinCtrl = Wire(Vec(c.width, new GPIOPinCtrl()))
+  val iof0Ctrl = Wire(Vec(c.width, new EnhancedPinCtrl()))
+  val iof1Ctrl = Wire(Vec(c.width, new EnhancedPinCtrl()))
 
+  val iofCtrl = Wire(Vec(c.width, new EnhancedPinCtrl()))
+  val iofPlusSwPinCtrl = Wire(Vec(c.width, new EnhancedPinCtrl()))
 
   for (pin <- 0 until c.width) {
 
@@ -202,7 +181,7 @@ trait HasGPIOModuleContents extends Module with HasRegMap {
     swPinCtrl(pin).ds     := dsReg(pin)
     swPinCtrl(pin).ie     := ieReg.io.q(pin)
 
-    val pre_xor = Wire(new GPIOPinCtrl())
+    val pre_xor = Wire(new EnhancedPinCtrl())
 
     if (c.includeIOF) {
       // Allow SW Override for invalid inputs.
@@ -246,57 +225,6 @@ trait HasGPIOModuleContents extends Module with HasRegMap {
   }
 }
 
-object GPIOOutputPinCtrl {
-
-  def apply( pin: GPIOPin, signal: Bool,
-    pue: Bool = Bool(false),
-    ds:  Bool = Bool(false),
-    ie:  Bool = Bool(false)
-  ): Unit = {
-    pin.o.oval := signal
-    pin.o.oe   := Bool(true)
-    pin.o.pue  := pue
-    pin.o.ds   := ds
-    pin.o.ie   := ie
-  }
-
-  def apply(pins: Vec[GPIOPin], signals: Bits,
-    pue: Bool, ds:  Bool, ie:  Bool
-  ): Unit = {
-    for ((signal, pin) <- (signals.toBools zip pins)) {
-      apply(pin, signal, pue, ds, ie)
-    }
-  }
-
-  def apply(pins: Vec[GPIOPin], signals: Bits): Unit = apply(pins, signals,
-    Bool(false), Bool(false), Bool(false))
-
-}
-
-object GPIOInputPinCtrl {
-
-  def apply (pin: GPIOPin, pue: Bool = Bool(false)): Bool = {
-    pin.o.oval := Bool(false)
-    pin.o.oe   := Bool(false)
-    pin.o.pue  := pue
-    pin.o.ds   := Bool(false)
-    pin.o.ie   := Bool(true)
-
-    pin.i.ival
-  }
-
-  def apply (pins: Vec[GPIOPin], pue: Bool): Vec[Bool] = {
-    val signals = Wire(Vec.fill(pins.size)(Bool(false)))
-    for ((signal, pin) <- (signals zip pins)) {
-      signal := GPIOInputPinCtrl(pin, pue)
-    }
-    signals
-  }
-
-  def apply (pins: Vec[GPIOPin]): Vec[Bool] = apply(pins, Bool(false))
-
-}
-
 // Magic TL2 Incantation to create a TL2 Slave
 class TLGPIO(w: Int, c: GPIOParams)(implicit p: Parameters)
   extends TLRegisterRouter(c.address, "gpio", Seq("sifive,gpio0"), interrupts = c.width, beatBytes = w)(
index 109ffb82991df1dcea50c16d013624b5f81373fb..d3b9cf5f17a49ba0c67aa54cdf27832f2267d158 100644 (file)
@@ -11,7 +11,7 @@ case object PeripheryGPIOKey extends Field[Seq[GPIOParams]]
 
 trait HasPeripheryGPIO extends HasPeripheryBus with HasInterruptBus {
   val gpioParams = p(PeripheryGPIOKey)
-  val gpio = gpioParams map { params =>
+  val gpios = gpioParams map { params =>
     val gpio = LazyModule(new TLGPIO(pbus.beatBytes, params))
     gpio.node := pbus.toVariableWidthSlaves
     ibus.fromSync := gpio.intnode
@@ -27,7 +27,7 @@ trait HasPeripheryGPIOModuleImp extends LazyMultiIOModuleImp with HasPeripheryGP
   val outer: HasPeripheryGPIO
   val gpio = IO(HeterogeneousBag(outer.gpioParams.map(new GPIOPortIO(_))))
 
-  (gpio zip outer.gpio) foreach { case (io, device) =>
+  (gpio zip outer.gpios) foreach { case (io, device) =>
     io <> device.module.io.port
   }
 }
diff --git a/src/main/scala/devices/gpio/GPIOPins.scala b/src/main/scala/devices/gpio/GPIOPins.scala
new file mode 100644 (file)
index 0000000..11723c4
--- /dev/null
@@ -0,0 +1,27 @@
+// See LICENSE for license details.
+package sifive.blocks.devices.gpio
+
+import Chisel._
+import sifive.blocks.devices.pinctrl.{Pin}
+
+// While this is a bit pendantic, it keeps the GPIO
+// device more similar to the other devices. It's not 'special'
+// even though it looks like something that more directly talks to
+// a pin. It also makes it possible to change the exact
+// type of pad this connects to.
+class GPIOPins[T <: Pin] (pingen: ()=> T,  c: GPIOParams) extends Bundle {
+
+  val pins = Vec(c.width, pingen())
+
+  override def cloneType: this.type =
+    this.getClass.getConstructors.head.newInstance(pingen, c).asInstanceOf[this.type]
+
+  def fromGPIOPort(port: GPIOPortIO){
+
+    // This will just match up the components of the Bundle that
+    // exist in both.
+    (pins zip port.pins) foreach {case (pin, port) =>
+      pin <> port
+    }
+  }
+}
index 63d9cc23d22ee8040f1ff117ce1b4332a6c6c439..e10f19b5fd8871cad71796c1619a1acc6b090578 100644 (file)
@@ -12,30 +12,23 @@ import Chisel._
 
 import freechips.rocketchip.config._
 import freechips.rocketchip.jtag.{JTAGIO}
+import sifive.blocks.devices.pinctrl.{Pin, PinCtrl}
 
-class JTAGPinsIO(hasTRSTn: Boolean = true) extends Bundle {
+class JTAGPins[T <: Pin](pingen: () => T, hasTRSTn: Boolean = true) extends Bundle {
 
-  val TCK    = new GPIOPin()
-  val TMS    = new GPIOPin()
-  val TDI    = new GPIOPin()
-  val TDO    = new GPIOPin()
-  val TRSTn  = if (hasTRSTn) Option(new GPIOPin()) else None
+  val TCK         = pingen()
+  val TMS         = pingen()
+  val TDI         = pingen()
+  val TDO        = pingen()
+  val TRSTn = if (hasTRSTn) Option(pingen()) else None
 
-}
-
-class JTAGGPIOPort(hasTRSTn: Boolean = true)(implicit p: Parameters) extends Module {
+  def fromJTAGPort(jtag: JTAGIO): Unit = {
+    jtag.TCK  := TCK.inputPin (pue = Bool(true)).asClock
+    jtag.TMS  := TMS.inputPin (pue = Bool(true))
+    jtag.TDI  := TDI.inputPin(pue = Bool(true))
+    jtag.TRSTn.foreach{t => t := TRSTn.get.inputPin(pue = Bool(true))}
 
-  val io = new Bundle {
-    // TODO: make this not hard-coded true.
-    val jtag = new JTAGIO(hasTRSTn)
-    val pins = new JTAGPinsIO(hasTRSTn)
+    TDO.outputPin(jtag.TDO.data)
+    TDO.o.oe := jtag.TDO.driven
   }
-
-  io.jtag.TCK  := GPIOInputPinCtrl(io.pins.TCK, pue = Bool(true)).asClock
-  io.jtag.TMS  := GPIOInputPinCtrl(io.pins.TMS, pue = Bool(true))
-  io.jtag.TDI  := GPIOInputPinCtrl(io.pins.TDI, pue = Bool(true))
-  io.jtag.TRSTn.foreach{t => t := GPIOInputPinCtrl(io.pins.TRSTn.get, pue = Bool(true))}
-
-  GPIOOutputPinCtrl(io.pins.TDO, io.jtag.TDO.data)
-  io.pins.TDO.o.oe := io.jtag.TDO.driven
 }
index 58ad5482688f8f193e8f047ba4cd1d0202675444..147a739b6041c01f361eb208bd6ce37345fedf07 100644 (file)
@@ -46,7 +46,6 @@ import freechips.rocketchip.config._
 import freechips.rocketchip.regmapper._
 import freechips.rocketchip.tilelink._
 import freechips.rocketchip.util.{AsyncResetRegVec, Majority}
-import sifive.blocks.devices.gpio.{GPIOPinCtrl}
 
 case class I2CParams(address: BigInt)
 
index 1cc927f46adf7b5243c76d31c23c0f703e4ac295..f4394073eceb3784414b66a756dea9c184f2f7a0 100644 (file)
@@ -19,20 +19,14 @@ trait HasPeripheryI2C extends HasPeripheryBus {
 }
 
 trait HasPeripheryI2CBundle {
-  val i2cs: Vec[I2CPort]
-
-  def I2CtoGPIOPins(syncStages: Int = 0): Seq[I2CPinsIO] = i2cs.map { i =>
-    val pins = Module(new I2CGPIOPort(syncStages))
-    pins.io.i2c <> i
-    pins.io.pins
-  }
+  val i2c: Vec[I2CPort]
 }
 
 trait HasPeripheryI2CModuleImp extends LazyMultiIOModuleImp with HasPeripheryI2CBundle {
   val outer: HasPeripheryI2C
-  val i2cs = IO(Vec(outer.i2cParams.size, new I2CPort))
+  val i2c = IO(Vec(outer.i2cParams.size, new I2CPort))
 
-  (i2cs zip outer.i2c).foreach { case (io, device) =>
+  (i2c zip outer.i2c).foreach { case (io, device) =>
     io <> device.module.io.port
   }
 }
index d7017bca46f249010bf648bd2613baa94aa0472c..8e17765b908a48511db73f27acd0b1d953b5dbad 100644 (file)
@@ -2,26 +2,28 @@
 package sifive.blocks.devices.i2c
 
 import Chisel._
-import sifive.blocks.devices.gpio.{GPIOPin, GPIOOutputPinCtrl}
+import chisel3.experimental.{withClockAndReset}
+import sifive.blocks.devices.pinctrl.{Pin, PinCtrl}
 import sifive.blocks.util.ShiftRegisterInit
 
 
-class I2CPinsIO extends Bundle {
-  val scl = new GPIOPin
-  val sda = new GPIOPin
-}
+class I2CPins[T <: Pin](pingen: () => T) extends Bundle {
 
-class I2CGPIOPort(syncStages: Int = 0) extends Module {
-  val io = new Bundle{
-    val i2c = new I2CPort().flip()
-    val pins = new I2CPinsIO
-  }
+  val scl: T = pingen()
+  val sda: T = pingen()
 
-  GPIOOutputPinCtrl(io.pins.scl, io.i2c.scl.out, pue=true.B, ie = true.B)
-  io.pins.scl.o.oe := io.i2c.scl.oe
-  io.i2c.scl.in := ShiftRegisterInit(io.pins.scl.i.ival, syncStages, Bool(true))
+  override def cloneType: this.type =
+    this.getClass.getConstructors.head.newInstance(pingen).asInstanceOf[this.type]
 
-  GPIOOutputPinCtrl(io.pins.sda, io.i2c.sda.out, pue=true.B, ie = true.B)
-  io.pins.sda.o.oe := io.i2c.sda.oe
-  io.i2c.sda.in := ShiftRegisterInit(io.pins.sda.i.ival, syncStages, Bool(true))
+  def fromI2CPort(i2c: I2CPort, clock: Clock, reset: Bool, syncStages: Int = 0) = {
+    withClockAndReset(clock, reset) {
+      scl.outputPin(i2c.scl.out, pue=true.B, ie = true.B)
+      scl.o.oe := i2c.scl.oe
+      i2c.scl.in := ShiftRegisterInit(scl.i.ival, syncStages, Bool(true))
+
+      sda.outputPin(i2c.sda.out, pue=true.B, ie = true.B)
+      sda.o.oe := i2c.sda.oe
+      i2c.sda.in := ShiftRegisterInit(sda.i.ival, syncStages, Bool(true))
+    }
+  }
 }
index 9062ff72bd38d957ce80a6644838c1ec1f79091a..a5fdedabe78df4fef181871ef6683bd2bb91d3e7 100644 (file)
@@ -6,25 +6,25 @@ import freechips.rocketchip.config.Parameters
 import freechips.rocketchip.diplomacy._
 import freechips.rocketchip.tilelink._
 import freechips.rocketchip.util._
-import sifive.blocks.devices.gpio.{GPIOPin, GPIOOutputPinCtrl, GPIOInputPinCtrl}
+import sifive.blocks.devices.pinctrl.{EnhancedPin}
 import sifive.blocks.util.{DeglitchShiftRegister, ResetCatchAndSync}
 
 /* The wrapper handles the Clock and Reset Generation for The AON block itself,
  and instantiates real pad controls (aka pull-ups)*/
 
 class MockAONWrapperPMUIO extends Bundle {
-  val dwakeup_n = new GPIOPin()
-  val vddpaden = new GPIOPin()
+  val dwakeup_n = new EnhancedPin()
+  val vddpaden = new  EnhancedPin()
 }
 
-class MockAONWrapperPadsIO extends Bundle {
-  val erst_n = new GPIOPin()
-  val lfextclk = new GPIOPin()
+class MockAONWrapperPins extends Bundle {
+  val erst_n   = new EnhancedPin()
+  val lfextclk = new EnhancedPin()
   val pmu = new MockAONWrapperPMUIO()
 }
 
 class MockAONWrapperBundle extends Bundle {
-  val pads = new MockAONWrapperPadsIO()
+  val pads = new MockAONWrapperPins()
   val rsts = new MockAONMOffRstIO()
 }
 
@@ -68,7 +68,7 @@ class MockAONWrapper(w: Int, c: MockAONParams)(implicit p: Parameters) extends L
     // -----------------------------------------------
 
     // ERST
-    val erst = ~ GPIOInputPinCtrl(pads.erst_n, pue = Bool(true))
+    val erst = ~pads.erst_n.inputPin(pue = Bool(true))
     aon_io.resetCauses.erst := erst
     aon_io.resetCauses.wdogrst := aon_io.wdog_rst
 
@@ -94,7 +94,7 @@ class MockAONWrapper(w: Int, c: MockAONParams)(implicit p: Parameters) extends L
     // Note that the actual mux lives inside AON itself.
     // Therefore, the lfclk which comes out of AON is the
     // true clock that AON and AONWrapper are running off of.
-    val lfextclk = GPIOInputPinCtrl(pads.lfextclk, pue=Bool(true))
+    val lfextclk = pads.lfextclk.inputPin(pue=Bool(true))
     aon_io.lfextclk := lfextclk.asClock
 
     // Drive AON's clock and Reset
@@ -136,14 +136,14 @@ class MockAONWrapper(w: Int, c: MockAONParams)(implicit p: Parameters) extends L
     // PMU <--> pads Interface
     //--------------------------------------------------
 
-    val dwakeup_n_async = GPIOInputPinCtrl(pads.pmu.dwakeup_n, pue=Bool(true))
+    val dwakeup_n_async = pads.pmu.dwakeup_n.inputPin(pue=Bool(true))
 
     val dwakeup_deglitch = Module (new DeglitchShiftRegister(3))
     dwakeup_deglitch.clock := lfclk
     dwakeup_deglitch.io.d := ~dwakeup_n_async
     aon.module.io.pmu.dwakeup := dwakeup_deglitch.io.q
 
-    GPIOOutputPinCtrl(pads.pmu.vddpaden, aon.module.io.pmu.vddpaden)
+    pads.pmu.vddpaden.outputPin(aon.module.io.pmu.vddpaden)
 
     //--------------------------------------------------
     // Connect signals to MOFF
diff --git a/src/main/scala/devices/pinctrl/PinCtrl.scala b/src/main/scala/devices/pinctrl/PinCtrl.scala
new file mode 100644 (file)
index 0000000..f487d39
--- /dev/null
@@ -0,0 +1,103 @@
+//See LICENSE for license details
+
+package sifive.blocks.devices.pinctrl
+
+import Chisel._
+
+// This is the base class of things you "always"
+// want to control from a HW block.
+class PinCtrl extends Bundle {
+  val oval = Bool()
+  val oe   = Bool()
+  val ie   = Bool()
+}
+
+// Package up the inputs and outputs
+// for the Pin
+abstract class Pin extends Bundle {
+  val i = new Bundle {
+    val ival = Bool(INPUT)
+  }
+  val o: PinCtrl
+
+  // Must be defined by the subclasses
+  def default(): Unit
+  def inputPin(pue: Bool = Bool(false)): Bool
+  def outputPin(signal: Bool,
+    pue: Bool = Bool(false),
+    ds: Bool = Bool(false),
+    ie: Bool = Bool(false)
+  ): Unit
+  
+}
+
+
+////////////////////////////////////////////////////////////////////////////////////
+
+class BasePin extends Pin() {
+  val o = new PinCtrl().asOutput
+
+  def default(): Unit = {
+    this.o.oval := Bool(false)
+    this.o.oe   := Bool(false)
+    this.o.ie   := Bool(false)
+  }
+
+  def inputPin(pue: Bool = Bool(false) /*ignored*/): Bool = {
+    this.o.oval := Bool(false)
+    this.o.oe   := Bool(false)
+    this.o.ie   := Bool(true)
+    this.i.ival
+  }
+
+  def outputPin(signal: Bool,
+    pue: Bool = Bool(false), /*ignored*/
+    ds: Bool = Bool(false), /*ignored*/
+    ie: Bool = Bool(false)
+  ): Unit = {
+    this.o.oval := signal
+    this.o.oe   := Bool(true)
+    this.o.ie   := ie
+  }
+}
+
+/////////////////////////////////////////////////////////////////////////
+class EnhancedPinCtrl extends PinCtrl {
+  val pue = Bool()
+  val ds = Bool()
+}
+
+class EnhancedPin extends Pin() {
+
+  val o = new EnhancedPinCtrl().asOutput
+
+  def default(): Unit = {
+    this.o.oval := Bool(false)
+    this.o.oe   := Bool(false)
+    this.o.ie   := Bool(false)
+    this.o.ds   := Bool(false)
+    this.o.pue  := Bool(false)
+  }
+
+  def inputPin(pue: Bool = Bool(false)): Bool = {
+    this.o.oval := Bool(false)
+    this.o.oe   := Bool(false)
+    this.o.pue  := pue
+    this.o.ds   := Bool(false)
+    this.o.ie   := Bool(true)
+
+    this.i.ival
+  }
+
+  def outputPin(signal: Bool,
+    pue: Bool = Bool(false),
+    ds: Bool = Bool(false),
+    ie: Bool = Bool(false)
+  ): Unit = {
+    this.o.oval := signal
+    this.o.oe   := Bool(true)
+    this.o.pue  := pue
+    this.o.ds   := ds
+    this.o.ie   := ie
+  }
+}
index 5ff9ccfe8f5b23dc17c79886c6afd2722a493070..ff5b6bbe1a20aff22e859e3a27c5b65f1ad0a430 100644 (file)
@@ -6,24 +6,25 @@ import freechips.rocketchip.config.Field
 import freechips.rocketchip.coreplex.{HasPeripheryBus, HasInterruptBus}
 import freechips.rocketchip.diplomacy.{LazyModule, LazyMultiIOModuleImp}
 import freechips.rocketchip.util.HeterogeneousBag
-import sifive.blocks.devices.gpio._
+import sifive.blocks.devices.pinctrl.{Pin}
 
 class PWMPortIO(val c: PWMParams) extends Bundle {
   val port = Vec(c.ncmp, Bool()).asOutput
   override def cloneType: this.type = new PWMPortIO(c).asInstanceOf[this.type]
 }
 
-class PWMPinsIO(val c: PWMParams) extends Bundle {
-  val pwm = Vec(c.ncmp, new GPIOPin)
-}
+class PWMPins[T <: Pin] (pingen: ()=> T, val c: PWMParams) extends Bundle {
 
-class PWMGPIOPort(val c: PWMParams) extends Module {
-  val io = new Bundle {
-    val pwm = new PWMPortIO(c).flip()
-    val pins = new PWMPinsIO(c)
-  }
+  val pwm: Vec[T] = Vec(c.ncmp, pingen())
+
+  override def cloneType: this.type =
+    this.getClass.getConstructors.head.newInstance(pingen, c).asInstanceOf[this.type]
 
-  GPIOOutputPinCtrl(io.pins.pwm, io.pwm.port.asUInt)
+  def fromPWMPort(port: PWMPortIO) {
+    (pwm zip port.port)  foreach {case (pin, port) =>
+      pin.outputPin(port)
+    }
+  }
 }
 
 case object PeripheryPWMKey extends Field[Seq[PWMParams]]
@@ -39,20 +40,15 @@ trait HasPeripheryPWM extends HasPeripheryBus with HasInterruptBus {
 }
 
 trait HasPeripheryPWMBundle {
-  val pwms: HeterogeneousBag[PWMPortIO]
+  val pwm: HeterogeneousBag[PWMPortIO]
 
-  def PWMtoGPIOPins(dummy: Int = 1): Seq[PWMPinsIO] = pwms.map { p =>
-    val pins = Module(new PWMGPIOPort(p.c))
-    pins.io.pwm <> p
-    pins.io.pins
-  }
 }
 
 trait HasPeripheryPWMModuleImp extends LazyMultiIOModuleImp with HasPeripheryPWMBundle {
   val outer: HasPeripheryPWM
-  val pwms = IO(HeterogeneousBag(outer.pwmParams.map(new PWMPortIO(_))))
+  val pwm = IO(HeterogeneousBag(outer.pwmParams.map(new PWMPortIO(_))))
 
-  (pwms zip outer.pwms) foreach { case (io, device) =>
+  (pwm zip outer.pwms) foreach { case (io, device) =>
     io.port := device.module.io.gpio
   }
 }
index 37151bd06cda84a0e8a5f6b9178824418c024e64..80978946103eec972449e71d82227beceb2b3e86 100644 (file)
@@ -21,20 +21,15 @@ trait HasPeripherySPI extends HasPeripheryBus with HasInterruptBus {
 }
 
 trait HasPeripherySPIBundle {
-  val spis: HeterogeneousBag[SPIPortIO]
+  val spi: HeterogeneousBag[SPIPortIO]
 
-  def SPItoGPIOPins(syncStages: Int = 0): Seq[SPIPinsIO] = spis.map { s =>
-    val pins = Module(new SPIGPIOPort(s.c, syncStages))
-    pins.io.spi <> s
-    pins.io.pins
-  }
 }
 
 trait HasPeripherySPIModuleImp extends LazyMultiIOModuleImp with HasPeripherySPIBundle {
   val outer: HasPeripherySPI
-  val spis = IO(HeterogeneousBag(outer.spiParams.map(new SPIPortIO(_))))
+  val spi = IO(HeterogeneousBag(outer.spiParams.map(new SPIPortIO(_))))
 
-  (spis zip outer.spis).foreach { case (io, device) =>
+  (spi zip outer.spis).foreach { case (io, device) =>
     io <> device.module.io.port
   }
 }
@@ -43,7 +38,7 @@ case object PeripherySPIFlashKey extends Field[Seq[SPIFlashParams]]
 
 trait HasPeripherySPIFlash extends HasPeripheryBus with HasInterruptBus {
   val spiFlashParams = p(PeripherySPIFlashKey)  
-  val qspi = spiFlashParams map { params =>
+  val qspis = spiFlashParams map { params =>
     val qspi = LazyModule(new TLSPIFlash(pbus.beatBytes, params))
     qspi.rnode := pbus.toVariableWidthSlaves
     qspi.fnode := TLFragmenter(1, pbus.blockBytes)(pbus.toFixedWidthSlaves)
@@ -55,21 +50,13 @@ trait HasPeripherySPIFlash extends HasPeripheryBus with HasInterruptBus {
 trait HasPeripherySPIFlashBundle {
   val qspi: HeterogeneousBag[SPIPortIO]
 
-  // It is important for SPIFlash that the syncStages is agreed upon, because
-  // internally it needs to realign the input data to the output SCK.
-  // Therefore, we rely on the syncStages parameter.
-  def SPIFlashtoGPIOPins(syncStages: Int = 0): Seq[SPIPinsIO] = qspi.map { s =>
-    val pins = Module(new SPIGPIOPort(s.c, syncStages))
-    pins.io.spi <> s
-    pins.io.pins
-  }
 }
 
 trait HasPeripherySPIFlashModuleImp extends LazyMultiIOModuleImp with HasPeripherySPIFlashBundle {
   val outer: HasPeripherySPIFlash
   val qspi = IO(HeterogeneousBag(outer.spiFlashParams.map(new SPIPortIO(_))))
 
-  (qspi zip outer.qspi) foreach { case (io, device) => 
+  (qspi zip outer.qspis) foreach { case (io, device) => 
     io <> device.module.io.port
   }
 }
index cad5e0f3c8f6c18e3aeed683d57d61d1c8f1e160..4307fadbd71a455cd43500eb2ff81dbed429cd68 100644 (file)
@@ -2,33 +2,34 @@
 package sifive.blocks.devices.spi
 
 import Chisel._
-import sifive.blocks.devices.gpio.{GPIOPin, GPIOOutputPinCtrl, GPIOInputPinCtrl}
+import chisel3.experimental.{withClockAndReset}
+import sifive.blocks.devices.pinctrl.{PinCtrl, Pin}
 
-class SPIPinsIO(c: SPIParamsBase) extends SPIBundle(c) {
-  val sck = new GPIOPin
-  val dq = Vec(4, new GPIOPin)
-  val cs = Vec(c.csWidth, new GPIOPin)
-}
+class SPIPins[T <: Pin] (pingen: ()=> T, c: SPIParamsBase) extends SPIBundle(c) {
 
-class SPIGPIOPort(c: SPIParamsBase, syncStages: Int = 0, driveStrength: Bool = Bool(false)) extends Module {
-  val io = new SPIBundle(c) {
-    val spi = new SPIPortIO(c).flip
-    val pins = new SPIPinsIO(c)
-  }
+  val sck = pingen()
+  val dq  = Vec(4, pingen())
+  val cs  = Vec(c.csWidth, pingen())
 
-  GPIOOutputPinCtrl(io.pins.sck, io.spi.sck, ds = driveStrength)
-
-  GPIOOutputPinCtrl(io.pins.dq, Bits(0, io.spi.dq.size))
-  (io.pins.dq zip io.spi.dq).foreach {
-    case (p, s) =>
-      p.o.oval := s.o
-      p.o.oe  := s.oe
-      p.o.ie  := ~s.oe
-      p.o.pue := Bool(true)
-      p.o.ds  := driveStrength
-      s.i := ShiftRegister(p.i.ival, syncStages)
-  }
+  override def cloneType: this.type =
+    this.getClass.getConstructors.head.newInstance(pingen, c).asInstanceOf[this.type]
+
+  def fromSPIPort(spi: SPIPortIO, clock: Clock, reset: Bool,
+    syncStages: Int = 0, driveStrength: Bool = Bool(false)) {
 
-  GPIOOutputPinCtrl(io.pins.cs, io.spi.cs.asUInt)
-  io.pins.cs.foreach(_.o.ds := driveStrength)
+    withClockAndReset(clock, reset) {
+      sck.outputPin(spi.sck, ds = driveStrength)
+
+      (dq zip spi.dq).foreach {case (p, s) =>
+        p.outputPin(s.o, pue = Bool(true), ds = driveStrength)
+        p.o.oe := s.oe
+        p.o.ie := ~s.oe
+        s.i := ShiftRegister(p.i.ival, syncStages)
+      }
+
+      (cs zip spi.cs) foreach { case (c, s) =>
+        c.outputPin(s, ds = driveStrength)
+      }
+    }
+  }
 }
index c925a38a0e47307e281788a7e30abb195ab8eb27..d42850f88eca4388a571ac86e47743c69406beef 100644 (file)
@@ -2,10 +2,11 @@
 package sifive.blocks.devices.uart
 
 import Chisel._
+import chisel3.experimental.{withClockAndReset}
 import freechips.rocketchip.config.Field
 import freechips.rocketchip.coreplex.{HasPeripheryBus, HasInterruptBus}
 import freechips.rocketchip.diplomacy.{LazyModule, LazyMultiIOModuleImp}
-import sifive.blocks.devices.gpio.{GPIOPin, GPIOOutputPinCtrl, GPIOInputPinCtrl}
+import sifive.blocks.devices.pinctrl.{Pin}
 import sifive.blocks.util.ShiftRegisterInit
 
 case object PeripheryUARTKey extends Field[Seq[UARTParams]]
@@ -21,40 +22,36 @@ trait HasPeripheryUART extends HasPeripheryBus with HasInterruptBus {
 }
 
 trait HasPeripheryUARTBundle {
-  val uarts: Vec[UARTPortIO]
+  val uart: Vec[UARTPortIO]
 
   def tieoffUARTs(dummy: Int = 1) {
-    uarts.foreach { _.rxd := UInt(1) }
+    uart.foreach { _.rxd := UInt(1) }
   }
 
-  def UARTtoGPIOPins(syncStages: Int = 0): Seq[UARTPinsIO] = uarts.map { u =>
-    val pins = Module(new UARTGPIOPort(syncStages))
-    pins.io.uart <> u
-    pins.io.pins
-  }
 }
 
 trait HasPeripheryUARTModuleImp extends LazyMultiIOModuleImp with HasPeripheryUARTBundle {
   val outer: HasPeripheryUART
-  val uarts = IO(Vec(outer.uartParams.size, new UARTPortIO))
+  val uart = IO(Vec(outer.uartParams.size, new UARTPortIO))
 
-  (uarts zip outer.uarts).foreach { case (io, device) =>
+  (uart zip outer.uarts).foreach { case (io, device) =>
     io <> device.module.io.port
   }
 }
 
-class UARTPinsIO extends Bundle {
-  val rxd = new GPIOPin
-  val txd = new GPIOPin
-}
+class UARTPins[T <: Pin] (pingen: () => T) extends Bundle {
+  val rxd = pingen()
+  val txd = pingen()
 
-class UARTGPIOPort(syncStages: Int = 0) extends Module {
-  val io = new Bundle{
-    val uart = new UARTPortIO().flip()
-    val pins = new UARTPinsIO
-  }
+  override def cloneType: this.type =
+    this.getClass.getConstructors.head.newInstance(pingen).asInstanceOf[this.type]
 
-  GPIOOutputPinCtrl(io.pins.txd, io.uart.txd)
-  val rxd = GPIOInputPinCtrl(io.pins.rxd)
-  io.uart.rxd := ShiftRegisterInit(rxd, syncStages, Bool(true))
+  def fromUARTPort(uart: UARTPortIO, clock: Clock, reset: Bool, syncStages: Int = 0) {
+    withClockAndReset(clock, reset) {
+      txd.outputPin(uart.txd)
+      val rxd_t = rxd.inputPin()
+      uart.rxd := ShiftRegisterInit(rxd_t, syncStages, Bool(true))
+    }
+  }
 }
+