max2771 spi liens has been added.

This commit is contained in:
onur
2026-08-06 22:14:52 +03:00
parent 847523078b
commit b4920d31e3
288 changed files with 214687 additions and 18389 deletions
+119
View File
@@ -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) ++