Skip to content

Commit

Permalink
latch regfile now use tristate
Browse files Browse the repository at this point in the history
  • Loading branch information
Dolu1990 committed Jan 11, 2024
1 parent a302df7 commit 942825a
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 43 deletions.
1 change: 1 addition & 0 deletions src/main/scala/naxriscv/compatibility/MultiportRam.scala
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ class MultiPortWritesSymplifier(onlyTagged : Boolean = false) extends PhaseMemBl


for((reworked, old) <- (io.read, readsAsync).zipped){
reworked.cmd.valid := True
reworked.cmd.payload.assignFrom(old.address)
wrapConsumers(typo, old, reworked.rsp)
}
Expand Down
70 changes: 43 additions & 27 deletions src/main/scala/naxriscv/misc/RegFilePlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,10 @@ case class RegFileWriteParameter(withReady : Boolean)
case class RegFileIo( addressWidth: Int,
dataWidth: Int,
readsParameter: Seq[RegFileReadParameter],
writesParameter: Seq[RegFileWriteParameter],
bypasseCount: Int
writesParameter: Seq[RegFileWriteParameter]
) extends Bundle{
val writes = Vec(writesParameter.map(p => slave(RegFileWrite(addressWidth, dataWidth, p.withReady))))
val reads = Vec(readsParameter.map(p => slave(RegFileRead(addressWidth, dataWidth, p.withReady, 0, p.forceNoBypass))))
val bypasses = Vec.fill(bypasseCount)(slave(RegFileBypass(addressWidth, dataWidth)))
}

//The bankCount is currently useless, but maybe uesefull in the future with execution units which can stall
Expand All @@ -35,14 +33,13 @@ class RegFileAsync(addressWidth : Int,
bankCount : Int,
readsParameter : Seq[RegFileReadParameter],
writesParameter : Seq[RegFileWriteParameter],
bypasseCount : Int,
preferedWritePortForInit : Int,
headZero : Boolean,
allOne : Boolean,
asyncReadBySyncReadRevertedClk : Boolean = false) extends Component {
assert(!(allOne && headZero))

val io = RegFileIo(addressWidth, dataWidth, readsParameter, writesParameter, bypasseCount)
val io = RegFileIo(addressWidth, dataWidth, readsParameter, writesParameter)

val bankShift = log2Up(bankCount)
val writePortCount = io.writes.count(!_.withReady)
Expand Down Expand Up @@ -72,14 +69,6 @@ class RegFileAsync(addressWidth : Int,
port.address := r.address >> bankShift
r.data := port.data
}

val bypass = (!r.forceNoBypass && bypasseCount != 0) generate new Area{
val hits = io.bypasses.map(b => b.valid && b.address === r.address)
val hitsValue = MuxOH.mux(hits, io.bypasses.map(_.data))
when(hits.orR){
r.data := hitsValue
}
}
}

