[MIDAS] wide daisychain whose width is a divisor of buswidth

This commit is contained in:
Donggyu Kim 2014-10-07 17:15:14 -07:00
parent 6b370ae6b3
commit 2ba6705ab0
5 changed files with 66 additions and 41 deletions

View File

@ -17,12 +17,6 @@ v : $(addsuffix Wrapper.v, $(designs))
%Wrapper.v: %.scala %Wrapper.v: %.scala
sbt "run $(basename $@) $(V_FLAGS)" | tee $@.out sbt "run $(basename $@) $(V_FLAGS)" | tee $@.out
%.v: %.scala
sbt "run $(basename $@) $(V_FLAGS)" | tee $@.out
%.cpp: %.scala
sbt "run $(basename $@) $(C_FLAGS)" | tee $@.out
clean: clean:
rm -rf $(gendir) *.out rm -rf $(gendir) *.out

View File

@ -101,7 +101,7 @@ object DaisyBackend {
def insertStateChain(m: Module) = { def insertStateChain(m: Module) = {
val datawidth = (states(m) foldLeft 0)(_ + _.needWidth) val datawidth = (states(m) foldLeft 0)(_ + _.needWidth)
val chain = if (!states(m).isEmpty) m.addModule(new StateChain(datawidth)) else null val chain = if (!states(m).isEmpty) m.addModule(new StateChain(datawidth, daisywidth)) else null
if (chain != null) { if (chain != null) {
if (m.name != top.name) insertStatePins(m) if (m.name != top.name) insertStatePins(m)
chain.io.data := UInt(Concatenate(states(m))) chain.io.data := UInt(Concatenate(states(m)))
@ -161,7 +161,7 @@ object DaisyBackend {
for (sram <- srams(m)) { for (sram <- srams(m)) {
val read = sram.readAccesses.head val read = sram.readAccesses.head
val datawidth = sram.needWidth val datawidth = sram.needWidth
val chain = m.addModule(new SRAMChain(sram.size, datawidth)) val chain = m.addModule(new SRAMChain(sram.size, datawidth, daisywidth))
chain.io.data := UInt(read) chain.io.data := UInt(read)
chain.io.stall := stallPins(m) chain.io.stall := stallPins(m)
if (lastChain == null) { if (lastChain == null) {
@ -240,8 +240,10 @@ object DaisyBackend {
val chainFile = Driver.createOutputFile(targetName + ".chain.map") val chainFile = Driver.createOutputFile(targetName + ".chain.map")
// Collect states // Collect states
var stateWidth = 0 var stateWidth = 0
var totalWidth = top.buswidth var totalWidth = 0
for (m <- Driver.sortedComps.reverse ; if m.name != top.name) { for (m <- Driver.sortedComps.reverse ; if m.name != top.name) {
var daisyWidth = 0
var thisWidth = 0
for (state <- states(m)) { for (state <- states(m)) {
state match { state match {
case read: MemRead => { case read: MemRead => {
@ -251,30 +253,44 @@ object DaisyBackend {
val width = mem.needWidth val width = mem.needWidth
res append "%s[%d] %d\n".format(path, addr, width) res append "%s[%d] %d\n".format(path, addr, width)
stateWidth += width stateWidth += width
if (totalWidth < stateWidth) totalWidth += top.buswidth thisWidth += width
while (totalWidth < stateWidth) totalWidth += top.buswidth
while (daisyWidth < thisWidth) daisyWidth += top.daisywidth
} }
case _ => { case _ => {
val path = targetName + "." + (m.getPathName(".") stripPrefix prefix) + state.name val path = targetName + "." + (m.getPathName(".") stripPrefix prefix) + state.name
val width = state.needWidth val width = state.needWidth
res append "%s %d\n".format(path, width) res append "%s %d\n".format(path, width)
stateWidth += width stateWidth += width
if (totalWidth < stateWidth) totalWidth += top.buswidth while (totalWidth < stateWidth) totalWidth += top.buswidth
while (daisyWidth < thisWidth) daisyWidth += top.daisywidth
} }
} }
} }
val daisyPadWidth = daisyWidth - thisWidth
if (daisyPadWidth > 0) {
res append "null %d\n".format(daisyPadWidth)
}
} }
val padWidth = totalWidth - stateWidth val totalPadWidth = totalWidth - stateWidth
if (padWidth > 0) { if (totalPadWidth > 0) {
res append "null %d\n".format(padWidth) res append "null %d\n".format(totalPadWidth)
} }
for (i <- 0 until Driver.sramMaxSize ; m <- Driver.sortedComps.reverse ; if m.name != top.name) { for (i <- 0 until Driver.sramMaxSize ; m <- Driver.sortedComps.reverse ; if m.name != top.name) {
for (sram <- srams(m)) { for (sram <- srams(m)) {
val path = targetName + "." + (m.getPathName(".") stripPrefix prefix) + sram.name val path = targetName + "." + (m.getPathName(".") stripPrefix prefix) + sram.name
val width = sram.needWidth
var daisyWidth = 0
if (i < sram.n) if (i < sram.n)
res append "%s[%d] %d\n".format(path, i, sram.needWidth) res append "%s[%d] %d\n".format(path, i, width)
else else
res append "null %d\n".format(sram.needWidth) res append "null %d\n".format(width)
while (daisyWidth < width) daisyWidth += top.daisywidth
val daisyPadWidth = daisyWidth - width
if (daisyPadWidth > 0) {
res append "null %d\n".format(daisyPadWidth)
}
} }
} }
try { try {

View File

@ -9,21 +9,28 @@ abstract class DaisyChainIO(datawidth: Int, daisywidth: Int) extends Bundle {
val out = Decoupled(UInt(INPUT, daisywidth)) val out = Decoupled(UInt(INPUT, daisywidth))
} }
abstract class DaisyChain(datawidth: Int, daisywidth: Int = 1) extends Module { abstract class DaisyChain(datawidth: Int, daisywidth: Int) extends Module {
val regs = Vec.fill(datawidth) { Reg(UInt(width=daisywidth)) }
def io: DaisyChainIO def io: DaisyChainIO
val counter = Reg(UInt(width=log2Up(datawidth+1)))
def copyCond: Bool def copyCond: Bool
def readCond: Bool def readCond: Bool
val daisylen = (datawidth - 1) / daisywidth + 1
val regs = Vec.fill(daisylen) { Reg(UInt(width=daisywidth)) }
val counter = Reg(UInt(width=log2Up(daisylen+1)))
def initChain(fake: Int = 0) { def initChain(fake: Int = 0) {
// Daisy chain datapath // Daisy chain datapath
io.out.bits := regs(datawidth-1) io.out.bits := regs(daisylen-1)
io.out.valid := counter.orR && io.out.ready io.out.valid := counter.orR // && io.out.ready
io.in.ready := io.out.ready io.in.ready := io.out.ready
for (i <- 0 until datawidth) { var high = datawidth-1
for (i <- (0 until daisylen).reverse) {
val low = math.max(high-daisywidth+1, 0)
val padwidth = daisywidth-(high-low+1)
when(copyCond) { when(copyCond) {
regs(i) := io.data(i) if (padwidth > 0)
regs(i) := Cat(io.data(high, low), UInt(0, padwidth))
else
regs(i) := io.data(high, low)
} }
when(readCond && counter.orR && io.out.fire()) { when(readCond && counter.orR && io.out.fire()) {
if (i == 0) if (i == 0)
@ -31,11 +38,12 @@ abstract class DaisyChain(datawidth: Int, daisywidth: Int = 1) extends Module {
else else
regs(i) := regs(i-1) regs(i) := regs(i-1)
} }
high -= daisywidth
} }
// Daisy chain control logic // Daisy chain control logic
when(copyCond) { when(copyCond) {
counter := UInt(datawidth) counter := UInt(daisylen)
} }
when(readCond && counter.orR && io.out.fire() && !io.in.valid) { when(readCond && counter.orR && io.out.fire() && !io.in.valid) {
counter := counter - UInt(1) counter := counter - UInt(1)
@ -55,14 +63,14 @@ class StateChain(datawidth: Int, daisywidth: Int = 1) extends
initChain() initChain()
} }
class SRAMChainIO(n: Int, datawidth: Int, daisywidth: Int = 1) extends class SRAMChainIO(n: Int, datawidth: Int, daisywidth: Int) extends
DaisyChainIO(datawidth, daisywidth) { DaisyChainIO(datawidth, daisywidth) {
val restart = Bool(INPUT) val restart = Bool(INPUT)
val addrIn = UInt(INPUT, width=log2Up(n)) val addrIn = UInt(INPUT, width=log2Up(n))
val addrOut = Valid(UInt(width=log2Up(n))) val addrOut = Valid(UInt(width=log2Up(n)))
} }
class SRAMChain(n: Int, datawidth: Int, daisywidth: Int = 1) extends class SRAMChain(n: Int, datawidth: Int, daisywidth: Int) extends
DaisyChain(datawidth, daisywidth) { DaisyChain(datawidth, daisywidth) {
val io = new SRAMChainIO(n, datawidth, daisywidth) val io = new SRAMChainIO(n, datawidth, daisywidth)

View File

@ -212,7 +212,8 @@ abstract class DaisyTester[+T <: DaisyWrapper[Module]](c: T, isTrace: Boolean =
for (line <- lines) { for (line <- lines) {
val tokens = line split " " val tokens = line split " "
stateNames += tokens.head stateNames += tokens.head
stateWidths += tokens.last.toInt stateWidths += tokens.last.toInt
println("%s %d".format(tokens.head, tokens.last.toInt))
} }
} }

View File

@ -2,7 +2,7 @@ package faee
import Chisel._ import Chisel._
class DaisyWrapperIO[T <: Data](buswidth: Int = 64) extends Bundle { class DaisyWrapperIO[T <: Data](buswidth: Int) extends Bundle {
val hostIn = Decoupled(UInt(width=buswidth)).flip val hostIn = Decoupled(UInt(width=buswidth)).flip
val hostOut = Decoupled(UInt(width=buswidth)) val hostOut = Decoupled(UInt(width=buswidth))
val memIn = Decoupled(UInt(width=buswidth)).flip val memIn = Decoupled(UInt(width=buswidth)).flip
@ -15,7 +15,7 @@ object DaisyWrapper {
class DaisyWrapper[+T <: Module](c: =>T, class DaisyWrapper[+T <: Module](c: =>T,
val buswidth: Int = 64, val buswidth: Int = 64,
val daisywidth: Int = 1, val daisywidth: Int = 3,
val opwidth: Int = 6) extends Module { val opwidth: Int = 6) extends Module {
val io = new DaisyWrapperIO(buswidth) val io = new DaisyWrapperIO(buswidth)
val target = Module(c) val target = Module(c)
@ -48,9 +48,10 @@ class DaisyWrapper[+T <: Module](c: =>T,
val PEEK = UInt(2, opwidth) val PEEK = UInt(2, opwidth)
// Counters for snapshotting // Counters for snapshotting
val snapBuffer = Reg(UInt(width=buswidth)) val snapBuffer = Reg(UInt(width=buswidth+daisywidth))
val snapCount = Reg(UInt(width=log2Up(buswidth+1))) val snapCount = Reg(UInt(width=log2Up(buswidth+1)))
val snapReady = Reg(Bool()) val snapReady = Reg(Bool())
val snapFinish = Reg(Bool())
val sramRestartCount = if (Driver.hasSRAM) Reg(UInt(width=log2Up(Driver.sramMaxSize+1))) else null val sramRestartCount = if (Driver.hasSRAM) Reg(UInt(width=log2Up(Driver.sramMaxSize+1))) else null
// Connect target IOs with buffers // Connect target IOs with buffers
@ -124,20 +125,22 @@ class DaisyWrapper[+T <: Module](c: =>T,
} }
// Snapshotring inputs and registers // Snapshotring inputs and registers
is(s_SNAP1) { is(s_SNAP1) {
stateOut.ready := Bool(true) stateOut.ready := snapReady
when(!snapReady && stateOut.valid) { when(!snapReady && stateOut.valid) {
snapReady := Bool(true) snapReady := Bool(true)
} }
when(snapCount >= UInt(buswidth-1)) { snapFinish := !stateOut.valid
when(snapCount >= UInt(buswidth)) {
when(io.memOut.ready) { when(io.memOut.ready) {
io.memOut.bits := snapBuffer io.memOut.bits := snapBuffer >> (snapCount - UInt(buswidth))
io.memOut.valid := Bool(true) io.memOut.valid := Bool(true)
snapCount := snapCount - UInt(buswidth-1) snapCount := snapCount - UInt(buswidth-daisywidth)
} }
when(!stateOut.valid) { when(snapFinish || !stateOut.valid && snapCount === UInt(buswidth)){
snapCount := UInt(0)
snapReady := Bool(false)
snapFinish := Bool(false)
if (Driver.hasSRAM) { if (Driver.hasSRAM) {
snapCount := UInt(0)
snapReady := Bool(false)
sramRestart := Bool(true) sramRestart := Bool(true)
state := s_SNAP2 state := s_SNAP2
} else { } else {
@ -152,18 +155,21 @@ class DaisyWrapper[+T <: Module](c: =>T,
// Snapshotring SRAMs // Snapshotring SRAMs
if (Driver.hasSRAM) { if (Driver.hasSRAM) {
is(s_SNAP2) { is(s_SNAP2) {
sramOut.ready := Bool(true) sramOut.ready := snapReady
when(!snapReady && sramOut.valid) { when(!snapReady && sramOut.valid) {
snapReady := Bool(true) snapReady := Bool(true)
} }
when(snapCount >= UInt(buswidth-1)) { snapFinish := !stateOut.valid
when(snapCount >= UInt(buswidth)) {
when(io.memOut.ready) { when(io.memOut.ready) {
io.memOut.bits := snapBuffer io.memOut.bits := snapBuffer
io.memOut.valid := Bool(true) io.memOut.valid := Bool(true)
snapCount := snapCount - UInt(buswidth-1) snapCount := snapCount - UInt(buswidth-daisywidth)
} }
when(!sramOut.valid) { when(snapFinish || !stateOut.valid && snapCount === UInt(buswidth)) {
snapCount := UInt(0)
snapReady := Bool(false) snapReady := Bool(false)
snapFinish := Bool(false)
when(sramRestartCount.orR) { when(sramRestartCount.orR) {
sramRestartCount := sramRestartCount - UInt(1) sramRestartCount := sramRestartCount - UInt(1)
sramRestart := Bool(true) sramRestart := Bool(true)