Skip to content

Commit

Permalink
tricky blackbox for coverpoint / bins, wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Clo91eaf committed Nov 19, 2024
1 parent 132746b commit d5b4da4
Showing 1 changed file with 130 additions and 76 deletions.
206 changes: 130 additions & 76 deletions t1/src/T1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import chisel3.util.{
Enum,
Fill,
FillInterleaved,
HasBlackBoxInline,
Mux1H,
OHToUInt,
Pipe,
Expand All @@ -38,6 +39,127 @@ import org.chipsalliance.t1.rtl.vrf.{RamType, VRFParam}

import scala.collection.immutable.SeqMap

class CoverBlackBoxInterface(parameter: T1Parameter) extends Bundle {
val clock = Input(Clock())
val reset = Input(if (parameter.useAsyncReset) AsyncReset() else Bool())
val instruction = Input(ValidIO(UInt(32.W)))
}

@instantiable
class CoverBlackBox(parameter: T1Parameter)
extends BlackBox
with HasBlackBoxInline
with Public
with ImplicitClock
with ImplicitReset
with FixedIORawModule(new CoverBlackBoxInterface(parameter))
with SerializableModule[T1Parameter] {
def implicitClock: Clock = io.clock
def implicitReset: Reset = io.reset

// unsupported 64-bit instructions for 32-bit xlen
val zve32f = Seq(
// format: off
"vfadd.vf", "vfadd.vv", "vfclass.v", "vfcvt.f.x.v",
"vfcvt.f.xu.v", "vfcvt.rtz.x.f.v", "vfcvt.rtz.xu.f.v", "vfcvt.x.f.v",
"vfcvt.xu.f.v", "vfdiv.vf", "vfdiv.vv", "vfmacc.vf",
"vfmacc.vv", "vfmadd.vf", "vfmadd.vv", "vfmax.vf",
"vfmax.vv", "vfmerge.vfm", "vfmin.vf", "vfmin.vv",
"vfmsac.vf", "vfmsac.vv", "vfmsub.vf", "vfmsub.vv",
"vfmul.vf", "vfmul.vv", "vfmv.f.s", "vfmv.s.f",
"vfmv.v.f", "vfnmacc.vf", "vfnmacc.vv", "vfnmadd.vf",
"vfnmadd.vv", "vfnmsac.vf", "vfnmsac.vv", "vfnmsub.vf",
"vfnmsub.vv", "vfrdiv.vf", "vfrec7.v", "vfredmax.vs",
"vfredmin.vs", "vfredosum.vs", "vfredusum.vs", "vfrsqrt7.v",
"vfrsub.vf", "vfsgnj.vf", "vfsgnj.vv", "vfsgnjn.vf",
"vfsgnjn.vv", "vfsgnjx.vf", "vfsgnjx.vv", "vfsqrt.v",
"vfsub.vf", "vfsub.vv", "vmfeq.vf", "vmfeq.vv",
"vmfge.vf", "vmfgt.vf", "vmfle.vf", "vmfle.vv",
"vmflt.vf", "vmflt.vv", "vmfne.vf", "vmfne.vv"
// format: on
)
val zve64f = Seq(
// format: off
"vfncvt.f.f.w", "vfncvt.f.x.w", "vfncvt.f.xu.w", "vfncvt.rod.f.f.w", "vfncvt.rtz.x.f.w", "vfncvt.rtz.xu.f.w", "vfncvt.x.f.w", "vfncvt.xu.f.w",
"vfslide1down.vf", "vfslide1up.vf",
"vfwadd.vf", "vfwadd.vv", "vfwadd.wf", "vfwadd.wv",
"vfwcvt.f.f.v", "vfwcvt.f.x.v", "vfwcvt.f.xu.v", "vfwcvt.rtz.x.f.v", "vfwcvt.rtz.xu.f.v", "vfwcvt.x.f.v", "vfwcvt.xu.f.v",
"vfwmacc.vf", "vfwmacc.vv", "vfwmsac.vf", "vfwmsac.vv",
"vfwmul.vf", "vfwmul.vv", "vfwnmacc.vf", "vfwnmacc.vv",
"vfwnmsac.vf", "vfwnmsac.vv", "vfwredosum.vs", "vfwredusum.vs",
"vfwsub.vf", "vfwsub.vv", "vfwsub.wf", "vfwsub.wv",
// format: on
)
val zve64x = Seq(
// format: off
"vl1re64.v", "vl2re64.v", "vl4re64.v", "vl8re64.v",
"vle64.v", "vle64ff.v", "vloxei64.v", "vlse64.v", "vluxei64.v",
"vse64.v", "vsoxei64.v", "vsse64.v", "vsuxei64.v",
"vsext.vf8", "vzext.vf8"
// format: on
)

val instructions: Seq[Instruction] = parameter.decoderParam.allInstructions.filter { instruction: Instruction =>
// format: off
!(zve64x.contains(instruction.name) && parameter.xLen == 32) &&
!(zve64f.contains(instruction.name) && parameter.xLen == 32 && parameter.fpuEnable) &&
!((zve32f ++ zve64f).contains(instruction.name) && !parameter.fpuEnable)
// format: on
}

// make strings for bins, like:
/*
bins vaadd_vv = 0;
bins vaadd_vx = 1;
...
*/
val binStrings = instructions.zipWithIndex.map { case (instruction: Instruction, index: Int) =>
s"bins ${instruction.name} = ${index};"
}.mkString

// coverage for one instruction
val coverOneInstVec: Vec[Bool] = VecInit(instructions.map { instruction: Instruction =>
io.instruction.valid && io.instruction.bits === BitPat("b" + instruction.encoding.toString)
})
val coverOneInstIndex = PriorityEncoder(coverOneInstVec)
val indexSize = instructions.size

// TODO:how to set pass coverOneInstIndex to inline verilog??
setInline(
s"coverBlackBox.sv",
s"""
|module coverBlackBox(
| input [${(log2Ceil(indexSize) - 1)}:0] index,
|);
|
|covergroup coverOneInst;
| option.per_instance = 1;
| coverpoint index {
| ${binStrings}
| }
|endgroup
|
|endmodule
""".stripMargin
)

// coverage for two instructions
// val coverTwoInstVec: Vec[Bool] = VecInit(
// instructions.map { case instructionNew: Instruction =>
// instructions.map { case instructionOld: Instruction =>
// val issueInstructionOld = RegEnable(requestReg.bits.issue.instruction, requestReg.valid)
// val coverMatchNew =
// requestReg.valid && requestReg.bits.issue.instruction === BitPat("b" + instructionNew.encoding.toString)
// val coverMatchOld = issueInstructionOld === BitPat("b" + instructionOld.encoding.toString)
// coverMatchNew && coverMatchOld
// }
// }
// )

// val coverTwoInstIndex = PriorityEncoder(coverTwoInstVec)

}

// TODO: this should be a object model. There should 3 object model here:
// 1. T1SubsystemOM(T1(OM), MemoryRegion, Cache configuration)
// 2. T1(Lane(OM), VLEN, DLEN, uarch parameters, customer IDs(for floorplan);)
Expand Down Expand Up @@ -1800,81 +1922,12 @@ class T1(val parameter: T1Parameter)
probeWire.retire.valid := io.retire.rd.valid
probeWire.retire.bits := io.retire.rd.bits.rdData
probeWire.idle := slots.map(_.state.idle).reduce(_ && _)
} // end of verification layer

