Add ps/2 keyboard module

This commit is contained in:
xinyangli 2024-01-10 20:20:45 +08:00
parent 0b34b19bdf
commit 1118f64668
No known key found for this signature in database
14 changed files with 405 additions and 207 deletions

View file

@ -0,0 +1,72 @@
package npc.keyboard
import chisel3._
import chiseltest._
import org.scalatest.freespec.AnyFreeSpec
import chiseltest.simulator.WriteVcdAnnotation
import npc.util._
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)
})
}
}
}
class SegSpec extends AnyFreeSpec with ChiselScalatestTester {
"try out vec" in {
test(new SegGenerator(8)) {c =>
c.io.keycode.bits.poke(0xAC)
c.clock.step(1)
println(s"out: ${c.io.segs(0).peek().litValue}")
}
}
}

View file

@ -3,9 +3,10 @@ package npc
import chisel3._
import chiseltest._
import org.scalatest.freespec.AnyFreeSpec
import chiseltest.simulator.ChiselBridge
import chiseltest.simulator.WriteVcdAnnotation
import npc.util._
class RegisterFileSpec extends AnyFreeSpec with ChiselScalatestTester {
"RegisterFile should work" - {
"with 2 read ports" in {
@ -102,46 +103,3 @@ class ALUGeneratorSpec extends AnyFreeSpec with ChiselScalatestTester {
}
}
}
class KeyboardControllerSpec extends AnyFreeSpec with ChiselScalatestTester {
def transfer(keycode: Int, c: KeyboardController) : Unit = {
require(keycode >= 0 && keycode < 0xFF)
var cycle = 0
var ps2_clk = true
var keycode_remain = keycode << 1 // Shift 1 to do nothing at cycle 1
var keycode_collect = 0
c.io.ps2_clk.poke(ps2_clk)
c.io.ps2_data.poke(1)
for (cycle <- 0 until 9) {
c.io.ps2_clk.poke(true)
c.clock.step(32)
val last_digit = keycode_remain & 1
c.io.ps2_data.poke(last_digit)
keycode_collect = keycode_collect | (last_digit << cycle)
keycode_remain = keycode_remain >> 1
c.io.ps2_clk.poke(false)
c.clock.step(32)
}
for (_ <- 9 until 11) {
c.io.ps2_clk.poke(true)
c.clock.step(32)
c.io.ps2_clk.poke(ps2_clk)
ps2_clk = !ps2_clk
c.io.ps2_clk.poke(false)
c.clock.step(32)
}
assert(keycode_collect >> 1 == keycode)
c.io.out.ready.poke(1)
c.clock.step(32)
c.io.out.bits.expect(keycode)
}
"Simple test" in {
test(new KeyboardController).withAnnotations(Seq(WriteVcdAnnotation)) { c =>
transfer(0xE4, c)
transfer(0xE4, c)
transfer(0xE4, c)
transfer(0xE4, c)
}
}
}