diff --git a/fuzzers/025-bram-config/Makefile b/fuzzers/025-bram-config/Makefile index 17bc7384..74dc1054 100644 --- a/fuzzers/025-bram-config/Makefile +++ b/fuzzers/025-bram-config/Makefile @@ -1,6 +1,6 @@ # read/write width is relatively slow to resolve # Even slower with multi bit masks... -N ?= 8 +N ?= 10 include ../fuzzer.mk diff --git a/fuzzers/025-bram-config/bits.dbf b/fuzzers/025-bram-config/bits.dbf index ac18652f..5a2605a2 100644 --- a/fuzzers/025-bram-config/bits.dbf +++ b/fuzzers/025-bram-config/bits.dbf @@ -3,10 +3,16 @@ 27_43 27_44 27_45,BRAM.RAMB18_Y0.READ_WIDTH_B_1 27_51 27_52 27_53,BRAM.RAMB18_Y0.WRITE_WIDTH_A_1 27_59 27_60 27_61,BRAM.RAMB18_Y0.WRITE_WIDTH_B_1 +27_96,BRAM.RAMB18_Y0.RDADDR_COLLISION_HWCONFIG_DELAYED_WRITE +27_124,BRAM.RAMB18_Y0.RSTREG_PRIORITY_A_RSTREG +27_125,BRAM.RAMB18_Y0.RSTREG_PRIORITY_B_RSTREG # Y1 27_285 27_284 27_283,BRAM.RAMB18_Y1.READ_WIDTH_A_1 27_277 27_276 27_275,BRAM.RAMB18_Y1.READ_WIDTH_B_1 27_269 27_268 27_267,BRAM.RAMB18_Y1.WRITE_WIDTH_A_1 27_261 27_260 27_259,BRAM.RAMB18_Y1.WRITE_WIDTH_B_1 +27_224,BRAM.RAMB18_Y1.RDADDR_COLLISION_HWCONFIG_DELAYED_WRITE +27_196,BRAM.RAMB18_Y1.RSTREG_PRIORITY_A_RSTREG +27_195,BRAM.RAMB18_Y1.RSTREG_PRIORITY_B_RSTREG diff --git a/fuzzers/025-bram-config/generate.py b/fuzzers/025-bram-config/generate.py index a0eb7831..ee1d062e 100644 --- a/fuzzers/025-bram-config/generate.py +++ b/fuzzers/025-bram-config/generate.py @@ -1,17 +1,20 @@ #!/usr/bin/env python3 import json +import csv from prjxray.segmaker import Segmaker from prjxray import verilog from prjxray import segmaker -def isinv_tags(segmk, ps, site): +def isinv_tags(segmk, ps, site, actual_ps): # all of these bits are inverted ks = [ ('IS_CLKARDCLK_INVERTED', 'ZINV_CLKARDCLK'), ('IS_CLKBWRCLK_INVERTED', 'ZINV_CLKBWRCLK'), + ('IS_REGCLKARDRCLK_INVERTED', 'ZINV_REGCLKARDRCLK'), + ('IS_REGCLKB_INVERTED', 'ZINV_REGCLKB'), ('IS_ENARDEN_INVERTED', 'ZINV_ENARDEN'), ('IS_ENBWREN_INVERTED', 'ZINV_ENBWREN'), ('IS_RSTRAMARSTRAM_INVERTED', 'ZINV_RSTRAMARSTRAM'), @@ -19,8 +22,33 @@ def isinv_tags(segmk, ps, site): ('IS_RSTREGARSTREG_INVERTED', 'ZINV_RSTREGARSTREG'), ('IS_RSTREGB_INVERTED', 'ZINV_RSTREGB'), ] + for param, tagname in ks: - segmk.add_site_tag(site, tagname, 1 ^ verilog.parsei(ps[param])) + # The CLK inverts sometimes are changed during synthesis, resulting + # in addition inversions. Take this into account. + if param in actual_ps: + tag = 1 ^ verilog.parsei(actual_ps[param]) + elif param == 'IS_REGCLKARDRCLK_INVERTED': + if verilog.parsei(ps['DOA_REG']): + # When DOA_REG == 1, REGCLKARDRCLK follows the CLKARDCLK setting. + tag = 1 ^ verilog.parsei(actual_ps['IS_CLKARDCLK_INVERTED']) + else: + # When DOA_REG == 0, REGCLKARDRCLK is always inverted. + tag = 0 + + segmk.add_site_tag(site, tagname, tag) + elif param == 'IS_REGCLKB_INVERTED': + if verilog.parsei(ps['DOB_REG']): + # When DOB_REG == 1, REGCLKB follows the CLKBWRCLK setting. + tag = 1 ^ verilog.parsei(actual_ps['IS_CLKBWRCLK_INVERTED']) + else: + # When DOB_REG == 0, REGCLKB is always inverted. + tag = 0 + + else: + tag = 1 ^ verilog.parsei(ps[param]) + + segmk.add_site_tag(site, tagname, tag) def bus_tags(segmk, ps, site): @@ -72,10 +100,29 @@ def write_mode_tags(segmk, ps, site): site, '%s_NO_CHANGE' % (param), set_val == "NO_CHANGE") +def write_rstreg_priority(segmk, ps, site): + for param in ["RSTREG_PRIORITY_A", "RSTREG_PRIORITY_B"]: + set_val = verilog.unquote(ps[param]) + for opt in ["RSTREG", "REGCE"]: + segmk.add_site_tag( + site, "{}_{}".format(param, opt), set_val == opt) + + +def write_rdaddr_collision(segmk, ps, site): + for opt in ["DELAYED_WRITE", "PERFORMANCE"]: + set_val = verilog.unquote(ps['RDADDR_COLLISION_HWCONFIG']) + segmk.add_site_tag( + site, "RDADDR_COLLISION_HWCONFIG_{}".format(opt), set_val == opt) + + def run(): segmk = Segmaker("design.bits") - #segmk.set_def_bt('BLOCK_RAM') + + clk_inverts = {} + with open('design.csv', 'r') as f: + for params in csv.DictReader(f): + clk_inverts[params['site']] = params print("Loading tags") f = open('params.jl', 'r') @@ -86,10 +133,12 @@ def run(): assert j['module'] == 'my_RAMB18E1' site = verilog.unquote(ps['LOC']) - isinv_tags(segmk, ps, site) + isinv_tags(segmk, ps, site, clk_inverts[site]) bus_tags(segmk, ps, site) rw_width_tags(segmk, ps, site) write_mode_tags(segmk, ps, site) + write_rstreg_priority(segmk, ps, site) + write_rdaddr_collision(segmk, ps, site) def bitfilter(frame, bit): # rw_width_tags() aliasing interconnect on large widths diff --git a/fuzzers/025-bram-config/generate.tcl b/fuzzers/025-bram-config/generate.tcl index 1a647bb1..ddc0fba2 100644 --- a/fuzzers/025-bram-config/generate.tcl +++ b/fuzzers/025-bram-config/generate.tcl @@ -23,3 +23,13 @@ route_design write_checkpoint -force design.dcp write_bitstream -force design.bit + +set fp [open "design.csv" "w"] +puts $fp "site,IS_CLKARDCLK_INVERTED,IS_CLKBWRCLK_INVERTED" +foreach ram [get_cells "roi/inst_*/ram"] { + set site [get_sites -of_objects [get_bels -of_objects $ram]] + set IS_CLKARDCLK_INVERTED [get_property IS_CLKARDCLK_INVERTED $ram] + set IS_CLKBWRCLK_INVERTED [get_property IS_CLKBWRCLK_INVERTED $ram] + puts $fp "$site,$IS_CLKARDCLK_INVERTED,$IS_CLKBWRCLK_INVERTED" +} +close $fp diff --git a/fuzzers/025-bram-config/top.py b/fuzzers/025-bram-config/top.py index 7f34a661..6ad6b695 100644 --- a/fuzzers/025-bram-config/top.py +++ b/fuzzers/025-bram-config/top.py @@ -4,7 +4,6 @@ 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 @@ -37,256 +36,183 @@ def gen_brams(): yield ('RAMB18E1', site) -brams = list(gen_brams()) -DUTN = len(brams) -DIN_N = DUTN * 8 -DOUT_N = DUTN * 8 +def place_bram18(site, loci): + ports = { + 'clk': 'clk', + 'din': 'din[ %d +: 8]' % (8 * loci, ), + 'dout': 'dout[ %d +: 8]' % (8 * loci, ), + } -verilog.top_harness(DIN_N, DOUT_N) + write_modes = ["WRITE_FIRST", "READ_FIRST", "NO_CHANGE"] + collisions = ["DELAYED_WRITE", "PERFORMANCE"] + priorities = ["RSTREG", "REGCE"] -f = open('params.jl', 'w') -f.write('module,loc,params\n') -print( - 'module roi(input clk, input [%d:0] din, output [%d:0] dout);' % - (DIN_N - 1, DOUT_N - 1)) + # 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(), + 'IS_CLKBWRCLK_INVERTED': vrandbit(), + 'IS_ENARDEN_INVERTED': vrandbit(), + 'IS_ENBWREN_INVERTED': vrandbit(), + 'IS_RSTRAMARSTRAM_INVERTED': vrandbit(), + 'IS_RSTRAMB_INVERTED': vrandbit(), + 'IS_RSTREGARSTREG_INVERTED': vrandbit(), + 'IS_RSTREGB_INVERTED': vrandbit(), + 'RAM_MODE': '"TDP"', + 'WRITE_MODE_A': verilog.quote(random.choice(write_modes)), + 'WRITE_MODE_B': verilog.quote(random.choice(write_modes)), + "DOA_REG": vrandbit(), + "DOB_REG": vrandbit(), + "SRVAL_A": vrandbits(18), + "SRVAL_B": vrandbits(18), + "INIT_A": vrandbits(18), + "INIT_B": vrandbits(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), + "RDADDR_COLLISION_HWCONFIG": verilog.quote(random.choice(collisions)), + "RSTREG_PRIORITY_A": verilog.quote(random.choice(priorities)), + "RSTREG_PRIORITY_B": verilog.quote(random.choice(priorities)), + } -for loci, (site_type, site) in enumerate(brams): + return ('my_RAMB18E1', ports, params) - def place_bram18(): - ports = { - 'clk': 'clk', - 'din': 'din[ %d +: 8]' % (8 * loci, ), - 'dout': 'dout[ %d +: 8]' % (8 * loci, ), - } - write_modes = ["WRITE_FIRST", "READ_FIRST", "NO_CHANGE"] +def main(): + brams = list(gen_brams()) + DUTN = len(brams) + DIN_N = DUTN * 8 + DOUT_N = DUTN * 8 - # 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(), - 'IS_CLKBWRCLK_INVERTED': vrandbit(), - 'IS_ENARDEN_INVERTED': vrandbit(), - 'IS_ENBWREN_INVERTED': vrandbit(), - 'IS_RSTRAMARSTRAM_INVERTED': vrandbit(), - 'IS_RSTRAMB_INVERTED': vrandbit(), - 'IS_RSTREGARSTREG_INVERTED': vrandbit(), - 'IS_RSTREGB_INVERTED': vrandbit(), - 'RAM_MODE': '"TDP"', - 'WRITE_MODE_A': verilog.quote(random.choice(write_modes)), - 'WRITE_MODE_B': verilog.quote(random.choice(write_modes)), - "DOA_REG": vrandbit(), - "DOB_REG": vrandbit(), - "SRVAL_A": vrandbits(18), - "SRVAL_B": vrandbits(18), - "INIT_A": vrandbits(18), - "INIT_B": vrandbits(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), - } + verilog.top_harness(DIN_N, DOUT_N) - return ('my_RAMB18E1', ports, params) + f = open('params.jl', 'w') + f.write('module,loc,params\n') + print( + 'module roi(input clk, input [%d:0] din, output [%d:0] dout);' % + (DIN_N - 1, DOUT_N - 1)) - ''' - def place_bram36(): - ports = { - 'clk': 'clk', - 'din': 'din[ %d +: 8]' % (8 * loci, ), - 'dout': 'dout[ %d +: 8]' % (8 * loci, ), - } - params = { - 'LOC': verilog.quote(site), - 'IS_CLKARDCLK_INVERTED': vrandbit(), - 'IS_CLKBWRCLK_INVERTED': vrandbit(), - 'IS_ENARDEN_INVERTED': vrandbit(), - 'IS_ENBWREN_INVERTED': vrandbit(), - 'IS_RSTRAMARSTRAM_INVERTED': vrandbit(), - 'IS_RSTRAMB_INVERTED': vrandbit(), - 'IS_RSTREGARSTREG_INVERTED': vrandbit(), - 'IS_RSTREGB_INVERTED': vrandbit(), - 'RAM_MODE': '"TDP"', - 'WRITE_MODE_A': '"WRITE_FIRST"', - 'WRITE_MODE_B': '"WRITE_FIRST"', - } - return ('my_RAMB36E1', ports, params) - ''' + for loci, (site_type, site) in enumerate(brams): + modname, ports, params = { + 'RAMB18E1': place_bram18, + #'RAMBFIFO36E1': place_bram36, + }[site_type](site, loci) - modname, ports, params = { - 'RAMB18E1': place_bram18, - #'RAMBFIFO36E1': place_bram36, - }[site_type]() + verilog.instance(modname, 'inst_%u' % loci, ports, params=params) - verilog.instance(modname, 'inst_%u' % loci, ports, params=params) + j = {'module': modname, 'i': loci, 'params': params} + f.write('%s\n' % (json.dumps(j))) + print('') - j = {'module': modname, 'i': loci, 'params': params} - f.write('%s\n' % (json.dumps(j))) + f.close() + print( + '''endmodule + + // --------------------------------------------------------------------- + + ''') + + # RAMB18E1 + print( + ''' + module my_RAMB18E1 (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter IS_CLKARDCLK_INVERTED = 1'b0; + parameter IS_CLKBWRCLK_INVERTED = 1'b0; + parameter IS_ENARDEN_INVERTED = 1'b0; + parameter IS_ENBWREN_INVERTED = 1'b0; + parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0; + parameter IS_RSTRAMB_INVERTED = 1'b0; + parameter IS_RSTREGARSTREG_INVERTED = 1'b0; + parameter IS_RSTREGB_INVERTED = 1'b0; + parameter RAM_MODE = "TDP"; + parameter WRITE_MODE_A = "WRITE_FIRST"; + parameter WRITE_MODE_B = "WRITE_FIRST"; + parameter RDADDR_COLLISION_HWCONFIG = "DELAYED_WRITE"; + parameter RSTREG_PRIORITY_A = "RSTREG"; + parameter RSTREG_PRIORITY_B = "RSTREG"; + + parameter DOA_REG = 1'b0; + parameter DOB_REG = 1'b0; + parameter SRVAL_A = 18'b0; + parameter SRVAL_B = 18'b0; + parameter INIT_A = 18'b0; + parameter INIT_B = 18'b0; + + parameter READ_WIDTH_A = 0; + parameter READ_WIDTH_B = 0; + parameter WRITE_WIDTH_A = 0; + parameter WRITE_WIDTH_B = 0; + ''') + print('''\ + (* LOC=LOC *) + RAMB18E1 #(''') + for i in range(8): + print(" .INITP_%02X(256'b0)," % (i, )) print('') + for i in range(0x40): + print(" .INIT_%02X(256'b0)," % (i, )) + print('') + print( + ''' + .IS_CLKARDCLK_INVERTED(IS_CLKARDCLK_INVERTED), + .IS_CLKBWRCLK_INVERTED(IS_CLKBWRCLK_INVERTED), + .IS_ENARDEN_INVERTED(IS_ENARDEN_INVERTED), + .IS_ENBWREN_INVERTED(IS_ENBWREN_INVERTED), + .IS_RSTRAMARSTRAM_INVERTED(IS_RSTRAMARSTRAM_INVERTED), + .IS_RSTRAMB_INVERTED(IS_RSTRAMB_INVERTED), + .IS_RSTREGARSTREG_INVERTED(IS_RSTREGARSTREG_INVERTED), + .IS_RSTREGB_INVERTED(IS_RSTREGB_INVERTED), + .RAM_MODE(RAM_MODE), + .WRITE_MODE_A(WRITE_MODE_A), + .WRITE_MODE_B(WRITE_MODE_B), -f.close() -print( - '''endmodule + .DOA_REG(DOA_REG), + .DOB_REG(DOB_REG), + .SRVAL_A(SRVAL_A), + .SRVAL_B(SRVAL_B), + .INIT_A(INIT_A), + .INIT_B(INIT_B), -// --------------------------------------------------------------------- + .READ_WIDTH_A(READ_WIDTH_A), + .READ_WIDTH_B(READ_WIDTH_B), + .WRITE_WIDTH_A(WRITE_WIDTH_A), + .WRITE_WIDTH_B(WRITE_WIDTH_B), -''') + .RDADDR_COLLISION_HWCONFIG(RDADDR_COLLISION_HWCONFIG), -# RAMB18E1 -print( - ''' -module my_RAMB18E1 (input clk, input [7:0] din, output [7:0] dout); - parameter LOC = ""; - parameter IS_CLKARDCLK_INVERTED = 1'b0; - parameter IS_CLKBWRCLK_INVERTED = 1'b0; - parameter IS_ENARDEN_INVERTED = 1'b0; - parameter IS_ENBWREN_INVERTED = 1'b0; - parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0; - parameter IS_RSTRAMB_INVERTED = 1'b0; - parameter IS_RSTREGARSTREG_INVERTED = 1'b0; - parameter IS_RSTREGB_INVERTED = 1'b0; - parameter RAM_MODE = "TDP"; - parameter WRITE_MODE_A = "WRITE_FIRST"; - parameter WRITE_MODE_B = "WRITE_FIRST"; - - parameter DOA_REG = 1'b0; - parameter DOB_REG = 1'b0; - parameter SRVAL_A = 18'b0; - parameter SRVAL_B = 18'b0; - parameter INIT_A = 18'b0; - parameter INIT_B = 18'b0; - - parameter READ_WIDTH_A = 0; - parameter READ_WIDTH_B = 0; - parameter WRITE_WIDTH_A = 0; - parameter WRITE_WIDTH_B = 0; + .RSTREG_PRIORITY_A(RSTREG_PRIORITY_A), + .RSTREG_PRIORITY_B(RSTREG_PRIORITY_B) + ) ram ( + .CLKARDCLK(din[0]), + .CLKBWRCLK(din[1]), + .ENARDEN(din[2]), + .ENBWREN(din[3]), + .REGCEAREGCE(din[4]), + .REGCEB(din[5]), + .RSTRAMARSTRAM(din[6]), + .RSTRAMB(din[7]), + .RSTREGARSTREG(din[0]), + .RSTREGB(din[1]), + .ADDRARDADDR(din[2]), + .ADDRBWRADDR(din[3]), + .DIADI(din[4]), + .DIBDI(din[5]), + .DIPADIP(din[6]), + .DIPBDIP(din[7]), + .WEA(din[0]), + .WEBWE(din[1]), + .DOADO(dout[0]), + .DOBDO(dout[1]), + .DOPADOP(dout[2]), + .DOPBDOP(dout[3])); + endmodule ''') -print('''\ - (* LOC=LOC *) - RAMB18E1 #(''') -for i in range(8): - print(" .INITP_%02X(256'b0)," % (i, )) -print('') -for i in range(0x40): - print(" .INIT_%02X(256'b0)," % (i, )) -print('') -print( - ''' - .IS_CLKARDCLK_INVERTED(IS_CLKARDCLK_INVERTED), - .IS_CLKBWRCLK_INVERTED(IS_CLKBWRCLK_INVERTED), - .IS_ENARDEN_INVERTED(IS_ENARDEN_INVERTED), - .IS_ENBWREN_INVERTED(IS_ENBWREN_INVERTED), - .IS_RSTRAMARSTRAM_INVERTED(IS_RSTRAMARSTRAM_INVERTED), - .IS_RSTRAMB_INVERTED(IS_RSTRAMB_INVERTED), - .IS_RSTREGARSTREG_INVERTED(IS_RSTREGARSTREG_INVERTED), - .IS_RSTREGB_INVERTED(IS_RSTREGB_INVERTED), - .RAM_MODE(RAM_MODE), - .WRITE_MODE_A(WRITE_MODE_A), - .WRITE_MODE_B(WRITE_MODE_B), - .DOA_REG(DOA_REG), - .DOB_REG(DOB_REG), - .SRVAL_A(SRVAL_A), - .SRVAL_B(SRVAL_B), - .INIT_A(INIT_A), - .INIT_B(INIT_B), - .READ_WIDTH_A(READ_WIDTH_A), - .READ_WIDTH_B(READ_WIDTH_B), - .WRITE_WIDTH_A(WRITE_WIDTH_A), - .WRITE_WIDTH_B(WRITE_WIDTH_B) - ) ram ( - .CLKARDCLK(din[0]), - .CLKBWRCLK(din[1]), - .ENARDEN(din[2]), - .ENBWREN(din[3]), - .REGCEAREGCE(din[4]), - .REGCEB(din[5]), - .RSTRAMARSTRAM(din[6]), - .RSTRAMB(din[7]), - .RSTREGARSTREG(din[0]), - .RSTREGB(din[1]), - .ADDRARDADDR(din[2]), - .ADDRBWRADDR(din[3]), - .DIADI(din[4]), - .DIBDI(din[5]), - .DIPADIP(din[6]), - .DIPBDIP(din[7]), - .WEA(din[0]), - .WEBWE(din[1]), - .DOADO(dout[0]), - .DOBDO(dout[1]), - .DOPADOP(dout[2]), - .DOPBDOP(dout[3])); -endmodule -''') - -print( - ''' - -module my_RAMB36E1 (input clk, input [7:0] din, output [7:0] dout); - parameter LOC = ""; - parameter IS_CLKARDCLK_INVERTED = 1'b0; - parameter IS_CLKBWRCLK_INVERTED = 1'b0; - parameter IS_ENARDEN_INVERTED = 1'b0; - parameter IS_ENBWREN_INVERTED = 1'b0; - parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0; - parameter IS_RSTRAMB_INVERTED = 1'b0; - parameter IS_RSTREGARSTREG_INVERTED = 1'b0; - parameter IS_RSTREGB_INVERTED = 1'b0; - parameter RAM_MODE = "TDP"; - parameter WRITE_MODE_A = "WRITE_FIRST"; - parameter WRITE_MODE_B = "WRITE_FIRST"; - - ''') -print('') -print('''\ - (* LOC=LOC *) - RAMB36E1 #(''') -for i in range(16): - print(" .INITP_%02X(256'b0)," % (i, )) -print('') -for i in range(0x80): - print(" .INIT_%02X(256'b0)," % (i, )) -print('') -print( - ''' - .IS_CLKARDCLK_INVERTED(IS_CLKARDCLK_INVERTED), - .IS_CLKBWRCLK_INVERTED(IS_CLKBWRCLK_INVERTED), - .IS_ENARDEN_INVERTED(IS_ENARDEN_INVERTED), - .IS_ENBWREN_INVERTED(IS_ENBWREN_INVERTED), - .IS_RSTRAMARSTRAM_INVERTED(IS_RSTRAMARSTRAM_INVERTED), - .IS_RSTRAMB_INVERTED(IS_RSTRAMB_INVERTED), - .IS_RSTREGARSTREG_INVERTED(IS_RSTREGARSTREG_INVERTED), - .IS_RSTREGB_INVERTED(IS_RSTREGB_INVERTED), - .RAM_MODE(RAM_MODE), - .WRITE_MODE_A(WRITE_MODE_A), - .WRITE_MODE_B(WRITE_MODE_B) - ) ram ( - .CLKARDCLK(din[0]), - .CLKBWRCLK(din[1]), - .ENARDEN(din[2]), - .ENBWREN(din[3]), - .REGCEAREGCE(din[4]), - .REGCEB(din[5]), - .RSTRAMARSTRAM(din[6]), - .RSTRAMB(din[7]), - .RSTREGARSTREG(din[0]), - .RSTREGB(din[1]), - .ADDRARDADDR(din[2]), - .ADDRBWRADDR(din[3]), - .DIADI(din[4]), - .DIBDI(din[5]), - .DIPADIP(din[6]), - .DIPBDIP(din[7]), - .WEA(din[0]), - .WEBWE(din[1]), - .DOADO(dout[0]), - .DOBDO(dout[1]), - .DOPADOP(dout[2]), - .DOPBDOP(dout[3])); -endmodule -''') +if __name__ == "__main__": + main() diff --git a/fuzzers/027-bram36-config/Makefile b/fuzzers/027-bram36-config/Makefile new file mode 100644 index 00000000..33d1cf14 --- /dev/null +++ b/fuzzers/027-bram36-config/Makefile @@ -0,0 +1,22 @@ +# read/write width is relatively slow to resolve +# Even slower with multi bit masks... +N ?= 2 + +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)) + +build/segbits_bramx.db: build/segbits_bramx.rdb + ${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --seg-fn-in $^ --seg-fn-out $@ + ${XRAY_MASKMERGE} build/mask_bramx.db $(addsuffix /segdata_bram_[lr].txt,$(SPECIMENS)) + +pushdb: + ${XRAY_MERGEDB} bram_l build/segbits_bramx.db + ${XRAY_MERGEDB} bram_r build/segbits_bramx.db + ${XRAY_MERGEDB} mask_bram_l build/mask_bramx.db + ${XRAY_MERGEDB} mask_bram_r build/mask_bramx.db + +.PHONY: database pushdb diff --git a/fuzzers/027-bram36-config/bits.dbf b/fuzzers/027-bram36-config/bits.dbf new file mode 100644 index 00000000..75770b57 --- /dev/null +++ b/fuzzers/027-bram36-config/bits.dbf @@ -0,0 +1,5 @@ +# Y0 +27_188,BRAM.RAMB36.RAM_EXTENSION_A_NONE_OR_UPPER + +# Y1 +27_187,BRAM.RAMB36.RAM_EXTENSION_B_NONE_OR_UPPER diff --git a/fuzzers/027-bram36-config/generate.py b/fuzzers/027-bram36-config/generate.py new file mode 100644 index 00000000..fb76f130 --- /dev/null +++ b/fuzzers/027-bram36-config/generate.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 + +import json + +from prjxray.segmaker import Segmaker + + +def write_ram_ext_tags(segmk, tile_param): + for param in ["RAM_EXTENSION_A", "RAM_EXTENSION_B"]: + set_val = tile_param[param] + for opt in ["LOWER"]: + segmk.add_site_tag( + tile_param['site'], "{}_{}".format(param, opt), set_val == opt) + segmk.add_site_tag( + tile_param['site'], "{}_NONE_OR_UPPER".format(param, opt), + set_val != "LOWER") + + +def main(): + segmk = Segmaker("design.bits") + + print("Loading tags") + with open('params.json') as f: + params = json.load(f) + + for tile_param in params: + write_ram_ext_tags(segmk, tile_param) + + 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']) + + segmk.compile() + segmk.write() + + +if __name__ == '__main__': + main() diff --git a/fuzzers/027-bram36-config/generate.tcl b/fuzzers/027-bram36-config/generate.tcl new file mode 100644 index 00000000..ae41001f --- /dev/null +++ b/fuzzers/027-bram36-config/generate.tcl @@ -0,0 +1,25 @@ +proc run {} { + create_project -force -part $::env(XRAY_PART) design design + read_verilog top.v + synth_design -top top + + set_property CFGBVS VCCO [current_design] + set_property CONFIG_VOLTAGE 3.3 [current_design] + set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] + set_property IS_ENABLED 0 [get_drc_checks {PDCN-137}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-191}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-192}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-193}] + set_property IS_ENABLED 0 [get_drc_checks {REQP-194}] + set_property IS_ENABLED 0 [get_drc_checks {AVAL-94}] + set_property IS_ENABLED 0 [get_drc_checks {AVAL-95}] + set_property IS_ENABLED 0 [get_drc_checks {PDCN-1576}] + + place_design + route_design + + write_checkpoint -force design.dcp + write_bitstream -force design.bit +} + +run diff --git a/fuzzers/027-bram36-config/top.py b/fuzzers/027-bram36-config/top.py new file mode 100644 index 00000000..32d9cdc7 --- /dev/null +++ b/fuzzers/027-bram36-config/top.py @@ -0,0 +1,94 @@ +import os +import random +import json +random.seed(int(os.getenv("SEED"), 16)) +from prjxray import util +from prjxray import verilog + + +def gen_bram36(): + for tile_name, site_name, _site_type in util.get_roi().gen_sites( + ['RAMBFIFO36E1']): + yield tile_name, site_name + + +RAM_EXTENSION_OPTS = [ + "NONE", + "LOWER", + "UPPER", +] + + +def main(): + print(''' +module top(); + ''') + + params = [] + for tile_name, site_name in gen_bram36(): + ram_extension_a = random.choice(RAM_EXTENSION_OPTS) + ram_extension_b = random.choice(RAM_EXTENSION_OPTS) + en_ecc_read = random.randint(0, 1) + en_ecc_write = random.randint(0, 1) + + print( + ''' + (* KEEP, DONT_TOUCH, LOC = "{site}" *) + RAMB36E1 #( + .READ_WIDTH_A(1), + .WRITE_WIDTH_A(1), + .READ_WIDTH_B(1), + .WRITE_WIDTH_B(1), + .RAM_EXTENSION_A({ram_extension_a}), + .RAM_EXTENSION_B({ram_extension_b}), + .EN_ECC_READ({en_ecc_read}), + .EN_ECC_WRITE({en_ecc_write}) + ) bram_{site} ( + .CLKARDCLK(), + .CLKBWRCLK(), + .ENARDEN(), + .ENBWREN(), + .REGCEAREGCE(), + .REGCEB(), + .RSTRAMARSTRAM(), + .RSTRAMB(), + .RSTREGARSTREG(), + .RSTREGB(), + .ADDRARDADDR(), + .ADDRBWRADDR(), + .DIADI(), + .DIBDI(), + .DIPADIP(), + .DIPBDIP(), + .WEA(), + .WEBWE(), + .DOADO(), + .DOBDO(), + .DOPADOP(), + .DOPBDOP()); + '''.format( + site=site_name, + ram_extension_a=verilog.quote(ram_extension_a), + ram_extension_b=verilog.quote(ram_extension_b), + en_ecc_read=en_ecc_read, + en_ecc_write=en_ecc_write, + )) + + params.append( + { + 'tile': tile_name, + 'site': site_name, + 'RAM_EXTENSION_A': ram_extension_a, + 'RAM_EXTENSION_B': ram_extension_b, + 'EN_ECC_READ': en_ecc_read, + 'EN_ECC_WRITE': en_ecc_write, + }) + + print("endmodule") + + with open('params.json', 'w') as f: + json.dump(params, f, indent=2) + + +if __name__ == '__main__': + main()