mirror of https://github.com/openXC7/prjxray.git
Refactor all existing tiles to fuzzer approach.
Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
This commit is contained in:
parent
8cbac3ee7a
commit
6a7acd4b23
|
|
@ -1,6 +1,14 @@
|
|||
FUZDIR=$(shell pwd)
|
||||
BUILD_DIR=$(FUZDIR)/build
|
||||
TILEGRID_TDB_DEPENDENCIES=iob/build/segbits_tilegrid.tdb mmcm/build/segbits_tilegrid.tdb pll/build/segbits_tilegrid.tdb monitor/build/segbits_tilegrid.tdb
|
||||
TILEGRID_TDB_DEPENDENCIES=
|
||||
TILEGRID_TDB_DEPENDENCIES += iob/build/segbits_tilegrid.tdb
|
||||
TILEGRID_TDB_DEPENDENCIES += mmcm/build/segbits_tilegrid.tdb
|
||||
TILEGRID_TDB_DEPENDENCIES += pll/build/segbits_tilegrid.tdb
|
||||
TILEGRID_TDB_DEPENDENCIES += monitor/build/segbits_tilegrid.tdb
|
||||
TILEGRID_TDB_DEPENDENCIES += bram/build/segbits_tilegrid.tdb
|
||||
TILEGRID_TDB_DEPENDENCIES += bram_block/build/segbits_tilegrid.tdb
|
||||
TILEGRID_TDB_DEPENDENCIES += clb/build/segbits_tilegrid.tdb
|
||||
TILEGRID_TDB_DEPENDENCIES += clb_int/build/segbits_tilegrid.tdb
|
||||
GENERATE_FULL_ARGS=
|
||||
|
||||
ifeq (${XRAY_DATABASE}, zynq7)
|
||||
|
|
@ -18,19 +26,15 @@ build/tiles/tiles.txt:
|
|||
|
||||
build/basicdb/tilegrid.json: generate.py build/tiles/tiles.txt
|
||||
mkdir -p build/basicdb
|
||||
cd build && python3 ${FUZDIR}/generate.py --tiles $(FUZDIR)/build/tiles/tiles.txt --out ${BUILD_DIR}/basicdb/tilegrid.json
|
||||
cd build && python3 ${FUZDIR}/generate.py \
|
||||
--tiles $(FUZDIR)/build/tiles/tiles.txt \
|
||||
--out ${BUILD_DIR}/basicdb/tilegrid.json
|
||||
|
||||
build/clb/deltas:
|
||||
bash generate.sh build/clb clb
|
||||
clb/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
||||
cd clb && $(MAKE)
|
||||
|
||||
build/bram/deltas:
|
||||
bash generate.sh build/bram bram
|
||||
|
||||
build/iob/deltas:
|
||||
bash generate.sh build/iob iob
|
||||
|
||||
build/tilegrid_tdb.json: add_tdb.py $(TILEGRID_TDB_DEPENDENCIES)
|
||||
python3 add_tdb.py --fn-in build/basicdb/tilegrid.json --fn-out build/tilegrid_tdb.json
|
||||
clb_int/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
||||
cd clb_int && $(MAKE)
|
||||
|
||||
iob/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
||||
cd iob && $(MAKE)
|
||||
|
|
@ -47,10 +51,21 @@ ps7_int/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
|||
monitor/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
||||
cd monitor && $(MAKE)
|
||||
|
||||
build/tilegrid.json: generate_full.py build/tilegrid_tdb.json build/clb/deltas build/bram/deltas
|
||||
bram/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
||||
cd bram && $(MAKE)
|
||||
|
||||
bram_block/build/segbits_tilegrid.tdb: build/basicdb/tilegrid.json
|
||||
cd bram_block && $(MAKE)
|
||||
|
||||
build/tilegrid_tdb.json: add_tdb.py $(TILEGRID_TDB_DEPENDENCIES)
|
||||
python3 add_tdb.py \
|
||||
--fn-in build/basicdb/tilegrid.json \
|
||||
--fn-out build/tilegrid_tdb.json
|
||||
|
||||
build/tilegrid.json: generate_full.py build/tilegrid_tdb.json
|
||||
cd build && python3 ${FUZDIR}/generate_full.py \
|
||||
--json-in tilegrid_tdb.json --json-out ${BUILD_DIR}/tilegrid.json \
|
||||
--tiles $(FUZDIR)/build/tiles/tiles.txt clb/design_*.delta bram/design_*.delta ${GENERATE_FULL_ARGS}
|
||||
--tiles $(FUZDIR)/build/tiles/tiles.txt ${GENERATE_FULL_ARGS}
|
||||
run:
|
||||
$(MAKE) clean
|
||||
$(MAKE) database
|
||||
|
|
@ -59,10 +74,15 @@ run:
|
|||
|
||||
clean:
|
||||
rm -rf build run.ok
|
||||
cd clb && $(MAKE) clean
|
||||
cd clb_int && $(MAKE) clean
|
||||
cd iob && $(MAKE) clean
|
||||
cd mmcm && $(MAKE) clean
|
||||
cd pll && $(MAKE) clean
|
||||
cd ps7_int && $(MAKE) clean
|
||||
cd bram && $(MAKE) clean
|
||||
cd bram_block && $(MAKE) clean
|
||||
cd monitor && $(MAKE) clean
|
||||
|
||||
.PHONY: database pushdb clean run
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ def run(fn_in, fn_out, verbose=False):
|
|||
# FIXME: generate frames from part file (or equivilent)
|
||||
# See https://github.com/SymbiFlow/prjxray/issues/327
|
||||
# FIXME: generate words from pitch
|
||||
int_frames = 28
|
||||
int_words = 2
|
||||
tdb_fns = [
|
||||
("iob/build/segbits_tilegrid.tdb", 42, 4),
|
||||
# FIXME: height
|
||||
|
|
@ -58,6 +60,10 @@ def run(fn_in, fn_out, verbose=False):
|
|||
# FIXME: height
|
||||
("pll/build/segbits_tilegrid.tdb", 30, 101),
|
||||
("monitor/build/segbits_tilegrid.tdb", 30, 101),
|
||||
("bram/build/segbits_tilegrid.tdb", 28, 10),
|
||||
("bram_block/build/segbits_tilegrid.tdb", 128, 10),
|
||||
("clb/build/segbits_tilegrid.tdb", 36, 2),
|
||||
("clb_int/build/segbits_tilegrid.tdb", int_frames, int_words),
|
||||
]
|
||||
|
||||
for (tdb_fn, frames, words) in tdb_fns:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
N ?= 30
|
||||
GENERATE_ARGS?="--oneval 1 --design params.csv --dword 2 --dframe 1B"
|
||||
include ../fuzzaddr/common.mk
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
source "$::env(XRAY_DIR)/utils/utils.tcl"
|
||||
|
||||
proc run {} {
|
||||
create_project -force -part $::env(XRAY_PART) design design
|
||||
read_verilog top.v
|
||||
synth_design -top top
|
||||
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_00) IOSTANDARD LVCMOS33" [get_ports clk]
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_01) IOSTANDARD LVCMOS33" [get_ports stb]
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_02) IOSTANDARD LVCMOS33" [get_ports di]
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_03) IOSTANDARD LVCMOS33" [get_ports do]
|
||||
|
||||
set_property CFGBVS VCCO [current_design]
|
||||
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
|
||||
|
||||
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_IBUF]
|
||||
|
||||
place_design
|
||||
route_design
|
||||
|
||||
write_checkpoint -force design.dcp
|
||||
write_bitstream -force design.bit
|
||||
}
|
||||
|
||||
run
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
import os
|
||||
import random
|
||||
random.seed(int(os.getenv("SEED"), 16))
|
||||
from prjxray import util
|
||||
from prjxray.db import Database
|
||||
|
||||
|
||||
def gen_sites():
|
||||
db = Database(util.get_db_root())
|
||||
grid = db.grid()
|
||||
for tile_name in grid.tiles():
|
||||
loc = grid.loc_of_tilename(tile_name)
|
||||
gridinfo = grid.gridinfo_at_loc(loc)
|
||||
|
||||
for site_name, site_type in gridinfo.sites.items():
|
||||
if site_type in ['FIFO18E1']:
|
||||
yield tile_name, site_name
|
||||
|
||||
|
||||
def write_params(params):
|
||||
pinstr = 'tile,val,site\n'
|
||||
for tile, (site, val) in sorted(params.items()):
|
||||
pinstr += '%s,%s,%s\n' % (tile, val, site)
|
||||
open('params.csv', 'w').write(pinstr)
|
||||
|
||||
|
||||
def run():
|
||||
print(
|
||||
'''
|
||||
module top(input clk, stb, di, output do);
|
||||
localparam integer DIN_N = 8;
|
||||
localparam integer DOUT_N = 8;
|
||||
|
||||
reg [DIN_N-1:0] din;
|
||||
wire [DOUT_N-1:0] dout;
|
||||
|
||||
reg [DIN_N-1:0] din_shr;
|
||||
reg [DOUT_N-1:0] dout_shr;
|
||||
|
||||
always @(posedge clk) begin
|
||||
din_shr <= {din_shr, di};
|
||||
dout_shr <= {dout_shr, din_shr[DIN_N-1]};
|
||||
if (stb) begin
|
||||
din <= din_shr;
|
||||
dout_shr <= dout;
|
||||
end
|
||||
end
|
||||
|
||||
assign do = dout_shr[DOUT_N-1];
|
||||
''')
|
||||
|
||||
params = {}
|
||||
|
||||
sites = list(gen_sites())
|
||||
for (tile_name, site_name), isone in zip(sites,
|
||||
util.gen_fuzz_states(len(sites))):
|
||||
params[tile_name] = (site_name, isone)
|
||||
|
||||
print(
|
||||
'''
|
||||
(* KEEP, DONT_TOUCH, LOC = "%s" *)
|
||||
RAMB18E1 #(
|
||||
.DOA_REG(%u)
|
||||
) bram_%s (
|
||||
.CLKARDCLK(),
|
||||
.CLKBWRCLK(),
|
||||
.ENARDEN(),
|
||||
.ENBWREN(),
|
||||
.REGCEAREGCE(),
|
||||
.REGCEB(),
|
||||
.RSTRAMARSTRAM(),
|
||||
.RSTRAMB(),
|
||||
.RSTREGARSTREG(),
|
||||
.RSTREGB(),
|
||||
.ADDRARDADDR(),
|
||||
.ADDRBWRADDR(),
|
||||
.DIADI(),
|
||||
.DIBDI(),
|
||||
.DIPADIP(),
|
||||
.DIPBDIP(),
|
||||
.WEA(),
|
||||
.WEBWE(),
|
||||
.DOADO(),
|
||||
.DOBDO(),
|
||||
.DOPADOP(),
|
||||
.DOPBDOP());
|
||||
''' % (site_name, isone, site_name))
|
||||
|
||||
print("endmodule")
|
||||
write_params(params)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
N ?= 30
|
||||
GENERATE_ARGS?="--oneval 1 --design params.csv --dword 0 --dframe 0"
|
||||
include ../fuzzaddr/common.mk
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
source "$::env(XRAY_DIR)/utils/utils.tcl"
|
||||
|
||||
proc run {} {
|
||||
create_project -force -part $::env(XRAY_PART) design design
|
||||
read_verilog top.v
|
||||
synth_design -top top
|
||||
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_00) IOSTANDARD LVCMOS33" [get_ports clk]
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_01) IOSTANDARD LVCMOS33" [get_ports stb]
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_02) IOSTANDARD LVCMOS33" [get_ports di]
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_03) IOSTANDARD LVCMOS33" [get_ports do]
|
||||
|
||||
set_property CFGBVS VCCO [current_design]
|
||||
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
|
||||
|
||||
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_IBUF]
|
||||
|
||||
place_design
|
||||
route_design
|
||||
|
||||
write_checkpoint -force design.dcp
|
||||
write_bitstream -force design.bit
|
||||
}
|
||||
|
||||
run
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
import os
|
||||
import random
|
||||
random.seed(int(os.getenv("SEED"), 16))
|
||||
from prjxray import util
|
||||
from prjxray.db import Database
|
||||
|
||||
|
||||
def gen_sites():
|
||||
db = Database(util.get_db_root())
|
||||
grid = db.grid()
|
||||
for tile_name in grid.tiles():
|
||||
loc = grid.loc_of_tilename(tile_name)
|
||||
gridinfo = grid.gridinfo_at_loc(loc)
|
||||
|
||||
for site_name, site_type in gridinfo.sites.items():
|
||||
if site_type in ['RAMBFIFO36E1']:
|
||||
yield tile_name, site_name
|
||||
|
||||
|
||||
def write_params(params):
|
||||
pinstr = 'tile,val,site\n'
|
||||
for tile, (site, val) in sorted(params.items()):
|
||||
pinstr += '%s,%s,%s\n' % (tile, val, site)
|
||||
open('params.csv', 'w').write(pinstr)
|
||||
|
||||
|
||||
def run():
|
||||
print(
|
||||
'''
|
||||
module top(input clk, stb, di, output do);
|
||||
localparam integer DIN_N = 8;
|
||||
localparam integer DOUT_N = 8;
|
||||
|
||||
reg [DIN_N-1:0] din;
|
||||
wire [DOUT_N-1:0] dout;
|
||||
|
||||
reg [DIN_N-1:0] din_shr;
|
||||
reg [DOUT_N-1:0] dout_shr;
|
||||
|
||||
always @(posedge clk) begin
|
||||
din_shr <= {din_shr, di};
|
||||
dout_shr <= {dout_shr, din_shr[DIN_N-1]};
|
||||
if (stb) begin
|
||||
din <= din_shr;
|
||||
dout_shr <= dout;
|
||||
end
|
||||
end
|
||||
|
||||
assign do = dout_shr[DOUT_N-1];
|
||||
''')
|
||||
|
||||
params = {}
|
||||
|
||||
sites = list(gen_sites())
|
||||
for (tile_name, site_name), isone in zip(sites,
|
||||
util.gen_fuzz_states(len(sites))):
|
||||
params[tile_name] = (site_name, isone)
|
||||
|
||||
print(
|
||||
'''
|
||||
(* KEEP, DONT_TOUCH, LOC = "%s" *)
|
||||
RAMB36E1 #(
|
||||
.INIT_00(256'b%u)
|
||||
) bram_%s (
|
||||
.CLKARDCLK(),
|
||||
.CLKBWRCLK(),
|
||||
.ENARDEN(),
|
||||
.ENBWREN(),
|
||||
.REGCEAREGCE(),
|
||||
.REGCEB(),
|
||||
.RSTRAMARSTRAM(),
|
||||
.RSTRAMB(),
|
||||
.RSTREGARSTREG(),
|
||||
.RSTREGB(),
|
||||
.ADDRARDADDR(),
|
||||
.ADDRBWRADDR(),
|
||||
.DIADI(),
|
||||
.DIBDI(),
|
||||
.DIPADIP(),
|
||||
.DIPBDIP(),
|
||||
.WEA(),
|
||||
.WEBWE(),
|
||||
.DOADO(),
|
||||
.DOBDO(),
|
||||
.DOPADOP(),
|
||||
.DOPBDOP());
|
||||
''' % (site_name, isone, site_name))
|
||||
|
||||
print("endmodule")
|
||||
write_params(params)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
N ?= 30
|
||||
GENERATE_ARGS?="--oneval 1 --design params.csv --dword 0 --dframe 0"
|
||||
include ../fuzzaddr/common.mk
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
source "$::env(XRAY_DIR)/utils/utils.tcl"
|
||||
|
||||
proc run {} {
|
||||
create_project -force -part $::env(XRAY_PART) design design
|
||||
read_verilog top.v
|
||||
synth_design -top top
|
||||
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_00) IOSTANDARD LVCMOS33" [get_ports clk]
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_01) IOSTANDARD LVCMOS33" [get_ports stb]
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_02) IOSTANDARD LVCMOS33" [get_ports di]
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_03) IOSTANDARD LVCMOS33" [get_ports do]
|
||||
|
||||
set_property CFGBVS VCCO [current_design]
|
||||
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
|
||||
|
||||
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_IBUF]
|
||||
|
||||
place_design
|
||||
route_design
|
||||
|
||||
write_checkpoint -force design.dcp
|
||||
write_bitstream -force design.bit
|
||||
}
|
||||
|
||||
run
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
import os
|
||||
import random
|
||||
random.seed(int(os.getenv("SEED"), 16))
|
||||
from prjxray import util
|
||||
from prjxray.db import Database
|
||||
|
||||
|
||||
def gen_sites():
|
||||
db = Database(util.get_db_root())
|
||||
grid = db.grid()
|
||||
for tile_name in grid.tiles():
|
||||
loc = grid.loc_of_tilename(tile_name)
|
||||
gridinfo = grid.gridinfo_at_loc(loc)
|
||||
if gridinfo.tile_type in ['CLBLL_L', 'CLBLL_R', 'CLBLM_L', 'CLBLM_R']:
|
||||
site_name = sorted(gridinfo.sites.keys())[0]
|
||||
yield tile_name, site_name
|
||||
|
||||
|
||||
def write_params(params):
|
||||
pinstr = 'tile,val,site\n'
|
||||
for tile, (site, val) in sorted(params.items()):
|
||||
pinstr += '%s,%s,%s\n' % (tile, val, site)
|
||||
open('params.csv', 'w').write(pinstr)
|
||||
|
||||
|
||||
def run():
|
||||
print(
|
||||
'''
|
||||
module top(input clk, stb, di, output do);
|
||||
localparam integer DIN_N = 8;
|
||||
localparam integer DOUT_N = 8;
|
||||
|
||||
reg [DIN_N-1:0] din;
|
||||
wire [DOUT_N-1:0] dout;
|
||||
|
||||
reg [DIN_N-1:0] din_shr;
|
||||
reg [DOUT_N-1:0] dout_shr;
|
||||
|
||||
always @(posedge clk) begin
|
||||
din_shr <= {din_shr, di};
|
||||
dout_shr <= {dout_shr, din_shr[DIN_N-1]};
|
||||
if (stb) begin
|
||||
din <= din_shr;
|
||||
dout_shr <= dout;
|
||||
end
|
||||
end
|
||||
|
||||
assign do = dout_shr[DOUT_N-1];
|
||||
''')
|
||||
|
||||
params = {}
|
||||
|
||||
sites = list(gen_sites())
|
||||
for (tile_name, site_name), isone in zip(sites,
|
||||
util.gen_fuzz_states(len(sites))):
|
||||
params[tile_name] = (site_name, isone)
|
||||
|
||||
print(
|
||||
'''
|
||||
(* KEEP, DONT_TOUCH, LOC = "%s" *)
|
||||
CARRY4 carry4_%s (
|
||||
.CYINIT(%u));
|
||||
''' % (site_name, site_name, isone))
|
||||
|
||||
print("endmodule")
|
||||
write_params(params)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
N ?= 30
|
||||
GENERATE_ARGS?="--oneval 0 --design params.csv --dword 1 --dframe 15"
|
||||
include ../fuzzaddr/common.mk
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
source "$::env(XRAY_DIR)/utils/utils.tcl"
|
||||
|
||||
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]
|
||||
|
||||
place_design
|
||||
route_design
|
||||
|
||||
write_checkpoint -force design.dcp
|
||||
write_bitstream -force design.bit
|
||||
}
|
||||
|
||||
run
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
import os
|
||||
import random
|
||||
random.seed(int(os.getenv("SEED"), 16))
|
||||
from prjxray import util
|
||||
from prjxray.db import Database
|
||||
|
||||
|
||||
def gen_sites():
|
||||
db = Database(util.get_db_root())
|
||||
grid = db.grid()
|
||||
for tile_name in grid.tiles():
|
||||
loc = grid.loc_of_tilename(tile_name)
|
||||
gridinfo = grid.gridinfo_at_loc(loc)
|
||||
if gridinfo.tile_type in ['CLBLL_L', 'CLBLL_R', 'CLBLM_L', 'CLBLM_R']:
|
||||
site_name = sorted(gridinfo.sites.keys())[0]
|
||||
if gridinfo.tile_type[-1] == 'L':
|
||||
int_tile_loc = (loc.grid_x + 1, loc.grid_y)
|
||||
else:
|
||||
int_tile_loc = (loc.grid_x - 1, loc.grid_y)
|
||||
|
||||
int_tile_name = grid.tilename_at_loc(int_tile_loc)
|
||||
|
||||
if not int_tile_name.startswith('INT_'):
|
||||
continue
|
||||
|
||||
yield int_tile_name, site_name
|
||||
|
||||
|
||||
def write_params(params):
|
||||
pinstr = 'tile,val\n'
|
||||
for tile, (site, val) in sorted(params.items()):
|
||||
pinstr += '%s,%s,%s\n' % (tile, val, site)
|
||||
open('params.csv', 'w').write(pinstr)
|
||||
|
||||
|
||||
def run():
|
||||
print(
|
||||
'''
|
||||
module top();
|
||||
''')
|
||||
|
||||
params = {}
|
||||
|
||||
sites = sorted(list(gen_sites()))
|
||||
for (tile_name, site_name), isone in zip(sites,
|
||||
util.gen_fuzz_states(len(sites))):
|
||||
params[tile_name] = (site_name, isone)
|
||||
|
||||
print(
|
||||
'''
|
||||
wire lut_to_f7_{0}, f7_to_f8_{0};
|
||||
(* KEEP, DONT_TOUCH, LOC = "{0}" *)
|
||||
LUT6_L #(
|
||||
.INIT(0)
|
||||
) lut_rom_{0} (
|
||||
.I0(1),
|
||||
.I1({1}),
|
||||
.I2(0),
|
||||
.I3(1),
|
||||
.I4(1),
|
||||
.I5(1),
|
||||
.LO(lut_to_f7_{0})
|
||||
);
|
||||
(* KEEP, DONT_TOUCH, LOC = "{0}" *)
|
||||
MUXF7_L f7_{0} (
|
||||
.I0(lut_to_f7_{0}),
|
||||
.LO(f7_to_f8_{0})
|
||||
);
|
||||
(* KEEP, DONT_TOUCH, LOC = "{0}" *)
|
||||
MUXF8 f8_{0} (
|
||||
.I0(f7_to_f8_{0})
|
||||
);
|
||||
''' .format(site_name, isone))
|
||||
|
||||
print("endmodule")
|
||||
write_params(params)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, sys, json, re
|
||||
|
||||
from utils import xjson
|
||||
|
||||
|
||||
|
|
@ -64,7 +62,6 @@ def run(tiles_fn, json_fn, verbose=False):
|
|||
|
||||
def main():
|
||||
import argparse
|
||||
import glob
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Generate tilegrid.json from bitstream deltas')
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
source "$::env(FUZDIR)/util.tcl"
|
||||
|
||||
# Return a list of sites containing BRAMs
|
||||
# sites are better than bels because site type may change and invalidate the bel
|
||||
proc loc_brams {} {
|
||||
# BRAM have multiple mutually exclusive sites
|
||||
# They can be cycled by setting the site type
|
||||
# Ex:
|
||||
# - RAMB36_X0Y10/RAMBFIFO36E1
|
||||
# - RAMB36_X0Y10/RAMB36E1
|
||||
# Default is RAMBFIFO36E1?
|
||||
# Work primarily on sites, not bels,
|
||||
# to avoid issues when switching site type during PnR
|
||||
set bram_sites [get_sites -of_objects [get_pblocks roi] -filter {SITE_TYPE =~ RAMBFIFO36E1*}]
|
||||
set bram_bels [get_bels -of_objects $bram_sites]
|
||||
|
||||
set bram_columns [group_dut_cols $bram_bels 10]
|
||||
# Output site, not bel, to avoid reference issues after PnR
|
||||
return [loc_dut_col_sites $bram_columns {roi/brams[} {].bram}]
|
||||
}
|
||||
|
||||
proc write_brams { selected_brams_sites } {
|
||||
puts "write_brams: [llength $selected_brams_sites] BRAMs"
|
||||
puts ""
|
||||
# Toggle one bit in each selected BRAM to generate base addresses
|
||||
for {set i 0} {$i < [llength $selected_brams_sites]} {incr i} {
|
||||
puts ""
|
||||
set cell [get_cells roi/brams[$i].bram]
|
||||
puts "BRAM $cell"
|
||||
set orig_init [get_property INIT_00 $cell]
|
||||
# Flip a bit by changing MSB 0 => 1
|
||||
set new_init [regsub "h8" $orig_init "h0"]
|
||||
puts "INIT_00 $orig_init => $new_init"
|
||||
set_property INIT_00 $new_init $cell
|
||||
set site [lindex $selected_brams_sites $i]
|
||||
if {"$site" == ""} {error "Bad site $site"}
|
||||
write_bitstream -force design_$site.bit
|
||||
set_property INIT_00 $orig_init $cell
|
||||
}
|
||||
}
|
||||
|
||||
proc run {} {
|
||||
make_project
|
||||
set selected_brams_sites [loc_brams]
|
||||
puts "Selected BRAMs: [llength $selected_brams_sites]"
|
||||
|
||||
place_design
|
||||
route_design
|
||||
write_checkpoint -force design.dcp
|
||||
write_bitstream -force design.bit
|
||||
|
||||
write_brams $selected_brams_sites
|
||||
}
|
||||
|
||||
run
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
source "$::env(FUZDIR)/util.tcl"
|
||||
|
||||
proc group_lut_cols { lut_bels } {
|
||||
# LOC one LUT (a "selected_lut") into each CLB segment configuration column (ie 50 per CMT column)
|
||||
set lut_columns ""
|
||||
foreach lut $lut_bels {
|
||||
regexp "SLICE_X([0-9]+)Y([0-9]+)/" $lut match slice_x slice_y
|
||||
|
||||
# Only even SLICEs should be used as column bases.
|
||||
if { $slice_x % 2 != 0 } {
|
||||
continue
|
||||
}
|
||||
|
||||
# 50 per column => 0, 50, 100, 150, etc
|
||||
# ex: SLICE_X2Y50/A6LUT
|
||||
# Only take one of the CLBs within a slice
|
||||
set y_column [expr ($slice_y / 50) * 50]
|
||||
dict append lut_columns "X${slice_x}Y${y_column}" "$lut "
|
||||
}
|
||||
return $lut_columns
|
||||
}
|
||||
|
||||
proc loc_luts {} {
|
||||
set lut_bels [get_bels -of_objects [get_sites -of_objects [get_pblocks roi]] -filter {TYPE =~ LUT*} */A6LUT]
|
||||
set lut_columns [group_lut_cols $lut_bels]
|
||||
return [loc_dut_col_bels $lut_columns {roi/luts[} {].lut}]
|
||||
}
|
||||
|
||||
proc write_clbs { selected_luts } {
|
||||
puts "write_brams: [llength $selected_luts] LUTs"
|
||||
puts ""
|
||||
# Toggle one bit in each selected LUT to generate base addresses
|
||||
for {set i 0} {$i < [llength $selected_luts]} {incr i} {
|
||||
puts ""
|
||||
set cell [get_cells roi/luts[$i].lut]
|
||||
puts "LUT $cell"
|
||||
set orig_init [get_property INIT $cell]
|
||||
# Flip a bit by changing MSB 0 => 1
|
||||
set new_init [regsub "h8" $orig_init "h0"]
|
||||
puts "INIT $orig_init => $new_init"
|
||||
set_property INIT $new_init $cell
|
||||
set site [get_sites -of_objects [lindex $selected_luts $i]]
|
||||
write_bitstream -force design_$site.bit
|
||||
set_property INIT $orig_init $cell
|
||||
}
|
||||
}
|
||||
|
||||
proc run {} {
|
||||
make_project
|
||||
set selected_luts [loc_luts]
|
||||
puts "Selected LUTs: [llength $selected_luts]"
|
||||
|
||||
place_design
|
||||
route_design
|
||||
write_checkpoint -force design.dcp
|
||||
write_bitstream -force design.bit
|
||||
|
||||
write_clbs $selected_luts
|
||||
}
|
||||
|
||||
run
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
import os, sys, json, re
|
||||
from __future__ import print_function
|
||||
import sys, json
|
||||
from utils import xjson
|
||||
'''
|
||||
Historically we grouped data into "segments"
|
||||
These were a region of the bitstream that encoded one or more tiles
|
||||
|
|
@ -11,7 +13,6 @@ A post processing step verifies that two tiles don't reference the same bitstrea
|
|||
'''
|
||||
|
||||
from generate import load_tiles
|
||||
from prjxray import util
|
||||
import util as localutil
|
||||
|
||||
|
||||
|
|
@ -28,22 +29,6 @@ def nolr(tile_type):
|
|||
return tile_type
|
||||
|
||||
|
||||
def load_baseaddrs(deltas_fns):
|
||||
site_baseaddr = dict()
|
||||
for arg in deltas_fns:
|
||||
with open(arg) as f:
|
||||
line = f.read().strip()
|
||||
# clb/design_SLICE_X10Y100.delta
|
||||
# site = arg[7:-6]
|
||||
site = re.match(r".*/design_(.*).delta", arg).group(1)
|
||||
# +bit_00400026_100_02
|
||||
_, frame_str, _, _ = line.split('_')
|
||||
frame = int(frame_str, 16)
|
||||
site_baseaddr[site] = frame & ~0x7f
|
||||
|
||||
return site_baseaddr
|
||||
|
||||
|
||||
def load_tdb_baseaddr(database, int_tdb, verbose=False):
|
||||
tdb_tile_baseaddrs = dict()
|
||||
for line in open(int_tdb, 'r'):
|
||||
|
|
@ -64,27 +49,6 @@ def load_tdb_baseaddr(database, int_tdb, verbose=False):
|
|||
return tdb_tile_baseaddrs
|
||||
|
||||
|
||||
def make_tile_baseaddrs(tiles, site_baseaddr, verbose=False):
|
||||
# Look up a base address by tile name
|
||||
tile_baseaddrs = dict()
|
||||
verbose and print('')
|
||||
verbose and print('%u tiles' % len(tiles))
|
||||
verbose and print("%u baseaddrs" % len(site_baseaddr))
|
||||
added = 0
|
||||
for tile in tiles:
|
||||
for site_name in tile["sites"].keys():
|
||||
if site_name not in site_baseaddr:
|
||||
continue
|
||||
framebaseaddr = site_baseaddr[site_name]
|
||||
localutil.add_baseaddr(
|
||||
tile_baseaddrs, tile["name"], framebaseaddr, verbose)
|
||||
added += 1
|
||||
|
||||
assert added, "Failed to add any base addresses"
|
||||
assert added == len(site_baseaddr)
|
||||
return tile_baseaddrs
|
||||
|
||||
|
||||
def make_tiles_by_grid(tiles):
|
||||
# lookup tile names by (X, Y)
|
||||
tiles_by_grid = dict()
|
||||
|
|
@ -94,34 +58,40 @@ def make_tiles_by_grid(tiles):
|
|||
|
||||
return tiles_by_grid
|
||||
|
||||
def add_int_bits(database, tile, baseaddr, offset):
|
||||
"""
|
||||
Add INT bits for given tile.
|
||||
"""
|
||||
if database[tile]['type'] not in ["INT_L", "INT_R"]:
|
||||
return
|
||||
|
||||
def add_segment(
|
||||
database, segments, name, tiles, segtype, verbose, baseaddr=None):
|
||||
assert name not in segments
|
||||
segment = segments.setdefault(name, {})
|
||||
segment["tiles"] = tiles
|
||||
segment["type"] = segtype
|
||||
if baseaddr:
|
||||
verbose and print('make_segment: %s baseaddr %s' % (
|
||||
name,
|
||||
baseaddr,
|
||||
))
|
||||
segment["baseaddr"] = baseaddr
|
||||
localutil.add_tile_bits(
|
||||
tile, database[tile], baseaddr, offset,
|
||||
frames=28, words=2, height=2)
|
||||
|
||||
for tile_name in tiles:
|
||||
database[tile_name]["segment"] = name
|
||||
|
||||
|
||||
def make_segments(database, tiles_by_grid, tile_baseaddrs, verbose=False):
|
||||
def add_adjacent_int_tiles(database, tiles_by_grid, verbose=False):
|
||||
'''
|
||||
Create segments data structure
|
||||
Indicates how tiles are related to bitstream locations
|
||||
Also modify database to annotate which segment the tiles belong to
|
||||
segments key examples:
|
||||
SEG_CLBLM_R_X13Y72
|
||||
SEG_BRAM3_L_X6Y85
|
||||
Attaches INT tiles adjacent to tiles.
|
||||
'''
|
||||
segments = dict()
|
||||
|
||||
def add_int_tile(inttile, parent_tile):
|
||||
if not database[parent_tile]['bits']:
|
||||
return
|
||||
|
||||
grid_x = database[inttile]["grid_x"]
|
||||
grid_y = database[inttile]["grid_y"]
|
||||
|
||||
framebase = int(database[parent_tile]['bits']['CLB_IO_CLK']['baseaddr'], 0)
|
||||
parent_wordbase = database[parent_tile]['bits']['CLB_IO_CLK']['offset']
|
||||
|
||||
for dst_tile, wordbase in localutil.propagate_up_INT(
|
||||
grid_x, grid_y, database, tiles_by_grid, parent_wordbase):
|
||||
dst_x = dst_tile['grid_x']
|
||||
dst_y = dst_tile['grid_y']
|
||||
|
||||
add_int_bits(
|
||||
database, tiles_by_grid[(dst_x, dst_y)], framebase,
|
||||
wordbase)
|
||||
|
||||
verbose and print('')
|
||||
for tile_name, tile_data in database.items():
|
||||
|
|
@ -129,111 +99,42 @@ def make_segments(database, tiles_by_grid, tile_baseaddrs, verbose=False):
|
|||
grid_x = tile_data["grid_x"]
|
||||
grid_y = tile_data["grid_y"]
|
||||
|
||||
def add_segment(tiles, segtype, name=None, baseaddr=None):
|
||||
assert name not in segments
|
||||
segment = segments.setdefault(name, {})
|
||||
segment["tiles"] = tiles
|
||||
segment["type"] = segtype
|
||||
if baseaddr:
|
||||
verbose and print(
|
||||
'make_segment: %s baseaddr %s' % (
|
||||
name,
|
||||
baseaddr,
|
||||
))
|
||||
segment["baseaddr"] = baseaddr
|
||||
|
||||
for tile_name in tiles:
|
||||
database[tile_name]["segment"] = name
|
||||
|
||||
def process_clb():
|
||||
if tile_type in ["CLBLL_L", "CLBLM_L"]:
|
||||
int_tile_name = tiles_by_grid[(grid_x + 1, grid_y)]
|
||||
else:
|
||||
int_tile_name = tiles_by_grid[(grid_x - 1, grid_y)]
|
||||
|
||||
add_segment(
|
||||
name="SEG_" + tile_name,
|
||||
tiles=[tile_name, int_tile_name],
|
||||
segtype=tile_type.lower(),
|
||||
baseaddr=tile_baseaddrs.get(tile_name, None))
|
||||
|
||||
def process_hclk():
|
||||
add_segment(
|
||||
name="SEG_" + tile_name,
|
||||
tiles=[tile_name],
|
||||
segtype=tile_type.lower())
|
||||
add_int_tile(int_tile_name, tile_name)
|
||||
|
||||
def process_iob():
|
||||
tiles = [tile_name]
|
||||
# FIXME mcmaster: removing INT for now
|
||||
# Geometry doesn't line up with CLB, unclear if they are included
|
||||
if tile_type.startswith('LIOB'):
|
||||
# Two INT_L's
|
||||
# tiles.append(tiles_by_grid[(grid_x + 4, grid_y)])
|
||||
# tiles.append(tiles_by_grid[(grid_x + 4, grid_y - 1)])
|
||||
# One IO interface tile
|
||||
tiles.append(tiles_by_grid[(grid_x + 1, grid_y)])
|
||||
#add_int_tile(tiles_by_grid[(grid_x + 4, grid_y)], tile_name)
|
||||
#add_int_tile(tiles_by_grid[(grid_x + 4, grid_y - 1)], tile_name)
|
||||
pass
|
||||
else:
|
||||
# Two INT_R's
|
||||
# tiles.append(tiles_by_grid[(grid_x - 4, grid_y)])
|
||||
# tiles.append(tiles_by_grid[(grid_x - 4, grid_y - 1)])
|
||||
# One IO interface tile
|
||||
tiles.append(tiles_by_grid[(grid_x - 1, grid_y)])
|
||||
|
||||
add_segment(
|
||||
name="SEG_" + tile_name,
|
||||
tiles=tiles,
|
||||
segtype=tile_type.lower(),
|
||||
baseaddr=tile_baseaddrs.get(tile_name, None))
|
||||
#add_int_tile(tiles_by_grid[(grid_x - 4, grid_y)], tile_name)
|
||||
#add_int_tile(tiles_by_grid[(grid_x - 4, grid_y - 1)], tile_name)
|
||||
pass
|
||||
|
||||
def process_iob_sing():
|
||||
# FIXME mcmaster: removing INT for now
|
||||
# Geometry doesn't line up with CLB, unclear if they are included
|
||||
tiles = [tile_name]
|
||||
if tile_type.startswith('LIOB'):
|
||||
tiles.append(tiles_by_grid[(grid_x + 1, grid_y)])
|
||||
# tiles.append(tiles_by_grid[(grid_x + 4, grid_y)])
|
||||
add_int_tile(tiles_by_grid[(grid_x + 4, grid_y)], tile_name)
|
||||
else:
|
||||
tiles.append(tiles_by_grid[(grid_x - 1, grid_y)])
|
||||
# tiles.append(tiles_by_grid[(grid_x - 4, grid_y)])
|
||||
|
||||
add_segment(
|
||||
name="SEG_" + tile_name,
|
||||
tiles=tiles,
|
||||
segtype=tile_type.lower(),
|
||||
baseaddr=tile_baseaddrs.get(tile_name, None))
|
||||
add_int_tile(tiles_by_grid[(grid_x - 4, grid_y)], tile_name)
|
||||
|
||||
def process_bram_dsp():
|
||||
for k in range(5):
|
||||
if tile_type in ["BRAM_L", "DSP_L"]:
|
||||
interface_tile_name = tiles_by_grid[(
|
||||
grid_x + 1, grid_y - k)]
|
||||
int_tile_name = tiles_by_grid[(grid_x + 2, grid_y - k)]
|
||||
elif tile_type in ["BRAM_R", "DSP_R"]:
|
||||
interface_tile_name = tiles_by_grid[(
|
||||
grid_x - 1, grid_y - k)]
|
||||
int_tile_name = tiles_by_grid[(grid_x - 2, grid_y - k)]
|
||||
else:
|
||||
assert 0
|
||||
'''
|
||||
BRAM/DSP itself is at the base y address
|
||||
There is one huge switchbox on the right for the 5 tiles
|
||||
These fan into 5 BRAM_INT_INTERFACE tiles each which feed into their own CENTER_INTER (just like a CLB has)
|
||||
'''
|
||||
if k == 0:
|
||||
tiles = [tile_name, interface_tile_name, int_tile_name]
|
||||
baseaddr = tile_baseaddrs.get(tile_name, None)
|
||||
else:
|
||||
tiles = [interface_tile_name, int_tile_name]
|
||||
baseaddr = None
|
||||
|
||||
add_segment(
|
||||
# BRAM_L_X6Y70 => SEG_BRAM4_L_X6Y70
|
||||
name="SEG_" + tile_name.replace("_", "%d_" % k, 1),
|
||||
tiles=tiles,
|
||||
# BRAM_L => bram4_l
|
||||
segtype=tile_type.lower().replace("_", "%d_" % k, 1),
|
||||
baseaddr=baseaddr)
|
||||
add_int_tile(int_tile_name, tile_name)
|
||||
|
||||
def process_default():
|
||||
verbose and nolr(tile_type) not in (
|
||||
|
|
@ -241,80 +142,20 @@ def make_segments(database, tiles_by_grid, tile_baseaddrs, verbose=False):
|
|||
'make_segment: drop %s' % (tile_type, ))
|
||||
pass
|
||||
|
||||
"""
|
||||
FIXME: review IOB
|
||||
{
|
||||
"CLBLL": process_clb,
|
||||
"CLBLM": process_clb,
|
||||
"HCLK": lambda: None,
|
||||
"BRAM": lambda: None,
|
||||
"DSP": lambda: None,
|
||||
"RIOB33": process_iob,
|
||||
"LIOB33": process_iob,
|
||||
"RIOB33_SING": process_iob_sing,
|
||||
"LIOB33_SING": process_iob_sing,
|
||||
"""
|
||||
{
|
||||
"CLBLL": process_clb,
|
||||
"CLBLM": process_clb,
|
||||
"HCLK": process_hclk,
|
||||
"BRAM": process_bram_dsp,
|
||||
"DSP": process_bram_dsp,
|
||||
}.get(nolr(tile_type), process_default)()
|
||||
|
||||
return segments
|
||||
|
||||
|
||||
def get_inttile(database, segment):
|
||||
'''Return interconnect tile for given segment'''
|
||||
return (
|
||||
tile for tile in segment["tiles"]
|
||||
if database[tile]["type"] in ["INT_L", "INT_R"])
|
||||
|
||||
|
||||
def get_iobtile(database, segment):
|
||||
'''Return IOB tile for given segment'''
|
||||
return (
|
||||
tile for tile in segment["tiles"]
|
||||
if database[tile]["type"] in ["LIOB33_SING", "LIOB33"])
|
||||
|
||||
|
||||
def get_bramtile(database, segment):
|
||||
inttiles = [
|
||||
tile for tile in segment["tiles"]
|
||||
if database[tile]["type"] in ["BRAM_L", "BRAM_R"]
|
||||
]
|
||||
assert len(inttiles) == 1
|
||||
return inttiles[0]
|
||||
|
||||
|
||||
def create_segment_for_int_lr(
|
||||
database, segments, tile, tiles_by_grid, verbose):
|
||||
""" Creates INT_[LR] segment for interconnect's without direct connectivity. """
|
||||
# Some INT_[LR] tiles have no adjacent connectivity, create a segment.
|
||||
grid_x = database[tile]["grid_x"]
|
||||
grid_y = database[tile]["grid_y"]
|
||||
if database[tile]["type"] == "INT_L":
|
||||
grid_x -= 1
|
||||
adjacent_tile = tiles_by_grid[(grid_x, grid_y)]
|
||||
elif database[tile]["type"] == "INT_R":
|
||||
grid_x += 1
|
||||
adjacent_tile = tiles_by_grid[(grid_x, grid_y)]
|
||||
else:
|
||||
assert False, database[tile]["type"]
|
||||
if (database[adjacent_tile]['type'].startswith('INT_INTERFACE_') or
|
||||
database[adjacent_tile]['type'].startswith('PCIE_INT_INTERFACE_')
|
||||
or
|
||||
database[adjacent_tile]['type'].startswith('GTP_INT_INTERFACE')):
|
||||
# This INT_[LR] tile has no adjacent connectivity,
|
||||
# create a segment.
|
||||
add_segment(
|
||||
database=database,
|
||||
segments=segments,
|
||||
name='SEG_' + tile,
|
||||
tiles=[tile],
|
||||
segtype=database[tile]["type"],
|
||||
verbose=verbose,
|
||||
)
|
||||
else:
|
||||
assert False, database[adjacent_tile]['type']
|
||||
|
||||
|
||||
def seg_base_addr_lr_INT(database, segments, tiles_by_grid, verbose=False):
|
||||
def seg_base_addr_lr_INT(database, tiles_by_grid, verbose=False):
|
||||
'''Populate segment base addresses: L/R along INT column'''
|
||||
'''
|
||||
Create BRAM base addresses based on nearby CLBs
|
||||
|
|
@ -322,63 +163,42 @@ def seg_base_addr_lr_INT(database, segments, tiles_by_grid, verbose=False):
|
|||
'''
|
||||
|
||||
verbose and print('')
|
||||
for segment_name in sorted(segments.keys()):
|
||||
segment = segments[segment_name]
|
||||
baseaddrs = segment.get("baseaddr", None)
|
||||
if not baseaddrs:
|
||||
for tile in database:
|
||||
if database[tile]["type"] not in ["INT_L", "INT_R"]:
|
||||
continue
|
||||
|
||||
for block_type, (framebase, wordbase) in sorted(baseaddrs.items()):
|
||||
verbose and print(
|
||||
'lr_INT: %s: %s.0x%08X:%u' %
|
||||
(segment_name, block_type, framebase, wordbase))
|
||||
if block_type != 'CLB_IO_CLK':
|
||||
verbose and print(' Skip non CLB')
|
||||
continue
|
||||
if not database[tile]["bits"]:
|
||||
continue
|
||||
|
||||
for inttile in get_inttile(database, segment):
|
||||
grid_x = database[inttile]["grid_x"]
|
||||
grid_y = database[inttile]["grid_y"]
|
||||
grid_x = database[tile]["grid_x"]
|
||||
grid_y = database[tile]["grid_y"]
|
||||
framebase = int(database[tile]["bits"]["CLB_IO_CLK"]["baseaddr"], 0)
|
||||
wordbase = database[tile]["bits"]["CLB_IO_CLK"]["offset"]
|
||||
|
||||
if database[inttile]["type"] == "INT_L":
|
||||
grid_x += 1
|
||||
framebase = framebase + 0x80
|
||||
elif database[inttile]["type"] == "INT_R":
|
||||
grid_x -= 1
|
||||
framebase = framebase - 0x80
|
||||
else:
|
||||
assert 0
|
||||
if database[tile]["type"] == "INT_L":
|
||||
grid_x += 1
|
||||
framebase = framebase + 0x80
|
||||
elif database[tile]["type"] == "INT_R":
|
||||
grid_x -= 1
|
||||
framebase = framebase - 0x80
|
||||
else:
|
||||
assert 0
|
||||
|
||||
# ROI at edge?
|
||||
if (grid_x, grid_y) not in tiles_by_grid:
|
||||
verbose and print(' Skip edge')
|
||||
continue
|
||||
# ROI at edge?
|
||||
if (grid_x, grid_y) not in tiles_by_grid:
|
||||
verbose and print(' Skip edge')
|
||||
continue
|
||||
|
||||
tile = tiles_by_grid[(grid_x, grid_y)]
|
||||
other_tile = tiles_by_grid[(grid_x, grid_y)]
|
||||
|
||||
if database[inttile]["type"] == "INT_L":
|
||||
assert database[tile]["type"] == "INT_R"
|
||||
elif database[inttile]["type"] == "INT_R":
|
||||
assert database[tile]["type"] == "INT_L"
|
||||
else:
|
||||
assert 0
|
||||
if database[tile]["type"] == "INT_L":
|
||||
assert database[other_tile]["type"] == "INT_R"
|
||||
elif database[tile]["type"] == "INT_R":
|
||||
assert database[other_tile]["type"] == "INT_L"
|
||||
else:
|
||||
assert 0
|
||||
|
||||
if "segment" not in database[tile]:
|
||||
continue
|
||||
|
||||
seg = database[tile]["segment"]
|
||||
|
||||
seg_baseaddrs = segments[seg].setdefault("baseaddr", {})
|
||||
# At least one duplicate when we re-compute the entry for the base address
|
||||
# should give the same address
|
||||
if block_type in seg_baseaddrs:
|
||||
assert seg_baseaddrs[block_type] == [
|
||||
framebase, wordbase
|
||||
], (seg_baseaddrs[block_type], [framebase, wordbase])
|
||||
verbose and print(' Existing OK')
|
||||
else:
|
||||
seg_baseaddrs[block_type] = [framebase, wordbase]
|
||||
verbose and print(' Add new')
|
||||
add_int_bits(database, other_tile, framebase, wordbase)
|
||||
|
||||
|
||||
def seg_base_addr_up_INT(database, segments, tiles_by_grid, verbose=False):
|
||||
|
|
@ -558,43 +378,29 @@ def db_int_fixup(database, tiles, tiles_by_grid):
|
|||
tile_name, tile, baseaddr, offset, frames, words, height)
|
||||
|
||||
|
||||
def run(
|
||||
json_in_fn, json_out_fn, tiles_fn, deltas_fns, int_tdb=None,
|
||||
verbose=False):
|
||||
def run(json_in_fn, json_out_fn, tiles_fn, int_tdb=None, verbose=False):
|
||||
# Load input files
|
||||
tiles = load_tiles(tiles_fn)
|
||||
site_baseaddr = load_baseaddrs(deltas_fns)
|
||||
#site_baseaddr = {}
|
||||
database = json.load(open(json_in_fn, "r"))
|
||||
|
||||
tile_baseaddrs = make_tile_baseaddrs(tiles, site_baseaddr, verbose=verbose)
|
||||
tiles_by_grid = make_tiles_by_grid(tiles)
|
||||
|
||||
segments = make_segments(
|
||||
database, tiles_by_grid, tile_baseaddrs, verbose=verbose)
|
||||
|
||||
# Reference adjacent CLBs to locate adjacent tiles by known offsets
|
||||
seg_base_addr_lr_INT(database, segments, tiles_by_grid, verbose=verbose)
|
||||
seg_base_addr_up_INT(database, segments, tiles_by_grid, verbose=verbose)
|
||||
|
||||
db_add_bits(database, segments)
|
||||
db_add_segments(database, segments)
|
||||
|
||||
if int_tdb is not None:
|
||||
tile_baseaddrs_fixup = load_tdb_baseaddr(database, int_tdb)
|
||||
db_int_fixup(database, tile_baseaddrs_fixup, tiles_by_grid)
|
||||
|
||||
#add_adjacent_int_tiles(database, tiles_by_grid, verbose=verbose)
|
||||
|
||||
# Reference adjacent CLBs to locate adjacent tiles by known offsets
|
||||
#seg_base_addr_lr_INT(database, tiles_by_grid, verbose=verbose)
|
||||
|
||||
# Save
|
||||
json.dump(
|
||||
database,
|
||||
open(json_out_fn, "w"),
|
||||
sort_keys=True,
|
||||
indent=4,
|
||||
separators=(",", ": "))
|
||||
xjson.pprint(open(json_out_fn, "w"), database)
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
import glob
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generate tilegrid.json from bitstream deltas")
|
||||
|
|
@ -608,23 +414,16 @@ def main():
|
|||
"--json-out", default="tilegrid.json", help="Output JSON")
|
||||
parser.add_argument(
|
||||
'--tiles', default='tiles.txt', help='Input tiles.txt tcl output')
|
||||
parser.add_argument(
|
||||
"deltas", nargs="*", help=".bit diffs to create base addresses from")
|
||||
parser.add_argument(
|
||||
"--int-tdb",
|
||||
default=None,
|
||||
help=".tdb diffs to fill the interconnects without any adjacent CLB")
|
||||
args = parser.parse_args()
|
||||
|
||||
deltas = args.deltas
|
||||
if not args.deltas:
|
||||
deltas = glob.glob("*.delta")
|
||||
|
||||
run(
|
||||
args.json_in,
|
||||
args.json_out,
|
||||
args.tiles,
|
||||
deltas,
|
||||
args.int_tdb,
|
||||
verbose=args.verbose)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
source "$::env(FUZDIR)/util.tcl"
|
||||
|
||||
proc loc_iob {} {
|
||||
# Some pads are output only (ex: OPAD_X0Y0/PAD) => filt IOB_*
|
||||
# XXX: GTX bank missing, deal with that later
|
||||
set roi_sites [get_sites -of_objects [get_pblocks roi]]
|
||||
set duts [get_bels -of_objects $roi_sites -filter {TYPE =~ PAD && NAME =~ IOB_*}]
|
||||
|
||||
# Sort them into CMT columns
|
||||
set dut_columns [group_dut_cols $duts 50]
|
||||
# Assign one from each
|
||||
return [loc_dut_col_sites $dut_columns {di_bufs[} {].ibuf} ]
|
||||
}
|
||||
|
||||
proc write_iob { sel_iob_sites } {
|
||||
foreach site $sel_iob_sites {
|
||||
puts ""
|
||||
set port [get_ports -of_objects $site]
|
||||
set tile [get_tiles -of_objects $site]
|
||||
set pin [get_property PACKAGE_PIN $port]
|
||||
puts "IOB $port $site $tile $pin"
|
||||
set orig_init [get_property PULLTYPE $port]
|
||||
set_property PULLTYPE PULLUP $port
|
||||
write_bitstream -force design_$site.bit
|
||||
set_property PULLTYPE "$orig_init" $port
|
||||
}
|
||||
}
|
||||
|
||||
proc run {} {
|
||||
make_project
|
||||
set sel_iob_sites [loc_iob]
|
||||
puts "Selected IOBs: [llength $sel_iob_sites]"
|
||||
|
||||
place_design
|
||||
route_design
|
||||
write_checkpoint -force design.dcp
|
||||
write_bitstream -force design.bit
|
||||
|
||||
write_iob $sel_iob_sites
|
||||
}
|
||||
|
||||
run
|
||||
|
|
@ -11,7 +11,9 @@ def check_frames(addrlist):
|
|||
for addrstr in addrlist:
|
||||
frame = parse_addr(addrstr, get_base_frame=True)
|
||||
frames.add(frame)
|
||||
assert len(frames) == 1, "More than one base address"
|
||||
assert len(frames) == 1, (
|
||||
"More than one base address", map(hex,frames)
|
||||
)
|
||||
|
||||
|
||||
def parse_addr(line, only_frame=False, get_base_frame=False):
|
||||
|
|
@ -120,8 +122,8 @@ def add_tile_bits(
|
|||
|
||||
assert offset <= 100, (tile_name, offset)
|
||||
# Few rare cases at X=0 for double width tiles split in half => small negative offset
|
||||
assert offset >= 0 or "IOB" in tile_name, (tile_name, offset)
|
||||
assert 1 <= words <= 101
|
||||
assert offset >= 0 or "IOB" in tile_name, (tile_name, hex(baseaddr), offset)
|
||||
assert 1 <= words <= 101, words
|
||||
assert offset + words <= 101, (
|
||||
tile_name, offset + words, offset, words, block_type)
|
||||
|
||||
|
|
@ -131,7 +133,7 @@ def add_tile_bits(
|
|||
verbose and print(
|
||||
"%s: existing defintion for %s" % (tile_name, block_type))
|
||||
assert block["baseaddr"] == baseaddr_str
|
||||
assert block["frames"] == frames
|
||||
assert block["frames"] == frames, (block, frames)
|
||||
assert block["offset"] == offset, "%s; orig offset %s, new %s" % (
|
||||
tile_name, block["offset"], offset)
|
||||
assert block["words"] == words
|
||||
|
|
|
|||
Loading…
Reference in New Issue