mirror of https://github.com/YosysHQ/icestorm.git
Merge branch 'daveshah1-u5k'
This commit is contained in:
commit
3ba18d0017
|
|
@ -0,0 +1,4 @@
|
|||
example.bin
|
||||
example.blif
|
||||
example.asc
|
||||
example.rpt
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
PROJ = example
|
||||
PIN_DEF = up5k.pcf
|
||||
DEVICE = up5k
|
||||
# Relative paths for easier development without messing with installed version
|
||||
ARACHNE = ../../../arachne-pnr/bin/arachne-pnr
|
||||
ARACHNE_ARGS = -c ../../icebox/chipdb-5k.txt
|
||||
ICEPACK = ../../icepack/icepack
|
||||
ICETIME = ../../icetime/icetime
|
||||
ICEPROG = ../../iceprog/iceprog
|
||||
|
||||
all: $(PROJ).bin
|
||||
|
||||
%.blif: %.v
|
||||
yosys -p 'synth_ice40 -top top -blif $@' $<
|
||||
|
||||
%.asc: $(PIN_DEF) %.blif
|
||||
$(ARACHNE) $(ARACHNE_ARGS) -d $(subst up,,$(subst hx,,$(subst lp,,$(DEVICE)))) -o $@ -p $^
|
||||
|
||||
%.bin: %.asc
|
||||
$(ICEPACK) $< $@
|
||||
|
||||
%.rpt: %.asc
|
||||
$(ICETIME) -d $(DEVICE) -mtr $@ $<
|
||||
|
||||
prog: $(PROJ).bin
|
||||
$(ICEPROG) -S $<
|
||||
|
||||
sudo-prog: $(PROJ).bin
|
||||
@echo 'Executing prog as root!!!'
|
||||
sudo $(ICEPROG) -S $<
|
||||
|
||||
clean:
|
||||
rm -f $(PROJ).blif $(PROJ).asc $(PROJ).rpt $(PROJ).bin
|
||||
|
||||
.SECONDARY:
|
||||
.PHONY: all prog clean
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
module top (
|
||||
input btn,
|
||||
output LED0,
|
||||
output LED1,
|
||||
);
|
||||
|
||||
assign LED0 = !btn;
|
||||
assign LED1 = btn;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
set_io LED0 12
|
||||
set_io LED1 21
|
||||
set_io btn 26
|
||||
233
icebox/icebox.py
233
icebox/icebox.py
|
|
@ -80,12 +80,12 @@ class iceconfig:
|
|||
def setup_empty_5k(self):
|
||||
self.clear()
|
||||
self.device = "5k"
|
||||
self.max_x = 26
|
||||
self.max_y = 33
|
||||
self.max_x = 25
|
||||
self.max_y = 31
|
||||
|
||||
for x in range(1, self.max_x):
|
||||
for y in range(1, self.max_y):
|
||||
if x in (7, 20):
|
||||
if x in (6, 19):
|
||||
if y % 2 == 1:
|
||||
self.ramb_tiles[(x, y)] = ["0" * 42 for i in range(16)]
|
||||
else:
|
||||
|
|
@ -194,6 +194,20 @@ class iceconfig:
|
|||
entries.append((x, src_y, x, y))
|
||||
return entries
|
||||
|
||||
if self.device == "5k": #Interesting, seems the 5k has more colbufs?
|
||||
entries = list()
|
||||
for x in range(self.max_x+1):
|
||||
for y in range(self.max_y+1):
|
||||
src_y = None
|
||||
if 0 <= y <= 4: src_y = 4
|
||||
if 5 <= y <= 10: src_y = 5
|
||||
if 11 <= y <= 14: src_y = 14
|
||||
if 15 <= y <= 20: src_y = 15
|
||||
if 21 <= y <= 26: src_y = 26
|
||||
if 27 <= y <= 31: src_y = 27
|
||||
entries.append((x, src_y, x, y))
|
||||
return entries
|
||||
|
||||
if self.device == "384":
|
||||
entries = list()
|
||||
for x in range(self.max_x+1):
|
||||
|
|
@ -213,8 +227,13 @@ class iceconfig:
|
|||
if self.device in ["384", "1k", "8k"]:
|
||||
if x == 0: return iotile_l_db
|
||||
if x == self.max_x: return iotile_r_db
|
||||
if y == 0: return iotile_b_db
|
||||
if y == self.max_y: return iotile_t_db
|
||||
# The 5k needs an IO db including the extra bits
|
||||
if self.device == "5k":
|
||||
if y == 0: return iotile_b_5k_db
|
||||
if y == self.max_y: return iotile_t_5k_db
|
||||
else:
|
||||
if y == 0: return iotile_b_db
|
||||
if y == self.max_y: return iotile_t_db
|
||||
if self.device == "1k":
|
||||
if (x, y) in self.logic_tiles: return logictile_db
|
||||
if (x, y) in self.ramb_tiles: return rambtile_db
|
||||
|
|
@ -642,7 +661,7 @@ class iceconfig:
|
|||
expected_data_lines -= 1
|
||||
continue
|
||||
assert expected_data_lines <= 0
|
||||
if line[0] in (".io_tile", ".logic_tile", ".ramb_tile", ".ramt_tile", ".ram_data"):
|
||||
if line[0] in (".io_tile", ".logic_tile", ".ramb_tile", ".ramt_tile", ".ram_data", ".ipconn_tile", ".dsp1_tile", ".dsp2_tile", ".dsp3_tile", ".dsp4_tile"):
|
||||
current_data = list()
|
||||
expected_data_lines = 16
|
||||
self.max_x = max(self.max_x, int(line[1]))
|
||||
|
|
@ -1094,20 +1113,15 @@ def parse_db(text, device="1k"):
|
|||
for line in text.split("\n"):
|
||||
line_384 = line.replace("384_glb_netwk_", "glb_netwk_")
|
||||
line_1k = line.replace("1k_glb_netwk_", "glb_netwk_")
|
||||
line_5k = line.replace("5k_glb_netwk_", "glb_netwk_")
|
||||
line_8k = line.replace("8k_glb_netwk_", "glb_netwk_")
|
||||
if line_1k != line:
|
||||
if device != "1k":
|
||||
continue
|
||||
line = line_1k
|
||||
elif line_8k != line:
|
||||
if device != "8k":
|
||||
if device != "8k" and device != "5k": # global network is the same for 8k and 5k
|
||||
continue
|
||||
line = line_8k
|
||||
elif line_5k != line:
|
||||
if device != "5k":
|
||||
continue
|
||||
line = line_5k
|
||||
elif line_384 != line:
|
||||
if device != "384":
|
||||
continue
|
||||
|
|
@ -1173,15 +1187,15 @@ gbufin_db = {
|
|||
( 6, 0, 5),
|
||||
( 6, 17, 4),
|
||||
],
|
||||
"5k": [ # not sure how to get the third column, currently based on diagram in pdf.
|
||||
( 6, 0, 0),
|
||||
(12, 0, 1),
|
||||
(13, 0, 3),
|
||||
(19, 0, 6),
|
||||
( 6, 31, 5),
|
||||
(12, 31, 2),
|
||||
(13, 31, 7),
|
||||
(19, 31, 4),
|
||||
"5k": [
|
||||
( 6, 0, 6), #checked
|
||||
(12, 0, 5), #checked
|
||||
(13, 0, 7), #unknown
|
||||
(19, 0, 0), #checked
|
||||
( 6, 31, 3), #checked
|
||||
(12, 31, 4), #checked
|
||||
(13, 31, 1), #checked
|
||||
(19, 31, 2), #checked
|
||||
],
|
||||
"8k": [
|
||||
(33, 16, 7),
|
||||
|
|
@ -1275,7 +1289,6 @@ noplls_db = {
|
|||
"1k-cb121": [ "1k" ],
|
||||
"1k-vq100": [ "1k" ],
|
||||
"384-qn32": [ "384" ],
|
||||
"5k-sg48": [ "5k" ],
|
||||
}
|
||||
|
||||
pllinfo_db = {
|
||||
|
|
@ -1381,89 +1394,88 @@ pllinfo_db = {
|
|||
# 3'b110 = "SB_PLL40_2F_PAD"
|
||||
# 3'b011 = "SB_PLL40_CORE"
|
||||
# 3'b111 = "SB_PLL40_2F_CORE"
|
||||
"PLLTYPE_0": ( 16, 0, "PLLCONFIG_5"),
|
||||
"PLLTYPE_1": ( 18, 0, "PLLCONFIG_1"),
|
||||
"PLLTYPE_2": ( 18, 0, "PLLCONFIG_3"),
|
||||
"PLLTYPE_0": (12, 31, "PLLCONFIG_5"),
|
||||
"PLLTYPE_1": (14, 31, "PLLCONFIG_1"),
|
||||
"PLLTYPE_2": (14, 31, "PLLCONFIG_3"),
|
||||
|
||||
# 3'b000 = "DELAY"
|
||||
# 3'b001 = "SIMPLE"
|
||||
# 3'b010 = "PHASE_AND_DELAY"
|
||||
# 3'b110 = "EXTERNAL"
|
||||
"FEEDBACK_PATH_0": ( 18, 0, "PLLCONFIG_5"),
|
||||
"FEEDBACK_PATH_1": ( 15, 0, "PLLCONFIG_9"),
|
||||
"FEEDBACK_PATH_2": ( 16, 0, "PLLCONFIG_1"),
|
||||
"FEEDBACK_PATH_0": (14, 31, "PLLCONFIG_5"),
|
||||
"FEEDBACK_PATH_1": (11, 31, "PLLCONFIG_9"),
|
||||
"FEEDBACK_PATH_2": (12, 31, "PLLCONFIG_1"),
|
||||
|
||||
# 1'b0 = "FIXED"
|
||||
# 1'b1 = "DYNAMIC" (also set FDA_FEEDBACK=4'b1111)
|
||||
"DELAY_ADJMODE_FB": ( 17, 0, "PLLCONFIG_4"),
|
||||
"DELAY_ADJMODE_FB": (13, 31, "PLLCONFIG_4"),
|
||||
|
||||
# 1'b0 = "FIXED"
|
||||
# 1'b1 = "DYNAMIC" (also set FDA_RELATIVE=4'b1111)
|
||||
"DELAY_ADJMODE_REL": ( 17, 0, "PLLCONFIG_9"),
|
||||
"DELAY_ADJMODE_REL": (13, 31, "PLLCONFIG_9"),
|
||||
|
||||
# 2'b00 = "GENCLK"
|
||||
# 2'b01 = "GENCLK_HALF"
|
||||
# 2'b10 = "SHIFTREG_90deg"
|
||||
# 2'b11 = "SHIFTREG_0deg"
|
||||
"PLLOUT_SELECT_A_0": ( 16, 0, "PLLCONFIG_6"),
|
||||
"PLLOUT_SELECT_A_1": ( 16, 0, "PLLCONFIG_7"),
|
||||
|
||||
"PLLOUT_SELECT_A_0": (12, 31, "PLLCONFIG_6"),
|
||||
"PLLOUT_SELECT_A_1": (12, 31, "PLLCONFIG_7"),
|
||||
# 2'b00 = "GENCLK"
|
||||
# 2'b01 = "GENCLK_HALF"
|
||||
# 2'b10 = "SHIFTREG_90deg"
|
||||
# 2'b11 = "SHIFTREG_0deg"
|
||||
"PLLOUT_SELECT_B_0": ( 16, 0, "PLLCONFIG_2"),
|
||||
"PLLOUT_SELECT_B_1": ( 16, 0, "PLLCONFIG_3"),
|
||||
"PLLOUT_SELECT_B_0": (12, 31, "PLLCONFIG_2"),
|
||||
"PLLOUT_SELECT_B_1": (12, 31, "PLLCONFIG_3"),
|
||||
|
||||
# Numeric Parameters
|
||||
"SHIFTREG_DIV_MODE": ( 16, 0, "PLLCONFIG_4"),
|
||||
"FDA_FEEDBACK_0": ( 16, 0, "PLLCONFIG_9"),
|
||||
"FDA_FEEDBACK_1": ( 17, 0, "PLLCONFIG_1"),
|
||||
"FDA_FEEDBACK_2": ( 17, 0, "PLLCONFIG_2"),
|
||||
"FDA_FEEDBACK_3": ( 17, 0, "PLLCONFIG_3"),
|
||||
"FDA_RELATIVE_0": ( 17, 0, "PLLCONFIG_5"),
|
||||
"FDA_RELATIVE_1": ( 17, 0, "PLLCONFIG_6"),
|
||||
"FDA_RELATIVE_2": ( 17, 0, "PLLCONFIG_7"),
|
||||
"FDA_RELATIVE_3": ( 17, 0, "PLLCONFIG_8"),
|
||||
"DIVR_0": ( 14, 0, "PLLCONFIG_1"),
|
||||
"DIVR_1": ( 14, 0, "PLLCONFIG_2"),
|
||||
"DIVR_2": ( 14, 0, "PLLCONFIG_3"),
|
||||
"DIVR_3": ( 14, 0, "PLLCONFIG_4"),
|
||||
"DIVF_0": ( 14, 0, "PLLCONFIG_5"),
|
||||
"DIVF_1": ( 14, 0, "PLLCONFIG_6"),
|
||||
"DIVF_2": ( 14, 0, "PLLCONFIG_7"),
|
||||
"DIVF_3": ( 14, 0, "PLLCONFIG_8"),
|
||||
"DIVF_4": ( 14, 0, "PLLCONFIG_9"),
|
||||
"DIVF_5": ( 15, 0, "PLLCONFIG_1"),
|
||||
"DIVF_6": ( 15, 0, "PLLCONFIG_2"),
|
||||
"DIVQ_0": ( 15, 0, "PLLCONFIG_3"),
|
||||
"DIVQ_1": ( 15, 0, "PLLCONFIG_4"),
|
||||
"DIVQ_2": ( 15, 0, "PLLCONFIG_5"),
|
||||
"FILTER_RANGE_0": ( 15, 0, "PLLCONFIG_6"),
|
||||
"FILTER_RANGE_1": ( 15, 0, "PLLCONFIG_7"),
|
||||
"FILTER_RANGE_2": ( 15, 0, "PLLCONFIG_8"),
|
||||
"TEST_MODE": ( 16, 0, "PLLCONFIG_8"),
|
||||
"SHIFTREG_DIV_MODE": (12, 31, "PLLCONFIG_4"),
|
||||
"FDA_FEEDBACK_0": (12, 31, "PLLCONFIG_9"),
|
||||
"FDA_FEEDBACK_1": (13, 31, "PLLCONFIG_1"),
|
||||
"FDA_FEEDBACK_2": (13, 31, "PLLCONFIG_2"),
|
||||
"FDA_FEEDBACK_3": (13, 31, "PLLCONFIG_3"),
|
||||
"FDA_RELATIVE_0": (13, 31, "PLLCONFIG_5"),
|
||||
"FDA_RELATIVE_1": (13, 31, "PLLCONFIG_6"),
|
||||
"FDA_RELATIVE_2": (13, 31, "PLLCONFIG_7"),
|
||||
"FDA_RELATIVE_3": (13, 31, "PLLCONFIG_8"),
|
||||
"DIVR_0": (10, 31, "PLLCONFIG_1"),
|
||||
"DIVR_1": (10, 31, "PLLCONFIG_2"),
|
||||
"DIVR_2": (10, 31, "PLLCONFIG_3"),
|
||||
"DIVR_3": (10, 31, "PLLCONFIG_4"),
|
||||
"DIVF_0": (10, 31, "PLLCONFIG_5"),
|
||||
"DIVF_1": (10, 31, "PLLCONFIG_6"),
|
||||
"DIVF_2": (10, 31, "PLLCONFIG_7"),
|
||||
"DIVF_3": (10, 31, "PLLCONFIG_8"),
|
||||
"DIVF_4": (10, 31, "PLLCONFIG_9"),
|
||||
"DIVF_5": (11, 31, "PLLCONFIG_1"),
|
||||
"DIVF_6": (11, 31, "PLLCONFIG_2"),
|
||||
"DIVQ_0": (11, 31, "PLLCONFIG_3"),
|
||||
"DIVQ_1": (11, 31, "PLLCONFIG_4"),
|
||||
"DIVQ_2": (11, 31, "PLLCONFIG_5"),
|
||||
"FILTER_RANGE_0": (11, 31, "PLLCONFIG_6"),
|
||||
"FILTER_RANGE_1": (11, 31, "PLLCONFIG_7"),
|
||||
"FILTER_RANGE_2": (11, 31, "PLLCONFIG_8"),
|
||||
"TEST_MODE": (12, 31, "PLLCONFIG_8"),
|
||||
|
||||
# PLL Ports
|
||||
"PLLOUT_A": ( 16, 0, 1),
|
||||
"PLLOUT_B": ( 17, 0, 0),
|
||||
"REFERENCECLK": ( 13, 0, "fabout"),
|
||||
"EXTFEEDBACK": ( 14, 0, "fabout"),
|
||||
"DYNAMICDELAY_0": ( 5, 0, "fabout"),
|
||||
"DYNAMICDELAY_1": ( 6, 0, "fabout"),
|
||||
"DYNAMICDELAY_2": ( 7, 0, "fabout"),
|
||||
"DYNAMICDELAY_3": ( 8, 0, "fabout"),
|
||||
"DYNAMICDELAY_4": ( 9, 0, "fabout"),
|
||||
"DYNAMICDELAY_5": ( 10, 0, "fabout"),
|
||||
"DYNAMICDELAY_6": ( 11, 0, "fabout"),
|
||||
"DYNAMICDELAY_7": ( 12, 0, "fabout"),
|
||||
"LOCK": ( 1, 1, "neigh_op_bnl_1"),
|
||||
"BYPASS": ( 19, 0, "fabout"),
|
||||
"RESETB": ( 20, 0, "fabout"),
|
||||
"LATCHINPUTVALUE": ( 15, 0, "fabout"),
|
||||
"SDO": ( 32, 1, "neigh_op_bnr_3"),
|
||||
"SDI": ( 22, 0, "fabout"),
|
||||
"SCLK": ( 21, 0, "fabout"),
|
||||
"PLLOUT_A": ( 12, 31, 1),
|
||||
"PLLOUT_B": ( 13, 31, 0),
|
||||
"REFERENCECLK": ( 10, 31, "fabout"),
|
||||
"EXTFEEDBACK": ( 11, 31, "fabout"),
|
||||
"DYNAMICDELAY_0": ( 1, 31, "fabout"),
|
||||
"DYNAMICDELAY_1": ( 2, 31, "fabout"),
|
||||
"DYNAMICDELAY_2": ( 3, 31, "fabout"),
|
||||
"DYNAMICDELAY_3": ( 4, 31, "fabout"),
|
||||
"DYNAMICDELAY_4": ( 5, 31, "fabout"),
|
||||
"DYNAMICDELAY_5": ( 7, 31, "fabout"),
|
||||
"DYNAMICDELAY_6": ( 8, 31, "fabout"),
|
||||
"DYNAMICDELAY_7": ( 9, 31, "fabout"),
|
||||
"LOCK": ( 1, 30, "neigh_op_tnl_1"), #check?
|
||||
"BYPASS": ( 15, 31, "fabout"),
|
||||
"RESETB": ( 16, 31, "fabout"),
|
||||
"LATCHINPUTVALUE": ( 14, 31, "fabout"),
|
||||
"SDO": ( 24, 30, "neigh_op_tnr_1"), #check?
|
||||
"SDI": ( 18, 31, "fabout"),
|
||||
"SCLK": ( 17, 31, "fabout"),
|
||||
},
|
||||
"8k_0": {
|
||||
"LOC" : (16, 0),
|
||||
|
|
@ -2057,6 +2069,47 @@ ieren_db = {
|
|||
( 7, 6, 0, 7, 6, 1),
|
||||
( 7, 6, 1, 7, 6, 0),
|
||||
],
|
||||
"5k": [
|
||||
( 8, 0, 0, 8, 0, 1),
|
||||
( 9, 0, 1, 9, 0, 0),
|
||||
( 9, 0, 0, 9, 0, 1),
|
||||
(13, 0, 1, 13, 0, 0),
|
||||
(15, 0, 0, 15, 0, 1),
|
||||
(16, 0, 0, 16, 0, 1),
|
||||
(17, 0, 0, 17, 0, 1),
|
||||
(18, 0, 0, 18, 0, 1),
|
||||
(19, 0, 0, 19, 0, 1),
|
||||
(23, 0, 0, 23, 0, 1),
|
||||
(24, 0, 0, 24, 0, 1),
|
||||
(24, 0, 1, 24, 0, 0),
|
||||
(23, 0, 1, 23, 0, 0),
|
||||
(22, 0, 1, 22, 0, 0),
|
||||
(21, 0, 1, 21, 0, 0),
|
||||
(19, 0, 1, 19, 0, 0),
|
||||
(18, 0, 1, 18, 0, 0),
|
||||
(19, 31, 0, 19, 31, 1),
|
||||
(19, 31, 1, 19, 31, 0),
|
||||
(18, 31, 0, 18, 31, 1),
|
||||
(18, 31, 1, 18, 31, 0),
|
||||
(17, 31, 0, 17, 31, 1),
|
||||
(16, 31, 1, 16, 31, 0),
|
||||
(16, 31, 0, 16, 31, 1),
|
||||
(13, 31, 1, 13, 31, 0),
|
||||
(12, 31, 1, 12, 31, 0),
|
||||
( 9, 31, 1, 9, 31, 0),
|
||||
(13, 31, 0, 13, 31, 1),
|
||||
( 4, 31, 0, 4, 31, 1),
|
||||
( 5, 31, 0, 5, 31, 1),
|
||||
( 6, 31, 0, 6, 31, 1),
|
||||
( 8, 31, 1, 8, 31, 0),
|
||||
( 8, 31, 0, 8, 31, 1),
|
||||
( 9, 31, 0, 9, 31, 1),
|
||||
( 6, 0, 1, 6, 0, 0),
|
||||
( 7, 0, 1, 7, 0, 0),
|
||||
( 5, 0, 0, 5, 0, 1),
|
||||
( 6, 0, 0, 6, 0, 1),
|
||||
( 7, 0, 0, 7, 0, 1)
|
||||
]
|
||||
}
|
||||
|
||||
# This dictionary maps package variants to a table of pin names and their
|
||||
|
|
@ -4152,13 +4205,29 @@ for entry in iotile_full_db:
|
|||
logictile_db.append([["B1[49]"], "buffer", "carry_in", "carry_in_mux"])
|
||||
logictile_db.append([["B1[50]"], "CarryInSet"])
|
||||
|
||||
logictile_5k_db.append([["B1[49]"], "buffer", "carry_in", "carry_in_mux"])
|
||||
logictile_5k_db.append([["B1[50]"], "CarryInSet"])
|
||||
|
||||
logictile_8k_db.append([["B1[49]"], "buffer", "carry_in", "carry_in_mux"])
|
||||
logictile_8k_db.append([["B1[50]"], "CarryInSet"])
|
||||
|
||||
logictile_384_db.append([["B1[49]"], "buffer", "carry_in", "carry_in_mux"])
|
||||
logictile_384_db.append([["B1[50]"], "CarryInSet"])
|
||||
|
||||
for db in [iotile_l_db, iotile_r_db, iotile_t_db, iotile_b_db, logictile_db, logictile_5k_db, logictile_8k_db, logictile_384_db, rambtile_db, ramttile_db, rambtile_5k_db, ramttile_5k_db, rambtile_8k_db, ramttile_8k_db]:
|
||||
# The 5k series has a couple of extra IO configuration bits. Add them in to a copy of the db here
|
||||
iotile_t_5k_db = list(iotile_t_db)
|
||||
iotile_t_5k_db.append([["B14[15]"], "IoCtrl", "padeb_test_1"])
|
||||
iotile_t_5k_db.append([["B15[14]"], "IoCtrl", "padeb_test_0"])
|
||||
iotile_t_5k_db.append([["B6[15]"], "IoCtrl", "cf_bit_35"])
|
||||
iotile_t_5k_db.append([["B12[15]"], "IoCtrl", "cf_bit_39"])
|
||||
|
||||
iotile_b_5k_db = list(iotile_b_db)
|
||||
iotile_b_5k_db.append([["B14[15]"], "IoCtrl", "padeb_test_1"])
|
||||
iotile_b_5k_db.append([["B15[14]"], "IoCtrl", "padeb_test_0"])
|
||||
iotile_b_5k_db.append([["B6[15]"], "IoCtrl", "cf_bit_35"])
|
||||
iotile_b_5k_db.append([["B12[15]"], "IoCtrl", "cf_bit_39"])
|
||||
|
||||
for db in [iotile_l_db, iotile_r_db, iotile_t_db, iotile_b_db, iotile_t_5k_db, iotile_b_5k_db, logictile_db, logictile_5k_db, logictile_8k_db, logictile_384_db, rambtile_db, ramttile_db, rambtile_5k_db, ramttile_5k_db, rambtile_8k_db, ramttile_8k_db]:
|
||||
for entry in db:
|
||||
if entry[1] in ("buffer", "routing"):
|
||||
entry[2] = netname_normalize(entry[2],
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -63,8 +63,10 @@ elif device_class == "5k":
|
|||
|
||||
#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
|
||||
#an SB_IO clk_in
|
||||
pins = """2 3 4 6 9 10 11 12
|
||||
13 18 19 20 21 23
|
||||
13 18 19 20 21
|
||||
25 26 27 28 31 32 34 35 36
|
||||
37 38 42 43 44 45 46 47 48
|
||||
""".split()
|
||||
|
|
|
|||
|
|
@ -30,13 +30,13 @@ with open(argv[1]) as f:
|
|||
with open(argv[2]) as f:
|
||||
current_tile = None
|
||||
for line in f:
|
||||
if line.startswith(("Tile", "IO_Tile", "RAM_Tile", "LogicTile")):
|
||||
f = line.replace("IO_", "").replace("RAM_", "").split("_")
|
||||
if line.startswith(("Tile", "IO_Tile", "RAM_Tile", "LogicTile", "DSP_Tile", "IpCon_Tile")):
|
||||
f = line.replace("IO_", "").replace("RAM_", "").replace("DSP_","").replace("IpCon_","").split("_")
|
||||
assert len(f) == 3
|
||||
current_tile = "%02d.%02d" % (int(f[1]), int(f[2]))
|
||||
continue
|
||||
|
||||
if line.find("GlobalNetwork") >= 0 or line.startswith(("IpCon", "DSP")):
|
||||
if line.find("GlobalNetwork") >= 0:
|
||||
current_tile = None
|
||||
continue
|
||||
|
||||
|
|
@ -65,4 +65,3 @@ for bit in sorted(only_in_glb):
|
|||
print(bit)
|
||||
|
||||
exit(1)
|
||||
|
||||
|
|
|
|||
|
|
@ -31,20 +31,40 @@ for idx in range(num):
|
|||
print("endmodule", file=f)
|
||||
with open(working_dir + "/prim_%02d.pcf" % idx, "w") as f:
|
||||
p = np.random.permutation(pins)
|
||||
used_pins = []
|
||||
if np.random.choice([True, False]):
|
||||
for i in range(w):
|
||||
print("set_io a[%d] %s" % (i, p[i]), file=f)
|
||||
used_pins.append(p[i])
|
||||
if np.random.choice([True, False]):
|
||||
for i in range(w):
|
||||
print("set_io b[%d] %s" % (i, p[w+i]), file=f)
|
||||
used_pins.append(p[w+i])
|
||||
if np.random.choice([True, False]):
|
||||
for i in range(w):
|
||||
print("set_io y[%d] %s" % (i, p[2*w+i]), file=f)
|
||||
used_pins.append(p[2*w+i])
|
||||
if np.random.choice([True, False]):
|
||||
print("set_io x %s" % p[3*w], file=f)
|
||||
used_pins.append(p[3*w])
|
||||
|
||||
if np.random.choice([True, False]):
|
||||
print("set_io y %s" % p[3*w+1], file=f)
|
||||
if np.random.choice([True, False]):
|
||||
used_pins.append(p[3*w+1])
|
||||
|
||||
# There is a low but non-zero probability, particularly on devices with
|
||||
# fewer pins and GBINs such as the UltraPlus, that a permutation will be
|
||||
# picked where all of the GBINs are already constrained at this point,
|
||||
# hence icecube fails to assign clk successfully. This is fixed by
|
||||
# forcing clock assignment if no GBINs are free.
|
||||
|
||||
global_free = False
|
||||
for glbi in gpins:
|
||||
if not glbi in used_pins:
|
||||
global_free = True
|
||||
break
|
||||
|
||||
if np.random.choice([True, False]) or not global_free:
|
||||
print("set_io clk %s" % p[3*w+2], file=f)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,11 @@ os.mkdir(working_dir)
|
|||
for idx in range(num):
|
||||
with open(working_dir + "/ram40_%02d.v" % idx, "w") as f:
|
||||
glbs = ["glb[%d]" % i for i in range(np.random.randint(8)+1)]
|
||||
glbs_choice = ["wa", "ra", "msk", "wd", "we", "wce", "wc", "re", "rce", "rc"]
|
||||
# Connecting GLB to CE pins seemingly disallowed
|
||||
if device_class == "5k":
|
||||
glbs_choice = ["wa", "ra", "msk", "wd", "we", "wc", "re", "rc"]
|
||||
else:
|
||||
glbs_choice = ["wa", "ra", "msk", "wd", "we", "wce", "wc", "re", "rce", "rc"]
|
||||
print("""
|
||||
module top (
|
||||
input [%d:0] glb_pins,
|
||||
|
|
@ -26,7 +30,7 @@ for idx in range(num):
|
|||
.USER_SIGNAL_TO_GLOBAL_BUFFER(glb_pins),
|
||||
.GLOBAL_BUFFER_OUTPUT(glb)
|
||||
);
|
||||
""" % (len(glbs)-1, len(pins) - 16 - 1, len(glbs)-1, len(glbs)-1), file=f)
|
||||
""" % (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(60)]
|
||||
bits = list(np.random.permutation(bits))
|
||||
for i in range(num_ramb40):
|
||||
|
|
@ -102,7 +106,7 @@ for idx in range(num):
|
|||
print("endmodule", file=f)
|
||||
with open(working_dir + "/ram40_%02d.pcf" % idx, "w") as f:
|
||||
p = list(np.random.permutation(pins))
|
||||
for i in range(len(pins) - 16):
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
ioctrl.work
|
||||
intosc.work
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
set_io clkhfpu 2
|
||||
set_io clkhfen 3
|
||||
set_io clkhf 4
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
module top (
|
||||
input clkhfpu,
|
||||
input clkhfen,
|
||||
output clkhf
|
||||
);
|
||||
SB_HFOSC #(
|
||||
|
||||
.CLKHF_DIV("0b10")
|
||||
) hfosc (
|
||||
.CLKHFPU(clkhfpu),
|
||||
.CLKHFEN(clkhfen),
|
||||
.CLKHF(clkhf)
|
||||
);
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import fileinput
|
||||
|
||||
for line in fileinput.input():
|
||||
line = line.split()
|
||||
if len(line) == 0:
|
||||
continue
|
||||
if line[0] == ".io_tile":
|
||||
current_tile = (int(line[1]), int(line[2]))
|
||||
if line[0] == "IoCtrl" and line[1] == "REN_0":
|
||||
ren = (current_tile[0], current_tile[1], 0)
|
||||
if line[0] == "IoCtrl" and line[1] == "REN_1":
|
||||
ren = (current_tile[0], current_tile[1], 1)
|
||||
if line[0] == "IOB_0":
|
||||
iob = (current_tile[0], current_tile[1], 0)
|
||||
if line[0] == "IOB_1":
|
||||
iob = (current_tile[0], current_tile[1], 1)
|
||||
|
||||
print("(%2d, %2d, %2d, %2d, %2d, %2d)," % (iob[0], iob[1], iob[2], ren[0], ren[1], ren[2]))
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -ex
|
||||
|
||||
mkdir -p ioctrl.work
|
||||
cd ioctrl.work
|
||||
|
||||
pins="2 3 4 6 9 10 11 12
|
||||
13 14 15 16 17 18 19 20 21 23
|
||||
25 26 27 28 31 32 34 35 36
|
||||
37 38 42 43 44 45 46 47 48
|
||||
"
|
||||
pins="$( echo $pins )"
|
||||
|
||||
for pin in $pins; do
|
||||
pf="ioctrl_$pin"
|
||||
echo "module top (output pin); assign pin = 1; endmodule" > ${pf}.v
|
||||
echo "set_io pin $pin" > ${pf}.pcf
|
||||
bash ../../icecube.sh -up5k ${pf}.v > ${pf}.log 2>&1
|
||||
../../../icebox/icebox_explain.py ${pf}.asc > ${pf}.exp
|
||||
done
|
||||
|
||||
set +x
|
||||
echo "--snip--"
|
||||
for pin in $pins; do
|
||||
python3 ../ioctrl_5k.py ioctrl_${pin}.exp
|
||||
done | tee ioctrl_db.txt
|
||||
echo "--snap--"
|
||||
|
|
@ -0,0 +1 @@
|
|||
work_pllauto/
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
"PLLTYPE_1": (14, 31, "PLLCONFIG_1"),
|
||||
"PLLTYPE_2": (14, 31, "PLLCONFIG_3"),
|
||||
"PLLTYPE_0": (12, 31, "PLLCONFIG_5"),
|
||||
"FEEDBACK_PATH_0": (14, 31, "PLLCONFIG_5"),
|
||||
"FEEDBACK_PATH_1": (11, 31, "PLLCONFIG_9"),
|
||||
"FEEDBACK_PATH_2": (12, 31, "PLLCONFIG_1"),
|
||||
"PLLOUT_SELECT_A_0": (12, 31, "PLLCONFIG_6"),
|
||||
"PLLOUT_SELECT_A_1": (12, 31, "PLLCONFIG_7"),
|
||||
"PLLOUT_SELECT_B_0": (12, 31, "PLLCONFIG_2"),
|
||||
"PLLOUT_SELECT_B_1": (12, 31, "PLLCONFIG_3"),
|
||||
"SHIFTREG_DIV_MODE": (12, 31, "PLLCONFIG_4"),
|
||||
"FDA_FEEDBACK_0": (12, 31, "PLLCONFIG_9"),
|
||||
"FDA_FEEDBACK_1": (13, 31, "PLLCONFIG_1"),
|
||||
"FDA_FEEDBACK_2": (13, 31, "PLLCONFIG_2"),
|
||||
"FDA_FEEDBACK_3": (13, 31, "PLLCONFIG_3"),
|
||||
"FDA_RELATIVE_0": (13, 31, "PLLCONFIG_5"),
|
||||
"FDA_RELATIVE_1": (13, 31, "PLLCONFIG_6"),
|
||||
"FDA_RELATIVE_2": (13, 31, "PLLCONFIG_7"),
|
||||
"FDA_RELATIVE_3": (13, 31, "PLLCONFIG_8"),
|
||||
"DIVR_0": (10, 31, "PLLCONFIG_1"),
|
||||
"DIVR_1": (10, 31, "PLLCONFIG_2"),
|
||||
"DIVR_2": (10, 31, "PLLCONFIG_3"),
|
||||
"DIVR_3": (10, 31, "PLLCONFIG_4"),
|
||||
"DIVF_0": (10, 31, "PLLCONFIG_5"),
|
||||
"DIVF_1": (10, 31, "PLLCONFIG_6"),
|
||||
"DIVF_2": (10, 31, "PLLCONFIG_7"),
|
||||
"DIVF_3": (10, 31, "PLLCONFIG_8"),
|
||||
"DIVF_4": (10, 31, "PLLCONFIG_9"),
|
||||
"DIVF_5": (11, 31, "PLLCONFIG_1"),
|
||||
"DIVF_6": (11, 31, "PLLCONFIG_2"),
|
||||
"DIVQ_0": (11, 31, "PLLCONFIG_3"),
|
||||
"DIVQ_1": (11, 31, "PLLCONFIG_4"),
|
||||
"DIVQ_2": (11, 31, "PLLCONFIG_5"),
|
||||
"FILTER_RANGE_0": (11, 31, "PLLCONFIG_6"),
|
||||
"FILTER_RANGE_1": (11, 31, "PLLCONFIG_7"),
|
||||
"FILTER_RANGE_2": (11, 31, "PLLCONFIG_8"),
|
||||
"TEST_MODE": (12, 31, "PLLCONFIG_8"),
|
||||
"DELAY_ADJMODE_FB": (13, 31, "PLLCONFIG_4"),
|
||||
"DELAY_ADJMODE_REL": (13, 31, "PLLCONFIG_9"),
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os, sys
|
||||
# PLL automatic fuzzing script (WIP)
|
||||
|
||||
device = "up5k"
|
||||
|
||||
# PLL config bits to be fuzzed
|
||||
# These must be in an order such that a config with bit i set doesn't set any other undiscovered bits yet
|
||||
# e.g. PLL_TYPE must be fuzzed first as these will need to be set later on by virtue of enabling the PLL
|
||||
|
||||
fuzz_bits = [
|
||||
"PLLTYPE_1",
|
||||
"PLLTYPE_2",
|
||||
"PLLTYPE_0", #NB: as per the rule above this comes later is it can only be set by also setting 1 or 2
|
||||
|
||||
"FEEDBACK_PATH_0",
|
||||
"FEEDBACK_PATH_1",
|
||||
"FEEDBACK_PATH_2",
|
||||
|
||||
"PLLOUT_SELECT_A_0",
|
||||
"PLLOUT_SELECT_A_1",
|
||||
|
||||
"PLLOUT_SELECT_B_0",
|
||||
"PLLOUT_SELECT_B_1",
|
||||
|
||||
"SHIFTREG_DIV_MODE",
|
||||
|
||||
"FDA_FEEDBACK_0",
|
||||
"FDA_FEEDBACK_1",
|
||||
"FDA_FEEDBACK_2",
|
||||
"FDA_FEEDBACK_3",
|
||||
|
||||
"FDA_RELATIVE_0",
|
||||
"FDA_RELATIVE_1",
|
||||
"FDA_RELATIVE_2",
|
||||
"FDA_RELATIVE_3",
|
||||
|
||||
"DIVR_0",
|
||||
"DIVR_1",
|
||||
"DIVR_2",
|
||||
"DIVR_3",
|
||||
|
||||
"DIVF_0",
|
||||
"DIVF_1",
|
||||
"DIVF_2",
|
||||
"DIVF_3",
|
||||
"DIVF_4",
|
||||
"DIVF_5",
|
||||
"DIVF_6",
|
||||
|
||||
#DIVQ_0 is missing, see comments later on
|
||||
"DIVQ_1",
|
||||
"DIVQ_2",
|
||||
|
||||
"FILTER_RANGE_0",
|
||||
"FILTER_RANGE_1",
|
||||
"FILTER_RANGE_2",
|
||||
|
||||
"TEST_MODE",
|
||||
|
||||
"DELAY_ADJMODE_FB", #these come at the end in case they set FDA_RELATIVE??
|
||||
"DELAY_ADJMODE_REL"
|
||||
]
|
||||
|
||||
# Boilerplate code based on the icefuzz script
|
||||
code_prefix = """
|
||||
module top(packagepin, a, b, w, x, y, z, extfeedback, bypass, resetb, lock, latchinputvalue, sdi, sdo, sclk, dynamicdelay_0, dynamicdelay_1, dynamicdelay_2, dynamicdelay_3, dynamicdelay_4, dynamicdelay_5, dynamicdelay_6, dynamicdelay_7);
|
||||
input packagepin;
|
||||
input a;
|
||||
input b;
|
||||
output w;
|
||||
output x;
|
||||
output reg y;
|
||||
output reg z;
|
||||
input extfeedback;
|
||||
input bypass;
|
||||
input resetb;
|
||||
output lock;
|
||||
input latchinputvalue;
|
||||
input sdi;
|
||||
output sdo;
|
||||
input sclk;
|
||||
wire plloutcorea;
|
||||
wire plloutcoreb;
|
||||
wire plloutglobala;
|
||||
wire plloutglobalb;
|
||||
assign w = plloutcorea ^ a;
|
||||
assign x = plloutcoreb ^ b;
|
||||
always @(posedge plloutglobala) y <= a;
|
||||
always @(posedge plloutglobalb) z <= b;
|
||||
input dynamicdelay_0;
|
||||
input dynamicdelay_1;
|
||||
input dynamicdelay_2;
|
||||
input dynamicdelay_3;
|
||||
input dynamicdelay_4;
|
||||
input dynamicdelay_5;
|
||||
input dynamicdelay_6;
|
||||
input dynamicdelay_7;
|
||||
"""
|
||||
|
||||
def get_param_value(param_name, param_size, fuzz_bit):
|
||||
param = str(param_size) + "'b";
|
||||
for i in range(param_size - 1, -1, -1):
|
||||
if fuzz_bit == param_name + "_" + str(i):
|
||||
param += '1'
|
||||
else:
|
||||
param += '0'
|
||||
return param
|
||||
def inst_pll(fuzz_bit):
|
||||
pll_type = "SB_PLL40_2F_PAD" #default to this as it's most flexible
|
||||
|
||||
if fuzz_bit == "PLLTYPE_0":
|
||||
pll_type = "SB_PLL40_CORE"
|
||||
elif fuzz_bit == "PLLTYPE_1":
|
||||
pll_type = "SB_PLL40_PAD"
|
||||
elif fuzz_bit == "PLLTYPE_2":
|
||||
pll_type = "SB_PLL40_2_PAD"
|
||||
|
||||
v = pll_type + " pll_inst (\n"
|
||||
if pll_type == "SB_PLL40_CORE":
|
||||
v += "\t.REFERENCECLK(referenceclk), \n"
|
||||
else:
|
||||
v += "\t.PACKAGEPIN(packagepin), \n"
|
||||
v += "\t.RESETB(resetb),\n"
|
||||
v += "\t.BYPASS(bypass),\n"
|
||||
v += "\t.EXTFEEDBACK(extfeedback),\n"
|
||||
v += "\t.LOCK(lock),\n"
|
||||
v += "\t.LATCHINPUTVALUE(latchinputvalue),\n"
|
||||
v += "\t.SDI(sdi),\n"
|
||||
v += "\t.SDO(sdo),\n"
|
||||
v += "\t.SCLK(sclk),\n"
|
||||
if pll_type == "SB_PLL40_2F_PAD" or pll_type == "SB_PLL40_2_PAD":
|
||||
v += "\t.PLLOUTCOREA(plloutcorea),\n"
|
||||
v += "\t.PLLOUTGLOBALA(plloutglobala),\n"
|
||||
v += "\t.PLLOUTCOREB(plloutcoreb),\n"
|
||||
v += "\t.PLLOUTGLOBALB(plloutglobalb),\n"
|
||||
else:
|
||||
v += "\t.PLLOUTCORE(plloutcorea),\n"
|
||||
v += "\t.PLLOUTGLOBAL(plloutglobala),\n"
|
||||
v += "\t.DYNAMICDELAY({dynamicdelay_7, dynamicdelay_6, dynamicdelay_5, dynamicdelay_4, dynamicdelay_3, dynamicdelay_2, dynamicdelay_1, dynamicdelay_0})\n"
|
||||
v += ");\n"
|
||||
|
||||
v += "defparam pll_inst.DIVR = " + get_param_value("DIVR", 4, fuzz_bit) + ";\n"
|
||||
v += "defparam pll_inst.DIVF = " + get_param_value("DIVF", 7, fuzz_bit) + ";\n"
|
||||
v += "defparam pll_inst.DIVQ = " + get_param_value("DIVQ", 3, fuzz_bit) + ";\n"
|
||||
v += "defparam pll_inst.FILTER_RANGE = " + get_param_value("FILTER_RANGE", 3, fuzz_bit) + ";\n"
|
||||
|
||||
if fuzz_bit == "FEEDBACK_PATH_0":
|
||||
v += "defparam pll_inst.FEEDBACK_PATH = \"SIMPLE\";\n"
|
||||
elif fuzz_bit == "FEEDBACK_PATH_1":
|
||||
v += "defparam pll_inst.FEEDBACK_PATH = \"PHASE_AND_DELAY\";\n"
|
||||
elif fuzz_bit == "FEEDBACK_PATH_2":
|
||||
v += "defparam pll_inst.FEEDBACK_PATH = \"EXTERNAL\";\n"
|
||||
else:
|
||||
v += "defparam pll_inst.FEEDBACK_PATH = \"DELAY\";\n"
|
||||
|
||||
v += "defparam pll_inst.DELAY_ADJUSTMENT_MODE_FEEDBACK = \"" + ("DYNAMIC" if (fuzz_bit == "DELAY_ADJMODE_FB") else "FIXED") + "\";\n"
|
||||
v += "defparam pll_inst.FDA_FEEDBACK = " + get_param_value("FDA_FEEDBACK", 4, fuzz_bit) + ";\n"
|
||||
v += "defparam pll_inst.DELAY_ADJUSTMENT_MODE_RELATIVE = \"" + ("DYNAMIC" if (fuzz_bit == "DELAY_ADJMODE_REL") else "FIXED") + "\";\n"
|
||||
v += "defparam pll_inst.FDA_RELATIVE = " + get_param_value("FDA_RELATIVE", 4, fuzz_bit) + ";\n"
|
||||
v += "defparam pll_inst.SHIFTREG_DIV_MODE = " + ("1'b1" if (fuzz_bit == "SHIFTREG_DIV_MODE") else "1'b0") + ";\n"
|
||||
|
||||
|
||||
|
||||
if pll_type == "SB_PLL40_2F_PAD" or pll_type == "SB_PLL40_2_PAD":
|
||||
if pll_type == "SB_PLL40_2F_PAD":
|
||||
if fuzz_bit == "PLLOUT_SELECT_A_0":
|
||||
v += "defparam pll_inst.PLLOUT_SELECT_PORTA = \"GENCLK_HALF\";\n"
|
||||
elif fuzz_bit == "PLLOUT_SELECT_A_1":
|
||||
v += "defparam pll_inst.PLLOUT_SELECT_PORTA = \"SHIFTREG_90deg\";\n"
|
||||
else:
|
||||
v += "defparam pll_inst.PLLOUT_SELECT_PORTA = \"GENCLK\";\n"
|
||||
if fuzz_bit == "PLLOUT_SELECT_B_0":
|
||||
v += "defparam pll_inst.PLLOUT_SELECT_PORTB = \"GENCLK_HALF\";\n"
|
||||
elif fuzz_bit == "PLLOUT_SELECT_B_1":
|
||||
v += "defparam pll_inst.PLLOUT_SELECT_PORTB = \"SHIFTREG_90deg\";\n"
|
||||
else:
|
||||
v += "defparam pll_inst.PLLOUT_SELECT_PORTB = \"GENCLK\";\n"
|
||||
else:
|
||||
if fuzz_bit == "PLLOUT_SELECT_A_0":
|
||||
v += "defparam pll_inst.PLLOUT_SELECT = \"GENCLK_HALF\";\n"
|
||||
elif fuzz_bit == "PLLOUT_SELECT_A_1":
|
||||
v += "defparam pll_inst.PLLOUT_SELECT = \"SHIFTREG_90deg\";\n"
|
||||
else:
|
||||
v += "defparam pll_inst.PLLOUT_SELECT = \"GENCLK\";\n"
|
||||
v += "defparam pll_inst.TEST_MODE = " + ("1'b1" if (fuzz_bit == "TEST_MODE") else "1'b0") + ";\n"
|
||||
|
||||
return v;
|
||||
|
||||
def make_vlog(fuzz_bit):
|
||||
vlog = code_prefix
|
||||
vlog += inst_pll(fuzz_bit)
|
||||
vlog += "endmodule"
|
||||
return vlog
|
||||
|
||||
known_bits = []
|
||||
|
||||
# Set to true to continue even if multiple bits are changed (needed because
|
||||
# of the issue discusssed below)
|
||||
show_all_bits = False #TODO: make this an argument
|
||||
|
||||
device = "up5k" #TODO: environment variable?
|
||||
|
||||
#HACK: icecube doesn't let you set all of the DIVQ bits to 0,
|
||||
#which makes fuzzing early on annoying as there is never a case
|
||||
#with just 1 bit set. So a tiny bit of semi-manual work is needed
|
||||
#first to discover this (basically run this script with show_all_bits=True
|
||||
#and look for the stuck bit)
|
||||
#TODO: clever code could get rid of this
|
||||
divq_bit0 = {
|
||||
"up5k" : (11, 31, 3)
|
||||
}
|
||||
|
||||
#Return a list of PLL config bits in the format (x, y, bit)
|
||||
def parse_exp(expfile):
|
||||
current_x = 0
|
||||
current_y = 0
|
||||
bits = []
|
||||
with open(expfile, 'r') as f:
|
||||
for line in f:
|
||||
splitline = line.split(' ')
|
||||
if splitline[0] == ".io_tile":
|
||||
current_x = int(splitline[1])
|
||||
current_y = int(splitline[2])
|
||||
elif splitline[0] == "PLL":
|
||||
if splitline[1][:10] == "PLLCONFIG_":
|
||||
bitidx = int(splitline[1][10:])
|
||||
bits.append((current_x, current_y, bitidx))
|
||||
return bits
|
||||
|
||||
#Convert a bit tuple as returned from the above to a nice string
|
||||
def bit_to_str(bit):
|
||||
return "(%d, %d, \"PLLCONFIG_%d\")" % bit
|
||||
|
||||
#The main fuzzing function
|
||||
def do_fuzz():
|
||||
if not os.path.exists("./work_pllauto"):
|
||||
os.mkdir("./work_pllauto")
|
||||
known_bits.append(divq_bit0[device])
|
||||
with open("pll_data_" + device + ".txt", 'w') as dat:
|
||||
for fuzz_bit in fuzz_bits:
|
||||
vlog = make_vlog(fuzz_bit)
|
||||
with open("./work_pllauto/pllauto.v", 'w') as f:
|
||||
f.write(vlog)
|
||||
retval = os.system("bash ../../icecube.sh -" + device + " ./work_pllauto/pllauto.v > ./work_pllauto/icecube.log 2>&1")
|
||||
if retval != 0:
|
||||
sys.stderr.write('ERROR: icecube returned non-zero error code\n')
|
||||
sys.exit(1)
|
||||
retval = os.system("../../../icebox/icebox_explain.py ./work_pllauto/pllauto.asc > ./work_pllauto/pllauto.exp")
|
||||
if retval != 0:
|
||||
sys.stderr.write('ERROR: icebox_explain returned non-zero error code\n')
|
||||
sys.exit(1)
|
||||
pll_bits = parse_exp("./work_pllauto/pllauto.exp")
|
||||
new_bits = []
|
||||
for set_bit in pll_bits:
|
||||
if not (set_bit in known_bits):
|
||||
new_bits.append(set_bit)
|
||||
if len(new_bits) == 0:
|
||||
sys.stderr.write('ERROR: no new bits set when setting config bit ' + fuzz_bit + '\n')
|
||||
sys.exit(1)
|
||||
if len(new_bits) > 1:
|
||||
sys.stderr.write('ERROR: multiple new bits set when setting config bit ' + fuzz_bit + '\n')
|
||||
for bit in new_bits:
|
||||
sys.stderr.write('\t' + bit_to_str(bit) + '\n')
|
||||
if not show_all_bits:
|
||||
sys.exit(1)
|
||||
if len(new_bits) == 1:
|
||||
known_bits.append(new_bits[0])
|
||||
#print DIVQ_0 at the right moment, as it's not fuzzed normally
|
||||
if fuzz_bit == "DIVQ_1":
|
||||
print(("\"DIVQ_0\":").ljust(24) + bit_to_str(divq_bit0[device]) + ",")
|
||||
dat.write(("\"DIVQ_0\":").ljust(24) + bit_to_str(divq_bit0[device]) + ",\n")
|
||||
print(("\"" + fuzz_bit + "\":").ljust(24) + bit_to_str(new_bits[0]) + ",")
|
||||
dat.write(("\"" + fuzz_bit + "\":").ljust(24) + bit_to_str(new_bits[0]) + ",\n")
|
||||
do_fuzz()
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
# set_io pin 1
|
||||
set_io pin 39
|
||||
|
||||
# set_io pin
|
||||
# set_io latch_in
|
||||
# set_io clk_in
|
||||
# set_io clk_out
|
||||
# set_io oen
|
||||
# set_io dout_0
|
||||
# set_io dout_1
|
||||
# set_io din_0
|
||||
# set_io din_1
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
//`define CONN_INTERNAL_BITS
|
||||
|
||||
`define PINTYPE 6'b010001
|
||||
// `define IOSTANDARD "SB_LVCMOS"
|
||||
`define IOSTANDARD "SB_LVCMOS"
|
||||
|
||||
// The following IO standards are just aliases for SB_LVCMOS
|
||||
// `define IOSTANDARD "SB_LVCMOS25_16"
|
||||
// `define IOSTANDARD "SB_LVCMOS25_12"
|
||||
// `define IOSTANDARD "SB_LVCMOS25_8"
|
||||
// `define IOSTANDARD "SB_LVCMOS25_4"
|
||||
// `define IOSTANDARD "SB_LVCMOS18_10"
|
||||
// `define IOSTANDARD "SB_LVCMOS18_8"
|
||||
// `define IOSTANDARD "SB_LVCMOS18_4"
|
||||
// `define IOSTANDARD "SB_LVCMOS18_2"
|
||||
// `define IOSTANDARD "SB_LVCMOS15_4"
|
||||
// `define IOSTANDARD "SB_LVCMOS15_2"
|
||||
// `define IOSTANDARD "SB_MDDR10"
|
||||
// `define IOSTANDARD "SB_MDDR8"
|
||||
// `define IOSTANDARD "SB_MDDR4"
|
||||
// `define IOSTANDARD "SB_MDDR2"
|
||||
|
||||
`ifdef CONN_INTERNAL_BITS
|
||||
module top (
|
||||
inout pin,
|
||||
input latch_in,
|
||||
input clk_in,
|
||||
input clk_out,
|
||||
input oen,
|
||||
input dout_0,
|
||||
input dout_1,
|
||||
output din_0,
|
||||
output din_1
|
||||
);
|
||||
`else
|
||||
module top(pin);
|
||||
inout pin;
|
||||
wire latch_in = 0;
|
||||
wire clk_in = 0;
|
||||
wire clk_out = 0;
|
||||
wire oen = 0;
|
||||
wire dout_0 = 0;
|
||||
wire dout_1 = 0;
|
||||
wire din_0;
|
||||
wire din_1;
|
||||
`endif
|
||||
SB_IO_OD #(
|
||||
.PIN_TYPE(`PINTYPE),
|
||||
.NEG_TRIGGER(1'b0)
|
||||
) IO_PIN_I (
|
||||
.PACKAGEPIN(pin),
|
||||
.LATCHINPUTVALUE(latch_in),
|
||||
.CLOCKENABLE(clk_en),
|
||||
.INPUTCLK(clk_in),
|
||||
.OUTPUTCLK(clk_out),
|
||||
.OUTPUTENABLE(oen),
|
||||
.DOUT0(dout_0),
|
||||
.DOUT1(dout_1),
|
||||
.DIN0(din_0),
|
||||
.DIN1(din_1)
|
||||
);
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
module top(
|
||||
input clk,
|
||||
input rst,
|
||||
input [7:0] a,
|
||||
input [7:0] b,
|
||||
output [15:0] y);
|
||||
wire co;
|
||||
wire [31:0] out;
|
||||
SB_MAC16 i_sbmac16
|
||||
(
|
||||
.A(a),
|
||||
.B(b),
|
||||
.C(8'd0),
|
||||
.D(8'd0),
|
||||
.O(out),
|
||||
.CLK(clk),
|
||||
.IRSTTOP(rst),
|
||||
.IRSTBOT(rst),
|
||||
.ORSTTOP(rst),
|
||||
.ORSTBOT(rst),
|
||||
.AHOLD(1'b0),
|
||||
.BHOLD(1'b0),
|
||||
.CHOLD(1'b0),
|
||||
.DHOLD(1'b0),
|
||||
.OHOLDTOP(1'b0),
|
||||
.OHOLDBOT(1'b0),
|
||||
.OLOADTOP(1'b0),
|
||||
.OLOADBOT(1'b0),
|
||||
.ADDSUBTOP(1'b0),
|
||||
.ADDSUBBOT(1'b0),
|
||||
.CO(co),
|
||||
.CI(1'b0),
|
||||
.ACCUMCI(),
|
||||
.ACCUMCO(),
|
||||
.SIGNEXTIN(),
|
||||
.SIGNEXTOUT()
|
||||
);
|
||||
|
||||
//Config: mult_8x8_pipeline_unsigned
|
||||
|
||||
defparam i_sbmac16. B_SIGNED = 1'b0;
|
||||
defparam i_sbmac16. A_SIGNED = 1'b0;
|
||||
defparam i_sbmac16. MODE_8x8 = 1'b1;
|
||||
|
||||
defparam i_sbmac16. BOTADDSUB_CARRYSELECT = 2'b00;
|
||||
defparam i_sbmac16. BOTADDSUB_UPPERINPUT = 1'b0;
|
||||
defparam i_sbmac16. BOTADDSUB_LOWERINPUT = 2'b00;
|
||||
defparam i_sbmac16. BOTOUTPUT_SELECT = 2'b10;
|
||||
|
||||
defparam i_sbmac16. TOPADDSUB_CARRYSELECT = 2'b00;
|
||||
defparam i_sbmac16. TOPADDSUB_UPPERINPUT = 1'b0;
|
||||
defparam i_sbmac16. TOPADDSUB_LOWERINPUT = 2'b00;
|
||||
defparam i_sbmac16. TOPOUTPUT_SELECT = 2'b10;
|
||||
|
||||
defparam i_sbmac16. PIPELINE_16x16_MULT_REG2 = 1'b0;
|
||||
defparam i_sbmac16. PIPELINE_16x16_MULT_REG1 = 1'b1;
|
||||
defparam i_sbmac16. BOT_8x8_MULT_REG = 1'b1;
|
||||
defparam i_sbmac16. TOP_8x8_MULT_REG = 1'b1;
|
||||
defparam i_sbmac16. D_REG = 1'b0;
|
||||
defparam i_sbmac16. B_REG = 1'b1;
|
||||
defparam i_sbmac16. A_REG = 1'b1;
|
||||
defparam i_sbmac16. C_REG = 1'b0;
|
||||
|
||||
assign y = out[15:0];
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
set_io r_led 39
|
||||
set_io g_led 40
|
||||
set_io b_led 41
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
module top(
|
||||
input r_in,
|
||||
input g_in,
|
||||
input b_in,
|
||||
output r_led,
|
||||
output g_led,
|
||||
output b_led);
|
||||
|
||||
wire curren;
|
||||
wire rgbleden;
|
||||
|
||||
SB_RGBA_DRV RGBA_DRIVER (
|
||||
.CURREN(curren),
|
||||
.RGBLEDEN(rgbleden),
|
||||
.RGB0PWM(r_in),
|
||||
.RGB1PWM(r_in),
|
||||
.RGB2PWM(r_in),
|
||||
.RGB0(r_led),
|
||||
.RGB1(g_led),
|
||||
.RGB2(b_led)
|
||||
);
|
||||
|
||||
defparam RGBA_DRIVER.CURRENT_MODE = "0b0";
|
||||
defparam RGBA_DRIVER.RGB0_CURRENT = "0b000011";
|
||||
defparam RGBA_DRIVER.RGB1_CURRENT = "0b001111";
|
||||
defparam RGBA_DRIVER.RGB2_CURRENT = "0b111111";
|
||||
|
||||
assign curren = 1'b1;
|
||||
assign rgbleden = 1'b1;
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
module top(
|
||||
input clk,
|
||||
input [13:0] addr,
|
||||
input [7:0] din,
|
||||
input wren,
|
||||
input cs,
|
||||
output [7:0] dout
|
||||
);
|
||||
|
||||
SB_SPRAM256KA spram_i
|
||||
(
|
||||
.ADDRESS(addr),
|
||||
.DATAIN(din),
|
||||
.MASKWREN(4'b1111),
|
||||
.WREN(wren),
|
||||
.CHIPSELECT(cs),
|
||||
.CLOCK(clk),
|
||||
.STANDBY(1'b0),
|
||||
.SLEEP(1'b0),
|
||||
.POWEROFF(1'b0),
|
||||
.DATAOUT(dout)
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
@ -801,7 +801,7 @@ void FpgaConfig::write_ascii(std::ostream &ofs) const
|
|||
error("cram_x %d (bit %d, %d) larger than bank size %lu\n", cram_x, bit_x, bit_y, this->cram[cram_bank].size());
|
||||
}
|
||||
if (cram_y > int(this->cram[cram_bank][cram_x].size())) {
|
||||
error("cram_y %d larger than bank size %lu\n", cram_y, this->cram[cram_bank][cram_x].size());
|
||||
error("cram_y %d (bit %d, %d) larger than bank %d size %lu\n", cram_y, bit_x, bit_y, cram_bank, this->cram[cram_bank][cram_x].size());
|
||||
}
|
||||
ofs << (this->cram[cram_bank][cram_x][cram_y] ? '1' : '0');
|
||||
}
|
||||
|
|
@ -980,8 +980,18 @@ vector<int> FpgaConfig::chip_cols() const
|
|||
string FpgaConfig::tile_type(int x, int y) const
|
||||
{
|
||||
if ((x == 0 || x == this->chip_width()+1) && (y == 0 || y == this->chip_height()+1)) return "corner";
|
||||
// The sides on the 5k devices are unsupported tile types.
|
||||
if (this->device == "5k" && (x == 0 || x == this->chip_width()+1)) return "unsupported";
|
||||
// The sides on the 5k devices are IPConnect or DSP tiles
|
||||
if (this->device == "5k" && (x == 0 || x == this->chip_width()+1)) {
|
||||
if( (y == 5) || (y == 10) || (y == 15) || (y == 23)) //check ordering here, tile 23-26 might be reversed
|
||||
return "dsp0";
|
||||
if( (y == 6) || (y == 11) || (y == 16) || (y == 24))
|
||||
return "dsp1";
|
||||
if( (y == 7) || (y == 12) || (y == 17) || (y == 25))
|
||||
return "dsp2";
|
||||
if( (y == 8) || (y == 13) || (y == 18) || (y == 26))
|
||||
return "dsp3";
|
||||
return "ipconn";
|
||||
}
|
||||
if ((x == 0 || x == this->chip_width()+1) || (y == 0 || y == this->chip_height()+1)) return "io";
|
||||
|
||||
if (this->device == "384") return "logic";
|
||||
|
|
@ -1011,7 +1021,9 @@ int FpgaConfig::tile_width(const string &type) const
|
|||
if (type == "ramb") return 42;
|
||||
if (type == "ramt") return 42;
|
||||
if (type == "io") return 18;
|
||||
if (type == "unsupported") return 76;
|
||||
if (type.substr(0, 3) == "dsp") return 54;
|
||||
if (type == "ipconn") return 54;
|
||||
|
||||
panic("Unknown tile type '%s'.\n", type.c_str());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue