max2771 spi liens has been added.
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
package freechips.rocketchip.fpga
|
||||
|
||||
import chisel3._
|
||||
import chisel3.experimental.IntParam
|
||||
import chisel3.util.Cat
|
||||
|
||||
import org.chipsalliance.cde.config.Parameters
|
||||
import org.chipsalliance.diplomacy.bundlebridge._
|
||||
import org.chipsalliance.diplomacy.lazymodule._
|
||||
|
||||
import freechips.rocketchip.diplomacy.AddressSet
|
||||
import freechips.rocketchip.regmapper.{RegField, RegFieldDesc, RegWriteFn}
|
||||
import freechips.rocketchip.resources.SimpleDevice
|
||||
import freechips.rocketchip.tilelink.TLRegisterNode
|
||||
|
||||
case class MAX2771SPIParams(
|
||||
address: BigInt = 0x10016000L,
|
||||
inputClockHz: Int = 100000000,
|
||||
maxSclkHz: Int = 4000000) {
|
||||
require(inputClockHz > 0, "MAX2771 SPI input clock must be positive")
|
||||
require(maxSclkHz > 0 && maxSclkHz <= 4000000,
|
||||
"MAX2771 data sheet limits SCLK to 4 MHz")
|
||||
|
||||
val halfPeriodCycles: Int = (inputClockHz + 2 * maxSclkHz - 1) / (2 * maxSclkHz)
|
||||
val actualSclkHz: Int = inputClockHz / (2 * halfPeriodCycles)
|
||||
}
|
||||
|
||||
class MAX2771SPIEngineBlackBox(params: MAX2771SPIParams) extends BlackBox(Map(
|
||||
"CLOCK_HZ" -> IntParam(params.inputClockHz),
|
||||
"MAX_SCLK_HZ" -> IntParam(params.maxSclkHz))) {
|
||||
override def desiredName: String = "max2771_spi_engine"
|
||||
|
||||
val io = IO(new Bundle {
|
||||
val clk = Input(Clock())
|
||||
val rst_n = Input(Bool())
|
||||
val start = Input(Bool())
|
||||
val read_not_write = Input(Bool())
|
||||
val address = Input(UInt(4.W))
|
||||
val write_data = Input(UInt(32.W))
|
||||
val read_data = Output(UInt(32.W))
|
||||
val busy = Output(Bool())
|
||||
val ready = Output(Bool())
|
||||
val sclk = Output(Bool())
|
||||
val csn = Output(Bool())
|
||||
val sdata_i = Input(Bool())
|
||||
val sdata_o = Output(Bool())
|
||||
val sdata_oe = Output(Bool())
|
||||
})
|
||||
}
|
||||
|
||||
class TLMAX2771SPI(params: MAX2771SPIParams, beatBytes: Int)(implicit p: Parameters)
|
||||
extends LazyModule {
|
||||
val device = new SimpleDevice("max2771-spi", Seq("analog-devices,max2771-spi"))
|
||||
val sclkNode = BundleBridgeSource(() => Bool())
|
||||
val csnNode = BundleBridgeSource(() => Bool())
|
||||
val sdataInNode = BundleBridgeSink[Bool]()
|
||||
val sdataOutNode = BundleBridgeSource(() => Bool())
|
||||
val sdataOeNode = BundleBridgeSource(() => Bool())
|
||||
val node = TLRegisterNode(
|
||||
address = Seq(AddressSet(params.address, 0xfff)),
|
||||
device = device,
|
||||
beatBytes = beatBytes,
|
||||
concurrency = 1)
|
||||
|
||||
lazy val module = new Impl
|
||||
class Impl extends LazyModuleImp(this) {
|
||||
val engine = Module(new MAX2771SPIEngineBlackBox(params))
|
||||
val writeData = RegInit(0.U(32.W))
|
||||
val start = WireDefault(false.B)
|
||||
val commandRead = WireDefault(false.B)
|
||||
val commandAddress = WireDefault(0.U(4.W))
|
||||
|
||||
engine.io.clk := clock
|
||||
engine.io.rst_n := !reset.asBool
|
||||
engine.io.start := start
|
||||
engine.io.read_not_write := commandRead
|
||||
engine.io.address := commandAddress
|
||||
engine.io.write_data := writeData
|
||||
engine.io.sdata_i := sdataInNode.bundle
|
||||
|
||||
sclkNode.bundle := engine.io.sclk
|
||||
csnNode.bundle := engine.io.csn
|
||||
sdataOutNode.bundle := engine.io.sdata_o
|
||||
sdataOeNode.bundle := engine.io.sdata_oe
|
||||
|
||||
val commandWrite = RegWriteFn { (valid, data) =>
|
||||
commandRead := data(8)
|
||||
commandAddress := data(3, 0)
|
||||
start := valid && engine.io.ready
|
||||
engine.io.ready
|
||||
}
|
||||
|
||||
val writeDataWrite = RegWriteFn { (valid, data) =>
|
||||
when(valid && engine.io.ready) { writeData := data }
|
||||
engine.io.ready
|
||||
}
|
||||
|
||||
val status = Cat(0.U(30.W), engine.io.busy, engine.io.ready)
|
||||
|
||||
node.regmap(
|
||||
0x00 -> Seq(RegField.w(32, commandWrite,
|
||||
RegFieldDesc("command", "bits[3:0] register address, bit8 read; write starts one 48-clock frame"))),
|
||||
0x04 -> Seq(RegField.w(32, writeDataWrite,
|
||||
RegFieldDesc("write_data", "32-bit MAX2771 register write data"))),
|
||||
0x08 -> Seq(RegField.r(32, engine.io.read_data,
|
||||
RegFieldDesc("read_data", "last 32-bit MAX2771 register read data"))),
|
||||
0x0c -> Seq(RegField.r(32, status,
|
||||
RegFieldDesc("status", "bit0 ready, bit1 busy"))),
|
||||
0x10 -> Seq(RegField.r(32, params.inputClockHz.U,
|
||||
RegFieldDesc("input_clock_hz", "peripheral input clock frequency"))),
|
||||
0x14 -> Seq(RegField.r(32, params.actualSclkHz.U,
|
||||
RegFieldDesc("sclk_hz", "actual integer MAX2771 serial clock frequency"))),
|
||||
0x18 -> Seq(RegField.r(32, params.halfPeriodCycles.U,
|
||||
RegFieldDesc("half_period_cycles", "input-clock cycles per SCLK half-period"))),
|
||||
0x1c -> Seq(RegField.r(32, "h4d415831".U,
|
||||
RegFieldDesc("identification", "ASCII MAX1 peripheral identification")))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -299,6 +299,15 @@ class WithVCU118PmodSPI(address: BigInt = 0x10015000L)
|
||||
compatibility = Seq("rocket,fpga-pmod-spi", "rocket,fpga-spi")))
|
||||
})
|
||||
|
||||
class WithMAX2771SPI(
|
||||
address: BigInt = 0x10016000L,
|
||||
inputClockHz: Int = 100000000)
|
||||
extends Config((site, here, up) => {
|
||||
case MAX2771SPIKey => Some(MAX2771SPIParams(
|
||||
address = address,
|
||||
inputClockHz = inputClockHz))
|
||||
})
|
||||
|
||||
case class FpgaGPSParams(
|
||||
baseAddress: BigInt = 0x10020000L,
|
||||
trackingCount: Int = 9,
|
||||
@@ -587,6 +596,7 @@ class WithVCU118FlashBootROM(file: String = "./soc/out/software/bootloader/bootl
|
||||
case object VCU118UARTKey extends Field[Option[FpgaUARTParams]](None)
|
||||
case object VCU118SPIKey extends Field[Option[FpgaSPIParams]](None)
|
||||
case object VCU118PmodSPIKey extends Field[Option[FpgaSPIParams]](None)
|
||||
case object MAX2771SPIKey extends Field[Option[MAX2771SPIParams]](None)
|
||||
case object VCU118GPSKey extends Field[Option[FpgaGPSParams]](None)
|
||||
case object VCU118RAMKey extends Field[Option[AddressSet]](None)
|
||||
|
||||
@@ -665,6 +675,26 @@ class VCU118RocketSystem(implicit p: Parameters) extends RocketSubsystem
|
||||
val pmodSPIDQOSinkNode = pmodSPI.map(_.dqOutNode.makeSink())
|
||||
val pmodSPIDQOESinkNode = pmodSPI.map(_.dqOeNode.makeSink())
|
||||
|
||||
val max2771SPIDataSourceNode = p(MAX2771SPIKey).map(_ => BundleBridgeSource(() => Bool()))
|
||||
|
||||
val max2771SPI = p(MAX2771SPIKey).map { params =>
|
||||
val pbus = locateTLBusWrapper(PBUS)
|
||||
val domain = pbus.generateSynchronousDomain("MAX2771SPI").suggestName("max2771_spi_domain")
|
||||
val dev = domain { LazyModule(new TLMAX2771SPI(params, pbus.beatBytes)) }
|
||||
domain {
|
||||
dev.node := pbus.coupleTo("max2771_spi") {
|
||||
TLFragmenter(pbus, Some("MAX2771SPI")) := _
|
||||
}
|
||||
}
|
||||
max2771SPIDataSourceNode.foreach { source => dev.sdataInNode := source }
|
||||
dev
|
||||
}
|
||||
|
||||
val max2771SPISCKSinkNode = max2771SPI.map(_.sclkNode.makeSink())
|
||||
val max2771SPICSNSinkNode = max2771SPI.map(_.csnNode.makeSink())
|
||||
val max2771SPIDataSinkNode = max2771SPI.map(_.sdataOutNode.makeSink())
|
||||
val max2771SPIDataOESinkNode = max2771SPI.map(_.sdataOeNode.makeSink())
|
||||
|
||||
val gps = p(VCU118GPSKey).map { params =>
|
||||
val pbus = locateTLBusWrapper(PBUS)
|
||||
val domain = pbus.generateSynchronousDomain("FPGAGPS").suggestName("fpga_gps_domain")
|
||||
@@ -708,6 +738,11 @@ class VCU118RocketSystemModuleImp[+L <: VCU118RocketSystem](_outer: L)
|
||||
val pmod_spi_dq_i = _outer.pmodSPIDQISourceNode.map(_.makeIO("pmod_spi_dq_i"))
|
||||
val pmod_spi_dq_o = _outer.pmodSPIDQOSinkNode.map(_.makeIO("pmod_spi_dq_o"))
|
||||
val pmod_spi_dq_oe = _outer.pmodSPIDQOESinkNode.map(_.makeIO("pmod_spi_dq_oe"))
|
||||
val max2771_spi_sclk = _outer.max2771SPISCKSinkNode.map(_.makeIO("max2771_spi_sclk"))
|
||||
val max2771_spi_csn = _outer.max2771SPICSNSinkNode.map(_.makeIO("max2771_spi_csn"))
|
||||
val max2771_spi_sdata_i = _outer.max2771SPIDataSourceNode.map(_.makeIO("max2771_spi_sdata_i"))
|
||||
val max2771_spi_sdata_o = _outer.max2771SPIDataSinkNode.map(_.makeIO("max2771_spi_sdata_o"))
|
||||
val max2771_spi_sdata_oe = _outer.max2771SPIDataOESinkNode.map(_.makeIO("max2771_spi_sdata_oe"))
|
||||
val pmod_irq = IO(Input(Bool()))
|
||||
|
||||
val gps_acq_clk = _outer.gpsAcqClockSourceNode.map(_.makeIO("gps_acq_clk"))
|
||||
@@ -735,6 +770,9 @@ class VCU118RocketConfig extends Config(
|
||||
new WithVCU118UART(0x10013000L, 100000000, 115200) ++
|
||||
new WithVCU118SPI(0x10014000L) ++
|
||||
new WithVCU118PmodSPI(0x10015000L) ++
|
||||
new WithMAX2771SPI(
|
||||
0x10016000L,
|
||||
FpgaBuildSettings.bigInt("ROCKET_SOC_CLOCK_HZ", 100000000L).toInt) ++
|
||||
new WithVCU118GPS(0x10020000L, 9) ++
|
||||
new WithNExtTopInterrupts(0) ++
|
||||
new WithNSmallCores(1) ++
|
||||
|
||||
Reference in New Issue
Block a user