1 # This file is Copyright (c) 2015-2018 Florent Kermarrec <florent@enjoy-digital.fr>
6 from migen
.genlib
.misc
import chooser
, WaitTimer
7 from migen
.genlib
.record
import Record
8 from migen
.genlib
.fsm
import FSM
, NextState
10 from litex
.soc
.interconnect
import wishbone
11 from litex
.soc
.interconnect
import stream
14 class WishboneStreamingBridge(Module
):
20 def __init__(self
, phy
, clk_freq
):
21 self
.wishbone
= wishbone
.Interface()
25 byte_counter
= Signal(3, reset_less
=True)
26 byte_counter_reset
= Signal()
27 byte_counter_ce
= Signal()
29 If(byte_counter_reset
,
31 ).Elif(byte_counter_ce
,
32 byte_counter
.eq(byte_counter
+ 1)
35 word_counter
= Signal(3, reset_less
=True)
36 word_counter_reset
= Signal()
37 word_counter_ce
= Signal()
39 If(word_counter_reset
,
41 ).Elif(word_counter_ce
,
42 word_counter
.eq(word_counter
+ 1)
45 cmd
= Signal(8, reset_less
=True)
48 length
= Signal(8, reset_less
=True)
51 address
= Signal(32, reset_less
=True)
54 data
= Signal(32, reset_less
=True)
59 If(cmd_ce
, cmd
.eq(phy
.source
.data
)),
60 If(length_ce
, length
.eq(phy
.source
.data
)),
61 If(address_ce
, address
.eq(Cat(phy
.source
.data
, address
[0:24]))),
63 data
.eq(Cat(phy
.source
.data
, data
[0:24]))
65 data
.eq(self
.wishbone
.dat_r
)
69 fsm
= ResetInserter()(FSM(reset_state
="IDLE"))
70 timer
= WaitTimer(clk_freq
//10)
71 self
.submodules
+= fsm
, timer
73 fsm
.reset
.eq(timer
.done
),
74 phy
.source
.ready
.eq(1)
79 If((phy
.source
.data
== self
.cmds
["write"]) |
80 (phy
.source
.data
== self
.cmds
["read"]),
81 NextState("RECEIVE_LENGTH")
83 byte_counter_reset
.eq(1),
84 word_counter_reset
.eq(1)
87 fsm
.act("RECEIVE_LENGTH",
90 NextState("RECEIVE_ADDRESS")
93 fsm
.act("RECEIVE_ADDRESS",
96 byte_counter_ce
.eq(1),
98 If(cmd
== self
.cmds
["write"],
99 NextState("RECEIVE_DATA")
100 ).Elif(cmd
== self
.cmds
["read"],
101 NextState("READ_DATA")
103 byte_counter_reset
.eq(1),
107 fsm
.act("RECEIVE_DATA",
110 byte_counter_ce
.eq(1),
111 If(byte_counter
== 3,
112 NextState("WRITE_DATA"),
113 byte_counter_reset
.eq(1)
118 self
.wishbone
.adr
.eq(address
+ word_counter
),
119 self
.wishbone
.dat_w
.eq(data
),
120 self
.wishbone
.sel
.eq(2**len(self
.wishbone
.sel
) - 1)
122 fsm
.act("WRITE_DATA",
123 self
.wishbone
.stb
.eq(1),
124 self
.wishbone
.we
.eq(1),
125 self
.wishbone
.cyc
.eq(1),
126 If(self
.wishbone
.ack
,
127 word_counter_ce
.eq(1),
128 If(word_counter
== (length
-1),
131 NextState("RECEIVE_DATA")
136 self
.wishbone
.stb
.eq(1),
137 self
.wishbone
.we
.eq(0),
138 self
.wishbone
.cyc
.eq(1),
139 If(self
.wishbone
.ack
,
141 NextState("SEND_DATA")
145 chooser(data
, byte_counter
, phy
.sink
.data
, n
=4, reverse
=True)
147 phy
.sink
.valid
.eq(1),
149 byte_counter_ce
.eq(1),
150 If(byte_counter
== 3,
151 word_counter_ce
.eq(1),
152 If(word_counter
== (length
-1),
155 NextState("READ_DATA"),
156 byte_counter_reset
.eq(1)
162 self
.comb
+= timer
.wait
.eq(~fsm
.ongoing("IDLE"))
164 self
.comb
+= phy
.sink
.last
.eq((byte_counter
== 3) & (word_counter
== length
- 1))
166 if hasattr(phy
.sink
, "length"):
167 self
.comb
+= phy
.sink
.length
.eq(4*length
)