diff --git a/npc/constr/SegHandler.nxdc b/npc/constr/SegHandler.nxdc deleted file mode 100644 index d87f990..0000000 --- a/npc/constr/SegHandler.nxdc +++ /dev/null @@ -1,11 +0,0 @@ -top=SegHandler - -io_keycode_bits (SW7, SW6, SW5, SW4, SW3, SW2, SW1, SW0) -io_segs_0 (SEG0A, SEG0B, SEG0C, SEG0D, SEG0E, SEG0F, SEG0G, DEC0P) -io_segs_1 (SEG1A, SEG1B, SEG1C, SEG1D, SEG1E, SEG1F, SEG1G, DEC1P) -io_segs_2 (SEG2A, SEG2B, SEG2C, SEG2D, SEG2E, SEG2F, SEG2G, DEC2P) -io_segs_3 (SEG3A, SEG3B, SEG3C, SEG3D, SEG3E, SEG3F, SEG3G, DEC3P) -io_segs_4 (SEG4A, SEG4B, SEG4C, SEG4D, SEG4E, SEG4F, SEG4G, DEC4P) -io_segs_5 (SEG5A, SEG5B, SEG5C, SEG5D, SEG5E, SEG5F, SEG5G, DEC5P) -io_segs_6 (SEG6A, SEG6B, SEG6C, SEG6D, SEG6E, SEG6F, SEG6G, DEC6P) -io_segs_7 (SEG7A, SEG7B, SEG7C, SEG7D, SEG7E, SEG7F, SEG7G, DEC7P) diff --git a/npc/core/src/main/scala/ALU.scala b/npc/core/src/main/scala/ALU.scala new file mode 100644 index 0000000..65ade3e --- /dev/null +++ b/npc/core/src/main/scala/ALU.scala @@ -0,0 +1,34 @@ +package npc.util + +import chisel3._ +import chisel3.util._ + +class ALUGenerator(width: Int) extends Module { + require(width >= 0) + 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 adder_b = (Fill(width, io.op(0)) ^ io.b) + io.op(0) // take (-b) if sub + val add = io.a + adder_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 + + 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, + )) +} diff --git a/npc/core/src/main/scala/Keyboard.scala b/npc/core/src/main/scala/Keyboard.scala index 8a5506b..ddc512c 100644 --- a/npc/core/src/main/scala/Keyboard.scala +++ b/npc/core/src/main/scala/Keyboard.scala @@ -1,10 +1,7 @@ -package npc.keyboard +package npc.util import chisel3._ -import chisel3.util.{Counter, Decoupled, Queue, Reverse, MuxLookup, RegEnable} - -import npc.seg._ -import upickle.implicits.key +import chisel3.util.{Counter, Decoupled, Queue, Reverse, MuxLookup} class PS2Port extends Bundle { val clk = Input(Bool()) @@ -56,49 +53,3 @@ class KeyboardController extends Module { received := false.B } } - -class SegGenerator(seg_count: Int) extends Module { - val io = IO(new Bundle { - val keycode = Flipped(Decoupled(UInt(8.W))) - val segs = Output(Vec(seg_count, UInt(8.W))) - }) - io.keycode.ready := false.B - when(io.keycode.valid) { - io.keycode.ready := true.B - } - - val seg_regs = RegInit(VecInit(Seq.fill(seg_count)(0.U(8.W)))) - val last_keycode = RegInit(0.U(8.W)) - val digit_to_seg = ((0 until 16).map(_.U)).zip(Seq( - "b00000011".U, "b10011111".U, "b00100101".U, "b00001101".U, - "b10011001".U, "b01001001".U, "b01000001".U, "b00011111".U, - "b00000001".U, "b00001001".U, "b00010001".U, "b11000001".U, - "b01100011".U, "b10000101".U, "b01100001".U, "b01110001".U, - )) - - val keycode_to_ascii = Seq( - 0x1C.U, 0x32.U, 0x21.U, 0x23.U, 0x24.U, 0x2B.U, - 0x34.U, 0x33.U, 0x43.U, 0x3B.U, 0x42.U, 0x4B.U, - 0x3A.U, 0x31.U, 0x44.U, 0x4D.U, 0x15.U, 0x2D.U, - 0x1B.U, 0x2C.U, 0x3C.U, 0x2A.U, 0x1D.U, 0x22.U, - 0x35.U, 0x1A.U, 0x45.U, 0x16.U, 0x1E.U, 0x26.U, - 0x25.U, 0x2E.U, 0x36.U, 0x3D.U, 0x3E.U, 0x46.U, - ).zip(((0x41 to 0x5A) ++ (0x30 to 0x39)).map(_.U)) - - // val keycode = Mux(io.keycode.ready && io.keycode.valid, io.keycode.bits, keycode) - val keycode = RegEnable(io.keycode.bits, io.keycode.ready && io.keycode.valid) - val keycode_digits = VecInit(keycode(3,0)) ++ VecInit(keycode(7,4)) - val keycode_seg = keycode_digits.map(MuxLookup(_, 0xFF.U)(digit_to_seg)) - val ascii = MuxLookup(keycode, 0.U)(keycode_to_ascii) - val ascii_digits = VecInit(ascii(3,0)) ++ VecInit(ascii(6,4)) - val ascii_seg = ascii_digits.map(MuxLookup(_, 0xFF.U)(digit_to_seg)) - val (counter, _) = Counter(io.keycode.valid && io.keycode.ready && io.keycode.bits =/= keycode, 0xFF) - val count_digits = VecInit(counter(3,0)) ++ VecInit(counter(7,4)) - val count_seg = count_digits.map(MuxLookup(_, 0xFF.U)(digit_to_seg)) - - seg_regs := keycode_seg ++ ascii_seg ++ count_seg ++ Seq(0xFF.U, 0xFF.U) - - io.segs := seg_regs -} - - diff --git a/npc/core/src/main/scala/Main.scala b/npc/core/src/main/scala/Main.scala index c3a1444..5644090 100644 --- a/npc/core/src/main/scala/Main.scala +++ b/npc/core/src/main/scala/Main.scala @@ -4,73 +4,6 @@ import chisel3._ import chisel3.util.{MuxLookup, Fill, Decoupled, Counter, Queue, Reverse} import chisel3.stage.ChiselOption -class RegisterFile(readPorts: Int) extends Module { - require(readPorts >= 0) - val io = IO(new Bundle { - val writeEnable = Input(Bool()) - val writeAddr = Input(UInt(5.W)) - val writeData = Input(UInt(32.W)) - val readAddr = Input(Vec(readPorts, UInt(5.W))) - val readData = Output(Vec(readPorts, UInt(32.W))) - }) - - val regFile = RegInit(VecInit(Seq.fill(32)(0.U(32.W)))) - for (i <- 1 until 32) { - regFile(i) := regFile(i) - } - regFile(io.writeAddr) := Mux(io.writeEnable, io.writeData, regFile(io.writeAddr)) - regFile(0) := 0.U - - for (i <- 0 until readPorts) { - io.readData(i) := regFile(io.readAddr(i)) - } -} - -class ALUGenerator(width: Int) extends Module { - require(width >= 0) - 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 adder_b = (Fill(width, io.op(0)) ^ io.b) + io.op(0) // take (-b) if sub - val add = io.a + adder_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 - - 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, - )) -} - -class Test extends Module { - val io = IO(new Bundle { - val in = Input(UInt(32.W)) - val out = Output(UInt(32.W)) - }) - - val regFile = Module(new RegisterFile(2)) - regFile.io.writeEnable := true.B - regFile.io.writeAddr := 1.U - regFile.io.writeData := io.in - regFile.io.readAddr(0) := 0.U - regFile.io.readAddr(1) := 1.U - io.out := regFile.io.readData(1) -} - class Switch extends Module { val io = IO(new Bundle { val sw = Input(Vec(2, Bool())) @@ -80,7 +13,7 @@ class Switch extends Module { io.out := io.sw(0) ^ io.sw(1) } -import npc.keyboard._ +import npc.util.{PS2Port, KeyboardController, SegGenerator} class Keyboard extends Module { val io = IO(new Bundle { diff --git a/npc/core/src/main/scala/RegisterFile.scala b/npc/core/src/main/scala/RegisterFile.scala new file mode 100644 index 0000000..3f1d50c --- /dev/null +++ b/npc/core/src/main/scala/RegisterFile.scala @@ -0,0 +1,23 @@ +import chisel3._ + +class RegisterFile(readPorts: Int) extends Module { + require(readPorts >= 0) + val io = IO(new Bundle { + val writeEnable = Input(Bool()) + val writeAddr = Input(UInt(5.W)) + val writeData = Input(UInt(32.W)) + val readAddr = Input(Vec(readPorts, UInt(5.W))) + val readData = Output(Vec(readPorts, UInt(32.W))) + }) + + val regFile = RegInit(VecInit(Seq.fill(32)(0.U(32.W)))) + for (i <- 1 until 32) { + regFile(i) := regFile(i) + } + regFile(io.writeAddr) := Mux(io.writeEnable, io.writeData, regFile(io.writeAddr)) + regFile(0) := 0.U + + for (i <- 0 until readPorts) { + io.readData(i) := regFile(io.readAddr(i)) + } +} diff --git a/npc/core/src/main/scala/SegGenerator.scala b/npc/core/src/main/scala/SegGenerator.scala index 7c2d334..0b4ac55 100644 --- a/npc/core/src/main/scala/SegGenerator.scala +++ b/npc/core/src/main/scala/SegGenerator.scala @@ -1,35 +1,52 @@ -package npc.seg +package npc.util import chisel3._ -import chisel3.util.{Decoupled} +import chisel3.util._ import chisel3.util.log2Ceil -class SegInput(width: Int) extends Bundle { - require(width > 0) - val addr = UInt(width.W) - val value = UInt(log2Ceil(width).W) -} - -object SegInput { - def apply(width: Int): SegInput = { - return new SegInput(width) - } -} - -class SegGenerator(width: Int) extends { +class SegGenerator(seg_count: Int) extends Module { val io = IO(new Bundle { - val write = Flipped(Decoupled(SegInput(8))) - val segs = Output(Vec(width, UInt(8.W))) + val keycode = Flipped(Decoupled(UInt(8.W))) + val segs = Output(Vec(seg_count, UInt(8.W))) }) - - val seg_regs = RegInit(VecInit(Seq.fill(width)(0.U(8.W)))) - io.segs := seg_regs - - when(io.write.valid) { - val data = io.write.bits - seg_regs(data.addr) := data.value - io.write.ready := true.B - }.otherwise { - io.write.ready := false.B + io.keycode.ready := false.B + when(io.keycode.valid) { + io.keycode.ready := true.B } + + val seg_regs = RegInit(VecInit(Seq.fill(seg_count)(0.U(8.W)))) + val last_keycode = RegInit(0.U(8.W)) + val digit_to_seg = ((0 until 16).map(_.U)).zip(Seq( + "b00000011".U, "b10011111".U, "b00100101".U, "b00001101".U, + "b10011001".U, "b01001001".U, "b01000001".U, "b00011111".U, + "b00000001".U, "b00001001".U, "b00010001".U, "b11000001".U, + "b01100011".U, "b10000101".U, "b01100001".U, "b01110001".U, + )) + + val keycode_to_ascii = Seq( + 0x1C.U, 0x32.U, 0x21.U, 0x23.U, 0x24.U, 0x2B.U, + 0x34.U, 0x33.U, 0x43.U, 0x3B.U, 0x42.U, 0x4B.U, + 0x3A.U, 0x31.U, 0x44.U, 0x4D.U, 0x15.U, 0x2D.U, + 0x1B.U, 0x2C.U, 0x3C.U, 0x2A.U, 0x1D.U, 0x22.U, + 0x35.U, 0x1A.U, 0x45.U, 0x16.U, 0x1E.U, 0x26.U, + 0x25.U, 0x2E.U, 0x36.U, 0x3D.U, 0x3E.U, 0x46.U, + ).zip(((0x41 to 0x5A) ++ (0x30 to 0x39)).map(_.U)) + + // val keycode = Mux(io.keycode.ready && io.keycode.valid, io.keycode.bits, keycode) + val keycode = RegEnable(io.keycode.bits, io.keycode.ready && io.keycode.valid) + val keycode_digits = VecInit(keycode(3,0)) ++ VecInit(keycode(7,4)) + val keycode_seg = keycode_digits.map(MuxLookup(_, 0xFF.U)(digit_to_seg)) + val ascii = MuxLookup(keycode, 0.U)(keycode_to_ascii) + val ascii_digits = VecInit(ascii(3,0)) ++ VecInit(ascii(6,4)) + val ascii_seg = ascii_digits.map(MuxLookup(_, 0xFF.U)(digit_to_seg)) + val (counter, _) = Counter(io.keycode.valid && io.keycode.ready && io.keycode.bits =/= keycode, 0xFF) + val count_digits = VecInit(counter(3,0)) ++ VecInit(counter(7,4)) + val count_seg = count_digits.map(MuxLookup(_, 0xFF.U)(digit_to_seg)) + + seg_regs := keycode_seg ++ ascii_seg ++ count_seg ++ Seq(0xFF.U, 0xFF.U) + + io.segs := seg_regs } + + + diff --git a/npc/csrc/Keyboard/main.cpp b/npc/csrc/Keyboard/main.cpp index 9a3f262..4728202 100644 --- a/npc/csrc/Keyboard/main.cpp +++ b/npc/csrc/Keyboard/main.cpp @@ -3,34 +3,10 @@ #include #include #include -#include - -const int MAX_SIM_TIME=100; int main(int argc, char **argv, char **env) { int sim_time = 0; Verilated::commandArgs(argc, argv); - VSwitch *top = new VSwitch; - Verilated::traceEverOn(true); - VerilatedVcdC *m_trace = new VerilatedVcdC; -#ifdef VERILATOR_TRACE - top->trace(m_trace, 5); - m_trace->open("waveform.vcd"); -#endif - for (sim_time = 0; sim_time < MAX_SIM_TIME; sim_time++) { - top->io_sw_0 = rand() % 2; - top->io_sw_1 = rand() % 2; - top->eval(); - printf("sw0 = %d, sw1 = %d, ledr = %d\n", top->io_sw_0, top->io_sw_1, top->io_out); - assert(top->io_out == (top->io_sw_0 ^ top->io_sw_1)); -#ifdef VERILATOR_TRACE - m_trace->dump(sim_time); -#endif - } -#ifdef VERILATOR_TRACE - m_trace->close(); -#endif - delete top; exit(EXIT_SUCCESS); } diff --git a/npc/csrc/Switch/main.cpp b/npc/csrc/Switch/main.cpp new file mode 100644 index 0000000..9a3f262 --- /dev/null +++ b/npc/csrc/Switch/main.cpp @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include +#include + +const int MAX_SIM_TIME=100; + +int main(int argc, char **argv, char **env) { + int sim_time = 0; + Verilated::commandArgs(argc, argv); + VSwitch *top = new VSwitch; + + Verilated::traceEverOn(true); + VerilatedVcdC *m_trace = new VerilatedVcdC; +#ifdef VERILATOR_TRACE + top->trace(m_trace, 5); + m_trace->open("waveform.vcd"); +#endif + for (sim_time = 0; sim_time < MAX_SIM_TIME; sim_time++) { + top->io_sw_0 = rand() % 2; + top->io_sw_1 = rand() % 2; + top->eval(); + printf("sw0 = %d, sw1 = %d, ledr = %d\n", top->io_sw_0, top->io_sw_1, top->io_out); + assert(top->io_out == (top->io_sw_0 ^ top->io_sw_1)); +#ifdef VERILATOR_TRACE + m_trace->dump(sim_time); +#endif + } +#ifdef VERILATOR_TRACE + m_trace->close(); +#endif + delete top; + exit(EXIT_SUCCESS); +} diff --git a/npc/csrc_nvboard/SegHandler/main.cpp b/npc/csrc_nvboard/SegHandler/main.cpp deleted file mode 100644 index 631d072..0000000 --- a/npc/csrc_nvboard/SegHandler/main.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include -#include -#include - -#ifndef VERILATOR_TOPMODULE -#define VERILATOR_TOPMODULE VSegHandler -#endif - -#define CLASS_SYSTEM_HEADER_NAME(name) CLASS_SYSTEM_HEADER_NAME_IMPL(name) -#define CLASS_SYSTEM_HEADER_NAME_IMPL(name) -#include CLASS_SYSTEM_HEADER_NAME(VERILATOR_TOPMODULE) -#undef CLASS_SYSTEM_HEADER_NAME -#undef CLASS_SYSTEM_HEADER_NAME_IMPL - -const int MAX_SIM_TIME = 100; -int keycode = 0; - -template void cycle(VERILATOR_TOPMODULE *top, F &&f) { - top->clock = 0; - top->eval(); - top->clock = 1; - top->eval(); - f(); -} - -void nvboard_bind_all_pins(VERILATOR_TOPMODULE *top); - -static void single_cycle(VERILATOR_TOPMODULE *top) { - top->clock = 0; - top->eval(); - top->clock = 1; - top->eval(); -} - -static void reset(VERILATOR_TOPMODULE *top, int n) { - top->reset = 1; - while (n-- > 0) - single_cycle(top); - top->reset = 0; -} - -int main(int argc, char **argv, char **env) { - VERILATOR_TOPMODULE *top = new VERILATOR_TOPMODULE; - - nvboard_bind_all_pins(top); - nvboard_init(); - reset(top, 10); - while (true) { - nvboard_update(); - cycle(top, [&] { - if (keycode != top->io_keycode_bits){ - keycode = top->io_keycode_bits; - printf("%d\n", keycode); - } - }); - } - delete top; -} \ No newline at end of file diff --git a/npc/csrc_nvboard/Switch/main.cpp b/npc/csrc_nvboard/Switch/main.cpp new file mode 100644 index 0000000..401de4b --- /dev/null +++ b/npc/csrc_nvboard/Switch/main.cpp @@ -0,0 +1,23 @@ +#include +#include +#include +#include +#include +#include +#include + +const int MAX_SIM_TIME=100; + +void nvboard_bind_all_pins(VSwitch* top); + +int main(int argc, char **argv, char **env) { + VSwitch *top = new VSwitch; + + nvboard_bind_all_pins(top); + nvboard_init(); + while (true) { + nvboard_update(); + top->eval(); + } + delete top; +} \ No newline at end of file