mirror of https://github.com/YosysHQ/icestorm.git
Create icefuzz scripts for DSP and 5k
This commit is contained in:
parent
629621642f
commit
96b527bfef
|
|
@ -42,8 +42,11 @@ ifneq ($(DEVICECLASS),384)
|
|||
TESTS += pll
|
||||
TESTS += aig
|
||||
endif
|
||||
|
||||
database: bitdata_io.txt bitdata_logic.txt bitdata_ramb$(RAM_SUFFIX).txt bitdata_ramt$(RAM_SUFFIX).txt
|
||||
ifeq ($(DEVICECLASS),5k)
|
||||
TESTS += dsp
|
||||
TESTS += upip
|
||||
endif
|
||||
database: bitdata_io.txt bitdata_logic.txt bitdata_ramb$(RAM_SUFFIX).txt bitdata_ramt$(RAM_SUFFIX).txt bitdata_dsp0_5k.txt bitdata_dsp1_5k.txt bitdata_dsp2_5k.txt bitdata_dsp3_5k.txt bitdata_ipcon_5k.txt
|
||||
ifneq ($(RAM_SUFFIX),)
|
||||
cp cached_ramb.txt bitdata_ramb.txt
|
||||
cp cached_ramt.txt bitdata_ramt.txt
|
||||
|
|
@ -135,19 +138,19 @@ bitdata_ramt$(RAM_SUFFIX).txt: data_cached.txt $(addprefix data_$(DEVICECLASS)_,
|
|||
grep ^ramt$(RAM_SUFFIX) $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
|
||||
|
||||
bitdata_dsp0_5k.txt: data_cached.txt $(addprefix data_$(DEVICECLASS)_,$(addsuffix .txt,$(TESTS)))
|
||||
grep ^dsp0_5k$(RAM_SUFFIX) $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
|
||||
grep ^dsp0_5k $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
|
||||
|
||||
bitdata_dsp1_5k.txt: data_cached.txt $(addprefix data_$(DEVICECLASS)_,$(addsuffix .txt,$(TESTS)))
|
||||
grep ^dsp1_5k$(RAM_SUFFIX) $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
|
||||
grep ^dsp1_5k $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
|
||||
|
||||
bitdata_dsp2_5k.txt: data_cached.txt $(addprefix data_$(DEVICECLASS)_,$(addsuffix .txt,$(TESTS)))
|
||||
grep ^dsp2_5k$(RAM_SUFFIX) $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
|
||||
grep ^dsp2_5k $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
|
||||
|
||||
bitdata_dsp3_5k.txt: data_cached.txt $(addprefix data_$(DEVICECLASS)_,$(addsuffix .txt,$(TESTS)))
|
||||
grep ^dsp3_5k$(RAM_SUFFIX) $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
|
||||
grep ^dsp3_5k $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
|
||||
|
||||
bitdata_ipcon_5k.txt: data_cached.txt $(addprefix data_$(DEVICECLASS)_,$(addsuffix .txt,$(TESTS)))
|
||||
grep ^ipcon_5k$(RAM_SUFFIX) $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
|
||||
grep ^ipcon_5k $^ | tr -s ' ' | tr -d '\r' | cut -f2- -d' ' | sort -u > $@
|
||||
|
||||
datafiles: $(addprefix data_,$(addsuffix .txt,$(TESTS)))
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -28,7 +28,7 @@ def read_database(filename, tile_type):
|
|||
line = re.sub(r"^Ram config bit:", "RamConfig", line)
|
||||
line = re.sub(r"^PLL config bit:", "PLL", line)
|
||||
line = re.sub(r"^Icegate Enable bit:", "Icegate", line)
|
||||
line = re.sub(r"^MAC16 functional bit:", "DspConfig", line)
|
||||
line = re.sub(r"^MAC16 functional bit:", "IpConfig", line)
|
||||
line = re.sub(r"^Hard IP config bit:", "IpConfig", line)
|
||||
|
||||
line = line.split()
|
||||
|
|
@ -57,14 +57,14 @@ def read_database(filename, tile_type):
|
|||
elif line[0] == "ColBufCtrl":
|
||||
line[1] = re.sub(r"B?IO(LEFT|RIGHT)_", "IO_", line[1])
|
||||
line[1] = re.sub(r"IO_half_column_clock_enable_", "glb_netwk_", line[1])
|
||||
line[1] = re.sub(r"(LH|MEM[BT])_colbuf_cntl_", "glb_netwk_", line[1])
|
||||
line[1] = re.sub(r"(LH|MEM[BT]|MULT\d|IPCON)_colbuf_cntl_", "glb_netwk_", line[1])
|
||||
if m.group(1) == "7":
|
||||
line[1] = re.sub(r"glb_netwk_", "8k_glb_netwk_", line[1])
|
||||
elif m.group(1) in ["1", "2"]:
|
||||
line[1] = re.sub(r"glb_netwk_", "1k_glb_netwk_", line[1])
|
||||
raw_db.append((bit, (line[0], line[1])))
|
||||
elif line[0] == "Cascade":
|
||||
match = re.match("(MULT\d|LH)_LC0(\d)_inmux02_5", line[1])
|
||||
match = re.match("LH_LC0(\d)_inmux02_5", line[1])
|
||||
if match:
|
||||
raw_db.append((bit, ("buffer", "wire_logic_cluster/lc_%d/lout" % (int(match.group(1))-1), "input_2_%s" % match.group(1))))
|
||||
else:
|
||||
|
|
@ -90,11 +90,10 @@ def read_database(filename, tile_type):
|
|||
raw_db.append((bit, (line[0],)))
|
||||
elif line[0] == "Carry_In_Mux":
|
||||
continue
|
||||
elif line[0] == "DspConfig":
|
||||
line[1] = re.sub(r"MULT\d_bram_cbit_", "CBIT_", line[1])
|
||||
elif line[0] == "IpConfig":
|
||||
line[1] = re.sub(r"MULT\d_bram_cbit_", "CBIT_", line[1]) #not a typo, sometimes IP config bits are in DSP tiles and use a MULT prefix...
|
||||
line[1] = re.sub(r"IPCON_bram_cbit_", "CBIT_", line[1])
|
||||
line[1] = re.sub(r"IPCON_bram_cbit_", "CBIT_", line[1])
|
||||
raw_db.append((bit, (line[0], line[1])))
|
||||
else:
|
||||
print("unsupported statement: %s: %s" % (bit, line))
|
||||
assert False
|
||||
|
|
@ -157,11 +156,11 @@ for device_class in ["5k", "8k"]:
|
|||
with open("database_ramt_%s.txt" % (device_class, ), "w") as f:
|
||||
for entry in read_database("bitdata_ramt_%s.txt" % (device_class, ), "ramt_" + device_class):
|
||||
print("\t".join(entry), file=f)
|
||||
if device_class == "5k":
|
||||
for dsp_idx in range(4):
|
||||
with open("database_dsp%d_5k.txt" % (dsp_idx, ), "w") as f:
|
||||
for entry in read_database("bitdata_dsp%d_5k.txt" % (dsp_idx, ), "dsp%d_5" % (dsp_idx, )):
|
||||
print("\t".join(entry), file=f)
|
||||
with open("database_ipcon.txt", "w") as f:
|
||||
for entry in read_database("bitdata_ipcon.txt", "ipcon"):
|
||||
print("\t".join(entry), file=f)
|
||||
|
||||
for dsp_idx in range(4):
|
||||
with open("database_dsp%d_5k.txt" % (dsp_idx, ), "w") as f:
|
||||
for entry in read_database("bitdata_dsp%d_5k.txt" % (dsp_idx, ), "dsp%d_5" % (dsp_idx, )):
|
||||
print("\t".join(entry), file=f)
|
||||
with open("database_ipcon_5k.txt", "w") as f:
|
||||
for entry in read_database("bitdata_ipcon_5k.txt", "ipcon"):
|
||||
print("\t".join(entry), file=f)
|
||||
|
|
@ -7,6 +7,7 @@ device_class = os.getenv("ICEDEVICE")
|
|||
if device_class == "8k":
|
||||
num_ramb40 = 32
|
||||
num_iobanks = 4
|
||||
num_dsp = 0
|
||||
|
||||
pins="""
|
||||
A1 A2 A5 A6 A7 A9 A10 A11 A15 A16
|
||||
|
|
@ -32,6 +33,7 @@ if device_class == "8k":
|
|||
elif device_class == "384":
|
||||
num_ramb40 = 0
|
||||
num_iobanks = 3
|
||||
num_dsp = 0
|
||||
|
||||
pins = """
|
||||
A1 A2 A3 A4 A5 A6 A7
|
||||
|
|
@ -48,6 +50,7 @@ elif device_class == "384":
|
|||
elif device_class == "1k":
|
||||
num_ramb40 = 16
|
||||
num_iobanks = 4
|
||||
num_dsp = 0
|
||||
|
||||
pins = """
|
||||
1 2 3 4 7 8 9 10 11 12 19 22 23 24 25 26 28 29 31 32 33 34
|
||||
|
|
@ -60,7 +63,8 @@ elif device_class == "1k":
|
|||
elif device_class == "5k":
|
||||
num_ramb40 = 30
|
||||
num_iobanks = 2
|
||||
|
||||
num_dsp = 8
|
||||
num_spram256ka = 4
|
||||
#TODO(tannewt): Add 39, 40, 41 to this list. It causes placement failures for some reason.
|
||||
# Also add 14 15 16 17 which are constrained to SPI.
|
||||
#TODO(daveshah1): Add back I3C IO 23 which cause placement failures when assigned to
|
||||
|
|
@ -73,7 +77,7 @@ elif device_class == "5k":
|
|||
|
||||
#TODO(tannewt): Add 39, 40, 41 to this list. It causes placement failures for some reason.
|
||||
gpins = "20 35 37 44".split()
|
||||
|
||||
led_pins = "39 40 41".split()
|
||||
def output_makefile(working_dir, fuzzname):
|
||||
with open(working_dir + "/Makefile", "w") as f:
|
||||
print("all: %s" % " ".join(["%s_%02d.bin" % (fuzzname, i) for i in range(num)]), file=f)
|
||||
|
|
|
|||
|
|
@ -6,26 +6,32 @@ asc_bits = set()
|
|||
glb_bits = set()
|
||||
|
||||
# parsing .asc file
|
||||
with open(argv[1]) as f:
|
||||
current_tile = None
|
||||
current_line = None
|
||||
for line in f:
|
||||
if line.startswith("."):
|
||||
if line.find("_tile ") >= 0:
|
||||
f = line.split()
|
||||
current_tile = "%02d.%02d" % (int(f[1]), int(f[2]))
|
||||
current_line = 0
|
||||
else:
|
||||
current_tile = None
|
||||
current_line = None
|
||||
continue
|
||||
|
||||
if current_tile is not None:
|
||||
for i in range(len(line)):
|
||||
if line[i] == '1':
|
||||
asc_bits.add("%s.%02d.%02d" % (current_tile, current_line, i))
|
||||
current_line += 1
|
||||
try:
|
||||
with open(argv[1]) as f:
|
||||
current_tile = None
|
||||
current_line = None
|
||||
for line in f:
|
||||
if line.startswith("."):
|
||||
if line.find("_tile ") >= 0:
|
||||
f = line.split()
|
||||
current_tile = "%02d.%02d" % (int(f[1]), int(f[2]))
|
||||
current_line = 0
|
||||
else:
|
||||
current_tile = None
|
||||
current_line = None
|
||||
continue
|
||||
|
||||
if current_tile is not None:
|
||||
for i in range(len(line)):
|
||||
if line[i] == '1':
|
||||
asc_bits.add("%s.%02d.%02d" % (current_tile, current_line, i))
|
||||
current_line += 1
|
||||
except FileNotFoundError:
|
||||
print("ASC file doesn't exist, skipping glbcheck!.")
|
||||
# The asc file may not exist for innocent reasons, such as
|
||||
# the icecube router failing. So exit with code 0 to keep
|
||||
# the fuzz Makefile happy
|
||||
exit(0)
|
||||
# parsing .glb file
|
||||
with open(argv[2]) as f:
|
||||
current_tile = None
|
||||
|
|
|
|||
|
|
@ -0,0 +1,206 @@
|
|||
#!/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_dsp" % (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)])
|
||||
|
||||
#Only certain combinations are allowed in icecube, list them here
|
||||
#This is not a complete set, but enough to cover all bits except cbit13, which
|
||||
#is not set in any allowed config (?)
|
||||
allowed_configs = ["0010000010000001001110110", "1110000010000001001110110", "0010000010000001000000000", "1110000010000001000000000",
|
||||
"0000000011000001111110110", "1100000011000001111110110", "0000000011000001110000110", "0010000101000010111111111",
|
||||
"0000001001100100111111111", "0001001001100100111111111", "0001101001100100111111111", "0001111000101100000000000"]
|
||||
|
||||
coverage = set()
|
||||
for c in allowed_configs:
|
||||
for i in range(25):
|
||||
if c[i] == "1":
|
||||
coverage.add(i)
|
||||
|
||||
assert len(coverage) >= 24
|
||||
|
||||
#print(len(coverage))
|
||||
#print(coverage)
|
||||
|
||||
for idx in range(num):
|
||||
with open(working_dir + "/dsp_%02d.v" % idx, "w") as f:
|
||||
glbs = ["glb[%d]" % i for i in range(np.random.randint(8)+1)]
|
||||
# TODO: ce should be on this list, but causes routing failures
|
||||
glbs_choice = ["clk", "a", "b", "c", "d,", "ah", "bh", "ch", "dh", "irt", "irb", "ort", "orb", "olt", "olb", "ast", "asb", "oht", "ohb", "sei"]
|
||||
print("""
|
||||
module top (
|
||||
input [%d:0] glb_pins,
|
||||
input [%d:0] in_pins,
|
||||
output [15:0] out_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(glbs)-1, len(glbs)-1), file=f)
|
||||
bits = ["in_pins[%d]" % i for i in range(100)]
|
||||
bits = list(np.random.permutation(bits))
|
||||
for i in range(num_dsp):
|
||||
tmp = list(np.random.permutation(bits))
|
||||
bits_c = [tmp.pop() for k in range(16)]
|
||||
bits_a = [tmp.pop() for k in range(16)]
|
||||
bits_b = [tmp.pop() for k in range(16)]
|
||||
bits_d = [tmp.pop() for k in range(16)]
|
||||
bit_ce = tmp.pop()
|
||||
bit_clk = tmp.pop()
|
||||
bit_ahold = tmp.pop()
|
||||
bit_bhold = tmp.pop()
|
||||
bit_chold = tmp.pop()
|
||||
bit_dhold = tmp.pop()
|
||||
bit_irsttop = tmp.pop()
|
||||
bit_irstbot = tmp.pop()
|
||||
bit_orsttop = tmp.pop()
|
||||
bit_orstbot = tmp.pop()
|
||||
bit_oloadtop = tmp.pop()
|
||||
bit_oloadbot = tmp.pop()
|
||||
bit_addsubtop = tmp.pop()
|
||||
bit_addsubbot = tmp.pop()
|
||||
bit_oholdtop = tmp.pop()
|
||||
bit_oholdbot = tmp.pop()
|
||||
|
||||
aci_opts = ["1'b0"]
|
||||
if i > 0 and i % 4 != 0:
|
||||
aci_opts.append("out_%d[33]" % (i-1));
|
||||
sei_opts = ["1'b0"]
|
||||
if i > 0 and i % 4 != 0:
|
||||
sei_opts.append("out_%d[34]" % (i - 1));
|
||||
|
||||
bit_ci = tmp.pop()
|
||||
bit_accumci = np.random.choice(aci_opts)
|
||||
bit_signextin = np.random.choice(sei_opts)
|
||||
|
||||
if len(glbs) != 0:
|
||||
s = np.random.choice(glbs_choice)
|
||||
glbs_choice.remove(s)
|
||||
if s == "clk": bit_clk = glbs.pop()
|
||||
if s == "a": bits_a[np.random.randint(len(bits_a))] = glbs.pop()
|
||||
if s == "b": bits_b[np.random.randint(len(bits_b))] = glbs.pop()
|
||||
if s == "c": bits_c[np.random.randint(len(bits_c))] = glbs.pop()
|
||||
if s == "d": bits_d[np.random.randint(len(bits_d))] = glbs.pop()
|
||||
if s == "ah": bit_ahold = glbs.pop()
|
||||
if s == "bh": bit_bhold = glbs.pop()
|
||||
if s == "ch": bit_chold = glbs.pop()
|
||||
if s == "dh": bit_dhold = glbs.pop()
|
||||
if s == "irt": bit_irsttop = glbs.pop()
|
||||
if s == "irb": bit_irstbot = glbs.pop()
|
||||
if s == "ort": bit_orsttop = glbs.pop()
|
||||
if s == "orb": bit_orstbot = glbs.pop()
|
||||
if s == "olt": bit_oloadtop = glbs.pop()
|
||||
if s == "olb": bit_oloadbot = glbs.pop()
|
||||
if s == "ast": bit_addsubtop = glbs.pop()
|
||||
if s == "asb": bit_addsubbot = glbs.pop()
|
||||
if s == "oht": bit_oholdtop = glbs.pop()
|
||||
if s == "ohb": bit_oholdbot = glbs.pop()
|
||||
if s == "ci": bit_ci = glbs.pop()
|
||||
|
||||
|
||||
bits_a = "{%s}" % ", ".join(bits_a)
|
||||
bits_b = "{%s}" % ", ".join(bits_b)
|
||||
bits_c = "{%s}" % ", ".join(bits_c)
|
||||
bits_d = "{%s}" % ", ".join(bits_d)
|
||||
|
||||
negclk = randbin(1)
|
||||
params = np.random.choice(allowed_configs)
|
||||
params = params[::-1]
|
||||
print("""
|
||||
wire [34:0] out_%d;
|
||||
SB_MAC16 #(
|
||||
.NEG_TRIGGER(1'b%s),
|
||||
.C_REG(1'b%s),
|
||||
.A_REG(1'b%s),
|
||||
.B_REG(1'b%s),
|
||||
.D_REG(1'b%s),
|
||||
.TOP_8x8_MULT_REG(1'b%s),
|
||||
.BOT_8x8_MULT_REG(1'b%s),
|
||||
.PIPELINE_16x16_MULT_REG1(1'b%s),
|
||||
.PIPELINE_16x16_MULT_REG2(1'b%s),
|
||||
.TOPOUTPUT_SELECT(2'b%s),
|
||||
.TOPADDSUB_LOWERINPUT(2'b%s),
|
||||
.TOPADDSUB_UPPERINPUT(1'b%s),
|
||||
.TOPADDSUB_CARRYSELECT(2'b%s),
|
||||
.BOTOUTPUT_SELECT(2'b%s),
|
||||
.BOTADDSUB_LOWERINPUT(2'b%s),
|
||||
.BOTADDSUB_UPPERINPUT(1'b%s),
|
||||
.BOTADDSUB_CARRYSELECT(2'b%s),
|
||||
.MODE_8x8(1'b%s),
|
||||
.A_SIGNED(1'b%s),
|
||||
.B_SIGNED(1'b%s)
|
||||
) dsp_%d (
|
||||
.CLK(%s),
|
||||
.CE(%s),
|
||||
.C(%s),
|
||||
.A(%s),
|
||||
.B(%s),
|
||||
.D(%s),
|
||||
.AHOLD(%s),
|
||||
.BHOLD(%s),
|
||||
.CHOLD(%s),
|
||||
.DHOLD(%s),
|
||||
.IRSTTOP(%s),
|
||||
.IRSTBOT(%s),
|
||||
.ORSTTOP(%s),
|
||||
.ORSTBOT(%s),
|
||||
.OLOADTOP(%s),
|
||||
.OLOADBOT(%s),
|
||||
.ADDSUBTOP(%s),
|
||||
.ADDSUBBOT(%s),
|
||||
.OHOLDTOP(%s),
|
||||
.OHOLDBOT(%s),
|
||||
.CI(%s),
|
||||
.ACCUMCI(%s),
|
||||
.SIGNEXTIN(%s),
|
||||
.O(out_%d[31:0]),
|
||||
.CO(out_%d[32]),
|
||||
.ACCUMCO(out_%d[33]),
|
||||
.SIGNEXTOUT(out_%d[34])
|
||||
);"""
|
||||
% (
|
||||
i,
|
||||
negclk,
|
||||
params[0], params[1], params[2], params[3],
|
||||
params[4], params[5], params[6], params[7],
|
||||
params[8:10][::-1], params[10:12][::-1], params[12], params[13:15][::-1],
|
||||
params[15:17][::-1], params[17:19][::-1], params[19], params[20:22][::-1],
|
||||
params[22], params[23], params[24],
|
||||
i,
|
||||
bit_clk, bit_ce, bits_c, bits_a, bits_b, bits_d,
|
||||
bit_ahold, bit_bhold, bit_chold, bit_dhold,
|
||||
bit_irsttop, bit_irstbot, bit_orsttop, bit_orstbot,
|
||||
bit_oloadtop, bit_oloadbot, bit_addsubtop, bit_addsubbot,
|
||||
bit_oholdtop, bit_oholdbot,
|
||||
bit_ci, bit_accumci, bit_signextin,
|
||||
i, i, i, i
|
||||
), file=f)
|
||||
bits = list(np.random.permutation(bits))
|
||||
for k in range(33):
|
||||
bits[k] = "out_%d[%d] ^ %s" % (i, k, bits[k])
|
||||
for k in range(16):
|
||||
print("assign out_pins[%d] = out_%d[%d] ^ out_%d[%d];" % (k, i, np.random.randint(33), i, np.random.randint(33)), file=f)
|
||||
print("endmodule", file=f)
|
||||
with open(working_dir + "/dsp_%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)
|
||||
|
||||
|
||||
output_makefile(working_dir, "dsp")
|
||||
|
|
@ -0,0 +1,218 @@
|
|||
#!/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")
|
||||
Loading…
Reference in New Issue