gpio: Make IOF optional (#21)
* gpio: Make IOF optional * IOF: Make the default false
This commit is contained in:
parent
473464eaa9
commit
2154e9eb3f
@ -7,7 +7,7 @@ import regmapper._
|
|||||||
import uncore.tilelink2._
|
import uncore.tilelink2._
|
||||||
import util.{AsyncResetRegVec, GenericParameterizedBundle}
|
import 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
|
// YAGNI: Make the PUE, DS, and
|
||||||
// these also optionally HW controllable.
|
// these also optionally HW controllable.
|
||||||
@ -95,8 +95,8 @@ class GPIOPin extends Bundle {
|
|||||||
|
|
||||||
class GPIOPortIO(c: GPIOParams) extends GenericParameterizedBundle(c) {
|
class GPIOPortIO(c: GPIOParams) extends GenericParameterizedBundle(c) {
|
||||||
val pins = Vec(c.width, new GPIOPin)
|
val pins = Vec(c.width, new GPIOPin)
|
||||||
val iof_0 = Vec(c.width, new GPIOPinIOF).flip
|
val iof_0 = if (c.includeIOF) Some(Vec(c.width, new GPIOPinIOF).flip) else None
|
||||||
val iof_1 = Vec(c.width, new GPIOPinIOF).flip
|
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
|
// It would be better if the IOF were here and
|
||||||
@ -142,7 +142,7 @@ trait HasGPIOModuleContents extends Module with HasRegMap {
|
|||||||
// HW IO Function
|
// HW IO Function
|
||||||
val iofEnReg = Module(new AsyncResetRegVec(c.width, 0))
|
val iofEnReg = Module(new AsyncResetRegVec(c.width, 0))
|
||||||
val iofSelReg = Reg(init = UInt(0, c.width))
|
val iofSelReg = Reg(init = UInt(0, c.width))
|
||||||
|
|
||||||
// Invert Output
|
// Invert Output
|
||||||
val xorReg = Reg(init = UInt(0, c.width))
|
val xorReg = Reg(init = UInt(0, c.width))
|
||||||
|
|
||||||
@ -153,6 +153,10 @@ trait HasGPIOModuleContents extends Module with HasRegMap {
|
|||||||
val rise = ~valueReg & inSyncReg;
|
val rise = ~valueReg & inSyncReg;
|
||||||
val fall = 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.
|
// Note that these are out of order.
|
||||||
regmap(
|
regmap(
|
||||||
GPIOCtrlRegs.value -> Seq(RegField.r(c.width, valueReg)),
|
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.low_ip -> Seq(RegField.w1ToClear(c.width,lowIpReg, ~valueReg)),
|
||||||
GPIOCtrlRegs.port -> Seq(RegField(c.width, portReg)),
|
GPIOCtrlRegs.port -> Seq(RegField(c.width, portReg)),
|
||||||
GPIOCtrlRegs.pullup_en -> Seq(RegField.rwReg(c.width, pueReg.io)),
|
GPIOCtrlRegs.pullup_en -> Seq(RegField.rwReg(c.width, pueReg.io)),
|
||||||
GPIOCtrlRegs.iof_en -> Seq(RegField.rwReg(c.width, iofEnReg.io)),
|
GPIOCtrlRegs.iof_en -> iofEnFields,
|
||||||
GPIOCtrlRegs.iof_sel -> Seq(RegField(c.width, iofSelReg)),
|
GPIOCtrlRegs.iof_sel -> iofSelFields,
|
||||||
GPIOCtrlRegs.drive -> Seq(RegField(c.width, dsReg)),
|
GPIOCtrlRegs.drive -> Seq(RegField(c.width, dsReg)),
|
||||||
GPIOCtrlRegs.input_en -> Seq(RegField.rwReg(c.width, ieReg.io)),
|
GPIOCtrlRegs.input_en -> Seq(RegField.rwReg(c.width, ieReg.io)),
|
||||||
GPIOCtrlRegs.out_xor -> Seq(RegField(c.width, xorReg))
|
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).ds := dsReg(pin)
|
||||||
swPinCtrl(pin).ie := ieReg.io.q(pin)
|
swPinCtrl(pin).ie := ieReg.io.q(pin)
|
||||||
|
|
||||||
// Allow SW Override for invalid inputs.
|
val pre_xor = Wire(new GPIOPinCtrl())
|
||||||
iof0Ctrl(pin) <> swPinCtrl(pin)
|
|
||||||
when (io.port.iof_0(pin).o.valid) {
|
if (c.includeIOF) {
|
||||||
iof0Ctrl(pin) <> io.port.iof_0(pin).o
|
// 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
iof1Ctrl(pin) <> swPinCtrl(pin)
|
|
||||||
when (io.port.iof_1(pin).o.valid) {
|
|
||||||
iof1Ctrl(pin) <> io.port.iof_1(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
|
|
||||||
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 := pre_xor
|
||||||
io.port.pins(pin).o.oval := pre_xor.oval ^ xorReg(pin)
|
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)) |
|
(highIpReg(pin) & highIeReg(pin)) |
|
||||||
(lowIpReg(pin) & lowIeReg(pin))
|
(lowIpReg(pin) & lowIeReg(pin))
|
||||||
|
|
||||||
// Send Value to all consumers
|
if (c.includeIOF) {
|
||||||
io.port.iof_0(pin).i.ival := inSyncReg(pin)
|
// Send Value to all consumers
|
||||||
io.port.iof_1(pin).i.ival := inSyncReg(pin)
|
io.port.iof_0.get(pin).i.ival := inSyncReg(pin)
|
||||||
|
io.port.iof_1.get(pin).i.ival := inSyncReg(pin)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user