Skip to content

Commit 8764e40

Browse files
committed
Finish UartDebug
1 parent be10ea3 commit 8764e40

File tree

3 files changed

+154
-18
lines changed

3 files changed

+154
-18
lines changed

7series.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ puts [irscan xc7.tap 0x09]
1818
puts [drscan xc7.tap 32 0]
1919

2020
puts "Programming FPGA..."
21-
pld load 0 build/BitBang.bit
21+
pld load 0 build/UartDebug.bit
2222
exit

src/main/scala/debug/UartDebug.scala

Lines changed: 133 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,147 @@ class UartDebug(frequ: Int, baudRate: Int = 115200) extends Module {
1515
val din = Input(UInt(32.W))
1616
})
1717

18+
// ASCII -> hex including valid signal
19+
def ascii2hex(in: UInt) = {
20+
val out = Wire(UInt(8.W))
21+
val valid = false.B
22+
out := 16.U
23+
switch(in) {
24+
is('0'.U) { out := "h0".U }
25+
is('1'.U) { out := "h1".U }
26+
is('2'.U) { out := "h2".U }
27+
is('3'.U) { out := "h3".U }
28+
is('4'.U) { out := "h4".U }
29+
is('5'.U) { out := "h5".U }
30+
is('6'.U) { out := "h6".U }
31+
is('7'.U) { out := "h7".U }
32+
is('8'.U) { out := "h8".U }
33+
is('9'.U) { out := "h9".U }
34+
is('a'.U) { out := "ha".U }
35+
is('b'.U) { out := "hb".U }
36+
is('c'.U) { out := "hc".U }
37+
is('d'.U) { out := "hd".U }
38+
is('e'.U) { out := "he".U }
39+
is('f'.U) { out := "hf".U }
40+
is('A'.U) { out := "hA".U }
41+
is('B'.U) { out := "hB".U }
42+
is('C'.U) { out := "hC".U }
43+
is('D'.U) { out := "hD".U }
44+
is('E'.U) { out := "hE".U }
45+
is('F'.U) { out := "hF".U }
46+
}
47+
(out(3, 0), out =/= 16.U)
48+
}
49+
50+
def hex2ascii(in: UInt) = {
51+
val out = Wire(UInt(8.W))
52+
out := 0.U
53+
switch(in) {
54+
is("h0".U) { out := '0'.U }
55+
is("h1".U) { out := '1'.U }
56+
is("h2".U) { out := '2'.U }
57+
is("h3".U) { out := '3'.U }
58+
is("h4".U) { out := '4'.U }
59+
is("h5".U) { out := '5'.U }
60+
is("h6".U) { out := '6'.U }
61+
is("h7".U) { out := '7'.U }
62+
is("h8".U) { out := '8'.U }
63+
is("h9".U) { out := '9'.U }
64+
is("ha".U) { out := 'a'.U }
65+
is("hb".U) { out := 'b'.U }
66+
is("hc".U) { out := 'c'.U }
67+
is("hd".U) { out := 'd'.U }
68+
is("he".U) { out := 'e'.U }
69+
is("hf".U) { out := 'f'.U }
70+
}
71+
out
72+
}
73+
1874
val tx = Module(new BufferedTx(100000000, baudRate))
1975
val rx = Module(new Rx(100000000, baudRate))
2076

2177
io.tx := tx.io.txd
2278
rx.io.rxd := io.rx
2379

24-
tx.io.channel.bits := rx.io.channel.bits + 1.U
25-
tx.io.channel.valid := rx.io.channel.valid
26-
rx.io.channel.ready := tx.io.channel.ready
80+
val inReg = RegInit(0.U(8.W))
81+
val validReg = RegInit(false.B)
82+
83+
rx.io.channel.ready := true.B
84+
when (rx.io.channel.valid) {
85+
inReg := rx.io.channel.bits
86+
validReg := true.B
87+
}
88+
89+
tx.io.channel.bits := inReg
90+
tx.io.channel.valid := false.B
91+
92+
when (tx.io.channel.ready && validReg) {
93+
validReg := false.B
94+
tx.io.channel.valid := true.B
95+
}
96+
97+
val doutReg = RegInit(0x1234.U(32.W))
98+
val doutShftReg = RegInit(0.U(32.W))
99+
val dinShftReg = RegInit(0.U(32.W))
100+
val cntRdReg = RegInit(0.U(4.W))
101+
102+
object State extends ChiselEnum {
103+
val sIdle, sLineFeed, sWrite, sRead, sCr = Value
104+
}
105+
import State._
106+
val stateReg = RegInit(sIdle)
27107

