mirror of https://github.com/openXC7/prjxray.git
timfuz: utility to create tile to speed model database
Signed-off-by: John McMaster <johndmcmaster@gmail.com>
This commit is contained in:
parent
5176374817
commit
fb69b9f045
|
|
@ -0,0 +1,74 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
import json
|
||||
|
||||
SI_NONE = 0xFFFF
|
||||
def load_speed_json(f):
|
||||
j = json.load(f)
|
||||
# Index speed indexes to names
|
||||
speed_i2s = {}
|
||||
for k, v in j['speed_model'].items():
|
||||
i = v['speed_index']
|
||||
if i != SI_NONE:
|
||||
speed_i2s[i] = k
|
||||
return j, speed_i2s
|
||||
|
||||
def gen_tiles(fnin, speed_i2s):
|
||||
for l in open(fnin):
|
||||
# lappend items pip $name $speed_index
|
||||
# puts $fp "$type $tile $grid_x $grid_y $items"
|
||||
parts = l.strip().split()
|
||||
tile_type, tile_name, grid_x, grid_y = parts[0:4]
|
||||
grid_x, grid_y = int(grid_x), int(grid_y)
|
||||
tuples = parts[4:]
|
||||
assert len(tuples) % 3 == 0
|
||||
pips = {}
|
||||
wires = {}
|
||||
for i in range(0, len(tuples), 3):
|
||||
ttype, name, speed_index = tuples[i:i+3]
|
||||
name_local = name.split('/')[1]
|
||||
{
|
||||
'pip': pips,
|
||||
'wire': wires,
|
||||
}[ttype][name_local] = speed_i2s[int(speed_index)]
|
||||
yield (tile_type, tile_name, grid_x, grid_y, pips, wires)
|
||||
|
||||
def run(fnin, fnout, speed_json_fn, verbose=False):
|
||||
speedj, speed_i2s = load_speed_json(open(speed_json_fn, 'r'))
|
||||
|
||||
tiles = {}
|
||||
for tile in gen_tiles(fnin, speed_i2s):
|
||||
(tile_type, tile_name, grid_x, grid_y, pips, wires) = tile
|
||||
this_dat = {'pips': pips, 'wires': wires}
|
||||
if tile_type not in tiles:
|
||||
tiles[tile_type] = this_dat
|
||||
else:
|
||||
if tiles[tile_type] != this_dat:
|
||||
print(tile_name, tile_type)
|
||||
print(this_dat)
|
||||
print(tiles[tile_type])
|
||||
assert 0
|
||||
|
||||
j = {'tiles': tiles}
|
||||
json.dump(j, open(fnout, 'w'), sort_keys=True, indent=4, separators=(',', ': '))
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description=
|
||||
'Solve timing solution'
|
||||
)
|
||||
parser.add_argument('--speed-json', default='build_speed/speed.json',
|
||||
help='Provides speed index to name translation')
|
||||
parser.add_argument('fnin', default=None, help='input tcl output .txt')
|
||||
parser.add_argument('fnout', default=None, help='output .json')
|
||||
args = parser.parse_args()
|
||||
|
||||
run(args.fnin, args.fnout, speed_json_fn=args.speed_json, verbose=False)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
N := 1
|
||||
SPECIMENS := $(addprefix specimen_,$(shell seq -f '%03.0f' $(N)))
|
||||
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
|
||||
|
||||
database: $(SPECIMENS_OK)
|
||||
cp specimen_001/tilegrid.json tilegrid.json
|
||||
|
||||
pushdb:
|
||||
cp tilegrid.json ${XRAY_DATABASE_DIR}/$(XRAY_DATABASE)/tilegrid.json
|
||||
|
||||
$(SPECIMENS_OK):
|
||||
bash generate.sh $(subst /OK,,$@)
|
||||
touch $@
|
||||
|
||||
run:
|
||||
$(MAKE) clean
|
||||
$(MAKE) database
|
||||
$(MAKE) pushdb
|
||||
touch run.ok
|
||||
|
||||
clean:
|
||||
rm -rf specimen_[0-9][0-9][0-9]/ tilegrid.json run.ok
|
||||
|
||||
.PHONY: database pushdb clean run
|
||||
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
#!/bin/bash -x
|
||||
|
||||
source ${XRAY_GENHEADER}
|
||||
|
||||
vivado -mode batch -source ../generate.tcl
|
||||
|
||||
for x in design*.bit; do
|
||||
${XRAY_BITREAD} -F $XRAY_ROI_FRAMES -o ${x}s -z -y $x
|
||||
done
|
||||
|
||||
for x in design_*.bits; do
|
||||
diff -u design.bits $x | grep '^[-+]bit' > ${x%.bits}.delta
|
||||
done
|
||||
|
||||
python3 ../generate.py design_*.delta > tilegrid.json
|
||||
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
proc create_project {} {
|
||||
if 0 {
|
||||
set grid_min_x -1
|
||||
set grid_max_x -1
|
||||
set grid_min_y -1
|
||||
set grid_max_y -1
|
||||
} {
|
||||
set grid_min_x $::env(XRAY_ROI_GRID_X1)
|
||||
set grid_max_x $::env(XRAY_ROI_GRID_X2)
|
||||
set grid_min_y $::env(XRAY_ROI_GRID_Y1)
|
||||
set grid_max_y $::env(XRAY_ROI_GRID_Y2)
|
||||
}
|
||||
|
||||
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 di]
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_02) IOSTANDARD LVCMOS33" [get_ports do]
|
||||
set_property -dict "PACKAGE_PIN $::env(XRAY_PIN_03) IOSTANDARD LVCMOS33" [get_ports stb]
|
||||
|
||||
create_pblock roi
|
||||
add_cells_to_pblock [get_pblocks roi] [get_cells roi]
|
||||
resize_pblock [get_pblocks roi] -add "$::env(XRAY_ROI)"
|
||||
|
||||
set_property CFGBVS VCCO [current_design]
|
||||
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
||||
set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]
|
||||
set_param tcl.collectionResultDisplayLimit 0
|
||||
|
||||
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_IBUF]
|
||||
|
||||
set luts [get_bels -of_objects [get_sites -of_objects [get_pblocks roi]] -filter {TYPE =~ LUT*} */A6LUT]
|
||||
set selected_luts {}
|
||||
set lut_index 0
|
||||
|
||||
# LOC one LUT (a "selected_lut") into each CLB segment configuration column (ie 50 per column)
|
||||
# Also, if GRID_MIN/MAX is not defined, automatically create it based on used CLBs
|
||||
# See caveat in README on automatic creation
|
||||
foreach lut $luts {
|
||||
set tile [get_tile -of_objects $lut]
|
||||
set grid_x [get_property GRID_POINT_X $tile]
|
||||
set grid_y [get_property GRID_POINT_Y $tile]
|
||||
|
||||
if [expr $grid_min_x < 0 || $grid_x < $grid_min_x] {set grid_min_x $grid_x}
|
||||
if [expr $grid_max_x < 0 || $grid_x > $grid_max_x] {set grid_max_x $grid_x}
|
||||
|
||||
if [expr $grid_min_y < 0 || $grid_y < $grid_min_y] {set grid_min_y $grid_y}
|
||||
if [expr $grid_max_y < 0 || $grid_y > $grid_max_y] {set grid_max_y $grid_y}
|
||||
|
||||
# 50 per column => 50, 100, 150, etc
|
||||
if [regexp "Y(0|[0-9]*[05]0)/" $lut] {
|
||||
set cell [get_cells roi/is[$lut_index].lut]
|
||||
set_property LOC [get_sites -of_objects $lut] $cell
|
||||
set lut_index [expr $lut_index + 1]
|
||||
lappend selected_luts $lut
|
||||
}
|
||||
}
|
||||
|
||||
place_design
|
||||
route_design
|
||||
|
||||
write_checkpoint -force design.dcp
|
||||
write_bitstream -force design.bit
|
||||
}
|
||||
|
||||
proc write_data {} {
|
||||
if 0 {
|
||||
set grid_min_x -1
|
||||
set grid_max_x -1
|
||||
set grid_min_y -1
|
||||
set grid_max_y -1
|
||||
} {
|
||||
set grid_min_x $::env(XRAY_ROI_GRID_X1)
|
||||
set grid_max_x $::env(XRAY_ROI_GRID_X2)
|
||||
set grid_min_y $::env(XRAY_ROI_GRID_Y1)
|
||||
set grid_max_y $::env(XRAY_ROI_GRID_Y2)
|
||||
}
|
||||
|
||||
# Get all tiles in ROI, ie not just the selected LUTs
|
||||
set tiles [get_tiles -filter "GRID_POINT_X >= $grid_min_x && GRID_POINT_X <= $grid_max_x && GRID_POINT_Y >= $grid_min_y && GRID_POINT_Y <= $grid_max_y"]
|
||||
|
||||
# Write tiles.txt with site metadata
|
||||
set fp [open "tiles.txt" w]
|
||||
foreach tile $tiles {
|
||||
set type [get_property TYPE $tile]
|
||||
set grid_x [get_property GRID_POINT_X $tile]
|
||||
set grid_y [get_property GRID_POINT_Y $tile]
|
||||
|
||||
set items {}
|
||||
|
||||
set wires [get_wires -of_objects $tile]
|
||||
if [llength $wires] {
|
||||
foreach wire $wires {
|
||||
set name [get_property NAME $wire]
|
||||
set speed_index [get_property SPEED_INDEX $wire]
|
||||
lappend items wire $name $speed_index
|
||||
}
|
||||
}
|
||||
|
||||
set pips [get_pips -of_objects $tile]
|
||||
if [llength $pips] {
|
||||
foreach pip $pips {
|
||||
set name [get_property NAME $pip]
|
||||
set speed_index [get_property SPEED_INDEX $pip]
|
||||
lappend items pip $name $speed_index
|
||||
}
|
||||
}
|
||||
|
||||
puts $fp "$type $tile $grid_x $grid_y $items"
|
||||
}
|
||||
close $fp
|
||||
}
|
||||
|
||||
create_project
|
||||
write_data
|
||||
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
//Need at least one LUT per frame base address we want
|
||||
`define N 100
|
||||
|
||||
module top(input clk, stb, di, output do);
|
||||
localparam integer DIN_N = 6;
|
||||
localparam integer DOUT_N = `N;
|
||||
|
||||
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];
|
||||
|
||||
roi roi (
|
||||
.clk(clk),
|
||||
.din(din),
|
||||
.dout(dout)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module roi(input clk, input [5:0] din, output [`N-1:0] dout);
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < `N; i = i+1) begin:is
|
||||
LUT6 #(
|
||||
.INIT(64'h8000_0000_0000_0001 + (i << 16))
|
||||
) lut (
|
||||
.I0(din[0]),
|
||||
.I1(din[1]),
|
||||
.I2(din[2]),
|
||||
.I3(din[3]),
|
||||
.I4(din[4]),
|
||||
.I5(din[5]),
|
||||
.O(dout[i])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
`define N 100
|
||||
|
||||
module top(input clk, stb, di, output do);
|
||||
localparam integer DIN_N = 8;
|
||||
localparam integer DOUT_N = `N;
|
||||
|
||||
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];
|
||||
|
||||
roi roi (
|
||||
.clk(clk),
|
||||
.din(din),
|
||||
.dout(dout)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module roi(input clk, input [7:0] din, output [`N-1:0] dout);
|
||||
genvar i;
|
||||
generate
|
||||
for (i = 0; i < `N; i = i+1) begin:is
|
||||
(* KEEP, DONT_TOUCH *)
|
||||
RAMB36E1 #(.INIT_00(256'h0000000000000000000000000000000000000000000000000000000000000000)) 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(),
|
||||
.DOPADOP(),
|
||||
.DOPBDOP());
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
Loading…
Reference in New Issue