X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmain%2Fscala%2Fdevices%2Fgpio%2FGPIO.scala;h=e7a48299d132df91965224608386f61812b810f4;hb=ef4f2ed888cd614858c6b2647c1eb6f988ff3973;hp=ae468cec2f909bb8511ea786092ef9ce7c484c7b;hpb=fb9dd313741196a062e6a0f6462cf3a2bce710a9;p=sifive-blocks.git diff --git a/src/main/scala/devices/gpio/GPIO.scala b/src/main/scala/devices/gpio/GPIO.scala index ae468ce..e7a4829 100644 --- a/src/main/scala/devices/gpio/GPIO.scala +++ b/src/main/scala/devices/gpio/GPIO.scala @@ -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)(