Fix new BRAM36 features.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
Keith Rothman 2020-10-28 13:37:12 -07:00
parent 91d91357b5
commit 88fc1f1b40
4 changed files with 95 additions and 19 deletions

View File

@ -7,14 +7,14 @@
# SPDX-License-Identifier: ISC
# read/write width is relatively slow to resolve
# Even slower with multi bit masks...
N ?= 10
N ?= 20
include ../fuzzer.mk
database: build/segbits_bramx.db
build/segbits_bramx.rdb: $(SPECIMENS_OK)
${XRAY_SEGMATCH} -o build/segbits_bramx.rdb $(addsuffix /segdata_bram_[lr].txt,$(SPECIMENS))
${XRAY_SEGMATCH} -c 1 -o build/segbits_bramx.rdb $(addsuffix /segdata_bram_[lr].txt,$(SPECIMENS))
build/segbits_bramx.db: build/segbits_bramx.rdb
${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --seg-fn-in $^ --seg-fn-out $@

View File

@ -0,0 +1,29 @@
RAMB36 features
===============
This fuzzer emits features that only are used in the RAMB36E1 cell. There are
3 categories:
- ECC
- RAM extension
- Odd address modes
Odd address modes
-----------------
Most RAMB36E1 address widths are expressed by configuring the underlying
RAMB18E1 to handle half of the data. So `RAMB36.READ_WIDTH = 4` is
expressed as `RAM18_Y0.READ_WIDTH = 2` and `RAM18_Y1.READ_WIDTH = 2`. However
two address widths (1 and 9) are odd (e.g. not divisible by 2). In these
cases, a RAMB36E1 specific feature is used. So `RAMB36.READ_WIDTH = 9` is
expressed as:
- `RAMB18_Y0.READ_WIDTH_4`
- `RAMB18_Y1.READ_WIDTH_4`
- `RAMB36.BRAM36_READ_WIDTH_1`
and `RAMB36.READ_WIDTH = 1` is expressed as:
- `RAMB18_Y0.READ_WIDTH_1`
- `RAMB18_Y1.READ_WIDTH_1`
- `RAMB36.BRAM36_READ_WIDTH_1`

View File

@ -36,13 +36,23 @@ def main():
if tile_param['BRAM36_IN_USE']:
write_ram_ext_tags(segmk, tile_param)
segmk.add_site_tag(tile_param['site'], 'BRAM36_IN_USE', 1)
segmk.add_site_tag(
tile_param['site'], 'EN_ECC_READ', tile_param['EN_ECC_READ'])
segmk.add_site_tag(
tile_param['site'], 'EN_ECC_WRITE', tile_param['EN_ECC_WRITE'])
else:
segmk.add_site_tag(tile_param['site'], 'BRAM36_IN_USE', 0)
for ab in 'ab':
for rw in 'rw':
if rw == 'r':
dir = 'READ'
else:
dir = 'WRITE'
width = tile_param['bram36_{}{}_width'.format(rw, ab)]
tag = 'BRAM36_{}_WIDTH_{}_1'.format(dir, ab.upper())
if width == 1:
segmk.add_site_tag(
tile_param['site'], tag, tile_param['BRAM36_IN_USE'])
segmk.compile()
segmk.write()

View File

@ -47,6 +47,9 @@ RAM_EXTENSION_OPTS = [
"UPPER",
]
BRAM36_WIDTHS = [1, 2]
BRAM36_TO_18_WIDTHS = {1: 1, 2: 1}
def main():
db = Database(util.get_db_root(), util.get_part())
@ -59,9 +62,27 @@ module top();
params = []
for tile_name, bram36_site_name, bram18_site_name, fifo18_site_name in gen_bram36(
grid):
bram36_ra_width = random.choice(BRAM36_WIDTHS)
bram36_wa_width = random.choice(BRAM36_WIDTHS)
bram36_rb_width = random.choice(BRAM36_WIDTHS)
bram36_wb_width = random.choice(BRAM36_WIDTHS)
bram18_ra_width = BRAM36_TO_18_WIDTHS[bram36_ra_width]
bram18_wa_width = BRAM36_TO_18_WIDTHS[bram36_wa_width]
bram18_rb_width = BRAM36_TO_18_WIDTHS[bram36_rb_width]
bram18_wb_width = BRAM36_TO_18_WIDTHS[bram36_wb_width]
if random.random() < .8:
ram_extension_a = random.choice(RAM_EXTENSION_OPTS)
ram_extension_b = random.choice(RAM_EXTENSION_OPTS)
if bram36_ra_width == 1 and bram36_wa_width == 1:
ram_extension_a = random.choice(RAM_EXTENSION_OPTS)
else:
ram_extension_a = 'NONE'
if bram36_rb_width == 1 and bram36_wb_width == 1:
ram_extension_b = random.choice(RAM_EXTENSION_OPTS)
else:
ram_extension_b = 'NONE'
en_ecc_read = random.randint(0, 1)
en_ecc_write = random.randint(0, 1)
@ -69,10 +90,10 @@ module top();
'''
(* KEEP, DONT_TOUCH, LOC = "{site}" *)
RAMB36E1 #(
.READ_WIDTH_A(1),
.WRITE_WIDTH_A(1),
.READ_WIDTH_B(1),
.WRITE_WIDTH_B(1),
.READ_WIDTH_A({bram36_ra_width}),
.WRITE_WIDTH_A({bram36_wa_width}),
.READ_WIDTH_B({bram36_rb_width}),
.WRITE_WIDTH_B({bram36_wb_width}),
.RAM_EXTENSION_A({ram_extension_a}),
.RAM_EXTENSION_B({ram_extension_b}),
.EN_ECC_READ({en_ecc_read}),
@ -106,6 +127,10 @@ module top();
ram_extension_b=verilog.quote(ram_extension_b),
en_ecc_read=en_ecc_read,
en_ecc_write=en_ecc_write,
bram36_ra_width=bram36_ra_width,
bram36_wa_width=bram36_wa_width,
bram36_rb_width=bram36_rb_width,
bram36_wb_width=bram36_wb_width,
))
params.append(
@ -117,16 +142,20 @@ module top();
'RAM_EXTENSION_B': ram_extension_b,
'EN_ECC_READ': en_ecc_read,
'EN_ECC_WRITE': en_ecc_write,
'bram36_ra_width': bram36_ra_width,
'bram36_wa_width': bram36_wa_width,
'bram36_rb_width': bram36_rb_width,
'bram36_wb_width': bram36_wb_width,
})
else:
print(
'''
(* KEEP, DONT_TOUCH, LOC = "{bram18}" *)
RAMB18E1 #(
.READ_WIDTH_A(1),
.WRITE_WIDTH_A(1),
.READ_WIDTH_B(1),
.WRITE_WIDTH_B(1)
.READ_WIDTH_A({bram18_ra_width}),
.WRITE_WIDTH_A({bram18_wa_width}),
.READ_WIDTH_B({bram18_rb_width}),
.WRITE_WIDTH_B({bram18_wb_width})
) bram_{bram18} (
.CLKARDCLK(),
.CLKBWRCLK(),
@ -153,10 +182,10 @@ module top();
(* KEEP, DONT_TOUCH, LOC = "{fifo18}" *)
RAMB18E1 #(
.READ_WIDTH_A(1),
.WRITE_WIDTH_A(1),
.READ_WIDTH_B(1),
.WRITE_WIDTH_B(1)
.READ_WIDTH_A({bram18_ra_width}),
.WRITE_WIDTH_A({bram18_wa_width}),
.READ_WIDTH_B({bram18_rb_width}),
.WRITE_WIDTH_B({bram18_wb_width})
) bram_{fifo18} (
.CLKARDCLK(),
.CLKBWRCLK(),
@ -183,6 +212,10 @@ module top();
'''.format(
bram18=bram18_site_name,
fifo18=fifo18_site_name,
bram18_ra_width=bram18_ra_width,
bram18_wa_width=bram18_wa_width,
bram18_rb_width=bram18_rb_width,
bram18_wb_width=bram18_wb_width,
))
params.append(
@ -190,6 +223,10 @@ module top();
'tile': tile_name,
'BRAM36_IN_USE': False,
'site': bram36_site_name,
'bram36_ra_width': bram36_ra_width,
'bram36_wa_width': bram36_wa_width,
'bram36_rb_width': bram36_rb_width,
'bram36_wb_width': bram36_wb_width,
})
print("endmodule")