diff --git a/t1/src/T1.scala b/t1/src/T1.scala index c8ee54e3b..44123f263 100644 --- a/t1/src/T1.scala +++ b/t1/src/T1.scala @@ -21,7 +21,6 @@ import chisel3.util.{ Enum, Fill, FillInterleaved, - HasBlackBoxInline, Mux1H, OHToUInt, Pipe, @@ -39,127 +38,6 @@ 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);) @@ -1103,18 +981,87 @@ class T1(val parameter: T1Parameter) ).asUInt probeWire.responseCounter := responseCounter probeWire.laneProbes.zip(laneVec).foreach { case (p, l) => p := probe.read(l.laneProbe) } - probeWire.lsuProbe := probe.read(lsu.lsuProbe) - probeWire.issue.valid := io.issue.fire - probeWire.issue.bits := instructionCounter - 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 + probeWire.lsuProbe := probe.read(lsu.lsuProbe) + probeWire.issue.valid := io.issue.fire + probeWire.issue.bits := instructionCounter + probeWire.retire.valid := io.retire.rd.valid + probeWire.retire.bits := io.retire.rd.bits.rdData + probeWire.idle := slots.map(_.state.idle).reduce(_ && _) + + // 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 + } - layer.block(layers.Verification.Cover) { - val CoverBlackBox = Instance(new CoverBlackBox(parameter)) + // 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}") + ) + } + } - 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) @@ -1142,12 +1089,11 @@ 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 = lsuProbe.storeUnitProbe + val storeUnitProbe = probeWire.lsuProbe.storeUnitProbe val storeRangeStartNew = storeUnitProbe.address val storeRangeEndNew = storeUnitProbe.address + PriorityEncoder(storeUnitProbe.mask) @@ -1166,7 +1112,7 @@ class T1(val parameter: T1Parameter) CoverProperty(BoolSequence(storeUnitProbe.valid && storeDisjoint), label = Some("4_store_disjoint")) // other unit probe - val otherUnitProbe = lsuProbe.otherUnitProbe + val otherUnitProbe = probeWire.lsuProbe.otherUnitProbe val otherRangeStartNew = otherUnitProbe.address val otherRangeEndNew = otherUnitProbe.address + PriorityEncoder(otherUnitProbe.mask) @@ -1183,5 +1129,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 }