> configure(npc)

ysyx_22040000 李心杨
 Linux calcite 6.1.69 #1-NixOS SMP PREEMPT_DYNAMIC Wed Dec 20 16:00:29 UTC 2023 x86_64 GNU/Linux
  18:42:28  up 2 days 17:43,  2 users,  load average: 1.11, 0.95, 0.90
This commit is contained in:
tracer-ysyx 2024-01-10 18:42:28 +08:00 committed by xinyangli
parent b8d0ecf1b3
commit f44cedc71d
No known key found for this signature in database
10 changed files with 163 additions and 241 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -3,34 +3,10 @@
#include <cstdlib>
#include <verilated.h>
#include <verilated_vcd_c.h>
#include <VSwitch.h>
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);
}

36
npc/csrc/Switch/main.cpp Normal file
View file

@ -0,0 +1,36 @@
#include <cstdlib>
#include <cassert>
#include <cstdlib>
#include <verilated.h>
#include <verilated_vcd_c.h>
#include <VSwitch.h>
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);
}

View file

@ -1,60 +0,0 @@
#include <cassert>
#include <cstdlib>
#include <nvboard.h>
#include <verilated.h>
#include <verilated_vcd_c.h>
#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) <name.h>
#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 <class F> 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;
}

View file

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