> 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:
parent
b8d0ecf1b3
commit
f44cedc71d
10 changed files with 163 additions and 241 deletions
|
@ -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)
|
34
npc/core/src/main/scala/ALU.scala
Normal file
34
npc/core/src/main/scala/ALU.scala
Normal 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,
|
||||
))
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
23
npc/core/src/main/scala/RegisterFile.scala
Normal file
23
npc/core/src/main/scala/RegisterFile.scala
Normal 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))
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
36
npc/csrc/Switch/main.cpp
Normal 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);
|
||||
}
|
|
@ -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;
|
||||
}
|
23
npc/csrc_nvboard/Switch/main.cpp
Normal file
23
npc/csrc_nvboard/Switch/main.cpp
Normal 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;
|
||||
}
|
Loading…
Reference in a new issue