Skip to content

Commit

Permalink
[Shift] Add blocks for barrel shifting, concatenation and position ca…
Browse files Browse the repository at this point in the history
…pturing.
  • Loading branch information
egorman44 committed Dec 16, 2024
1 parent 260f2af commit ad1c00b
Show file tree
Hide file tree
Showing 3 changed files with 246 additions and 0 deletions.
104 changes: 104 additions & 0 deletions src/main/scala/CapturePositions.scala
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)
}
}
104 changes: 104 additions & 0 deletions src/main/scala/ExtractPositions.scala
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())
}
38 changes: 38 additions & 0 deletions src/main/scala/InsertVec.scala
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())
}

0 comments on commit ad1c00b

Please sign in to comment.