@@ -79,6 +79,7 @@ def initval_parameters(contents, width):
79
79
class NXLRAM (Module ):
80
80
def __init__ (self , width = 32 , size = 128 * kB , dual_port = False , init = []):
81
81
self .bus = wishbone .Interface (width )
82
+ bus_bursting = False
82
83
assert width in [32 , 64 ]
83
84
self .width = width
84
85
self .size = size
@@ -115,6 +116,85 @@ def __init__(self, width=32, size=128*kB, dual_port=False, init=[]):
115
116
print ("sel_bits_start " , sel_bits_start )
116
117
print ("adr_bits_start " , adr_bits_start )
117
118
119
+ # # #
120
+
121
+ adr_burst = Signal ()
122
+
123
+ # Incrementing address burst cycles support - address generator
124
+
125
+ if bus_bursting :
126
+ adr_wrap_mask = Array ((0b0000 , 0b0011 , 0b0111 , 0b1111 ))
127
+ adr_wrap_max = adr_wrap_mask [- 1 ].bit_length ()
128
+
129
+ adr_latched = Signal ()
130
+
131
+ adr_counter = Signal (len (self .bus .adr ))
132
+ adr_counter_base = Signal (len (self .bus .adr ))
133
+ adr_counter_offset = Signal (adr_wrap_max )
134
+ adr_offset_lsb = Signal (adr_wrap_max )
135
+ adr_offset_msb = Signal (len (self .bus .adr ))
136
+
137
+ adr_next = Signal (len (self .bus .adr ))
138
+
139
+ # Only incrementing burst cycles are supported
140
+ self .comb += [
141
+ Case (self .bus .cti , {
142
+ # incrementing address burst cycle
143
+ 0b010 : adr_burst .eq (1 ),
144
+ # end current burst cycle
145
+ 0b111 : adr_burst .eq (0 ),
146
+ # unsupported burst cycle
147
+ "default" : adr_burst .eq (0 )
148
+ }),
149
+ adr_counter_base .eq (
150
+ Cat (self .bus .adr & ~ adr_wrap_mask [self .bus .bte ],
151
+ self .bus .adr [adr_wrap_max :]
152
+ )
153
+ )
154
+ ]
155
+
156
+ # Latch initial address - initial address without wrapping bits and wrap offset
157
+ self .sync += [
158
+ If (self .bus .cyc & self .bus .stb & adr_burst ,
159
+ adr_latched .eq (1 ),
160
+ # latch initial address, then increment it every clock cycle
161
+ If (adr_latched ,
162
+ adr_counter .eq (adr_counter + 1 )
163
+ ).Else (
164
+ adr_counter_offset .eq (self .bus .adr & adr_wrap_mask [self .bus .bte ]),
165
+ adr_counter .eq (adr_counter_base +
166
+ Cat (~ self .bus .we , Replicate (0 , len (adr_counter )- 1 ))
167
+ ),
168
+ ),
169
+ If (self .bus .cti == 0b111 ,
170
+ adr_latched .eq (0 ),
171
+ adr_counter .eq (0 ),
172
+ adr_counter_offset .eq (0 )
173
+ )
174
+ ).Else (
175
+ adr_latched .eq (0 ),
176
+ adr_counter .eq (0 ),
177
+ adr_counter_offset .eq (0 )
178
+ ),
179
+ ]
180
+
181
+ # Next address = sum of counter value without wrapped bits
182
+ # and wrapped counter bits with offset
183
+ self .comb += [
184
+ adr_offset_lsb .eq ((adr_counter + adr_counter_offset ) & adr_wrap_mask [self .bus .bte ]),
185
+ adr_offset_msb .eq (adr_counter &
186
+ Cat (~ adr_wrap_mask [self .bus .bte ], Replicate (1 , len (adr_offset_msb )- len (adr_offset_lsb )))
187
+ ),
188
+ adr_next .eq (adr_offset_msb +
189
+ Cat (adr_offset_lsb , Replicate (0 , len (adr_next ) - len (adr_offset_lsb )))
190
+ )
191
+ ]
192
+
193
+ else : # bus_bursting = False
194
+ self .comb += adr_burst .eq (0 )
195
+
196
+ # # #
197
+
118
198
if dual_port :
119
199
self .b_addrs = []
120
200
self .b_douts = []
@@ -124,6 +204,7 @@ def __init__(self, width=32, size=128*kB, dual_port=False, init=[]):
124
204
self .lram_blocks .append ([])
125
205
# Combine RAMs to increase Width.
126
206
for w in range (self .width_cascading ):
207
+ address = Signal (self .width )
127
208
datain = Signal (32 )
128
209
dataout = Signal (32 )
129
210
cs = Signal ()
@@ -146,13 +227,19 @@ def __init__(self, width=32, size=128*kB, dual_port=False, init=[]):
146
227
self .bus .dat_r [32 * w :32 * (w + 1 )].eq (dataout )
147
228
]
148
229
230
+ self .comb += address .eq (self .bus .adr [adr_bits_start :adr_bits_start + 14 ])
231
+ if bus_bursting :
232
+ self .comb += If (adr_burst & adr_latched ,
233
+ address .eq (adr_next [adr_bits_start :adr_bits_start + 14 ]),
234
+ )
235
+
149
236
if dual_port :
150
237
b_addr = Signal (14 )
151
238
b_dout = Signal (32 )
152
239
lram_block = Instance ("DPSC512K" ,
153
240
p_ECC_BYTE_SEL = "BYTE_EN" ,
154
241
i_DIA = datain ,
155
- i_ADA = self . bus . adr [ adr_bits_start : adr_bits_start + 14 ] ,
242
+ i_ADA = address ,
156
243
i_CLK = ClockSignal (),
157
244
i_CEA = 0b1 ,
158
245
i_WEA = wren ,
@@ -177,7 +264,7 @@ def __init__(self, width=32, size=128*kB, dual_port=False, init=[]):
177
264
lram_block = Instance ("SP512K" ,
178
265
p_ECC_BYTE_SEL = "BYTE_EN" ,
179
266
i_DI = datain ,
180
- i_AD = self . bus . adr [ adr_bits_start : adr_bits_start + 14 ] ,
267
+ i_AD = address ,
181
268
i_CLK = ClockSignal (),
182
269
i_CE = 0b1 ,
183
270
i_WE = wren ,
@@ -190,7 +277,7 @@ def __init__(self, width=32, size=128*kB, dual_port=False, init=[]):
190
277
self .lram_blocks [d ].append (lram_block )
191
278
self .specials += lram_block
192
279
193
- self .sync += self .bus .ack .eq (self .bus .stb & self .bus .cyc & ~ self .bus .ack )
280
+ self .sync += self .bus .ack .eq (self .bus .cyc & self .bus .stb & ( ~ self .bus .ack | adr_burst ) )
194
281
195
282
if init != []:
196
283
self .add_init (init )
0 commit comments