@@ -235,29 +235,30 @@ def elaborate(self, platform):
235235
236236 for elem , (elem_start , elem_end ) in self ._map .resources ():
237237 shadow = Signal (elem .width , name = "{}__shadow" .format (elem .name ))
238+ if elem .access .readable ():
239+ shadow_en = Signal (elem_end - elem_start , name = "{}__shadow_en" .format (elem .name ))
240+ m .d .sync += shadow_en .eq (0 )
238241 if elem .access .writable ():
239242 m .d .comb += elem .w_data .eq (shadow )
243+ m .d .sync += elem .w_stb .eq (0 )
240244
241245 # Enumerate every address used by the register explicitly, rather than using
242246 # arithmetic comparisons, since some toolchains (e.g. Yosys) are too eager to infer
243247 # carry chains for comparisons, even with a constant. (Register sizes don't have
244248 # to be powers of 2.)
245249 with m .Switch (self .bus .addr ):
246250 for chunk_offset , chunk_addr in enumerate (range (elem_start , elem_end )):
247- with m .Case (chunk_addr ):
248- shadow_slice = shadow [chunk_offset * self .bus .data_width :
249- (chunk_offset + 1 ) * self .bus .data_width ]
251+ shadow_slice = shadow .word_select (chunk_offset , self .bus .data_width )
250252
253+ with m .Case (chunk_addr ):
251254 if elem .access .readable ():
252- chunk_r_stb = Signal (self .bus .data_width ,
253- name = "{}__r_stb_{}" .format (elem .name , chunk_offset ))
254- r_data_fanin |= Mux (chunk_r_stb , shadow_slice , 0 )
255+ r_data_fanin |= Mux (shadow_en [chunk_offset ], shadow_slice , 0 )
255256 if chunk_addr == elem_start :
256257 m .d .comb += elem .r_stb .eq (self .bus .r_stb )
257258 with m .If (self .bus .r_stb ):
258259 m .d .sync += shadow .eq (elem .r_data )
259260 # Delay by 1 cycle, allowing reads to be pipelined.
260- m .d .sync += chunk_r_stb .eq (self .bus .r_stb )
261+ m .d .sync += shadow_en .eq (self .bus .r_stb << chunk_offset )
261262
262263 if elem .access .writable ():
263264 if chunk_addr == elem_end - 1 :
@@ -267,9 +268,6 @@ def elaborate(self, platform):
267268 with m .If (self .bus .w_stb ):
268269 m .d .sync += shadow_slice .eq (self .bus .w_data )
269270
270- with m .Default ():
271- m .d .sync += shadow .eq (0 )
272-
273271 m .d .comb += self .bus .r_data .eq (r_data_fanin )
274272
275273 return m
0 commit comments