From 8fc1f3838b6904a1055605f13bf2e39f50b7b5b5 Mon Sep 17 00:00:00 2001 From: tracer-ysyx Date: Mon, 11 Mar 2024 23:25:23 +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=2023:25:23=20=20up?= =?UTF-8?q?=202=20days=2014:15,=20=202=20users,=20=20load=20average:=200.5?= =?UTF-8?q?5,=200.82,=200.95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- npc/CMakeLists.txt | 2 +- npc/constr/Flow.nxdc | 5 ++ npc/core/src/main/scala/ALU.scala | 71 +++++++++++++------- npc/core/src/main/scala/Main.scala | 53 +++++---------- npc/core/src/main/scala/ProgramCounter.scala | 34 ++++++++-- npc/core/src/main/scala/RegisterFile.scala | 16 +++-- npc/core/src/test/scala/RegisterFile.scala | 29 ++++---- npc/csrc/Flow/main.cpp | 12 ++++ npc/csrc_nvboard/Flow/main.cpp | 23 +++++++ 9 files changed, 155 insertions(+), 90 deletions(-) create mode 100644 npc/constr/Flow.nxdc create mode 100644 npc/csrc/Flow/main.cpp create mode 100644 npc/csrc_nvboard/Flow/main.cpp diff --git a/npc/CMakeLists.txt b/npc/CMakeLists.txt index ef78ddd..4ecb1cf 100644 --- a/npc/CMakeLists.txt +++ b/npc/CMakeLists.txt @@ -17,7 +17,7 @@ find_package(verilator REQUIRED) find_library(NVBOARD_LIBRARY NAMES nvboard) find_path(NVBOARD_INCLUDE_DIR NAMES nvboard.h) -set(TOPMODULES "Switch" "Keyboard") +set(TOPMODULES "Flow") foreach(TOPMODULE IN LISTS TOPMODULES) diff --git a/npc/constr/Flow.nxdc b/npc/constr/Flow.nxdc new file mode 100644 index 0000000..7a55bc1 --- /dev/null +++ b/npc/constr/Flow.nxdc @@ -0,0 +1,5 @@ +top=Flow + +io_sw_0 (SW0) +io_sw_1 (SW1) +io_out (LD0) diff --git a/npc/core/src/main/scala/ALU.scala b/npc/core/src/main/scala/ALU.scala index 70705d7..a16e64c 100644 --- a/npc/core/src/main/scala/ALU.scala +++ b/npc/core/src/main/scala/ALU.scala @@ -1,38 +1,57 @@ -package npc.util +package flow.components import chisel3._ import chisel3.util._ +import shapeless.{HNil, ::} -object ALUSel extends ChiselEnum { - val add, sub, not, and, or, xor, slt, eq, nop = Value +class ALUControlInterface extends Bundle { + object OpSelect extends ChiselEnum { + val aOpAdd, aOpSub, aOpNot, aOpAnd, aOpOr, aOpXor, aOpSlt, aOpEq, aOpNop = Value + } + val op = Input(OpSelect()) } -class ALUGenerator[T <: ChiselEnum](width: Int, tpe: T = ALUSel) extends Module { - val io = IO(new Bundle { - val a = Input(UInt(tpe.getWidth.W)) - val b = Input(UInt(tpe.getWidth.W)) - val op = Input(ALUSel()) - val out = Output(UInt(tpe.getWidth.W)) +class ALU[T <: UInt](tpe: T) extends Module { + val control = new ALUControlInterface + val in = IO(new Bundle { + val a = Input(tpe) + val b = Input(tpe) + }) + val out = IO(new Bundle { + val result = Output(tpe) }) // val adder_b = (Fill(tpe.getWidth, io.op(0)) ^ io.b) + io.op(0) // take (-b) if sub - val add = io.a + io.b - val sub = io.a - io.b - val and = io.a & io.b - val not = ~io.a - val or = io.a | io.b - val xor = io.a ^ io.b - val slt = io.a < io.b - val eq = io.a === io.b + val add = in.a + in.b + val sub = in.a - in.b + val and = in.a & in.b + val not = ~in.a + val or = in.a | in.b + val xor = in.a ^ in.b + val slt = in.a < in.b + val eq = in.a === in.b - io.out := MuxLookup(io.op, ALUSel.nop.asUInt)(Seq( - ALUSel.add -> add, - ALUSel.sub -> sub, - ALUSel.not -> not, - ALUSel.and -> and, - ALUSel.or -> or, - ALUSel.xor -> xor, - ALUSel.slt -> slt, - ALUSel.eq -> eq + import control.OpSelect._ + + out.result := MuxLookup(control.op, aOpNop.asUInt)(Seq( + aOpAdd -> add, + aOpSub -> sub, + aOpNot -> not, + aOpAnd -> and, + aOpOr -> or, + aOpXor -> xor, + aOpSlt -> slt, + aOpEq -> eq )) + + type ctrlTypes = control.OpSelect.Type :: HNil + def ctrlBindPorts: ctrlTypes = { + control.op :: HNil + } +} + +object ALU { + def apply[T <: UInt](tpe: T): ALU[T] = { + new ALU(tpe) + } } diff --git a/npc/core/src/main/scala/Main.scala b/npc/core/src/main/scala/Main.scala index 73fa959..685f801 100644 --- a/npc/core/src/main/scala/Main.scala +++ b/npc/core/src/main/scala/Main.scala @@ -1,4 +1,4 @@ -package npc +package flow import scala.reflect.runtime.universe._ import chisel3._ @@ -6,39 +6,13 @@ import chisel3.util.{MuxLookup, Fill, Decoupled, Counter, Queue, Reverse} import chisel3.util.{SRAM} import chisel3.util.experimental.decode.{decoder, TruthTable, QMCMinimizer} import chisel3.stage.ChiselOption -import npc.util.{ KeyboardSegController } -import flowpc.components.RegisterFile import chisel3.util.log2Ceil import chisel3.util.BitPat import chisel3.util.Enum import chisel3.experimental.prefix import shapeless.{ HNil, :: } - -class Switch extends Module { - val io = IO(new Bundle { - val sw = Input(Vec(2, Bool())) - val out = Output(Bool()) - }) - - io.out := io.sw(0) ^ io.sw(1) -} - -import npc.util.{PS2Port, KeyboardController, SegControllerGenerator} - -class Keyboard extends Module { - val io = IO(new Bundle { - val ps2 = PS2Port() - val segs = Output(Vec(8, UInt(8.W))) - }) - - val seg_handler = Module(new KeyboardSegController) - val keyboard_controller = Module(new KeyboardController) - - seg_handler.io.keycode <> keyboard_controller.io.out - - keyboard_controller.io.ps2 := io.ps2 - io.segs := seg_handler.io.segs -} +import shapeless.HList +import shapeless.ops.coproduct.Prepend object RV32Inst { private val bp = BitPat @@ -54,25 +28,28 @@ class PcControl(width: Int) extends Bundle { } -import flowpc.components.{ RegisterFile } +import flow.components.{ RegisterFile, ProgramCounter, ALU } class Control(width: Int) extends Module { - val reg = Flipped(RegisterFile(32, UInt(32.W), 2, 2)) - val pc = new PcControl(width) - val inst = IO(Input(UInt(width.W))) + val inst = Input(UInt(width.W)) + val reg = Flipped(RegisterFile(32, UInt(width.W), 2, 2)) + val pc = ProgramCounter(UInt(width.W)) + val alu = ALU(UInt(width.W)) - type T = Bool :: reg.control.WriteSelect.Type :: HNil - val dst: T = reg.control.writeEnable :: reg.control.writeSelect :: HNil + // TODO: Add .ctrlTypes together instead of write them by hand. + type T = Bool :: reg.control.WriteSelect.Type :: pc.SrcSelect.Type :: alu.control.OpSelect.Type :: HNil + val dst: T = reg.ctrlBindPorts ++ pc.ctrlBindPorts ++ alu.ctrlBindPorts val dstList: List[Data] = dst.toList val reversePrefixSum = dstList.scanLeft(0)(_ + _.getWidth).reverse val slices = reversePrefixSum.zip(reversePrefixSum.tail) import reg.control.WriteSelect._ import pc.SrcSelect._ + import alu.control.OpSelect._ import RV32Inst._ val ControlMapping: Array[(BitPat, T)] = Array( // Regs :: PC :: Exe // writeEnable :: writeSelect :: srcSelect :: - (addi, false.B :: rAluOut :: HNil) + (addi, false.B :: rAluOut :: pStaticNpc :: aOpAdd :: HNil) ) def toBits(t: T): BitPat = { @@ -82,13 +59,15 @@ class Control(width: Int) extends Module { val out = decoder(QMCMinimizer, inst, TruthTable( ControlMapping.map(it => (it._1, toBits(it._2))), inv)) + val srcList = slices.map(s => out(s._1 - 1, s._2)) srcList.zip(dstList).foreach({ case (src, dst) => dst := src }) } -class Flowpc extends Module { +class Flow extends Module { val io = IO(new Bundle { }) val ram = SRAM(size=128*1024*1024, tpe=UInt(32.W), numReadPorts=2, numWritePorts=1,numReadwritePorts=0) + val control = new Control(32) // Instruction Fetch ram.readPorts(0).enable := true.B diff --git a/npc/core/src/main/scala/ProgramCounter.scala b/npc/core/src/main/scala/ProgramCounter.scala index 8a740bf..0f0adba 100644 --- a/npc/core/src/main/scala/ProgramCounter.scala +++ b/npc/core/src/main/scala/ProgramCounter.scala @@ -1,13 +1,33 @@ -package flowpc.components +package flow.components import chisel3._ import chisel3.util.{Valid, log2Ceil} import chisel3.util.MuxLookup +import shapeless.{HNil, ::} -class ProgramCounter[T <: Data](tpe: T, numPcSrc: Int) extends Module { - val io = new Bundle { - val pc_srcs = Input(Vec(numPcSrc, tpe)) - val select = Input(UInt(log2Ceil(numPcSrc).W)) - val pc = Output(tpe) +class ProgramCounter[T <: Data](tpe: T) extends Module { + object SrcSelect extends ChiselEnum { + val pStaticNpc, pBranchResult = Value + } + + val control = IO(new Bundle { + val srcSelect = Input(SrcSelect()) + }) + val in = IO(new Bundle { + val pcSrcs = Input(Vec(SrcSelect.all.length, tpe)) + }) + val out = Output(tpe) + + out := in.pcSrcs(control.srcSelect.asUInt) + + type ctrlTypes = SrcSelect.Type :: HNil + def ctrlBindPorts: ctrlTypes = { + control.srcSelect :: HNil + } +} + +object ProgramCounter { + def apply[T <: Data](tpe: T): ProgramCounter[T] = { + val pc = new ProgramCounter(tpe) + pc } - io.pc := io.pc_srcs(io.select) } diff --git a/npc/core/src/main/scala/RegisterFile.scala b/npc/core/src/main/scala/RegisterFile.scala index d100344..9ba7b64 100644 --- a/npc/core/src/main/scala/RegisterFile.scala +++ b/npc/core/src/main/scala/RegisterFile.scala @@ -1,16 +1,17 @@ -package flowpc.components +package flow.components import chisel3._ import chisel3.util.log2Ceil import chisel3.util.UIntToOH import chisel3.util.MuxLookup +import shapeless.{ HNil, :: } class RegControl extends Bundle { - val writeEnable = Input(Bool()) - object WriteSelect extends ChiselEnum { val rAluOut, rMemOut = Value } + + val writeEnable = Input(Bool()) val writeSelect = Input(WriteSelect()) } @@ -28,6 +29,11 @@ class RegFileData[T <: Data](size:Int, tpe: T, numReadPorts: Int, numWritePorts: class RegFileInterface[T <: Data](size: Int, tpe: T, numReadPorts: Int, numWritePorts: Int) extends Bundle { val control = new RegControl val data = new RegFileData(size, tpe, numReadPorts, numWritePorts) + + type ctrlTypes = Bool :: control.WriteSelect.Type :: HNil + def ctrlBindPorts: ctrlTypes = { + control.writeEnable :: control.writeSelect :: HNil + } } class RegisterFileCore[T <: Data](size: Int, tpe: T, numReadPorts: Int) extends Module { @@ -59,9 +65,9 @@ object RegisterFile { val core = Module(new RegisterFileCore(size, tpe, numReadPorts)) val _out = Wire(new RegFileInterface(size, tpe, numReadPorts, numWritePorts)) val clock = core.clock - for (i <- 0 to numReadPorts) { + for (i <- 0 until numReadPorts) { core.readPorts(i).addr := _out.data.read(i).rs - core.readPorts(i).data := _out.data.read(i).src + _out.data.read(i).src := core.readPorts(i).data } core.writePort.addr := _out.data.write.addr core.writePort.data := MuxLookup(_out.control.writeSelect, 0.U)( diff --git a/npc/core/src/test/scala/RegisterFile.scala b/npc/core/src/test/scala/RegisterFile.scala index 9308838..87be171 100644 --- a/npc/core/src/test/scala/RegisterFile.scala +++ b/npc/core/src/test/scala/RegisterFile.scala @@ -5,8 +5,6 @@ import chiseltest._ import org.scalatest.freespec.AnyFreeSpec import chiseltest.simulator.WriteVcdAnnotation -import chisel3.util.{SRAM} - import flowpc.components._ class RegisterFileSpec extends AnyFreeSpec with ChiselScalatestTester { "RegisterFileCore" - { @@ -43,19 +41,22 @@ class RegisterFileSpec extends AnyFreeSpec with ChiselScalatestTester { } } "RegisterInterface" - { - class Top extends Module { - val io = RegisterFile(32, UInt(32.W), 2, 2) - } "worked" in { - test(new Top) { c => - // import c.io.control.WriteSelect._ - // c.io.control.writeEnable.poke(true) - // c.io.control.writeSelect.poke(rAluOut) - // c.io.data.write.addr.poke(1) - // c.io.data.write.data(rAluOut.asUInt).poke(0xcdef) - // c.io.data.read(0).rs.poke(1) - // c.clock.step(1) - // c.io.data.read(0).src.expect(0xcdef) + class Top extends Module { + val io = IO(new RegFileInterface(32, UInt(32.W), 2, 2)) + val rf = RegisterFile(32, UInt(32.W), 2, 2) + io :<>= rf + } + test(new Top).withAnnotations(Seq(WriteVcdAnnotation)) { c => + import c.io.control.WriteSelect._ + val writePort = rAluOut.litValue.toInt + c.io.control.writeEnable.poke(true) + c.io.control.writeSelect.poke(rAluOut) + c.io.data.write.addr.poke(5) + c.io.data.write.data(writePort).poke(0xcdef) + c.io.data.read(0).rs.poke(5) + c.clock.step(1) + c.io.data.read(0).src.expect(0xcdef) } } } diff --git a/npc/csrc/Flow/main.cpp b/npc/csrc/Flow/main.cpp new file mode 100644 index 0000000..4728202 --- /dev/null +++ b/npc/csrc/Flow/main.cpp @@ -0,0 +1,12 @@ +#include +#include +#include +#include +#include + +int main(int argc, char **argv, char **env) { + int sim_time = 0; + Verilated::commandArgs(argc, argv); + + exit(EXIT_SUCCESS); +} diff --git a/npc/csrc_nvboard/Flow/main.cpp b/npc/csrc_nvboard/Flow/main.cpp new file mode 100644 index 0000000..a3a5672 --- /dev/null +++ b/npc/csrc_nvboard/Flow/main.cpp @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include +#include +#include + +const int MAX_SIM_TIME=100; + +void nvboard_bind_all_pins(VFLow* top); + +int main(int argc, char **argv, char **env) { + VFlow *top = new VFlow; + + nvboard_bind_all_pins(top); + nvboard_init(); + while (true) { + nvboard_update(); + top->eval(); + } + delete top; +} \ No newline at end of file