generated from chipsalliance/chisel-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Shift] Add blocks for barrel shifting, concatenation and position ca…
…pturing.
- Loading branch information
Showing
3 changed files
with
246 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package Rs | ||
|
||
import chisel3._ | ||
import circt.stage.ChiselStage | ||
import chisel3.util._ | ||
|
||
class CapturePositions(c:Config) extends Module { | ||
val io = IO(new Bundle { | ||
val bitPos = Input(new BitPosIf(c.chienRootsPerCycle)) | ||
val errPosIf = Output(Valid(new vecFfsIf(c.T_LEN, c.SYMB_WIDTH))) | ||
}) | ||
|
||
//////////////////////////////// | ||
// Extract position from incomming | ||
// bit vector where bits are asserted | ||
//////////////////////////////// | ||
|
||
val extrPos = Module(new ExtractPositions(c.chienRootsPerCycle, c.T_LEN, 4)) | ||
val numStages = extrPos.numStages | ||
|
||
extrPos.io.in.bits := io.bitPos.pos | ||
extrPos.io.in.valid := io.bitPos.valid | ||
|
||
// Shift last | ||
val lastQ = Reg(Vec(numStages, Bool())) | ||
|
||
lastQ(0) := io.bitPos.last | ||
for(i <- 1 until numStages) { | ||
lastQ(i) := lastQ(i-1) | ||
} | ||
|
||
//////////////////////////////// | ||
// insertVec is used to capture and shift | ||
// valid positions into shift register of | ||
// length T_LEN. | ||
// | ||
// outShift is used to remove bubbles in | ||
// the shift registers since number of | ||
// errors could be less than T_LEN. | ||
//////////////////////////////// | ||
|
||
val insertVec = Module(new InsertVec(new PositionsVld,c.T_LEN, c.T_LEN)) | ||
val baseVec = Reg(Vec(c.T_LEN, new PositionsVld)) | ||
val vecIn = Wire(Vec(c.T_LEN, new PositionsVld)) | ||
val baseCntr = RegInit(UInt(log2Ceil(c.SYMB_NUM).W), 0.U) | ||
|
||
// Final shift | ||
val outShift = Module(new BarrelShifter(new PositionsVld, c.T_LEN)) | ||
val outputVec = Reg(Vec(c.T_LEN, new PositionsVld)) | ||
|
||
class PositionsVld extends Bundle { | ||
val positions = UInt(c.SYMB_WIDTH.W) | ||
val vld = Bool() | ||
} | ||
|
||
insertVec.io.vecIn := vecIn | ||
insertVec.io.baseVec := baseVec | ||
insertVec.io.shiftVal := extrPos.io.outTkeep.map(_.asUInt).reduce(_ +& _) | ||
|
||
outShift.io.vecIn := insertVec.io.vecOut | ||
outShift.io.shiftVal := insertVec.io.vecOut.map(bundle => (!bundle.vld).asUInt).reduce(_ +& _) | ||
|
||
// need to add baseCntr to get a proper position: | ||
when(extrPos.io.outValid) { | ||
when(lastQ(numStages-1)) { | ||
baseCntr := 0.U | ||
baseVec.foreach(x => x := 0.U.asTypeOf(new PositionsVld)) | ||
outputVec := outShift.io.vecOut | ||
//outputVec := outShift.io.vecOut | ||
}.otherwise{ | ||
baseCntr := baseCntr + c.chienRootsPerCycle.U | ||
baseVec := insertVec.io.vecOut | ||
} | ||
} | ||
|
||
for(i <- 0 until c.T_LEN) { | ||
vecIn(i).positions := extrPos.io.positions(i) + baseCntr | ||
vecIn(i).vld := extrPos.io.outTkeep(i) | ||
io.errPosIf.bits.vec(i) := outputVec(i).positions | ||
} | ||
|
||
//io.errPosIf.bits.ffs := Reverse((VecInit(outputVec.map(_.vld))).asUInt) | ||
//io.errPosIf.bits.vec := insertVec.io.vecOut | ||
|
||
io.errPosIf.valid := lastQ(numStages-1) | ||
io.errPosIf.bits.ffs := (VecInit(insertVec.io.vecOut.map(_.vld))).asUInt | ||
io.errPosIf.bits.vec := (VecInit(insertVec.io.vecOut.map(_.positions))) | ||
} | ||
|
||
object GenCapturePositions extends App { | ||
|
||
val projectRoot = System.getProperty("project.root") | ||
|
||
ConfigParser.parse(args) match { | ||
case Some(config) => | ||
JsonHandler.writeToFile(config, "rs.json") | ||
// Get | ||
val rsCfg = RSDecoderConfigs.getConfig(config.N_LEN, config.K_LEN) | ||
val c = Config(config, rsCfg) | ||
ChiselStage.emitSystemVerilogFile(new CapturePositions(c), Array()) | ||
case None => | ||
sys.exit(1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package Rs | ||
|
||
import chisel3._ | ||
import circt.stage.ChiselStage | ||
import chisel3.util._ | ||
|
||
class ExtractPositions(val InWidth: Int, val PosNum: Int, val pipelineInterval: Int) extends Module { | ||
val io = IO(new Bundle { | ||
val in = Input(Valid(UInt(InWidth.W))) | ||
val positions = Output(Vec(PosNum, UInt(log2Ceil(InWidth).W))) | ||
val outTkeep = Output(Vec(PosNum, Bool())) | ||
val outValid = Output(Bool()) | ||
}) | ||
|
||
// Number of pipeline stages required | ||
val numStages = (InWidth + pipelineInterval - 1) / pipelineInterval | ||
|
||
// Convert input to a vector of Bools | ||
val inVec = io.in.bits.asBools | ||
|
||
val prefSumOut = Wire(Vec(InWidth, UInt(log2Ceil(InWidth).W))) | ||
val prefSumVldOut = Wire(Bool()) | ||
|
||
val inOut = Wire(UInt(InWidth.W)) | ||
val inQ = Reg(Vec(numStages, (UInt(InWidth.W)))) | ||
val inVecQ = Reg(Vec(numStages, (Vec(InWidth, Bool())))) | ||
|
||
val prefSumQ = Reg(Vec(numStages, Vec(InWidth, UInt(log2Ceil(InWidth).W)))) | ||
val vldQ = Reg(Vec(numStages, Bool())) | ||
|
||
// Compute prefix sum with pipeline registers | ||
for (stage <- 0 until numStages+1) { | ||
|
||
val prefSumInit = Wire(Vec(InWidth, UInt(log2Ceil(InWidth).W))) | ||
val prefSum = Wire(Vec(InWidth, UInt(log2Ceil(InWidth).W))) | ||
|
||
if(stage == 0) { | ||
prefSumInit := VecInit(inVec.map(b => Mux(b, 1.U, 0.U))) | ||
} else { | ||
prefSumInit := prefSumQ(stage-1) | ||
} | ||
|
||
val startIdx = stage * pipelineInterval | ||
val endIdx = stage * pipelineInterval + pipelineInterval | ||
|
||
prefSum(0) := prefSumInit(0) | ||
|
||
for(pos <- 1 until InWidth) { | ||
if(pos < startIdx) | ||
prefSum(pos) := prefSumInit(pos) | ||
else if(pos < endIdx) | ||
prefSum(pos) := prefSumInit(pos) + prefSum(pos-1) | ||
else | ||
prefSum(pos) := prefSumInit(pos) | ||
} | ||
|
||
if(stage == numStages) { | ||
prefSumOut := prefSum.map(b => b - 1.U) | ||
prefSumVldOut := vldQ(stage-1) | ||
inOut := inQ(stage-1) | ||
} | ||
else { | ||
prefSumQ(stage) := prefSum | ||
if(stage == 0) { | ||
vldQ(stage) := io.in.valid | ||
inQ(stage) := io.in.bits | ||
} | ||
else { | ||
vldQ(stage) := vldQ(stage-1) | ||
inQ(stage) := inQ(stage-1) | ||
} | ||
} | ||
} | ||
|
||
// Initialize outputs | ||
val positionsReg = Reg(Vec(PosNum, UInt(log2Ceil(InWidth).W))) | ||
val outTkeepReg = Reg(Vec(PosNum, Bool())) | ||
val outputOutValid = RegInit(false.B) | ||
|
||
// Default assignments | ||
for (i <- 0 until PosNum) { | ||
positionsReg(i) := 0.U | ||
outTkeepReg(i) := false.B | ||
} | ||
|
||
// Assign positions | ||
for (i <- 0 until InWidth) { | ||
when(inOut.asBools(i) && prefSumOut(i) < PosNum.U) { | ||
val index = prefSumOut(i)(log2Ceil(PosNum)-1, 0) // Truncate prefSumOut(i) to the correct width | ||
positionsReg(index) := i.U | ||
outTkeepReg(index) := true.B | ||
} | ||
} | ||
|
||
// Connect outputs | ||
io.positions := positionsReg | ||
io.outTkeep := outTkeepReg | ||
io.outValid := RegNext(prefSumVldOut, init=false.B ) | ||
//io.outValid := io.in.valid | ||
} | ||
|
||
object GenExtractPositions extends App { | ||
ChiselStage.emitSystemVerilogFile(new ExtractPositions(8, 4, 4), Array()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package Rs | ||
|
||
import chisel3._ | ||
import circt.stage.ChiselStage | ||
import chisel3.util._ | ||
|
||
class InsertVec[T <: Data](shiftUnit: T, inWidth: Int, outWidth: Int) extends Module { | ||
val io = IO(new Bundle { | ||
val baseVec = Input(Vec(outWidth, shiftUnit)) | ||
val vecIn = Input(Vec(inWidth, shiftUnit)) | ||
val shiftVal = Input(UInt(log2Ceil(inWidth+1).W)) | ||
val vecOut = Output(Vec(outWidth, shiftUnit)) | ||
}) | ||
|
||
val alignInVec = Module(new AlignInVec(shiftUnit, inWidth, outWidth)) | ||
val barrelShifter = Module(new BarrelShifter(shiftUnit, outWidth)) | ||
|
||
alignInVec.io.vecIn := io.vecIn | ||
alignInVec.io.shiftVal := io.shiftVal | ||
|
||
barrelShifter.io.vecIn := io.baseVec | ||
barrelShifter.io.shiftVal := io.shiftVal | ||
|
||
// Perform the OR operation element-wise | ||
for (i <- 0 until outWidth) { | ||
io.vecOut(i) := (barrelShifter.io.vecOut(i).asUInt | alignInVec.io.vecOut(i).asUInt).asTypeOf(shiftUnit) | ||
} | ||
|
||
} | ||
|
||
object GenInsertVec extends App { | ||
class ShiftUnit extends Bundle { | ||
val formDerSymb = UInt(10.W) | ||
val errEvalXlInvSymb = UInt(8.W) | ||
val XlSymb = UInt(1.W) | ||
} | ||
ChiselStage.emitSystemVerilogFile(new InsertVec(new ShiftUnit, 4, 8), Array()) | ||
} |