From d5b4da4a1167633615bb8a7e27d16bd8cec022c0 Mon Sep 17 00:00:00 2001 From: Clo91eaf Date: Tue, 19 Nov 2024 20:42:12 +0800 Subject: [PATCH] tricky blackbox for coverpoint / bins, wip --- t1/src/T1.scala | 206 ++++++++++++++++++++++++++++++------------------ 1 file changed, 130 insertions(+), 76 deletions(-) diff --git a/t1/src/T1.scala b/t1/src/T1.scala index c5da0a9a0..7888c8726 100644 --- a/t1/src/T1.scala +++ b/t1/src/T1.scala @@ -21,6 +21,7 @@ import chisel3.util.{ Enum, Fill, FillInterleaved, + HasBlackBoxInline, Mux1H, OHToUInt, Pipe, @@ -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);) @@ -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) @@ -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) @@ -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) @@ -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 + } }