| #!/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") |