X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmain%2Fscala%2Fdevices%2Fgpio%2FGPIO.scala;h=ae468cec2f909bb8511ea786092ef9ce7c484c7b;hb=fb9dd313741196a062e6a0f6462cf3a2bce710a9;hp=9dd8d87ba58ef8d6da8da59263fa5fd771641a14;hpb=64bff444622bf7a61a84ed6cdda8aa6ddd5119cf;p=sifive-blocks.git diff --git a/src/main/scala/devices/gpio/GPIO.scala b/src/main/scala/devices/gpio/GPIO.scala index 9dd8d87..ae468ce 100644 --- a/src/main/scala/devices/gpio/GPIO.scala +++ b/src/main/scala/devices/gpio/GPIO.scala @@ -2,12 +2,12 @@ package sifive.blocks.devices.gpio import Chisel._ -import config.Parameters -import regmapper._ -import uncore.tilelink2._ -import util.AsyncResetRegVec +import freechips.rocketchip.config.Parameters +import freechips.rocketchip.regmapper._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util.{AsyncResetRegVec, GenericParameterizedBundle} -case class GPIOParams(address: BigInt, width: Int) +case class GPIOParams(address: BigInt, width: Int, includeIOF: Boolean = false) // YAGNI: Make the PUE, DS, and // these also optionally HW controllable. @@ -93,10 +93,10 @@ class GPIOPin extends Bundle { // level, and we have to do the pinmux // outside of RocketChipTop. -class GPIOPortIO(c: GPIOParams) extends Bundle { +class GPIOPortIO(c: GPIOParams) extends GenericParameterizedBundle(c) { val pins = Vec(c.width, new GPIOPin) - val iof_0 = Vec(c.width, new GPIOPinIOF).flip - val iof_1 = Vec(c.width, new GPIOPinIOF).flip + 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 } // It would be better if the IOF were here and @@ -142,7 +142,7 @@ trait HasGPIOModuleContents extends Module with HasRegMap { // HW IO Function val iofEnReg = Module(new AsyncResetRegVec(c.width, 0)) val iofSelReg = Reg(init = UInt(0, c.width)) - + // Invert Output val xorReg = Reg(init = UInt(0, c.width)) @@ -153,6 +153,10 @@ trait HasGPIOModuleContents extends Module with HasRegMap { val rise = ~valueReg & inSyncReg; val fall = valueReg & ~inSyncReg; + val iofEnFields = if (c.includeIOF) (Seq(RegField.rwReg(c.width, iofEnReg.io))) else (Seq(RegField(c.width))) + val iofSelFields = if (c.includeIOF) (Seq(RegField(c.width, iofSelReg))) else (Seq(RegField(c.width))) + + // Note that these are out of order. regmap( GPIOCtrlRegs.value -> Seq(RegField.r(c.width, valueReg)), @@ -167,8 +171,8 @@ trait HasGPIOModuleContents extends Module with HasRegMap { GPIOCtrlRegs.low_ip -> Seq(RegField.w1ToClear(c.width,lowIpReg, ~valueReg)), GPIOCtrlRegs.port -> Seq(RegField(c.width, portReg)), GPIOCtrlRegs.pullup_en -> Seq(RegField.rwReg(c.width, pueReg.io)), - GPIOCtrlRegs.iof_en -> Seq(RegField.rwReg(c.width, iofEnReg.io)), - GPIOCtrlRegs.iof_sel -> Seq(RegField(c.width, iofSelReg)), + GPIOCtrlRegs.iof_en -> iofEnFields, + GPIOCtrlRegs.iof_sel -> iofSelFields, GPIOCtrlRegs.drive -> Seq(RegField(c.width, dsReg)), GPIOCtrlRegs.input_en -> Seq(RegField.rwReg(c.width, ieReg.io)), GPIOCtrlRegs.out_xor -> Seq(RegField(c.width, xorReg)) @@ -198,26 +202,33 @@ trait HasGPIOModuleContents extends Module with HasRegMap { swPinCtrl(pin).ds := dsReg(pin) swPinCtrl(pin).ie := ieReg.io.q(pin) - // Allow SW Override for invalid inputs. - iof0Ctrl(pin) <> swPinCtrl(pin) - when (io.port.iof_0(pin).o.valid) { - iof0Ctrl(pin) <> io.port.iof_0(pin).o - } - - iof1Ctrl(pin) <> swPinCtrl(pin) - when (io.port.iof_1(pin).o.valid) { - iof1Ctrl(pin) <> io.port.iof_1(pin).o + val pre_xor = Wire(new GPIOPinCtrl()) + + if (c.includeIOF) { + // Allow SW Override for invalid inputs. + iof0Ctrl(pin) <> swPinCtrl(pin) + when (io.port.iof_0.get(pin).o.valid) { + iof0Ctrl(pin) <> io.port.iof_0.get(pin).o + } + + iof1Ctrl(pin) <> swPinCtrl(pin) + when (io.port.iof_1.get(pin).o.valid) { + iof1Ctrl(pin) <> io.port.iof_1.get(pin).o + } + + // Select IOF 0 vs. IOF 1. + iofCtrl(pin) <> Mux(iofSelReg(pin), iof1Ctrl(pin), iof0Ctrl(pin)) + + // Allow SW Override for things IOF doesn't control. + iofPlusSwPinCtrl(pin) <> swPinCtrl(pin) + iofPlusSwPinCtrl(pin) <> iofCtrl(pin) + + // Final XOR & Pin Control + pre_xor := Mux(iofEnReg.io.q(pin), iofPlusSwPinCtrl(pin), swPinCtrl(pin)) + } else { + pre_xor := swPinCtrl(pin) } - // Select IOF 0 vs. IOF 1. - iofCtrl(pin) <> Mux(iofSelReg(pin), iof1Ctrl(pin), iof0Ctrl(pin)) - - // Allow SW Override for things IOF doesn't control. - iofPlusSwPinCtrl(pin) <> swPinCtrl(pin) - iofPlusSwPinCtrl(pin) <> iofCtrl(pin) - - // Final XOR & Pin Control - val pre_xor: GPIOPinCtrl = Mux(iofEnReg.io.q(pin), iofPlusSwPinCtrl(pin), swPinCtrl(pin)) io.port.pins(pin).o := pre_xor io.port.pins(pin).o.oval := pre_xor.oval ^ xorReg(pin) @@ -227,9 +238,11 @@ trait HasGPIOModuleContents extends Module with HasRegMap { (highIpReg(pin) & highIeReg(pin)) | (lowIpReg(pin) & lowIeReg(pin)) - // Send Value to all consumers - io.port.iof_0(pin).i.ival := inSyncReg(pin) - io.port.iof_1(pin).i.ival := inSyncReg(pin) + if (c.includeIOF) { + // Send Value to all consumers + io.port.iof_0.get(pin).i.ival := inSyncReg(pin) + io.port.iof_1.get(pin).i.ival := inSyncReg(pin) + } } }