Skip to content

Commit

Permalink
[MIDAS] Merge pull request ucb-bar#6 from ucb-bar/midas_integration
Browse files Browse the repository at this point in the history
Midas integration
  • Loading branch information
donggyukim committed Oct 3, 2016
2 parents 63bc9b3 + 4256c38 commit 3be463f
Show file tree
Hide file tree
Showing 11 changed files with 818 additions and 251 deletions.
3 changes: 0 additions & 3 deletions csrc/simif.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,6 @@ class simif_t
void init();
void finish();
inline uint64_t cycles() { return t; }
inline void set_latency(size_t cycles) {
poke_channel(LATENCY_ADDR, cycles);
}
inline void set_tracelen(size_t len) {
assert(len > 2);
trace_len = len;
Expand Down
38 changes: 19 additions & 19 deletions src/main/scala/compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ private class StroberCompilerContext {
val shims = ArrayBuffer[ZynqShim[_]]()
// Todo: Should be handled in the backend
val memPorts = ArrayBuffer[junctions.NastiIO]()
val memWires = HashSet[Chisel.Bits]()
val memWires = HashSet[chisel3.Bits]()
}

private class StroberCompiler extends firrtl.Compiler {
Expand Down Expand Up @@ -75,30 +75,30 @@ object StroberCompiler {
implicit val channelWidth = sim.channelWidth
def dump(arg: (String, Int)) = s"#define ${arg._1} ${arg._2}\n"
val consts = List(
"HOST_RESET_ADDR" -> ZynqCtrlSignals.HOST_RESET.id,
"SIM_RESET_ADDR" -> ZynqCtrlSignals.SIM_RESET.id,
"STEP_ADDR" -> ZynqCtrlSignals.STEP.id,
"DONE_ADDR" -> ZynqCtrlSignals.DONE.id,
"TRACELEN_ADDR" -> ZynqCtrlSignals.TRACELEN.id,
"LATENCY_ADDR" -> ZynqCtrlSignals.LATENCY.id,
"MEM_AR_ADDR" -> c.AR_ADDR,
"MEM_AW_ADDR" -> c.AW_ADDR,
"MEM_W_ADDR" -> c.W_ADDR,
"MEM_R_ADDR" -> c.R_ADDR,
"CTRL_NUM" -> c.CTRL_NUM,
"CTRL_NUM" -> c.CTRL_NUM,
"DAISY_WIDTH" -> (c.sim match { case sim: SimWrapper[_] => sim.daisyWidth }),
"POKE_SIZE" -> c.ins.size,
"PEEK_SIZE" -> c.outs.size,
"MEM_DATA_BITS" -> c.arb.nastiXDataBits,
"TRACE_MAX_LEN" -> sim.traceMaxLen,
"MEM_DATA_CHUNK" -> SimUtils.getChunks(c.io.slave.w.bits.data),

"HOST_RESET_ADDR" -> ZynqCtrlSignals.HOST_RESET.id,
"SIM_RESET_ADDR" -> ZynqCtrlSignals.SIM_RESET.id,
"STEP_ADDR" -> ZynqCtrlSignals.STEP.id,
"DONE_ADDR" -> ZynqCtrlSignals.DONE.id,
"TRACELEN_ADDR" -> ZynqCtrlSignals.TRACELEN.id,
"SRAM_RESTART_ADDR" -> c.SRAM_RESTART_ADDR,
"DAISY_WIDTH" -> (c.sim match { case sim: SimWrapper[_] => sim.daisyWidth }),
"POKE_SIZE" -> c.ins.size,
"PEEK_SIZE" -> c.outs.size,
"MEM_DATA_BITS" -> c.arb.nastiXDataBits,
"TRACE_MAX_LEN" -> sim.traceMaxLen,
"MEM_DATA_CHUNK" -> SimUtils.getChunks(c.io.slave.w.bits.data)
"MEM_AR_ADDR" -> c.AR_ADDR,
"MEM_AW_ADDR" -> c.AW_ADDR,
"MEM_W_ADDR" -> c.W_ADDR,
"MEM_R_ADDR" -> c.R_ADDR
)
val sb = new StringBuilder
sb append "#ifndef __%s_H\n".format(targetName.toUpperCase)
sb append "#define __%s_H\n".format(targetName.toUpperCase)
consts foreach (sb append dump(_))
val chainTypes =
c.genHeader(sb)
sb append "enum CHAIN_TYPE {%s,CHAIN_NUM};\n".format(
ChainType.values.toList map (t => s"${t.toString.toUpperCase}_CHAIN") mkString ",")
sb append "const unsigned CHAIN_SIZE[CHAIN_NUM] = {%s};\n".format(
Expand Down
3 changes: 2 additions & 1 deletion src/main/scala/daisy.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package strober

import Chisel._
import chisel3._
import chisel3.util._
import cde.{Parameters, Field}
import scala.collection.mutable.HashMap

Expand Down
97 changes: 0 additions & 97 deletions src/main/scala/mem.scala

This file was deleted.

17 changes: 12 additions & 5 deletions src/main/scala/testers/ZynqShimTester.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package strober
package testers

import junctions._
import midas_widgets._
import scala.collection.mutable.{HashMap, ArrayBuffer, Queue => ScalaQueue}
import java.io.{File, InputStream}

Expand All @@ -26,7 +27,7 @@ abstract class ZynqShimTester[+T <: SimNetwork](
private val MAXI_aw = new ChannelSource(c.io.master.aw, (aw: NastiWriteAddressChannel, in: NastiWriteAddr) =>
{ _poke(aw.id, in.id) ; _poke(aw.addr, in.addr) })
private val MAXI_w = new ChannelSource(c.io.master.w, (w: NastiWriteDataChannel, in: NastiWriteData) =>
{ _poke(w.data, in.data) })
{ _poke(w.data, in.data) ; _poke(w.last, in.last) ; _poke(w.strb, (BigInt(1) << w.nastiWStrobeBits) - 1) })
private val MAXI_b = new ChannelSink(c.io.master.b, (b: NastiWriteResponseChannel) =>
new NastiWriteResp(_peek(b.id), _peek(b.resp)))
private val MAXI_ar = new ChannelSource(c.io.master.ar, (ar: NastiReadAddressChannel, in: NastiReadAddr) =>
Expand Down Expand Up @@ -54,15 +55,21 @@ abstract class ZynqShimTester[+T <: SimNetwork](
pokeChannel(ZynqCtrlSignals.TRACELEN.id, len)
}

def setMemLatency(cycles: Int) {
pokeChannel(ZynqCtrlSignals.LATENCY.id, cycles)
def writeCR(w: Widget, crName: String, value: BigInt){
val addr = c.getCRAddr(w, crName)
pokeChannel(addr, value)
}

def readCR(w: Widget, crName: String) = {
val addr = c.getCRAddr(w, crName)
peekChannel(addr)
}

override def reset(n: Int) {
for (_ <- 0 until n) {
pokeChannel(ZynqCtrlSignals.HOST_RESET.id, 0)
pokeChannel(ZynqCtrlSignals.SIM_RESET.id, 0)
Predef.assert(_eventually(peekChannel(ZynqCtrlSignals.DONE.id)),
Predef.assert(_eventually(peekChannel(ZynqCtrlSignals.DONE.id) == BigInt(1)),
"simulation is not done in time")
_peekMap.clear
// flush junk output tokens
Expand All @@ -79,7 +86,7 @@ abstract class ZynqShimTester[+T <: SimNetwork](
c.IN_ADDRS foreach {case (in, addr) =>
pokeChunks(addr, SimUtils.getChunks(in), _pokeMap getOrElse (in, BigInt(rnd.nextInt)))
}
Predef.assert(_eventually(peekChannel(ZynqCtrlSignals.DONE.id)),
Predef.assert(_eventually(peekChannel(ZynqCtrlSignals.DONE.id) == BigInt(1)),
"simulation is not done in time")
c.OUT_ADDRS foreach {case (out, addr) =>
_peekMap(out) = peekChunks(addr, SimUtils.getChunks(out))
Expand Down
20 changes: 18 additions & 2 deletions src/main/scala/util.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package strober

import Chisel._
import chisel3._
import chisel3.util._
import junctions.NastiIO
import scala.collection.immutable.ListMap
import scala.collection.mutable.ArrayBuffer
Expand Down Expand Up @@ -55,7 +56,7 @@ object SimUtils {
val channels = inChannels slice (off, off + getChunks(wire))
val channelOuts = wire match {
case _: Bool => channels.head.io.out.bits.toBool
case _ => Vec(channels map (_.io.out.bits)).toBits
case _ => Cat(channels map (_.io.out.bits))
}
val buffer = RegEnable(channelOuts, fire)
buffer suggestName (name + "_buffer")
Expand All @@ -72,3 +73,18 @@ object SimUtils {
off + getChunks(wire)
}
}

object SimMemIO {
def add(mem: NastiIO) {
val (ins, outs) = SimUtils.parsePorts(mem)
StroberCompiler.context.memWires ++= ins.unzip._1
StroberCompiler.context.memWires ++= outs.unzip._1
StroberCompiler.context.memPorts += mem
}
def apply(i: Int): NastiIO = StroberCompiler.context.memPorts(i)
def apply(wire: Bits) = StroberCompiler.context.memWires(wire)
def apply(mem: NastiIO) = StroberCompiler.context.memPorts contains mem
def zipWithIndex = StroberCompiler.context.memPorts.toList.zipWithIndex
def size = StroberCompiler.context.memPorts.size
}

79 changes: 79 additions & 0 deletions src/main/scala/widgets/Interfaces.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package midas_widgets

import chisel3._

// Adapted from DecoupledIO in Chisel3
class HostDecoupledIO[+T <: Data](gen: T) extends Bundle
{
val hReady = Bool(INPUT)
val hValid = Bool(OUTPUT)
val hBits = gen.cloneType
def fire(dummy: Int = 0): Bool = hReady && hValid
override def cloneType: this.type =
new HostDecoupledIO(gen).asInstanceOf[this.type]
}

/** Adds a ready-valid handshaking protocol to any interface.
* The standard used is that the consumer uses the flipped interface.
*/
object HostDecoupled {
def apply[T <: Data](gen: T): HostDecoupledIO[T] = new HostDecoupledIO(gen)
}


class HostReadyValid extends Bundle {
val hReady= Bool(INPUT)
val hValid = Bool(OUTPUT)
def fire(dummy: Int = 0): Bool = hReady && hValid
}

/**
* Hack: A note on tokenFlip:
* Previously we had difficulties generating hostPortIOs with flipped
* aggregates of aggregates. We thus had to manually flip the subfields of the
* aggregate in a new class (ex. the FlipNastiIO). tokenFlip captures
* whether hBits should be flipped when it is cloned.
*
* thus what would ideally be expressed as HostPort(Flipped(new NastiIO)) must
* be expressed as HostPort((new NastiIO), tokenFlip = true)
*/

class HostPortIO[+T <: Data](gen: T, tokenFlip: Boolean) extends Bundle
{
val fromHost = Flipped(new HostReadyValid)
val toHost = new HostReadyValid
val hBits = if (tokenFlip) Flipped(gen.cloneType) else gen cloneType
override def cloneType: this.type =
new HostPortIO(gen, tokenFlip).asInstanceOf[this.type]
}

object HostPort {
def apply[T <: Data](gen: T, tokenFlip : Boolean = false): HostPortIO[T] = new HostPortIO(gen, tokenFlip)
}


// The below is currently used to generate FIRRTL code for buildSimQueue
// TODO
// - Actually use this code in buildSimQueue instead of one off FIRRTL
// - This requires either a change to Bundle API (and possible others)
// or using Scala macros (see quasiquotes)

/** An I/O Bundle with simple handshaking using valid and ready signals for
* data 'bits'
*/
class MidasDecoupledIO[+T <: Data](gen: T) extends Bundle
{
val hReady = Bool(INPUT)
val hValid = Bool(OUTPUT)
val hBits = gen.cloneType.asOutput
def fire(dummy: Int = 0): Bool = hReady && hValid
override def cloneType: this.type =
new MidasDecoupledIO(gen).asInstanceOf[this.type]
}

/** Adds a hReady-hValid handshaking protocol to any interface.
* The standard used is that the consumer uses the flipped interface.
*/
object MidasDecoupled {
def apply[T <: Data](gen: T): MidasDecoupledIO[T] = new MidasDecoupledIO(gen)
}
Loading

0 comments on commit 3be463f

Please sign in to comment.