mirror of https://github.com/openXC7/prjxray.git
iob-stag: IOB supertag
Signed-off-by: John McMaster <johndmcmaster@gmail.com>
This commit is contained in:
parent
075a939ffc
commit
f3fade68bd
|
|
@ -0,0 +1,20 @@
|
||||||
|
N := 1
|
||||||
|
include ../fuzzer.mk
|
||||||
|
|
||||||
|
SEGDATAS=$(addsuffix /segdata_liob33.txt,$(SPECIMENS))
|
||||||
|
|
||||||
|
database: build/segbits_liob33.db
|
||||||
|
|
||||||
|
build/segbits_liob33.rdb: $(SPECIMENS_OK)
|
||||||
|
${XRAY_SEGMATCH} -c -1 -o build/segbits_liob33.rdb $(SEGDATAS)
|
||||||
|
|
||||||
|
build/segbits_liob33.db: build/segbits_liob33.rdb
|
||||||
|
${XRAY_DBFIXUP} --db-root build --zero-db bits.dbf --seg-fn-in $^ --seg-fn-out $@
|
||||||
|
${XRAY_MASKMERGE} build/mask_liob33.db $(SEGDATAS)
|
||||||
|
|
||||||
|
pushdb:
|
||||||
|
${XRAY_MERGEDB} liob33 build/segbits_liob33.db
|
||||||
|
${XRAY_MERGEDB} mask_liob33 build/mask_liob33.db
|
||||||
|
|
||||||
|
.PHONY: database pushdb
|
||||||
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from prjxray.segmaker import Segmaker
|
||||||
|
from prjxray import segmaker
|
||||||
|
|
||||||
|
segmk = Segmaker("design.bits")
|
||||||
|
|
||||||
|
print("Loading params")
|
||||||
|
f = open('params.csv', 'r')
|
||||||
|
f.readline()
|
||||||
|
for l in f:
|
||||||
|
l = l.strip()
|
||||||
|
site, name, dir_, cell = l.split(',')
|
||||||
|
segmaker.add_site_group_zero(
|
||||||
|
segmk, site, "MACRO.", ("INPUT", "OUTPUT"), "", dir_.upper())
|
||||||
|
|
||||||
|
segmk.compile()
|
||||||
|
segmk.write()
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -ex
|
||||||
|
source ${XRAY_DIR}/utils/top_generate.sh
|
||||||
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
source "$::env(XRAY_DIR)/utils/utils.tcl"
|
||||||
|
|
||||||
|
proc make_io_pin_sites {} {
|
||||||
|
# get all possible IOB pins
|
||||||
|
foreach pad [get_package_pins -filter "IS_GENERAL_PURPOSE == 1"] {
|
||||||
|
set site [get_sites -of_objects $pad]
|
||||||
|
if {[llength $site] == 0} {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if [string match IOB33* [get_property SITE_TYPE $site]] {
|
||||||
|
dict append io_pin_sites $site $pad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $io_pin_sites
|
||||||
|
}
|
||||||
|
|
||||||
|
proc load_pin_lines {} {
|
||||||
|
# IOB_X0Y103 clk input
|
||||||
|
# IOB_X0Y129 do[0] output
|
||||||
|
|
||||||
|
set fp [open "params.csv" r]
|
||||||
|
set pin_lines {}
|
||||||
|
for {gets $fp line} {$line != ""} {gets $fp line} {
|
||||||
|
lappend pin_lines [split $line ","]
|
||||||
|
}
|
||||||
|
close $fp
|
||||||
|
return $pin_lines
|
||||||
|
}
|
||||||
|
|
||||||
|
proc loc_pins {} {
|
||||||
|
set pin_lines [load_pin_lines]
|
||||||
|
set io_pin_sites [make_io_pin_sites]
|
||||||
|
|
||||||
|
set fp [open "design.csv" w]
|
||||||
|
puts $fp "port,site,tile,pin,val"
|
||||||
|
|
||||||
|
puts "Looping"
|
||||||
|
for {set idx 1} {$idx < [llength $pin_lines]} {incr idx} {
|
||||||
|
set line [lindex $pin_lines $idx]
|
||||||
|
puts "$line"
|
||||||
|
|
||||||
|
set site_str [lindex $line 0]
|
||||||
|
set pin_str [lindex $line 1]
|
||||||
|
set io [lindex $line 2]
|
||||||
|
set cell_str [lindex $line 3]
|
||||||
|
# Skip unused site
|
||||||
|
if {"$pin_str" == ""} {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
# Have: site
|
||||||
|
# Want: pin for site
|
||||||
|
set site [get_sites $site_str]
|
||||||
|
set pad_bel [get_bels -of_objects $site -filter {TYPE =~ PAD && NAME =~ IOB_*}]
|
||||||
|
set port [get_ports $pin_str]
|
||||||
|
set tile [get_tiles -of_objects $site]
|
||||||
|
set pin [dict get $io_pin_sites $site]
|
||||||
|
|
||||||
|
set_property -dict "PACKAGE_PIN $pin IOSTANDARD LVCMOS33" $port
|
||||||
|
|
||||||
|
puts $fp "$port,$site,$tile,$pin"
|
||||||
|
}
|
||||||
|
close $fp
|
||||||
|
}
|
||||||
|
|
||||||
|
proc run {} {
|
||||||
|
create_project -force -part $::env(XRAY_PART) design design
|
||||||
|
read_verilog top.v
|
||||||
|
synth_design -top top
|
||||||
|
|
||||||
|
# Mostly doesn't matter since IOB are special, but add anyway
|
||||||
|
create_pblock roi
|
||||||
|
add_cells_to_pblock [get_pblocks roi] [get_cells roi]
|
||||||
|
resize_pblock [get_pblocks roi] -add "$::env(XRAY_ROI)"
|
||||||
|
|
||||||
|
loc_pins
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
place_design
|
||||||
|
route_design
|
||||||
|
|
||||||
|
write_checkpoint -force design.dcp
|
||||||
|
write_bitstream -force design.bit
|
||||||
|
}
|
||||||
|
|
||||||
|
run
|
||||||
|
|
@ -0,0 +1,152 @@
|
||||||
|
'''
|
||||||
|
Generate a primitive to place at every I/O
|
||||||
|
Unlike CLB tests, the LFSR for this is inside the ROI, not driving it
|
||||||
|
'''
|
||||||
|
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
random.seed(int(os.getenv("SEED"), 16))
|
||||||
|
from prjxray import util
|
||||||
|
from prjxray import verilog
|
||||||
|
|
||||||
|
|
||||||
|
def gen_iobs():
|
||||||
|
'''
|
||||||
|
IOB33S: main IOB of a diff pair
|
||||||
|
IOB33M: secondary IOB of a diff pair
|
||||||
|
IOB33: not a diff pair. Relatively rare (at least in ROI...2 of them?)
|
||||||
|
Focus on IOB33S to start
|
||||||
|
'''
|
||||||
|
for _tile_name, site_name, site_type in util.get_roi().gen_sites(
|
||||||
|
#['IOB33', 'IOB33S', 'IOB33M']):
|
||||||
|
['IOB33S']):
|
||||||
|
yield site_name, site_type
|
||||||
|
|
||||||
|
|
||||||
|
def write_pins(ports):
|
||||||
|
pinstr = 'site,name,dir,cell\n'
|
||||||
|
for site, (name, dir_, cell) in sorted(ports.items(), key=lambda x: x[1]):
|
||||||
|
# pinstr += 'set_property -dict "PACKAGE_PIN %s IOSTANDARD LVCMOS33" [get_ports %s]' % (packpin, port)
|
||||||
|
pinstr += '%s,%s,%s,%s\n' % (site, name, dir_, cell)
|
||||||
|
open('params.csv', 'w').write(pinstr)
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
# All possible values
|
||||||
|
iosites = {}
|
||||||
|
for site_name, site_type in gen_iobs():
|
||||||
|
iosites[site_name] = site_type
|
||||||
|
|
||||||
|
# Assigned in this design
|
||||||
|
ports = {}
|
||||||
|
DIN_N = 0
|
||||||
|
DOUT_N = 0
|
||||||
|
|
||||||
|
def remain_sites():
|
||||||
|
return set(iosites.keys()) - set(ports.keys())
|
||||||
|
|
||||||
|
def rand_site():
|
||||||
|
'''Get a random, unused site'''
|
||||||
|
return random.choice(list(remain_sites()))
|
||||||
|
|
||||||
|
def assign_i(site, name):
|
||||||
|
nonlocal DIN_N
|
||||||
|
|
||||||
|
assert site not in ports
|
||||||
|
cell = "di_bufs[%u].ibuf" % DIN_N
|
||||||
|
DIN_N += 1
|
||||||
|
ports[site] = (name, 'input', cell)
|
||||||
|
|
||||||
|
def assign_o(site, name):
|
||||||
|
nonlocal DOUT_N
|
||||||
|
|
||||||
|
assert site not in ports
|
||||||
|
cell = "do_bufs[%u].obuf" % DOUT_N
|
||||||
|
DOUT_N += 1
|
||||||
|
ports[site] = (name, 'output', cell)
|
||||||
|
|
||||||
|
# Assign at least one di and one do
|
||||||
|
assign_i(rand_site(), 'di[0]')
|
||||||
|
assign_o(rand_site(), 'do[0]')
|
||||||
|
# Now assign the rest randomly
|
||||||
|
while len(remain_sites()):
|
||||||
|
site = rand_site()
|
||||||
|
choice = random.randint(0, 2)
|
||||||
|
if choice == 0:
|
||||||
|
assign_i(site, 'di[%u]' % DIN_N)
|
||||||
|
elif choice == 1:
|
||||||
|
assign_o(site, 'do[%u]' % DOUT_N)
|
||||||
|
# Empty to provide a reference for no instance
|
||||||
|
else:
|
||||||
|
ports[site] = ("", "", "")
|
||||||
|
|
||||||
|
write_pins(ports)
|
||||||
|
|
||||||
|
print(
|
||||||
|
'''
|
||||||
|
`define N_DI %u
|
||||||
|
`define N_DO %u
|
||||||
|
|
||||||
|
module top(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do);
|
||||||
|
genvar i;
|
||||||
|
|
||||||
|
//Instantiate BUFs so we can LOC them
|
||||||
|
|
||||||
|
wire [`N_DI-1:0] di_buf;
|
||||||
|
generate
|
||||||
|
for (i = 0; i < `N_DI; i = i+1) begin:di_bufs
|
||||||
|
IBUF ibuf(.I(di[i]), .O(di_buf[i]));
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
wire [`N_DO-1:0] do_unbuf;
|
||||||
|
generate
|
||||||
|
for (i = 0; i < `N_DO; i = i+1) begin:do_bufs
|
||||||
|
OBUF obuf(.I(do_unbuf[i]), .O(do[i]));
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
roi roi(.di(di_buf), .do(do_unbuf));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
//Arbitrary terminate into LUTs
|
||||||
|
module roi(input wire [`N_DI-1:0] di, output wire [`N_DO-1:0] do);
|
||||||
|
genvar i;
|
||||||
|
|
||||||
|
generate
|
||||||
|
for (i = 0; i < `N_DI; i = i+1) begin:dis
|
||||||
|
(* KEEP, DONT_TOUCH *)
|
||||||
|
LUT6 #(
|
||||||
|
.INIT(64'h8000_0000_0000_0001)
|
||||||
|
) lut (
|
||||||
|
.I0(di[i]),
|
||||||
|
.I1(di[i]),
|
||||||
|
.I2(di[i]),
|
||||||
|
.I3(di[i]),
|
||||||
|
.I4(di[i]),
|
||||||
|
.I5(di[i]),
|
||||||
|
.O());
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate
|
||||||
|
for (i = 0; i < `N_DO; i = i+1) begin:dos
|
||||||
|
(* KEEP, DONT_TOUCH *)
|
||||||
|
LUT6 #(
|
||||||
|
.INIT(64'h8000_0000_0000_0001)
|
||||||
|
) lut (
|
||||||
|
.I0(),
|
||||||
|
.I1(),
|
||||||
|
.I2(),
|
||||||
|
.I3(),
|
||||||
|
.I4(),
|
||||||
|
.I5(),
|
||||||
|
.O(do[i]));
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
||||||
|
''' % (DIN_N, DOUT_N))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
run()
|
||||||
Loading…
Reference in New Issue