Merge pull request #578 from litghost/add_zinv_reg_clk

Add remaining RAMB parameters
This commit is contained in:
litghost 2019-01-30 08:20:41 -08:00 committed by GitHub
commit a8299c84a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 416 additions and 240 deletions

View File

@ -1,6 +1,6 @@
# read/write width is relatively slow to resolve # read/write width is relatively slow to resolve
# Even slower with multi bit masks... # Even slower with multi bit masks...
N ?= 8 N ?= 10
include ../fuzzer.mk include ../fuzzer.mk

View File

@ -3,10 +3,16 @@
27_43 27_44 27_45,BRAM.RAMB18_Y0.READ_WIDTH_B_1 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_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_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 # Y1
27_285 27_284 27_283,BRAM.RAMB18_Y1.READ_WIDTH_A_1 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_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_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_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

View File

@ -1,17 +1,20 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import json import json
import csv
from prjxray.segmaker import Segmaker from prjxray.segmaker import Segmaker
from prjxray import verilog from prjxray import verilog
from prjxray import segmaker from prjxray import segmaker
def isinv_tags(segmk, ps, site): def isinv_tags(segmk, ps, site, actual_ps):
# all of these bits are inverted # all of these bits are inverted
ks = [ ks = [
('IS_CLKARDCLK_INVERTED', 'ZINV_CLKARDCLK'), ('IS_CLKARDCLK_INVERTED', 'ZINV_CLKARDCLK'),
('IS_CLKBWRCLK_INVERTED', 'ZINV_CLKBWRCLK'), ('IS_CLKBWRCLK_INVERTED', 'ZINV_CLKBWRCLK'),
('IS_REGCLKARDRCLK_INVERTED', 'ZINV_REGCLKARDRCLK'),
('IS_REGCLKB_INVERTED', 'ZINV_REGCLKB'),
('IS_ENARDEN_INVERTED', 'ZINV_ENARDEN'), ('IS_ENARDEN_INVERTED', 'ZINV_ENARDEN'),
('IS_ENBWREN_INVERTED', 'ZINV_ENBWREN'), ('IS_ENBWREN_INVERTED', 'ZINV_ENBWREN'),
('IS_RSTRAMARSTRAM_INVERTED', 'ZINV_RSTRAMARSTRAM'), ('IS_RSTRAMARSTRAM_INVERTED', 'ZINV_RSTRAMARSTRAM'),
@ -19,8 +22,33 @@ def isinv_tags(segmk, ps, site):
('IS_RSTREGARSTREG_INVERTED', 'ZINV_RSTREGARSTREG'), ('IS_RSTREGARSTREG_INVERTED', 'ZINV_RSTREGARSTREG'),
('IS_RSTREGB_INVERTED', 'ZINV_RSTREGB'), ('IS_RSTREGB_INVERTED', 'ZINV_RSTREGB'),
] ]
for param, tagname in ks: 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): 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") 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(): def run():
segmk = Segmaker("design.bits") 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") print("Loading tags")
f = open('params.jl', 'r') f = open('params.jl', 'r')
@ -86,10 +133,12 @@ def run():
assert j['module'] == 'my_RAMB18E1' assert j['module'] == 'my_RAMB18E1'
site = verilog.unquote(ps['LOC']) site = verilog.unquote(ps['LOC'])
isinv_tags(segmk, ps, site) isinv_tags(segmk, ps, site, clk_inverts[site])
bus_tags(segmk, ps, site) bus_tags(segmk, ps, site)
rw_width_tags(segmk, ps, site) rw_width_tags(segmk, ps, site)
write_mode_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): def bitfilter(frame, bit):
# rw_width_tags() aliasing interconnect on large widths # rw_width_tags() aliasing interconnect on large widths

View File

@ -23,3 +23,13 @@ route_design
write_checkpoint -force design.dcp write_checkpoint -force design.dcp
write_bitstream -force design.bit 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

View File

