From 7d581b47eb24f2b811aa88c35e9a1b1618d86aa5 Mon Sep 17 00:00:00 2001 From: tracer-ysyx Date: Tue, 12 Mar 2024 21:14:33 +0800 Subject: [PATCH] =?UTF-8?q?>=20configure(npc)=20=20ysyx=5F22040000=20?= =?UTF-8?q?=E6=9D=8E=E5=BF=83=E6=9D=A8=20=20Linux=20calcite=206.6.19=20#1-?= =?UTF-8?q?NixOS=20SMP=20PREEMPT=5FDYNAMIC=20Fri=20Mar=20=201=2012:35:11?= =?UTF-8?q?=20UTC=202024=20x86=5F64=20GNU/Linux=20=20=2021:14:33=20=20up?= =?UTF-8?q?=203=20days=2012:05,=20=202=20users,=20=20load=20average:=204.4?= =?UTF-8?q?3,=202.70,=201.61?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- flake.lock | 12 ++-- npc/core/build.sbt | 6 +- npc/core/src/main/scala/Main.scala | 80 ++++++++++++++-------- npc/core/src/test/scala/Main.scala | 104 ++++++++++++----------------- npc/flake.lock | 20 +++--- npc/flake.nix | 5 +- npc/resource/addi.txt | 10 +++ 7 files changed, 126 insertions(+), 111 deletions(-) create mode 100644 npc/resource/addi.txt diff --git a/flake.lock b/flake.lock index 36b9a39..b609f2e 100644 --- a/flake.lock +++ b/flake.lock @@ -5,11 +5,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1709126324, - "narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=", + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "d465f4819400de7c8d874d50b982301f28a84605", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "type": "github" }, "original": { @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1709237383, - "narHash": "sha256-cy6ArO4k5qTx+l5o+0mL9f5fa86tYUX3ozE1S+Txlds=", + "lastModified": 1709961763, + "narHash": "sha256-6H95HGJHhEZtyYA3rIQpvamMKAGoa8Yh2rFV29QnuGw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "1536926ef5621b09bba54035ae2bb6d806d72ac8", + "rev": "3030f185ba6a4bf4f18b87f345f104e6a6961f34", "type": "github" }, "original": { diff --git a/npc/core/build.sbt b/npc/core/build.sbt index 16f31f3..e04b603 100644 --- a/npc/core/build.sbt +++ b/npc/core/build.sbt @@ -2,14 +2,14 @@ ThisBuild / scalaVersion := "2.13.12" ThisBuild / version := "0.1.0" -val chiselVersion = "5.1.0" +val chiselVersion = "6.2.0" lazy val root = (project in file(".")) .settings( name := "flow", libraryDependencies ++= Seq( "org.chipsalliance" %% "chisel" % chiselVersion, - "edu.berkeley.cs" %% "chiseltest" % "5.0.2" % "test", + "edu.berkeley.cs" %% "chiseltest" % "6.0.0" % "test", "com.chuusai" %% "shapeless" % "2.3.3" ), scalacOptions ++= Seq( @@ -20,4 +20,4 @@ lazy val root = (project in file(".")) "-Ymacro-annotations", ), addCompilerPlugin("org.chipsalliance" % "chisel-plugin" % chiselVersion cross CrossVersion.full), - ) \ No newline at end of file + ) diff --git a/npc/core/src/main/scala/Main.scala b/npc/core/src/main/scala/Main.scala index 0a21ab7..a9eb10e 100644 --- a/npc/core/src/main/scala/Main.scala +++ b/npc/core/src/main/scala/Main.scala @@ -4,15 +4,16 @@ import scala.reflect.runtime.universe._ import chisel3._ import chisel3.util.{MuxLookup, Fill, Decoupled, Counter, Queue, Reverse} import chisel3.util.{SRAM} -import chisel3.util.experimental.decode.{decoder, TruthTable, QMCMinimizer} +import chisel3.util.experimental.decode.{decoder, TruthTable} import chisel3.stage.ChiselOption import chisel3.util.log2Ceil import chisel3.util.BitPat import chisel3.util.Enum import chisel3.experimental.prefix -import shapeless.{ HNil, :: } +import shapeless.{HNil, ::} import shapeless.HList import shapeless.ops.coproduct.Prepend +import chisel3.util.{ BinaryMemoryFile, HexMemoryFile } object RV32Inst { private val bp = BitPat @@ -22,13 +23,12 @@ object RV32Inst { class PcControl(width: Int) extends Bundle { object SrcSelect extends ChiselEnum { - val pPC, pExeResult = Value + val pPC, pExeResult = Value } val srcSelect = Output(SrcSelect()) } - -import flow.components.{ RegControl, PcControlInterface, ALUControlInterface } +import flow.components.{RegControl, PcControlInterface, ALUControlInterface} class Control(width: Int) extends Module { val inst = IO(Input(UInt(width.W))) @@ -36,9 +36,9 @@ class Control(width: Int) extends Module { val pc = IO(Flipped(new PcControlInterface)) val alu = IO(Flipped(new ALUControlInterface)) - // TODO: Add .ctrlTypes together instead of writing them by hand. - type T = Bool :: reg.WriteSelect.Type :: pc.SrcSelect.Type :: alu.OpSelect.Type :: HNil + type T = + Bool :: reg.WriteSelect.Type :: pc.SrcSelect.Type :: alu.OpSelect.Type :: HNil val dst: T = reg.ctrlBindPorts ++ pc.ctrlBindPorts ++ alu.ctrlBindPorts import reg.WriteSelect._ import pc.SrcSelect._ @@ -46,41 +46,67 @@ class Control(width: Int) extends Module { import RV32Inst._ val ControlMapping: Array[(BitPat, T)] = Array( // Regs :: PC :: Exe - // writeEnable :: writeSelect :: srcSelect :: - (addi, false.B :: rAluOut :: pStaticNpc :: aOpAdd :: HNil) + // writeEnable :: writeSelect :: srcSelect :: + (addi, false.B :: rAluOut :: pStaticNpc :: aOpAdd :: HNil), + // ("", false.B :: rAluOut :: pStaticNpc :: aOpNop :: HNil), ) def toBits(t: T): BitPat = { val list: List[Data] = t.toList list.map(x => BitPat(x.litValue.toInt.U(x.getWidth.W))).reduce(_ ## _) } - val default = toBits(false.B :: rAluOut :: pStaticNpc :: aOpSlt:: HNil) + // val default = toBits(false.B :: rAluOut :: pStaticNpc :: aOpAdd :: HNil).getWidth + val default = BitPat("b???????") - val out = decoder(QMCMinimizer, inst, TruthTable( - ControlMapping.map(it => (it._1, toBits(it._2))), default)) + reg.writeEnable := false.B + reg.writeSelect := reg.WriteSelect(0.U) + alu.op := alu.OpSelect(0.U) + pc.srcSelect := pc.SrcSelect(0.U) - val dstList = dst.toList - val reversePrefixSum = dstList.scanLeft(0)(_ + _.getWidth).reverse - val slices = reversePrefixSum.zip(reversePrefixSum.tail) - val srcList = slices.map(s => out(s._1 - 1, s._2)) + // val out = decoder( + // inst, + // TruthTable(ControlMapping.map(it => (it._1 -> toBits(it._2))), default)) + val table = TruthTable( + (0 until 16).map { i => + BitPat(i.U(4.W)) -> BitPat((1 << i).U(16.W)) + }, + BitPat.dontCare(16) + ) - srcList.zip(dstList).foreach({ - case (src, dst) => dst := src.asTypeOf(dst) - }) + val out = decoder.qmc(inst(3,0), table) + + // val dstList = dst.toList + // val reversePrefixSum = dstList.scanLeft(0)(_ + _.getWidth).reverse + // val slices = reversePrefixSum.zip(reversePrefixSum.tail) + // val srcList = slices.map(s => out(s._1 - 1, s._2)) + + // srcList + // .zip(dstList) + // .foreach({ case (src, dst) => + // dst := src.asTypeOf(dst) + // }) } -import flow.components.{ RegisterFile, RegFileInterface, ProgramCounter, ALU } -class Flow extends Module { - val dataType = UInt(32.W) +import flow.components.{RegisterFile, RegFileInterface, ProgramCounter, ALU} +import chisel3.util.experimental.loadMemoryFromFileInline +class Flow(memoryFile: String) extends Module { + // val dataType = UInt(32.W) - val ram = SRAM(size=128*1024*1024, tpe=dataType, numReadPorts=2, numWritePorts=1,numReadwritePorts=0) + val ram = SRAM( + size = 128 * 1024 * 1024, + tpe = UInt(32.W), + numReadPorts = 2, + numWritePorts = 1, + numReadwritePorts = 0, + memoryFile = HexMemoryFile(memoryFile) + ) val control = Module(new Control(32)) - val reg = RegisterFile(32, dataType, 2, 2) - val pc = Module(new ProgramCounter(dataType)) - val alu = Module(new ALU(dataType)) + val reg = RegisterFile(32, UInt(32.W), 2, 2) + val pc = Module(new ProgramCounter(UInt(32.W))) + val alu = Module(new ALU(UInt(32.W))) ram.readPorts(0).enable := true.B - ram.readPorts(0).address := pc.out + ram.readPorts(0).address := pc.out - 0x80000000L.U val inst = ram.readPorts(0).data import control.pc.SrcSelect._ diff --git a/npc/core/src/test/scala/Main.scala b/npc/core/src/test/scala/Main.scala index e2f7fee..6a04681 100644 --- a/npc/core/src/test/scala/Main.scala +++ b/npc/core/src/test/scala/Main.scala @@ -1,70 +1,48 @@ -package npc +package flow import chisel3._ import chiseltest._ import org.scalatest.freespec.AnyFreeSpec import chiseltest.simulator.WriteVcdAnnotation -import npc.util._ +import flow.Flow -// class ALUGeneratorSpec extends AnyFreeSpec with ChiselScalatestTester { -// "With 32 width, " - { -// val neg = (x: BigInt) => BigInt("FFFFFFFF", 16) - x + 1 -// val not = (x: BigInt) => x ^ BigInt("FFFFFFFF", 16) -// val mask = BigInt("FFFFFFFF", 16) -// val oprands: List[(BigInt, BigInt)] = List( -// (5, 3), (101010, 101010), (0xFFFFFFFCL, 0xFFFFFFFFL), (4264115, 2) -// ) -// val operations: Map[Int, (BigInt, BigInt) => BigInt] = Map( -// 0 -> ((a: BigInt, b: BigInt) => (a + b) & mask), -// 1 -> ((a: BigInt, b: BigInt) => (a + neg(b)) & mask), -// 2 -> ((a, _) => not(a)), -// 3 -> (_ & _), -// 4 -> (_ | _), -// 5 -> (_ ^ _), -// 6 -> ((a, b) => if (a < b) 1 else 0), -// 7 -> ((a, b) => if (a == b) 1 else 0), -// ) -// val validate = (c: ALUGenerator[32], op: Int, oprands: List[(BigInt, BigInt)]) => { -// c.io.op.poke(op.U) -// oprands.foreach({ case (a, b) => -// c.io.a.poke(a.U) -// c.io.b.poke(b.U) -// c.io.out.expect(operations(op)(a, b)) -// }) -// } -// "add should work" in { -// test(new ALUGenerator(32)) { c => validate(c, 0, oprands) } -// } -// "sub should work" - { -// "with positive result" in { -// test(new ALUGenerator(32)) { c => -// validate(c, 1, oprands.filter({case (a, b) => a >= b})) -// } -// } -// "with negative result" in { -// test(new ALUGenerator(32)) { c => -// validate(c, 1, oprands.filter({case (a, b) => a < b})) -// } -// } -// } -// "not should work" in { -// test(new ALUGenerator(32)) { c => validate(c, 2, oprands) } -// } -// "and should work" in { -// test(new ALUGenerator(32)) { c => validate(c, 3, oprands) } -// } -// "or should work" in { -// test(new ALUGenerator(32)) { c => validate(c, 4, oprands) } -// } -// "xor should work" in { -// test(new ALUGenerator(32)) { c => validate(c, 5, oprands) } -// } -// "compare should work" in { -// test(new ALUGenerator(32)) { c => validate(c, 6, oprands) } -// } -// "equal should work" in { -// test(new ALUGenerator(32)) { c => validate(c, 7, oprands) } -// } -// } -// } +class RV32CPUSpec extends AnyFreeSpec with ChiselScalatestTester { + "MemoryFile" - { + "correctly load" in { + import chisel3.util.{SRAM, SRAMInterface, HexMemoryFile} + class UserMem extends Module { + val io = IO(new SRAMInterface(1024, UInt(32.W), 1, 1, 0)) + val memoryFile = HexMemoryFile("../resource/addi.txt") + io :<>= SRAM( + size = 1024, + tpe = UInt(32.W), + numReadPorts = 1, + numWritePorts = 1, + numReadwritePorts = 0, + memoryFile = memoryFile + ) + + val read = io.readPorts(0).data + printf(cf"memoryFile=$memoryFile, readPort=$read%x\n") + } + test(new UserMem).withAnnotations(Seq(WriteVcdAnnotation)) { c => + c.io.readPorts(0).enable.poke(true.B) + c.io.writePorts(0).enable.poke(false.B) + c.io.writePorts(0).address.poke(0.U) + c.io.writePorts(0).data.poke(0.U) + for (i <- 0 until 32) { + c.io.readPorts(0).address.poke(i.U) + c.clock.step(1) + } + } + } + } + "should compile" in { + test(new Flow("../resource/addi.txt")) { c => + c.clock.step(1) + // c.clock.step(100) + } + } + +} diff --git a/npc/flake.lock b/npc/flake.lock index 8763898..f32f7c0 100644 --- a/npc/flake.lock +++ b/npc/flake.lock @@ -5,11 +5,11 @@ "systems": "systems" }, "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "lastModified": 1710146030, + "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", "owner": "numtide", "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", "type": "github" }, "original": { @@ -20,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1704194953, - "narHash": "sha256-RtDKd8Mynhe5CFnVT8s0/0yqtWFMM9LmCzXv/YKxnq4=", + "lastModified": 1709961763, + "narHash": "sha256-6H95HGJHhEZtyYA3rIQpvamMKAGoa8Yh2rFV29QnuGw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "bd645e8668ec6612439a9ee7e71f7eac4099d4f6", + "rev": "3030f185ba6a4bf4f18b87f345f104e6a6961f34", "type": "github" }, "original": { @@ -41,11 +41,11 @@ ] }, "locked": { - "lastModified": 1704450168, - "narHash": "sha256-zOLL35LX83Of64quCyxpyP8rTSO/tgrfHNm52tFo6VU=", + "lastModified": 1707020873, + "narHash": "sha256-+dNltc7tjgTIyle/I/5siQ5IvPwu+R5Uf6e24CmjLNk=", "ref": "refs/heads/master", - "rev": "beda2a57d946f392d958755c7bb03ac092a20f42", - "revCount": 140, + "rev": "8142717e7154dbaadee0679f0224fe75cebb1735", + "revCount": 147, "type": "git", "url": "https://git.xinyang.life/xin/nur.git" }, diff --git a/npc/flake.nix b/npc/flake.nix index e62173c..b101382 100644 --- a/npc/flake.nix +++ b/npc/flake.nix @@ -11,15 +11,16 @@ outputs = { self, ... }@inputs: with inputs; flake-utils.lib.eachDefaultSystem (system: let - pkgs = nixpkgs.legacyPackages.${system} // + pkgs = import nixpkgs { inherit system; config.allowUnfree = true; }// { nur.xin = nur-xin.legacyPackages.${system}; }; in { devShells.default = with pkgs; mkShell { packages = [ clang-tools - rnix-lsp + # rnix-lsp coursier + espresso gdb jre diff --git a/npc/resource/addi.txt b/npc/resource/addi.txt new file mode 100644 index 0000000..55960bf --- /dev/null +++ b/npc/resource/addi.txt @@ -0,0 +1,10 @@ +00084113 +00084113 +00084113 +00084113 +00084113 +00084113 +00084113 +00084113 +00084113 +00084113