1
0

Add XilinxML507MIG periphery and connect top level signals

This commit is contained in:
Klemens Schölhorn 2018-05-10 00:29:22 +02:00
parent 3797385a8c
commit 2707fa59a4
3 changed files with 121 additions and 17 deletions

View File

@ -3,35 +3,37 @@
package sifive.fpgashells.devices.xilinx.xilinxml507mig
import Chisel._
import freechips.rocketchip.config.{Field, Parameters}
import chisel3.core.{Input, Output}
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util._
case class MemoryML507Params(
case class XilinxML507MIGParams(
address: Seq[AddressSet]
)
case object MemoryML507Key extends Field[MemoryML507Params]
class MemoryController extends BlackBox {
val io = IO(new Bundle {
val sys = new MemorySysIO
val ddr2 = new MemoryDDR2IO
trait HasMemoryML507 { this: BaseSubsystem =>
val memory = LazyModule(new TLMemoryML507(p(MemoryML507Key)))
val request_addr = Input(UInt(28.W))
val request_read = Input(Bool())
val request_data = Input(UInt(256.W))
val request_mask = Input(UInt(32.W))
val request_valid = Input(Bool())
val request_ready = Output(Bool())
// The Fragmenter will not fragment messages <= 32 bytes, so all
// slaves have to support this size. 64 byte specifies the maximum
// supported transfer size that the slave side of the fragmenter supports
// against the master (here the main memory bus). Specifying alwaysMin as
// true results in all messages being fragmented to the minimal size
// (32 byte). In TL1 terms, slaves
// correspond roughly to managers and masters to clients (confusingly).
val fragmenter = TLFragmenter(32, 64, alwaysMin=true)
val response_data = Output(UInt(256.W))
val response_valid = Output(Bool())
// no ready, as the mig does not wait
})
// TODO: right TL/memory node chain?
memory.node := fragmenter := memBuses.head.toDRAMController(Some("ml507mig"))()
override def desiredName: String = "memory_controller"
}
class TLMemoryML507(c: MemoryML507Params)(implicit p: Parameters) extends LazyModule {
class XilinxML507MIGToTL(c: XilinxML507MIGParams)(implicit p: Parameters) extends LazyModule {
// Corresponds to MIG interface with 64 bit width and a burst length of 4
val width = 256
val beatBytes = width/8 // 32 byte (half a cache-line, fragmented)
@ -56,6 +58,15 @@ class TLMemoryML507(c: MemoryML507Params)(implicit p: Parameters) extends LazyMo
// the data width (size signal, see below).
lazy val module = new LazyModuleImp(this) {
val io = IO(new Bundle {
val port_sys = new MemorySysIO
val port_ddr2 = new MemoryDDR2IO
})
val controller = Module(new MemoryController)
io.port_sys <> controller.io.sys
io.port_ddr2 <> controller.io.ddr2
// in: TLBundle, edge: TLEdgeIn
val (in, edge) = node.in(0)
@ -102,3 +113,28 @@ class TLMemoryML507(c: MemoryML507Params)(implicit p: Parameters) extends LazyMo
in.e.ready := Bool(true)
}
}
class XilinxML507MIG(c : XilinxML507MIGParams)(implicit p: Parameters) extends LazyModule {
// The Fragmenter will not fragment messages <= 32 bytes, so all
// slaves have to support this size. 64 byte specifies the maximum
// supported transfer size that the slave side of the fragmenter supports
// against the master (here the main memory bus). Specifying alwaysMin as
// true results in all messages being fragmented to the minimal size
// (32 byte). In TL1 terms, slaves correspond roughly to managers and
// masters to clients (confusingly).
val fragmenter = LazyModule(new TLFragmenter(32, 64, alwaysMin=true))
val island = LazyModule(new XilinxML507MIGToTL(c))
val node: TLInwardNode =
island.node := fragmenter.node
lazy val module = new LazyModuleImp(this) {
val io = IO(new Bundle {
val port_sys = new MemorySysIO
val port_ddr2 = new MemoryDDR2IO
})
io.port_sys <> island.module.io.port_sys
io.port_ddr2 <> island.module.io.port_ddr2
}
}

View File

@ -0,0 +1,58 @@
// See LICENSE.SiFive for license details.
package sifive.fpgashells.devices.xilinx.xilinxml507mig
import Chisel._
import chisel3.core.{Input, Output}
import chisel3.experimental.Analog
import freechips.rocketchip.config.Field
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.subsystem.BaseSubsystem
case object MemoryML507Key extends Field[XilinxML507MIGParams]
trait HasMemoryML507 { this: BaseSubsystem =>
val memory = LazyModule(new XilinxML507MIG(p(MemoryML507Key)))
memory.node := memBuses.head.toDRAMController(Some("xilinxml507mig"))()
}
class MemorySysIO extends Bundle {
val clk0 = Input(Clock())
val clk90 = Input(Clock())
val clkdiv0 = Input(Clock())
val clk_locked = Input(Bool())
val clk_idelay = Input(Clock())
val reset = Input(Bool())
}
class MemoryDDR2IO extends Bundle {
val dq = Analog(64.W)
val a = Output(Bits(13.W))
val ba = Output(Bits(2.W))
val ras_n = Output(Bits(1.W))
val cas_n = Output(Bits(1.W))
val we_n = Output(Bits(1.W))
val cs_n = Output(Bits(1.W))
val odt = Output(Bits(1.W))
val cke = Output(Bits(1.W))
val dm = Output(Bits(8.W))
val dqs = Analog(8.W)
val dqs_n = Analog(8.W)
val ck = Output(Bits(2.W))
val ck_n = Output(Bits(2.W))
}
trait HasMemoryML507Bundle {
val ddr_sys: MemorySysIO
val ddr2: MemoryDDR2IO
}
trait HasMemoryML507ModuleImp extends LazyModuleImp with HasMemoryML507Bundle {
val outer: HasMemoryML507
val ddr_sys = IO(new MemorySysIO)
val ddr2 = IO(new MemoryDDR2IO)
ddr_sys <> outer.memory.module.io.port_sys
ddr2 <> outer.memory.module.io.port_ddr2
}

View File

@ -15,6 +15,7 @@ import sifive.blocks.devices.uart._
import sifive.blocks.devices.chiplink._
import sifive.blocks.devices.terminal._
import sifive.fpgashells.devices.xilinx.xilinxml507mig._
import sifive.fpgashells.ip.xilinx.{PowerOnResetFPGAOnly, sdio_spi_bridge, ml507_dvi_clock, ml507_sys_clock, vc707reset}
//-------------------------------------------------------------------------
@ -79,6 +80,7 @@ abstract class ML507Shell(implicit val p: Parameters) extends RawModule {
val reset_led = IO(Output(Bool()))
val dvi = IO(new TerminalDVIIO)
val ddr2 = IO(new MemoryDDR2IO)
//-----------------------------------------------------------------------
// Wire declrations
@ -159,6 +161,14 @@ abstract class ML507Shell(implicit val p: Parameters) extends RawModule {
dut.terminal.reset := dvi_reset
}
//-----------------------------------------------------------------------
// Memory controller
//-----------------------------------------------------------------------
def connectDDRMemory(dut: HasMemoryML507ModuleImp): Unit = {
ddr2 <> dut.ddr2
}
//-----------------------------------------------------------------------
// UART
//-----------------------------------------------------------------------