diff --git a/fuzzers/101-bram-config/Makefile b/fuzzers/101-bram-config/Makefile index ccd825a4..6fb1f91c 100644 --- a/fuzzers/101-bram-config/Makefile +++ b/fuzzers/101-bram-config/Makefile @@ -1,5 +1,5 @@ # read/write width is relatively slow to resolve -N := 2 +N := 4 SPECIMENS := $(addprefix build/specimen_,$(shell seq -f '%03.0f' $(N))) SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS)) diff --git a/fuzzers/101-bram-config/generate.py b/fuzzers/101-bram-config/generate.py index 29c22f9f..f89351db 100644 --- a/fuzzers/101-bram-config/generate.py +++ b/fuzzers/101-bram-config/generate.py @@ -34,8 +34,14 @@ def bus_tags(segmk, ps, site): for param, tagname in [('SRVAL_A', 'ZSRVAL_A'), ('SRVAL_B', 'ZSRVAL_B'), ('INIT_A', 'ZINIT_A'), ('INIT_B', 'ZINIT_B')]: bitstr = verilog.parse_bitstr(ps[param]) + ab = param[-1] + # Are all bits present? + hasparity = ps['READ_WIDTH_' + ab] == 18 for i in range(18): - segmk.add_site_tag(site, '%s[%u]' % (param, i), 1 ^ bitstr[i]) + # Magic bit positions from experimentation + # we could just only solve when parity, but this check documents the fine points a bit better + if hasparity or i not in (1, 9): + segmk.add_site_tag(site, '%s[%u]' % (param, i), 1 ^ bitstr[i]) def rw_width_tags(segmk, ps, site): @@ -83,8 +89,8 @@ def run(): site = verilog.unquote(ps['LOC']) #print('site', site) - # isenv_tags(segmk, ps, site) - # bus_tags(segmk, ps, site) + isenv_tags(segmk, ps, site) + bus_tags(segmk, ps, site) rw_width_tags(segmk, ps, site) def bitfilter(frame, bit): diff --git a/fuzzers/101-bram-config/top.py b/fuzzers/101-bram-config/top.py index a8234553..ea5b1e5e 100644 --- a/fuzzers/101-bram-config/top.py +++ b/fuzzers/101-bram-config/top.py @@ -3,6 +3,7 @@ import random random.seed(int(os.getenv("SEED"), 16)) from prjxray import util from prjxray import verilog +from prjxray.verilog import vrandbit, vrandbits import sys import json @@ -57,21 +58,6 @@ print( 'module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1)) - -def vrandbit(): - if random.randint(0, 1): - return "1'b1" - else: - return "1'b0" - - -def vrandbits(n): - ret = "%u'b" % n - for _i in range(n): - ret += str(random.randint(0, 1)) - return ret - - for loci, (site_type, site) in enumerate(brams): def place_bram18(): @@ -80,6 +66,11 @@ for loci, (site_type, site) in enumerate(brams): 'din': 'din[ %d +: 8]' % (8 * loci, ), 'dout': 'dout[ %d +: 8]' % (8 * loci, ), } + + # Datasheet says 72 is legal in some cases, but think its a copy paste error from BRAM36 + # also 0 and 36 aren't real sizes + # Bias choice to 18 as its needed to solve certain bits quickly + widths = [1, 2, 4, 9, 18, 18, 18, 18] params = { 'LOC': verilog.quote(site), 'IS_CLKARDCLK_INVERTED': vrandbit(), @@ -99,13 +90,12 @@ for loci, (site_type, site) in enumerate(brams): "SRVAL_B": vrandbits(18), "INIT_A": vrandbits(18), "INIT_B": vrandbits(18), - # Datasheet says 72 is legal, but think its a copy paste error from BRAM36 - # also 0 and 36 aren't real sizes - "READ_WIDTH_A": random.choice([1, 2, 4, 9, 18]), - "READ_WIDTH_B": random.choice([1, 2, 4, 9, 18]), - "WRITE_WIDTH_A": random.choice([1, 2, 4, 9, 18]), - "WRITE_WIDTH_B": random.choice([1, 2, 4, 9, 18]), + "READ_WIDTH_A": random.choice(widths), + "READ_WIDTH_B": random.choice(widths), + "WRITE_WIDTH_A": random.choice(widths), + "WRITE_WIDTH_B": random.choice(widths), } + return ('my_RAMB18E1', ports, params) def place_bram36(): diff --git a/prjxray/verilog.py b/prjxray/verilog.py index 9ab29a40..029a01fd 100644 --- a/prjxray/verilog.py +++ b/prjxray/verilog.py @@ -1,4 +1,5 @@ import sys +import random def top_harness(DIN_N, DOUT_N, f=sys.stdout): @@ -76,3 +77,17 @@ def parse_bitstr(s): bitstr = postfix[1:] assert len(bitstr) == n return [int(x) for x in bitstr] + + +def vrandbit(): + if random.randint(0, 1): + return "1'b1" + else: + return "1'b0" + + +def vrandbits(n): + ret = "%u'b" % n + for _i in range(n): + ret += str(random.randint(0, 1)) + return ret