-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSDIOSnifferModule.scala
121 lines (100 loc) · 4.09 KB
/
SDIOSnifferModule.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package projectname
import spinal.core._
import spinal.lib.bus.amba4.axilite._
import spinal.lib._
case class AXI4LiteSDIOSnifferWithTrigger(axiLite4Config: AxiLite4Config, axiClk: ClockDomain, glitchClk: ClockDomain) extends Component {
val io = new Bundle {
val axi = slave(AxiLite4(axiLite4Config))
// from glitch clock domain
val trigger_cmd_clr = in Bool()
val trigger_cmd_trigger = out Bool()
// from sdio clock domain
val sdio_sclk = in Bool()
val sdio_cmd = in Bool()
}
val area_glitch = new ClockingArea(glitchClk) {
val trigger_inst = SDIOTrigger()
trigger_inst.io.trigger_cmd_clr := io.trigger_cmd_clr
io.trigger_cmd_trigger := trigger_inst.io.trigger_cmd_trigger
}
val resultFifo = StreamFifoCC(
dataType = Bits(48 bits),
depth = 8,
pushClock = area_glitch.trigger_inst.sdio_clk,
popClock = axiClk
)
val area_sdio = new ClockingArea(area_glitch.trigger_inst.sdio_clk) {
area_glitch.trigger_inst.io.sdio_sclk := io.sdio_sclk
area_glitch.trigger_inst.io.sdio_cmd := io.sdio_cmd
resultFifo.io.push.valid := area_glitch.trigger_inst.io.finish_pulse && area_glitch.trigger_inst.io.cmd_triggered
resultFifo.io.push.payload := area_glitch.trigger_inst.io.cmd_bits
}
val area_axi = new ClockingArea(axiClk) {
val axiLite4SlaveFactory = AxiLite4SlaveFactory(io.axi)
resultFifo.io.pop.ready := False
axiLite4SlaveFactory.read(resultFifo.io.pop.valid, 0x0, 0, "Result FIFO has data")
axiLite4SlaveFactory.write(resultFifo.io.pop.ready, 0x0, 0, "Result FIFO next element")
axiLite4SlaveFactory.read(resultFifo.io.pop.payload(31 downto 0), 0x4, 0, "Result FIFO data bits 31:0")
axiLite4SlaveFactory.read(resultFifo.io.pop.payload(47 downto 32), 0x8, 0, "Result FIFO data bits 47:32")
}
}
case class SDIOTrigger() extends Component {
val io = new Bundle {
val trigger_cmd_clr = in Bool()
val trigger_cmd_trigger = out Bool()
// from sdio clock domain
val sdio_sclk = in Bool()
val sdio_cmd = in Bool()
val finish_pulse = out Bool()
val cmd_bits = out Bits(48 bits)
val cmd_triggered = out Bool()
}
val sdio_clk = ClockDomain(clock = io.sdio_sclk, reset = io.trigger_cmd_clr, config = ClockDomainConfig(
clockEdge = RISING,
resetKind = ASYNC,
resetActiveLevel = HIGH
))
val sdio_sniffer = new ClockingArea(sdio_clk) {
val sniffer = SDIOSnifferModule()
val trig_flag_cmd18_reg = Reg(Bool()) init False
val trig_flag_stop_transmission_reg = Reg(Bool()) init False
sniffer.io.sdio_cmd := io.sdio_cmd
io.finish_pulse := sniffer.io.finish_pulse
io.cmd_bits := sniffer.io.cmd_bits
when(sniffer.io.finish_pulse && sniffer.io.cmd_bits(46 downto 40) === 0x52) { // CMD18 Host to card READ_MULTIPLE_BLOCK
trig_flag_cmd18_reg := True
}
when(trig_flag_cmd18_reg && sniffer.io.finish_pulse && sniffer.io.cmd_bits(46 downto 40) === 0x4C) { // CMD12 Host to card STOP_TRANSMISSION
trig_flag_stop_transmission_reg := True
}
io.cmd_triggered := trig_flag_cmd18_reg && trig_flag_stop_transmission_reg
}
io.trigger_cmd_trigger := RegNext(io.cmd_triggered, False) init False addTag(crossClockDomain)
}
case class SDIOSnifferModule() extends Component {
val io = new Bundle {
val sdio_cmd = in Bool()
val finish_pulse = out Bool()
val cmd_bits = out Bits(48 bits)
}
val cmd_bits_reg = Reg(Bits(48 bits))
val start_flag_reg = Reg(Bool()) init False
val cmd_bits_cnt_reg = Reg(UInt(log2Up(47) bits)) init 0
val finish_pulse_reg = Reg(Bool()) init False
io.finish_pulse := finish_pulse_reg
io.cmd_bits := cmd_bits_reg
cmd_bits_reg := cmd_bits_reg(46 downto 0) ## io.sdio_cmd
when(io.sdio_cmd === False) { // Start bit always 0
start_flag_reg := True
}
when(start_flag_reg === True) {
cmd_bits_cnt_reg := cmd_bits_cnt_reg + 1
} otherwise {
cmd_bits_cnt_reg := 0
finish_pulse_reg := False
}
when(cmd_bits_cnt_reg === 46) {
start_flag_reg := False
finish_pulse_reg := True
}
}