Description
Currently, StaticLogicToCalyx
will explicitly emit the set of group activations required for the prologue and epilogue of a pipeline. E.g., a pipeline with 4 stages will emit a schedule such as (excluding the group that evaluates pipeline continuation %cont
):
calyx.control {
calyx.seq {
calyx.par {
calyx.enable @stage0
}
calyx.par {
calyx.enable @stage0
calyx.enable @stage1
}
calyx.par {
calyx.enable @stage0
calyx.enable @stage1
calyx.enable @stage2
}
calyx.while %cont {
calyx.par {
calyx.enable @stage0
calyx.enable @stage1
calyx.enable @stage2
calyx.enable @stage3
}
}
calyx.par {
calyx.enable @stage1
calyx.enable @stage2
calyx.enable @stage3
}
calyx.par {
calyx.enable @stage2
calyx.enable @stage3
}
calyx.par {
calyx.enable @stage3
}
}
}
One alternative to this is to employ rotating predicate registers, known from e.g. software pipelining.
In this model, the execution of each stage is predicated by a bit in a predicate register. Every cycle while the pipeline runs, a new '1' is rotated into the predicate register. Once the pipeline no longer continues (epilogue), '0's are shifted into the predicate register.
This could be integrated by guarding group enablement with the predicate in the control schedule using an if
statement:
%r_pred.in, %r_pred.write_en, %r_pred.clk, %r_pred.reset, %r_pred.out, %r_pred.done = calyx.register @r_pred : i4, i1, i1, i1, i4, i1
calyx.group @update_pred {
// Shift pipeline continuation state into predicate register
calyx.assign %r_pred.in = {%r_pred.out[2:0], %cont} : i4
calyx.assign %r_pred.write_en = %true : i1
}
calyx.control {
calyx.seq {
calyx.while %cont {
calyx.par {
calyx.if %r_pred.out[0] { calyx.enable @stage0 }
calyx.if %r_pred.out[1] { calyx.enable @stage1 }
calyx.if %r_pred.out[2] { calyx.enable @stage2 }
calyx.if %r_pred.out[3] { calyx.enable @stage3 }
calyx.enable @update_pred
}
}
}
}