val initPort = banks.head.writePort(preferedWritePortForInit)
Expand Down Expand Up @@ -118,7 +107,6 @@ object RegFileAsyncSynth extends App{
bankCount = 1,
readsParameter = Seq.fill(4)(RegFileReadParameter(withReady = false, forceNoBypass = false)),
writesParameter = Seq.fill(1)(RegFileWriteParameter(withReady = false)),
bypasseCount = 0,
preferedWritePortForInit = 0,
headZero = true,
allOne = false
Expand All @@ -141,19 +129,23 @@ Artix 7 -> 375 Mhz 176 LUT 585 FF
Artix 7 -> 538 Mhz 176 LUT 585 FF
*/
class sky130_fd_sc_hd__dlxtp_1 extends BlackBox {
val Q = out Bool()
val D = in Bool()
val GATE = in Bool()
}

class RegFileLatch(addressWidth : Int,
dataWidth : Int,
readsParameter : Seq[RegFileReadParameter],
writesParameter : Seq[RegFileWriteParameter],
bypasseCount : Int,
headZero : Boolean) extends Component {
val io = RegFileIo(addressWidth, dataWidth, readsParameter, writesParameter, bypasseCount)
val io = RegFileIo(addressWidth, dataWidth, readsParameter, writesParameter)

io.reads.foreach(e => assert(!e.withReady))
io.writes.foreach(e => assert(!e.withReady))


val writeFrontend = new Area {
@dontName val clock = ClockDomain.current.readClockWire
val buffers = for (port <- io.writes) yield LatchWhen(port.data, clock)
Expand All @@ -169,22 +161,32 @@ class RegFileLatch(addressWidth : Int,
// val validReg = RegNext(mask.orR)
val data = OhMux.or(maskReg, writeFrontend.buffers)
}

// val storages = Array.fill(dataWidth)(new sky130_fd_sc_hd__dlxtp_1)
// val GATE = !writeFrontend.clock && write.validReg
// for((s, i) <- storages.zipWithIndex){
// s.D := write.data(i)
// s.GATE := GATE
// }
// val storage = storages.map(_.Q).toSeq.asBits

val storage = LatchWhen(write.data, !writeFrontend.clock && write.validReg)
}


val readLogic = for ((r, i) <- io.reads.zipWithIndex) yield new Area {
var mem = latches.map(_.storage).toList
if(headZero) mem = B(0, dataWidth bits) :: mem
r.data := mem.read(r.address)

val bypass = (!r.forceNoBypass && bypasseCount != 0) generate new Area {
val hits = io.bypasses.map(b => b.valid && b.address === r.address)
val hitsValue = MuxOH.or(hits, io.bypasses.map(_.data))
when(hits.orR) {
r.data := hitsValue
}
val oh = UIntToOh(r.address)
val tri = Analog(Bits(dataWidth bits))
mem.onMask(oh){ value =>
tri := value
}
r.data := tri


// r.data := mem.read(r.address)
}
}

Expand Down Expand Up @@ -286,7 +288,6 @@ class RegFilePlugin(var spec : RegfileSpec,
bankCount = bankCount,
readsParameter = reads.map(e => RegFileReadParameter(withReady = e.withReady, e.forceNoBypass)),
writesParameter = writeMerges.map(e => RegFileWriteParameter(withReady = false)).toList,
bypasseCount = bypasses.size,
headZero = spec.x0AlwaysZero,
preferedWritePortForInit = writeGroups.zipWithIndex.find(_._1._2.exists(_.port.getName().contains(preferedWritePortForInit))).get._2,
allOne = allOne,
Expand All @@ -298,7 +299,6 @@ class RegFilePlugin(var spec : RegfileSpec,
dataWidth = dataWidth,
readsParameter = reads.map(e => RegFileReadParameter(withReady = e.withReady, e.forceNoBypass)),
writesParameter = writeMerges.map(e => RegFileWriteParameter(withReady = false)).toList,
bypasseCount = bypasses.size,
headZero = spec.x0AlwaysZero
)

Expand All @@ -312,7 +312,16 @@ class RegFilePlugin(var spec : RegfileSpec,

(regfile.io.reads, reads).zipped.foreach(_ <> _)
(regfile.io.writes, writeMerges.map(_.bus)).zipped.foreach(_ <> _)
(regfile.io.bypasses, bypasses).zipped.foreach(_ <> _)
val bypass = for(i <- 0 until regfile.io.readsParameter.size) {
val r = reads(i)
if(!r.forceNoBypass && bypasses.size != 0){
val hits = bypasses.map(b => b.valid && b.address === r.address)
val hitsValue = MuxOH.mux(hits, bypasses.map(_.data))
when(hits.orR) {
r.data := hitsValue
}
}
}

//Used for tracing in verilator sim
val writeEvents = Vec(writeMerges.map(e => CombInit(e.bus)))
Expand All @@ -321,4 +330,11 @@ class RegFilePlugin(var spec : RegfileSpec,
doc.property(writeEvents.getName() +"_count", writeEvents.size)
doc.property(spec.getName() +"_PHYSICAL_DEPTH", physicalDepth)
}
}


object LatchRegFilePlacer extends App{

// latches_17_storages_24 585.12 848.64
// latches_17_storages_25 585.58 848.64
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@ import spinal.core._
import spinal.lib._
import spinal.lib.eda.bench.Rtl

object test_c extends App{
object NaxAsicGen extends App{
var target = "asic"

assert(new scopt.OptionParser[Unit]("NaxAsicGen") {
help("help").text("prints this usage text")
opt[Unit]("sky130") action { (v, c) => target = "sky130" }
}.parse(args, Unit).nonEmpty)


LutInputs.set(4)
def plugins = {
val l = Config.plugins(
Expand Down Expand Up @@ -41,24 +49,24 @@ object test_c extends App{
l.foreach{
case p : EmbeddedJtagPlugin => p.debugCd.load(ClockDomain.current.copy(reset = Bool().setName("debug_reset")))

// case p: FetchCachePlugin => p.wayCount = 2; p.cacheSize = 4096; p.memDataWidth = 64
// case p: DataCachePlugin => p.wayCount = 2; p.cacheSize = 4096; p.memDataWidth = 64
// case p: BtbPlugin => p.entries = 64
// case p: GSharePlugin => p.memBytes = 512
case p: FetchCachePlugin => p.wayCount = 2; p.cacheSize = 4096; p.memDataWidth = 64
case p: DataCachePlugin => p.wayCount = 2; p.cacheSize = 4096; p.memDataWidth = 64
case p: BtbPlugin => p.entries = 64
case p: GSharePlugin => p.memBytes = 512

case p: FetchCachePlugin => p.wayCount = 1; p.cacheSize = 256; p.memDataWidth = 64
case p: DataCachePlugin => p.wayCount = 1; p.cacheSize = 256; p.memDataWidth = 64
case p: BtbPlugin => p.entries = 8
case p: GSharePlugin => p.memBytes = 32
// case p: FetchCachePlugin => p.wayCount = 1; p.cacheSize = 256; p.memDataWidth = 64
// case p: DataCachePlugin => p.wayCount = 1; p.cacheSize = 256; p.memDataWidth = 64
// case p: BtbPlugin => p.entries = 8
// case p: GSharePlugin => p.memBytes = 32
case _ =>
}
l
}

val spinalConfig = SpinalConfig()
// val spinalConfig = SpinalSky130()
//spinalConfig.addTransformationPhase(new MultiPortWritesSymplifier)
// spinalConfig.addStandardMemBlackboxing(blackboxAllWhatsYouCan)
var spinalConfig = target match {
case "asic" => SpinalConfig()
case "sky130" => SpinalSky130()
}

spinalConfig.generateVerilog(new NaxRiscv(plugins).setDefinitionName("nax"))

Expand Down
2 changes: 2 additions & 0 deletions src/main/scala/naxriscv/platform/asic/Sky130.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

package naxriscv.platform.asic
import naxriscv.compatibility.MultiPortWritesSymplifier
import spinal.core._
import spinal.core.internals.{MemTopology, PhaseContext, PhaseMemBlackBoxingWithPolicy, PhaseNetlist}
import spinal.lib._
Expand All @@ -15,6 +16,7 @@ object SpinalSky130{
}
def apply() = {
val c = SpinalConfig(mode = Verilog)
c.addTransformationPhase(new MultiPortWritesSymplifier)
c.addStandardMemBlackboxing(blackboxPolicy)
c.phasesInserters += { phases =>
val i = phases.lastIndexWhere(_.isInstanceOf[PhaseMemBlackBoxingWithPolicy])
Expand Down
3 changes: 1 addition & 2 deletions src/main/scala/naxriscv/platform/asic/test_rf.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@ object TestRfGen extends App {
dataWidth = 2,
readsParameter = List.fill(1)(RegFileReadParameter(false, false)),
writesParameter = List.fill(1)(RegFileWriteParameter(false)),
bypasseCount = 0,
headZero = false
).setDefinitionName("top")
).setDefinitionName("rf")
}
}
}
2 changes: 1 addition & 1 deletion src/main/scala/naxriscv/platform/tilelinkdemo/SocSim.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ object SocSim extends App {

val sc = SimConfig
sc.normalOptimisation
sc.withIVerilog
// sc.withIVerilog
// sc.withFstWave
sc.withConfig(SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = ASYNC)).includeSimulation)
// sc.addSimulatorFlag("--threads 1")
Expand Down

0 comments on commit 942825a

Please sign in to comment.