1
0

Initial commit.

This commit is contained in:
SiFive
2016-11-29 04:08:44 -08:00
commit 7916ef5249
42 changed files with 3763 additions and 0 deletions

View File

@ -0,0 +1,82 @@
// See LICENSE for license details.
package sifive.blocks.devices.pwm
import Chisel._
import Chisel.ImplicitConversions._
import config._
import regmapper._
import rocketchip.PeripheryBusConfig
import uncore.tilelink2._
import util._
import sifive.blocks.util.GenericTimer
// Core PWM Functionality & Register Interface
class PWM(val ncmp: Int = 4, val cmpWidth: Int = 16)(implicit p: Parameters) extends GenericTimer {
protected def countWidth = ((1 << scaleWidth) - 1) + cmpWidth
protected lazy val countAlways = RegEnable(io.regs.cfg.write.bits(12), Bool(false), io.regs.cfg.write.valid && unlocked)
protected lazy val feed = count.carryOut(scale + UInt(cmpWidth))
protected lazy val countEn = Wire(Bool())
override protected lazy val oneShot = RegEnable(io.regs.cfg.write.bits(13) && !countReset, Bool(false), (io.regs.cfg.write.valid && unlocked) || countReset)
override protected lazy val center = RegEnable(io.regs.cfg.write.bits(16 + ncmp - 1, 16), io.regs.cfg.write.valid && unlocked)
override protected lazy val gang = RegEnable(io.regs.cfg.write.bits(24 + ncmp - 1, 24), io.regs.cfg.write.valid && unlocked)
override protected lazy val deglitch = RegEnable(io.regs.cfg.write.bits(10), io.regs.cfg.write.valid && unlocked)(0)
override protected lazy val sticky = RegEnable(io.regs.cfg.write.bits(8), io.regs.cfg.write.valid && unlocked)(0)
override protected lazy val ip = {
val doSticky = Reg(next = (deglitch && !countReset) || sticky)
val sel = ((0 until ncmp).map(i => s(cmpWidth-1) && center(i))).asUInt
val reg = Reg(UInt(width = ncmp))
reg := (sel & elapsed.asUInt) | (~sel & (elapsed.asUInt | (Fill(ncmp, doSticky) & reg)))
when (io.regs.cfg.write.valid && unlocked) { reg := io.regs.cfg.write.bits(28 + ncmp - 1, 28) }
reg
}
lazy val io = new GenericTimerIO {
val gpio = Vec(ncmp, Bool()).asOutput
}
io.gpio := io.gpio.fromBits(ip & ~(gang & Cat(ip(0), ip >> 1)))
countEn := countAlways || oneShot
}
case class PWMConfig(
address: BigInt,
size: Int = 0x1000,
regBytes: Int = 4,
ncmp: Int = 4,
cmpWidth: Int = 16)
{
val bc = new PWMBundleConfig(ncmp)
}
case class PWMBundleConfig(
ncmp: Int)
{
def union(that: PWMBundleConfig): PWMBundleConfig =
PWMBundleConfig(scala.math.max(ncmp, that.ncmp))
}
trait HasPWMParameters {
val params: (PWMConfig, Parameters)
val c = params._1
implicit val p = params._2
}
trait PWMBundle extends Bundle with HasPWMParameters {
val gpio = Vec(c.ncmp, Bool()).asOutput
}
trait PWMModule extends Module with HasRegMap with HasPWMParameters {
val io: PWMBundle
val pwm = Module(new PWM(c.ncmp, c.cmpWidth))
interrupts := pwm.io.ip
io.gpio := pwm.io.gpio
regmap((GenericTimer.timerRegMap(pwm, 0, c.regBytes)):_*)
}
class TLPWM(c: PWMConfig)(implicit val p: Parameters)
extends TLRegisterRouter(c.address, interrupts = c.ncmp, size = c.size, beatBytes = p(PeripheryBusConfig).beatBytes)(
new TLRegBundle((c, p), _) with PWMBundle)(
new TLRegModule((c, p), _, _) with PWMModule)

View File

@ -0,0 +1,58 @@
// See LICENSE for license details.
package sifive.blocks.devices.pwm
import Chisel._
import config._
import diplomacy.LazyModule
import rocketchip.{TopNetwork,TopNetworkModule}
import uncore.tilelink2.TLFragmenter
import sifive.blocks.devices.gpio._
class PWMPortIO(c: PWMBundleConfig)(implicit p: Parameters) extends Bundle {
val port = Vec(c.ncmp, Bool()).asOutput
override def cloneType: this.type = new PWMPortIO(c).asInstanceOf[this.type]
}
class PWMPinsIO(c: PWMBundleConfig)(implicit p: Parameters) extends Bundle {
val pwm = Vec(c.ncmp, new GPIOPin)
}
class PWMGPIOPort(c: PWMBundleConfig)(implicit p: Parameters) extends Module {
val io = new Bundle {
val pwm = new PWMPortIO(c).flip()
val pins = new PWMPinsIO(c)
}
GPIOOutputPinCtrl(io.pins.pwm, io.pwm.port.asUInt)
}
trait PeripheryPWM {
this: TopNetwork { val pwmConfigs: Seq[PWMConfig] } =>
val pwmDevices = (pwmConfigs.zipWithIndex) map { case (c, i) =>
val pwm = LazyModule(new TLPWM(c) { override lazy val valName = Some(s"pwm$i") })
pwm.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node)
intBus.intnode := pwm.intnode
pwm
}
}
trait PeripheryPWMBundle {
this: {
val p: Parameters
val pwmConfigs: Seq[PWMConfig]
} =>
val pwm_bc = pwmConfigs.map(_.bc).reduce(_.union(_))
val pwms = Vec(pwmConfigs.size, new PWMPortIO(pwm_bc)(p))
}
trait PeripheryPWMModule {
this: TopNetworkModule {
val outer: PeripheryPWM
val io: PeripheryPWMBundle
} =>
(io.pwms.zipWithIndex zip outer.pwmDevices) foreach { case ((io, i), device) =>
io.port := device.module.io.gpio
}
}