> 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:
tracer-ysyx 2024-03-12 21:14:33 +08:00 committed by xinyangli
parent 810a743e9e
commit 7d581b47eb
7 changed files with 126 additions and 111 deletions

View file

@ -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": {

View file

@ -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),
)
)

View file

@ -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._

View file

@ -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)
}
}
}

View file

@ -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"
},

View file

@ -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
View file

@ -0,0 +1,10 @@
00084113
00084113
00084113
00084113
00084113
00084113
00084113
00084113
00084113
00084113