diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 04dbe91eb..fc2afc196 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -163,7 +163,10 @@ jobs: ref: ${{ github.event.pull_request.head.sha }} - name: "Run testcases" run: | - nix run ".#ci-helper" -- runTests --jobs "${{ matrix.jobs }}" + nix develop -c t1-helper runTests --jobs "${{ matrix.jobs }}" + - name: "Run OM tests" + run: | + nix develop -c t1-helper runOMTests --jobs "${{ matrix.jobs }}" report: name: "Report CI result" diff --git a/configgen/generated/blastoise.json b/configgen/generated/blastoise.json index 081bcb424..d0e26eb82 100644 --- a/configgen/generated/blastoise.json +++ b/configgen/generated/blastoise.json @@ -5,6 +5,7 @@ "extensions": [ "Zve32f" ], + "t1customInstructions": [], "lsuBankParameters": [ { "name": "scalar", diff --git a/configgen/generated/machamp.json b/configgen/generated/machamp.json index 39a3fa1ba..dc0a4b2d9 100644 --- a/configgen/generated/machamp.json +++ b/configgen/generated/machamp.json @@ -5,6 +5,7 @@ "extensions": [ "Zve32x" ], + "t1customInstructions": [], "lsuBankParameters": [ { "name": "scalar", diff --git a/configgen/generated/sandslash.json b/configgen/generated/sandslash.json index 4f1c3ed8a..5ae0cb6b3 100644 --- a/configgen/generated/sandslash.json +++ b/configgen/generated/sandslash.json @@ -5,6 +5,7 @@ "extensions": [ "Zve32x" ], + "t1customInstructions": [], "lsuBankParameters": [ { "name": "scalar", diff --git a/configgen/src/Main.scala b/configgen/src/Main.scala index 747724553..2426a118d 100644 --- a/configgen/src/Main.scala +++ b/configgen/src/Main.scala @@ -8,8 +8,10 @@ import chisel3.util.{BitPat, log2Ceil} import chisel3.util.experimental.BitSet import mainargs._ import org.chipsalliance.t1.rtl._ +import org.chipsalliance.t1.rtl.decoder.T1CustomInstruction import org.chipsalliance.t1.rtl.lsu.LSUInstantiateParameter import org.chipsalliance.t1.rtl.vrf.RamType + import java.util.LinkedHashMap object Main { @@ -67,6 +69,7 @@ object Main { vLen, dLen, extensions = Seq("Zve32f"), + t1customInstructions = Nil, lsuBankParameters = // scalar bank 0-1G Seq( @@ -138,6 +141,7 @@ object Main { vLen, dLen, extensions = Seq("Zve32x"), + t1customInstructions = Nil, // banks=8 dLen=512 beatbyte16 lsuBankParameters = // scalar bank 0-1G @@ -215,6 +219,7 @@ object Main { vLen, dLen, extensions = Seq("Zve32x"), + t1customInstructions = Nil, lsuBankParameters = // scalar bank 0-1G Seq( diff --git a/ipemu/src/TestBench.scala b/ipemu/src/TestBench.scala index 07649af22..1cbcc26b4 100644 --- a/ipemu/src/TestBench.scala +++ b/ipemu/src/TestBench.scala @@ -5,11 +5,27 @@ package org.chipsalliance.t1.ipemu import chisel3._ import chisel3.experimental.SerializableModuleGenerator -import chisel3.probe._ +import chisel3.experimental.hierarchy.{Instance, Instantiate, instantiable, public} +import chisel3.properties.{AnyClassType, Class, ClassType, Property} import org.chipsalliance.t1.ipemu.dpi._ import org.chipsalliance.t1.rtl.{T1, T1Parameter} +@instantiable +class TestBenchOM extends Class { + @public + val t1 = IO(Output(Property[AnyClassType]())) + @public + val t1In = IO(Input(Property[AnyClassType]())) + t1 := t1In +} + class TestBench(generator: SerializableModuleGenerator[T1, T1Parameter]) extends RawModule { + val omInstance: Instance[TestBenchOM] = Instantiate(new TestBenchOM) + val omType: ClassType = omInstance.toDefinition.getClassType + @public + val om: Property[ClassType] = IO(Output(Property[omType.Type]())) + om := omInstance.getPropertyReference + // Scheduler to schedule different DPI calls for online difftest, // TODO: after switching to offline version, everything should be cleaned up. val clockRate = 5 @@ -32,6 +48,7 @@ class TestBench(generator: SerializableModuleGenerator[T1, T1Parameter]) extends val dut: T1 = withClockAndReset(clock, reset)(Module(generator.module())) dut.storeBufferClear := true.B + omInstance.t1In := Property(dut.om.asAnyClassType) val laneProbes = dut.laneProbes.zipWithIndex.map{case (p, idx) => val wire = Wire(p.cloneType).suggestName(s"lane${idx}Probe") diff --git a/nix/t1/default.nix b/nix/t1/default.nix index dfeea63ac..0b8ceb13b 100644 --- a/nix/t1/default.nix +++ b/nix/t1/default.nix @@ -34,7 +34,7 @@ lib.makeScope newScope configgen = _millOutput.configgen // { meta.mainProgram = "configgen"; }; t1package = _millOutput.t1package; - omreader = self.callPackage ./omreader.nix { }; + omreader-unwrapped = self.callPackage ./omreader.nix { }; submodules = self.callPackage ./submodules.nix { }; riscv-opcodes-src = self.submodules.sources.riscv-opcodes.src; @@ -65,10 +65,14 @@ lib.makeScope newScope elaborate = innerSelf.callPackage ./elaborate.nix { target = "ip"; /* use-binder = true; */ }; mlirbc = innerSelf.callPackage ./mlirbc.nix { inherit elaborate; }; rtl = innerSelf.callPackage ./rtl.nix { inherit mlirbc; }; + + omreader = self.omreader-unwrapped.mkWrapper { inherit mlirbc; }; + om = innerSelf.callPackage ./om.nix { inherit mlirbc; }; emu-elaborate = innerSelf.callPackage ./elaborate.nix { target = "ipemu"; /* use-binder = true; */ }; emu-mlirbc = innerSelf.callPackage ./mlirbc.nix { elaborate = emu-elaborate; }; + emu-omreader = self.omreader-unwrapped.mkWrapper { mlirbc = emu-mlirbc; }; emu-rtl = innerSelf.callPackage ./rtl.nix { mlirbc = emu-mlirbc; }; emu = innerSelf.callPackage ./ipemu.nix { rtl = ip.emu-rtl; stdenv = moldStdenv; }; diff --git a/nix/t1/omreader.nix b/nix/t1/omreader.nix index 66873e050..a8d5da399 100644 --- a/nix/t1/omreader.nix +++ b/nix/t1/omreader.nix @@ -1,5 +1,6 @@ { lib , stdenv +, runCommand , fetchMillDeps , makeWrapper , jdk21 @@ -41,12 +42,22 @@ let nativeBuildInputs = [ submodules.setupHook ]; }; - passthru.editable = self.overrideAttrs (_: { - shellHook = '' - setupSubmodulesEditable - mill mill.bsp.BSP/install 0 - ''; - }); + passthru = { + editable = self.overrideAttrs (_: { + shellHook = '' + setupSubmodulesEditable + mill mill.bsp.BSP/install 0 + ''; + }); + + mkWrapper = { mlirbc }: runCommand "wrap-omreader" + { nativeBuildInputs = [ makeWrapper ]; meta.mainProgram = "omreader"; } + '' + mkdir -p "$out/bin" + mlirbc=$(find ${mlirbc}/ -type f) + makeWrapper ${self}/bin/omreader "$out/bin/omreader" --append-flags "--mlirbc-file $mlirbc" + ''; + }; shellHook = '' setupSubmodules diff --git a/omreader/src/Main.scala b/omreader/src/Main.scala index 394dbf22e..78a377349 100644 --- a/omreader/src/Main.scala +++ b/omreader/src/Main.scala @@ -47,6 +47,16 @@ object Main { println(simplyGetT1Reader(mlirbcFile).dlen) } + @main + def decoderInstructionsJson(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = { + println(simplyGetT1Reader(mlirbcFile).decoderInstructionsJson) + } + + @main + def decoderInstructionsJsonPretty(@arg(name = "mlirbc-file") mlirbcFile: os.Path) = { + println(simplyGetT1Reader(mlirbcFile).decoderInstructionsJsonPretty) + } + def simplyGetT1Reader(mlirbcFile: os.Path) = OMReader.fromFile(mlirbcFile).t1Reader def main(args: Array[String]): Unit = ParserForMethods(this).runOrExit(args) diff --git a/omreaderlib/src/Interface.scala b/omreaderlib/src/Interface.scala index 33c301053..56e5293f1 100644 --- a/omreaderlib/src/Interface.scala +++ b/omreaderlib/src/Interface.scala @@ -44,6 +44,31 @@ class T1Reader private[omreaderlib](evaluator: PanamaCIRCTOMEvaluator, basePath: def vlen: Long = t1.field("vlen").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer def dlen: Long = t1.field("dlen").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveInteger].integer + private def decoderInstructionsJsonImpl: ujson.Value = { + val decoder = t1.field("decoder").asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + val instructions = decoder.field("instructions").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + + instructions.elements.map(instruction => { + val instr = instruction.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + val attributes = instr.field("attributes").asInstanceOf[PanamaCIRCTOMEvaluatorValueList] + + ujson.Obj( + "attributes" -> attributes.elements.map(attribute => { + val attr = attribute.asInstanceOf[PanamaCIRCTOMEvaluatorValueObject] + val description = attr.field("description").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString + val identifier = attr.field("identifier").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString + val value = attr.field("value").asInstanceOf[PanamaCIRCTOMEvaluatorValuePrimitiveString].toString + ujson.Obj( + "description" -> description, + "identifier" -> identifier, + "value" -> value + ) + }) + ) + }) + } + def decoderInstructionsJson: String = ujson.write(decoderInstructionsJsonImpl) + def decoderInstructionsJsonPretty: String = ujson.write(decoderInstructionsJsonImpl, 2) def dumpMethods(): Unit = { val mirror = runtimeMirror(getClass.getClassLoader).reflect(this) @@ -52,7 +77,13 @@ class T1Reader private[omreaderlib](evaluator: PanamaCIRCTOMEvaluator, basePath: ) methods.foreach(method => { if (!method.name.toString.startsWith("dump")) { - val value = mirror.reflectMethod(method.asMethod)() + var value = mirror.reflectMethod(method.asMethod)().toString.replace("\n", "\\n") + + val displayLength = 80 + if (value.length > displayLength) { + value = value.take(displayLength) + s" (... ${value.length - displayLength} characters)" + } + println(s"${method.name} = $value") } }) diff --git a/script/emu/src/Main.scala b/script/emu/src/Main.scala index 4b18eb360..92088c27c 100644 --- a/script/emu/src/Main.scala +++ b/script/emu/src/Main.scala @@ -407,6 +407,350 @@ object Main: ).call(stdout = os.Inherit, stderr = os.Inherit, stdin = os.Inherit) Logger.info(s"RTLs store in $finalOutLink") + // + // CI + // + // The below script will try to read all the tests in ../../.github/cases/**/default.json, + // arranging them together by their required cycle, and using GitHub "matrix" feature to manage + // and separate those test job to multiple machines. + // + // We define that, the term "bucket" refers to a list of test job, concating by ';' into text. + // "Bucket" will be recorded in "matrix" payload field "jobs". Each machine will run a "bucket" of tests. + // + // Function `generateMatrix` will be used to produce necessary information to feed the GitHub matrix. + // Function `runTests` will parse the GitHub matrix, run a "bucket" of tests and generate GitHub CI report. + // + // The final "matrix" will have json data like: { include: [ { jobs: "taskA;taskB", id: 1 }, { jobs: "taskC;taskD", id: 2 } ] }. + // + + case class Bucket(buffer: Seq[String] = Seq(), totalCycle: Int = 0): + def cons(data: (String, Int)): Bucket = + val (testName, cycle) = data + Bucket(buffer ++ Seq(testName), totalCycle + cycle) + + def mkString(sep: String = ";") = buffer.mkString(sep) + + // Read test case and their cycle data from the given paths. + // Test cases will be grouped into a single bucket, and then partitioned into given `bucketSize` of sub-bucket. + // Each sub-bucket will have similar weight, so that the time cost will be similar between each runners. + // + // For example: + // + // [ {A: 100}, {B: 180}, {C: 300}, {D:200} ] => [[A,C], [B,D]] + // + // @param allTasksFile List of the default.json file path + // @param bucketSize Specify the size of the output Seq + def scheduleTasks(allTasksFile: Seq[os.Path], bucketSize: Int): Seq[String] = + // Produce a list of ("config,testName", cycle) pair + val allCycleData = allTasksFile.flatMap: file => + Logger.trace(s"Generate tests from file: $file") + val config = file.segments.toSeq.reverse.apply(1) + ujson + .read(os.read(file)) + .obj + .map { case (caseName, cycle) => + (s"$config,$caseName", cycle.num.toInt) + } + .toSeq + + val (unProcessedData, normalData) = + allCycleData.partition: + case (_, cycle) => cycle <= 0 + + // Initialize a list of buckets + val cargoInit = + (0 until math.min(bucketSize, allCycleData.length)).map(_ => Bucket()) + // Group tests that have cycle data into subset by their cycle size + val cargoStaged = normalData + .sortBy(_._2)(Ordering[Int].reverse) + .foldLeft(cargoInit): (cargo, elem) => + val smallest = cargo.minBy(_.totalCycle) + cargo.updated(cargo.indexOf(smallest), smallest.cons(elem)) + + // For unprocessed data, just split them into subset that have equal size + if unProcessedData.nonEmpty then + val chunkSize = unProcessedData.length.toDouble / bucketSize.toDouble + val cargoFinal = unProcessedData + .grouped(math.ceil(chunkSize).toInt) + .zipWithIndex + .foldLeft(cargoStaged): (cargo, chunkWithIndex) => + val (chunk, idx) = chunkWithIndex + val newBucket = chunk.foldLeft(cargoStaged.apply(idx)): + (bucket, data) => bucket.cons(data) + cargo.updated(idx, newBucket) + + cargoFinal.map(_.buffer.mkString(";")).toSeq + else cargoStaged.map(_.buffer.mkString(";")).toSeq + end scheduleTasks + + // Turn Seq( "A;B", "C;D" ) to GitHub Action matrix style json: { "include": [ { "jobs": "A;B", id: 1 }, { "jobs": "C;D", id: 2 } ] } + // + // @param buckets Seq of String that is already packed into bucket using the `buckets` function + // @param outputFile Path to the output json file + def toMatrixJson(buckets: Seq[String]) = + ujson.Obj("include" -> buckets.zipWithIndex.map: (bucket, i) => + ujson.Obj( + "jobs" -> ujson.Str(bucket), + "id" -> ujson.Num(i + 1) + )) + + // Read default tests information from '.github/cases/default.txt' file, and use that information to generate GitHub CI matrix. + // The result will be printed to stdout, and should be pipe into $GITHUB_OUTPUT + @main + def generateCiMatrix( + runnersAmount: Int, + testPlanFile: String = "default.json" + ) = { + val testPlans = + os.walk(os.pwd / ".github" / "cases").filter(_.last == testPlanFile) + println(toMatrixJson(scheduleTasks(testPlans, runnersAmount))) + } + + // Run jobs and give a brief result report + // - Log of tailed tests will be tailed and copied into $resultDir/failed-logs/$testName.log + // - List of failed tests will be written into $resultDir/failed-tests.md + // - Report of cycle updates will be written into $resultDir/cycle-updates.md + // - New cycle file will be written into $resultDir/$config_$runConfig_cycle.json + // + // @param: jobs A semicolon-separated list of job names of the form $config,$caseName,$runConfig + // @param: resultDir output directory of the test results, default to ./test-results + // @param: dontBail don't throw exception when test fail. Useful for postpr. + @main + def runTests( + jobs: String, + dontBail: Flag = Flag(false) + ): Unit = + if jobs == "" then + Logger.info("No test found, exiting") + return + + val allJobs = jobs.split(";") + def findFailedTests() = allJobs.zipWithIndex.foldLeft(Seq[String]()): + (allFailedTest, currentTest) => + val (testName, index) = currentTest + val Array(config, caseName) = testName.split(",") + println("\n") + Logger.info( + s"${BOLD}[${index + 1}/${allJobs.length}]${RESET} Running test case $caseName with config $config" + ) + + val testResultPath = + os.Path(nixResolvePath(s".#t1.$config.cases.$caseName.emu-result")) + val testSuccess = + os.read(testResultPath / "emu-success").trim().toInt == 1 + + if !testSuccess then + Logger.error(s"Test case $testName failed") + val err = os.read(testResultPath / "emu.log") + Logger.error(s"Detail error: $err") + + Logger.info("Running difftest") + val diffTestSuccess = + try + difftest( + config = config, + caseAttr = caseName, + logLevel = "ERROR" + ) + true + catch + err => + Logger.error(s"difftest run failed: $err") + false + + if diffTestSuccess != testSuccess then + Logger.fatal( + "Got different online and offline difftest result, please check this test manually. CI aborted." + ) + + if !testSuccess then allFailedTest :+ s"t1.$config.cases.$caseName" + else allFailedTest + end findFailedTests + + val failedTests = findFailedTests() + if failedTests.isEmpty then Logger.info(s"All tests passed") + else + val listOfFailJobs = + failedTests.map(job => s"* $job").appended("").mkString("\n") + val failedJobsWithError = failedTests + .map(testName => + val testResult = os.Path(nixResolvePath(s".#$testName.emu-result")) + val emuLog = os.read(testResult / "emu.log") + if emuLog.nonEmpty then + s"* $testName\n >>> ERROR SUMMARY <<<\n${emuLog}" + else + s"* $testName\n >>> OTHER ERROR <<<\n${os.read(testResult / "emu.journal")}" + ) + .appended("") + .mkString("\n") + + if dontBail.value then + Logger.error( + s"${BOLD}${failedTests.length} tests failed${RESET}:\n${failedJobsWithError}" + ) + else + Logger.fatal( + s"${BOLD}${failedTests.length} tests failed${RESET}:\n${failedJobsWithError}" + ) + end runTests + + @main + def runOMTests( + jobs: String, + ): Unit = + val configs = jobs.split(";").map(_.split(",")(0)) + configs.distinct.foreach: config => + Seq("omreader", "emu-omreader").foreach: target => + val command = Seq( + "nix", + "run", + s".#t1.$config.ip.$target", + "--", + "run", + "--dump-methods" + ) + println("\n") + Logger.info(s"Running OM test with command $BOLD'${command.mkString(" ")}'$RESET") + val outputs = os.proc(command).call().out.trim() + Logger.trace(s"Outputs:\n${outputs}") + + Seq("vlen =", "dlen =").foreach: keyword => + if outputs.contains(keyword) then + Logger.info(s"Keyword $BOLD'$keyword'$RESET found - ${GREEN}Pass!$RESET") + else + Logger.fatal(s"Keyword $BOLD'$keyword'$RESET not found - ${RED}Fail!$RESET") + end runOMTests + + // PostCI do the below four things: + // * read default.json at .github/cases/$config/default.json + // * generate case information for each entry in default.json (cycle, run success) + // * collect and report failed tests + // * collect and report cycle update + @main + def postCI( + @arg( + name = "failed-test-file-path", + doc = "specify the failed test markdown file output path" + ) failedTestsFilePath: String, + @arg( + name = "cycle-update-file-path", + doc = "specify the cycle update markdown file output path" + ) cycleUpdateFilePath: String + ) = + os.walk(os.pwd / ".github" / "cases") + .filter(_.last == "default.json") + .foreach: file => + val config = file.segments.toSeq.reverse.apply(1) + var cycleRecord = ujson.read(os.read(file)) + + Logger.info("Fetching CI results") + val emuResultPath = + os.Path(nixResolvePath(s".#t1.$config.cases._allEmuResult")) + + Logger.info("Collecting failed cases") + val failedCases = os + .walk(emuResultPath) + .filter(path => path.last == "emu-success") + .filter(path => os.read(path) == "0") + .map(path => path.segments.toSeq.reverse.drop(1).head) + .map(caseName => s"* `.#t1.${config}.cases.${caseName}`") + val failedTestsRecordFile = os.Path(failedTestsFilePath, os.pwd) + os.write.over(failedTestsRecordFile, "## Failed tests\n") + os.write.append(failedTestsRecordFile, failedCases) + + Logger.info("Collecting cycle update info") + val cycleUpdateRecordFile = os.Path(cycleUpdateFilePath, os.pwd) + os.write.over(cycleUpdateRecordFile, "## Cycle Update\n") + val perfCycleRegex = raw"total_cycles:\s(\d+)".r + val allCycleUpdates = os + .walk(emuResultPath) + .filter(path => path.last == "perf.txt") + .map(path => { + val cycle = os.read.lines(path).head match + case perfCycleRegex(cycle) => cycle.toInt + case _ => + throw new Exception("perf.txt file is not format as expected") + val caseName = path.segments.toSeq.reverse.drop(1).head + (caseName, cycle, cycleRecord.obj(caseName).num.toInt) + }) + .filter((_, newCycle, oldCycle) => newCycle != oldCycle) + .map: + case (caseName, newCycle, oldCycle) => + cycleRecord(caseName) = newCycle + if oldCycle == -1 then s"* 🆕 ${caseName}: NaN -> ${newCycle}" + else if oldCycle > newCycle then + s"* 🚀 $caseName: $oldCycle -> $newCycle" + else s"* 🐢 $caseName: $oldCycle -> $newCycle" + + os.write.append(cycleUpdateRecordFile, allCycleUpdates.mkString("\n")) + + os.write.over(file, ujson.write(cycleRecord, indent = 2)) + end postCI + + @main + def generateTestPlan() = + val allCases = + os.walk(os.pwd / ".github" / "cases").filter(_.last == "default.json") + val testPlans = allCases.map: caseFilePath => + caseFilePath.segments.dropWhile(_ != "cases").drop(1).next + + println(ujson.write(Map("config" -> testPlans))) + end generateTestPlan + + @main + def generateRegressionTestPlan(runnersAmount: Int): Unit = + // Find emulator configs + val emulatorConfigs: Seq[String] = + os.walk(os.pwd / ".github" / "cases") + .filter: path => + path.last == "default.json" + .map: path => + // We have a list of pwd/.github/cases//default.json string, + // but all we need is the name. + path.segments.toSeq.reverse.drop(1).head + + import scala.util.chaining._ + val testPlans: Seq[String] = emulatorConfigs.flatMap: configName => + val allCasesPath = nixResolvePath(s".#t1.$configName.cases.all") + os.walk(os.Path(allCasesPath) / "configs") + .filter: path => + path.ext == "json" + .map: path => + // configs/ directory have a list of .json files, we need those + val testName = path.segments.toSeq.last.stripSuffix(".json") + s"$configName,$testName" + + def getTestPlan(filePat: String): Seq[String] = + os.walk(os.pwd / ".github" / "cases") + .filter: path => + path.last == filePat + .flatMap: path => + val config = path.segments.toSeq.reverse.drop(1).head + os.read(path) + .pipe(raw => ujson.read(raw)) + .pipe(json => json.obj.keys.map(testName => s"$config,$testName")) + + val currentTestPlan = getTestPlan("default.json") + val perfCases = getTestPlan("perf.json") + + // We don't have much information for this tests, so randomly split them into same size buckets + // Merge Seq( "A", "B", "C", "D" ) into Seq( "A;B", "C;D" ) + def buckets(alltests: Seq[String], bucketSize: Int): Seq[String] = + scala.util.Random + .shuffle(alltests) + .grouped( + math.ceil(alltests.size.toDouble / bucketSize).toInt + ) + .toSeq + .map(_.mkString(";")) + + val finalTestPlan = + (testPlans.toSet -- currentTestPlan.toSet -- perfCases.toSet).toSeq + buckets(finalTestPlan, runnersAmount) + .pipe(toMatrixJson) + .pipe(println) + end generateRegressionTestPlan + @main def difftest( @arg( diff --git a/t1/src/Bundles.scala b/t1/src/Bundles.scala index f1b450ec8..fb79e2af3 100644 --- a/t1/src/Bundles.scala +++ b/t1/src/Bundles.scala @@ -135,7 +135,7 @@ class ExtendInstructionType extends Bundle { class LaneRequest(param: LaneParameter) extends Bundle { val instructionIndex: UInt = UInt(param.instructionIndexBits.W) // decode - val decodeResult: DecodeBundle = Decoder.bundle(param.fpuEnable) + val decodeResult: DecodeBundle = Decoder.bundle(param.decoderParam) val loadStore: Bool = Bool() val issueInst: Bool = Bool() val store: Bool = Bool() @@ -506,7 +506,7 @@ class InstructionPipeBundle(parameter: T1Parameter) extends Bundle { // 原始指令信息 val request: VRequest = new VRequest(parameter.xLen) // decode 的结果 - val decodeResult: DecodeBundle = new DecodeBundle(Decoder.all(parameter.fpuEnable)) + val decodeResult: DecodeBundle = new DecodeBundle(Decoder.allFields(parameter.decoderParam)) // 这条指令被vector分配的index val instructionIndex: UInt = UInt(parameter.instructionIndexBits.W) // 指令的csr信息 @@ -632,7 +632,7 @@ class LaneExecuteStage(parameter: LaneParameter)(isLastSlot: Boolean) extends Bu val sSendResponse: Option[Bool] = Option.when(isLastSlot)(Bool()) // pipe state for stage3 - val decodeResult: DecodeBundle = Decoder.bundle(parameter.fpuEnable) + val decodeResult: DecodeBundle = Decoder.bundle(parameter.decoderParam) val instructionIndex: UInt = UInt(parameter.instructionIndexBits.W) val loadStore: Bool = Bool() val vd: UInt = UInt(5.W) @@ -656,7 +656,7 @@ class ExecutionUnitRecord(parameter: LaneParameter)(isLastSlot: Boolean) extends val maskType: Bool = Bool() val laneIndex: UInt = UInt(parameter.laneNumberBits.W) // pipe state - val decodeResult: DecodeBundle = Decoder.bundle(parameter.fpuEnable) + val decodeResult: DecodeBundle = Decoder.bundle(parameter.decoderParam) } class SlotRequestToVFU(parameter: LaneParameter) extends Bundle { diff --git a/t1/src/Lane.scala b/t1/src/Lane.scala index 7095054b3..beb3623bf 100644 --- a/t1/src/Lane.scala +++ b/t1/src/Lane.scala @@ -10,7 +10,7 @@ import chisel3.probe.{Probe, ProbeValue, define} import chisel3.properties.{AnyClassType, Class, ClassType, Path, Property} import chisel3.util._ import chisel3.util.experimental.decode.DecodeBundle -import org.chipsalliance.t1.rtl.decoder.Decoder +import org.chipsalliance.t1.rtl.decoder.{Decoder, DecoderParam} import org.chipsalliance.t1.rtl.lane._ import org.chipsalliance.t1.rtl.vrf.{RamType, VRF, VRFParam, VRFProbe} @@ -80,6 +80,7 @@ case class LaneParameter( fpuEnable: Boolean, portFactor: Int, vrfRamType: RamType, + decoderParam: DecoderParam, vfuInstantiateParameter: VFUInstantiateParameter) extends SerializableModuleParameter { @@ -469,10 +470,10 @@ class Lane(val parameter: LaneParameter) extends Module with SerializableModule[ val requestVec: Vec[SlotRequestToVFU] = Wire(Vec(parameter.chainingSize, new SlotRequestToVFU(parameter))) /** decode message for [[requestVec]]. */ - val executeDecodeVec: Vec[DecodeBundle] = Wire(Vec(parameter.chainingSize, Decoder.bundle(parameter.fpuEnable))) + val executeDecodeVec: Vec[DecodeBundle] = Wire(Vec(parameter.chainingSize, Decoder.bundle(parameter.decoderParam))) /** decode message for [[responseVec]]. */ - val responseDecodeVec: Vec[DecodeBundle] = Wire(Vec(parameter.chainingSize, Decoder.bundle(parameter.fpuEnable))) + val responseDecodeVec: Vec[DecodeBundle] = Wire(Vec(parameter.chainingSize, Decoder.bundle(parameter.decoderParam))) /** response from vfu to slot. */ val responseVec: Vec[ValidIO[VFUResponseToSlot]] = Wire(Vec(parameter.chainingSize, Valid(new VFUResponseToSlot(parameter)))) diff --git a/t1/src/T1.scala b/t1/src/T1.scala index 655f511c6..197288639 100644 --- a/t1/src/T1.scala +++ b/t1/src/T1.scala @@ -12,7 +12,8 @@ import tilelink.{TLBundle, TLBundleParameter, TLChannelAParameter, TLChannelDPar import chisel3.probe.{Probe, ProbeValue, define, force} import chisel3.properties.{AnyClassType, Class, ClassType, Property} import chisel3.util.experimental.BitSet -import org.chipsalliance.t1.rtl.decoder.Decoder +import org.chipsalliance.rvdecoderdb.Instruction +import org.chipsalliance.t1.rtl.decoder.{Decoder, DecoderParam, T1CustomInstruction} import org.chipsalliance.t1.rtl.lsu.{LSU, LSUParameter, LSUProbe} import org.chipsalliance.t1.rtl.vrf.{RamType, VRFParam, VRFProbe} @@ -39,6 +40,12 @@ class T1OM extends Class { @public val lanesIn = IO(Input(Property[Seq[AnyClassType]]())) lanes := lanesIn + + @public + val decoder = IO(Output(Property[AnyClassType]())) + @public + val decoderIn = IO(Input(Property[AnyClassType]())) + decoder := decoderIn } object T1Parameter { @@ -84,6 +91,7 @@ case class T1Parameter( vLen: Int, dLen: Int, extensions: Seq[String], + t1customInstructions: Seq[T1CustomInstruction], // LSU lsuBankParameters: Seq[LSUBankParameter], // Lane @@ -111,6 +119,17 @@ case class T1Parameter( |""".stripMargin}} |""".stripMargin + val allInstructions: Seq[Instruction] = { + org.chipsalliance.rvdecoderdb.instructions(org.chipsalliance.rvdecoderdb.extractResource(getClass.getClassLoader)) + .filter(instruction => instruction.instructionSet.name == "rv_v")++ + t1customInstructions.map(_.instruction) + }.toSeq.sortBy(_.instructionSet.name).filter{ + insn => insn.name match { + case s if Seq("vsetivli", "vsetvli", "vsetvl").contains(s) => false + case _ => true + } + } + require(extensions.forall(Seq("Zve32x", "Zve32f").contains), "unsupported extension.") // TODO: require bank not overlap /** xLen of T1, we currently only support 32. */ @@ -208,6 +227,8 @@ case class T1Parameter( // and the values are their respective delays. val crossLaneConnectCycles: Seq[Seq[Int]] = Seq.tabulate(laneNumber)(_ => Seq(1, 1)) + val decoderParam: DecoderParam = DecoderParam(fpuEnable, allInstructions) + /** parameter for TileLink. */ val tlParam: TLBundleParameter = TLBundleParameter( a = TLChannelAParameter(physicalAddressWidth, sourceWidth, memoryDataWidthBytes * 8, sizeWidth, maskWidth), @@ -228,6 +249,7 @@ case class T1Parameter( fpuEnable = fpuEnable, portFactor = vrfBankSize, vrfRamType = vrfRamType, + decoderParam = decoderParam, vfuInstantiateParameter = vfuInstantiateParameter ) /** Parameter for each LSU. */ @@ -308,7 +330,8 @@ class T1(val parameter: T1Parameter) extends Module with SerializableModule[T1Pa /** the LSU Module */ val lsu: Instance[LSU] = Instantiate(new LSU(parameter.lsuParameters)) - val decode: Instance[VectorDecoder] = Instantiate(new VectorDecoder(parameter.fpuEnable)) + val decode: Instance[VectorDecoder] = Instantiate(new VectorDecoder(parameter.decoderParam)) + omInstance.decoderIn := Property(decode.om.asAnyClassType) // TODO: cover overflow // TODO: uarch doc about the order of instructions diff --git a/t1/src/VectorDecoder.scala b/t1/src/VectorDecoder.scala index 432e132a9..f6f7cd1ed 100644 --- a/t1/src/VectorDecoder.scala +++ b/t1/src/VectorDecoder.scala @@ -4,16 +4,35 @@ package org.chipsalliance.t1.rtl import chisel3._ -import chisel3.experimental.hierarchy.{instantiable, public} +import chisel3.experimental.hierarchy.{Instance, Instantiate, instantiable, public} +import chisel3.properties.{AnyClassType, Class, ClassType, Property} import chisel3.util.experimental.decode._ -import org.chipsalliance.t1.rtl.decoder.Decoder +import org.chipsalliance.t1.rtl.decoder.{Decoder, DecoderParam} + @instantiable -class VectorDecoder(fpuEnable: Boolean) extends Module { +class VectorDecoderOM extends Class { + @public + val instructions = IO(Output(Property[Seq[AnyClassType]]())) + @public + val instructionsIn = IO(Input(Property[Seq[AnyClassType]]())) + instructions := instructionsIn +} + +@instantiable +class VectorDecoder(param: DecoderParam) extends Module { + val omInstance: Instance[VectorDecoderOM] = Instantiate(new VectorDecoderOM) + val omType: ClassType = omInstance.toDefinition.getClassType + @public + val om: Property[ClassType] = IO(Output(Property[omType.Type]())) + om := omInstance.getPropertyReference + @public val decodeInput: UInt = IO(Input(UInt(32.W))) @public - val decodeResult: DecodeBundle = IO(Output(new DecodeBundle(Decoder.all(fpuEnable)))) + val decodeResult: DecodeBundle = IO(Output(new DecodeBundle(Decoder.allFields(param)))) + + omInstance.instructionsIn := Property(Decoder.allDecodePattern(param).map(_.om.asAnyClassType)) - decodeResult := Decoder.decode(fpuEnable)(decodeInput) + decodeResult := Decoder.decode(param)(decodeInput) } diff --git a/t1/src/decoder/Decoder.scala b/t1/src/decoder/Decoder.scala index 3233105e8..3ebe07df3 100644 --- a/t1/src/decoder/Decoder.scala +++ b/t1/src/decoder/Decoder.scala @@ -5,1033 +5,432 @@ package org.chipsalliance.t1.rtl.decoder import chisel3._ import chisel3.util.BitPat -import chisel3.util.experimental.decode.{DecodeField, BoolDecodeField, DecodeTable, DecodeBundle, DecodePattern} -import org.chipsalliance.rvdecoderdb -import org.chipsalliance.rvdecoderdb.{Encoding, Instruction, InstructionSet} +import chisel3.util.experimental.decode._ +import org.chipsalliance.rvdecoderdb.Instruction +import org.chipsalliance.t1.rtl.T1Parameter +import org.chipsalliance.t1.rtl.decoder.attribute._ -trait FieldName { - def name: String = this.getClass.getSimpleName.replace("$", "") +object DecoderParam { + implicit def rwP: upickle.default.ReadWriter[DecoderParam] = upickle.default.macroRW } +case class DecoderParam(fpuEnable: Boolean, allInstructions: Seq[Instruction]) -trait UopField extends DecodeField[Op, UInt] with FieldName { - def chiselType: UInt = UInt(4.W) -} +trait T1DecodeFiled[D <: Data] extends DecodeField[T1DecodePattern, D] with FieldName -trait FloatType extends DecodeField[Op, UInt] with FieldName { - def chiselType: UInt = UInt(2.W) +trait BoolField extends T1DecodeFiled[Bool] with BoolDecodeField[T1DecodePattern] { + def getTriState(pattern: T1DecodePattern): TriState + + override def genTable(pattern: T1DecodePattern): BitPat = + getTriState(pattern) match { + case attribute.Y => y + case attribute.N => n + case attribute.DC => dc + } } -trait TopUopField extends DecodeField[Op, UInt] with FieldName { - def chiselType: UInt = UInt(3.W) +trait T1UopField extends T1DecodeFiled[UInt] with FieldName { + def chiselType: UInt = UInt(4.W) } -trait BoolField extends BoolDecodeField[Op] with FieldName { - def dontCareCase(op: Op): Boolean = false - // 如果包含lsu, 那么value不会被纠正, 否则value只在不是lsu的情况下被视为1 - def containsLSU: Boolean = false - def value(op: Op): Boolean - def genTable(op: Op): BitPat = if (dontCareCase(op)) dc else if (value(op) && (containsLSU || op.notLSU)) y else n +trait T1TopUopField extends T1DecodeFiled[UInt] with FieldName { + def chiselType: UInt = UInt(3.W) } -case class SpecialAux(name: String, vs: Int, value: String) -case class SpecialMap(name: String, vs: Int, data: Map[String, String]) -case class SpecialAuxInstr(instrName: String, vs: Int, value: String, name: String) -case class Op(tpe: String, funct6: String, tpeOp2: String, funct3: String, - name: String, special: Option[SpecialAux], notLSU: Boolean, vd: String, opcode: String) extends DecodePattern { - // include 32 bits: funct6 + vm + vs2 + vs1 + funct3 + vd + opcode - def bitPat: BitPat = BitPat( - "b" + - // funct6 - funct6 + - // ? for vm - "?" + - // vs2 - (if (special.isEmpty || special.get.vs == 1) "?????" else special.get.value) + - // vs1 - (if (special.isEmpty || special.get.vs == 2) "?????" else special.get.value) + - // funct3 - funct3 + - vd + - opcode - ) +trait T1fpExecutionTypeUopField extends T1DecodeFiled[UInt] with FieldName { + def chiselType: UInt = UInt(2.W) } object Decoder { - // Opcode: instruction[6:0] - // refer to [https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#vector-instruction-formats] - private val opcodeV = "1010111" - private val opcodeLoadF = "0000111" - private val opcodeStoreF = "0100111" - - // Funct3: instruction[14:12] - // refer to [https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#101-vector-arithmetic-instruction-encoding] - private val funct3IVV = "000" - private val funct3IVI = "011" - private val funct3IVX = "100" - private val funct3MVV = "010" - private val funct3MVX = "110" - private val funct3FVV = "001" - private val funct3FVF = "101" - private val funct3CFG = "111" // TODO: need implementations - - // type of rs1 - private val op1iFunct3 = Seq(funct3IVV, funct3IVI, funct3IVX) - private val op1mFunct3 = Seq(funct3MVV, funct3MVX) - private val op1fFunct3 = Seq(funct3FVV, funct3FVF) - private val op1cFunct3 = Seq(funct3CFG) - // type of rs2 - private val op2vFunct3 = Seq(funct3IVV, funct3MVV, funct3FVV) - private val op2xFunct3 = Seq(funct3IVX, funct3MVX) - private val op2iFunct3 = Seq(funct3IVI) - private val op2fFunct3 = Seq(funct3FVF) - - // special instrctions - // refer to [https://github.com/riscv/riscv-v-spec/blob/master/inst-table.adoc] - private val insnVRXUNARY0 = SpecialMap("VRXUNARY0", 2, Map("vmv.s.x" -> "00000")) - private val insnVWXUNARY0 = SpecialMap("VWXUNARY0", 1, Map( - "vmv.x.s" -> "00000", - "vcpop" -> "10000", - "vfirst" -> "10001", - ) - ) - private val insnVXUNARY0 = SpecialMap("VXUNARY0", 1, Map( - "vzext.vf8" -> "00010", - "vsext.vf8" -> "00011", - "vzext.vf4" -> "00100", - "vsext.vf4" -> "00101", - "vzext.vf2" -> "00110", - "vsext.vf2" -> "00111" - ) - ) - private val insnVRFUNARY0 = SpecialMap("VRFUNARY0", 2, Map("vfmv.s.f" -> "00000")) - private val insnVWFUNARY0 = SpecialMap("VWFUNARY0", 1, Map("vfmv.f.s" -> "00000")) - private val insnVFUNARY0 = SpecialMap("VFUNARY0", 1, Map( - // single-width converts - "vfcvt.xu.f.v" -> "00000", - "vfcvt.x.f.v" -> "00001", - "vfcvt.f.xu.v" -> "00010", - "vfcvt.f.x.v" -> "00011", - "vfcvt.rtz.xu.f.v" -> "00110", - "vfcvt.rtz.x.f.v" -> "00111", - // widening converts - "vfwcvt.xu.f.v" -> "01000", - "vfwcvt.x.f.v" -> "01001", - "vfwcvt.f.xu.v" -> "01010", - "vfwcvt.f.x.v" -> "01011", - "vfwcvt.f.f.v" -> "01100", - "vfwcvt.rtz.xu.f.v" -> "01110", - "vfwcvt.rtz.x.f.v" -> "01111", - // narrowing converts - "vfncvt.xu.f.w" -> "10000", - "vfncvt.x.f.w" -> "10001", - "vfncvt.f.xu.w" -> "10010", - "vfncvt.f.x.w" -> "10011", - "vfncvt.f.f.w" -> "10100", - "vfncvt.rod.f.f.w" -> "10101", - "vfncvt.rtz.xu.f.w" -> "10110", - "vfncvt.rtz.x.f.w" -> "10111", - ) - ) - private val insnVFUNARY1 = SpecialMap("VFUNARY1", 1, Map( - "vfsqrt.v" -> "00000", - "vfrsqrt7.v" -> "00100", - "vfrec7.v" -> "00101", - "vfclass.v" -> "10000", - ) - ) - private val insnVMUNARY0 = SpecialMap("VMUNARY0", 1, Map( - "vmsbf" -> "00001", - "vmsof" -> "00010", - "vmsif" -> "00011", - "viota" -> "10000", - "vid" -> "10001", - ) - ) - def insnVToSpecialAux(insns: SpecialMap): Seq[SpecialAuxInstr] = { - val vs = insns.vs - val name = insns.name - insns.data.map { case (instrName, value) => - SpecialAuxInstr(instrName, vs, value, name) - }.toSeq - } - private val insnSpec: Seq[SpecialAuxInstr] = insnVToSpecialAux(insnVRXUNARY0) ++ insnVToSpecialAux(insnVWXUNARY0) ++ insnVToSpecialAux(insnVXUNARY0) ++ insnVToSpecialAux(insnVRFUNARY0) ++ insnVToSpecialAux(insnVWFUNARY0) ++ insnVToSpecialAux(insnVFUNARY0) ++ insnVToSpecialAux(insnVFUNARY1) ++ insnVToSpecialAux(insnVMUNARY0) - - def ops(fpuEnable: Boolean): Array[Op] = { - val instructions: Seq[Instruction] = (org.chipsalliance.rvdecoderdb.instructions(org.chipsalliance.rvdecoderdb.extractResource(getClass.getClassLoader))).filter { i => - i.instructionSets.map(_.name) match { - case s if s.contains("rv_v") => true - case _ => false - } - }.filter { i => - i.name match { - // csr instructions - case s if Seq("vsetivli", "vsetvli", "vsetvl").contains(s) => false - // instrctions `vmv` and `vmerge` share the same opcode, as defined in [https://github.com/riscv/riscv-v-spec/blob/master/inst-table.adoc] - case s if s.contains("vmv.v") => false - // instructions `vfmv.v.f` and `vfmerge.vfm` share the same opcode, as defined in [https://github.com/riscv/riscv-v-spec/blob/master/inst-table.adoc] - case s if s.contains("vfmv.v.f") => false - case _ => true - } - }.toSeq.distinct - val expandedOps: Array[Op] = - // case of notLSU instructions - (instructions.filter(_.encoding.toString.substring(32-6-1, 32-0) == opcodeV).map{ insn => - val funct3 = insn.encoding.toString.substring(32-14-1, 32-12) - - val tpe = if (op1iFunct3.contains(funct3)) "I" else if (op1mFunct3.contains(funct3)) "M" else if (op1fFunct3.contains(funct3)) "F" else "" // TODO: OPCFG - val tpeOp2 = if (op2vFunct3.contains(funct3)) "V" else if (op2xFunct3.contains(funct3)) "X" else if (op2iFunct3.contains(funct3)) "I" else if (op2fFunct3.contains(funct3)) "F" else "" // TODO: OPCFG - val funct6 = insn.encoding.toString.substring(32-31-1, 32-26) - val special = insnSpec.collectFirst { case s if (insn.name.contains(s.instrName)) => SpecialAux(s.name, s.vs, s.value) } - val vd = insn.encoding.toString.substring(32-11-1, 32-7) - val opcode = insn.encoding.toString.substring(32-6-1, 32-0) - Op(tpe, funct6, tpeOp2, funct3, insn.name, special, notLSU=true, vd, opcode) - } - // case of LSU instructions: `opcodeLoadF` and `opcodeStoreF` - ++ Seq("1", "0").map(fun6End => - Op( - "I", // tpe - "?????" + fun6End, - "?", // tpeOp2 - "???", // funct3 - "lsu", - None, - notLSU = false, - "?????", // vd - opcodeLoadF - ) - ) - ++ Seq("1", "0").map(fun6End => - Op( - "I", // tpe - "?????" + fun6End, - "?", // tpeOp2 - "???", // funct3 - "lsu", - None, - notLSU = false, - "?????", // vd - opcodeStoreF - ) - ) - ).toArray - - expandedOps.filter(_.tpe != "F" || fpuEnable) - } - - /** Instruction should use [[org.chipsalliance.t1.rtl.decoder.TableGenerator.LaneDecodeTable.LogicUnit]]. - * "vand.vi" - * "vand.vv" - * "vand.vx" - * "vmand.mm" - * "vmandn.mm" - * "vmnand.mm" - * "vredand.vs" - * "vmnor.mm" - * "vmor.mm" - * "vmorn.mm" - * "vmxnor.mm" - * "vmxor.mm" - * "vor.vi" - * "vor.vv" - * "vor.vx" - * "vredor.vs" - * "vredxor.vs" - * "vxor.vi" - * "vxor.vv" - * "vxor.vx" - */ object logic extends BoolField { - val subs: Seq[String] = Seq("and", "or") - // 执行单元现在不做dc,因为会在top判断是否可以chain - def value(op: Op): Boolean = subs.exists(op.name.contains) && op.tpe != "F" + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isLogic.value } - /** goes to [[org.chipsalliance.t1.rtl.LaneAdder]]. */ object adder extends BoolField { - val subs: Seq[String] = Seq( - "add", - "sub", - "slt", - "sle", - "sgt", - "sge", - "max", - "min", - "seq", - "sne", - "adc", - "sbc", - "sum" - ) - def value(op: Op): Boolean = subs.exists(op.name.contains) && - !(op.tpe == "M" && Seq("vm", "vnm").exists(op.name.startsWith)) && op.tpe != "F" + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isAdder.value } - /** goes to [[org.chipsalliance.t1.rtl.LaneShifter]]. */ object shift extends BoolField { - val subs: Seq[String] = Seq( - "srl", - "sll", - "sra" - ) - def value(op: Op): Boolean = subs.exists(op.name.contains) && op.tpe != "F" + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isShift.value } - /** goes to [[org.chipsalliance.t1.rtl.LaneMul]]. - * only apply to int mul - */ object multiplier extends BoolField { - val subs: Seq[String] = Seq( - "mul", - "madd", - "macc", - "msub", - "msac" - ) - def value(op: Op): Boolean = subs.exists(op.name.contains) && op.tpe != "F" + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isMultiplier.value } - /** goes to [[org.chipsalliance.t1.rtl.LaneDiv]] or [[org.chipsalliance.t1.rtl.LaneDivFP]]. - * if FP exist, all div goes to [[org.chipsalliance.t1.rtl.LaneDivFP]] - */ object divider extends BoolField { - val intDiv: Seq[String] = Seq( - "div", - "rem" - ) - val floatDiv: Seq[String] = Seq( - "fdiv", - "fsqrt", - "frdiv" - ) - val subs: Seq[String] = intDiv ++ floatDiv - def value(op: Op): Boolean = subs.exists(op.name.contains) + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isDivider.value } - /** TODO: remove? only Div or customer */ object multiCycle extends BoolField { - def value(op: Op): Boolean = divider.value(op) || float.value(op) + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isMulticycle.value } - /** goes to [[org.chipsalliance.t1.rtl.OtherUnit]] */ object other extends BoolField { - val subs: Seq[String] = Seq( - "rgather", - "merge", - "mv", - // TODO: move to shift - "clip" - ) - def getType(op: Op): (Boolean, Int) = { - // todo: vType gather -> mv - val isGather = op.name.contains("rgather") - val isMerge = op.name.contains("merge") - val isClip = op.name.contains("clip") - val isFFO = ffo.value(op) - // extend read only - val extendType = Seq(mv, popCount, id) - val isMVtoFP = op.special.isDefined && op.special.get.name == "VWFUNARY0" - val isOtherType: Boolean = - !isMVtoFP && (Seq(isGather, isMerge, isClip, isFFO) ++ extendType.map(_.value(op))).reduce(_ || _) - // ++ffo - val otherType = Seq(isGather, isMerge, isClip) ++ extendType.map(_.value(op)) - val typeIndex = if (otherType.contains(true)) 4 + otherType.indexOf(true) else 0 - // ffo 占据 0, 1, 2, 3 作为字编码 - val otherUop = if (isFFO) ffo.subs.indexOf(op.name) else typeIndex - (isOtherType, otherUop) - } - - def value(op: Op): Boolean = getType(op)._1 + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isOther.value } - /** is a float type. - * TODO: remove it. - */ - object floatType extends BoolField { - def value(op: Op): Boolean = op.tpe == "F" + object unsigned0 extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isUnsigned0.value } - /** goes to [[org.chipsalliance.t1.rtl.LaneFloat]]. */ - object float extends BoolField { - def value(op: Op): Boolean = op.tpe == "F" && - !( - other.value(op) || - dontNeedExecuteInLane.value(op) || - slid.value(op) || divider.value(op)) + object unsigned1 extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isUnsigned1.value } - /** TODO: remove it. */ - object floatConvertUnsigned extends BoolField { - override def dontCareCase(op: Op): Boolean = !float.value(op) - def value(op: Op): Boolean = { - op.name.contains("fcvt") && op.name.contains(".xu.") - } + object itype extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isItype.value } - /** uop of FMA, - * goes to [[org.chipsalliance.t1.rtl.LaneFloat]] FMA unit. - */ - object FMA extends BoolField { - val adderSubsMap: Seq[(String, Int)] = Seq( - "vfadd" -> 0, - "vfsub" -> 1, - "vfrsub" -> 5, - ) - - // need read vd - val maMap: Seq[(String, Int)] = Seq( - "vfmacc" -> 0, - "vfnmacc" -> 3, - "vfmsac" -> 1, - "vfnmsac" -> 2, - "vfmadd" -> 4, - "vfnmadd" -> 7, - "vfmsub" -> 5, - "vfnmsub" -> 6, - ) - - val subsMap: Seq[(String, Int)] = Seq( - "vfmul" -> 0, - "vfredosum" -> 0, - "vfredusum" -> 0, - ) ++ adderSubsMap ++ maMap - - def value(op: Op): Boolean = subsMap.exists(a => op.name.contains(a._1)) - - def uop(op: Op): Int = { - val isAdder = adderSubsMap.exists(a => op.name.contains(a._1)) || op.name.contains("sum") - val msbCode = if (isAdder) 8 else 0 - // vfwadd 暂时不支持,所以没处理, 所有的widen narrow 会被解成 fma-0 - val mapFilter: Seq[(String, Int)] = subsMap.filter(a => op.name.contains(a._1)) - val lsbCode: Int = if (mapFilter.isEmpty) 0 else mapFilter.head._2 - msbCode + lsbCode - } + object nr extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isNr.value } - /** TODO: add op. */ - object floatMul extends BoolField { - def value(op: Op): Boolean = op.name.contains("vfmul") + object red extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isRed.value } - /** don't use it, it's slow, lane read all elements from VRF, send to Top. - */ - object orderReduce extends BoolField { - def value(op: Op): Boolean = op.name.contains("vfredosum") + object widenReduce extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isWidenreduce.value } - object FDiv extends BoolField { - // todo: remove FDiv - val subsMap: Seq[(String, Int)] = Seq.empty[(String, Int)] - def value(op: Op): Boolean = subsMap.exists(a => op.name.contains(a._1)) - - def uop(op: Op): Int = { - val mapFilter = subsMap.filter(a => op.name.contains(a._1)) - if (mapFilter.isEmpty) 0 else mapFilter.head._2 - } + object targetRd extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isTargetrd.value } - /** TODO: remove it, but remains attribute. */ - object FCompare extends BoolField { - val subsMap = Seq( - "vmfeq" -> 1, - "vmfge" -> 5, - "vmfgt" -> 4, - "vmfle" -> 3, - "vmflt" -> 2, - "vmfne" -> 0, - "vfmin" -> 8, - "vfmax" -> 12, - "vfredmin" -> 8, - "vfredmax" -> 12, - ) - - def value(op: Op): Boolean = subsMap.exists(a => op.name.contains(a._1)) - - def uop(op: Op): Int = { - val mapFilter = subsMap.filter(a => op.name.contains(a._1)) - if (mapFilter.isEmpty) 0 else mapFilter.head._2 - } + object slid extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isSlid.value } - /** designed for Other Unit in FP. - * goes to [[org.chipsalliance.t1.rtl.LaneFloat]] OtherUnit. - * TODO: perf it. - */ - object FOther extends BoolField { - val unsignedMap = Seq( - "vfcvt.f.xu.v" -> 8, - "vfcvt.rtz.xu.f.v" -> 13, - ) - val subsMap = Seq( - "vfcvt.f.x.v" -> 8, - "vfcvt.rtz.x.f.v" -> 14, - "vfcvt.x.f.v" -> 10, - "vfcvt.xu.f.v" -> 9, - "vfsgnjn" -> 2, - "vfsgnjx" -> 3, - "vfsgnj" -> 1, - "vfclass" -> 4, - "vfrsqrt7" -> 7, - "vfrec7" -> 6, - ) ++ unsignedMap - - def value(op: Op): Boolean = subsMap.exists(a => op.name.contains(a._1)) - - def uop(op: Op): Int = { - val mapFilter = subsMap.filter(a => op.name.contains(a._1)) - if (mapFilter.isEmpty) 0 else mapFilter.head._2 - } + object gather extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isGather.value } - /** float uop, goes to [[org.chipsalliance.t1.rtl.LaneFloatRequest.unitSelet]] - * TODO: remove FDiv. move to VFU uop - */ - object fpExecutionType extends FloatType { - def genTable(op: Op): BitPat = { - val code: Int = if (FDiv.value(op)) 1 else if (FCompare.value(op)) 2 else if (FOther.value(op)) 3 else 0 /* FMA */ - BitPat("b" + ("00" + code.toBinaryString).takeRight(2)) - } + object gather16 extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isGather16.value } - /** There are two types of widen: - * - vd -> widen. - * - vs2, vd -> widen. - * - * This op will widen vs2. - * TODO: remove it as attribute. - */ - object firstWiden extends BoolField { - def value(op: Op): Boolean = { - val nameWoW = op.name.replace(".wf", ".w").replace(".wx", ".w").replace(".wv", ".w") - nameWoW.endsWith(".w") || vwmacc.value(op) - } + object compress extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isCompress.value } - /** for vmvnr, move vreg group to another vreg group. - * it will ignore lmul, use from instr. - * chainable - */ - object nr extends BoolField { - // for instructions `vmv1r.v`,`vmv2r.v`, `vmv4r.v`, `vmv8r.v` - def value(op: Op): Boolean = Seq("vmv1r.v","vmv2r.v", "vmv4r.v", "vmv8r.v").contains(op.name) + object unOrderWrite extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isUnorderwrite.value } - /** do reduce in each lane. - * each element will sequentially executed in each lanes. - * after finishing, pop it to Top, and use ALU at top to get the final result and send to element0 - * TODO: better name. - */ - object red extends BoolField { - // reduce 会影响special, special会极大地影响性能, 所以不能dc - def value(op: Op): Boolean = op.name.contains("red") || op.name.contains("pop") + object extend extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isExtend.value } - // TODO: remove this. - object maskOp extends BoolField { - def value(op: Op): Boolean = op.name.startsWith("vm") && - ((adder.value(op) && !Seq("min", "max").exists(op.name.contains)) || logic.value(op)) + object mv extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isMv.value } - /** only instruction will switch src. - * TODO: send it to uop. - */ - object reverse extends BoolField { - def value(op: Op): Boolean = op.name.contains("vrsub") + object iota extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isIota.value } - /** dual width of src will be convert to single width to dst. - * narrow can be the src of chain. - * as the dst of chain, only can be fed with Load. - * - * TODO: remove it as attribute. - */ - object narrow extends BoolField { - val subs: Seq[String] = Seq( - "vnsrl", - "vnsra", - "vnclip" - ) - // todo: 确认是否可以dc - override def dontCareCase(op: Op): Boolean = op.special.nonEmpty - def value(op: Op): Boolean = subs.exists(op.name.contains) + object maskLogic extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isMasklogic.value } - /** lane should write to another lane - */ - object crossWrite extends BoolField { - override def dontCareCase(op: Op): Boolean = op.special.nonEmpty - def value(op: Op): Boolean = op.name.startsWith("vw") && !op.name.startsWith("vwred") + object maskDestination extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isMaskdestination.value } - /** a special widen, only write dual vd from Top to element0 - * it doesn't cross. - * TODO: better name. - */ - object widenReduce extends BoolField { - override def dontCareCase(op: Op): Boolean = op.special.nonEmpty - def value(op: Op): Boolean = op.name.startsWith("vwred") + object maskSource extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isMasksource.value } - /** For adder, does it need to take care of saturate. - * TODO: add to uop - */ - object saturate extends BoolField { - override def dontCareCase(op: Op): Boolean = op.special.nonEmpty - def value(op: Op): Boolean = Seq("vsa", "vss", "vsm").exists(op.name.startsWith) + object readOnly extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isReadonly.value } - /** For adder, does it need to take care of saturate. - * TODO: add to uop - */ - object average extends BoolField { - val subs: Seq[String] = Seq( - "vaa", - "vas" - ) - override def dontCareCase(op: Op): Boolean = op.special.nonEmpty - def value(op: Op): Boolean = subs.exists(op.name.startsWith) + object vwmacc extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isVwmacc.value } - /** is src0 unsigned? - * used everywhere in Lane and VFU. - */ - object unsigned0 extends BoolField { - def value(op: Op): Boolean = { - val nameWoW = op.name.replace(".vv", "").replace(".vi", "").replace(".vx", "").replace(".vs", "").replace(".wi", "").replace(".wx", "").replace(".wv", "") - val logicShift = shift.genTable(op) == y && nameWoW.endsWith("l") - val UIntOperation = nameWoW.endsWith("u") && !nameWoW.endsWith("su") - val mul = op.name.contains("mulhsu") || op.name.contains("wmulsu") || op.name.contains("vwmaccus") - val madc = Seq("adc", "sbc").exists(op.name.contains) && op.name.startsWith("vm") - op.special.nonEmpty || logicShift || UIntOperation || mul || madc - } + object saturate extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isSaturate.value } - /** is src1 unsigned? - * used everywhere in Lane and VFU. - */ - object unsigned1 extends BoolField { - def value(op: Op): Boolean = { - val nameWoW = op.name.replace(".vv", "").replace(".vi", "").replace(".vx", "").replace(".vs", "").replace(".wi", "").replace(".wx", "").replace(".wv", "") - val logicShift = shift.genTable(op) == y && nameWoW.endsWith("l") - val UIntOperation = nameWoW.endsWith("u") && !nameWoW.endsWith("su") - val madc = Seq("adc", "sbc").exists(op.name.contains) && op.name.startsWith("vm") - val vwmaccsu = op.name.contains("vwmaccsu") - if (floatType.value(op)) { - FOther.unsignedMap.exists(a => op.name.contains(a._1)) - } else { - op.special.nonEmpty || logicShift || UIntOperation || madc || vwmaccsu - } - } + object special extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isSpecial.value } - /** src1 is vtype. */ - object vtype extends BoolField { - def value(op: Op): Boolean = op.tpeOp2 == "V" + object maskUnit extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isMaskunit.value } - /** src is imm. */ - object itype extends BoolField { - def value(op: Op): Boolean = op.tpeOp2 == "I" + object crossWrite extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isCrosswrite.value } - /** write rd/fd at scalar core. */ - object targetRd extends BoolField { - def value(op: Op): Boolean = op.special.isDefined && - (op.special.get.name == "VWXUNARY0" || op.special.get.name == "VWFUNARY0") + object crossRead extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isCrossread.value } - /** send element to MaskUnit at top, extend and broadcast to multiple Lanes. */ - object extend extends BoolField { - def value(op: Op): Boolean = op.special.isDefined && op.special.get.name == "VXUNARY0" + object sWrite extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isSwrite.value } - /** move instruction, v->v s->v x->v, - * single element move. - * TODO: split them into multiple op since datapath differs - */ - object mv extends BoolField { - def value(op: Op): Boolean = (op.name.startsWith("vmv") || op.name.startsWith("vfmv")) && !nr.value(op) + object vtype extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isVtype.value } - /** find first one, - * lane will report if 1 is found, Sequencer should decide which is exactly the first 1 in lanes. - * after 1 is found, tell each lane, 1 has been found at which the corresponding location. - * lane will stale at stage2. - * TODO: should split into lane control uop - */ - object ffo extends BoolField { - val subs: Seq[String] = Seq( - "vfirst.m", - "vmsbf.m", - "vmsof.m", - "vmsif.m" - ) - - def value(op: Op): Boolean = subs.exists(op.name.contains) + object sReadVD extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isSreadvd.value } - /** used in Sequencer mask unit, decide which vrf should be read. - * send read request to corresponding lane, lane will respond data to Sequencer. - * Sequencer will write data to VD. - * mask unit is work as the router here. - * - * TODO: opimize mask unit. - */ - object slid extends BoolField { - def value(op: Op): Boolean = op.name.contains("slid") + object scheduler extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isScheduler.value } - /** lane will read index from vs1, send to Sequencer. - * mask unit will calculate vrf address based on the vs1 from lane, and send read request to lanes, - * lanes should read it and send vs2 to Sequencer. - * Sequencer will write vd at last. - * address: 0 -> vlmax(sew decide address width.) - */ - object gather extends BoolField { - def value(op: Op): Boolean = op.name.contains("rgather") + object dontNeedExecuteInLane extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isDontneedexecuteinlane.value } - /** same with [[gather]] - * ignore sew, address width is fixed to 16. - * - * @note - * When SEW=8, vrgather.vv can only reference vector elements 0-255. - * The vrgatherei16 form can index 64K elements, - * and can also be used to reduce the register capacity needed to hold indices when SEW > 16. - */ - object gather16 extends BoolField { - def value(op: Op): Boolean = op.name.contains("rgatherei16") + object reverse extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isReverse.value } - /** lane will read data from vs2, send to Sequencer. - * then Sequencer will read vs1 for mask. - * use mask to compress data in vs2. - * and write to vd at last. - */ - object compress extends BoolField { - def value(op: Op): Boolean = op.name.contains("compress") + object average extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isAverage.value } - /** lane read only instructions. - * for these instructions lane will only read vrf and send data back to Sequencer. - */ - object readOnly extends BoolField { - def value(op: Op): Boolean = { - val vGather: Boolean = op.name.contains("gather") && vtype.genTable(op) == y - val compress: Boolean = op.name.contains("compress") - val iota: Boolean = op.name.contains("iota") - val extend: Boolean = op.name.contains("ext.vf") - vGather || compress || iota || extend - } + object ffo extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isFfo.value } - /** count how many 1s in VS2. - * lane will use [[org.chipsalliance.t1.rtl.OtherUnit]] to how many 1s locally; - * use reduce datapath to accumulate, - * send total result to top - * top will send result to vd. - */ object popCount extends BoolField { - def value(op: Op): Boolean = op.name.contains("vcpop") + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isPopcount.value } - /** lane will read vs2 from VRF, send to Top. - * Top read v0(at register) calculate the result and write back to VRFs - */ - object iota extends BoolField { - def value(op: Op): Boolean = op.name.contains("viota") + object specialSlot extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isSpecialslot.value } - /** write 0...vlmax to VRF. - * Lane other unit should handle it. - * TODO: remove it, it's a uop. - */ - object id extends BoolField { - def value(op: Op): Boolean = op.name.contains("vid") + object float extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isFloat.value } - /** special MAC instruction, MAC use vd as source, it cross read vd. - * TODO: cross read vd + mac uop. - */ - object vwmacc extends BoolField { - def value(op: Op): Boolean = op.name.contains("vwmacc") + object floatMul extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isFloatmul.value } - /** unmanaged write for VRF. these instructions cannot be chain as source. - * - * TODO: add an attribute these instruction cannot be the source of chaining. - */ - object unOrderWrite extends BoolField { - def value(op: Op): Boolean = slid.value(op) || iota.value(op) || mv.value(op) || orderReduce.value(op) + object orderReduce extends BoolField { + override def getTriState(pattern: T1DecodePattern): TriState = pattern.isOrderreduce.value + } + + object topUop extends T1TopUopField { + override def genTable(pattern: T1DecodePattern): BitPat = pattern.topUop.value match { + case _: TopT0.type => BitPat("b000") + case _: TopT1.type => BitPat("b001") + case _: TopT2.type => BitPat("b010") + case _: TopT3.type => BitPat("b011") + case _: TopT5.type => BitPat("b101") + case _: TopT6.type => BitPat("b110") + case _: TopT7.type => BitPat("b111") + case _ => BitPat.dontCare(3) + } } - /** VFU uop: - * TODO: need full documentation on how to encode it. - */ - object uop extends UopField { - val mul: Seq[String] = Seq( - "mul", - "ma", - "ms" - ) - - def y: BitPat = BitPat.Y(1) - def genTable(op: Op): BitPat = { - val firstIndexContains = (xs: Iterable[String], s: String) => - xs.map(s.indexOf).zipWithIndex.filter(_._1 != -1).head._2 - val opcode: Int = if(float.value(op)) { - if (FMA.value(op)) { - FMA.uop(op) - } else if (FDiv.value(op)) { - FDiv.uop(op) - } else if (FCompare.value(op)) { - FCompare.uop(op) - } else { - FOther.uop(op) + object uop extends T1UopField { + override def genTable(pattern: T1DecodePattern): BitPat = pattern.decoderUop.value match { + case addCase: AdderUOPType => + addCase match { + case _: addUop0.type => BitPat("b0000") + case _: addUop1.type => BitPat("b0001") + case _: addUop10.type => BitPat("b1010") + case _: addUop11.type => BitPat("b1011") + case _: addUop2.type => BitPat("b0010") + case _: addUop3.type => BitPat("b0011") + case _: addUop4.type => BitPat("b0100") + case _: addUop6.type => BitPat("b0110") + case _: addUop7.type => BitPat("b0111") + case _: addUop8.type => BitPat("b1000") + case _: addUop9.type => BitPat("b1001") + case _ => BitPat.dontCare(4) } - } else if (multiplier.value(op)) { - val nameWoW = op.name.replace(".vv", "").replace(".vi", "").replace(".vx", "").replace(".vs", "") - val high = nameWoW.contains("mulh") - // 0b1000 - val negative = if (nameWoW.startsWith("vn")) 8 else 0 - // 0b100 - val asAddend = if (Seq("c", "cu", "cus", "csu").exists(nameWoW.endsWith)) 4 else 0 - val n = if (high) 3 else firstIndexContains(mul, nameWoW) - negative + asAddend + n - } else if (divider.value(op)) { - if (op.tpe != "F") { - firstIndexContains(divider.intDiv, op.name) - } else { - 8 + firstIndexContains(divider.floatDiv, op.name) + case divCase: DivUOPType => + divCase match { + case _: divUop0.type => BitPat("b0000") + case _: divUop1.type => BitPat("b0001") + case _: divUop10.type => BitPat("b1010") + case _: divUop8.type => BitPat("b1000") + case _: divUop9.type => BitPat("b1001") + case _ => BitPat.dontCare(4) } - } else if (adder.value(op)) { - if (op.name.contains("sum")) 0 else firstIndexContains(adder.subs, op.name) - } else if (logic.value(op)) { - val nameWoW = op.name.replace(".mm", "") - val isXnor = op.name.contains("vmxnor") - val isXor = op.name.contains("xor") - val notX = if (op.name.startsWith("vmn")) 8 else 0 - val xNot = if (isXnor || nameWoW.endsWith("n")) 4 else 0 - val subOp = if (isXnor || isXor) 2 else firstIndexContains(logic.subs, op.name) - notX + xNot + subOp - } else if (shift.value(op)) { - val subOp = firstIndexContains(shift.subs, op.name) - require(subOp < 4) - val ssr = if (op.name.contains("ssr")) 4 else 0 - subOp + ssr - } else if (other.value(op)) { - other.getType(op)._2 - } else 0 - if (!op.notLSU) { - BitPat("b" + "????") - } else { - BitPat("b" + ("0000" + opcode.toBinaryString).takeRight(4)) - } - } - } - - - /** uop for mask unit. */ - object topUop extends TopUopField { - def genTable(op: Op): BitPat = { - val isSlide = slid.value(op) - val isExtend = extend.value(op) - val log2 = (x: Int) => (math.log10(x) / math.log10(2)).toInt - val opcode = if (isSlide) { - val up = if (op.name.contains("up")) 2 else 0 - val slid1 = if (op.name.contains("slide1")) 1 else 0 - up + slid1 - } else if (isExtend) { - val signExtend = if (op.name.startsWith("vs")) 4 else 0 - val extUop = log2(op.name.last.toString.toInt) - signExtend + extUop - } else 0 - BitPat("b" + ("000" + opcode.toBinaryString).takeRight(3)) - } - } - - /** only one or two operators - * src is mask format(one element one bit). - * vl should align with src. - * if datapath is unaligned, need to take care the tail. - */ - object maskLogic extends BoolField { - def value(op: Op): Boolean = { - // todo: rename maskLogic -> maskOperation - val otherMaskOperation = Seq("sbf", "sif", "sof", "first", "cpop", "viota").exists(op.name.contains) - val logicMaskOperation = op.name.startsWith("vm") && logic.genTable(op) == y - logicMaskOperation || otherMaskOperation - } - } - - /** vd is mask format. - * execute at lane, send result to Sequencer, regroup it and write to vd. - * if datapath is unaligned, need to take care the tail. - */ - object maskDestination extends BoolField { - def value(op: Op): Boolean = - (op.name.startsWith("vm") && adder.value(op) && !Seq("min", "max").exists(op.name.contains)) || - (op.name.startsWith("vm") && floatType.value(op)) - } - - /** three ops. these ops don't use mask. use v0 as third op, read it from duplicate V0. - * it will read - * use mask(v0) in mask format as source. - */ - object maskSource extends BoolField { - def value(op: Op): Boolean = Seq("vadc", "vsbc", "vmadc", "vmsbc", "vmerge", "vfmerge").exists(op.name.startsWith) - } - - - /** TODO: remove it. */ - object indexType extends BoolField { - override def containsLSU: Boolean = true - // funct6 的最低位是mop(0) - def value(op: Op): Boolean = !op.notLSU && op.funct6.endsWith("1") - } - - /** if Sequencer is the router for data from Lane to LSU or Sequencer mask unit. - * special -> maskUnit || index type load store - */ - object special extends BoolField { - override def containsLSU: Boolean = true - def value(op: Op): Boolean = { - Seq(indexType, maskUnit).map(_.value(op)).reduce(_ || _) - } - } - - // mask unit -> red || compress || viota || ffo || slid || maskDestination || gather(v) || mv || popCount || extend - /** all instruction in Sequencer mask unit. */ - object maskUnit extends BoolField { - def value(op: Op): Boolean = { - Seq(red, compress, iota, ffo, slid, maskDestination, mv, popCount, extend) - .map(_.value(op)) - .reduce(_ || _) || (gather.value(op) && vtype.value(op)) + case floatCase: FloatUopType => + floatCase match { + case _: FUT0.type => BitPat("b0000") + case _: FUT1.type => BitPat("b0001") + case _: FUT10.type => BitPat("b1010") + case _: FUT12.type => BitPat("b1100") + case _: FUT13.type => BitPat("b1101") + case _: FUT14.type => BitPat("b1110") + case _: FUT2.type => BitPat("b0010") + case _: FUT3.type => BitPat("b0011") + case _: FUT4.type => BitPat("b0100") + case _: FUT5.type => BitPat("b0101") + case _: FUT6.type => BitPat("b0110") + case _: FUT7.type => BitPat("b0111") + case _: FUT8.type => BitPat("b1000") + case _: FUT9.type => BitPat("b1001") + case _ => BitPat.dontCare(4) + } + case logicCase: LogicUopType => + logicCase match { + case _: logicUop0.type => BitPat("b0000") + case _: logicUop1.type => BitPat("b0001") + case _: logicUop2.type => BitPat("b0010") + case _: logicUop4.type => BitPat("b0100") + case _: logicUop5.type => BitPat("b0101") + case _: logicUop6.type => BitPat("b0110") + case _: logicUop8.type => BitPat("b1000") + case _: logicUop9.type => BitPat("b1001") + case _ => BitPat.dontCare(4) + } + case mulCase: MulUOPType => + mulCase match { + case _: mulUop0.type => BitPat("b0000") + case _: mulUop1.type => BitPat("b0001") + case _: mulUop10.type => BitPat("b1010") + case _: mulUop14.type => BitPat("b1110") + case _: mulUop3.type => BitPat("b0011") + case _: mulUop5.type => BitPat("b0101") + case _ => BitPat.dontCare(4) + } + case otherCase: OtherUopType => + otherCase match { + case _: otherUop0.type => BitPat("b0000") + case _: otherUop1.type => BitPat("b0001") + case _: otherUop2.type => BitPat("b0010") + case _: otherUop3.type => BitPat("b0011") + case _: otherUop4.type => BitPat("b0100") + case _: otherUop5.type => BitPat("b0101") + case _: otherUop6.type => BitPat("b0110") + case _: otherUop7.type => BitPat("b0111") + case _: otherUop8.type => BitPat("b1000") + case _: otherUop9.type => BitPat("b1001") + case _ => BitPat.dontCare(4) + } + case shiftCase: ShiftUopType => + shiftCase match { + case _: shiftUop0.type => BitPat("b0000") + case _: shiftUop1.type => BitPat("b0001") + case _: shiftUop2.type => BitPat("b0010") + case _: shiftUop4.type => BitPat("b0100") + case _: shiftUop6.type => BitPat("b0110") + case _ => BitPat.dontCare(4) + } + case zeroCase: ZeroUOPType => + zeroCase match { + case _: zeroUop0.type => BitPat("b0000") + case _ => BitPat.dontCare(4) + } + case _ => BitPat.dontCare(4) } } - /** Read vs2 or vd with cross read channel. */ - // crossRead -> narrow || firstWiden - object crossRead extends BoolField { - def value(op: Op): Boolean = Seq(narrow, firstWiden).map(_.value(op)).reduce(_ || _) - } - - //sWrite -> targetRd || readOnly || crossWrite || maskDestination || reduce || loadStore - /** instruction will write vd or rd(scalar) from outside of lane. - * It will request vrf wait, and lane will not write. - */ - object sWrite extends BoolField { - override def containsLSU: Boolean = true - def value(op: Op): Boolean = - Seq(targetRd, readOnly, crossWrite, maskDestination, red).map(_.value(op)).reduce(_ || _) || !op.notLSU - } - - // decodeResult(Decoder.multiplier) && decodeResult(Decoder.uop)(1, 0).xorR && !decodeResult(Decoder.vwmacc) - /** TODO: remove it. */ - object ma extends BoolField { - def value(op: Op): Boolean = { - (multiplier.value(op) && Seq(BitPat("b??01"), BitPat("b??10")).exists(_.cover(uop.genTable(op))) && - !vwmacc.value(op)) || (floatType.value(op) && FMA.maMap.exists(a => op.name.contains(a._1))) + object fpExecutionType extends T1fpExecutionTypeUopField { + override def genTable(pattern: T1DecodePattern): BitPat = pattern.fpExecutionType match { + case FpExecutionType.Compare => BitPat("b10") + case FpExecutionType.MA => BitPat("b00") + case FpExecutionType.Other => BitPat("b11") + case FpExecutionType.Nil => BitPat.dontCare(2) } } - // sReadVD -> !(ma || maskLogic) - /** instruction need to read vd as operator. */ - object sReadVD extends BoolField { - def value(op: Op): Boolean = !Seq(ma, maskLogic).map(_.value(op)).reduce(_ || _) - } - - // wScheduler 原来与 sScheduler 如果出错了需要检查一下,真不一样需要说明记录 - //sScheduler -> maskDestination || red || readOnly || ffo || popCount || loadStore - /** lane will send request to Sequencer and wait ack from Sequencer. */ - object scheduler extends BoolField { - override def containsLSU: Boolean = true - def value(op: Op): Boolean = !(Seq(maskDestination, red, readOnly, ffo, popCount).map(_.value(op)).reduce(_ || _) || !op.notLSU) + def allFields(param: DecoderParam): Seq[T1DecodeFiled[_ >: Bool <: UInt]] = Seq( + logic, + adder, + shift, + multiplier, + divider, + multiCycle, + other, + unsigned0, + unsigned1, + itype, + nr, + red, + // top only + widenReduce, + targetRd, + slid, + gather, + gather16, + compress, + unOrderWrite, + // top uop + extend, // top uop + mv, // top uop + iota, // top uop + uop, + maskLogic, + maskDestination, + maskSource, + readOnly, + vwmacc, + saturate, + special, + maskUnit, + crossWrite, + crossRead, + // state + sWrite, + //sRead1 -> vType + vtype, + sReadVD, + scheduler, + dontNeedExecuteInLane, + reverse, // uop + average, // uop + ffo, // todo: add mask select -> top uop + popCount, // top uop add, red, uop popCount + topUop, + specialSlot + ) ++ { + if (param.fpuEnable) + Seq( + float, + fpExecutionType, + floatMul, + orderReduce + ) + else Seq() } + def allDecodePattern(param: DecoderParam): Seq[T1DecodePattern] = param.allInstructions.map(T1DecodePattern(_, param)).toSeq.sortBy(_.instruction.name) - // sExecute 与 wExecuteRes 也不一样,需要校验 - // sExecute -> readOnly || nr || loadStore - /** Lane doesn't need VFU to execute the instruction. - * datapath will directly goes to VRF. - */ - object dontNeedExecuteInLane extends BoolField { - override def containsLSU: Boolean = true - def value(op: Op): Boolean = - Seq(readOnly, nr).map(_.value(op)).reduce(_ || _) || !op.notLSU - } + def decodeTable(param: DecoderParam): DecodeTable[T1DecodePattern] = new DecodeTable[T1DecodePattern](allDecodePattern(param), allFields(param) ) - // lane中只能在slot0中执行的指令 - // specialSlot -> crossRead || crossWrite || maskLogic || maskDestination || maskSource - /** instructions schedule to slot0. */ - object specialSlot extends BoolField { - def value(op: Op): Boolean = - Seq(crossRead, crossWrite, maskLogic, maskDestination, maskSource).map(_.value(op)).reduce(_ || _) - } + def decode(param: DecoderParam): UInt => DecodeBundle = decodeTable(param).decode + def bundle(param: DecoderParam): DecodeBundle = decodeTable(param).bundle +} - // TODO: how to add custom decoder for niche customer: linking. - def all(fpuEnable: Boolean): Seq[DecodeField[Op, _ >: Bool <: UInt]] = { - Seq( - logic, - adder, - shift, - multiplier, - divider, - multiCycle, - other, - unsigned0, - unsigned1, - itype, - nr, - red, - // top only - widenReduce, - targetRd, - slid, - gather, - gather16, - compress, - unOrderWrite, - // top uop - extend, // top uop - mv, // top uop - iota, // top uop - uop, - maskLogic, - maskDestination, - maskSource, - readOnly, - vwmacc, - saturate, - special, - maskUnit, - crossWrite, - crossRead, - // state - sWrite, - //sRead1 -> vType - vtype, - sReadVD, - scheduler, - dontNeedExecuteInLane, - reverse, // uop - average, // uop - ffo, // todo: add mask select -> top uop - popCount, // top uop add, red, uop popCount - topUop, - specialSlot - ) ++ { - if (fpuEnable) - Seq( - float, - fpExecutionType, - floatMul, - orderReduce - ) - else Seq() - } - } +trait FieldName { + def name: String = this.getClass.getSimpleName.replace("$", "") +} - def decodeTable(fpuEnable: Boolean): DecodeTable[Op] = new DecodeTable[Op](ops(fpuEnable), all(fpuEnable)) - def decode(fpuEnable: Boolean): UInt => DecodeBundle = decodeTable(fpuEnable).decode - def bundle(fpuEnable: Boolean): DecodeBundle = decodeTable(fpuEnable).bundle +case class SpecialAux(name: String, vs: Int, value: String) +case class SpecialMap(name: String, vs: Int, data: Map[String, String]) +case class SpecialAuxInstr(instrName: String, vs: Int, value: String, name: String) +case class Op(tpe: String, funct6: String, tpeOp2: String, funct3: String, + name: String, special: Option[SpecialAux], notLSU: Boolean, vd: String, opcode: String) extends DecodePattern { + // include 32 bits: funct6 + vm + vs2 + vs1 + funct3 + vd + opcode + def bitPat: BitPat = BitPat( + "b" + + // funct6 + funct6 + + // ? for vm + "?" + + // vs2 + (if (special.isEmpty || special.get.vs == 1) "?????" else special.get.value) + + // vs1 + (if (special.isEmpty || special.get.vs == 2) "?????" else special.get.value) + + // funct3 + funct3 + + vd + + opcode + ) } diff --git a/t1/src/decoder/InstructionDocumentation.scala b/t1/src/decoder/InstructionDocumentation.scala index dbeec2a89..22cf95823 100644 --- a/t1/src/decoder/InstructionDocumentation.scala +++ b/t1/src/decoder/InstructionDocumentation.scala @@ -1,14 +1,15 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2022 Jiuyang Liu -package org.chipsalliance.t1.rtl +package org.chipsalliance.t1.rtl.decoder import org.chipsalliance.rvdecoderdb.Instruction /** Generate documentation for each instructions for T1. * The documentation should contain the behavior for instruction in a specific configuration in T1. + * @todo should it be a post process at omreader? */ -case class InstructionDocumentation(instruction: Instruction, t1Parameter: T1Parameter) { +case class InstructionDocumentation(instruction: Instruction, param: DecoderParam) { override def toString: String = instruction.name match { case "vaadd.vv" => "TODO!" case "vaadd.vx" => "TODO!" diff --git a/t1/src/decoder/T1CustomInstruction.scala b/t1/src/decoder/T1CustomInstruction.scala new file mode 100644 index 000000000..2882603c2 --- /dev/null +++ b/t1/src/decoder/T1CustomInstruction.scala @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder + +import org.chipsalliance.rvdecoderdb.Instruction + +object T1CustomInstruction { + implicit def rw: upickle.default.ReadWriter[T1CustomInstruction] = upickle.default.macroRW[T1CustomInstruction] +} + +// TODO: other field will be fill in the future, e.g. something that user can config, e.g. +// readRS1, readRD? +case class T1CustomInstruction(instruction: Instruction) \ No newline at end of file diff --git a/t1/src/decoder/T1DecodePattern.scala b/t1/src/decoder/T1DecodePattern.scala index 0470a73e9..3d53a111b 100644 --- a/t1/src/decoder/T1DecodePattern.scala +++ b/t1/src/decoder/T1DecodePattern.scala @@ -1,15 +1,17 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2022 Jiuyang Liu -package org.chipsalliance.t1.rtl +package org.chipsalliance.t1.rtl.decoder import chisel3._ import chisel3.experimental.hierarchy.core.Definition -import chisel3.experimental.hierarchy.{instantiable, public, Instantiate} -import chisel3.properties.{Class, ClassType, Property} +import chisel3.experimental.hierarchy.{Instantiate, instantiable, public} +import chisel3.properties.{AnyClassType, Class, ClassType, Property} import chisel3.util.BitPat import chisel3.util.experimental.decode.DecodePattern import org.chipsalliance.rvdecoderdb.Instruction +import org.chipsalliance.t1.rtl.T1Parameter +import org.chipsalliance.t1.rtl.decoder.attribute._ @instantiable class T1DecodeAttributeOM extends Class { @@ -26,19 +28,15 @@ class T1DecodeAttributeOM extends Class { @instantiable class T1InstructionOM extends Class { - // get type of [[T1DecodeAttributeOM]] - val attributeClass = Instantiate.definition(new T1DecodeAttributeOM) - val attributeClassTpe = attributeClass.getClassType - val instructionName = IO(Output(Property[String]())) val documentation = IO(Output(Property[String]())) val bitPat = IO(Output(Property[String]())) - val attributes = IO(Output(Property[Seq[attributeClassTpe.Type]])) + val attributes = IO(Output(Property[Seq[AnyClassType]])) @public val instructionNameIn = IO(Input(Property[String]())) @public val documentationIn = IO(Input(Property[String]())) @public val bitPatIn = IO(Input(Property[String]())) - @public val attributesIn = IO(Input(Property[Seq[attributeClassTpe.Type]])) + @public val attributesIn = IO(Input(Property[Seq[AnyClassType]])) instructionName := instructionNameIn documentation := documentationIn @@ -46,152 +44,142 @@ class T1InstructionOM extends Class { attributes := attributesIn } -/** Attribute that will be encode into object module. - * the Attribute is used to provide metadata for verifications. - */ -trait DecodeAttribute[T] { - val identifier: String = this.getClass.getSimpleName.replace("$", "") - val value: T - val description: String - // Property of this attribute - def om: Property[ClassType] = { - val obj = Instantiate(new T1DecodeAttributeOM) - obj.identifierIn := Property(identifier) - obj.descriptionIn := Property(description) - // Use toString to avoid type issues... - obj.valueIn := Property(value.toString) - obj.getPropertyReference - } -} - -trait BooleanDecodeAttribute extends DecodeAttribute[Boolean] -trait StringDecodeAttribute extends DecodeAttribute[String] - -// All Attributes expose to OM, -case class IsVectorOM(value: Boolean) extends BooleanDecodeAttribute { - override val description: String = "This instruction should be decode by T1." -} - -case class UseLaneExecOM(value: String) extends StringDecodeAttribute { - require(Seq("logic", "adder", "shift", "multiplier", "divider").contains(value), s"invalid execution type: ${value}") - override val description: String = - "Types of Execution Unit used in T1, can be logic, adder, shift, multiplier, divider" -} - /** A case class that should wrap all Vector Instructions. * This is used to store the attribute for Vector Instruction under the T1 uArch. * It generates [[chisel3.util.experimental.decode.TruthTable]], as well as documentation field. */ -case class T1DecodePattern(instruction: Instruction, t1Parameter: T1Parameter) extends DecodePattern { +case class T1DecodePattern(instruction: Instruction, param: DecoderParam) extends DecodePattern { override def bitPat: BitPat = BitPat("b" + instruction.encoding.toString) - private def documentation: String = InstructionDocumentation(instruction, t1Parameter).toString - - // Below is the Scala in-memory attributes queried from DecodeTable. - def isVector = instruction.instructionSet.name == "rv_v" - - /** goes into the [[org.chipsalliance.t1.rtl.decoder.TableGenerator.LaneDecodeTable.LogicUnit]]. */ - def isLogic = Seq( - "vand.vi", - "vand.vv", - "vand.vx", - "vmand.mm", - "vmandn.mm", - "vmnand.mm", - "vredand.vs", - "vmnor.mm", - "vmor.mm", - "vmorn.mm", - "vmxnor.mm", - "vmxor.mm", - "vor.vi", - "vor.vv", - "vor.vx", - "vredor.vs", - "vredxor.vs", - "vxor.vi", - "vxor.vv", - "vxor.vx" - ).contains(instruction.name) - - def isAdder = Seq( - "vaadd.vv", - "vaadd.vx", - "vaaddu.vv", - "vaaddu.vx", - "vadd.vi", - "vadd.vv", - "vadd.vx", - "vmadd.vv", - "vmadd.vx", - "vsadd.vi", - "vsadd.vv", - "vsadd.vx", - "vsaddu.vi", - "vsaddu.vv", - "vsaddu.vx", - "vwadd.vv", - "vwadd.vx", - "vwadd.wv", - "vwadd.wx", - "vwaddu.vv", - "vwaddu.vx", - "vwaddu.wv", - "vwaddu.wx", - "vasub.vv", - "vasub.vx", - "vasubu.vv", - "vasubu.vx", - "vfmsub.vf", - "vfmsub.vv", - "vfnmsub.vf", - "vfnmsub.vv", - "vfrsub.vf", - "vfsub.vf", - "vfsub.vv", - "vfwsub.vf", - "vfwsub.vv", - "vfwsub.wf", - "vfwsub.wv", - "vnmsub.vv", - "vnmsub.vx", - "vrsub.vi", - "vrsub.vx", - "vssub.vv", - "vssub.vx", - "vssubu.vv", - "vssubu.vx", - "vsub.vv", - "vsub.vx", - "vwsub.vv", - "vwsub.vx", - "vwsub.wv", - "vwsub.wx", - "vwsubu.vv", - "vwsubu.vx", - "vwsubu.wv", - "vwsubu.wx", - "vmslt.vv", - "vmslt.vx", - "vmsltu.vv", - "vmsltu.vx" - ).contains(instruction.name) + // use the attribute w/ [[isVector.value]] + def isVector: isVector = attribute.isVector(this) + def isAdder: isAdder = attribute.isAdder(this) + def isAverage: isAverage = attribute.isAverage(this) + def isCompress: isCompress = attribute.isCompress(this) + def isCrossread: isCrossread = attribute.isCrossread(this) + def isCrosswrite: isCrosswrite = attribute.isCrosswrite(this) + def isDivider: isDivider = attribute.isDivider(this) + def isDontneedexecuteinlane: isDontneedexecuteinlane = attribute.isDontneedexecuteinlane(this) + def isExtend: isExtend = attribute.isExtend(this) + def isFcompare: isFcompare = attribute.isFcompare(this) + def isFfo: isFfo = attribute.isFfo(this) + def isFirstwiden: isFirstwiden = attribute.isFirstwiden(this) + def isFloatmul: isFloatmul = attribute.isFloatmul(this) + def isFloat: isFloat = attribute.isFloat(this) + def isFloattype: isFloattype = attribute.isFloattype(this) + def isFma: isFma = attribute.isFma(this) + def isFother: isFother = attribute.isFother(this) + def isGather16: isGather16 = attribute.isGather16(this) + def isGather: isGather = attribute.isGather(this) + def isId: isId = attribute.isId(this) + def isIndextype: isIndextype = attribute.isIndextype(this) + def isIota: isIota = attribute.isIota(this) + def isItype: isItype = attribute.isItype(this) + def isLogic: isLogic = attribute.isLogic(this) + def isMa: isMa = attribute.isMa(this) + def isMaskdestination: isMaskdestination = attribute.isMaskdestination(this) + def isMasklogic: isMasklogic = attribute.isMasklogic(this) + def isMasksource: isMasksource = attribute.isMasksource(this) + def isMaskunit: isMaskunit = attribute.isMaskunit(this) + def isMulticycle: isMulticycle = attribute.isMulticycle(this) + def isMultiplier: isMultiplier = attribute.isMultiplier(this) + def isMv: isMv = attribute.isMv(this) + def isNarrow: isNarrow = attribute.isNarrow(this) + def isNr: isNr = attribute.isNr(this) + def isOrderreduce: isOrderreduce = attribute.isOrderreduce(this) + def isOther: isOther = attribute.isOther(this) + def isZero: isZero = attribute.isZero(this) + def isPopcount: isPopcount = attribute.isPopcount(this) + def isReadonly: isReadonly = attribute.isReadonly(this) + def isRed: isRed = attribute.isRed(this) + def isReverse: isReverse = attribute.isReverse(this) + def isSaturate: isSaturate = attribute.isSaturate(this) + def isScheduler: isScheduler = attribute.isScheduler(this) + def isShift: isShift = attribute.isShift(this) + def isSlid: isSlid = attribute.isSlid(this) + def isSpecial: isSpecial = attribute.isSpecial(this) + def isSpecialslot: isSpecialslot = attribute.isSpecialslot(this) + def isSreadvd: isSreadvd = attribute.isSreadvd(this) + def isSwrite: isSwrite = attribute.isSwrite(this) + def isTargetrd: isTargetrd = attribute.isTargetrd(this) + def isUnorderwrite: isUnorderwrite = attribute.isUnorderwrite(this) + def isUnsigned0: isUnsigned0 = attribute.isUnsigned0(this) + def isUnsigned1: isUnsigned1 = attribute.isUnsigned1(this) + def isVtype: isVtype = attribute.isVtype(this) + def isVwmacc: isVwmacc = attribute.isVwmacc(this) + def isWidenreduce: isWidenreduce = attribute.isWidenreduce(this) + def fpExecutionType: FpExecutionType.Type = attribute.FpExecutionType(this) + def topUop: TopUop = attribute.TopUop(this) + def decoderUop: DecoderUop = attribute.DecoderUop(this) + + private def documentation: String = InstructionDocumentation(instruction, param).toString // This is the OM for this instruction def om: Property[ClassType] = { val obj = Instantiate(new T1InstructionOM) - // get type of [[T1DecodeAttributeOM]] - val attributeClass = Definition(new T1DecodeAttributeOM) - val attributeClassTpe = attributeClass.getClassType - obj.instructionNameIn := Property(instruction.name) obj.bitPatIn := Property(bitPat.rawString) obj.documentationIn := Property(documentation) // convert in-memory attributes to Chisel Property + // get type of [[T1DecodeAttributeOM]] obj.attributesIn :#= Property( Seq( - IsVectorOM(isVector), - ).map(_.om.as(attributeClassTpe)) + isVector, + isAdder, + isAverage, + isCompress, + isCrossread, + isCrosswrite, + isDivider, + isDontneedexecuteinlane, + isExtend, + isFcompare, + isFfo, + isFirstwiden, + isFloatmul, + isFloat, + isFloattype, + isFma, + isFother, + isGather16, + isGather, + isId, + isIndextype, + isIota, + isItype, + isLogic, + isMa, + isMaskdestination, + isMasklogic, + isMasksource, + isMaskunit, + isMulticycle, + isMultiplier, + isMv, + isNarrow, + isNr, + isOrderreduce, + isOther, + isPopcount, + isReadonly, + isRed, + isReverse, + isSaturate, + isScheduler, + isShift, + isSlid, + isSpecial, + isSpecialslot, + isSreadvd, + isSwrite, + isTargetrd, + isUnorderwrite, + isUnsigned0, + isUnsigned1, + isVtype, + isVwmacc, + isWidenreduce, + ).map(_.om.asAnyClassType) ) obj.getPropertyReference } diff --git a/t1/src/decoder/attribute/adderUop.scala b/t1/src/decoder/attribute/adderUop.scala new file mode 100644 index 000000000..02ebdd0c6 --- /dev/null +++ b/t1/src/decoder/attribute/adderUop.scala @@ -0,0 +1,185 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +trait AdderUOPType extends Uop +object addUop0 extends AdderUOPType +object addUop1 extends AdderUOPType +object addUop2 extends AdderUOPType +object addUop3 extends AdderUOPType +object addUop4 extends AdderUOPType +object addUop6 extends AdderUOPType +object addUop7 extends AdderUOPType +object addUop8 extends AdderUOPType +object addUop9 extends AdderUOPType +object addUop10 extends AdderUOPType +object addUop11 extends AdderUOPType + +object AdderUOP { + def apply(t1DecodePattern: T1DecodePattern): Uop = { + Seq( + t0 _ -> addUop0, + t1 _ -> addUop1, + t2 _ -> addUop2, + t3 _ -> addUop3, + t4 _ -> addUop4, + t6 _ -> addUop6, + t7 _ -> addUop7, + t8 _ -> addUop8, + t9 _ -> addUop9, + t10 _ -> addUop10, + t11 _ -> addUop11, + ).collectFirst { + case (fn, tpe) if fn(t1DecodePattern) => tpe + }.getOrElse(UopDC) + } + def t0(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vaadd.vv", + "vaadd.vx", + "vaaddu.vv", + "vaaddu.vx", + "vadd.vi", + "vadd.vv", + "vadd.vx", + "vredsum.vs", + "vsadd.vi", + "vsadd.vv", + "vsadd.vx", + "vsaddu.vi", + "vsaddu.vv", + "vsaddu.vx", + "vwadd.vv", + "vwadd.vx", + "vwadd.wv", + "vwadd.wx", + "vwaddu.vv", + "vwaddu.vx", + "vwaddu.wv", + "vwaddu.wx", + "vwredsum.vs", + "vwredsumu.vs", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t1(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vasub.vv", + "vasub.vx", + "vasubu.vv", + "vasubu.vx", + "vrsub.vi", + "vrsub.vx", + "vssub.vv", + "vssub.vx", + "vssubu.vv", + "vssubu.vx", + "vsub.vv", + "vsub.vx", + "vwsub.vv", + "vwsub.vx", + "vwsub.wv", + "vwsub.wx", + "vwsubu.vv", + "vwsubu.vx", + "vwsubu.wv", + "vwsubu.wx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t2(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmslt.vv", + "vmslt.vx", + "vmsltu.vv", + "vmsltu.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t3(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmsle.vi", + "vmsle.vv", + "vmsle.vx", + "vmsleu.vi", + "vmsleu.vv", + "vmsleu.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t4(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmsgt.vi", + "vmsgt.vx", + "vmsgtu.vi", + "vmsgtu.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t6(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmax.vv", + "vmax.vx", + "vmaxu.vv", + "vmaxu.vx", + "vredmax.vs", + "vredmaxu.vs", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t7(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmin.vv", + "vmin.vx", + "vminu.vv", + "vminu.vx", + "vredmin.vs", + "vredminu.vs", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t8(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmseq.vi", + "vmseq.vv", + "vmseq.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t9(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmsne.vi", + "vmsne.vv", + "vmsne.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t10(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vadc.vim", + "vadc.vvm", + "vadc.vxm", + "vmadc.vi", + "vmadc.vim", + "vmadc.vv", + "vmadc.vvm", + "vmadc.vx", + "vmadc.vxm", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t11(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmsbc.vv", + "vmsbc.vvm", + "vmsbc.vx", + "vmsbc.vxm", + "vsbc.vvm", + "vsbc.vxm", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } +} diff --git a/t1/src/decoder/attribute/divUop.scala b/t1/src/decoder/attribute/divUop.scala new file mode 100644 index 000000000..df084df77 --- /dev/null +++ b/t1/src/decoder/attribute/divUop.scala @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +trait DivUOPType extends Uop +object divUop0 extends DivUOPType +object divUop1 extends DivUOPType +object divUop8 extends DivUOPType +object divUop9 extends DivUOPType +object divUop10 extends DivUOPType + +object DivUOP { + def apply(t1DecodePattern: T1DecodePattern): Uop = { + Seq( + t0 _ -> divUop0, + t1 _ -> divUop1, + t8 _ -> divUop8, + t9 _ -> divUop9, + t10 _ -> divUop10 + ).collectFirst { + case (fn, tpe) if fn(t1DecodePattern) => tpe + }.getOrElse(UopDC) + } + def t0(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vdiv.vv", + "vdiv.vx", + "vdivu.vv", + "vdivu.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t1(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vrem.vv", + "vrem.vx", + "vremu.vv", + "vremu.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t8(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfdiv.vf", + "vfdiv.vv", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t9(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfsqrt.v", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t10(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfrdiv.vf", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } +} diff --git a/t1/src/decoder/attribute/floatUop.scala b/t1/src/decoder/attribute/floatUop.scala new file mode 100644 index 000000000..ed08031ca --- /dev/null +++ b/t1/src/decoder/attribute/floatUop.scala @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +trait FloatUopType extends Uop +object FUT0 extends FloatUopType +object FUT1 extends FloatUopType +object FUT2 extends FloatUopType +object FUT3 extends FloatUopType +object FUT4 extends FloatUopType +object FUT5 extends FloatUopType +object FUT6 extends FloatUopType +object FUT7 extends FloatUopType +object FUT8 extends FloatUopType +object FUT9 extends FloatUopType +object FUT10 extends FloatUopType +object FUT12 extends FloatUopType +object FUT13 extends FloatUopType +object FUT14 extends FloatUopType + +object FloatUop { + def apply(t1DecodePattern: T1DecodePattern) = { + Seq( + t0 _ -> FUT0, + t1 _ -> FUT1, + t2 _ -> FUT2, + t3 _ -> FUT3, + t4 _ -> FUT4, + t5 _ -> FUT5, + t6 _ -> FUT6, + t7 _ -> FUT7, + t8 _ -> FUT8, + t9 _ -> FUT9, + t10 _ -> FUT10, + t12 _ -> FUT12, + t13 _ -> FUT13, + t14 _ -> FUT14, + ).collectFirst { + case (fn, tpe) if fn(t1DecodePattern) => tpe + }.getOrElse(UopDC) + } + def t0(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(t1(t1DecodePattern) + || t2(t1DecodePattern) + || t3(t1DecodePattern) + || t4(t1DecodePattern) + || t5(t1DecodePattern) + || t6(t1DecodePattern) + || t7(t1DecodePattern) + || t8(t1DecodePattern) + || t9(t1DecodePattern) + || t10(t1DecodePattern) + || t12(t1DecodePattern) + || t13(t1DecodePattern) + || t14(t1DecodePattern) + ) + ) + allMatched.contains(t1DecodePattern.instruction) + } + def t1(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfmsac.vf", + "vfmsac.vv", + "vfsgnj.vf", + "vfsgnj.vv", + "vmfeq.vf", + "vmfeq.vv", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t2(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfnmsac.vf", + "vfnmsac.vv", + "vfsgnjn.vf", + "vfsgnjn.vv", + "vmflt.vf", + "vmflt.vv", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t3(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfnmacc.vf", + "vfnmacc.vv", + "vfsgnjx.vf", + "vfsgnjx.vv", + "vmfle.vf", + "vmfle.vv", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t4(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfclass.v", + "vfmadd.vf", + "vfmadd.vv", + "vmfgt.vf", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t5(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfmsub.vf", + "vfmsub.vv", + "vmfge.vf", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t6(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfnmsub.vf", + "vfnmsub.vv", + "vfrec7.v", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t7(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfnmadd.vf", + "vfnmadd.vv", + "vfrsqrt7.v", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t8(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfadd.vf", + "vfadd.vv", + "vfcvt.f.x.v", + "vfcvt.f.xu.v", + "vfmin.vf", + "vfmin.vv", + "vfredmin.vs", + "vfredosum.vs", + "vfredusum.vs", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t9(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfcvt.xu.f.v", + "vfsub.vf", + "vfsub.vv", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t10(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfcvt.x.f.v", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t12(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfmax.vf", + "vfmax.vv", + "vfredmax.vs", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t13(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfcvt.rtz.xu.f.v", + "vfrsub.vf", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t14(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfcvt.rtz.x.f.v", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } +} diff --git a/t1/src/decoder/attribute/fpExecutionType.scala b/t1/src/decoder/attribute/fpExecutionType.scala new file mode 100644 index 000000000..8810ae693 --- /dev/null +++ b/t1/src/decoder/attribute/fpExecutionType.scala @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object FpExecutionType { + trait Type extends Uop { + def apply(t1DecodePattern: T1DecodePattern): Boolean + } + case object Compare extends Type { + def apply(t1DecodePattern: T1DecodePattern): Boolean = isFcompare.y(t1DecodePattern) + } + case object Other extends Type { + def apply(t1DecodePattern: T1DecodePattern): Boolean = isFother.y(t1DecodePattern) + } + case object MA extends Type { + def apply(t1DecodePattern: T1DecodePattern): Boolean = !(isFcompare.y(t1DecodePattern) || isFother.y(t1DecodePattern)) + } + case object Nil extends Type { + def apply(t1DecodePattern: T1DecodePattern): Boolean = { + require(requirement = false, "unreachable") + false + } + } + def apply(t1DecodePattern: T1DecodePattern): Type = { + val tpe = Seq(Compare, Other, MA).filter(tpe => + tpe(t1DecodePattern) + ) + require(tpe.size <= 1) + tpe.headOption.getOrElse(Nil) + } +} + +case class FpExecutionType(value: FpExecutionType.Type) extends UopDecodeAttribute[FpExecutionType.Type] { + override val description: String = "float uop, goes to [[org.chipsalliance.t1.rtl.LaneFloatRequest.unitSelet]]" +} diff --git a/t1/src/decoder/attribute/isAdder.scala b/t1/src/decoder/attribute/isAdder.scala new file mode 100644 index 000000000..10653c446 --- /dev/null +++ b/t1/src/decoder/attribute/isAdder.scala @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isAdder { + def apply(t1DecodePattern: T1DecodePattern): isAdder = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isAdder(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vaadd.vv", + "vaadd.vx", + "vaaddu.vv", + "vaaddu.vx", + "vadc.vim", + "vadc.vvm", + "vadc.vxm", + "vadd.vi", + "vadd.vv", + "vadd.vx", + "vasub.vv", + "vasub.vx", + "vasubu.vv", + "vasubu.vx", + "vmadc.vi", + "vmadc.vim", + "vmadc.vv", + "vmadc.vvm", + "vmadc.vx", + "vmadc.vxm", + "vmax.vv", + "vmax.vx", + "vmaxu.vv", + "vmaxu.vx", + "vmin.vv", + "vmin.vx", + "vminu.vv", + "vminu.vx", + "vmsbc.vv", + "vmsbc.vvm", + "vmsbc.vx", + "vmsbc.vxm", + "vmseq.vi", + "vmseq.vv", + "vmseq.vx", + "vmsgt.vi", + "vmsgt.vx", + "vmsgtu.vi", + "vmsgtu.vx", + "vmsle.vi", + "vmsle.vv", + "vmsle.vx", + "vmsleu.vi", + "vmsleu.vv", + "vmsleu.vx", + "vmslt.vv", + "vmslt.vx", + "vmsltu.vv", + "vmsltu.vx", + "vmsne.vi", + "vmsne.vv", + "vmsne.vx", + "vredmax.vs", + "vredmaxu.vs", + "vredmin.vs", + "vredminu.vs", + "vredsum.vs", + "vrsub.vi", + "vrsub.vx", + "vsadd.vi", + "vsadd.vv", + "vsadd.vx", + "vsaddu.vi", + "vsaddu.vv", + "vsaddu.vx", + "vsbc.vvm", + "vsbc.vxm", + "vssub.vv", + "vssub.vx", + "vssubu.vv", + "vssubu.vx", + "vsub.vv", + "vsub.vx", + "vwadd.vv", + "vwadd.vx", + "vwadd.wv", + "vwadd.wx", + "vwaddu.vv", + "vwaddu.vx", + "vwaddu.wv", + "vwaddu.wx", + "vwredsum.vs", + "vwredsumu.vs", + "vwsub.vv", + "vwsub.vx", + "vwsub.wv", + "vwsub.wx", + "vwsubu.vv", + "vwsubu.vx", + "vwsubu.wv", + "vwsubu.wx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isAdder(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "goes to [[org.chipsalliance.t1.rtl.LaneAdder]]." +} diff --git a/t1/src/decoder/attribute/isAverage.scala b/t1/src/decoder/attribute/isAverage.scala new file mode 100644 index 000000000..8763aeaa5 --- /dev/null +++ b/t1/src/decoder/attribute/isAverage.scala @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isAverage { + def apply(t1DecodePattern: T1DecodePattern): isAverage = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isAverage(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vaadd.vv", + "vaadd.vx", + "vaaddu.vv", + "vaaddu.vx", + "vasub.vv", + "vasub.vx", + "vasubu.vv", + "vasubu.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcpop.m", + "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", + "vfirst.m", + "vfmv.f.s", + "vfmv.s.f", + "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", + "vfrec7.v", + "vfrsqrt7.v", + "vfsqrt.v", + "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", + "vid.v", + "viota.m", + "vmsbf.m", + "vmsif.m", + "vmsof.m", + "vmv.s.x", + "vmv.x.s", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } +} + +case class isAverage(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "For adder, does it need to take care of saturate. TODO: add to uop " +} diff --git a/t1/src/decoder/attribute/isCompress.scala b/t1/src/decoder/attribute/isCompress.scala new file mode 100644 index 000000000..744d3c530 --- /dev/null +++ b/t1/src/decoder/attribute/isCompress.scala @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isCompress { + def apply(t1DecodePattern: T1DecodePattern): isCompress = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isCompress(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcompress.vm", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isCompress(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "lane will read data from vs2, send to Sequencer. then Sequencer will read vs1 for mask. use mask to compress data in vs2. and write to vd at last. " +} diff --git a/t1/src/decoder/attribute/isCrossread.scala b/t1/src/decoder/attribute/isCrossread.scala new file mode 100644 index 000000000..34c11bed3 --- /dev/null +++ b/t1/src/decoder/attribute/isCrossread.scala @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isCrossread { + def apply(t1DecodePattern: T1DecodePattern): isCrossread = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isCrossread(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "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", + "vfwadd.wf", + "vfwadd.wv", + "vfwsub.wf", + "vfwsub.wv", + "vnclip.wi", + "vnclip.wv", + "vnclip.wx", + "vnclipu.wi", + "vnclipu.wv", + "vnclipu.wx", + "vnsra.wi", + "vnsra.wv", + "vnsra.wx", + "vnsrl.wi", + "vnsrl.wv", + "vnsrl.wx", + "vwadd.wv", + "vwadd.wx", + "vwaddu.wv", + "vwaddu.wx", + "vwmacc.vv", + "vwmacc.vx", + "vwmaccsu.vv", + "vwmaccsu.vx", + "vwmaccu.vv", + "vwmaccu.vx", + "vwmaccus.vx", + "vwsub.wv", + "vwsub.wx", + "vwsubu.wv", + "vwsubu.wx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isCrossread(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "Read vs2 or vd with cross read channel. crossRead -> narrow || firstWiden " +} diff --git a/t1/src/decoder/attribute/isCrosswrite.scala b/t1/src/decoder/attribute/isCrosswrite.scala new file mode 100644 index 000000000..cbe920dbb --- /dev/null +++ b/t1/src/decoder/attribute/isCrosswrite.scala @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isCrosswrite { + def apply(t1DecodePattern: T1DecodePattern): isCrosswrite = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isCrosswrite(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vwadd.vv", + "vwadd.vx", + "vwadd.wv", + "vwadd.wx", + "vwaddu.vv", + "vwaddu.vx", + "vwaddu.wv", + "vwaddu.wx", + "vwmacc.vv", + "vwmacc.vx", + "vwmaccsu.vv", + "vwmaccsu.vx", + "vwmaccu.vv", + "vwmaccu.vx", + "vwmaccus.vx", + "vwmul.vv", + "vwmul.vx", + "vwmulsu.vv", + "vwmulsu.vx", + "vwmulu.vv", + "vwmulu.vx", + "vwsub.vv", + "vwsub.vx", + "vwsub.wv", + "vwsub.wx", + "vwsubu.vv", + "vwsubu.vx", + "vwsubu.wv", + "vwsubu.wx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcpop.m", + "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", + "vfirst.m", + "vfmv.f.s", + "vfmv.s.f", + "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", + "vfrec7.v", + "vfrsqrt7.v", + "vfsqrt.v", + "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", + "vid.v", + "viota.m", + "vmsbf.m", + "vmsif.m", + "vmsof.m", + "vmv.s.x", + "vmv.x.s", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } +} + +case class isCrosswrite(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "lane should write to another lane" +} diff --git a/t1/src/decoder/attribute/isDivider.scala b/t1/src/decoder/attribute/isDivider.scala new file mode 100644 index 000000000..b89b2d79f --- /dev/null +++ b/t1/src/decoder/attribute/isDivider.scala @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isDivider { + def apply(t1DecodePattern: T1DecodePattern): isDivider = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isDivider(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vdiv.vv", + "vdiv.vx", + "vdivu.vv", + "vdivu.vx", + "vfdiv.vf", + "vfdiv.vv", + "vfrdiv.vf", + "vfsqrt.v", + "vrem.vv", + "vrem.vx", + "vremu.vv", + "vremu.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isDivider(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "goes to [[org.chipsalliance.t1.rtl.LaneDiv]] or [[org.chipsalliance.t1.rtl.LaneDivFP]]. if FP exist, all div goes to [[org.chipsalliance.t1.rtl.LaneDivFP]]" +} diff --git a/t1/src/decoder/attribute/isDontneedexecuteinlane.scala b/t1/src/decoder/attribute/isDontneedexecuteinlane.scala new file mode 100644 index 000000000..5dfab94cc --- /dev/null +++ b/t1/src/decoder/attribute/isDontneedexecuteinlane.scala @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isDontneedexecuteinlane { + def apply(t1DecodePattern: T1DecodePattern): isDontneedexecuteinlane = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isDontneedexecuteinlane(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcompress.vm", + "viota.m", + "vl1re16.v", + "vl1re32.v", + "vl1re64.v", + "vl1re8.v", + "vl2re16.v", + "vl2re32.v", + "vl2re64.v", + "vl2re8.v", + "vl4re16.v", + "vl4re32.v", + "vl4re64.v", + "vl4re8.v", + "vl8re16.v", + "vl8re32.v", + "vl8re64.v", + "vl8re8.v", + "vle1024.v", + "vle1024ff.v", + "vle128.v", + "vle128ff.v", + "vle16.v", + "vle16ff.v", + "vle256.v", + "vle256ff.v", + "vle32.v", + "vle32ff.v", + "vle512.v", + "vle512ff.v", + "vle64.v", + "vle64ff.v", + "vle8.v", + "vle8ff.v", + "vlm.v", + "vloxei1024.v", + "vloxei128.v", + "vloxei16.v", + "vloxei256.v", + "vloxei32.v", + "vloxei512.v", + "vloxei64.v", + "vloxei8.v", + "vlse1024.v", + "vlse128.v", + "vlse16.v", + "vlse256.v", + "vlse32.v", + "vlse512.v", + "vlse64.v", + "vlse8.v", + "vluxei1024.v", + "vluxei128.v", + "vluxei16.v", + "vluxei256.v", + "vluxei32.v", + "vluxei512.v", + "vluxei64.v", + "vluxei8.v", + "vmv1r.v", + "vmv2r.v", + "vmv4r.v", + "vmv8r.v", + "vrgather.vv", + "vrgatherei16.vv", + "vs1r.v", + "vs2r.v", + "vs4r.v", + "vs8r.v", + "vse1024.v", + "vse128.v", + "vse16.v", + "vse256.v", + "vse32.v", + "vse512.v", + "vse64.v", + "vse8.v", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vsm.v", + "vsoxei1024.v", + "vsoxei128.v", + "vsoxei16.v", + "vsoxei256.v", + "vsoxei32.v", + "vsoxei512.v", + "vsoxei64.v", + "vsoxei8.v", + "vsse1024.v", + "vsse128.v", + "vsse16.v", + "vsse256.v", + "vsse32.v", + "vsse512.v", + "vsse64.v", + "vsse8.v", + "vsuxei1024.v", + "vsuxei128.v", + "vsuxei16.v", + "vsuxei256.v", + "vsuxei32.v", + "vsuxei512.v", + "vsuxei64.v", + "vsuxei8.v", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isDontneedexecuteinlane(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "Lane doesn't need VFU to execute the instruction. datapath will directly goes to VRF. " +} diff --git a/t1/src/decoder/attribute/isExtend.scala b/t1/src/decoder/attribute/isExtend.scala new file mode 100644 index 000000000..b2c3bb418 --- /dev/null +++ b/t1/src/decoder/attribute/isExtend.scala @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isExtend { + def apply(t1DecodePattern: T1DecodePattern): isExtend = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isExtend(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isExtend(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "send element to MaskUnit at top, extend and broadcast to multiple Lanes." +} diff --git a/t1/src/decoder/attribute/isFcompare.scala b/t1/src/decoder/attribute/isFcompare.scala new file mode 100644 index 000000000..10383b2a8 --- /dev/null +++ b/t1/src/decoder/attribute/isFcompare.scala @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isFcompare { + def apply(t1DecodePattern: T1DecodePattern): isFcompare = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isFcompare(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vfmax.vf", + "vfmax.vv", + "vfmin.vf", + "vfmin.vv", + "vfredmax.vs", + "vfredmin.vs", + "vmfeq.vf", + "vmfeq.vv", + "vmfge.vf", + "vmfgt.vf", + "vmfle.vf", + "vmfle.vv", + "vmflt.vf", + "vmflt.vv", + "vmfne.vf", + "vmfne.vv", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isFcompare(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "TODO: remove it, but remains attribute." +} diff --git a/t1/src/decoder/attribute/isFfo.scala b/t1/src/decoder/attribute/isFfo.scala new file mode 100644 index 000000000..b446268ee --- /dev/null +++ b/t1/src/decoder/attribute/isFfo.scala @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isFfo { + def apply(t1DecodePattern: T1DecodePattern): isFfo = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isFfo(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vfirst.m", + "vmsbf.m", + "vmsif.m", + "vmsof.m", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isFfo(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "find first one, lane will report if 1 is found, Sequencer should decide which is exactly the first 1 in lanes. after 1 is found, tell each lane, 1 has been found at which the corresponding location. lane will stale at stage2. TODO: should split into lane control uop " +} diff --git a/t1/src/decoder/attribute/isFirstwiden.scala b/t1/src/decoder/attribute/isFirstwiden.scala new file mode 100644 index 000000000..6f4b46ef3 --- /dev/null +++ b/t1/src/decoder/attribute/isFirstwiden.scala @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isFirstwiden { + def apply(t1DecodePattern: T1DecodePattern): isFirstwiden = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isFirstwiden(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "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", + "vfwadd.wf", + "vfwadd.wv", + "vfwsub.wf", + "vfwsub.wv", + "vnclip.wv", + "vnclip.wx", + "vnclipu.wv", + "vnclipu.wx", + "vnsra.wv", + "vnsra.wx", + "vnsrl.wv", + "vnsrl.wx", + "vwadd.wv", + "vwadd.wx", + "vwaddu.wv", + "vwaddu.wx", + "vwmacc.vv", + "vwmacc.vx", + "vwmaccsu.vv", + "vwmaccsu.vx", + "vwmaccu.vv", + "vwmaccu.vx", + "vwmaccus.vx", + "vwsub.wv", + "vwsub.wx", + "vwsubu.wv", + "vwsubu.wx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isFirstwiden(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "There are two types of widen: - vd -> widen. - vs2, vd -> widen. This op will widen vs2. TODO: remove it as attribute." +} diff --git a/t1/src/decoder/attribute/isFloat.scala b/t1/src/decoder/attribute/isFloat.scala new file mode 100644 index 000000000..0d6b4f0a7 --- /dev/null +++ b/t1/src/decoder/attribute/isFloat.scala @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isFloat { + def apply(t1DecodePattern: T1DecodePattern): isFloat = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isFloat(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = if(t1DecodePattern.param.fpuEnable) Seq( + "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", + "vfmacc.vf", + "vfmacc.vv", + "vfmadd.vf", + "vfmadd.vv", + "vfmax.vf", + "vfmax.vv", + "vfmin.vf", + "vfmin.vv", + "vfmsac.vf", + "vfmsac.vv", + "vfmsub.vf", + "vfmsub.vv", + "vfmul.vf", + "vfmul.vv", + "vfmv.f.s", + "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", + "vfnmacc.vf", + "vfnmacc.vv", + "vfnmadd.vf", + "vfnmadd.vv", + "vfnmsac.vf", + "vfnmsac.vv", + "vfnmsub.vf", + "vfnmsub.vv", + "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", + "vfsub.vf", + "vfsub.vv", + "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", + "vmfeq.vf", + "vmfeq.vv", + "vmfge.vf", + "vmfgt.vf", + "vmfle.vf", + "vmfle.vv", + "vmflt.vf", + "vmflt.vv", + "vmfne.vf", + "vmfne.vv", + ) else Seq() + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isFloat(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "goes to [[org.chipsalliance.t1.rtl.LaneFloat]]." +} diff --git a/t1/src/decoder/attribute/isFloatmul.scala b/t1/src/decoder/attribute/isFloatmul.scala new file mode 100644 index 000000000..139e3ffc3 --- /dev/null +++ b/t1/src/decoder/attribute/isFloatmul.scala @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isFloatmul { + def apply(t1DecodePattern: T1DecodePattern): isFloatmul = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isFloatmul(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = if(t1DecodePattern.param.fpuEnable) Seq( + "vfmul.vf", + "vfmul.vv", + ) else Seq() + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isFloatmul(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "TODO: add op." +} diff --git a/t1/src/decoder/attribute/isFloattype.scala b/t1/src/decoder/attribute/isFloattype.scala new file mode 100644 index 000000000..3ac3e1110 --- /dev/null +++ b/t1/src/decoder/attribute/isFloattype.scala @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isFloattype { + def apply(t1DecodePattern: T1DecodePattern): isFloattype = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isFloattype(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = if(t1DecodePattern.param.fpuEnable) Seq( + "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", + "vfmv.v.f", + "vfmin.vf", + "vfmin.vv", + "vfmsac.vf", + "vfmsac.vv", + "vfmsub.vf", + "vfmsub.vv", + "vfmul.vf", + "vfmul.vv", + "vfmv.f.s", + "vfmv.s.f", + "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", + "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", + "vfslide1down.vf", + "vfslide1up.vf", + "vfsqrt.v", + "vfsub.vf", + "vfsub.vv", + "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", + "vmfeq.vf", + "vmfeq.vv", + "vmfge.vf", + "vmfgt.vf", + "vmfle.vf", + "vmfle.vv", + "vmflt.vf", + "vmflt.vv", + "vmfne.vf", + "vmfne.vv", + ) else Seq() + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isFloattype(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "is a float type. TODO: remove it." +} diff --git a/t1/src/decoder/attribute/isFma.scala b/t1/src/decoder/attribute/isFma.scala new file mode 100644 index 000000000..c2bc6d495 --- /dev/null +++ b/t1/src/decoder/attribute/isFma.scala @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isFma { + def apply(t1DecodePattern: T1DecodePattern): isFma = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isFma(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vfadd.vf", + "vfadd.vv", + "vfmacc.vf", + "vfmacc.vv", + "vfmadd.vf", + "vfmadd.vv", + "vfmsac.vf", + "vfmsac.vv", + "vfmsub.vf", + "vfmsub.vv", + "vfmul.vf", + "vfmul.vv", + "vfnmacc.vf", + "vfnmacc.vv", + "vfnmadd.vf", + "vfnmadd.vv", + "vfnmsac.vf", + "vfnmsac.vv", + "vfnmsub.vf", + "vfnmsub.vv", + "vfredosum.vs", + "vfredusum.vs", + "vfrsub.vf", + "vfsub.vf", + "vfsub.vv", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isFma(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "uop of FMA, goes to [[org.chipsalliance.t1.rtl.LaneFloat]] FMA unit." +} diff --git a/t1/src/decoder/attribute/isFother.scala b/t1/src/decoder/attribute/isFother.scala new file mode 100644 index 000000000..7f4d556ea --- /dev/null +++ b/t1/src/decoder/attribute/isFother.scala @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isFother { + def apply(t1DecodePattern: T1DecodePattern): isFother = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isFother(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "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", + "vfrec7.v", + "vfrsqrt7.v", + "vfsgnj.vf", + "vfsgnj.vv", + "vfsgnjn.vf", + "vfsgnjn.vv", + "vfsgnjx.vf", + "vfsgnjx.vv", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isFother(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "designed for Other Unit in FP. goes to [[org.chipsalliance.t1.rtl.LaneFloat]] OtherUnit. TODO: perf it." +} diff --git a/t1/src/decoder/attribute/isGather.scala b/t1/src/decoder/attribute/isGather.scala new file mode 100644 index 000000000..4741dd45f --- /dev/null +++ b/t1/src/decoder/attribute/isGather.scala @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isGather { + def apply(t1DecodePattern: T1DecodePattern): isGather = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isGather(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vrgather.vi", + "vrgather.vv", + "vrgather.vx", + "vrgatherei16.vv", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isGather(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "lane will read index from vs1, send to Sequencer. mask unit will calculate vrf address based on the vs1 from lane, and send read request to lanes, lanes should read it and send vs2 to Sequencer. Sequencer will write vd at last. address: 0 -> vlmax(sew decide address width.) " +} diff --git a/t1/src/decoder/attribute/isGather16.scala b/t1/src/decoder/attribute/isGather16.scala new file mode 100644 index 000000000..4d2a93661 --- /dev/null +++ b/t1/src/decoder/attribute/isGather16.scala @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isGather16 { + def apply(t1DecodePattern: T1DecodePattern): isGather16 = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isGather16(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vrgatherei16.vv", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isGather16(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "same with [[gather]] ignore sew, address width is fixed to 16. @note When SEW=8, vrgather.vv can only reference vector elements 0-255. The vrgatherei16 form can index 64K elements, and can also be used to reduce the register capacity needed to hold indices when SEW > 16. " +} diff --git a/t1/src/decoder/attribute/isId.scala b/t1/src/decoder/attribute/isId.scala new file mode 100644 index 000000000..d530c26ed --- /dev/null +++ b/t1/src/decoder/attribute/isId.scala @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isId { + def apply(t1DecodePattern: T1DecodePattern): isId = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isId(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vdiv.vv", + "vdiv.vx", + "vdivu.vv", + "vdivu.vx", + "vfdiv.vf", + "vfdiv.vv", + "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", + "vfrdiv.vf", + "vfslide1down.vf", + "vfslide1up.vf", + "vfsqrt.v", + "vfwadd.wf", + "vfwadd.wv", + "vfwsub.wf", + "vfwsub.wv", + "vid.v", + "vnclip.wv", + "vnclip.wx", + "vnclipu.wv", + "vnclipu.wx", + "vnsra.wv", + "vnsra.wx", + "vnsrl.wv", + "vnsrl.wx", + "vrem.vv", + "vrem.vx", + "vremu.vv", + "vremu.vx", + "vslide1down.vx", + "vslide1up.vx", + "vslidedown.vi", + "vslidedown.vx", + "vslideup.vi", + "vslideup.vx", + "vwadd.wv", + "vwadd.wx", + "vwaddu.wv", + "vwaddu.wx", + "vwmacc.vv", + "vwmacc.vx", + "vwmaccsu.vv", + "vwmaccsu.vx", + "vwmaccu.vv", + "vwmaccu.vx", + "vwmaccus.vx", + "vwredsum.vs", + "vwredsumu.vs", + "vwsub.wv", + "vwsub.wx", + "vwsubu.wv", + "vwsubu.wx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isId(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "write 0...vlmax to VRF. Lane other unit should handle it. TODO: remove it, it's a uop. " +} diff --git a/t1/src/decoder/attribute/isIndextype.scala b/t1/src/decoder/attribute/isIndextype.scala new file mode 100644 index 000000000..6a3b781a7 --- /dev/null +++ b/t1/src/decoder/attribute/isIndextype.scala @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isIndextype { + def apply(t1DecodePattern: T1DecodePattern): isIndextype = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isIndextype(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vloxei1024.v", + "vloxei128.v", + "vloxei16.v", + "vloxei256.v", + "vloxei32.v", + "vloxei512.v", + "vloxei64.v", + "vloxei8.v", + "vluxei1024.v", + "vluxei128.v", + "vluxei16.v", + "vluxei256.v", + "vluxei32.v", + "vluxei512.v", + "vluxei64.v", + "vluxei8.v", + "vsoxei1024.v", + "vsoxei128.v", + "vsoxei16.v", + "vsoxei256.v", + "vsoxei32.v", + "vsoxei512.v", + "vsoxei64.v", + "vsoxei8.v", + "vsuxei1024.v", + "vsuxei128.v", + "vsuxei16.v", + "vsuxei256.v", + "vsuxei32.v", + "vsuxei512.v", + "vsuxei64.v", + "vsuxei8.v", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isIndextype(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "TODO: remove it." +} diff --git a/t1/src/decoder/attribute/isIota.scala b/t1/src/decoder/attribute/isIota.scala new file mode 100644 index 000000000..d9194845e --- /dev/null +++ b/t1/src/decoder/attribute/isIota.scala @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isIota { + def apply(t1DecodePattern: T1DecodePattern): isIota = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isIota(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "viota.m", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isIota(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "lane will read vs2 from VRF, send to Top. Top read v0(at register) calculate the result and write back to VRFs " +} diff --git a/t1/src/decoder/attribute/isItype.scala b/t1/src/decoder/attribute/isItype.scala new file mode 100644 index 000000000..aafc0641c --- /dev/null +++ b/t1/src/decoder/attribute/isItype.scala @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isItype { + def apply(t1DecodePattern: T1DecodePattern): isItype = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isItype(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vadc.vim", + "vadd.vi", + "vand.vi", + "vmadc.vi", + "vmadc.vim", + "vmerge.vim", + "vmv.v.i", + "vmseq.vi", + "vmsgt.vi", + "vmsgtu.vi", + "vmsle.vi", + "vmsleu.vi", + "vmsne.vi", + "vmv1r.v", + "vmv2r.v", + "vmv4r.v", + "vmv8r.v", + "vnclip.wi", + "vnclipu.wi", + "vnsra.wi", + "vnsrl.wi", + "vor.vi", + "vrgather.vi", + "vrsub.vi", + "vsadd.vi", + "vsaddu.vi", + "vslidedown.vi", + "vslideup.vi", + "vsll.vi", + "vsra.vi", + "vsrl.vi", + "vssra.vi", + "vssrl.vi", + "vxor.vi", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isItype(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "src is imm." +} diff --git a/t1/src/decoder/attribute/isLogic.scala b/t1/src/decoder/attribute/isLogic.scala new file mode 100644 index 000000000..96cc6c57f --- /dev/null +++ b/t1/src/decoder/attribute/isLogic.scala @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isLogic { + def apply(t1DecodePattern: T1DecodePattern): isLogic = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isLogic(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vand.vi", + "vand.vv", + "vand.vx", + "vmand.mm", + "vmandn.mm", + "vmnand.mm", + "vmnor.mm", + "vmor.mm", + "vmorn.mm", + "vmxnor.mm", + "vmxor.mm", + "vor.vi", + "vor.vv", + "vor.vx", + "vredand.vs", + "vredor.vs", + "vredxor.vs", + "vxor.vi", + "vxor.vv", + "vxor.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isLogic(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "Instruction should use [[org.chipsalliance.t1.rtl.decoder.TableGenerator.LaneDecodeTable.LogicUnit]]." +} diff --git a/t1/src/decoder/attribute/isMa.scala b/t1/src/decoder/attribute/isMa.scala new file mode 100644 index 000000000..a69773aff --- /dev/null +++ b/t1/src/decoder/attribute/isMa.scala @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isMa { + def apply(t1DecodePattern: T1DecodePattern): isMa = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isMa(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vadc.vim", + "vadc.vvm", + "vadc.vxm", + "vcompress.vm", + "vcpop.m", + "vfirst.m", + "vfmacc.vf", + "vfmacc.vv", + "vfmadd.vf", + "vfmadd.vv", + "vfmax.vf", + "vfmax.vv", + "vfmerge.vfm", + "vfmv.v.f", + "vfmsac.vf", + "vfmsac.vv", + "vfmsub.vf", + "vfmsub.vv", + "vfmv.f.s", + "vfmv.s.f", + "vfnmacc.vf", + "vfnmacc.vv", + "vfnmadd.vf", + "vfnmadd.vv", + "vfnmsac.vf", + "vfnmsac.vv", + "vfnmsub.vf", + "vfnmsub.vv", + "vfredmax.vs", + "vfredmin.vs", + "vfredosum.vs", + "vfredusum.vs", + "vfslide1down.vf", + "vfslide1up.vf", + "vfwmacc.vf", + "vfwmacc.vv", + "vfwnmacc.vf", + "vfwnmacc.vv", + "vfwredosum.vs", + "vfwredusum.vs", + "viota.m", + "vmacc.vv", + "vmacc.vx", + "vmadc.vi", + "vmadc.vim", + "vmadc.vv", + "vmadc.vvm", + "vmadc.vx", + "vmadc.vxm", + "vmadd.vv", + "vmadd.vx", + "vmand.mm", + "vmandn.mm", + "vmax.vv", + "vmax.vx", + "vmaxu.vv", + "vmaxu.vx", + "vmerge.vim", + "vmv.v.i", + "vmerge.vvm", + "vmv.v.v", + "vmerge.vxm", + "vmv.v.x", + "vmfeq.vf", + "vmfeq.vv", + "vmfge.vf", + "vmfgt.vf", + "vmfle.vf", + "vmfle.vv", + "vmflt.vf", + "vmflt.vv", + "vmfne.vf", + "vmfne.vv", + "vmnand.mm", + "vmnor.mm", + "vmor.mm", + "vmorn.mm", + "vmsbc.vv", + "vmsbc.vvm", + "vmsbc.vx", + "vmsbc.vxm", + "vmsbf.m", + "vmseq.vi", + "vmseq.vv", + "vmseq.vx", + "vmsgt.vi", + "vmsgt.vx", + "vmsgtu.vi", + "vmsgtu.vx", + "vmsif.m", + "vmsle.vi", + "vmsle.vv", + "vmsle.vx", + "vmsleu.vi", + "vmsleu.vv", + "vmsleu.vx", + "vmslt.vv", + "vmslt.vx", + "vmsltu.vv", + "vmsltu.vx", + "vmsne.vi", + "vmsne.vv", + "vmsne.vx", + "vmsof.m", + "vmv.s.x", + "vmv.x.s", + "vmxnor.mm", + "vmxor.mm", + "vnmsac.vv", + "vnmsac.vx", + "vnmsub.vv", + "vnmsub.vx", + "vredand.vs", + "vredmax.vs", + "vredmaxu.vs", + "vredmin.vs", + "vredminu.vs", + "vredor.vs", + "vredsum.vs", + "vredxor.vs", + "vrgather.vv", + "vrgatherei16.vv", + "vsbc.vvm", + "vsbc.vxm", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vslide1down.vx", + "vslide1up.vx", + "vslidedown.vi", + "vslidedown.vx", + "vslideup.vi", + "vslideup.vx", + "vwmacc.vv", + "vwmacc.vx", + "vwmaccsu.vv", + "vwmaccsu.vx", + "vwmaccu.vv", + "vwmaccu.vx", + "vwmaccus.vx", + "vwredsum.vs", + "vwredsumu.vs", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isMa(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "decodeResult(Decoder.multiplier) && decodeResult(Decoder.uop)(1, 0).xorR && !decodeResult(Decoder.vwmacc) TODO: remove it. */ " +} diff --git a/t1/src/decoder/attribute/isMaskdestination.scala b/t1/src/decoder/attribute/isMaskdestination.scala new file mode 100644 index 000000000..528f00a32 --- /dev/null +++ b/t1/src/decoder/attribute/isMaskdestination.scala @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isMaskdestination { + def apply(t1DecodePattern: T1DecodePattern): isMaskdestination = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isMaskdestination(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vmadc.vi", + "vmadc.vim", + "vmadc.vv", + "vmadc.vvm", + "vmadc.vx", + "vmadc.vxm", + "vmfeq.vf", + "vmfeq.vv", + "vmfge.vf", + "vmfgt.vf", + "vmfle.vf", + "vmfle.vv", + "vmflt.vf", + "vmflt.vv", + "vmfne.vf", + "vmfne.vv", + "vmsbc.vv", + "vmsbc.vvm", + "vmsbc.vx", + "vmsbc.vxm", + "vmseq.vi", + "vmseq.vv", + "vmseq.vx", + "vmsgt.vi", + "vmsgt.vx", + "vmsgtu.vi", + "vmsgtu.vx", + "vmsle.vi", + "vmsle.vv", + "vmsle.vx", + "vmsleu.vi", + "vmsleu.vv", + "vmsleu.vx", + "vmslt.vv", + "vmslt.vx", + "vmsltu.vv", + "vmsltu.vx", + "vmsne.vi", + "vmsne.vv", + "vmsne.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isMaskdestination(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "vd is mask format. execute at lane, send result to Sequencer, regroup it and write to vd. if datapath is unaligned, need to take care the tail. " +} diff --git a/t1/src/decoder/attribute/isMasklogic.scala b/t1/src/decoder/attribute/isMasklogic.scala new file mode 100644 index 000000000..d9f1a3599 --- /dev/null +++ b/t1/src/decoder/attribute/isMasklogic.scala @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isMasklogic { + def apply(t1DecodePattern: T1DecodePattern): isMasklogic = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isMasklogic(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcpop.m", + "vfirst.m", + "viota.m", + "vmand.mm", + "vmandn.mm", + "vmnand.mm", + "vmnor.mm", + "vmor.mm", + "vmorn.mm", + "vmsbf.m", + "vmsif.m", + "vmsof.m", + "vmxnor.mm", + "vmxor.mm", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isMasklogic(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "only one or two operators src is mask format(one element one bit). vl should align with src. if datapath is unaligned, need to take care the tail. " +} diff --git a/t1/src/decoder/attribute/isMasksource.scala b/t1/src/decoder/attribute/isMasksource.scala new file mode 100644 index 000000000..e460457fa --- /dev/null +++ b/t1/src/decoder/attribute/isMasksource.scala @@ -0,0 +1,58 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isMasksource { + def apply(t1DecodePattern: T1DecodePattern): isMasksource = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isMasksource(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vadc.vim", + "vadc.vvm", + "vadc.vxm", + "vfmerge.vfm", + "vfmv.v.f", + "vmadc.vi", + "vmadc.vim", + "vmadc.vv", + "vmadc.vvm", + "vmadc.vx", + "vmadc.vxm", + "vmerge.vim", + "vmv.v.i", + "vmerge.vvm", + "vmv.v.v", + "vmerge.vxm", + "vmv.v.x", + "vmsbc.vv", + "vmsbc.vvm", + "vmsbc.vx", + "vmsbc.vxm", + "vsbc.vvm", + "vsbc.vxm", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isMasksource(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "three ops. these ops don't use mask. use v0 as third op, read it from duplicate V0. it will read use mask(v0) in mask format as source. " +} diff --git a/t1/src/decoder/attribute/isMaskunit.scala b/t1/src/decoder/attribute/isMaskunit.scala new file mode 100644 index 000000000..c5e553798 --- /dev/null +++ b/t1/src/decoder/attribute/isMaskunit.scala @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isMaskunit { + def apply(t1DecodePattern: T1DecodePattern): isMaskunit = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isMaskunit(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcompress.vm", + "vcpop.m", + "vfirst.m", + "vfmv.f.s", + "vfmv.s.f", + "vfredmax.vs", + "vfredmin.vs", + "vfredosum.vs", + "vfredusum.vs", + "vfslide1down.vf", + "vfslide1up.vf", + "vfwredosum.vs", + "vfwredusum.vs", + "viota.m", + "vmadc.vi", + "vmadc.vim", + "vmadc.vv", + "vmadc.vvm", + "vmadc.vx", + "vmadc.vxm", + "vmfeq.vf", + "vmfeq.vv", + "vmfge.vf", + "vmfgt.vf", + "vmfle.vf", + "vmfle.vv", + "vmflt.vf", + "vmflt.vv", + "vmfne.vf", + "vmfne.vv", + "vmsbc.vv", + "vmsbc.vvm", + "vmsbc.vx", + "vmsbc.vxm", + "vmsbf.m", + "vmseq.vi", + "vmseq.vv", + "vmseq.vx", + "vmsgt.vi", + "vmsgt.vx", + "vmsgtu.vi", + "vmsgtu.vx", + "vmsif.m", + "vmsle.vi", + "vmsle.vv", + "vmsle.vx", + "vmsleu.vi", + "vmsleu.vv", + "vmsleu.vx", + "vmslt.vv", + "vmslt.vx", + "vmsltu.vv", + "vmsltu.vx", + "vmsne.vi", + "vmsne.vv", + "vmsne.vx", + "vmsof.m", + "vmv.s.x", + "vmv.x.s", + "vredand.vs", + "vredmax.vs", + "vredmaxu.vs", + "vredmin.vs", + "vredminu.vs", + "vredor.vs", + "vredsum.vs", + "vredxor.vs", + "vrgather.vv", + "vrgatherei16.vv", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vslide1down.vx", + "vslide1up.vx", + "vslidedown.vi", + "vslidedown.vx", + "vslideup.vi", + "vslideup.vx", + "vwredsum.vs", + "vwredsumu.vs", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isMaskunit(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "mask unit -> red || compress || viota || ffo || slid || maskDestination || gather(v) || mv || popCount || extend all instruction in Sequencer mask unit. " +} diff --git a/t1/src/decoder/attribute/isMulticycle.scala b/t1/src/decoder/attribute/isMulticycle.scala new file mode 100644 index 000000000..d1b3a661d --- /dev/null +++ b/t1/src/decoder/attribute/isMulticycle.scala @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isMulticycle { + def apply(t1DecodePattern: T1DecodePattern): isMulticycle = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isMulticycle(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vdiv.vv", + "vdiv.vx", + "vdivu.vv", + "vdivu.vx", + "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", + "vfmin.vf", + "vfmin.vv", + "vfmsac.vf", + "vfmsac.vv", + "vfmsub.vf", + "vfmsub.vv", + "vfmul.vf", + "vfmul.vv", + "vfmv.f.s", + "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", + "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", + "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", + "vmfeq.vf", + "vmfeq.vv", + "vmfge.vf", + "vmfgt.vf", + "vmfle.vf", + "vmfle.vv", + "vmflt.vf", + "vmflt.vv", + "vmfne.vf", + "vmfne.vv", + "vrem.vv", + "vrem.vx", + "vremu.vv", + "vremu.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isMulticycle(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "TODO: remove? only Div or customer" +} diff --git a/t1/src/decoder/attribute/isMultiplier.scala b/t1/src/decoder/attribute/isMultiplier.scala new file mode 100644 index 000000000..fa36dcb65 --- /dev/null +++ b/t1/src/decoder/attribute/isMultiplier.scala @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isMultiplier { + def apply(t1DecodePattern: T1DecodePattern): isMultiplier = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isMultiplier(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vmacc.vv", + "vmacc.vx", + "vmadd.vv", + "vmadd.vx", + "vmul.vv", + "vmul.vx", + "vmulh.vv", + "vmulh.vx", + "vmulhsu.vv", + "vmulhsu.vx", + "vmulhu.vv", + "vmulhu.vx", + "vnmsac.vv", + "vnmsac.vx", + "vnmsub.vv", + "vnmsub.vx", + "vsmul.vv", + "vsmul.vx", + "vwmacc.vv", + "vwmacc.vx", + "vwmaccsu.vv", + "vwmaccsu.vx", + "vwmaccu.vv", + "vwmaccu.vx", + "vwmaccus.vx", + "vwmul.vv", + "vwmul.vx", + "vwmulsu.vv", + "vwmulsu.vx", + "vwmulu.vv", + "vwmulu.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isMultiplier(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "goes to [[org.chipsalliance.t1.rtl.LaneMul]]. (only apply to int mul)" +} diff --git a/t1/src/decoder/attribute/isMv.scala b/t1/src/decoder/attribute/isMv.scala new file mode 100644 index 000000000..edd4ce39f --- /dev/null +++ b/t1/src/decoder/attribute/isMv.scala @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isMv { + def apply(t1DecodePattern: T1DecodePattern): isMv = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isMv(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vfmv.f.s", + "vfmv.s.f", + "vmv.s.x", + "vmv.x.s", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isMv(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "move instruction, v->v s->v x->v, single element move. TODO: split them into multiple op since datapath differs " +} diff --git a/t1/src/decoder/attribute/isNarrow.scala b/t1/src/decoder/attribute/isNarrow.scala new file mode 100644 index 000000000..bc9576073 --- /dev/null +++ b/t1/src/decoder/attribute/isNarrow.scala @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isNarrow { + def apply(t1DecodePattern: T1DecodePattern): isNarrow = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isNarrow(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vnclip.wi", + "vnclip.wv", + "vnclip.wx", + "vnclipu.wi", + "vnclipu.wv", + "vnclipu.wx", + "vnsra.wi", + "vnsra.wv", + "vnsra.wx", + "vnsrl.wi", + "vnsrl.wv", + "vnsrl.wx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isNarrow(value: TriState) extends BooleanDecodeAttribute { + override val description: String = " dual width of src will be convert to single width to dst. narrow can be the src of chain. as the dst of chain, only can be fed with Load. TODO: remove it as attribute. " +} diff --git a/t1/src/decoder/attribute/isNr.scala b/t1/src/decoder/attribute/isNr.scala new file mode 100644 index 000000000..e4252d953 --- /dev/null +++ b/t1/src/decoder/attribute/isNr.scala @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isNr { + def apply(t1DecodePattern: T1DecodePattern): isNr = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isNr(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vmv1r.v", + "vmv2r.v", + "vmv4r.v", + "vmv8r.v", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isNr(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "for vmvnr, move vreg group to another vreg group. it will ignore lmul, use from instr. chainable" +} diff --git a/t1/src/decoder/attribute/isOrderreduce.scala b/t1/src/decoder/attribute/isOrderreduce.scala new file mode 100644 index 000000000..abb32796e --- /dev/null +++ b/t1/src/decoder/attribute/isOrderreduce.scala @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isOrderreduce { + def apply(t1DecodePattern: T1DecodePattern): isOrderreduce = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isOrderreduce(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vfredosum.vs", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isOrderreduce(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "don't use it, it's slow, lane read all elements from VRF, send to Top." +} diff --git a/t1/src/decoder/attribute/isOther.scala b/t1/src/decoder/attribute/isOther.scala new file mode 100644 index 000000000..16ddb6214 --- /dev/null +++ b/t1/src/decoder/attribute/isOther.scala @@ -0,0 +1,62 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isOther { + def apply(t1DecodePattern: T1DecodePattern): isOther = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isOther(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcpop.m", + "vfirst.m", + "vfmerge.vfm", + "vfmv.v.f", + "vfmv.s.f", + "vid.v", + "vmerge.vim", + "vmv.v.i", + "vmerge.vvm", + "vmv.v.v", + "vmerge.vxm", + "vmv.v.x", + "vmsbf.m", + "vmsif.m", + "vmsof.m", + "vmv.s.x", + "vmv.x.s", + "vnclip.wi", + "vnclip.wv", + "vnclip.wx", + "vnclipu.wi", + "vnclipu.wv", + "vnclipu.wx", + "vrgather.vi", + "vrgather.vv", + "vrgather.vx", + "vrgatherei16.vv", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isOther(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "goes to [[org.chipsalliance.t1.rtl.OtherUnit]]" +} diff --git a/t1/src/decoder/attribute/isPopcount.scala b/t1/src/decoder/attribute/isPopcount.scala new file mode 100644 index 000000000..0137b77b0 --- /dev/null +++ b/t1/src/decoder/attribute/isPopcount.scala @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isPopcount { + def apply(t1DecodePattern: T1DecodePattern): isPopcount = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isPopcount(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcpop.m", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isPopcount(value: TriState) extends BooleanDecodeAttribute { + override val description: String = " count how many 1s in VS2. lane will use [[org.chipsalliance.t1.rtl.OtherUnit]] to how many 1s locally; use reduce datapath to accumulate, send total result to top top will send result to vd. " +} diff --git a/t1/src/decoder/attribute/isReadonly.scala b/t1/src/decoder/attribute/isReadonly.scala new file mode 100644 index 000000000..cd5754b4b --- /dev/null +++ b/t1/src/decoder/attribute/isReadonly.scala @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isReadonly { + def apply(t1DecodePattern: T1DecodePattern): isReadonly = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isReadonly(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcompress.vm", + "viota.m", + "vrgather.vv", + "vrgatherei16.vv", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isReadonly(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "lane read only instructions. for these instructions lane will only read vrf and send data back to Sequencer. " +} diff --git a/t1/src/decoder/attribute/isRed.scala b/t1/src/decoder/attribute/isRed.scala new file mode 100644 index 000000000..bad01b4ce --- /dev/null +++ b/t1/src/decoder/attribute/isRed.scala @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isRed { + def apply(t1DecodePattern: T1DecodePattern): isRed = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isRed(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcpop.m", + "vfredmax.vs", + "vfredmin.vs", + "vfredosum.vs", + "vfredusum.vs", + "vfwredosum.vs", + "vfwredusum.vs", + "vredand.vs", + "vredmax.vs", + "vredmaxu.vs", + "vredmin.vs", + "vredminu.vs", + "vredor.vs", + "vredsum.vs", + "vredxor.vs", + "vwredsum.vs", + "vwredsumu.vs", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isRed(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "do reduce in each lane. each element will sequentially executed in each lanes. after finishing, pop it to Top, and use ALU at top to get the final result and send to element0 TODO: better name. " +} diff --git a/t1/src/decoder/attribute/isReverse.scala b/t1/src/decoder/attribute/isReverse.scala new file mode 100644 index 000000000..5a26fb507 --- /dev/null +++ b/t1/src/decoder/attribute/isReverse.scala @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isReverse { + def apply(t1DecodePattern: T1DecodePattern): isReverse = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isReverse(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vrsub.vi", + "vrsub.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isReverse(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "only instruction will switch src. TODO: send it to uop. " +} diff --git a/t1/src/decoder/attribute/isSaturate.scala b/t1/src/decoder/attribute/isSaturate.scala new file mode 100644 index 000000000..dba7111e3 --- /dev/null +++ b/t1/src/decoder/attribute/isSaturate.scala @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isSaturate { + def apply(t1DecodePattern: T1DecodePattern): isSaturate = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isSaturate(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vsadd.vi", + "vsadd.vv", + "vsadd.vx", + "vsaddu.vi", + "vsaddu.vv", + "vsaddu.vx", + "vsmul.vv", + "vsmul.vx", + "vssra.vi", + "vssra.vv", + "vssra.vx", + "vssrl.vi", + "vssrl.vv", + "vssrl.vx", + "vssub.vv", + "vssub.vx", + "vssubu.vv", + "vssubu.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcpop.m", + "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", + "vfirst.m", + "vfmv.f.s", + "vfmv.s.f", + "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", + "vfrec7.v", + "vfrsqrt7.v", + "vfsqrt.v", + "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", + "vid.v", + "viota.m", + "vmsbf.m", + "vmsif.m", + "vmsof.m", + "vmv.s.x", + "vmv.x.s", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } +} + +case class isSaturate(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "For adder, does it need to take care of saturate. TODO: add to uop " +} diff --git a/t1/src/decoder/attribute/isScheduler.scala b/t1/src/decoder/attribute/isScheduler.scala new file mode 100644 index 000000000..229c45575 --- /dev/null +++ b/t1/src/decoder/attribute/isScheduler.scala @@ -0,0 +1,278 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isScheduler { + def apply(t1DecodePattern: T1DecodePattern): isScheduler = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isScheduler(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vaadd.vv", + "vaadd.vx", + "vaaddu.vv", + "vaaddu.vx", + "vadc.vim", + "vadc.vvm", + "vadc.vxm", + "vadd.vi", + "vadd.vv", + "vadd.vx", + "vand.vi", + "vand.vv", + "vand.vx", + "vasub.vv", + "vasub.vx", + "vasubu.vv", + "vasubu.vx", + "vdiv.vv", + "vdiv.vx", + "vdivu.vv", + "vdivu.vx", + "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", + "vfmv.v.f", + "vfmin.vf", + "vfmin.vv", + "vfmsac.vf", + "vfmsac.vv", + "vfmsub.vf", + "vfmsub.vv", + "vfmul.vf", + "vfmul.vv", + "vfmv.f.s", + "vfmv.s.f", + "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", + "vfnmacc.vf", + "vfnmacc.vv", + "vfnmadd.vf", + "vfnmadd.vv", + "vfnmsac.vf", + "vfnmsac.vv", + "vfnmsub.vf", + "vfnmsub.vv", + "vfrdiv.vf", + "vfrec7.v", + "vfrsqrt7.v", + "vfrsub.vf", + "vfsgnj.vf", + "vfsgnj.vv", + "vfsgnjn.vf", + "vfsgnjn.vv", + "vfsgnjx.vf", + "vfsgnjx.vv", + "vfslide1down.vf", + "vfslide1up.vf", + "vfsqrt.v", + "vfsub.vf", + "vfsub.vv", + "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", + "vfwsub.vf", + "vfwsub.vv", + "vfwsub.wf", + "vfwsub.wv", + "vid.v", + "vmacc.vv", + "vmacc.vx", + "vmadd.vv", + "vmadd.vx", + "vmand.mm", + "vmandn.mm", + "vmax.vv", + "vmax.vx", + "vmaxu.vv", + "vmaxu.vx", + "vmerge.vim", + "vmv.v.i", + "vmerge.vvm", + "vmv.v.v", + "vmerge.vxm", + "vmv.v.x", + "vmin.vv", + "vmin.vx", + "vminu.vv", + "vminu.vx", + "vmnand.mm", + "vmnor.mm", + "vmor.mm", + "vmorn.mm", + "vmul.vv", + "vmul.vx", + "vmulh.vv", + "vmulh.vx", + "vmulhsu.vv", + "vmulhsu.vx", + "vmulhu.vv", + "vmulhu.vx", + "vmv.s.x", + "vmv.x.s", + "vmv1r.v", + "vmv2r.v", + "vmv4r.v", + "vmv8r.v", + "vmxnor.mm", + "vmxor.mm", + "vnclip.wi", + "vnclip.wv", + "vnclip.wx", + "vnclipu.wi", + "vnclipu.wv", + "vnclipu.wx", + "vnmsac.vv", + "vnmsac.vx", + "vnmsub.vv", + "vnmsub.vx", + "vnsra.wi", + "vnsra.wv", + "vnsra.wx", + "vnsrl.wi", + "vnsrl.wv", + "vnsrl.wx", + "vor.vi", + "vor.vv", + "vor.vx", + "vrem.vv", + "vrem.vx", + "vremu.vv", + "vremu.vx", + "vrgather.vi", + "vrgather.vx", + "vrsub.vi", + "vrsub.vx", + "vsadd.vi", + "vsadd.vv", + "vsadd.vx", + "vsaddu.vi", + "vsaddu.vv", + "vsaddu.vx", + "vsbc.vvm", + "vsbc.vxm", + "vslide1down.vx", + "vslide1up.vx", + "vslidedown.vi", + "vslidedown.vx", + "vslideup.vi", + "vslideup.vx", + "vsll.vi", + "vsll.vv", + "vsll.vx", + "vsmul.vv", + "vsmul.vx", + "vsra.vi", + "vsra.vv", + "vsra.vx", + "vsrl.vi", + "vsrl.vv", + "vsrl.vx", + "vssra.vi", + "vssra.vv", + "vssra.vx", + "vssrl.vi", + "vssrl.vv", + "vssrl.vx", + "vssub.vv", + "vssub.vx", + "vssubu.vv", + "vssubu.vx", + "vsub.vv", + "vsub.vx", + "vwadd.vv", + "vwadd.vx", + "vwadd.wv", + "vwadd.wx", + "vwaddu.vv", + "vwaddu.vx", + "vwaddu.wv", + "vwaddu.wx", + "vwmacc.vv", + "vwmacc.vx", + "vwmaccsu.vv", + "vwmaccsu.vx", + "vwmaccu.vv", + "vwmaccu.vx", + "vwmaccus.vx", + "vwmul.vv", + "vwmul.vx", + "vwmulsu.vv", + "vwmulsu.vx", + "vwmulu.vv", + "vwmulu.vx", + "vwsub.vv", + "vwsub.vx", + "vwsub.wv", + "vwsub.wx", + "vwsubu.vv", + "vwsubu.vx", + "vwsubu.wv", + "vwsubu.wx", + "vxor.vi", + "vxor.vv", + "vxor.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isScheduler(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "lane will send request to Sequencer and wait ack from Sequencer. */ " +} diff --git a/t1/src/decoder/attribute/isShift.scala b/t1/src/decoder/attribute/isShift.scala new file mode 100644 index 000000000..7c78f2f91 --- /dev/null +++ b/t1/src/decoder/attribute/isShift.scala @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isShift { + def apply(t1DecodePattern: T1DecodePattern): isShift = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isShift(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vnsra.wi", + "vnsra.wv", + "vnsra.wx", + "vnsrl.wi", + "vnsrl.wv", + "vnsrl.wx", + "vsll.vi", + "vsll.vv", + "vsll.vx", + "vsra.vi", + "vsra.vv", + "vsra.vx", + "vsrl.vi", + "vsrl.vv", + "vsrl.vx", + "vssra.vi", + "vssra.vv", + "vssra.vx", + "vssrl.vi", + "vssrl.vv", + "vssrl.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isShift(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "goes to [[org.chipsalliance.t1.rtl.LaneShifter]]." +} diff --git a/t1/src/decoder/attribute/isSlid.scala b/t1/src/decoder/attribute/isSlid.scala new file mode 100644 index 000000000..bb60e9a74 --- /dev/null +++ b/t1/src/decoder/attribute/isSlid.scala @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isSlid { + def apply(t1DecodePattern: T1DecodePattern): isSlid = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isSlid(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vfslide1down.vf", + "vfslide1up.vf", + "vslide1down.vx", + "vslide1up.vx", + "vslidedown.vi", + "vslidedown.vx", + "vslideup.vi", + "vslideup.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isSlid(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "used in Sequencer mask unit, decide which vrf should be read. send read request to corresponding lane, lane will respond data to Sequencer. Sequencer will write data to VD. mask unit is work as the router here. TODO: opimize mask unit. " +} diff --git a/t1/src/decoder/attribute/isSpecial.scala b/t1/src/decoder/attribute/isSpecial.scala new file mode 100644 index 000000000..5e361cee3 --- /dev/null +++ b/t1/src/decoder/attribute/isSpecial.scala @@ -0,0 +1,150 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isSpecial { + def apply(t1DecodePattern: T1DecodePattern): isSpecial = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isSpecial(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcompress.vm", + "vcpop.m", + "vfirst.m", + "vfmv.f.s", + "vfmv.s.f", + "vfredmax.vs", + "vfredmin.vs", + "vfredosum.vs", + "vfredusum.vs", + "vfslide1down.vf", + "vfslide1up.vf", + "vfwredosum.vs", + "vfwredusum.vs", + "viota.m", + "vloxei1024.v", + "vloxei128.v", + "vloxei16.v", + "vloxei256.v", + "vloxei32.v", + "vloxei512.v", + "vloxei64.v", + "vloxei8.v", + "vluxei1024.v", + "vluxei128.v", + "vluxei16.v", + "vluxei256.v", + "vluxei32.v", + "vluxei512.v", + "vluxei64.v", + "vluxei8.v", + "vmadc.vi", + "vmadc.vim", + "vmadc.vv", + "vmadc.vvm", + "vmadc.vx", + "vmadc.vxm", + "vmfeq.vf", + "vmfeq.vv", + "vmfge.vf", + "vmfgt.vf", + "vmfle.vf", + "vmfle.vv", + "vmflt.vf", + "vmflt.vv", + "vmfne.vf", + "vmfne.vv", + "vmsbc.vv", + "vmsbc.vvm", + "vmsbc.vx", + "vmsbc.vxm", + "vmsbf.m", + "vmseq.vi", + "vmseq.vv", + "vmseq.vx", + "vmsgt.vi", + "vmsgt.vx", + "vmsgtu.vi", + "vmsgtu.vx", + "vmsif.m", + "vmsle.vi", + "vmsle.vv", + "vmsle.vx", + "vmsleu.vi", + "vmsleu.vv", + "vmsleu.vx", + "vmslt.vv", + "vmslt.vx", + "vmsltu.vv", + "vmsltu.vx", + "vmsne.vi", + "vmsne.vv", + "vmsne.vx", + "vmsof.m", + "vmv.s.x", + "vmv.x.s", + "vredand.vs", + "vredmax.vs", + "vredmaxu.vs", + "vredmin.vs", + "vredminu.vs", + "vredor.vs", + "vredsum.vs", + "vredxor.vs", + "vrgather.vv", + "vrgatherei16.vv", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vslide1down.vx", + "vslide1up.vx", + "vslidedown.vi", + "vslidedown.vx", + "vslideup.vi", + "vslideup.vx", + "vsoxei1024.v", + "vsoxei128.v", + "vsoxei16.v", + "vsoxei256.v", + "vsoxei32.v", + "vsoxei512.v", + "vsoxei64.v", + "vsoxei8.v", + "vsuxei1024.v", + "vsuxei128.v", + "vsuxei16.v", + "vsuxei256.v", + "vsuxei32.v", + "vsuxei512.v", + "vsuxei64.v", + "vsuxei8.v", + "vwredsum.vs", + "vwredsumu.vs", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isSpecial(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "if Sequencer is the router for data from Lane to LSU or Sequencer mask unit. special -> maskUnit || index type load store " +} diff --git a/t1/src/decoder/attribute/isSpecialslot.scala b/t1/src/decoder/attribute/isSpecialslot.scala new file mode 100644 index 000000000..d9afd8bc5 --- /dev/null +++ b/t1/src/decoder/attribute/isSpecialslot.scala @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isSpecialslot { + def apply(t1DecodePattern: T1DecodePattern): isSpecialslot = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isSpecialslot(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vadc.vim", + "vadc.vvm", + "vadc.vxm", + "vcpop.m", + "vfirst.m", + "vfmerge.vfm", + "vfmv.v.f", + "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", + "vfwadd.wf", + "vfwadd.wv", + "vfwsub.wf", + "vfwsub.wv", + "viota.m", + "vmadc.vi", + "vmadc.vim", + "vmadc.vv", + "vmadc.vvm", + "vmadc.vx", + "vmadc.vxm", + "vmand.mm", + "vmandn.mm", + "vmerge.vim", + "vmv.v.i", + "vmerge.vvm", + "vmv.v.v", + "vmerge.vxm", + "vmv.v.x", + "vmfeq.vf", + "vmfeq.vv", + "vmfge.vf", + "vmfgt.vf", + "vmfle.vf", + "vmfle.vv", + "vmflt.vf", + "vmflt.vv", + "vmfne.vf", + "vmfne.vv", + "vmnand.mm", + "vmnor.mm", + "vmor.mm", + "vmorn.mm", + "vmsbc.vv", + "vmsbc.vvm", + "vmsbc.vx", + "vmsbc.vxm", + "vmsbf.m", + "vmseq.vi", + "vmseq.vv", + "vmseq.vx", + "vmsgt.vi", + "vmsgt.vx", + "vmsgtu.vi", + "vmsgtu.vx", + "vmsif.m", + "vmsle.vi", + "vmsle.vv", + "vmsle.vx", + "vmsleu.vi", + "vmsleu.vv", + "vmsleu.vx", + "vmslt.vv", + "vmslt.vx", + "vmsltu.vv", + "vmsltu.vx", + "vmsne.vi", + "vmsne.vv", + "vmsne.vx", + "vmsof.m", + "vmxnor.mm", + "vmxor.mm", + "vnclip.wi", + "vnclip.wv", + "vnclip.wx", + "vnclipu.wi", + "vnclipu.wv", + "vnclipu.wx", + "vnsra.wi", + "vnsra.wv", + "vnsra.wx", + "vnsrl.wi", + "vnsrl.wv", + "vnsrl.wx", + "vsbc.vvm", + "vsbc.vxm", + "vwadd.vv", + "vwadd.vx", + "vwadd.wv", + "vwadd.wx", + "vwaddu.vv", + "vwaddu.vx", + "vwaddu.wv", + "vwaddu.wx", + "vwmacc.vv", + "vwmacc.vx", + "vwmaccsu.vv", + "vwmaccsu.vx", + "vwmaccu.vv", + "vwmaccu.vx", + "vwmaccus.vx", + "vwmul.vv", + "vwmul.vx", + "vwmulsu.vv", + "vwmulsu.vx", + "vwmulu.vv", + "vwmulu.vx", + "vwsub.vv", + "vwsub.vx", + "vwsub.wv", + "vwsub.wx", + "vwsubu.vv", + "vwsubu.vx", + "vwsubu.wv", + "vwsubu.wx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isSpecialslot(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "special instructions schedule to slot0." +} diff --git a/t1/src/decoder/attribute/isSreadvd.scala b/t1/src/decoder/attribute/isSreadvd.scala new file mode 100644 index 000000000..bf9fc6837 --- /dev/null +++ b/t1/src/decoder/attribute/isSreadvd.scala @@ -0,0 +1,311 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isSreadvd { + def apply(t1DecodePattern: T1DecodePattern): isSreadvd = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isSreadvd(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vaadd.vv", + "vaadd.vx", + "vaaddu.vv", + "vaaddu.vx", + "vadc.vim", + "vadc.vvm", + "vadc.vxm", + "vadd.vi", + "vadd.vv", + "vadd.vx", + "vand.vi", + "vand.vv", + "vand.vx", + "vasub.vv", + "vasub.vx", + "vasubu.vv", + "vasubu.vx", + "vcompress.vm", + "vdiv.vv", + "vdiv.vx", + "vdivu.vv", + "vdivu.vx", + "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", + "vfmax.vf", + "vfmax.vv", + "vfmerge.vfm", + "vfmv.v.f", + "vfmin.vf", + "vfmin.vv", + "vfmul.vf", + "vfmul.vv", + "vfmv.f.s", + "vfmv.s.f", + "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", + "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", + "vfslide1down.vf", + "vfslide1up.vf", + "vfsqrt.v", + "vfsub.vf", + "vfsub.vv", + "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", + "vid.v", + "vmadc.vi", + "vmadc.vim", + "vmadc.vv", + "vmadc.vvm", + "vmadc.vx", + "vmadc.vxm", + "vmax.vv", + "vmax.vx", + "vmaxu.vv", + "vmaxu.vx", + "vmerge.vim", + "vmv.v.i", + "vmerge.vvm", + "vmv.v.v", + "vmerge.vxm", + "vmv.v.x", + "vmfeq.vf", + "vmfeq.vv", + "vmfge.vf", + "vmfgt.vf", + "vmfle.vf", + "vmfle.vv", + "vmflt.vf", + "vmflt.vv", + "vmfne.vf", + "vmfne.vv", + "vmin.vv", + "vmin.vx", + "vminu.vv", + "vminu.vx", + "vmsbc.vv", + "vmsbc.vvm", + "vmsbc.vx", + "vmsbc.vxm", + "vmseq.vi", + "vmseq.vv", + "vmseq.vx", + "vmsgt.vi", + "vmsgt.vx", + "vmsgtu.vi", + "vmsgtu.vx", + "vmsle.vi", + "vmsle.vv", + "vmsle.vx", + "vmsleu.vi", + "vmsleu.vv", + "vmsleu.vx", + "vmslt.vv", + "vmslt.vx", + "vmsltu.vv", + "vmsltu.vx", + "vmsne.vi", + "vmsne.vv", + "vmsne.vx", + "vmul.vv", + "vmul.vx", + "vmulh.vv", + "vmulh.vx", + "vmulhsu.vv", + "vmulhsu.vx", + "vmulhu.vv", + "vmulhu.vx", + "vmv.s.x", + "vmv.x.s", + "vmv1r.v", + "vmv2r.v", + "vmv4r.v", + "vmv8r.v", + "vnclip.wi", + "vnclip.wv", + "vnclip.wx", + "vnclipu.wi", + "vnclipu.wv", + "vnclipu.wx", + "vnsra.wi", + "vnsra.wv", + "vnsra.wx", + "vnsrl.wi", + "vnsrl.wv", + "vnsrl.wx", + "vor.vi", + "vor.vv", + "vor.vx", + "vredand.vs", + "vredmax.vs", + "vredmaxu.vs", + "vredmin.vs", + "vredminu.vs", + "vredor.vs", + "vredsum.vs", + "vredxor.vs", + "vrem.vv", + "vrem.vx", + "vremu.vv", + "vremu.vx", + "vrgather.vi", + "vrgather.vv", + "vrgather.vx", + "vrgatherei16.vv", + "vrsub.vi", + "vrsub.vx", + "vsadd.vi", + "vsadd.vv", + "vsadd.vx", + "vsaddu.vi", + "vsaddu.vv", + "vsaddu.vx", + "vsbc.vvm", + "vsbc.vxm", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vslide1down.vx", + "vslide1up.vx", + "vslidedown.vi", + "vslidedown.vx", + "vslideup.vi", + "vslideup.vx", + "vsll.vi", + "vsll.vv", + "vsll.vx", + "vsmul.vv", + "vsmul.vx", + "vsra.vi", + "vsra.vv", + "vsra.vx", + "vsrl.vi", + "vsrl.vv", + "vsrl.vx", + "vssra.vi", + "vssra.vv", + "vssra.vx", + "vssrl.vi", + "vssrl.vv", + "vssrl.vx", + "vssub.vv", + "vssub.vx", + "vssubu.vv", + "vssubu.vx", + "vsub.vv", + "vsub.vx", + "vwadd.vv", + "vwadd.vx", + "vwadd.wv", + "vwadd.wx", + "vwaddu.vv", + "vwaddu.vx", + "vwaddu.wv", + "vwaddu.wx", + "vwmacc.vv", + "vwmacc.vx", + "vwmaccsu.vv", + "vwmaccsu.vx", + "vwmaccu.vv", + "vwmaccu.vx", + "vwmaccus.vx", + "vwmul.vv", + "vwmul.vx", + "vwmulsu.vv", + "vwmulsu.vx", + "vwmulu.vv", + "vwmulu.vx", + "vwredsum.vs", + "vwredsumu.vs", + "vwsub.vv", + "vwsub.vx", + "vwsub.wv", + "vwsub.wx", + "vwsubu.vv", + "vwsubu.vx", + "vwsubu.wv", + "vwsubu.wx", + "vxor.vi", + "vxor.vv", + "vxor.vx", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isSreadvd(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "sReadVD -> !(ma || maskLogic) instruction need to read vd as operator. " +} diff --git a/t1/src/decoder/attribute/isSwrite.scala b/t1/src/decoder/attribute/isSwrite.scala new file mode 100644 index 000000000..cfddf2e04 --- /dev/null +++ b/t1/src/decoder/attribute/isSwrite.scala @@ -0,0 +1,228 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isSwrite { + def apply(t1DecodePattern: T1DecodePattern): isSwrite = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isSwrite(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcompress.vm", + "vcpop.m", + "vfirst.m", + "vfmv.f.s", + "vfredmax.vs", + "vfredmin.vs", + "vfredosum.vs", + "vfredusum.vs", + "vfwredosum.vs", + "vfwredusum.vs", + "viota.m", + "vl1re16.v", + "vl1re32.v", + "vl1re64.v", + "vl1re8.v", + "vl2re16.v", + "vl2re32.v", + "vl2re64.v", + "vl2re8.v", + "vl4re16.v", + "vl4re32.v", + "vl4re64.v", + "vl4re8.v", + "vl8re16.v", + "vl8re32.v", + "vl8re64.v", + "vl8re8.v", + "vle1024.v", + "vle1024ff.v", + "vle128.v", + "vle128ff.v", + "vle16.v", + "vle16ff.v", + "vle256.v", + "vle256ff.v", + "vle32.v", + "vle32ff.v", + "vle512.v", + "vle512ff.v", + "vle64.v", + "vle64ff.v", + "vle8.v", + "vle8ff.v", + "vlm.v", + "vloxei1024.v", + "vloxei128.v", + "vloxei16.v", + "vloxei256.v", + "vloxei32.v", + "vloxei512.v", + "vloxei64.v", + "vloxei8.v", + "vlse1024.v", + "vlse128.v", + "vlse16.v", + "vlse256.v", + "vlse32.v", + "vlse512.v", + "vlse64.v", + "vlse8.v", + "vluxei1024.v", + "vluxei128.v", + "vluxei16.v", + "vluxei256.v", + "vluxei32.v", + "vluxei512.v", + "vluxei64.v", + "vluxei8.v", + "vmadc.vi", + "vmadc.vim", + "vmadc.vv", + "vmadc.vvm", + "vmadc.vx", + "vmadc.vxm", + "vmfeq.vf", + "vmfeq.vv", + "vmfge.vf", + "vmfgt.vf", + "vmfle.vf", + "vmfle.vv", + "vmflt.vf", + "vmflt.vv", + "vmfne.vf", + "vmfne.vv", + "vmsbc.vv", + "vmsbc.vvm", + "vmsbc.vx", + "vmsbc.vxm", + "vmseq.vi", + "vmseq.vv", + "vmseq.vx", + "vmsgt.vi", + "vmsgt.vx", + "vmsgtu.vi", + "vmsgtu.vx", + "vmsle.vi", + "vmsle.vv", + "vmsle.vx", + "vmsleu.vi", + "vmsleu.vv", + "vmsleu.vx", + "vmslt.vv", + "vmslt.vx", + "vmsltu.vv", + "vmsltu.vx", + "vmsne.vi", + "vmsne.vv", + "vmsne.vx", + "vmv.x.s", + "vredand.vs", + "vredmax.vs", + "vredmaxu.vs", + "vredmin.vs", + "vredminu.vs", + "vredor.vs", + "vredsum.vs", + "vredxor.vs", + "vrgather.vv", + "vrgatherei16.vv", + "vs1r.v", + "vs2r.v", + "vs4r.v", + "vs8r.v", + "vse1024.v", + "vse128.v", + "vse16.v", + "vse256.v", + "vse32.v", + "vse512.v", + "vse64.v", + "vse8.v", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vsm.v", + "vsoxei1024.v", + "vsoxei128.v", + "vsoxei16.v", + "vsoxei256.v", + "vsoxei32.v", + "vsoxei512.v", + "vsoxei64.v", + "vsoxei8.v", + "vsse1024.v", + "vsse128.v", + "vsse16.v", + "vsse256.v", + "vsse32.v", + "vsse512.v", + "vsse64.v", + "vsse8.v", + "vsuxei1024.v", + "vsuxei128.v", + "vsuxei16.v", + "vsuxei256.v", + "vsuxei32.v", + "vsuxei512.v", + "vsuxei64.v", + "vsuxei8.v", + "vwadd.vv", + "vwadd.vx", + "vwadd.wv", + "vwadd.wx", + "vwaddu.vv", + "vwaddu.vx", + "vwaddu.wv", + "vwaddu.wx", + "vwmacc.vv", + "vwmacc.vx", + "vwmaccsu.vv", + "vwmaccsu.vx", + "vwmaccu.vv", + "vwmaccu.vx", + "vwmaccus.vx", + "vwmul.vv", + "vwmul.vx", + "vwmulsu.vv", + "vwmulsu.vx", + "vwmulu.vv", + "vwmulu.vx", + "vwredsum.vs", + "vwredsumu.vs", + "vwsub.vv", + "vwsub.vx", + "vwsub.wv", + "vwsub.wx", + "vwsubu.vv", + "vwsubu.vx", + "vwsubu.wv", + "vwsubu.wx", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isSwrite(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "sWrite -> targetRd || readOnly || crossWrite || maskDestination || reduce || loadStore instruction will write vd or rd(scalar) from outside of lane. It will request vrf wait, and lane will not write. " +} diff --git a/t1/src/decoder/attribute/isTargetrd.scala b/t1/src/decoder/attribute/isTargetrd.scala new file mode 100644 index 000000000..d4f6b7dcc --- /dev/null +++ b/t1/src/decoder/attribute/isTargetrd.scala @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isTargetrd { + def apply(t1DecodePattern: T1DecodePattern): isTargetrd = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isTargetrd(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcpop.m", + "vfirst.m", + "vfmv.f.s", + "vmv.x.s", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isTargetrd(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "write rd/fd at scalar core." +} diff --git a/t1/src/decoder/attribute/isUnorderwrite.scala b/t1/src/decoder/attribute/isUnorderwrite.scala new file mode 100644 index 000000000..36a87f910 --- /dev/null +++ b/t1/src/decoder/attribute/isUnorderwrite.scala @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isUnorderwrite { + def apply(t1DecodePattern: T1DecodePattern): isUnorderwrite = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isUnorderwrite(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vfmv.f.s", + "vfmv.s.f", + "vfredosum.vs", + "vfslide1down.vf", + "vfslide1up.vf", + "viota.m", + "vmv.s.x", + "vmv.x.s", + "vslide1down.vx", + "vslide1up.vx", + "vslidedown.vi", + "vslidedown.vx", + "vslideup.vi", + "vslideup.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isUnorderwrite(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "unmanaged write for VRF. these instructions cannot be chain as source. TODO: add an attribute these instruction cannot be the source of chaining. " +} diff --git a/t1/src/decoder/attribute/isUnsigned0.scala b/t1/src/decoder/attribute/isUnsigned0.scala new file mode 100644 index 000000000..c180180bd --- /dev/null +++ b/t1/src/decoder/attribute/isUnsigned0.scala @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isUnsigned0 { + def apply(t1DecodePattern: T1DecodePattern): isUnsigned0 = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isUnsigned0(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vaaddu.vv", + "vaaddu.vx", + "vasubu.vv", + "vasubu.vx", + "vcpop.m", + "vdivu.vv", + "vdivu.vx", + "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", + "vfirst.m", + "vfmv.f.s", + "vfmv.s.f", + "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", + "vfrec7.v", + "vfrsqrt7.v", + "vfsqrt.v", + "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", + "vid.v", + "viota.m", + "vmadc.vi", + "vmadc.vim", + "vmadc.vv", + "vmadc.vvm", + "vmadc.vx", + "vmadc.vxm", + "vmaxu.vv", + "vmaxu.vx", + "vminu.vv", + "vminu.vx", + "vmsbc.vv", + "vmsbc.vvm", + "vmsbc.vx", + "vmsbc.vxm", + "vmsbf.m", + "vmsgtu.vi", + "vmsgtu.vx", + "vmsif.m", + "vmsleu.vi", + "vmsleu.vv", + "vmsleu.vx", + "vmsltu.vv", + "vmsltu.vx", + "vmsof.m", + "vmulhsu.vv", + "vmulhsu.vx", + "vmulhu.vv", + "vmulhu.vx", + "vmv.s.x", + "vmv.x.s", + "vnclipu.wi", + "vnclipu.wv", + "vnclipu.wx", + "vnsrl.wi", + "vnsrl.wv", + "vnsrl.wx", + "vredmaxu.vs", + "vredminu.vs", + "vremu.vv", + "vremu.vx", + "vsaddu.vi", + "vsaddu.vv", + "vsaddu.vx", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vsll.vi", + "vsll.vv", + "vsll.vx", + "vsrl.vi", + "vsrl.vv", + "vsrl.vx", + "vssrl.vi", + "vssrl.vv", + "vssrl.vx", + "vssubu.vv", + "vssubu.vx", + "vwaddu.vv", + "vwaddu.vx", + "vwaddu.wv", + "vwaddu.wx", + "vwmaccu.vv", + "vwmaccu.vx", + "vwmaccus.vx", + "vwmulsu.vv", + "vwmulsu.vx", + "vwmulu.vv", + "vwmulu.vx", + "vwredsumu.vs", + "vwsubu.vv", + "vwsubu.vx", + "vwsubu.wv", + "vwsubu.wx", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isUnsigned0(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "is src0 unsigned? used everywhere in Lane and VFU. " +} diff --git a/t1/src/decoder/attribute/isUnsigned1.scala b/t1/src/decoder/attribute/isUnsigned1.scala new file mode 100644 index 000000000..1f71f2310 --- /dev/null +++ b/t1/src/decoder/attribute/isUnsigned1.scala @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isUnsigned1 { + def apply(t1DecodePattern: T1DecodePattern): isUnsigned1 = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isUnsigned1(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vaaddu.vv", + "vaaddu.vx", + "vasubu.vv", + "vasubu.vx", + "vcpop.m", + "vdivu.vv", + "vdivu.vx", + "vfcvt.f.xu.v", + "vfcvt.rtz.xu.f.v", + "vfirst.m", + "vid.v", + "viota.m", + "vmadc.vi", + "vmadc.vim", + "vmadc.vv", + "vmadc.vvm", + "vmadc.vx", + "vmadc.vxm", + "vmaxu.vv", + "vmaxu.vx", + "vminu.vv", + "vminu.vx", + "vmsbc.vv", + "vmsbc.vvm", + "vmsbc.vx", + "vmsbc.vxm", + "vmsbf.m", + "vmsgtu.vi", + "vmsgtu.vx", + "vmsif.m", + "vmsleu.vi", + "vmsleu.vv", + "vmsleu.vx", + "vmsltu.vv", + "vmsltu.vx", + "vmsof.m", + "vmulhu.vv", + "vmulhu.vx", + "vmv.s.x", + "vmv.x.s", + "vnclipu.wi", + "vnclipu.wv", + "vnclipu.wx", + "vnsrl.wi", + "vnsrl.wv", + "vnsrl.wx", + "vredmaxu.vs", + "vredminu.vs", + "vremu.vv", + "vremu.vx", + "vsaddu.vi", + "vsaddu.vv", + "vsaddu.vx", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vsll.vi", + "vsll.vv", + "vsll.vx", + "vsrl.vi", + "vsrl.vv", + "vsrl.vx", + "vssrl.vi", + "vssrl.vv", + "vssrl.vx", + "vssubu.vv", + "vssubu.vx", + "vwaddu.vv", + "vwaddu.vx", + "vwaddu.wv", + "vwaddu.wx", + "vwmaccsu.vv", + "vwmaccsu.vx", + "vwmaccu.vv", + "vwmaccu.vx", + "vwmulu.vv", + "vwmulu.vx", + "vwredsumu.vs", + "vwsubu.vv", + "vwsubu.vx", + "vwsubu.wv", + "vwsubu.wx", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isUnsigned1(value: TriState) extends BooleanDecodeAttribute { + override val description: String = " is src1 unsigned? used everywhere in Lane and VFU. " +} diff --git a/t1/src/decoder/attribute/isVector.scala b/t1/src/decoder/attribute/isVector.scala new file mode 100644 index 000000000..170c6c43b --- /dev/null +++ b/t1/src/decoder/attribute/isVector.scala @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isVector { + def apply(t1DecodePattern: T1DecodePattern): isVector = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isVector(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + i.instructionSets.map(_.name).contains("rv_v") + ) + allMatched.contains(t1DecodePattern.instruction) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isVector(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "This instruction should be decode by T1." +} diff --git a/t1/src/decoder/attribute/isVtype.scala b/t1/src/decoder/attribute/isVtype.scala new file mode 100644 index 000000000..605588b08 --- /dev/null +++ b/t1/src/decoder/attribute/isVtype.scala @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isVtype { + def apply(t1DecodePattern: T1DecodePattern): isVtype = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isVtype(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vaadd.vv", + "vaaddu.vv", + "vadc.vvm", + "vadd.vv", + "vand.vv", + "vasub.vv", + "vasubu.vv", + "vcompress.vm", + "vcpop.m", + "vdiv.vv", + "vdivu.vv", + "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.vv", + "vfirst.m", + "vfmacc.vv", + "vfmadd.vv", + "vfmax.vv", + "vfmin.vv", + "vfmsac.vv", + "vfmsub.vv", + "vfmul.vv", + "vfmv.f.s", + "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", + "vfnmacc.vv", + "vfnmadd.vv", + "vfnmsac.vv", + "vfnmsub.vv", + "vfrec7.v", + "vfredmax.vs", + "vfredmin.vs", + "vfredosum.vs", + "vfredusum.vs", + "vfrsqrt7.v", + "vfsgnj.vv", + "vfsgnjn.vv", + "vfsgnjx.vv", + "vfsqrt.v", + "vfsub.vv", + "vfwadd.vv", + "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.vv", + "vfwmsac.vv", + "vfwmul.vv", + "vfwnmacc.vv", + "vfwnmsac.vv", + "vfwredosum.vs", + "vfwredusum.vs", + "vfwsub.vv", + "vfwsub.wv", + "vid.v", + "viota.m", + "vmacc.vv", + "vmadc.vv", + "vmadc.vvm", + "vmadd.vv", + "vmand.mm", + "vmandn.mm", + "vmax.vv", + "vmaxu.vv", + "vmerge.vvm", + "vmv.v.v", + "vmfeq.vv", + "vmfle.vv", + "vmflt.vv", + "vmfne.vv", + "vmin.vv", + "vminu.vv", + "vmnand.mm", + "vmnor.mm", + "vmor.mm", + "vmorn.mm", + "vmsbc.vv", + "vmsbc.vvm", + "vmsbf.m", + "vmseq.vv", + "vmsif.m", + "vmsle.vv", + "vmsleu.vv", + "vmslt.vv", + "vmsltu.vv", + "vmsne.vv", + "vmsof.m", + "vmul.vv", + "vmulh.vv", + "vmulhsu.vv", + "vmulhu.vv", + "vmv.x.s", + "vmxnor.mm", + "vmxor.mm", + "vnclip.wv", + "vnclipu.wv", + "vnmsac.vv", + "vnmsub.vv", + "vnsra.wv", + "vnsrl.wv", + "vor.vv", + "vredand.vs", + "vredmax.vs", + "vredmaxu.vs", + "vredmin.vs", + "vredminu.vs", + "vredor.vs", + "vredsum.vs", + "vredxor.vs", + "vrem.vv", + "vremu.vv", + "vrgather.vv", + "vrgatherei16.vv", + "vsadd.vv", + "vsaddu.vv", + "vsbc.vvm", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vsll.vv", + "vsmul.vv", + "vsra.vv", + "vsrl.vv", + "vssra.vv", + "vssrl.vv", + "vssub.vv", + "vssubu.vv", + "vsub.vv", + "vwadd.vv", + "vwadd.wv", + "vwaddu.vv", + "vwaddu.wv", + "vwmacc.vv", + "vwmaccsu.vv", + "vwmaccu.vv", + "vwmul.vv", + "vwmulsu.vv", + "vwmulu.vv", + "vwredsum.vs", + "vwredsumu.vs", + "vwsub.vv", + "vwsub.wv", + "vwsubu.vv", + "vwsubu.wv", + "vxor.vv", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isVtype(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "src1 is vtype." +} diff --git a/t1/src/decoder/attribute/isVwmacc.scala b/t1/src/decoder/attribute/isVwmacc.scala new file mode 100644 index 000000000..1d8978e25 --- /dev/null +++ b/t1/src/decoder/attribute/isVwmacc.scala @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isVwmacc { + def apply(t1DecodePattern: T1DecodePattern): isVwmacc = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isVwmacc(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vwmacc.vv", + "vwmacc.vx", + "vwmaccsu.vv", + "vwmaccsu.vx", + "vwmaccu.vv", + "vwmaccu.vx", + "vwmaccus.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isVwmacc(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "special MAC instruction, MAC use vd as source, it cross read vd. TODO: cross read vd + mac uop. " +} diff --git a/t1/src/decoder/attribute/isWidenreduce.scala b/t1/src/decoder/attribute/isWidenreduce.scala new file mode 100644 index 000000000..8815b4a2e --- /dev/null +++ b/t1/src/decoder/attribute/isWidenreduce.scala @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isWidenreduce { + def apply(t1DecodePattern: T1DecodePattern): isWidenreduce = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isWidenreduce(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vwredsum.vs", + "vwredsumu.vs", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcpop.m", + "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", + "vfirst.m", + "vfmv.f.s", + "vfmv.s.f", + "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", + "vfrec7.v", + "vfrsqrt7.v", + "vfsqrt.v", + "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", + "vid.v", + "viota.m", + "vmsbf.m", + "vmsif.m", + "vmsof.m", + "vmv.s.x", + "vmv.x.s", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } +} + +case class isWidenreduce(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "a special widen, only write dual vd from Top to element0 it doesn't cross. TODO: better name. " +} diff --git a/t1/src/decoder/attribute/isZero.scala b/t1/src/decoder/attribute/isZero.scala new file mode 100644 index 000000000..8017ebf56 --- /dev/null +++ b/t1/src/decoder/attribute/isZero.scala @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object isZero { + def apply(t1DecodePattern: T1DecodePattern): isZero = + Seq( + y _ -> Y, + n _ -> N, + dc _ -> DC + ).collectFirst { + case (fn, tri) if fn(t1DecodePattern) => isZero(tri) + }.get + + def y(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = Seq( + "vcompress.vm", + "vfslide1down.vf", + "vfslide1up.vf", + "viota.m", + "vmv1r.v", + "vmv2r.v", + "vmv4r.v", + "vmv8r.v", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vslide1down.vx", + "vslide1up.vx", + "vslidedown.vi", + "vslidedown.vx", + "vslideup.vi", + "vslideup.vx", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def n(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(y(t1DecodePattern) || dc(t1DecodePattern)) + ) + allMatched.contains(t1DecodePattern.instruction) + } + + def dc(t1DecodePattern: T1DecodePattern): Boolean = false +} + +case class isZero(value: TriState) extends BooleanDecodeAttribute { + override val description: String = "goes to [[org.chipsalliance.t1.rtl.OtherUnit]]" +} diff --git a/t1/src/decoder/attribute/logicUop.scala b/t1/src/decoder/attribute/logicUop.scala new file mode 100644 index 000000000..dcda5a7d0 --- /dev/null +++ b/t1/src/decoder/attribute/logicUop.scala @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +trait LogicUopType extends Uop +object logicUop0 extends LogicUopType +object logicUop1 extends LogicUopType +object logicUop2 extends LogicUopType +object logicUop4 extends LogicUopType +object logicUop5 extends LogicUopType +object logicUop6 extends LogicUopType +object logicUop8 extends LogicUopType +object logicUop9 extends LogicUopType + +object LogicUop { + def apply(t1DecodePattern: T1DecodePattern): Uop = { + Seq( + t0 _ -> logicUop0, + t1 _ -> logicUop1, + t2 _ -> logicUop2, + t4 _ -> logicUop4, + t5 _ -> logicUop5, + t6 _ -> logicUop6, + t8 _ -> logicUop8, + t9 _ -> logicUop9, + ).collectFirst { + case (fn, tpe) if fn(t1DecodePattern) => tpe + }.getOrElse(UopDC) + } + def t0(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vand.vi", + "vand.vv", + "vand.vx", + "vmand.mm", + "vredand.vs", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t1(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmor.mm", + "vor.vi", + "vor.vv", + "vor.vx", + "vredor.vs", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t2(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmxor.mm", + "vredxor.vs", + "vxor.vi", + "vxor.vv", + "vxor.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t4(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmandn.mm", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t5(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmorn.mm", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t6(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmxnor.mm", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t8(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmnand.mm", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t9(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmnor.mm", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } +} diff --git a/t1/src/decoder/attribute/mulUop.scala b/t1/src/decoder/attribute/mulUop.scala new file mode 100644 index 000000000..c7c1a9ef6 --- /dev/null +++ b/t1/src/decoder/attribute/mulUop.scala @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +trait MulUOPType extends Uop +object mulUop0 extends MulUOPType +object mulUop1 extends MulUOPType +object mulUop3 extends MulUOPType +object mulUop5 extends MulUOPType +object mulUop10 extends MulUOPType +object mulUop14 extends MulUOPType + +object MulUOP { + def apply(t1DecodePattern: T1DecodePattern): Uop = { + Seq( + t0 _ -> mulUop0, + t1 _ -> mulUop1, + t3 _ -> mulUop3, + t5 _ -> mulUop5, + t10 _ -> mulUop10, + t14 _ -> mulUop14, + ).collectFirst { + case (fn, tpe) if fn(t1DecodePattern) => tpe + }.getOrElse(UopDC) + } + def t0(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmul.vv", + "vmul.vx", + "vsmul.vv", + "vsmul.vx", + "vwmul.vv", + "vwmul.vx", + "vwmulsu.vv", + "vwmulsu.vx", + "vwmulu.vv", + "vwmulu.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t1(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmadd.vv", + "vmadd.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t3(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmulh.vv", + "vmulh.vx", + "vmulhsu.vv", + "vmulhsu.vx", + "vmulhu.vv", + "vmulhu.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t5(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmacc.vv", + "vmacc.vx", + "vwmacc.vv", + "vwmacc.vx", + "vwmaccsu.vv", + "vwmaccsu.vx", + "vwmaccu.vv", + "vwmaccu.vx", + "vwmaccus.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t10(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vnmsub.vv", + "vnmsub.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t14(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vnmsac.vv", + "vnmsac.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } +} + +case class MulUOP(value: MulUOPType) extends UopDecodeAttribute[MulUOPType] { + override val description: String = "" +} diff --git a/t1/src/decoder/attribute/otherUop.scala b/t1/src/decoder/attribute/otherUop.scala new file mode 100644 index 000000000..63e77635c --- /dev/null +++ b/t1/src/decoder/attribute/otherUop.scala @@ -0,0 +1,114 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +trait OtherUopType extends Uop +object otherUop0 extends OtherUopType +object otherUop1 extends OtherUopType +object otherUop2 extends OtherUopType +object otherUop3 extends OtherUopType +object otherUop4 extends OtherUopType +object otherUop5 extends OtherUopType +object otherUop6 extends OtherUopType +object otherUop7 extends OtherUopType +object otherUop8 extends OtherUopType +object otherUop9 extends OtherUopType + +object OtherUop { + def apply(t1DecodePattern: T1DecodePattern): Uop = { + Seq( + t0 _ -> otherUop0, + t1 _ -> otherUop1, + t2 _ -> otherUop2, + t3 _ -> otherUop3, + t4 _ -> otherUop4, + t5 _ -> otherUop5, + t6 _ -> otherUop6, + t7 _ -> otherUop7, + t8 _ -> otherUop8, + t9 _ -> otherUop9, + ).collectFirst { + case (fn, tpe) if fn(t1DecodePattern) => tpe + }.getOrElse(UopDC) + } + def t0(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfirst.m", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t1(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmsbf.m", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t2(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmsof.m", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t3(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vmsif.m", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t4(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vrgather.vi", + "vrgather.vv", + "vrgather.vx", + "vrgatherei16.vv", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t5(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfmerge.vfm", + "vfmv.v.f", + "vmerge.vim", + "vmv.v.i", + "vmerge.vvm", + "vmv.v.v", + "vmerge.vxm", + "vmv.v.x", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t6(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vnclip.wi", + "vnclip.wv", + "vnclip.wx", + "vnclipu.wi", + "vnclipu.wv", + "vnclipu.wx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t7(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfmv.s.f", + "vmv.s.x", + "vmv.x.s", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t8(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vcpop.m", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t9(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vid.v", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } +} diff --git a/t1/src/decoder/attribute/package.scala b/t1/src/decoder/attribute/package.scala new file mode 100644 index 000000000..da62fe4cd --- /dev/null +++ b/t1/src/decoder/attribute/package.scala @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder + +import chisel3.experimental.hierarchy.Instantiate +import chisel3.properties.{ClassType, Property} + +package object attribute { + /** Attribute that will be encode the property of an instruction in the uarch + * and will be additional encode into the object module, + * which will be used to provide metadata for verifications. + */ + trait DecodeAttribute[T] { + val identifier: String = this.getClass.getSimpleName.replace("$", "") + val value: T + val description: String + // Property of this attribute + def om: Property[ClassType] = { + val obj = Instantiate(new T1DecodeAttributeOM) + obj.identifierIn := Property(identifier) + obj.descriptionIn := Property(description) + // Use toString to avoid type issues... + obj.valueIn := Property(value.toString) + obj.getPropertyReference + } + } + + sealed trait TriState + case object Y extends TriState + case object N extends TriState + case object DC extends TriState + + trait Uop + object UopDC extends Uop + trait UopDecodeAttribute[T <: Uop] extends DecodeAttribute[T] + + trait BooleanDecodeAttribute extends DecodeAttribute[TriState] + // TODO: we can add more scala type to avoid string type. + trait StringDecodeAttribute extends DecodeAttribute[String] +} + + diff --git a/t1/src/decoder/attribute/shiftUop.scala b/t1/src/decoder/attribute/shiftUop.scala new file mode 100644 index 000000000..787dd1d94 --- /dev/null +++ b/t1/src/decoder/attribute/shiftUop.scala @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +trait ShiftUopType extends Uop +object shiftUop0 extends ShiftUopType +object shiftUop1 extends ShiftUopType +object shiftUop2 extends ShiftUopType +object shiftUop4 extends ShiftUopType +object shiftUop6 extends ShiftUopType + +object ShiftUop { + def apply(t1DecodePattern: T1DecodePattern): Uop = { + Seq( + t0 _ -> shiftUop0, + t1 _ -> shiftUop1, + t2 _ -> shiftUop2, + t4 _ -> shiftUop4, + t6 _ -> shiftUop6, + ).collectFirst { + case (fn, tpe) if fn(t1DecodePattern) => tpe + }.getOrElse(UopDC) + } + def t0(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vnsrl.wi", + "vnsrl.wv", + "vnsrl.wx", + "vsrl.vi", + "vsrl.vv", + "vsrl.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t1(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vsll.vi", + "vsll.vv", + "vsll.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t2(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vnsra.wi", + "vnsra.wv", + "vnsra.wx", + "vsra.vi", + "vsra.vv", + "vsra.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t4(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vssrl.vi", + "vssrl.vv", + "vssrl.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t6(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vssra.vi", + "vssra.vv", + "vssra.vx", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } +} + +case class ShiftUop(value: ShiftUopType) extends UopDecodeAttribute[ShiftUopType] { + override val description: String = "" +} diff --git a/t1/src/decoder/attribute/topUop.scala b/t1/src/decoder/attribute/topUop.scala new file mode 100644 index 000000000..115141083 --- /dev/null +++ b/t1/src/decoder/attribute/topUop.scala @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +trait TopUopType extends Uop +object TopT0 extends TopUopType +object TopT1 extends TopUopType +object TopT2 extends TopUopType +object TopT3 extends TopUopType +object TopT5 extends TopUopType +object TopT6 extends TopUopType +object TopT7 extends TopUopType + +object TopUop { + def apply(t1DecodePattern: T1DecodePattern): TopUop = { + Seq( + t0 _ -> TopT0, + t1 _ -> TopT1, + t2 _ -> TopT2, + t3 _ -> TopT3, + t5 _ -> TopT5, + t6 _ -> TopT6, + t7 _ -> TopT7, + ).collectFirst { + case (fn, tpe) if fn(t1DecodePattern) => TopUop(tpe) + }.getOrElse(TopUop(TopT0)) + } + def t0(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched = t1DecodePattern.param.allInstructions.filter(i => + !(t1(t1DecodePattern) + || t2(t1DecodePattern) + || t3(t1DecodePattern) + || t5(t1DecodePattern) + || t6(t1DecodePattern) + || t7(t1DecodePattern) + ) + ) + allMatched.contains(t1DecodePattern.instruction) + } + def t1(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfslide1down.vf", + "vslide1down.vx", + "vzext.vf2", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t2(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vslideup.vi", + "vslideup.vx", + "vzext.vf4", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t3(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vfslide1up.vf", + "vslide1up.vx", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t5(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vsext.vf2", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t6(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vsext.vf4", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } + def t7(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vsext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } +} + +case class TopUop(value: TopUopType) extends UopDecodeAttribute[TopUopType] { + override val description: String = "uop for mask unit." +} diff --git a/t1/src/decoder/attribute/uop.scala b/t1/src/decoder/attribute/uop.scala new file mode 100644 index 000000000..66d8dbf02 --- /dev/null +++ b/t1/src/decoder/attribute/uop.scala @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +object DecoderUop { + def apply(t1DecodePattern: T1DecodePattern): DecoderUop = { + val tpe: Option[DecoderUop] = Seq( + isDivider.y(t1DecodePattern) -> DivUOP(t1DecodePattern), + isFloat.y(t1DecodePattern) -> FloatUop(t1DecodePattern), + isMultiplier.y(t1DecodePattern) -> MulUOP(t1DecodePattern), + isAdder.y(t1DecodePattern) -> AdderUOP(t1DecodePattern), + isLogic.y(t1DecodePattern) -> LogicUop(t1DecodePattern), + isShift.y(t1DecodePattern) -> ShiftUop(t1DecodePattern), + isOther.y(t1DecodePattern) -> OtherUop(t1DecodePattern), + isZero.y(t1DecodePattern) -> ZeroUOP(t1DecodePattern) + ).collectFirst { + case (fn, tpe) if fn => DecoderUop(tpe) + } + require(tpe.size <= 1) + tpe.getOrElse(DecoderUop(UopDC)) + } +} + +case class DecoderUop(value: Uop) extends UopDecodeAttribute[Uop] { + override val description: String = "uop for mask unit." +} diff --git a/t1/src/decoder/attribute/zeroUop.scala b/t1/src/decoder/attribute/zeroUop.scala new file mode 100644 index 000000000..3c009614e --- /dev/null +++ b/t1/src/decoder/attribute/zeroUop.scala @@ -0,0 +1,45 @@ + +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2022 Jiuyang Liu + +package org.chipsalliance.t1.rtl.decoder.attribute + +import org.chipsalliance.t1.rtl.decoder.T1DecodePattern + +trait ZeroUOPType extends Uop +object zeroUop0 extends ZeroUOPType + +object ZeroUOP { + def apply(t1DecodePattern: T1DecodePattern): Uop = { + Seq( + t0 _ -> zeroUop0, + ).collectFirst { + case (fn, tpe) if fn(t1DecodePattern) => tpe + }.getOrElse(UopDC) + } + def t0(t1DecodePattern: T1DecodePattern): Boolean = { + val allMatched: Seq[String] = Seq( + "vcompress.vm", + "vfslide1down.vf", + "vfslide1up.vf", + "viota.m", + "vmv1r.v", + "vmv2r.v", + "vmv4r.v", + "vmv8r.v", + "vsext.vf2", + "vsext.vf4", + "vsext.vf8", + "vslide1down.vx", + "vslide1up.vx", + "vslidedown.vi", + "vslidedown.vx", + "vslideup.vi", + "vslideup.vx", + "vzext.vf2", + "vzext.vf4", + "vzext.vf8", + ) + allMatched.contains(t1DecodePattern.instruction.name) + } +} diff --git a/t1/src/laneStage/LaneExecutionBridge.scala b/t1/src/laneStage/LaneExecutionBridge.scala index a898a0d4a..3a58046f3 100644 --- a/t1/src/laneStage/LaneExecutionBridge.scala +++ b/t1/src/laneStage/LaneExecutionBridge.scala @@ -19,7 +19,7 @@ class LaneExecuteRequest(parameter: LaneParameter, isLastSlot: Boolean) extends val groupCounter: UInt = UInt(parameter.groupNumberBits.W) val sSendResponse: Option[Bool] = Option.when(isLastSlot)(Bool()) // pipe state - val decodeResult: DecodeBundle = Decoder.bundle(parameter.fpuEnable) + val decodeResult: DecodeBundle = Decoder.bundle(parameter.decoderParam) val vSew1H: UInt = UInt(3.W) val csr: CSRInterface = new CSRInterface(parameter.vlMaxBits) val maskType: Bool = Bool() @@ -43,7 +43,7 @@ class ExecutionBridgeRecordQueue(parameter: LaneParameter, isLastSlot: Boolean) val executeIndex: Bool = Bool() val source2: UInt = UInt(parameter.datapathWidth.W) // pipe state - val decodeResult: DecodeBundle = Decoder.bundle(parameter.fpuEnable) + val decodeResult: DecodeBundle = Decoder.bundle(parameter.decoderParam) val vSew1H: UInt = UInt(3.W) } @@ -68,9 +68,9 @@ class LaneExecutionBridge(parameter: LaneParameter, isLastSlot: Boolean, slotInd val selfCompleted: Bool = IO(Input(Bool())) @public - val executeDecode: DecodeBundle = IO(Output(Decoder.bundle(parameter.fpuEnable))) + val executeDecode: DecodeBundle = IO(Output(Decoder.bundle(parameter.decoderParam))) @public - val responseDecode: DecodeBundle = IO(Output(Decoder.bundle(parameter.fpuEnable))) + val responseDecode: DecodeBundle = IO(Output(Decoder.bundle(parameter.decoderParam))) val executionRecord: ExecutionUnitRecord = RegInit(0.U.asTypeOf(new ExecutionUnitRecord(parameter)(isLastSlot))) val executionRecordValid = RegInit(false.B) diff --git a/t1/src/laneStage/LaneStage.scala b/t1/src/laneStage/LaneStage.scala index f4ec2606a..17a890d45 100644 --- a/t1/src/laneStage/LaneStage.scala +++ b/t1/src/laneStage/LaneStage.scala @@ -14,7 +14,7 @@ class LaneState(parameter: LaneParameter) extends Bundle { val vSew1H: UInt = UInt(3.W) val loadStore: Bool = Bool() val laneIndex: UInt = UInt(parameter.laneNumberBits.W) - val decodeResult: DecodeBundle = Decoder.bundle(parameter.fpuEnable) + val decodeResult: DecodeBundle = Decoder.bundle(parameter.decoderParam) /** which group is the last group for instruction. */ val lastGroupForInstruction: UInt = UInt(parameter.groupNumberBits.W) val isLastLaneForInstruction: Bool = Bool() diff --git a/t1/src/laneStage/LaneStage0.scala b/t1/src/laneStage/LaneStage0.scala index 78798092a..b07d617da 100644 --- a/t1/src/laneStage/LaneStage0.scala +++ b/t1/src/laneStage/LaneStage0.scala @@ -21,7 +21,7 @@ class LaneStage0Enqueue(parameter: LaneParameter) extends Bundle { val vSew1H: UInt = UInt(3.W) val loadStore: Bool = Bool() val laneIndex: UInt = UInt(parameter.laneNumberBits.W) - val decodeResult: DecodeBundle = Decoder.bundle(parameter.fpuEnable) + val decodeResult: DecodeBundle = Decoder.bundle(parameter.decoderParam) /** which group is the last group for instruction. */ val lastGroupForInstruction: UInt = UInt(parameter.groupNumberBits.W) val isLastLaneForInstruction: Bool = Bool() @@ -65,7 +65,7 @@ class LaneStage0Dequeue(parameter: LaneParameter, isLastSlot: Boolean) extends B // pipe state val instructionIndex: UInt = UInt(parameter.instructionIndexBits.W) - val decodeResult: DecodeBundle = Decoder.bundle(parameter.fpuEnable) + val decodeResult: DecodeBundle = Decoder.bundle(parameter.decoderParam) val laneIndex: UInt = UInt(parameter.laneNumberBits.W) // skip vrf read in stage 1? val skipRead: Bool = Bool() diff --git a/t1/src/laneStage/LaneStage1.scala b/t1/src/laneStage/LaneStage1.scala index 95e6237c1..f44826e79 100644 --- a/t1/src/laneStage/LaneStage1.scala +++ b/t1/src/laneStage/LaneStage1.scala @@ -18,7 +18,7 @@ class LaneStage1Enqueue(parameter: LaneParameter, isLastSlot: Boolean) extends B val sSendResponse: Option[Bool] = Option.when(isLastSlot)(Bool()) // pipe state val instructionIndex: UInt = UInt(parameter.instructionIndexBits.W) - val decodeResult: DecodeBundle = Decoder.bundle(parameter.fpuEnable) + val decodeResult: DecodeBundle = Decoder.bundle(parameter.decoderParam) val laneIndex: UInt = UInt(parameter.laneNumberBits.W) // skip vrf read in stage 1? val skipRead: Bool = Bool() @@ -49,7 +49,7 @@ class LaneStage1Dequeue(parameter: LaneParameter, isLastSlot: Boolean) extends B // pipe state // for exe stage - val decodeResult: DecodeBundle = Decoder.bundle(parameter.fpuEnable) + val decodeResult: DecodeBundle = Decoder.bundle(parameter.decoderParam) val vSew1H: UInt = UInt(3.W) val csr: CSRInterface = new CSRInterface(parameter.vlMaxBits) val maskType: Bool = Bool() diff --git a/t1/src/laneStage/LaneStage2.scala b/t1/src/laneStage/LaneStage2.scala index 367bef1c8..f9bd76621 100644 --- a/t1/src/laneStage/LaneStage2.scala +++ b/t1/src/laneStage/LaneStage2.scala @@ -19,7 +19,7 @@ class LaneStage2Enqueue(parameter: LaneParameter, isLastSlot: Boolean) extends B val bordersForMaskLogic: Bool = Bool() // pipe state // for stage3 - val decodeResult: DecodeBundle = Decoder.bundle(parameter.fpuEnable) + val decodeResult: DecodeBundle = Decoder.bundle(parameter.decoderParam) val instructionIndex: UInt = UInt(parameter.instructionIndexBits.W) val loadStore: Bool = Bool() /** vd or rd */ @@ -37,7 +37,7 @@ class LaneStage2Dequeue(parameter: LaneParameter, isLastSlot: Boolean) extends B val pipeData: Option[UInt] = Option.when(isLastSlot)(UInt(parameter.datapathWidth.W)) // pipe state for stage3 - val decodeResult: DecodeBundle = Decoder.bundle(parameter.fpuEnable) + val decodeResult: DecodeBundle = Decoder.bundle(parameter.decoderParam) val instructionIndex: UInt = UInt(parameter.instructionIndexBits.W) val loadStore: Bool = Bool() val vd: UInt = UInt(5.W) diff --git a/t1/src/laneStage/LaneStage3.scala b/t1/src/laneStage/LaneStage3.scala index fb68529f8..8ccc6fbc1 100644 --- a/t1/src/laneStage/LaneStage3.scala +++ b/t1/src/laneStage/LaneStage3.scala @@ -21,7 +21,7 @@ class LaneStage3Enqueue(parameter: LaneParameter, isLastSlot: Boolean) extends B val ffoSuccess: Bool = Bool() val fpReduceValid: Option[Bool] = Option.when(parameter.fpuEnable && isLastSlot)(Bool()) // pipe state - val decodeResult: DecodeBundle = Decoder.bundle(parameter.fpuEnable) + val decodeResult: DecodeBundle = Decoder.bundle(parameter.decoderParam) val instructionIndex: UInt = UInt(parameter.instructionIndexBits.W) // Need real-time status, no pipe val ffoByOtherLanes: Bool = Bool() diff --git a/t1/src/laneStage/SlotTokenManager.scala b/t1/src/laneStage/SlotTokenManager.scala index 10b7a5516..6bdead928 100644 --- a/t1/src/laneStage/SlotTokenManager.scala +++ b/t1/src/laneStage/SlotTokenManager.scala @@ -11,7 +11,7 @@ import org.chipsalliance.t1.rtl._ import org.chipsalliance.t1.rtl.decoder.Decoder class EnqReportBundle(parameter: LaneParameter) extends Bundle { - val decodeResult: DecodeBundle = Decoder.bundle(parameter.fpuEnable) + val decodeResult: DecodeBundle = Decoder.bundle(parameter.decoderParam) val instructionIndex: UInt = UInt(parameter.instructionIndexBits.W) val sSendResponse: Bool = Bool() val mask: UInt = UInt(4.W)