> 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
  23:25:23  up 2 days 14:15,  2 users,  load average: 0.55, 0.82, 0.95
This commit is contained in:
tracer-ysyx 2024-03-11 23:25:23 +08:00 committed by xinyangli
parent ee22c1541d
commit 8fc1f3838b
9 changed files with 155 additions and 90 deletions

View file

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

5
npc/constr/Flow.nxdc Normal file
View file

@ -0,0 +1,5 @@
top=Flow
io_sw_0 (SW0)
io_sw_1 (SW1)
io_out (LD0)

View file

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

View file

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

View file

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

View file

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

View file

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

12
npc/csrc/Flow/main.cpp Normal file
View file

@ -0,0 +1,12 @@
#include <cstdlib>
#include <cassert>
#include <cstdlib>
#include <verilated.h>
#include <verilated_vcd_c.h>
int main(int argc, char **argv, char **env) {
int sim_time = 0;
Verilated::commandArgs(argc, argv);
exit(EXIT_SUCCESS);
}

View file

@ -0,0 +1,23 @@
#include <cstdlib>
#include <cassert>
#include <cstdlib>
#include <verilated.h>
#include <verilated_vcd_c.h>
#include <nvboard.h>
#include <VFlow.h>
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;
}