@ -4,7 +4,6 @@ random.seed(int(os.getenv("SEED"), 16))
from prjxray import util from prjxray import util
from prjxray import verilog from prjxray import verilog
from prjxray.verilog import vrandbit, vrandbits from prjxray.verilog import vrandbit, vrandbits
import sys
import json import json
@ -37,256 +36,183 @@ def gen_brams():
yield ('RAMB18E1', site) yield ('RAMB18E1', site)
brams = list(gen_brams()) def place_bram18(site, loci):
DUTN = len(brams) ports = {
DIN_N = DUTN * 8 'clk': 'clk',
DOUT_N = DUTN * 8 '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') # Datasheet says 72 is legal in some cases, but think its a copy paste error from BRAM36
f.write('module,loc,params\n') # also 0 and 36 aren't real sizes
print( # Bias choice to 18 as its needed to solve certain bits quickly
'module roi(input clk, input [%d:0] din, output [%d:0] dout);' % widths = [1, 2, 4, 9, 18, 18, 18, 18]
(DIN_N - 1, DOUT_N - 1)) 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 verilog.top_harness(DIN_N, DOUT_N)
# 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),
}
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))
''' for loci, (site_type, site) in enumerate(brams):
def place_bram36(): modname, ports, params = {
ports = { 'RAMB18E1': place_bram18,
'clk': 'clk', #'RAMBFIFO36E1': place_bram36,
'din': 'din[ %d +: 8]' % (8 * loci, ), }[site_type](site, 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)
'''
modname, ports, params = { verilog.instance(modname, 'inst_%u' % loci, ports, params=params)
'RAMB18E1': place_bram18,
#'RAMBFIFO36E1': place_bram36,
}[site_type]()
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.close()
f.write('%s\n' % (json.dumps(j))) 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('') 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() .DOA_REG(DOA_REG),
print( .DOB_REG(DOB_REG),
'''endmodule .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 .RSTREG_PRIORITY_A(RSTREG_PRIORITY_A),
print( .RSTREG_PRIORITY_B(RSTREG_PRIORITY_B)
''' ) ram (
module my_RAMB18E1 (input clk, input [7:0] din, output [7:0] dout); .CLKARDCLK(din[0]),
parameter LOC = ""; .CLKBWRCLK(din[1]),
parameter IS_CLKARDCLK_INVERTED = 1'b0; .ENARDEN(din[2]),
parameter IS_CLKBWRCLK_INVERTED = 1'b0; .ENBWREN(din[3]),
parameter IS_ENARDEN_INVERTED = 1'b0; .REGCEAREGCE(din[4]),
parameter IS_ENBWREN_INVERTED = 1'b0; .REGCEB(din[5]),
parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0; .RSTRAMARSTRAM(din[6]),
parameter IS_RSTRAMB_INVERTED = 1'b0; .RSTRAMB(din[7]),
parameter IS_RSTREGARSTREG_INVERTED = 1'b0; .RSTREGARSTREG(din[0]),
parameter IS_RSTREGB_INVERTED = 1'b0; .RSTREGB(din[1]),
parameter RAM_MODE = "TDP"; .ADDRARDADDR(din[2]),
parameter WRITE_MODE_A = "WRITE_FIRST"; .ADDRBWRADDR(din[3]),
parameter WRITE_MODE_B = "WRITE_FIRST"; .DIADI(din[4]),
.DIBDI(din[5]),
parameter DOA_REG = 1'b0; .DIPADIP(din[6]),
parameter DOB_REG = 1'b0; .DIPBDIP(din[7]),
parameter SRVAL_A = 18'b0; .WEA(din[0]),
parameter SRVAL_B = 18'b0; .WEBWE(din[1]),
parameter INIT_A = 18'b0; .DOADO(dout[0]),
parameter INIT_B = 18'b0; .DOBDO(dout[1]),
.DOPADOP(dout[2]),
parameter READ_WIDTH_A = 0; .DOPBDOP(dout[3]));
parameter READ_WIDTH_B = 0; endmodule
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),
.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), if __name__ == "__main__":
.READ_WIDTH_B(READ_WIDTH_B), main()
.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
''')

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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()