// coverage
import Sequence.BoolSequence
// unsupported 64-bit instructions for 32-bit xlen
val zve32f = Seq(
// format: off
"vfadd.vf", "vfadd.vv", "vfclass.v", "vfcvt.f.x.v",
"vfcvt.f.xu.v", "vfcvt.rtz.x.f.v", "vfcvt.rtz.xu.f.v", "vfcvt.x.f.v",
"vfcvt.xu.f.v", "vfdiv.vf", "vfdiv.vv", "vfmacc.vf",
"vfmacc.vv", "vfmadd.vf", "vfmadd.vv", "vfmax.vf",
"vfmax.vv", "vfmerge.vfm", "vfmin.vf", "vfmin.vv",
"vfmsac.vf", "vfmsac.vv", "vfmsub.vf", "vfmsub.vv",
"vfmul.vf", "vfmul.vv", "vfmv.f.s", "vfmv.s.f",
"vfmv.v.f", "vfnmacc.vf", "vfnmacc.vv", "vfnmadd.vf",
"vfnmadd.vv", "vfnmsac.vf", "vfnmsac.vv", "vfnmsub.vf",
"vfnmsub.vv", "vfrdiv.vf", "vfrec7.v", "vfredmax.vs",
"vfredmin.vs", "vfredosum.vs", "vfredusum.vs", "vfrsqrt7.v",
"vfrsub.vf", "vfsgnj.vf", "vfsgnj.vv", "vfsgnjn.vf",
"vfsgnjn.vv", "vfsgnjx.vf", "vfsgnjx.vv", "vfsqrt.v",
"vfsub.vf", "vfsub.vv", "vmfeq.vf", "vmfeq.vv",
"vmfge.vf", "vmfgt.vf", "vmfle.vf", "vmfle.vv",
"vmflt.vf", "vmflt.vv", "vmfne.vf", "vmfne.vv"
// format: on
)
val zve64f = Seq(
// format: off
"vfncvt.f.f.w", "vfncvt.f.x.w", "vfncvt.f.xu.w", "vfncvt.rod.f.f.w", "vfncvt.rtz.x.f.w", "vfncvt.rtz.xu.f.w", "vfncvt.x.f.w", "vfncvt.xu.f.w",
"vfslide1down.vf", "vfslide1up.vf",
"vfwadd.vf", "vfwadd.vv", "vfwadd.wf", "vfwadd.wv",
"vfwcvt.f.f.v", "vfwcvt.f.x.v", "vfwcvt.f.xu.v", "vfwcvt.rtz.x.f.v", "vfwcvt.rtz.xu.f.v", "vfwcvt.x.f.v", "vfwcvt.xu.f.v",
"vfwmacc.vf", "vfwmacc.vv", "vfwmsac.vf", "vfwmsac.vv",
"vfwmul.vf", "vfwmul.vv", "vfwnmacc.vf", "vfwnmacc.vv",
"vfwnmsac.vf", "vfwnmsac.vv", "vfwredosum.vs", "vfwredusum.vs",
"vfwsub.vf", "vfwsub.vv", "vfwsub.wf", "vfwsub.wv",
// format: on
)
val zve64x = Seq(
// format: off
"vl1re64.v", "vl2re64.v", "vl4re64.v", "vl8re64.v",
"vle64.v", "vle64ff.v", "vloxei64.v", "vlse64.v", "vluxei64.v",
"vse64.v", "vsoxei64.v", "vsse64.v", "vsuxei64.v",
"vsext.vf8", "vzext.vf8"
// format: on
)
val instructions: Seq[Instruction] = parameter.decoderParam.allInstructions.filter { instruction: Instruction =>
// format: off
!(zve64x.contains(instruction.name) && parameter.xLen == 32) &&
!(zve64f.contains(instruction.name) && parameter.xLen == 32 && parameter.fpuEnable) &&
!((zve32f ++ zve64f).contains(instruction.name) && !parameter.fpuEnable)
// format: on
}

