diff --git a/npc/core/src/main/scala/ALU.scala b/npc/core/src/main/scala/ALU.scala index 65ade3e..70705d7 100644 --- a/npc/core/src/main/scala/ALU.scala +++ b/npc/core/src/main/scala/ALU.scala @@ -3,17 +3,21 @@ package npc.util import chisel3._ import chisel3.util._ -class ALUGenerator(width: Int) extends Module { - require(width >= 0) +object ALUSel extends ChiselEnum { + val add, sub, not, and, or, xor, slt, eq, nop = Value +} + +class ALUGenerator[T <: ChiselEnum](width: Int, tpe: T = ALUSel) extends Module { val io = IO(new Bundle { - val a = Input(UInt(width.W)) - val b = Input(UInt(width.W)) - val op = Input(UInt(4.W)) - val out = Output(UInt(width.W)) + 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)) }) - val adder_b = (Fill(width, io.op(0)) ^ io.b) + io.op(0) // take (-b) if sub - val add = io.a + adder_b + // 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 @@ -21,14 +25,14 @@ class ALUGenerator(width: Int) extends Module { val slt = io.a < io.b val eq = io.a === io.b - io.out := MuxLookup(io.op, 0.U)(Seq( - 0.U -> add, - 1.U -> add, // add with b reversed - 2.U -> not, - 3.U -> and, - 4.U -> or, - 5.U -> xor, - 6.U -> slt, - 7.U -> eq, + 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 )) } diff --git a/npc/core/src/main/scala/Main.scala b/npc/core/src/main/scala/Main.scala index d34a038..41b4ba4 100644 --- a/npc/core/src/main/scala/Main.scala +++ b/npc/core/src/main/scala/Main.scala @@ -5,7 +5,7 @@ import chisel3.util.{MuxLookup, Fill, Decoupled, Counter, Queue, Reverse} import chisel3.util.{SRAM} import chisel3.stage.ChiselOption import npc.util.{ KeyboardSegController, RegisterFile } -import flowpc.components.ProgramCounter +import flowpc.components.{ProgramCounter, ProgramCounterSel} class Switch extends Module { val io = IO(new Bundle { @@ -33,8 +33,31 @@ class Keyboard extends Module { io.segs := seg_handler.io.segs } +object Opcode extends ChiselEnum { + val addi = Value("b0010011".U) +} + +class Control extends Bundle { + +} + class Flowpc extends Module { val io = IO(new Bundle { }) - val register_file = new RegisterFile(readPorts = 2); - val pc = new ProgramCounter(32); + val register_file = new RegisterFile(readPorts = 2) + val pc = new ProgramCounter(32) + val ram = SRAM(size=128*1024*1024, tpe=UInt(32.W), numReadPorts=2, numWritePorts=1,numReadwritePorts=0) + + // Instruction Fetch + ram.readPorts(0).address := pc.io.pc + ram.readPorts(0).enable := true.B + val instruction = ram.readPorts(0).address + + // Instruction Decode + val opcode = Opcode(instruction(7,0)) + + // Execution + + // Next PC + pc.io.pc_srcs(ProgramCounterSel.selectPC.asUInt) := pc.io.pc + 4.U + // pc.io.pc_srcs(ProgramCounterSel.selectResult.asUInt) := } diff --git a/npc/core/src/main/scala/ProgramCounter.scala b/npc/core/src/main/scala/ProgramCounter.scala index 0687f9a..056cd5b 100644 --- a/npc/core/src/main/scala/ProgramCounter.scala +++ b/npc/core/src/main/scala/ProgramCounter.scala @@ -1,11 +1,17 @@ package flowpc.components import chisel3._ -import chisel3.util.{Valid} +import chisel3.util.{Valid, log2Ceil} +import chisel3.util.MuxLookup + +object ProgramCounterSel extends ChiselEnum { + val selectPC, selectResult = Value +} class ProgramCounter (width: Int) extends Module { val io = new Bundle { - val next_pc = Input(Flipped(Valid(UInt(width.W)))) + val pc_srcs = Input(Vec(1 << (ProgramCounterSel.getWidth - 1), UInt(width.W))) + val select = Input(UInt(ProgramCounterSel.getWidth.W)) val pc = Output(UInt(width.W)) } - io.pc := Mux(io.next_pc.valid, io.next_pc.bits, io.pc) + io.pc := io.pc_srcs(io.select) } diff --git a/npc/core/src/test/scala/Main.scala b/npc/core/src/test/scala/Main.scala index c9c093e..51fa284 100644 --- a/npc/core/src/test/scala/Main.scala +++ b/npc/core/src/test/scala/Main.scala @@ -60,7 +60,7 @@ class ALUGeneratorSpec extends AnyFreeSpec with ChiselScalatestTester { 6 -> ((a, b) => if (a < b) 1 else 0), 7 -> ((a, b) => if (a == b) 1 else 0), ) - val validate = (c: ALUGenerator,op: Int, oprands: List[(BigInt, BigInt)]) => { + 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)