|  | #!/usr/bin/env python3 | 
|  |  | 
|  | from fuzzconfig import * | 
|  | import numpy as np | 
|  | import os | 
|  |  | 
|  | from numpy.random import randint, choice, permutation | 
|  |  | 
|  | def randbin(n): | 
|  | return  "".join([choice(["0", "1"]) for i in range(n)]) | 
|  |  | 
|  | for p in gpins: | 
|  | if p in pins: pins.remove(p) | 
|  |  | 
|  | device_class = os.getenv("ICEDEVICE") | 
|  |  | 
|  | working_dir = "work_%s_pll" % (device_class, ) | 
|  |  | 
|  | os.system("rm -rf " + working_dir) | 
|  | os.mkdir(working_dir) | 
|  |  | 
|  | for idx in range(num): | 
|  | pin_names = list() | 
|  | vlog_body = list() | 
|  | pll_inst = list() | 
|  |  | 
|  | pll_type = choice(["SB_PLL40_CORE", "SB_PLL40_2F_CORE", "SB_PLL40_PAD", "SB_PLL40_2_PAD", "SB_PLL40_2F_PAD"]) | 
|  |  | 
|  | pll_inst.append("%s uut (" % pll_type) | 
|  |  | 
|  | if pll_type.endswith("_PAD"): | 
|  | pin_names.append("packagepin") | 
|  | vlog_body.append("input packagepin;") | 
|  | pll_inst.append("  .PACKAGEPIN(packagepin),") | 
|  | else: | 
|  | pin_names.append("referenceclk") | 
|  | vlog_body.append("input referenceclk;") | 
|  | pll_inst.append("  .REFERENCECLK(referenceclk),") | 
|  |  | 
|  | for pin in ["a", "b"]: | 
|  | pin_names.append(pin) | 
|  | vlog_body.append("input %s;" % pin) | 
|  |  | 
|  | for pin in ["w", "x", "y", "z"]: | 
|  | pin_names.append(pin) | 
|  | vlog_body.append("output %s%s;" % ("reg " if pin in ["y", "z"] else "", pin)) | 
|  |  | 
|  | for pin in ["EXTFEEDBACK", "BYPASS", "RESETB", "LOCK", "LATCHINPUTVALUE", "SDI", "SDO", "SCLK"]: | 
|  | pin_names.append(pin.lower()) | 
|  | vlog_body.append("%sput %s;" % ("out" if pin in ["LOCK", "SDO"] else "in", pin.lower())) | 
|  | pll_inst.append("  .%s(%s)," % (pin, pin.lower())) | 
|  |  | 
|  | if pll_type.find("_2_") < 0 and pll_type.find("_2F_") < 0: | 
|  | for pin in ["PLLOUTCORE", "PLLOUTGLOBAL"]: | 
|  | vlog_body.append("wire %s;" % pin.lower()) | 
|  | pll_inst.append("  .%s(%s)," % (pin, pin.lower())) | 
|  | vlog_body.append("assign w = plloutcore ^ a;") | 
|  | vlog_body.append("assign x = plloutcore ^ b;") | 
|  | vlog_body.append("always @(posedge plloutglobal) y <= a;") | 
|  | vlog_body.append("always @(posedge plloutglobal) z <= b;") | 
|  | else: | 
|  | for pin in ["PLLOUTCOREA", "PLLOUTCOREB", "PLLOUTGLOBALA", "PLLOUTGLOBALB"]: | 
|  | vlog_body.append("wire %s;" % pin.lower()) | 
|  | pll_inst.append("  .%s(%s)," % (pin, pin.lower())) | 
|  | vlog_body.append("assign w = plloutcorea ^ a;") | 
|  | vlog_body.append("assign x = plloutcoreb ^ b;") | 
|  | vlog_body.append("always @(posedge plloutglobala) y <= a;") | 
|  | vlog_body.append("always @(posedge plloutglobalb) z <= b;") | 
|  |  | 
|  | for i in range(8): | 
|  | pin_names.append("dynamicdelay_%d" % i) | 
|  | vlog_body.append("input dynamicdelay_%d;" % i) | 
|  | pll_inst.append("  .DYNAMICDELAY({%s})" % ", ".join(["dynamicdelay_%d" % i for i in range(7, -1, -1)])) | 
|  | pll_inst.append(");") | 
|  |  | 
|  | divq = randbin(3) | 
|  | if divq == "000": divq = "001" | 
|  | if divq == "111": divq = "110" | 
|  | pll_inst.append("defparam uut.DIVR = 4'b%s;" % randbin(4)) | 
|  | pll_inst.append("defparam uut.DIVF = 7'b%s;" % randbin(7)) | 
|  | pll_inst.append("defparam uut.DIVQ = 3'b%s;" % divq) | 
|  | pll_inst.append("defparam uut.FILTER_RANGE = 3'b%s;" %  randbin(3)) | 
|  | pll_inst.append("defparam uut.FEEDBACK_PATH = \"%s\";" % choice(["DELAY", "SIMPLE", "PHASE_AND_DELAY", "EXTERNAL"])) | 
|  |  | 
|  | if choice([True, False]): | 
|  | pll_inst.append("defparam uut.DELAY_ADJUSTMENT_MODE_FEEDBACK = \"FIXED\";") | 
|  | pll_inst.append("defparam uut.FDA_FEEDBACK = 4'b%s;" %  randbin(4)) | 
|  | else: | 
|  | pll_inst.append("defparam uut.DELAY_ADJUSTMENT_MODE_FEEDBACK = \"DYNAMIC\";") | 
|  | pll_inst.append("defparam uut.FDA_FEEDBACK = 4'b1111;") | 
|  |  | 
|  | if choice([True, False]): | 
|  | pll_inst.append("defparam uut.DELAY_ADJUSTMENT_MODE_RELATIVE = \"FIXED\";") | 
|  | pll_inst.append("defparam uut.FDA_RELATIVE = 4'b%s;" %  randbin(4)) | 
|  | else: | 
|  | pll_inst.append("defparam uut.DELAY_ADJUSTMENT_MODE_RELATIVE = \"DYNAMIC\";") | 
|  | pll_inst.append("defparam uut.FDA_RELATIVE = 4'b1111;") | 
|  |  | 
|  | pll_inst.append("defparam uut.SHIFTREG_DIV_MODE = 1'b%s;" %  randbin(1)) | 
|  |  | 
|  | if pll_type.find("_2_") < 0 and pll_type.find("_2F_") < 0: | 
|  | pll_inst.append("defparam uut.PLLOUT_SELECT = \"%s\";" % choice(["GENCLK", "GENCLK_HALF", "SHIFTREG_90deg", "SHIFTREG_0deg"])) | 
|  | elif pll_type.find("_2F_") < 0: | 
|  | pll_inst.append("defparam uut.PLLOUT_SELECT_PORTB = \"%s\";" % choice(["GENCLK", "GENCLK_HALF", "SHIFTREG_90deg", "SHIFTREG_0deg"])) | 
|  | else: | 
|  | pll_inst.append("defparam uut.PLLOUT_SELECT_PORTA = \"%s\";" % choice(["GENCLK", "GENCLK_HALF", "SHIFTREG_90deg", "SHIFTREG_0deg"])) | 
|  | pll_inst.append("defparam uut.PLLOUT_SELECT_PORTB = \"%s\";" % choice(["GENCLK", "GENCLK_HALF", "SHIFTREG_90deg", "SHIFTREG_0deg"])) | 
|  |  | 
|  | if pll_type.find("_2_") < 0 and pll_type.find("_2F_") < 0: | 
|  | pll_inst.append("defparam uut.ENABLE_ICEGATE = 1'b0;") | 
|  | else: | 
|  | pll_inst.append("defparam uut.ENABLE_ICEGATE_PORTA = 1'b0;") | 
|  | pll_inst.append("defparam uut.ENABLE_ICEGATE_PORTB = 1'b0;") | 
|  |  | 
|  | pll_inst.append("defparam uut.TEST_MODE = 1'b0;") | 
|  |  | 
|  | with open(working_dir + "/pll_%02d.v" % idx, "w") as f: | 
|  | print("module top(%s);" % ", ".join(pin_names), file=f) | 
|  | print("\n".join(vlog_body), file=f) | 
|  | print("\n".join(pll_inst), file=f) | 
|  | print("endmodule", file=f) | 
|  |  | 
|  | with open(working_dir + "/pll_%02d.pcf" % idx, "w") as f: | 
|  | for pll_pin, package_pin in zip(pin_names, list(permutation(pins))[0:len(pin_names)]): | 
|  | if pll_pin == "packagepin": package_pin = "49" | 
|  | print("set_io %s %s" % (pll_pin, package_pin), file=f) | 
|  |  | 
|  |  | 
|  | output_makefile(working_dir, "pll") | 
|  |  |