mirror of https://github.com/openXC7/prjxray.git
Merge pull request #578 from litghost/add_zinv_reg_clk
Add remaining RAMB parameters
This commit is contained in:
commit
a8299c84a3
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
''')
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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()
|
||||||
Loading…
Reference in New Issue