Skip to content

Commit

Permalink
Add support for multiple CS pin for SDRAM controller
Browse files Browse the repository at this point in the history
  • Loading branch information
t123yh authored and gmlayer0 committed Dec 20, 2023
1 parent 2700185 commit b806244
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 23 deletions.
8 changes: 5 additions & 3 deletions lib/src/main/scala/spinal/lib/memory/sdram/SdramLayout.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ case class SdramLayout( generation : SdramGeneration,
bankWidth : Int,
columnWidth : Int,
rowWidth : Int,
dataWidth : Int){
dataWidth : Int,
csWidth : Int = 1){
def bytePerWord = dataWidth/8
def wordAddressWidth = bankWidth + columnWidth + rowWidth
def byteAddressWidth = bankWidth + columnWidth + rowWidth + log2Up(bytePerWord)
def csAddressWidth = if (csWidth == 1) 0 else log2Up(csWidth)
def wordAddressWidth = bankWidth + columnWidth + rowWidth + csAddressWidth
def byteAddressWidth = wordAddressWidth + log2Up(bytePerWord)
def chipAddressWidth = Math.max(columnWidth,rowWidth)
def bankCount = 1 << bankWidth
def capacity = BigInt(1) << byteAddressWidth
Expand Down
2 changes: 1 addition & 1 deletion lib/src/main/scala/spinal/lib/memory/sdram/sdr/Sdram.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ case class SdramInterface(g : SdramLayout) extends Bundle with IMasterSlave{
val DQM = Bits(g.bytePerWord bits)
val CASn = Bool()
val CKE = Bool()
val CSn = Bool()
val CSn = Bits(g.csWidth bits)
val RASn = Bool()
val WEn = Bool()

Expand Down
38 changes: 21 additions & 17 deletions lib/src/main/scala/spinal/lib/memory/sdram/sdr/SdramCtrl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ case class SdramCtrlBackendCmd[T <: Data](c : SdramLayout,contextType : T) exten
val data = Bits(c.dataWidth bits)
val mask = Bits(c.bytePerWord bits)
val context = cloneOf(contextType)
val cs = Bits(c.csWidth bits)
}

case class SdramCtrlBank(c : SdramLayout) extends Bundle{
Expand Down Expand Up @@ -153,13 +154,14 @@ case class SdramCtrl[T <: Data](l : SdramLayout, t : SdramTimings, CAS : Int, co


val frontend = new Area{
val banks = Reg(Vec(SdramCtrlBank(l),l.bankCount))
banks.foreach(_.active init(False))
val banks = Reg(Vec(Vec(SdramCtrlBank(l),l.bankCount), l.csWidth))
banks.foreach(_.foreach(_.active init(False)))

val address = new Bundle{
val column = UInt(l.columnWidth bits)
val bank = UInt(l.bankWidth bits)
val row = UInt(l.rowWidth bits)
val chip = UInt(l.csAddressWidth bits)
}
address.assignFromBits(io.bus.cmd.address.asBits)

Expand All @@ -171,6 +173,7 @@ case class SdramCtrl[T <: Data](l : SdramLayout, t : SdramTimings, CAS : Int, co
rsp.data := io.bus.cmd.data
rsp.mask := io.bus.cmd.mask
rsp.context := io.bus.cmd.context
rsp.cs := ~(B(l.csWidth bits, 0 -> True, default -> False) |<< address.chip)

io.bus.cmd.ready := False

Expand Down Expand Up @@ -207,10 +210,11 @@ case class SdramCtrl[T <: Data](l : SdramLayout, t : SdramTimings, CAS : Int, co
default { //RUN
when(refresh.pending){
rsp.valid := True
when(banks.map(_.active).reduce(_ || _)){
// When any of the banks are active
when(banks.map(_.map(_.active).reduce(_ || _)).reduce(_ || _)){
rsp.task := PRECHARGE_ALL
when(rsp.ready){
banks.foreach(_.active := False)
banks.foreach(_.foreach(_.active := False))
}
} otherwise {
rsp.task := REFRESH
Expand All @@ -220,15 +224,15 @@ case class SdramCtrl[T <: Data](l : SdramLayout, t : SdramTimings, CAS : Int, co
}
}elsewhen(io.bus.cmd.valid){
rsp.valid := True
val bank = banks(address.bank)
val bank = banks(address.chip)(address.bank)

when(bank.active && bank.row =/= address.row){
rsp.task := PRECHARGE_SINGLE
when(rsp.ready){
banks(address.bank).active := False
bank.active := False
}
} elsewhen (!banks(address.bank).active) {
} elsewhen (!bank.active) {
rsp.task := ACTIVE
val bank = banks(address.bank)
bank.row := address.row
when(rsp.ready){
bank.active := True
Expand Down Expand Up @@ -357,7 +361,7 @@ case class SdramCtrl[T <: Data](l : SdramLayout, t : SdramTimings, CAS : Int, co

when(remoteCke){
sdram.DQ.read := io.sdram.DQ.read
sdram.CSn := False
sdram.CSn.clearAll()
sdram.RASn := True
sdram.CASn := True
sdram.WEn := True
Expand All @@ -369,13 +373,13 @@ case class SdramCtrl[T <: Data](l : SdramLayout, t : SdramTimings, CAS : Int, co
switch(cmd.task) {
is(PRECHARGE_ALL) {
sdram.ADDR(10) := True
sdram.CSn := False
sdram.CSn.clearAll()
sdram.RASn := False
sdram.CASn := True
sdram.WEn := False
}
is(REFRESH) {
sdram.CSn := False
sdram.CSn.clearAll()
sdram.RASn := False
sdram.CASn := False
sdram.WEn := True
Expand All @@ -388,15 +392,15 @@ case class SdramCtrl[T <: Data](l : SdramLayout, t : SdramTimings, CAS : Int, co
sdram.ADDR(8 downto 7) := 0
sdram.ADDR(9) := False
sdram.BA := 0
sdram.CSn := False
sdram.CSn.clearAll()
sdram.RASn := False
sdram.CASn := False
sdram.WEn := False
}
is(ACTIVE) {
sdram.ADDR := cmd.rowColumn.asBits
sdram.BA := cmd.bank.asBits
sdram.CSn := False
sdram.CSn := cmd.cs
sdram.RASn := False
sdram.CASn := True
sdram.WEn := True
Expand All @@ -408,7 +412,7 @@ case class SdramCtrl[T <: Data](l : SdramLayout, t : SdramTimings, CAS : Int, co
sdram.DQ.write := cmd.data
sdram.DQM := ~cmd.mask
sdram.BA := cmd.bank.asBits
sdram.CSn := False
sdram.CSn := cmd.cs
sdram.RASn := True
sdram.CASn := False
sdram.WEn := False
Expand All @@ -418,15 +422,15 @@ case class SdramCtrl[T <: Data](l : SdramLayout, t : SdramTimings, CAS : Int, co
sdram.ADDR := cmd.rowColumn.asBits
sdram.ADDR(10) := False
sdram.BA := cmd.bank.asBits
sdram.CSn := False
sdram.CSn := cmd.cs
sdram.RASn := True
sdram.CASn := False
sdram.WEn := True
}
is(PRECHARGE_SINGLE) {
sdram.BA := cmd.bank.asBits
sdram.ADDR(10) := False
sdram.CSn := False
sdram.CSn := cmd.cs
sdram.RASn := False
sdram.CASn := True
sdram.WEn := False
Expand All @@ -452,4 +456,4 @@ object SdramCtrlMain{
val device = IS42x320D
SpinalConfig(defaultClockDomainFrequency = FixedFrequency(100 MHz)).generateVhdl(SdramCtrl(device.layout,device.timingGrade7,3,UInt(8 bits)))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ case class SdramModel(io : SdramInterface,
}
def report(msg : String) = println(simTime() + " " + msg)
clockDomain.onSamplings{
if(!io.CSn.toBoolean && ckeLast){
if(!io.CSn(0).toBoolean && ckeLast){
val code = (if(io.RASn.toBoolean) 0x4 else 0) | (if(io.CASn.toBoolean) 0x2 else 0) | (if(io.WEn.toBoolean) 0x1 else 0)
val ba = io.BA.toInt
val addr = io.ADDR.toInt
Expand Down Expand Up @@ -136,4 +136,4 @@ case class SdramModel(io : SdramInterface,
}
}
}
}
}

0 comments on commit b806244

Please sign in to comment.