// coverage for one instruction
instructions.map { instruction: Instruction =>
val coverMatch = BoolSequence(
requestReg.valid && requestReg.bits.issue.instruction === BitPat("b" + instruction.encoding.toString)
)
CoverProperty(coverMatch, label = Some(s"1_${instruction.name}"))
}

// coverage for two instructions
instructions.map { case instructionNew: Instruction =>
instructions.map { case instructionOld: Instruction =>
val issueInstructionOld = RegEnable(requestReg.bits.issue.instruction, requestReg.valid)
val coverMatchNew = BoolSequence(
requestReg.valid && requestReg.bits.issue.instruction === BitPat("b" + instructionNew.encoding.toString)
)
val coverMatchOld = BoolSequence(issueInstructionOld === BitPat("b" + instructionOld.encoding.toString))
CoverProperty(
coverMatchNew.and(coverMatchOld),
label = Some(s"2_${instructionOld.name}_and_${instructionNew.name}")
)
}
}
layer.block(layers.Verification.Cover) {
val CoverBlackBox = Instance(new CoverBlackBox(parameter))

import Sequence.BoolSequence
// coverage for different sew / vlmul / vl
val vsews: Seq[Int] = Seq(0, 1, 2)
val sews: Seq[Int] = Seq(8, 16, 32)
Expand Down Expand Up @@ -1902,11 +1955,12 @@ class T1(val parameter: T1Parameter)
}

// coverage for lsu (load / store / other) with slots (contain / intersection / disjoint)
val lsuProbe = probe.read(lsu.lsuProbe)

// TODO:load unit probe

// store unit probe
val storeUnitProbe = probeWire.lsuProbe.storeUnitProbe
val storeUnitProbe = lsuProbe.storeUnitProbe

val storeRangeStartNew = storeUnitProbe.address
val storeRangeEndNew = storeUnitProbe.address + PriorityEncoder(storeUnitProbe.mask)
Expand All @@ -1925,7 +1979,7 @@ class T1(val parameter: T1Parameter)
CoverProperty(BoolSequence(storeUnitProbe.valid && storeDisjoint), label = Some("4_store_disjoint"))

// other unit probe
val otherUnitProbe = probeWire.lsuProbe.otherUnitProbe
val otherUnitProbe = lsuProbe.otherUnitProbe

val otherRangeStartNew = otherUnitProbe.address
val otherRangeEndNew = otherUnitProbe.address + PriorityEncoder(otherUnitProbe.mask)
Expand All @@ -1942,5 +1996,5 @@ class T1(val parameter: T1Parameter)
CoverProperty(BoolSequence(otherUnitProbe.valid && otherContain), label = Some("4_other_contain"))
CoverProperty(BoolSequence(otherUnitProbe.valid && otherIntersection), label = Some("4_other_intersection"))
CoverProperty(BoolSequence(otherUnitProbe.valid && otherDisjoint), label = Some("4_other_disjoint"))
} // end of verification layer
}
}

0 comments on commit d5b4da4

Please sign in to comment.