> configure(npc)
ysyx_22040000 李心杨 Linux calcite 6.6.19 #1-NixOS SMP PREEMPT_DYNAMIC Fri Mar 1 12:35:11 UTC 2024 x86_64 GNU/Linux 21:14:33 up 3 days 12:05, 2 users, load average: 4.43, 2.70, 1.61
This commit is contained in:
parent
810a743e9e
commit
7d581b47eb
7 changed files with 126 additions and 111 deletions
12
flake.lock
12
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": {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
@ -27,8 +28,7 @@ class PcControl(width: Int) extends Bundle {
|
|||
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._
|
||||
|
@ -47,40 +47,66 @@ class Control(width: Int) extends Module {
|
|||
val ControlMapping: Array[(BitPat, T)] = Array(
|
||||
// Regs :: PC :: Exe
|
||||
// writeEnable :: writeSelect :: srcSelect ::
|
||||
(addi, false.B :: rAluOut :: pStaticNpc :: aOpAdd :: HNil)
|
||||
(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._
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
},
|
||||
|
|
|
@ -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
|
||||
|
|
10
npc/resource/addi.txt
Normal file
10
npc/resource/addi.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
00084113
|
||||
00084113
|
||||
00084113
|
||||
00084113
|
||||
00084113
|
||||
00084113
|
||||
00084113
|
||||
00084113
|
||||
00084113
|
||||
00084113
|
Loading…
Reference in a new issue