diff --git a/fuzzers/032-cmt-pll/generate.py b/fuzzers/032-cmt-pll/generate.py index c358070a..1d428dfb 100644 --- a/fuzzers/032-cmt-pll/generate.py +++ b/fuzzers/032-cmt-pll/generate.py @@ -10,9 +10,6 @@ def bitfilter(frame, word): if frame < 28: return False - if frame == 25 and word == 3121: - return False - return True @@ -69,15 +66,17 @@ def bus_tags(segmk, ps, site): site, 'COMP.' + opt + '_Z' + conn + '_' + ps['site'], opt_match and not conn_match) - match = verilog.unquote(ps['COMPENSATION']) in ['BUF_IN', 'EXTERNAL'] bufg_on_clkin = \ 'BUFG' in ps['clkin1_conn'] or \ 'BUFG' in ps['clkin2_conn'] - if not match: - if verilog.unquote(ps['COMPENSATION']) == 'ZHOLD' and bufg_on_clkin: - match = True - segmk.add_site_tag( - site, 'COMPENSATION.BUF_IN_OR_EXTERNAL_OR_ZHOLD_CLKIN_BUF', match) + + # This one is in conflict with some clock routing bits. + # match = verilog.unquote(ps['COMPENSATION']) in ['BUF_IN', 'EXTERNAL'] + # if not match: + # if verilog.unquote(ps['COMPENSATION']) == 'ZHOLD' and bufg_on_clkin: + # match = True + # segmk.add_site_tag( + # site, 'COMPENSATION.BUF_IN_OR_EXTERNAL_OR_ZHOLD_CLKIN_BUF', match) match = verilog.unquote(ps['COMPENSATION']) in ['ZHOLD'] segmk.add_site_tag( @@ -98,7 +97,8 @@ def bus_tags(segmk, ps, site): site == "PLLE2_ADV_X0Y2" ) - for opt in ['ZHOLD', 'BUF_IN', 'EXTERNAL', 'INTERNAL']: + # No INTERNAL as it has conflicting bits + for opt in ['ZHOLD', 'BUF_IN', 'EXTERNAL']: if opt in ['BUF_IN', 'EXTERNAL']: if ps['clkfbin_conn'] not in ['', 'clk']: continue @@ -115,9 +115,11 @@ def bus_tags(segmk, ps, site): site, 'COMPENSATION.Z_' + opt, verilog.unquote(ps['COMPENSATION']) != opt) - segmk.add_site_tag( - site, 'COMPENSATION.INTERNAL', - verilog.unquote(ps['COMPENSATION']) in ['INTERNAL']) + +# This one has bits that are in conflict with clock routing +# segmk.add_site_tag( +# site, 'COMPENSATION.INTERNAL', +# verilog.unquote(ps['COMPENSATION']) in ['INTERNAL']) for param in ['CLKFBOUT_MULT']: paramadj = int(ps[param]) diff --git a/fuzzers/032-cmt-pll/generate.tcl b/fuzzers/032-cmt-pll/generate.tcl index 46ff0d76..cfc2f3f7 100644 --- a/fuzzers/032-cmt-pll/generate.tcl +++ b/fuzzers/032-cmt-pll/generate.tcl @@ -1,19 +1,53 @@ +source "$::env(XRAY_DIR)/utils/utils.tcl" + +proc make_manual_routes {filename} { + puts "MANROUTE: Loading routes from $filename" + + set fp [open $filename r] + foreach line [split [read $fp] "\n"] { + if {$line eq ""} { + continue + } + + puts "MANROUTE: Line: $line" + + # Parse the line + set fields [split $line " "] + set net_name [lindex $fields 0] + set wire_name [lindex $fields 1] + + # Check if that net exist + if {[get_nets $net_name] eq ""} { + puts "MANROUTE: net $net_name does not exist" + continue + } + + # Make the route + set status [route_via $net_name [list $wire_name] 0] + + # Failure, skip manual routing of this net + if { $status != 1 } { + puts "MANROUTE: Manual routing failed!" + set net [get_nets $net_name] + set_property -quiet FIXED_ROUTE "" $net + set_property IS_ROUTE_FIXED 0 $net + continue + } + + puts "MANROUTE: Success!" + } +} + 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 CFGBVS VCCO [current_design] set_property CONFIG_VOLTAGE 3.3 [current_design] set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design] -create_clock -period 10.00 [get_ports clk] - -set net [get_nets clk_IBUF] -if { [llength $net] > 0 } { - set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets clk_IBUF] -} +create_clock -period 10.00 [get_ports clkin1*] +create_clock -period 10.00 [get_ports clkin2*] # Disable MMCM frequency etc sanity checks set_property IS_ENABLED 0 [get_drc_checks {PDRC-29}] @@ -26,8 +60,32 @@ set_property IS_ENABLED 0 [get_drc_checks {PDRC-43}] set_property IS_ENABLED 0 [get_drc_checks {REQP-161}] set_property IS_ENABLED 0 [get_drc_checks {AVAL-78}] +set_property IS_ENABLED 0 [get_drc_checks {UCIO-1}] +set_property IS_ENABLED 0 [get_drc_checks {NSTD-1}] + place_design -route_design +write_checkpoint -force design_placed.dcp + +make_manual_routes routes.txt +write_checkpoint -force design_pre_route.dcp + +route_design -directive Quick -preserve + +set unrouted_nets [get_nets -filter {ROUTE_STATUS!="ROUTED"}] +if {[llength $unrouted_nets] ne 0} { + puts "MANROUTE: Got unrouted nets: $unrouted_nets" + puts "MANROUTE: Ripping up and starting again with no fixed routes" + + route_design -unroute + + set fixed_nets [get_nets -filter {IS_ROUTE_FIXED==1}] + if {[llength $fixed_nets] ne 0} { + set_property FIXED_ROUTE "" $fixed_nets + set_property IS_ROUTE_FIXED 0 $fixed_nets + } + + route_design -directive Quick +} write_checkpoint -force design.dcp write_bitstream -force design.bit diff --git a/fuzzers/032-cmt-pll/top.py b/fuzzers/032-cmt-pll/top.py index 02cc7256..441028a8 100644 --- a/fuzzers/032-cmt-pll/top.py +++ b/fuzzers/032-cmt-pll/top.py @@ -14,42 +14,55 @@ def gen_sites(): loc = grid.loc_of_tilename(tile_name) gridinfo = grid.gridinfo_at_loc(loc) + tile_type = tile_name.rsplit("_", 1)[0] + for site_name, site_type in gridinfo.sites.items(): if site_type in ['PLLE2_ADV']: - yield site_name + yield tile_name, tile_type, site_name def main(): + sites = sorted(list(gen_sites())) + max_sites = len(sites) + f = open('params.jl', 'w') f.write('module,loc,params\n') + routes_file = open('routes.txt', 'w') + print( - """module top(input clk); + """ +module top( + input [{N}:0] clkin1, + input [{N}:0] clkin2, + input [{N}:0] clkfb, + input [{N}:0] dclk +); (* KEEP, DONT_TOUCH *) LUT1 dummy(); - """) +""".format(N=max_sites - 1)) - for site in sorted(gen_sites()): + for i, ( + tile_name, + tile_type, + site, + ) in enumerate(sorted(gen_sites())): params = { "site": site, 'active': random.random() > .2, "clkin1_conn": - random.choice(( - "clkfbout_mult_BUFG_" + site, - "clk", - )), + random.choice( + ("clkfbout_mult_BUFG_" + site, "clkin1[{}]".format(i), "")), "clkin2_conn": - random.choice(( - "clkfbout_mult_BUFG_" + site, - "clk", - )), + random.choice( + ("clkfbout_mult_BUFG_" + site, "clkin2[{}]".format(i), "")), "dclk_conn": random.choice(( "0", - "clk", + "dclk[{}]".format(i), )), "dwe_conn": random.choice(( @@ -127,10 +140,62 @@ def main(): )) else: params['clkfbin_conn'] = random.choice( - ("", "clk", "clkfbout_mult_BUFG_" + site)) + ("", "clkfb[{}]".format(i), "clkfbout_mult_BUFG_" + site)) + + params['clkin1_route'] = random.choice( + ( + "{}_CLKIN1", + "{}_FREQ_BB0", + "{}_FREQ_BB1", + "{}_FREQ_BB2", + "{}_FREQ_BB3", + "{}_PLLE2_CLK_IN1_INT", + )).format(tile_type) + + params['clkin2_route'] = random.choice( + ( + "{}_CLKIN2", + "{}_FREQ_BB0", + "{}_FREQ_BB1", + "{}_FREQ_BB2", + "{}_FREQ_BB3", + "{}_PLLE2_CLK_IN2_INT", + )).format(tile_type) + + params['clkfbin_route'] = random.choice( + ( + "{}_CLKFBOUT2IN", + "{}_UPPER_T_FREQ_BB0", + "{}_UPPER_T_FREQ_BB1", + "{}_UPPER_T_FREQ_BB2", + "{}_UPPER_T_FREQ_BB3", + "{}_UPPER_T_PLLE2_CLK_FB_INT", + )).format(tile_type.replace("_UPPER_T", "")) f.write('%s\n' % (json.dumps(params))) + def make_ibuf_net(net): + p = net.find('[') + return net[:p] + '_IBUF' + net[p:] + + if params['clkin1_conn'] != "": + net = make_ibuf_net(params['clkin1_conn']) + wire = '{}/{}'.format(tile_name, params['clkin1_route']) + routes_file.write('{} {}\n'.format(net, wire)) + + if params['clkin2_conn'] != "": + net = make_ibuf_net(params['clkin2_conn']) + wire = '{}/{}'.format(tile_name, params['clkin2_route']) + routes_file.write('{} {}\n'.format(net, wire)) + + if params['clkfbin_conn'] != "" and\ + params['clkfbin_conn'] != ("clkfbout_mult_BUFG_" + site): + net = params['clkfbin_conn'] + if "[" in net and "]" in net: + net = make_ibuf_net(net) + wire = '{}/{}'.format(tile_name, params['clkfbin_route']) + routes_file.write('{} {}\n'.format(net, wire)) + if not params['active']: continue diff --git a/fuzzers/034-cmt-pll-pips/fixup_and_group.py b/fuzzers/034-cmt-pll-pips/fixup_and_group.py index b005b05a..eae668c3 100755 --- a/fuzzers/034-cmt-pll-pips/fixup_and_group.py +++ b/fuzzers/034-cmt-pll-pips/fixup_and_group.py @@ -74,7 +74,7 @@ def bit_to_str(bit): Converts a tuple (frame, bit, value) to its string representation. """ s = "!" if not bit[2] else "" - return "{}{}_{}".format(s, bit[0], bit[1]) + return "{}{}_{:02d}".format(s, bit[0], bit[1]) def load_segbits(file_name):