> 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
  20:30:51  up 1 day 19:31,  2 users,  load average: 0.75, 0.84, 0.73
This commit is contained in:
tracer-ysyx 2024-01-09 20:30:51 +08:00 committed by xinyangli
parent d02c8f5681
commit 45b0983c4a
No known key found for this signature in database
21 changed files with 290 additions and 780 deletions

View file

@ -0,0 +1,64 @@
package npc.keyboard
import chisel3._
import chiseltest._
import org.scalatest.freespec.AnyFreeSpec
import chiseltest.simulator.WriteVcdAnnotation
class KeyboardControllerSpec extends AnyFreeSpec with ChiselScalatestTester {
def transfer(keycode: Int, clock: Clock, ps2: PS2Port) : Unit = {
require(keycode >= 0 && keycode < 0xFF)
var cycle = 0
var keycode_remain = keycode << 1 // Shift 1 to do nothing at cycle 0
var keycode_collect = 0
ps2.data.poke(1)
ps2.clk.poke(true)
clock.step(1)
for (cycle <- 0 until 9) {
val last_digit = keycode_remain & 1
ps2.clk.poke(true)
ps2.data.poke(last_digit)
clock.step(32)
keycode_collect = keycode_collect | (last_digit << cycle)
keycode_remain = keycode_remain >> 1
ps2.clk.poke(false)
clock.step(32)
}
for (_ <- 9 until 11) {
ps2.clk.poke(true)
clock.step(32)
ps2.clk.poke(false)
clock.step(32)
}
assert(keycode_collect >> 1 == keycode)
clock.step(32)
}
"Simple test" in {
test(new KeyboardController).withAnnotations(Seq(WriteVcdAnnotation)) { c =>
val data = Array(0xE4, 0xD4, 0xC4, 0xA9)
data.foreach(d => {
transfer(d, c.clock, c.io.ps2)
c.io.out.valid.expect(1.U)
c.io.out.bits.expect(d)
c.io.out.ready.poke(1)
c.clock.step(1)
c.io.out.ready.poke(0)
})
data.foreach(d => {
transfer(d, c.clock, c.io.ps2)
})
data.foreach(d => {
c.io.out.valid.expect(1.U)
c.io.out.bits.expect(d)
c.io.out.ready.poke(1)
c.clock.step(1)
c.io.out.ready.poke(0)
})
}
}
"Keyboard Simulation" in {
test(new Keyboard) { c =>
}
}
}

View file

@ -3,6 +3,7 @@ package npc
import chisel3._
import chiseltest._
import org.scalatest.freespec.AnyFreeSpec
import chiseltest.simulator.WriteVcdAnnotation
class RegisterFileSpec extends AnyFreeSpec with ChiselScalatestTester {
"RegisterFile should work" - {
@ -41,97 +42,62 @@ class RegisterFileSpec extends AnyFreeSpec with ChiselScalatestTester {
class ALUGeneratorSpec extends AnyFreeSpec with ChiselScalatestTester {
"With 32 width, " - {
val neg = (x: BigInt) => BigInt("FFFFFFFF", 16) - x + 1
val not = (x: BigInt) => x ^ BigInt("FFFFFFFF", 16)
val mask = BigInt("FFFFFFFF", 16)
val oprands: List[(BigInt, BigInt)] = List(
(5, 3), (101010, 101010), (0xFFFFFFFCL, 0xFFFFFFFFL), (4264115, 2)
)
val operations: Map[Int, (BigInt, BigInt) => BigInt] = Map(
0 -> ((a: BigInt, b: BigInt) => (a + b) & mask),
1 -> ((a: BigInt, b: BigInt) => (a + neg(b)) & mask),
2 -> ((a, _) => not(a)),
3 -> (_ & _),
4 -> (_ | _),
5 -> (_ ^ _),
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)]) => {
c.io.op.poke(op.U)
oprands.foreach({ case (a, b) =>
c.io.a.poke(a.U)
c.io.b.poke(b.U)
c.io.out.expect(operations(op)(a, b))
})
}
"add should work" in {
test(new ALUGenerator(32)) { c =>
c.io.op.poke(0.U)
c.io.a.poke(5.U)
c.io.b.poke(3.U)
c.io.out.expect(8.U)
}
test(new ALUGenerator(32)) { c => validate(c, 0, oprands) }
}
"sub should work" - {
"with positive result" in {
test(new ALUGenerator(32)) { c =>
c.io.op.poke(1.U)
c.io.a.poke(5.U)
c.io.b.poke(3.U)
c.io.out.expect(2)
validate(c, 1, oprands.filter({case (a, b) => a >= b}))
}
}
"with negative result" in {
test(new ALUGenerator(32)) { c =>
c.io.op.poke(1.U)
c.io.a.poke(3.U)
c.io.b.poke(5.U)
c.io.out.expect(BigInt("FFFFFFFF", 16) - 1)
validate(c, 1, oprands.filter({case (a, b) => a < b}))
}
}
}
"not should work" in {
test(new ALUGenerator(32)) { c =>
c.io.op.poke(2.U)
c.io.a.poke(5.U)
c.io.b.poke(3.U)
c.io.out.expect(BigInt("FFFFFFFA", 16))
}
test(new ALUGenerator(32)) { c => validate(c, 2, oprands) }
}
"and should work" in {
test(new ALUGenerator(32)) { c =>
c.io.op.poke(3.U)
c.io.a.poke(5.U)
c.io.b.poke(3.U)
c.io.out.expect(1.U)
}
test(new ALUGenerator(32)) { c => validate(c, 3, oprands) }
}
"or should work" in {
test(new ALUGenerator(32)) { c =>
c.io.op.poke(4.U)
c.io.a.poke(5.U)
c.io.b.poke(3.U)
c.io.out.expect(7.U)
}
test(new ALUGenerator(32)) { c => validate(c, 4, oprands) }
}
"xor should work" in {
test(new ALUGenerator(32)) { c =>
c.io.op.poke(5.U)
c.io.a.poke(5.U)
c.io.b.poke(3.U)
c.io.out.expect(6.U)
}
test(new ALUGenerator(32)) { c => validate(c, 5, oprands) }
}
"compare should work" in {
test(new ALUGenerator(32)) { c =>
c.io.op.poke(6)
c.io.a.poke(62.U)
c.io.b.poke(3.U)
c.io.out.expect(0.U)
c.io.a.poke(2.U)
c.io.b.poke(103.U)
c.io.out.expect(1.U)
c.io.a.poke(16.U)
c.io.b.poke(16.U)
c.io.out.expect(0.U)
}
test(new ALUGenerator(32)) { c => validate(c, 6, oprands) }
}
"equal should work" in {
test(new ALUGenerator(32)) { c =>
c.io.op.poke(7)
c.io.a.poke(62.U)
c.io.b.poke(3.U)
c.io.out.expect(0.U)
c.io.a.poke(2.U)
c.io.b.poke(103.U)
c.io.out.expect(0.U)
c.io.a.poke(16.U)
c.io.b.poke(16.U)
c.io.out.expect(1.U)
}
test(new ALUGenerator(32)) { c => validate(c, 7, oprands) }
}
}
}