From fa7573bc2239c9a722349c49d4116dea63b24631 Mon Sep 17 00:00:00 2001 From: xueweiwujxw Date: Wed, 11 Jun 2025 15:04:51 +0800 Subject: [PATCH 01/11] =?UTF-8?q?feat:=20=E2=9C=A8(IProject)=20add=20=20IP?= =?UTF-8?q?roject=20trait?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scala/spinalutils/xilinx/IProject.scala | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 src/main/scala/spinalutils/xilinx/IProject.scala diff --git a/src/main/scala/spinalutils/xilinx/IProject.scala b/src/main/scala/spinalutils/xilinx/IProject.scala new file mode 100644 index 0000000..9cb4b1d --- /dev/null +++ b/src/main/scala/spinalutils/xilinx/IProject.scala @@ -0,0 +1,87 @@ +package spinalutils.xilinx + +import spinal.core._ +import spinal.lib._ + +import java.io.File +import java.io.PrintWriter +import java.io.FileWriter +import java.io.BufferedWriter +import java.nio.file._ +import spinalutils.xilinx.ip.IXilinxIP + +case class ProjectConfig( + part: String, + name: String = "vivadoPrj", + version: String = "2021.1" +) + +trait IProject { + var config: ProjectConfig = ProjectConfig(part = "xc7k325tffg900-2") + def configProject(cfg: ProjectConfig) { + config = cfg + } + + def traverseTcl(com: Component): List[String] = { + var tcls: List[String] = List() + if (com.isInstanceOf[IXilinxIP]) { + var ip = com.asInstanceOf[IXilinxIP] + tcls = tcls ::: ip.generateTcl() + ip.displayInfo() + } else if (com.isInstanceOf[Component]) { + com.children.map { case c => + tcls = tcls ::: traverseTcl(c) + } + } + tcls + } + + def traverseXdc(com: Component): List[String] = { + var tcls: List[String] = List() + if (com.isInstanceOf[IXilinxIP]) { + tcls = tcls ::: com.asInstanceOf[IXilinxIP].generateXdc() + } else if (com.isInstanceOf[Component]) { + com.children.map { case c => + tcls = tcls ::: traverseXdc(c) + } + } + tcls + } + + def outputTcl(filename: String = "generate.tcl") { + var tcls: List[String] = traverseTcl(this.asInstanceOf[Component]) + val file = new File(filename) + val writer = new PrintWriter(file) + println("") + writer.write("#Create IPs \r\n") + tcls.zipWithIndex.map { case (t, i) => writer.write(t + "\r\n") } + writer.close() + } + + def outputXdc(basefile: String = null, filename: String = "constraints.xdc") { + val file = new File(filename) + if (file.exists()) { + file.delete() + } + + if (basefile != null) { + val base = new File(basefile) + if (base.exists()) { + Files.copy( + base.toPath(), + file.toPath(), + StandardCopyOption.REPLACE_EXISTING + ) + } + } + + val fw = new FileWriter(file, true) + val bw = new BufferedWriter(fw) + val pw = new PrintWriter(bw) + var xdcs: List[String] = traverseXdc(this.asInstanceOf[Component]) + xdcs.zipWithIndex.map { case (x, i) => pw.println(x) } + pw.close() + bw.close() + fw.close() + } +} From 8b4d9c712a7f3b4ed492c7391df2c4437eba6e8c Mon Sep 17 00:00:00 2001 From: xueweiwujxw Date: Wed, 11 Jun 2025 17:23:51 +0800 Subject: [PATCH 02/11] =?UTF-8?q?feat:=20=E2=9C=A8(build.sbt)=20add=20mave?= =?UTF-8?q?n=20central=20needed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.sbt | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index be93f75..a87b7f7 100644 --- a/build.sbt +++ b/build.sbt @@ -1,14 +1,27 @@ ThisBuild / version := "0.1.4" ThisBuild / scalaVersion := "2.12.18" -ThisBuild / organization := "com.github.xueweiwujxw" +ThisBuild / organization := "io.github.xueweiwujxw" -val spinalVersion = "1.11.0" +val spinalVersion = "1.12.2" val spinalCore = "com.github.spinalhdl" %% "spinalhdl-core" % spinalVersion val spinalLib = "com.github.spinalhdl" %% "spinalhdl-lib" % spinalVersion val spinalIdslPlugin = compilerPlugin( "com.github.spinalhdl" %% "spinalhdl-idsl-plugin" % spinalVersion ) +description := "Utils collection based on SpinalHDL" +homepage := Some(url("https://github.com/xueweiwujxw/SpinalUtils")) +scmInfo := Some( + ScmInfo( + url("https://github.com/xueweiwujxw/SpinalUtils"), + "scm:git@github.com:xueweiwujxw/SpinalUtils.git" + ) +) +developers := List( + Developer(id = "xueweiwujxw", name = "Wlanxww", email = "xueweiwujxw@outlook.com", url = url("https://wlanxww.com")) +) +licenses := Seq("BSD 3-Clause" -> new URL("https://opensource.org/licenses/BSD-3-Clause")) + lazy val spinalUtils = (project in file(".")) .settings( name := "spinalUtils", From fc261d319abec10814ad98edc54ed1dccbeb73f5 Mon Sep 17 00:00:00 2001 From: xueweiwujxw Date: Thu, 12 Jun 2025 19:15:21 +0800 Subject: [PATCH 03/11] =?UTF-8?q?refactor:=20=F0=9F=A6=84(all)=20split=20t?= =?UTF-8?q?est=20code=20from=20src=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + build.sbt | 2 + .../libs/axispi/Axi4SpiMaster.scala | 172 ----------------- .../libs/axispi/SpiMasterCtrl.scala | 74 +------- .../spinalutils/libs/encoder/OneHot.scala | 38 ---- .../spinalutils/libs/expand/Bundle.scala | 19 -- src/main/scala/spinalutils/pn/PNDetect.scala | 8 - src/main/scala/spinalutils/pn/PNGen.scala | 87 --------- src/main/scala/spinalutils/pn/PNSim.scala | 38 ---- .../libs/axispi/Axi4SpiMaster.scala | 177 ++++++++++++++++++ .../libs/axispi/SpiMasterCtrl.scala | 77 ++++++++ .../spinalutils/libs/encoder/OneHot.scala | 42 +++++ src/test/scala/spinalutils/pn/PN.scala | 137 ++++++++++++++ 13 files changed, 437 insertions(+), 435 deletions(-) create mode 100644 src/test/scala/spinalutils/libs/axispi/Axi4SpiMaster.scala create mode 100644 src/test/scala/spinalutils/libs/axispi/SpiMasterCtrl.scala create mode 100644 src/test/scala/spinalutils/libs/encoder/OneHot.scala create mode 100644 src/test/scala/spinalutils/pn/PN.scala diff --git a/.gitignore b/.gitignore index 4d7ed08..10529af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ *.class *.log *.bak +*.txt # sbt specific .cache/ diff --git a/build.sbt b/build.sbt index a87b7f7..357fc83 100644 --- a/build.sbt +++ b/build.sbt @@ -2,6 +2,8 @@ ThisBuild / version := "0.1.4" ThisBuild / scalaVersion := "2.12.18" ThisBuild / organization := "io.github.xueweiwujxw" +publishMavenStyle := true + val spinalVersion = "1.12.2" val spinalCore = "com.github.spinalhdl" %% "spinalhdl-core" % spinalVersion val spinalLib = "com.github.spinalhdl" %% "spinalhdl-lib" % spinalVersion diff --git a/src/main/scala/spinalutils/libs/axispi/Axi4SpiMaster.scala b/src/main/scala/spinalutils/libs/axispi/Axi4SpiMaster.scala index 93d4c87..2e1e3ef 100644 --- a/src/main/scala/spinalutils/libs/axispi/Axi4SpiMaster.scala +++ b/src/main/scala/spinalutils/libs/axispi/Axi4SpiMaster.scala @@ -1,6 +1,5 @@ package spinalutils.libs.axispi - import spinal.core._ import spinal.lib._ import spinal.lib.bus.amba4.axi._ @@ -42,174 +41,3 @@ case class Axi4SpiMaster(config: Axi4SpiMasterConfig) extends Component { noIoPrefix() Axi4SpecRenamer(io.s_axi) } - -object Axi4SpiMasterGen extends App { - SpinalVerilog( - Axi4SpiMaster( - config = Axi4SpiMasterConfig( - axiConfig = Axi4Config( - addressWidth = 12, - dataWidth = 32, - useBurst = true, - idWidth = 4, - useRegion = false, - useProt = true, - useCache = true, - useLock = true, - useQos = false - ), - spiConfig = SpiMasterCtrlGenerics( - ssWidth = 8, - timerWidth = 4, - dataWidth = 8 - ) - ) - ) - ) -} - -import spinal.sim._ -import spinal.core.sim._ -import spinal.lib.bus.amba4.axi.sim._ - -object Axi4SpiMasterSim extends App { - SimConfig.withFstWave.doSim( - Axi4SpiMaster( - config = Axi4SpiMasterConfig( - axiConfig = Axi4Config( - addressWidth = 12, - dataWidth = 32, - useBurst = true, - idWidth = 4, - useRegion = false, - useProt = true, - useCache = true, - useLock = true, - useQos = false - ), - spiConfig = SpiMasterCtrlGenerics( - ssWidth = 8, - timerWidth = 4, - dataWidth = 8 - ) - ) - ) - ) { dut => - dut.io.m_spi.miso #= false - dut.io.s_axi.ar.valid #= false - dut.io.s_axi.aw.valid #= false - dut.io.s_axi.w.valid #= false - - dut.clockDomain.forkStimulus(20 MHz) - val axiMaster = Axi4Master(dut.io.s_axi, dut.clockDomain, "Axi4SpiMaster") - - var threadRunning = true - val ssAllTrue = (BigInt(1) << dut.config.spiConfig.ssWidth) - 1 - - def hasSS = dut.io.m_spi.ss.toBigInt != ssAllTrue - - val misoThread = fork { - while (threadRunning) { - dut.clockDomain.waitSamplingWhere(hasSS || !threadRunning) - var i = 0 - while (threadRunning && hasSS) { - dut.io.m_spi.miso #= i % 2 == 1 - if (hasSS) { - dut.clockDomain.waitRisingEdgeWhere(dut.io.m_spi.sclk.toBoolean || !hasSS) - if (hasSS) - i += 1 - } - } - } - } - - dut.clockDomain.waitSampling(10) - - println("disable cmd en") - axiMaster.write(0x1c, List(0x00.toByte, 0, 0, 0)) - - println("set cpha as 0 and cpol as 0") - axiMaster.write(8, List(0), burst = Axi4Bursts.Fixed) - println("set sclkToggle as 0") - axiMaster.write(0xc, List(0), burst = Axi4Bursts.Fixed) - println("set ssSetup as 0") - axiMaster.write(0x10, List(0), burst = Axi4Bursts.Fixed) - println("set ssHold as 0") - axiMaster.write(0x14, List(0), burst = Axi4Bursts.Fixed) - println("set ssDisable as 0") - axiMaster.write(0x18, List(4), burst = Axi4Bursts.Fixed) - println("enable cmd intr amd rsp intr") - axiMaster.write(0x4, List(0x03), burst = Axi4Bursts.Fixed) - - println("first spi transfer") - - println("enable chip 1") - axiMaster.write(0, List(0x01.toByte, 0, 0, 0x11.toByte)) - - println("write 0xa5 to spi") - axiMaster.write(0, List(0xa5.toByte, 0, 0, 0x00.toByte)) - - println("write 0x96 to spi and read from spi") - axiMaster.write(0, List(0x96.toByte, 0, 0, 0x01.toByte)) - - println("write 0x00 to spi and read from spi") - axiMaster.write(0, List(0x00.toByte, 0, 0, 0x01.toByte)) - - println("disable chip 0") - axiMaster.write(0, List(0x01.toByte, 0, 0, 0x10.toByte)) - - println("enable cmd en") - axiMaster.write(0x1c, List(0x01.toByte)) - dut.clockDomain.waitSamplingWhere(dut.io.m_spi.ss.toBigInt == 0xff) - println("disable cmd en") - axiMaster.write(0x1c, List(0x00.toByte)) - - println("read status") - axiMaster.read(4, 4) - - println("read data") - axiMaster.read(0, 1) - println("read data") - axiMaster.read(0, 1) - - dut.clockDomain.waitSampling(50) - - println("second spi transfer") - - println("enable chip 1") - axiMaster.write(0, List(0x01.toByte, 0, 0, 0x11.toByte)) - - println("write 0xa5 to spi") - axiMaster.write(0, List(0xa5.toByte, 0, 0, 0x00.toByte)) - - println("write 0x96 to spi and read from spi") - axiMaster.write(0, List(0x96.toByte, 0, 0, 0x01.toByte)) - - println("write 0x00 to spi and read from spi") - axiMaster.write(0, List(0x00.toByte, 0, 0, 0x01.toByte)) - - println("disable chip 0") - axiMaster.write(0, List(0x01.toByte, 0, 0, 0x10.toByte)) - - println("enable cmd en") - axiMaster.write(0x1c, List(0x01.toByte)) - dut.clockDomain.waitSamplingWhere(dut.io.m_spi.ss.toBigInt == 0xff) - println("disable cmd en") - axiMaster.write(0x1c, List(0x00.toByte)) - - println("read status") - axiMaster.read(4, 4) - - println("read data") - axiMaster.read(0, 1) - println("read data") - axiMaster.read(0, 1) - - axiMaster.read(0x20, 4) - - dut.clockDomain.waitSampling(50) - - threadRunning = false - misoThread.join() - } -} diff --git a/src/main/scala/spinalutils/libs/axispi/SpiMasterCtrl.scala b/src/main/scala/spinalutils/libs/axispi/SpiMasterCtrl.scala index 7ad5ad7..e3b69c8 100644 --- a/src/main/scala/spinalutils/libs/axispi/SpiMasterCtrl.scala +++ b/src/main/scala/spinalutils/libs/axispi/SpiMasterCtrl.scala @@ -204,76 +204,4 @@ case class SpiMasterCtrlContinuous(generics: SpiMasterCtrlGenerics, continuous: io.spi.mosi := RegNext(io.cmd.argsData.data(dataWidth - 1 - (counter >> 1))) } -} - -import spinal.sim._ -import spinal.core.sim._ - -object SpiMasterCtrlSim extends App { - SimConfig.withFstWave.doSim( - SpiMasterCtrlContinuous(SpiMasterCtrlGenerics(ssWidth = 8, timerWidth = 8, dataWidth = 8)) - ) { dut => - dut.clockDomain.forkStimulus(10 MHz) - - // init - dut.io.cmd.valid #= false - - dut.io.spi.miso #= true - - // config - dut.io.config.kind.cpha #= false - dut.io.config.kind.cpol #= false - dut.io.config.sclkToggle #= 1 - dut.io.config.ss.activeHigh #= 0 - dut.io.config.ss.setup #= 1 - dut.io.config.ss.hold #= 1 - dut.io.config.ss.disable #= 1 - - dut.clockDomain.waitSampling(10) - - // enable 0 args[4:1] index args[0] enable/disable - dut.io.cmd.mode #= SpiMasterCtrlCmdMode.SS - dut.io.cmd.args #= BigInt("0001", 2) - dut.io.cmd.valid #= true - dut.clockDomain.waitSampling() - while (!dut.io.cmd.ready.toBoolean) - dut.clockDomain.waitSampling() - - // spi send a5 args[8] r/w args[7:0] wdata - dut.io.cmd.mode #= SpiMasterCtrlCmdMode.DATA - dut.io.cmd.args #= BigInt("010100101", 2) - dut.io.cmd.valid #= true - dut.clockDomain.waitSampling() - while (!dut.io.cmd.ready.toBoolean) - dut.clockDomain.waitSampling() - - // spi send 66 and read args[8] r/w args[7:0] wdata - dut.io.cmd.mode #= SpiMasterCtrlCmdMode.DATA - dut.io.cmd.args #= BigInt("101100110", 2) - dut.io.cmd.valid #= true - dut.clockDomain.waitSampling() - while (!dut.io.cmd.ready.toBoolean) - dut.clockDomain.waitSampling() - - // spi read args[8] r/w args[7:0] wdata - dut.io.cmd.mode #= SpiMasterCtrlCmdMode.DATA - dut.io.cmd.args #= BigInt("100000000", 2) - dut.io.cmd.valid #= true - dut.clockDomain.waitSampling() - while (!dut.io.cmd.ready.toBoolean) - dut.clockDomain.waitSampling() - - // disable 0 args[4:1] index args[0] enable/disable - dut.io.cmd.mode #= SpiMasterCtrlCmdMode.SS - dut.io.cmd.args #= BigInt("0000", 2) - dut.io.cmd.valid #= true - dut.clockDomain.waitSampling() - while (!dut.io.cmd.ready.toBoolean) - dut.clockDomain.waitSampling() - - // finish - dut.io.cmd.valid #= false - - dut.clockDomain.waitSampling(10) - } -} +} \ No newline at end of file diff --git a/src/main/scala/spinalutils/libs/encoder/OneHot.scala b/src/main/scala/spinalutils/libs/encoder/OneHot.scala index e1ff67a..cbc3cd1 100644 --- a/src/main/scala/spinalutils/libs/encoder/OneHot.scala +++ b/src/main/scala/spinalutils/libs/encoder/OneHot.scala @@ -51,41 +51,3 @@ object OneHot { oh } } - -object OneHotExampleGen extends App { - case class Bin2OneHotExample() extends Component { - val io = new Bundle { - val bin = in(Bits(3 bits)) - val oh = out(Bits(8 bits)) - } - - io.oh := OneHot.bin2OneHot(io.bin) - } - - case class OneHot2BinExample() extends Component { - val io = new Bundle { - val oh = in(Bits(8 bits)) - val bin = out(Bits(3 bits)) - } - - io.bin := OneHot.oneHot2Bin(io.oh).asBits - } - - case class OneHot2BinSecureExample() extends Component { - val io = new Bundle { - val oh = in(Bits(8 bits)) - val bin = out(Bits(3 bits)) - val valid = out(Bool()) - } - - val binSecure = OneHot.oneHot2BinSecure(io.oh) - io.bin := binSecure._1.asBits - io.valid := binSecure._2 - } - - SpinalVerilog(Bin2OneHotExample()) - - SpinalVerilog(OneHot2BinExample()) - - SpinalVerilog(OneHot2BinSecureExample()) -} diff --git a/src/main/scala/spinalutils/libs/expand/Bundle.scala b/src/main/scala/spinalutils/libs/expand/Bundle.scala index 55df4f8..1e42121 100644 --- a/src/main/scala/spinalutils/libs/expand/Bundle.scala +++ b/src/main/scala/spinalutils/libs/expand/Bundle.scala @@ -38,22 +38,3 @@ trait IPadSingleDir[T <: IPadSingleDir[T]] extends Bundle with IMasterSlave with def busAlignedBytes(busDataWidth: Int): Int = scala.math.ceil(this.bits.toDouble / busDataWidth.toDouble).toInt * (busDataWidth / 8) } - -object IPadSingleDirDataTest extends App { - case class IPadSingleDirData(pad: Boolean = false) extends IPadSingleDir[IPadSingleDirData] { - val data = Bits(32 bits) - val __pad_0__ = pad generate B(0, 1 bits) - } - case class IPadSingleDirComponent() extends Component { - val io = new Bundle { - val input = slave(IPadSingleDirData()) - val output = master(IPadSingleDirData()) - } - - val reg = RegInit(IPadSingleDirData(true).getZero) - io.input >> reg - io.output << reg - } - - SpinalConfig().generateVerilog(IPadSingleDirComponent()) -} diff --git a/src/main/scala/spinalutils/pn/PNDetect.scala b/src/main/scala/spinalutils/pn/PNDetect.scala index 5bc9d93..5bd35aa 100644 --- a/src/main/scala/spinalutils/pn/PNDetect.scala +++ b/src/main/scala/spinalutils/pn/PNDetect.scala @@ -107,11 +107,3 @@ object PNDetect { def apply(order: Int, poly: BigInt, inWidth: Int): PNDetect = new PNDetect(order = order, poly = poly, inWidth = inWidth) } - -object PNDetectExample extends App { - SpinalConfig() - .generateVerilog( - PNDetect(order = 23, poly = 0x800021, inWidth = 8) - ) - .printPruned() -} diff --git a/src/main/scala/spinalutils/pn/PNGen.scala b/src/main/scala/spinalutils/pn/PNGen.scala index 4efd47d..63e41ff 100644 --- a/src/main/scala/spinalutils/pn/PNGen.scala +++ b/src/main/scala/spinalutils/pn/PNGen.scala @@ -4,13 +4,6 @@ import spinal.core._ import spinal.lib._ import spinal.lib.fsm._ -import spinal.core.sim._ -import spinal.sim._ -import java.nio.file.Paths -import java.io._ -import scala.util.Random -import scala.collection.mutable.ArrayBuffer - /** * Generates a PN (Pseudo-Noise) sequence using a given polynomial. * @@ -159,83 +152,3 @@ object PNGen { def apply(order: Int, init: BigInt, poly: BigInt, outWidth: Int): PNGen = new PNGen(order = order, init = init, poly = poly, outWidth = outWidth) } - -object PNGenExample extends App { - SpinalConfig().generateVerilog( - new PNGen( - order = 23, - init = 1, - poly = 0x800021, - outWidth = 32 - ) - ) -} - -object PNGenSim extends App { - SimConfig.withIVerilog.doSim( - new PNGen( - order = 23, - init = 1, - poly = 0x800021, - outWidth = 32 - ) - ) { dut => - val pnfile = new File("pntest23.dat") - val outputStream = new DataOutputStream(new FileOutputStream(pnfile)) - var correct = new Array[Byte](dut.io.m_stream.payload.getBitsWidth / 8) - val random = new Random - val threshold = 0.8 - dut.clockDomain.forkStimulus(10) - - dut.io.en #= false - dut.io.flush #= false - dut.io.m_stream.ready #= false - - dut.clockDomain.waitSampling(20) - - dut.io.en #= true - - val ready_for = fork { - for (i <- 0 until 5000000) { - dut.clockDomain.waitSampling() - val randomValue = random.nextDouble() - if (randomValue <= threshold) - dut.io.m_stream.ready #= true - else - dut.io.m_stream.ready #= false - } - } - - for (i <- 0 until 5000000) { - dut.clockDomain.waitSampling() - if (dut.io.m_stream.valid.toBoolean && dut.io.m_stream.ready.toBoolean) { - var bytes = dut.io.m_stream.payload.toBigInt.toByteArray - - if (bytes.size > correct.size) { - for (i <- 1 until correct.size + 1) - correct(i - 1) = bytes(i) - } else if (bytes.size == correct.size) { - for (i <- 0 until correct.size) - correct(i) = bytes(i) - } else { - for (i <- (correct.size - bytes.size) until correct.size) - correct(i) = bytes(i - (correct.size - bytes.size)) - for (i <- 0 until (correct.size - bytes.size)) - correct(i) = 0 - } - outputStream.write(correct) - } - } - - dut.io.flush #= true - - dut.clockDomain.waitSampling(20) - - dut.io.flush #= false - dut.io.en #= false - - dut.clockDomain.waitSampling(20) - ready_for.join() - outputStream.close() - } -} diff --git a/src/main/scala/spinalutils/pn/PNSim.scala b/src/main/scala/spinalutils/pn/PNSim.scala index 25c92c7..1140697 100644 --- a/src/main/scala/spinalutils/pn/PNSim.scala +++ b/src/main/scala/spinalutils/pn/PNSim.scala @@ -24,41 +24,3 @@ case class PNSimWrapper(order: Int, init: BigInt, poly: BigInt, width: Int) exte gen.io.m_stream >> detect.io.s_stream } - -object PNSim extends App { - SimConfig.withFstWave.doSim( - PNSimWrapper(order = 23, init = 1, poly = 0x800021, width = 256) - ) { dut => - dut.clockDomain.forkStimulus(10) - - dut.io.en #= false - dut.io.flush #= false - - var running = true - - val check_thread = fork { - while (running) { - dut.clockDomain.waitSampling() - assert(dut.io.errcnt.toBigInt == 0) - } - } - - dut.clockDomain.waitSampling(20) - - dut.io.en #= true - - dut.clockDomain.waitSampling(5000) - - dut.io.flush #= true - - dut.clockDomain.waitSampling(20) - - dut.io.flush #= false - dut.io.en #= false - - running = false - check_thread.join() - - dut.clockDomain.waitSampling(20) - } -} diff --git a/src/test/scala/spinalutils/libs/axispi/Axi4SpiMaster.scala b/src/test/scala/spinalutils/libs/axispi/Axi4SpiMaster.scala new file mode 100644 index 0000000..1ef6600 --- /dev/null +++ b/src/test/scala/spinalutils/libs/axispi/Axi4SpiMaster.scala @@ -0,0 +1,177 @@ +package spinalutils.libs.axispi + +import spinal.core._ +import spinal.lib._ +import spinal.lib.bus.amba4.axi._ +import spinal.lib.com.spi._ + +object Axi4SpiMasterGen extends App { + SpinalVerilog( + Axi4SpiMaster( + config = Axi4SpiMasterConfig( + axiConfig = Axi4Config( + addressWidth = 12, + dataWidth = 32, + useBurst = true, + idWidth = 4, + useRegion = false, + useProt = true, + useCache = true, + useLock = true, + useQos = false + ), + spiConfig = SpiMasterCtrlGenerics( + ssWidth = 8, + timerWidth = 4, + dataWidth = 8 + ) + ) + ) + ) +} + +import spinal.sim._ +import spinal.core.sim._ +import spinal.lib.bus.amba4.axi.sim._ + +object Axi4SpiMasterSim extends App { + SimConfig.withFstWave.doSim( + Axi4SpiMaster( + config = Axi4SpiMasterConfig( + axiConfig = Axi4Config( + addressWidth = 12, + dataWidth = 32, + useBurst = true, + idWidth = 4, + useRegion = false, + useProt = true, + useCache = true, + useLock = true, + useQos = false + ), + spiConfig = SpiMasterCtrlGenerics( + ssWidth = 8, + timerWidth = 4, + dataWidth = 8 + ) + ) + ) + ) { dut => + dut.io.m_spi.miso #= false + dut.io.s_axi.ar.valid #= false + dut.io.s_axi.aw.valid #= false + dut.io.s_axi.w.valid #= false + + dut.clockDomain.forkStimulus(20 MHz) + val axiMaster = Axi4Master(dut.io.s_axi, dut.clockDomain, "Axi4SpiMaster") + + var threadRunning = true + val ssAllTrue = (BigInt(1) << dut.config.spiConfig.ssWidth) - 1 + + def hasSS = dut.io.m_spi.ss.toBigInt != ssAllTrue + + val misoThread = fork { + while (threadRunning) { + dut.clockDomain.waitSamplingWhere(hasSS || !threadRunning) + var i = 0 + while (threadRunning && hasSS) { + dut.io.m_spi.miso #= i % 2 == 1 + if (hasSS) { + dut.clockDomain.waitRisingEdgeWhere(dut.io.m_spi.sclk.toBoolean || !hasSS) + if (hasSS) + i += 1 + } + } + } + } + + dut.clockDomain.waitSampling(10) + + println("disable cmd en") + axiMaster.write(0x1c, List(0x00.toByte, 0, 0, 0)) + + println("set cpha as 0 and cpol as 0") + axiMaster.write(8, List(0), burst = Axi4Bursts.Fixed) + println("set sclkToggle as 0") + axiMaster.write(0xc, List(0), burst = Axi4Bursts.Fixed) + println("set ssSetup as 0") + axiMaster.write(0x10, List(0), burst = Axi4Bursts.Fixed) + println("set ssHold as 0") + axiMaster.write(0x14, List(0), burst = Axi4Bursts.Fixed) + println("set ssDisable as 0") + axiMaster.write(0x18, List(4), burst = Axi4Bursts.Fixed) + println("enable cmd intr amd rsp intr") + axiMaster.write(0x4, List(0x03), burst = Axi4Bursts.Fixed) + + println("first spi transfer") + + println("enable chip 1") + axiMaster.write(0, List(0x01.toByte, 0, 0, 0x11.toByte)) + + println("write 0xa5 to spi") + axiMaster.write(0, List(0xa5.toByte, 0, 0, 0x00.toByte)) + + println("write 0x96 to spi and read from spi") + axiMaster.write(0, List(0x96.toByte, 0, 0, 0x01.toByte)) + + println("write 0x00 to spi and read from spi") + axiMaster.write(0, List(0x00.toByte, 0, 0, 0x01.toByte)) + + println("disable chip 0") + axiMaster.write(0, List(0x01.toByte, 0, 0, 0x10.toByte)) + + println("enable cmd en") + axiMaster.write(0x1c, List(0x01.toByte)) + dut.clockDomain.waitSamplingWhere(dut.io.m_spi.ss.toBigInt == 0xff) + println("disable cmd en") + axiMaster.write(0x1c, List(0x00.toByte)) + + println("read status") + axiMaster.read(4, 4) + + println("read data") + axiMaster.read(0, 1) + println("read data") + axiMaster.read(0, 1) + + dut.clockDomain.waitSampling(50) + + println("second spi transfer") + + println("enable chip 1") + axiMaster.write(0, List(0x01.toByte, 0, 0, 0x11.toByte)) + + println("write 0xa5 to spi") + axiMaster.write(0, List(0xa5.toByte, 0, 0, 0x00.toByte)) + + println("write 0x96 to spi and read from spi") + axiMaster.write(0, List(0x96.toByte, 0, 0, 0x01.toByte)) + + println("write 0x00 to spi and read from spi") + axiMaster.write(0, List(0x00.toByte, 0, 0, 0x01.toByte)) + + println("disable chip 0") + axiMaster.write(0, List(0x01.toByte, 0, 0, 0x10.toByte)) + + println("enable cmd en") + axiMaster.write(0x1c, List(0x01.toByte)) + dut.clockDomain.waitSamplingWhere(dut.io.m_spi.ss.toBigInt == 0xff) + println("disable cmd en") + axiMaster.write(0x1c, List(0x00.toByte)) + + println("read status") + axiMaster.read(4, 4) + + println("read data") + axiMaster.read(0, 1) + println("read data") + axiMaster.read(0, 1) + + axiMaster.read(0x20, 4) + + dut.clockDomain.waitSampling(50) + + threadRunning = false + misoThread.join() + } +} diff --git a/src/test/scala/spinalutils/libs/axispi/SpiMasterCtrl.scala b/src/test/scala/spinalutils/libs/axispi/SpiMasterCtrl.scala new file mode 100644 index 0000000..b398a63 --- /dev/null +++ b/src/test/scala/spinalutils/libs/axispi/SpiMasterCtrl.scala @@ -0,0 +1,77 @@ +package spinalutils.libs.axispi + +import spinal.core._ +import spinal.lib._ + +import spinal.sim._ +import spinal.core.sim._ +import spinal.lib.com.spi._ + +object SpiMasterCtrlSim extends App { + SimConfig.withFstWave.doSim( + SpiMasterCtrlContinuous(SpiMasterCtrlGenerics(ssWidth = 8, timerWidth = 8, dataWidth = 8)) + ) { dut => + dut.clockDomain.forkStimulus(10 MHz) + + // init + dut.io.cmd.valid #= false + + dut.io.spi.miso #= true + + // config + dut.io.config.kind.cpha #= false + dut.io.config.kind.cpol #= false + dut.io.config.sclkToggle #= 1 + dut.io.config.ss.activeHigh #= 0 + dut.io.config.ss.setup #= 1 + dut.io.config.ss.hold #= 1 + dut.io.config.ss.disable #= 1 + + dut.clockDomain.waitSampling(10) + + // enable 0 args[4:1] index args[0] enable/disable + dut.io.cmd.mode #= SpiMasterCtrlCmdMode.SS + dut.io.cmd.args #= BigInt("0001", 2) + dut.io.cmd.valid #= true + dut.clockDomain.waitSampling() + while (!dut.io.cmd.ready.toBoolean) + dut.clockDomain.waitSampling() + + // spi send a5 args[8] r/w args[7:0] wdata + dut.io.cmd.mode #= SpiMasterCtrlCmdMode.DATA + dut.io.cmd.args #= BigInt("010100101", 2) + dut.io.cmd.valid #= true + dut.clockDomain.waitSampling() + while (!dut.io.cmd.ready.toBoolean) + dut.clockDomain.waitSampling() + + // spi send 66 and read args[8] r/w args[7:0] wdata + dut.io.cmd.mode #= SpiMasterCtrlCmdMode.DATA + dut.io.cmd.args #= BigInt("101100110", 2) + dut.io.cmd.valid #= true + dut.clockDomain.waitSampling() + while (!dut.io.cmd.ready.toBoolean) + dut.clockDomain.waitSampling() + + // spi read args[8] r/w args[7:0] wdata + dut.io.cmd.mode #= SpiMasterCtrlCmdMode.DATA + dut.io.cmd.args #= BigInt("100000000", 2) + dut.io.cmd.valid #= true + dut.clockDomain.waitSampling() + while (!dut.io.cmd.ready.toBoolean) + dut.clockDomain.waitSampling() + + // disable 0 args[4:1] index args[0] enable/disable + dut.io.cmd.mode #= SpiMasterCtrlCmdMode.SS + dut.io.cmd.args #= BigInt("0000", 2) + dut.io.cmd.valid #= true + dut.clockDomain.waitSampling() + while (!dut.io.cmd.ready.toBoolean) + dut.clockDomain.waitSampling() + + // finish + dut.io.cmd.valid #= false + + dut.clockDomain.waitSampling(10) + } +} diff --git a/src/test/scala/spinalutils/libs/encoder/OneHot.scala b/src/test/scala/spinalutils/libs/encoder/OneHot.scala new file mode 100644 index 0000000..33534ac --- /dev/null +++ b/src/test/scala/spinalutils/libs/encoder/OneHot.scala @@ -0,0 +1,42 @@ +package spinalutils.libs.encoder + +import spinal.core._ +import spinal.lib._ + +object OneHotExampleGen extends App { + case class Bin2OneHotExample() extends Component { + val io = new Bundle { + val bin = in(Bits(3 bits)) + val oh = out(Bits(8 bits)) + } + + io.oh := OneHot.bin2OneHot(io.bin) + } + + case class OneHot2BinExample() extends Component { + val io = new Bundle { + val oh = in(Bits(8 bits)) + val bin = out(Bits(3 bits)) + } + + io.bin := OneHot.oneHot2Bin(io.oh).asBits + } + + case class OneHot2BinSecureExample() extends Component { + val io = new Bundle { + val oh = in(Bits(8 bits)) + val bin = out(Bits(3 bits)) + val valid = out(Bool()) + } + + val binSecure = OneHot.oneHot2BinSecure(io.oh) + io.bin := binSecure._1.asBits + io.valid := binSecure._2 + } + + SpinalVerilog(Bin2OneHotExample()) + + SpinalVerilog(OneHot2BinExample()) + + SpinalVerilog(OneHot2BinSecureExample()) +} diff --git a/src/test/scala/spinalutils/pn/PN.scala b/src/test/scala/spinalutils/pn/PN.scala new file mode 100644 index 0000000..5437ba4 --- /dev/null +++ b/src/test/scala/spinalutils/pn/PN.scala @@ -0,0 +1,137 @@ +package spinalutils.pn + +import spinal.core._ +import spinal.lib._ + +import spinal.core.sim._ +import spinal.sim._ +import java.nio.file.Paths +import java.io._ +import scala.util.Random +import scala.collection.mutable.ArrayBuffer + +object PNDetectExample extends App { + SpinalConfig() + .generateVerilog( + PNDetect(order = 23, poly = 0x800021, inWidth = 8) + ) + .printPruned() +} + +object PNGenExample extends App { + SpinalConfig().generateVerilog( + new PNGen( + order = 23, + init = 1, + poly = 0x800021, + outWidth = 32 + ) + ) +} + +object PNGenSim extends App { + SimConfig.withIVerilog.doSim( + new PNGen( + order = 23, + init = 1, + poly = 0x800021, + outWidth = 32 + ) + ) { dut => + val pnfile = new File("pntest23.dat") + val outputStream = new DataOutputStream(new FileOutputStream(pnfile)) + var correct = new Array[Byte](dut.io.m_stream.payload.getBitsWidth / 8) + val random = new Random + val threshold = 0.8 + dut.clockDomain.forkStimulus(10) + + dut.io.en #= false + dut.io.flush #= false + dut.io.m_stream.ready #= false + + dut.clockDomain.waitSampling(20) + + dut.io.en #= true + + val ready_for = fork { + for (i <- 0 until 5000000) { + dut.clockDomain.waitSampling() + val randomValue = random.nextDouble() + if (randomValue <= threshold) + dut.io.m_stream.ready #= true + else + dut.io.m_stream.ready #= false + } + } + + for (i <- 0 until 5000000) { + dut.clockDomain.waitSampling() + if (dut.io.m_stream.valid.toBoolean && dut.io.m_stream.ready.toBoolean) { + var bytes = dut.io.m_stream.payload.toBigInt.toByteArray + + if (bytes.size > correct.size) { + for (i <- 1 until correct.size + 1) + correct(i - 1) = bytes(i) + } else if (bytes.size == correct.size) { + for (i <- 0 until correct.size) + correct(i) = bytes(i) + } else { + for (i <- (correct.size - bytes.size) until correct.size) + correct(i) = bytes(i - (correct.size - bytes.size)) + for (i <- 0 until (correct.size - bytes.size)) + correct(i) = 0 + } + outputStream.write(correct) + } + } + + dut.io.flush #= true + + dut.clockDomain.waitSampling(20) + + dut.io.flush #= false + dut.io.en #= false + + dut.clockDomain.waitSampling(20) + ready_for.join() + outputStream.close() + } +} + +object PNSim extends App { + SimConfig.withFstWave.doSim( + PNSimWrapper(order = 23, init = 1, poly = 0x800021, width = 256) + ) { dut => + dut.clockDomain.forkStimulus(10) + + dut.io.en #= false + dut.io.flush #= false + + var running = true + + val check_thread = fork { + while (running) { + dut.clockDomain.waitSampling() + assert(dut.io.errcnt.toBigInt == 0) + } + } + + dut.clockDomain.waitSampling(20) + + dut.io.en #= true + + dut.clockDomain.waitSampling(5000) + + dut.io.flush #= true + + dut.clockDomain.waitSampling(20) + + dut.io.flush #= false + dut.io.en #= false + + running = false + check_thread.join() + + dut.clockDomain.waitSampling(20) + } +} From 4bf09b059dd3e9b5a170a43e3e30e74ce78473e6 Mon Sep 17 00:00:00 2001 From: xueweiwujxw Date: Thu, 12 Jun 2025 19:41:40 +0800 Subject: [PATCH 04/11] =?UTF-8?q?fix:=20=F0=9F=90=9E(pn)=20remove=20test?= =?UTF-8?q?=20code=20PNSim?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/scala/spinalutils/pn/PNSim.scala | 26 ----------------------- src/test/scala/spinalutils/pn/PN.scala | 19 +++++++++++++++++ 2 files changed, 19 insertions(+), 26 deletions(-) delete mode 100644 src/main/scala/spinalutils/pn/PNSim.scala diff --git a/src/main/scala/spinalutils/pn/PNSim.scala b/src/main/scala/spinalutils/pn/PNSim.scala deleted file mode 100644 index 1140697..0000000 --- a/src/main/scala/spinalutils/pn/PNSim.scala +++ /dev/null @@ -1,26 +0,0 @@ -package spinalutils.pn - -import spinal.core._ -import spinal.lib._ - -import spinal.core.sim._ -import spinal.sim._ - -case class PNSimWrapper(order: Int, init: BigInt, poly: BigInt, width: Int) extends Component { - val io = new Bundle { - val en = in(Bool()) - val flush = in(Bool()) - val errcnt = out(UInt(64 bits)) - } - - val gen = PNGen(order = order, init = init, poly = poly, outWidth = width) - val detect = PNDetect(order = order, poly = poly, inWidth = width) - - gen.io.en := io.en - gen.io.flush := io.flush - - detect.io.flush := io.flush - io.errcnt := detect.io.errcnt - - gen.io.m_stream >> detect.io.s_stream -} diff --git a/src/test/scala/spinalutils/pn/PN.scala b/src/test/scala/spinalutils/pn/PN.scala index 5437ba4..5ed02da 100644 --- a/src/test/scala/spinalutils/pn/PN.scala +++ b/src/test/scala/spinalutils/pn/PN.scala @@ -10,6 +10,25 @@ import java.io._ import scala.util.Random import scala.collection.mutable.ArrayBuffer +case class PNSimWrapper(order: Int, init: BigInt, poly: BigInt, width: Int) extends Component { + val io = new Bundle { + val en = in(Bool()) + val flush = in(Bool()) + val errcnt = out(UInt(64 bits)) + } + + val gen = PNGen(order = order, init = init, poly = poly, outWidth = width) + val detect = PNDetect(order = order, poly = poly, inWidth = width) + + gen.io.en := io.en + gen.io.flush := io.flush + + detect.io.flush := io.flush + io.errcnt := detect.io.errcnt + + gen.io.m_stream >> detect.io.s_stream +} + object PNDetectExample extends App { SpinalConfig() .generateVerilog( From 607bee5b7830af5f22f4b78cd495464e6ff9d453 Mon Sep 17 00:00:00 2001 From: xueweiwujxw Date: Thu, 12 Jun 2025 20:41:46 +0800 Subject: [PATCH 05/11] =?UTF-8?q?docs:=20=F0=9F=93=83(README)=20add=20mave?= =?UTF-8?q?n=20badge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index fbf4cbe..6c8211d 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ ## Utils Based on SpinalHDL + +SpinalUtils Maven + + This repository uses SpinalHDL to implement some FPGA algorithms, building scripts for some Xilinx IP cores and primitive descriptions which can be easily used througn `BlackBox`. ### Reference From 8e7a47d9d1bfbf8ef89380518c7b45a3c21554fe Mon Sep 17 00:00:00 2001 From: xueweiwujxw Date: Fri, 13 Jun 2025 11:00:24 +0800 Subject: [PATCH 06/11] =?UTF-8?q?docs:=20=F0=9F=93=83(README)=20upgrade=20?= =?UTF-8?q?badge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 6c8211d..1127c6b 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ ## Utils Based on SpinalHDL - -SpinalUtils Maven - +[![Maven Central Version](https://img.shields.io/maven-central/v/io.github.xueweiwujxw/spinalutils_2.12.svg?label=Maven%20Central&logo=scala)](https://central.sonatype.com/artifact/io.github.xueweiwujxw/spinalutils_2.12) This repository uses SpinalHDL to implement some FPGA algorithms, building scripts for some Xilinx IP cores and primitive descriptions which can be easily used througn `BlackBox`. From 0d90342617a694ebe47f83d0804c37cbe869ad1f Mon Sep 17 00:00:00 2001 From: xueweiwujxw Date: Sun, 15 Jun 2025 02:34:26 +0800 Subject: [PATCH 07/11] =?UTF-8?q?ci:=20=F0=9F=90=8E(workflow=20pr.yml)=20a?= =?UTF-8?q?dd=20pr=20check?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/pr.yml | 93 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 .github/workflows/pr.yml diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..a727666 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,93 @@ +name: Publish Maven Central + +on: + pull_request: + branches: ['main'] + +env: + SCALA_VERSION: '2.12' + PROJECT_NAME: 'spinalutils' + +jobs: + build-and-package: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout/@v4 + + - name: Setup Jave + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: '17' + + - name: Install sbt + run: | + # Install sbt + SBT_VERSION=1.9.7 + curl -fLO "https://github.com/sbt/sbt/releases/download/v$SBT_VERSION/sbt-$SBT_VERSION.tgz" + sudo tar -xzf "sbt-$SBT_VERSION.tgz" -C /usr/share + sudo ln -s /usr/share/sbt/bin/sbt /usr/bin/sbt + + # Verify Installation + sbt sbtVersion + + - name: Extract Project Version + id: get_version + run: | + # get project version + VERSION=$(awk -F'"' '/ThisBuild \/ version :=/ {print $2}' build.sbt) + if [ -z "$VERSION" ]; then + echo "::error::Failed to extract version from build.sbt" + echo "Looking for pattern: ThisBuild / version := \"...\"" + exit 1 + fi + + echo "Extracted version from build.sbt: $VERSION" + echo "version=$VERSION" >> $GITHUB_OUTPUT + + - name: Import GPG Key + id: import_gpg + env: + GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} + GPG_PASSPHRASE: ${{ secrets.GPG_PRIVATE_KEY_PASSWORD }} + run: | + echo "$GPG_PRIVATE_KEY" | gpg --batch --import + + echo "use-agent" >> ~/.gnupg/gpg.conf + echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf + echo "default-cache-ttl 86400" >> ~/.gnupg/gpg-agent.conf + echo "max-cache-ttl 604800" >> ~/.gnupg/gpg-agent.conf + gpgconf --kill gpg-agent + gpgconf --reload gpg-agent + + echo "$GPG_PASSPHRASE" | gpg --batch --pinentry-mode loopback --passphrase-fd 0 --sign ~/.gnupg/gpg-agent.conf + rm ~/.gnupg/gpg-agent.conf.gpg + + - name: Build project + run: | + + - name: Package and Sign artifacts + id: package_and_sign + env: + PROJECT_VERSION: ${{ steps.get_version.outputs.version }} + run: | + TARGET_DIR="target/scala-$SCALA_VERSION" + cd $TARGET_DIR + + for file in *.jar *.pom; do + echo "${{ secrets.GPG_PRIVATE_KEY_PASSWORD }}" | gpg --batch --pinentry-mode loopback --passphrase-fd 0 --detach-sign --armor "$file" + + md5sum "$file" | awk '{print $1}' > "${file}.md5" + sha1sum "$file" | awk '{print $1}' > "${file}.sha1" + sha256sum "$file" | awk '{print $1}' > "${file}.sha256" + done + + ZIP_NAME="${PROJECT_NAME}_${SCALA_VERSION}-${PROJECT_VERSION}-dist.zip" + ZIP_PREFIX="${PROJECT_NAME}_${SCALA_VERSION}-${PROJECT_VERSION}" + zip $ZIP_NAME $ZIP_PREFIX* + + cd ../../ + + echo "artifact_path=$TARGET_DIR/$ZIP_NAME" >> $GITHUB_OUTPUT + echo "publish_dir=$TARGET_DIR" >> $GITHUB_OUTPUT From e5a837d99fc1910da5712d7ca5ef7ee68df9f295 Mon Sep 17 00:00:00 2001 From: xueweiwujxw Date: Sun, 15 Jun 2025 02:39:30 +0800 Subject: [PATCH 08/11] =?UTF-8?q?fix:=20=F0=9F=90=9E(pr)=20add=20build=20c?= =?UTF-8?q?ommand?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/pr.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index a727666..188ce32 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -1,4 +1,4 @@ -name: Publish Maven Central +name: Pull Request Check on: pull_request: @@ -66,6 +66,7 @@ jobs: - name: Build project run: | + sbt clean compile package packageSrc packageDoc makePom - name: Package and Sign artifacts id: package_and_sign From b78085b7ffb8cb3994daeeb914c7ddc45c4e0787 Mon Sep 17 00:00:00 2001 From: xueweiwujxw Date: Sun, 15 Jun 2025 03:01:21 +0800 Subject: [PATCH 09/11] =?UTF-8?q?fix:=20=F0=9F=90=9E(pr.yml)=20fix=20zip?= =?UTF-8?q?=20path?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/pr.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 188ce32..a561e31 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -81,12 +81,14 @@ jobs: md5sum "$file" | awk '{print $1}' > "${file}.md5" sha1sum "$file" | awk '{print $1}' > "${file}.sha1" - sha256sum "$file" | awk '{print $1}' > "${file}.sha256" done ZIP_NAME="${PROJECT_NAME}_${SCALA_VERSION}-${PROJECT_VERSION}-dist.zip" ZIP_PREFIX="${PROJECT_NAME}_${SCALA_VERSION}-${PROJECT_VERSION}" - zip $ZIP_NAME $ZIP_PREFIX* + TAR_PATH="io/github/xueweiwujxw/${PROJECT_NAME}_${SCALA_VERSION}/${PROJECT_VERSION}" + mkdir -p $TAR_PATH + cp $ZIP_PREFIX* $TAR_PATH + zip -r $ZIP_NAME $TAR_PATH cd ../../ From 36f54b73267d6b5baec0e3559b330bdc0b4f5710 Mon Sep 17 00:00:00 2001 From: xueweiwujxw Date: Sun, 15 Jun 2025 03:04:07 +0800 Subject: [PATCH 10/11] =?UTF-8?q?fix:=20=F0=9F=90=9E(pr.yml)=20fix=20jobs?= =?UTF-8?q?=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index a561e31..a11dfb8 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -15,7 +15,7 @@ jobs: - name: Checkout repository uses: actions/checkout/@v4 - - name: Setup Jave + - name: Setup Java uses: actions/setup-java@v3 with: distribution: 'temurin' From 9de376cd20ac986b5e4ba65c1b3066b03a6f408f Mon Sep 17 00:00:00 2001 From: xueweiwujxw Date: Sun, 15 Jun 2025 11:28:09 +0800 Subject: [PATCH 11/11] =?UTF-8?q?feat:=20=E2=9C=A8(pr.yml)=20upload=20arti?= =?UTF-8?q?facts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/pr.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index a11dfb8..091e84c 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -94,3 +94,11 @@ jobs: echo "artifact_path=$TARGET_DIR/$ZIP_NAME" >> $GITHUB_OUTPUT echo "publish_dir=$TARGET_DIR" >> $GITHUB_OUTPUT + + - name: Upload Artifacts + uses: actions/upload-artifact@v4 + with: + name: release-bundle + path: | + target/scala-${{ env.SCALA_VERSION }}/${{ env.PROJECT_NAME }}_${{ env.SCALA_VERSION }}-${{ steps.get_version.outputs.version }}-dist.zip + retention-days: 1