|  | #!/usr/bin/env python3 | 
|  |  | 
|  | from fuzzconfig import * | 
|  | import numpy as np | 
|  | import os | 
|  |  | 
|  | device_class = os.getenv("ICEDEVICE") | 
|  |  | 
|  | assert device_class == "5k" | 
|  |  | 
|  | working_dir = "work_%s_upip" % (device_class, ) | 
|  |  | 
|  | os.system("rm -rf " + working_dir) | 
|  | os.mkdir(working_dir) | 
|  | def randbin(n): | 
|  | return  "".join([np.random.choice(["0", "1"]) for i in range(n)]) | 
|  | for idx in range(num): | 
|  | with open(working_dir + "/upip_%02d.v" % idx, "w") as f: | 
|  | glbs = ["glb[%d]" % i for i in range(np.random.randint(6)+1)] | 
|  |  | 
|  | print(""" | 
|  | module top ( | 
|  | input  [%d:0] glb_pins, | 
|  | input  [%d:0] in_pins, | 
|  | output [15:0] out_pins, | 
|  | output [%d:0] led_pins | 
|  | ); | 
|  | wire [%d:0] glb, glb_pins; | 
|  | SB_GB gbufs [%d:0] ( | 
|  | .USER_SIGNAL_TO_GLOBAL_BUFFER(glb_pins), | 
|  | .GLOBAL_BUFFER_OUTPUT(glb) | 
|  | ); | 
|  | """ % (len(glbs)-1, len(pins) - len(glbs) - 16 - 1, len(led_pins)-1, len(glbs)-1, len(glbs)-1), file=f) | 
|  | bits = ["in_pins[%d]" % (i % (len(pins) - len(glbs) - 16 - 1)) for i in range(60)] | 
|  | bits = list(np.random.permutation(bits)) | 
|  | #Internal oscillators | 
|  | tmp =  ["in_pins[%d]" % i for i in range(len(pins) - len(glbs) - 16 - 1)] | 
|  | tmp = list(np.random.permutation(tmp)) | 
|  | for osc in ["LF", "HF"]: | 
|  | bit_pu = tmp.pop() | 
|  | bit_en = tmp.pop() | 
|  | bit_clk = "clk_" + osc | 
|  | glbs.append(bit_clk) | 
|  | param = "" | 
|  | if osc == "HF": #only HFOSC has a divider: | 
|  | param = "#(.CLKHF_DIV(\"0b%s\"))" % randbin(2) | 
|  |  | 
|  | route = np.random.choice(["", "/* synthesis ROUTE_THROUGH_FABRIC = 1 */"]) | 
|  |  | 
|  | print(""" | 
|  | SB_%sOSC %s osc_%s ( | 
|  | .CLK%sPU(%s), | 
|  | .CLK%sEN(%s), | 
|  | .CLK%s(%s) | 
|  | ) %s; | 
|  | """ % ( | 
|  | osc, param, osc, osc, bit_pu, | 
|  | osc, bit_en, osc, bit_clk, route | 
|  | ), file=f) | 
|  | glbs_orig = list(glbs) | 
|  | #256k SPRAM blocks | 
|  | for i in range(num_spram256ka): | 
|  | tmp = list(np.random.permutation(bits)) | 
|  |  | 
|  | bits_addr       = [tmp.pop() for k in range(14)] | 
|  | bits_mask       = [tmp.pop() for k in range(4)] | 
|  | bits_wdata      = [tmp.pop() for k in range(16)] | 
|  | bit_wren        = tmp.pop() | 
|  | bit_cs          = tmp.pop() | 
|  | bit_clock       = tmp.pop() | 
|  | bit_standby     = tmp.pop() | 
|  | bit_sleep       = tmp.pop() | 
|  | bit_poweroff    = tmp.pop() | 
|  |  | 
|  | glbs_choice = ["clk", "a", "msk", "wd", "we", "cs", "stb", "slp", "po"] | 
|  |  | 
|  | if len(glbs) != 0: | 
|  | s = np.random.choice(glbs_choice) | 
|  | glbs_choice.remove(s) | 
|  | if s == "clk":  bit_clock       = glbs.pop() | 
|  | if s == "a":    bits_addr[np.random.randint(len(bits_addr))] = glbs.pop() | 
|  | if s == "msk":  bits_mask [np.random.randint(len(bits_mask ))] = glbs.pop() | 
|  | if s == "wd":   bits_wdata[np.random.randint(len(bits_wdata))] = glbs.pop() | 
|  | if s == "we":   bit_wren        = glbs.pop() | 
|  | if s == "cs":   bit_cs          = glbs.pop() | 
|  | if s == "stb":  bit_standby     = glbs.pop() | 
|  | if s == "slp":  bit_sleep       = glbs.pop() | 
|  | if s == "po":   bit_poweroff    = glbs.pop() | 
|  | bits_addr = "{%s}" % ", ".join(bits_addr) | 
|  | bits_mask  = "{%s}" % ", ".join(bits_mask) | 
|  | bits_wdata = "{%s}" % ", ".join(bits_wdata) | 
|  |  | 
|  | print(""" | 
|  | wire [15:0] rdata_%d; | 
|  | SB_SPRAM256KA spram_%d ( | 
|  | .ADDRESS(%s), | 
|  | .DATAIN(%s), | 
|  | .MASKWREN(%s), | 
|  | .WREN(%s), | 
|  | .CHIPSELECT(%s), | 
|  | .CLOCK(%s), | 
|  | .STANDBY(%s), | 
|  | .SLEEP(%s), | 
|  | .POWEROFF(%s), | 
|  | .DATAOUT(rdata_%d) | 
|  | ); | 
|  | """ % ( | 
|  | i, i, | 
|  | bits_addr, bits_wdata, bits_mask, bit_wren, | 
|  | bit_cs, bit_clock, bit_standby, bit_sleep, | 
|  | bit_poweroff, i | 
|  | ), file=f) | 
|  | bits = list(np.random.permutation(bits)) | 
|  | if np.random.choice(["XOR", "MULT"]) == "MULT": | 
|  | #stress routing at sides more with a multiply | 
|  | print(""" | 
|  | wire [31:0] mult_res_%d; | 
|  | assign mult_res_%d = rdata_%d * %s; | 
|  | """ % ( | 
|  | i, i, i, ("{%s}" % ", ".join(bits[0:32])) | 
|  | ), file=f) | 
|  | for k in range(32): | 
|  | bits[k] = "mult_res_%d[%d]" % (i, k) | 
|  | else: | 
|  | for k in range(16): | 
|  | bits[k] = "rdata_%d[%d] ^ %s" % (i, k, bits[k]) | 
|  |  | 
|  | # Internal PWM IP | 
|  | tmp = list(np.random.permutation(bits)) | 
|  | glbs = list(glbs_orig) | 
|  | bit_cs = tmp.pop() | 
|  | bit_clk = np.random.choice([glbs.pop(), tmp.pop()]) | 
|  | bit_rst = np.random.choice([glbs.pop(), tmp.pop()]) | 
|  | bit_den = tmp.pop() | 
|  | bit_exe = tmp.pop() | 
|  |  | 
|  | bits_dat = [tmp.pop() for k in range(8)] | 
|  | bits_addr = [tmp.pop() for k in range(4)] | 
|  |  | 
|  | print(""" | 
|  | wire [2:0] pwm_out; | 
|  | SB_LEDDA_IP ledda ( | 
|  | .LEDDCS(%s), | 
|  | .LEDDCLK(%s), | 
|  | .LEDDDAT7(%s), | 
|  | .LEDDDAT6(%s), | 
|  | .LEDDDAT5(%s), | 
|  | .LEDDDAT4(%s), | 
|  | .LEDDDAT3(%s), | 
|  | .LEDDDAT2(%s), | 
|  | .LEDDDAT1(%s), | 
|  | .LEDDDAT0(%s), | 
|  | .LEDDADDR3(%s), | 
|  | .LEDDADDR2(%s), | 
|  | .LEDDADDR1(%s), | 
|  | .LEDDADDR0(%s), | 
|  | .LEDDDEN(%s), | 
|  | .LEDDEXE(%s), | 
|  | .LEDDRST(%s), | 
|  | .PWMOUT0(pwm_out[0]), | 
|  | .PWMOUT1(pwm_out[1]), | 
|  | .PWMOUT2(pwm_out[2]) | 
|  | ); | 
|  | """ % ( | 
|  | bit_cs, bit_clk, bits_dat[7], bits_dat[6], bits_dat[5], bits_dat[4], | 
|  | bits_dat[3], bits_dat[2], bits_dat[1], bits_dat[0], bits_addr[3], | 
|  | bits_addr[2], bits_addr[1], bits_addr[0], bit_den, bit_exe, bit_rst | 
|  | ), file=f) | 
|  |  | 
|  | bits.append("pwm_out[0]") | 
|  | bits.append("pwm_out[1]") | 
|  | bits.append("pwm_out[2]") | 
|  |  | 
|  | # Constant current LED driver | 
|  | current_choices = ["0b000000", "0b000001", "0b000011", "0b000111", "0b001111", "0b011111", "0b111111"] | 
|  | current_modes = ["0b0", "0b1"] | 
|  |  | 
|  | currents = [np.random.choice(current_choices) for i in range(3)] | 
|  |  | 
|  | bit_curren = np.random.choice(bits) | 
|  | bit_rgbleden = np.random.choice(bits) | 
|  | bits_pwm = [np.random.choice([np.random.choice(bits), "pwm_out[%d]" % i]) for i in range(3)] | 
|  |  | 
|  | print(""" | 
|  | SB_RGBA_DRV #( | 
|  | .CURRENT_MODE(\"%s\"), | 
|  | .RGB0_CURRENT(\"%s\"), | 
|  | .RGB1_CURRENT(\"%s\"), | 
|  | .RGB2_CURRENT(\"%s\") | 
|  | ) rgba_drv ( | 
|  | .CURREN(%s), | 
|  | .RGBLEDEN(%s), | 
|  | .RGB0PWM(%s), | 
|  | .RGB1PWM(%s), | 
|  | .RGB2PWM(%s), | 
|  | .RGB0(led_pins[0]), | 
|  | .RGB1(led_pins[1]), | 
|  | .RGB2(led_pins[2]) | 
|  | ); | 
|  | """ % ( | 
|  | np.random.choice(current_modes), currents[0], currents[1], currents[2], | 
|  | bit_curren, bit_rgbleden, bits_pwm[0], bits_pwm[1], bits_pwm[2] | 
|  | ), file = f) | 
|  |  | 
|  | # TODO: I2C and SPI | 
|  |  | 
|  | print("assign out_pins = rdata_%d;" % i, file=f) | 
|  | print("endmodule", file=f) | 
|  | with open(working_dir + "/upip_%02d.pcf" % idx, "w") as f: | 
|  | p = list(np.random.permutation(pins)) | 
|  | for i in range(len(pins) - len(glbs) - 16): | 
|  | print("set_io in_pins[%d] %s" % (i, p.pop()), file=f) | 
|  | for i in range(16): | 
|  | print("set_io out_pins[%d] %s" % (i, p.pop()), file=f) | 
|  | for i in range(len(led_pins)): | 
|  | print("set_io led_pins[%d] %s" % (i, led_pins[i]), file=f) | 
|  |  | 
|  | output_makefile(working_dir, "upip") |