@@ -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 = True
82
83
assert width in [32 , 64 ]
83
84
self .width = width
84
85
self .size = size
@@ -115,6 +116,81 @@ 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 & ~ adr_wrap_mask [self .bus .bte ]),
186
+ adr_next .eq (adr_offset_msb + adr_offset_lsb )
187
+ ]
188
+
189
+ else : # bus_bursting = False
190
+ self .comb += adr_burst .eq (0 )
191
+
192
+ # # #
193
+
118
194
if dual_port :
119
195
self .b_addrs = []
120
196
self .b_douts = []
@@ -124,6 +200,7 @@ def __init__(self, width=32, size=128*kB, dual_port=False, init=[]):
124
200
self .lram_blocks .append ([])
125
201
# Combine RAMs to increase Width.
126
202
for w in range (self .width_cascading ):
203
+ address = Signal (self .width )
127
204
datain = Signal (32 )
128
205
dataout = Signal (32 )
129
206
cs = Signal ()
@@ -146,13 +223,19 @@ def __init__(self, width=32, size=128*kB, dual_port=False, init=[]):
146
223
self .bus .dat_r [32 * w :32 * (w + 1 )].eq (dataout )
147
224
]
148
225
226
+ self .comb += address .eq (self .bus .adr [adr_bits_start :adr_bits_start + 14 ])
227
+ if bus_bursting :
228
+ self .comb += If (adr_burst & adr_latched ,
229
+ address .eq (adr_next [adr_bits_start :adr_bits_start + 14 ]),
230
+ )
231
+
149
232
if dual_port :
150
233
b_addr = Signal (14 )
151
234
b_dout = Signal (32 )
152
235
lram_block = Instance ("DPSC512K" ,
153
236
p_ECC_BYTE_SEL = "BYTE_EN" ,
154
237
i_DIA = datain ,
155
- i_ADA = self . bus . adr [ adr_bits_start : adr_bits_start + 14 ] ,
238
+ i_ADA = address ,
156
239
i_CLK = ClockSignal (),
157
240
i_CEA = 0b1 ,
158
241
i_WEA = wren ,
@@ -177,7 +260,7 @@ def __init__(self, width=32, size=128*kB, dual_port=False, init=[]):
177
260
lram_block = Instance ("SP512K" ,
178
261
p_ECC_BYTE_SEL = "BYTE_EN" ,
179
262
i_DI = datain ,
180
- i_AD = self . bus . adr [ adr_bits_start : adr_bits_start + 14 ] ,
263
+ i_AD = address ,
181
264
i_CLK = ClockSignal (),
182
265
i_CE = 0b1 ,
183
266
i_WE = wren ,
@@ -190,7 +273,7 @@ def __init__(self, width=32, size=128*kB, dual_port=False, init=[]):
190
273
self .lram_blocks [d ].append (lram_block )
191
274
self .specials += lram_block
192
275
193
- self .sync += self .bus .ack .eq (self .bus .stb & self .bus .cyc & ~ self .bus .ack )
276
+ self .sync += self .bus .ack .eq (self .bus .cyc & self .bus .stb & ( ~ self .bus .ack | adr_burst ) )
194
277
195
278
if init != []:
196
279
self .add_init (init )
0 commit comments