Skip to content

Instantly share code, notes, and snippets.

@amsharifian
Created February 6, 2019 08:40
Show Gist options
  • Save amsharifian/bf5dd831f27d2bc7bcbce328c798978e to your computer and use it in GitHub Desktop.
Save amsharifian/bf5dd831f27d2bc7bcbce328c798978e to your computer and use it in GitHub Desktop.
Epic code example:
class BasicBlockNoMaskFastNode(BID: Int, val NumInputs: Int = 1, val NumOuts: Int)
(implicit val p: Parameters,
name: sourcecode.Name,
file: sourcecode.File)
extends Module with CoreParams with UniformPrintfs {
val io = IO(new BasicBlockNoMaskFastVecIO(NumInputs, NumOuts)(p))
// Printf debugging
val node_name = name.value
val module_name = file.value.split("/").tail.last.split("\\.").head.capitalize
val (cycleCount, _) = Counter(true.B, 32 * 1024)
override val printfSigil = "[" + module_name + "] " + node_name + ": " + BID + " "
// Defining IO latches
// Data Inputs
val in_data_R = RegInit(VecInit(Seq.fill(NumInputs)(DataBundle.default)))
val in_data_valid_R = RegInit(VecInit(Seq.fill(NumInputs)(false.B)))
val output_R = RegInit(ControlBundle.default)
val output_valid_R = Seq.fill(NumOuts)(RegInit(false.B))
val output_fire_R = Seq.fill(NumOuts)(RegInit(false.B))
//Make sure whenever output is fired we latch it
for (i <- 0 until NumInputs) {
io.predicateIn(i).ready := ~in_data_valid_R(i)
when(io.predicateIn(i).fire) {
//Make sure that we only pick predicated values!
in_data_R(i) <> io.predicateIn(i).bits
in_data_valid_R(i) := true.B
}
}
for (i <- 0 until NumOuts) {
when(io.Out(i).fire()) {
output_fire_R(i) := true.B
output_valid_R(i) := false.B
}
}
//Connecting output signals
(io.Out.map(_.valid) zip output_valid_R) foreach {
case (a, b) => a := b
}
io.Out.map(_.bits) foreach (_ := output_R)
//Check whether any input is fired
val fire_input_mask = VecInit(Seq.fill(NumInputs)(false.B))
(fire_input_mask zip io.predicateIn.map(_.fire)) foreach {
case (a, b) => a := b
}
io.predicateIn.foreach(_.ready := false.B)
val ziped_predicate = for (i <- 0 until NumInputs) yield {
i.U -> io.predicateIn(i).bits
}
val output_value = MuxLookup(
OHToUInt(fire_input_mask.asUInt()), io.predicateIn(0).bits, ziped_predicate)
val out_fire_mask = ((output_fire_R zip io.Out.map(_.fire)) map {
case (a, b) => a | b
}) reduce (_ & _)
val s_idle :: s_fire :: Nil = Enum(2)
val state = RegInit(s_idle)
switch(state) {
is(s_idle) {
io.predicateIn.foreach(_.ready := true.B)
when(fire_input_mask.reduce(_ | _)) {
io.Out.map(_.valid) foreach {_ := true.B}
io.Out.map(_.bits) foreach (_ := output_value)
output_valid_R.foreach(_ := true.B)
output_R <> output_value
state := s_fire
if (log) {
printf("[LOG] " + "[" + module_name + "] [TID->%d] "
+ node_name + ": Output [T] fired @ %d\n", output_R.taskID, cycleCount)
}
}
}
is(s_fire) {
io.Out.map(_.bits) foreach (_ := output_R)
when(out_fire_mask) {
output_fire_R foreach (_ := false.B)
state := s_idle
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment