@@ -78,7 +78,7 @@ class LiteSPIMMAP(LiteXModule):
7878 def __init__ (self , flash , clock_domain = "sys" , endianness = "big" , with_csr = True , with_write = False , cs_width = 1 , cs_mask = 1 ):
7979 self .source = source = stream .Endpoint (spi_core2phy_layout )
8080 self .sink = sink = stream .Endpoint (spi_phy2core_layout )
81- self .bus = bus = wishbone .Interface ()
81+ self .bus = bus = wishbone .Interface (mode = "rw" if with_write else "r" )
8282 self .cs = Signal (cs_width )
8383 self .request = cs = Signal ()
8484
@@ -87,8 +87,6 @@ def __init__(self, flash, clock_domain="sys", endianness="big", with_csr=True, w
8787 burst_adr = Signal (len (bus .adr ), reset_less = True )
8888 self .burst_timeout = burst_timeout = WaitTimer (MMAP_DEFAULT_TIMEOUT )
8989
90- write = Signal ()
91- write_enabled = Signal ()
9290 write_mask = Signal (len (bus .sel ))
9391
9492 cmd_bits = 8
@@ -110,6 +108,7 @@ def __init__(self, flash, clock_domain="sys", endianness="big", with_csr=True, w
110108 dummy = Signal (data_bits , reset = 0xdead )
111109
112110 if with_write and with_write == "csr" :
111+ write_enabled = Signal ()
113112 self .write_config = write_config = CSRStorage (fields = [
114113 CSRField ("write_enable" , size = 1 , reset = 0 , description = "MMAP write enable" ),
115114 ])
@@ -118,10 +117,15 @@ def __init__(self, flash, clock_domain="sys", endianness="big", with_csr=True, w
118117 else :
119118 self .comb += write_enabled .eq (write_config .fields .write_enable )
120119 else :
121- self .comb += write_enabled .eq (Constant (with_write == True ))
120+ write_enabled = Constant (with_write == True )
121+
122+ if with_write :
123+ write = Signal ()
124+ self .data_write = Signal (32 )
125+ else :
126+ write = Constant (0 )
122127
123128 self .byte_count = byte_count = Signal (2 , reset_less = True )
124- self .data_write = Signal (32 )
125129
126130 self .comb += If (self .request , self .cs .eq (cs_mask ))
127131
@@ -145,49 +149,54 @@ def __init__(self, flash, clock_domain="sys", endianness="big", with_csr=True, w
145149 cs .eq (0 ),
146150 NextState ("BURST-CMD" )
147151 ),
148- NextValue (write , 0 )
149- # On Bus Write access (if enabled)...
150- ).Elif (write_enabled ,
151- # If CS is still active, Bus address matches previous Burst address and previous access was writing:
152- # Just continue the current Burst.
153- NextValue (write_mask , bus .sel ),
154- NextValue (self .data_write , bus .dat_w ),
155- If (burst_cs & (bus .adr == burst_adr ) & bus .sel [0 ] & write ,
156- NextState ("WRITE" )
157- # Otherwise initialize a new Burst.
158- ).Else (
159- cs .eq (0 ),
160- NextState ("PRE-BURST-CMD-WRITE" ),
161- ),
162- NextValue (write , 1 )
163152 )
164153 )
165154 )
166155
167- fsm .act ("PRE-BURST-CMD-WRITE" ,
168- cs .eq (0 ),
169- If (write_mask [0 ],
170- NextState ("BURST-CMD" ),
171- NextValue (write , 1 )
172- ).Elif (byte_count == 3 ,
173- bus .ack .eq (1 ),
174- NextValue (burst_adr , burst_adr + 1 ),
175- NextState ("IDLE" ),
176- NextValue (write , 0 )
177- ).Else (
178- NextValue (byte_count , byte_count + 1 ),
179- NextValue (write_mask , Cat (write_mask [1 :len (bus .sel )], Signal (1 ))),
156+ if with_write :
157+ fsm .act ("IDLE" ,
158+ If (bus .cyc & bus .stb ,
159+ # On Bus Read access...
160+ If (~ bus .we ,
161+ NextValue (write , 0 )
162+ # On Bus Write access (if enabled)...
163+ ).Elif (write_enabled ,
164+ # If CS is still active, Bus address matches previous Burst address and previous access was writing:
165+ # Just continue the current Burst.
166+ NextValue (write_mask , bus .sel ),
167+ NextValue (self .data_write , bus .dat_w ),
168+ If (burst_cs & (bus .adr == burst_adr ) & bus .sel [0 ] & write ,
169+ NextState ("WRITE" )
170+ # Otherwise initialize a new Burst.
171+ ).Else (
172+ cs .eq (0 ),
173+ NextState ("PRE-BURST-CMD-WRITE" ),
174+ ),
175+ NextValue (write , 1 )
176+ )
177+ )
178+ )
179+
180+ fsm .act ("PRE-BURST-CMD-WRITE" ,
181+ cs .eq (0 ),
182+ If (write_mask [0 ],
183+ NextState ("BURST-CMD" ),
184+ NextValue (write , 1 )
185+ ).Elif (byte_count == 3 ,
186+ bus .ack .eq (1 ),
187+ NextValue (burst_adr , burst_adr + 1 ),
188+ NextState ("IDLE" ),
189+ NextValue (write , 0 )
190+ ).Else (
191+ NextValue (byte_count , byte_count + 1 ),
192+ NextValue (write_mask , Cat (write_mask [1 :len (bus .sel )], Signal (1 ))),
193+ )
180194 )
181- )
182195
183196 fsm .act ("BURST-CMD" ,
184197 cs .eq (1 ),
185198 source .valid .eq (1 ),
186- If (write_enabled & write ,
187- source .data .eq (flash .program_opcode .code ), # send command.
188- ).Else (
189- source .data .eq (flash .read_opcode .code ), # send command.
190- ),
199+ source .data .eq (flash .read_opcode .code ), # send command.
191200 source .len .eq (cmd_bits ),
192201 source .width .eq (flash .cmd_width ),
193202 source .mask .eq (cmd_oe_mask [flash .cmd_width ]),
@@ -197,6 +206,13 @@ def __init__(self, flash, clock_domain="sys", endianness="big", with_csr=True, w
197206 )
198207 )
199208
209+ if with_write :
210+ fsm .act ("BURST-CMD" ,
211+ If (write_enabled & write ,
212+ source .data .eq (flash .program_opcode .code ), # send command.
213+ )
214+ )
215+
200216 fsm .act ("CMD-RET" ,
201217 cs .eq (1 ),
202218 sink .ready .eq (1 ),
@@ -223,16 +239,21 @@ def __init__(self, flash, clock_domain="sys", endianness="big", with_csr=True, w
223239 cs .eq (1 ),
224240 sink .ready .eq (1 ),
225241 If (sink .valid ,
226- If (write_enabled & write ,
227- NextState ("WRITE" ),
228- ).Elif (spi_dummy_bits == 0 ,
242+ If (spi_dummy_bits == 0 ,
229243 NextState ("BURST-REQ" ),
230244 ).Else (
231245 NextState ("DUMMY" ),
232246 )
233247 )
234248 )
235249
250+ if with_write :
251+ fsm .act ("ADDR-RET" ,
252+ If (sink .valid & write_enabled & write ,
253+ NextState ("WRITE" ),
254+ )
255+ )
256+
236257 fsm .act ("DUMMY" ,
237258 cs .eq (1 ),
238259 source .valid .eq (1 ),
@@ -275,38 +296,39 @@ def __init__(self, flash, clock_domain="sys", endianness="big", with_csr=True, w
275296 )
276297 )
277298
278- fsm .act ("WRITE" ,
279- cs .eq (1 ),
280- source .valid .eq (1 ),
281- source .width .eq (flash .addr_width ),
282- source .mask .eq (addr_oe_mask [flash .bus_width ]),
283- source .data .eq (self .data_write ),
284- source .len .eq (8 ),
285- If (source .ready ,
286- NextState ("WRITE-RET" ),
299+ if with_write :
300+ fsm .act ("WRITE" ,
301+ cs .eq (1 ),
302+ source .valid .eq (1 ),
303+ source .width .eq (flash .addr_width ),
304+ source .mask .eq (addr_oe_mask [flash .bus_width ]),
305+ source .data .eq (self .data_write ),
306+ source .len .eq (8 ),
307+ If (source .ready ,
308+ NextState ("WRITE-RET" ),
309+ )
287310 )
288- )
289311
290- fsm .act ("WRITE-RET" ,
291- cs .eq (1 ),
292- sink .ready .eq (1 ),
293- If (sink .valid ,
294- If (byte_count != 3 ,
295- NextValue (write_mask , Cat (write_mask [1 :len (bus .sel )], Signal (1 ))),
296- NextValue (byte_count , byte_count + 1 ),
297- NextValue (self .data_write , self .data_write >> 8 ),
298- If (write_mask [1 ],
299- NextState ("WRITE" ),
312+ fsm .act ("WRITE-RET" ,
313+ cs .eq (1 ),
314+ sink .ready .eq (1 ),
315+ If (sink .valid ,
316+ If (byte_count != 3 ,
317+ NextValue (write_mask , Cat (write_mask [1 :len (bus .sel )], Signal (1 ))),
318+ NextValue (byte_count , byte_count + 1 ),
319+ NextValue (self .data_write , self .data_write >> 8 ),
320+ If (write_mask [1 ],
321+ NextState ("WRITE" ),
322+ ).Else (
323+ cs .eq (0 ),
324+ NextValue (write , 0 ),
325+ NextState ("PRE-BURST-CMD-WRITE" ),
326+ ),
327+
300328 ).Else (
301- cs . eq (0 ),
302- NextValue (write , 0 ),
303- NextState ("PRE-BURST-CMD-WRITE " ),
329+ bus . ack . eq (1 ),
330+ NextValue (burst_adr , burst_adr + 1 ),
331+ NextState ("IDLE " ),
304332 ),
305-
306- ).Else (
307- bus .ack .eq (1 ),
308- NextValue (burst_adr , burst_adr + 1 ),
309- NextState ("IDLE" ),
310- ),
333+ )
311334 )
312- )
0 commit comments