28-
io.dout := 0x1234.U
29-
when (tx.io.channel.valid && tx.io.channel.ready) {
30-
io.dout := tx.io.channel.bits
108+
switch(stateReg) {
109+
is(sIdle) {
110+
when (validReg && inReg === 'w'.U) {
111+
stateReg := sWrite
112+
doutShftReg := 0.U
113+
}
114+
when (validReg && inReg === 'r'.U) {
115+
stateReg := sRead
116+
dinShftReg := io.din
117+
cntRdReg := 8.U
118+
}
119+
}
120+
is(sWrite) {
121+
when (validReg) {
122+
when (inReg === '\r'.U) {
123+
stateReg := sLineFeed
124+
doutReg := doutShftReg
125+
}
126+
val (out, valid) = ascii2hex(inReg)
127+
when (valid) {
128+
doutShftReg := doutShftReg(31, 8)
129+
doutShftReg := doutShftReg ## out
130+
}
131+
}
132+
}
133+
is(sLineFeed) {
134+
tx.io.channel.valid := true.B
135+
tx.io.channel.bits := '\n'.U
136+
when (tx.io.channel.ready) {
137+
stateReg := sIdle
138+
}
139+
}
140+
is(sRead) {
141+
when (cntRdReg =/= 0.U) {
142+
tx.io.channel.valid := true.B
143+
tx.io.channel.bits := hex2ascii(dinShftReg(31, 28))
144+
when (tx.io.channel.ready) {
145+
dinShftReg := dinShftReg << 4
146+
cntRdReg := cntRdReg - 1.U
147+
}
148+
}
149+
when (cntRdReg === 0.U) {
150+
tx.io.channel.valid := true.B
151+
tx.io.channel.bits := '\r'.U
152+
when (tx.io.channel.ready) {
153+
stateReg := sLineFeed
154+
}
155+
}
156+
}
31157
}
158+
io.dout := doutReg
32159
}
33160

34161
object UartDebug extends App {

src/test/scala/debug/UartDebugTest.scala

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ class UartDebugTestTop extends Module {
1010
val io = IO(new Bundle {
1111
val inRx = new UartIO()
1212
val outTx = Flipped(new UartIO())
13-
val dout = Output(UInt(32.W))
14-
val din = Input(UInt(32.W))
13+
// val dout = Output(UInt(32.W))
14+
// val din = Input(UInt(32.W))
1515
})
1616

1717
val tx = Module(new BufferedTx(100000000, 100000000/16))
@@ -24,20 +24,29 @@ class UartDebugTestTop extends Module {
2424

2525
dbg.io.rx := tx.io.txd
2626
rx.io.rxd := dbg.io.tx
27-
io.dout := dbg.io.dout
28-
dbg.io.din := io.din
27+
dbg.io.din := ~dbg.io.dout
2928
}
3029

3130
class UartDebugTest extends AnyFlatSpec with ChiselScalatestTester {
3231
"UartDebug" should "work" in {
3332
test(new UartDebugTestTop()).withAnnotations(Seq(WriteVcdAnnotation)) { dut =>
34-
dut.io.din.poke(0xabcd.U)
35-
dut.clock.setTimeout(10001)
36-
dut.io.outTx.valid.poke(true.B)
37-
dut.io.outTx.bits.poke(0x42.U)
38-
dut.clock.step(10)
39-
dut.io.outTx.valid.poke(false.B)
40-
dut.clock.step(1000)
33+
def write(c: Char): Unit = {
34+
dut.io.outTx.valid.poke(true.B)
35+
dut.io.outTx.bits.poke(c.U)
36+
while (!dut.io.outTx.ready.peekBoolean()) {
37+
dut.clock.step(1)
38+
}
39+
dut.clock.step(1)
40+
dut.io.outTx.valid.poke(false.B)
41+
}
42+
43+
val s = "w123xabc\r r "
44+
for (c <- s) {
45+
write(c)
46+
}
47+
dut.clock.setTimeout(0)
48+
// TODO: real checks would be nice, not jst waveform inspection
49+
dut.clock.step(5000)
4150
}
4251
}
4352
}

0 commit comments

Comments
 (0)