gpio: Make IOF optional (#21)
authorMegan Wachs <megan@sifive.com>
Mon, 19 Jun 2017 19:41:38 +0000 (12:41 -0700)
committerGitHub <noreply@github.com>
Mon, 19 Jun 2017 19:41:38 +0000 (12:41 -0700)
* gpio: Make IOF optional

* IOF: Make the default false

src/main/scala/devices/gpio/GPIO.scala

index 8c4cfbd3beae29c03f84630b0787f5ec770d5d2e..12ac055bbb1d74ed224483129d39ba20e7ed2969 100644 (file)
@@ -7,7 +7,7 @@ import regmapper._
 import uncore.tilelink2._
 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
 // these also optionally HW controllable.
@@ -95,8 +95,8 @@ class GPIOPin 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)
+    }
   }
 }