Merge pull request #116 from daveshah1/up5k_misc_fixes

Miscellaneous UltraPlus fixes and improvements
This commit is contained in:
Clifford Wolf 2018-01-16 18:03:49 +01:00 committed by GitHub
commit edef5d2465
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 270 additions and 10109 deletions

View File

@ -205,6 +205,14 @@ The <span style="font-family:monospace">CLKHF</span> output of SB_HFOSC is conne
<p>Configuration bit <span style="font-family:monospace">CLKHF_DIV[1]</span> maps to DSP1 tile (0, 16) config bit <span style="font-family:monospace">CBIT_4</span>, and
<span style="font-family:monospace">CLKHF_DIV[0]</span> maps to DSP1 tile (0, 16) config bit <span style="font-family:monospace">CBIT_3</span>.</p>
<p>There is also an undocumented trimming function of the HFOSC, using the ports <span style="font-family:monospace">TRIM0</span> through <span style="font-family:monospace">TRIM9</span>. This can only be accessed directly in iCECUBE if you modify the standard cell library. However
if you set the attribute <span style="font-family:monospace">VPP_2V5_TO_1P8V</span> (which itself is not that well documented either) to 1 on the top level module, then the configuration bit
<span style="font-family:monospace">CBIT_5</span> of (0, 16) is set; and <span style="font-family:monospace">TRIM8</span> and <span style="font-family:monospace">TRIM4</span> are connected to
the same net as <span style="font-family:monospace">CLKHFPU</span>.</p>
<p><span style="font-family:monospace">TRIM[3:0]</span> connect to <span style="font-family:monospace">(25, 28, lutff_[7:4]/in_0)</span> and <span style="font-family:monospace">TRIM[9:4]</span>
connect to <span style="font-family:monospace">(25, 29, lutff_[5:0]/in_3)</span>. <span style="font-family:monospace">CBIT_5</span> of (0, 16) must be set to enable trimming. The trim range
on the device used for testing was from 30.1 to 75.9 MHz. TRIM9 seemed to have no effect, the other inputs could broadly be considered to form a binary word, however it appeared neither linear
nor even monotonic.</p>
<h3>SB_LFOSC</h3>
<p>The <span style="font-family:monospace">CLKLFPU</span> input connects through IPConnect tile (25, 29) input <span style="font-family:monospace">lutff_0/in_1</span>;
and the <span style="font-family:monospace">CLKLFEN</span> input connects through input <span style="font-family:monospace">lutff_7/in_3</span> of the same tile.<br/>
@ -282,6 +290,19 @@ can be used as an open-drain IO using the standard IO cell.</p>
</table>
<h3>I<sup>3</sup>C capable IO</h3>
<p>The UltraPlus devices have two IO pins designed for the new MIPI I<sup>3</sup>C standard (pins 23 and 25 in the SG48 package),
compared to normal IO pins they have two switchable pullups each. One of these pullups, the weak pullup, is fixed at 100k and the
other can be set to 3.3k, 6.8k or 10k using the mechanism above. The pullup control signals do not
connect directly to the IO tile, but instead connect through an IPConnect tile.</p>
<p>The connections are listed below:</p>
<table class="ctab">
<tr><th>Signal</th><th>Pin 23<br/>(19, 31, 0)</th><th>Pin 25<br/>(19, 31, 1)</th></tr>
<tr><td>PU_ENB</td><td>(25, 27, lutff_6/in_0)</td><td>(25, 27, lutff_7/in_0)</td></tr>
<tr><td>WEAK_PU_ENB</td><td>(25, 27, lutff_4/in_0)</td><td>(25, 27, lutff_5/in_0)</td></tr>
</table>
<h2>Hard IP</h2>
<p>The UltraPlus devices contain three types of Hard IP: I<sup>2</sup>C (<span style="font-family:monospace">SB_I2C</span>), SPI (<span style="font-family:monospace">SB_SPI</span>), and LED PWM generation
@ -383,6 +404,10 @@ where multiple bits are used to enable an IP they are labeled as <span style="fo
<tr><td>SOE</td><td>(0, 20, slf_op_5)</td><td>(25, 20, slf_op_5)</td></tr>
<tr><td>SPIIRQ</td><td>(0, 20, slf_op_2)</td><td>(25, 20, slf_op_2)</td></tr>
<tr><td>SPIWKUP</td><td>(0, 20, slf_op_3)</td><td>(25, 20, slf_op_3)</td></tr>
<tr><td><em>SPI_ENABLE_0</em></td><td><em>(7, 0, cbit2usealt_in_0)</em></td><td><em>(23, 0, cbit2usealt_in_0)</em></td></tr>
<tr><td><em>SPI_ENABLE_1</em></td><td><em>(7, 0, cbit2usealt_in_1)</em></td><td><em>(24, 0, cbit2usealt_in_0)</em></td></tr>
<tr><td><em>SPI_ENABLE_2</em></td><td><em>(6, 0, cbit2usealt_in_0)</em></td><td><em>(23, 0, cbit2usealt_in_1)</em></td></tr>
<tr><td><em>SPI_ENABLE_3</em></td><td><em>(6, 0, cbit2usealt_in_1)</em></td><td><em>(24, 0, cbit2usealt_in_1)</em></td></tr>
</table>
</td><td>
<table class="cstab">

View File

@ -0,0 +1,36 @@
PROJ = rgb
PIN_DEF = rgb_uwg30.pcf
DEVICE = up5k
ARACHNE = arachne-pnr
ARACHNE_ARGS =
ICEPACK = icepack
ICETIME = icetime
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 $^ -P uwg30
%.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

View File

@ -0,0 +1,3 @@
set_io RGB0 A5
set_io RGB1 B5
set_io RGB2 C5

View File

@ -318,8 +318,8 @@ class iceconfig:
if (x, y) in self.ramt_tiles: return ramttile_db
elif self.device == "5k":
if (x, y) in self.logic_tiles: return logictile_5k_db
if (x, y) in self.ramb_tiles: return rambtile_5k_db
if (x, y) in self.ramt_tiles: return ramttile_5k_db
if (x, y) in self.ramb_tiles: return rambtile_8k_db
if (x, y) in self.ramt_tiles: return ramttile_8k_db
if (x, y) in self.ipcon_tiles: return ipcon_5k_db
if (x, y) in self.dsp_tiles[0]: return dsp0_5k_db
if (x, y) in self.dsp_tiles[1]: return dsp1_5k_db
@ -419,7 +419,7 @@ class iceconfig:
def do_direction(name, nx, ny):
if (0 < nx < self.max_x or self.is_ultra()) and 0 < ny < self.max_y:
neighbours.add((nx, ny, "neigh_op_%s_%d" % (name, func)))
if nx in (0, self.max_x) and 0 < ny < self.max_y and nx != x:
if nx in (0, self.max_x) and 0 < ny < self.max_y and nx != x and (not self.is_ultra()):
neighbours.add((nx, ny, "logic_op_%s_%d" % (name, func)))
if ny in (0, self.max_y) and 0 < nx < self.max_x and ny != y:
neighbours.add((nx, ny, "logic_op_%s_%d" % (name, func)))
@ -463,7 +463,7 @@ class iceconfig:
else:
assert False
elif pos == "x" and npos in ("l", "r", "t", "b"):
elif pos == "x" and ((npos in ("t", "b")) or ((not self.is_ultra()) and (npos in ("l", "r")))):
if func in (0, 4): return (nx, ny, "io_0/D_IN_0")
if func in (1, 5): return (nx, ny, "io_0/D_IN_1")
if func in (2, 6): return (nx, ny, "io_1/D_IN_0")
@ -507,34 +507,52 @@ class iceconfig:
return funcnets
def ultraplus_follow_corner(self, corner, direction, netname):
m = re.match("span4_(horz|vert)_([lrtb])_(\d+)$", netname)
if not m:
return None
cur_edge = m.group(2)
cur_index = int(m.group(3))
if direction not in corner:
return None
if direction != cur_edge:
return None
h_idx, v_idx = self.ultraplus_trace_corner_idx(corner, cur_index)
if h_idx is None and (direction == "b" or direction == "t"):
return None
if v_idx is None and (direction == "l" or direction == "r"):
return None
if corner == "bl" and direction == "l":
return (0, 1, sp4v_normalize("sp4_v_b_%d" % v_idx))
if corner == "bl" and direction == "b":
return (1, 0, ultra_span4_horz_normalize("span4_horz_l_%d" % h_idx))
if corner == "br" and direction == "r":
return (self.max_x, 1, sp4v_normalize("sp4_v_b_%d" % v_idx))
if corner == "br" and direction == "b":
return (self.max_x-1, 0, ultra_span4_horz_normalize("span4_horz_r_%d" % h_idx))
if corner == "tl" and direction == "l":
return (0, self.max_y-1, sp4v_normalize("sp4_v_t_%d" % v_idx))
if corner == "tl" and direction == "t":
return (1, self.max_y, ultra_span4_horz_normalize("span4_horz_l_%d" % h_idx))
if corner == "tr" and direction == "r":
return (self.max_x, self.max_y-1, sp4v_normalize("sp4_v_t_%d" % v_idx))
if corner == "tr" and direction == "t":
return (self.max_x-1, self.max_y, ultra_span4_horz_normalize("span4_horz_r_%d" % h_idx))
assert False
#UltraPlus corner routing: given the corner name and net index,
#return a tuple containing H and V indexes, or none if NA
def ultraplus_trace_corner(self, corner, idx):
def ultraplus_trace_corner_idx(self, corner, idx):
h_idx = None
v_idx = None
if corner == "bl":
if idx >= 4:
v_idx = idx + 28
if idx >= 32 and idx < 48:
h_idx = idx - 28
elif corner == "tl":
#TODO: bounds check for v_idx case?
if idx >= 4:
v_idx = (idx + 8) ^ 1
if idx >= 12 and idx < 28:
h_idx = (idx ^ 1) - 8
elif corner == "tr":
#TODO: bounds check for v_idx case?
if idx <= 16:
v_idx = (idx + 12) ^ 1
if idx >= 12 and idx < 28:
h_idx = (idx ^ 1) - 12
elif corner == "br":
#TODO: bounds check for v_idx case?
if idx <= 16:
if corner == "bl" or corner == "br":
if idx < 16:
v_idx = idx + 32
if idx >= 32 and idx < 48: #check
if idx >= 32 and idx < 48:
h_idx = idx - 32
elif corner == "tl" or corner == "tr":
if idx >= 0 and idx < 16:
v_idx = idx
h_idx = idx
return (h_idx, v_idx)
def get_corner(self, x, y):
@ -551,7 +569,7 @@ class iceconfig:
corner += "r"
else:
corner += "x"
return corner
return corner
def follow_net(self, netspec):
x, y, netname = netspec
@ -608,37 +626,16 @@ class iceconfig:
if direction == "b": s = (x, y-1, n)
if s[0] in (0, self.max_x) and s[1] in (0, self.max_y):
if re.match("span4_(vert|horz)_[lrtb]_\d+$", n):
m = re.match("span4_(vert|horz)_([lrtb])_\d+$", n)
#We ignore L and T edges when performing the Ultra/UltraPlus corner algorithm
if self.is_ultra() and (m.group(2) == "l" or m.group(2) == "t"):
if self.is_ultra():
s = self.ultraplus_follow_corner(self.get_corner(s[0], s[1]), direction, n)
if s is None:
continue
elif re.match("span4_(vert|horz)_[lrtb]_\d+$", n) and not self.is_ultra():
m = re.match("span4_(vert|horz)_([lrtb])_\d+$", n)
vert_net = n.replace("_l_", "_t_").replace("_r_", "_b_").replace("_horz_", "_vert_")
horz_net = n.replace("_t_", "_l_").replace("_b_", "_r_").replace("_vert_", "_horz_")
if self.is_ultra(): #Convert between span4 and sp4, and perform U/UP corner tracing
m = re.match("span4_vert_([lrtb])_(\d+)$", vert_net)
assert m
idx = int(m.group(2))
h_idx, v_idx = self.ultraplus_trace_corner(self.get_corner(s[0], s[1]), idx)
if v_idx is None:
if (s[0] == 0 and s[1] == 0 and direction == "l") or (s[0] == self.max_x and s[1] == self.max_y and direction == "r"):
continue #Not routed, skip
else:
vert_net = "sp4_v_%s_%d" % (m.group(1), v_idx)
m = re.match("span4_horz_([lrtb])_(\d+)$", horz_net)
assert m
idx = int(m.group(2))
h_idx, v_idx = self.ultraplus_trace_corner(self.get_corner(s[0], s[1]), idx)
if h_idx is None:
if (s[0] == 0 and s[1] == 0 and direction == "b") or (s[0] == self.max_x and s[1] == self.max_y and direction == "t"):
continue #Not routed, skip
else:
horz_net = "span4_horz_%s_%d" % (m.group(1), h_idx)
if s[0] == 0 and s[1] == 0:
if direction == "l": s = (0, 1, vert_net)
if direction == "b": s = (1, 0, horz_net)
@ -649,30 +646,6 @@ class iceconfig:
vert_net = netname.replace("_l_", "_t_").replace("_r_", "_b_").replace("_horz_", "_vert_")
horz_net = netname.replace("_t_", "_l_").replace("_b_", "_r_").replace("_vert_", "_horz_")
if self.is_ultra():
# Might have sp4 not span4 here
vert_net = vert_net.replace("_h_", "_v_")
horz_net = horz_net.replace("_v_", "_h_")
m = re.match("(span4_vert|sp4_v)_([lrtb])_(\d+)$", vert_net)
assert m
idx = int(m.group(3))
h_idx, v_idx = self.ultraplus_trace_corner(self.get_corner(s[0], s[1]), idx)
if v_idx is None:
if (s[0] == 0 and s[1] == self.max_y and direction == "l") or (s[0] == self.max_x and s[1] == 0 and direction == "r"):
continue
else:
vert_net = "sp4_v_%s_%d" % (m.group(2), v_idx)
m = re.match("(span4_horz|sp4_h)_([lrtb])_(\d+)$", horz_net)
assert m
idx = int(m.group(3))
h_idx, v_idx = self.ultraplus_trace_corner(self.get_corner(s[0], s[1]), idx)
if h_idx is None:
if (s[0] == 0 and s[1] == self.max_y and direction == "t") or (s[0] == self.max_x and s[1] == 0 and direction == "b"):
continue
else:
horz_net = "span4_horz_%s_%d" % (m.group(2), h_idx)
if s[0] == 0 and s[1] == self.max_y:
if direction == "l": s = (0, self.max_y-1, vert_net)
@ -752,7 +725,7 @@ class iceconfig:
if self.device == "1k":
add_seed_segments(idx, tile, rambtile_db)
elif self.device == "5k":
add_seed_segments(idx, tile, rambtile_5k_db)
add_seed_segments(idx, tile, rambtile_8k_db)
elif self.device == "8k":
add_seed_segments(idx, tile, rambtile_8k_db)
else:
@ -762,7 +735,7 @@ class iceconfig:
if self.device == "1k":
add_seed_segments(idx, tile, ramttile_db)
elif self.device == "5k":
add_seed_segments(idx, tile, ramttile_5k_db)
add_seed_segments(idx, tile, ramttile_8k_db)
elif self.device == "8k":
add_seed_segments(idx, tile, ramttile_8k_db)
else:
@ -1008,7 +981,34 @@ def sp4h_normalize(netname, edge=""):
return "sp4_h_r_%d" % ((cur_index+12)^1)
return netname
# "Normalization" of span4 (not just sp4) is needed during Ultra/UltraPlus
# corner tracing
def ultra_span4_horz_normalize(netname, edge=""):
m = re.match("span4_horz_([rl])_(\d+)$", netname)
assert m
if not m: return None
cur_edge = m.group(1)
cur_index = int(m.group(2))
if cur_edge == edge:
return netname
if edge == "":
if cur_edge == "l" and cur_index < 12:
return "span4_horz_r_%d" % (cur_index + 4)
else:
return netname
elif edge == "l" and cur_edge == "r":
if cur_index < 4:
return None
else:
cur_index -= 4
return "span4_horz_l_%d" % cur_index
elif edge == "r" and cur_edge == "l":
if cur_index < 12:
return "span4_horz_r_%d" % (cur_index + 4)
else:
return None
assert False
def sp4v_normalize(netname, edge=""):
m = re.match("sp4_v_([bt])_(\d+)$", netname)
assert m
@ -1141,11 +1141,11 @@ def pos_follow_net(pos, direction, netname, is_ultra):
m = re.match("sp4_v_[tb]_(\d+)$", netname)
if m and direction in ("t", "T"):
if is_ultra and direction == "T" and pos in ("l", "r"):
return re.sub("sp4_v_", "span4_vert_", netname)
n = sp4v_normalize(netname, "t")
if n is not None:
if direction == "t":
if is_ultra and direction == "T" and pos in ("l", "r"):
return re.sub("sp4_v_", "span4_vert_", n)
elif direction == "t":
n = re.sub("_t_", "_b_", n)
n = sp4v_normalize(n)
else:
@ -1153,11 +1153,11 @@ def pos_follow_net(pos, direction, netname, is_ultra):
n = re.sub("sp4_v_", "span4_vert_", n)
return n
if m and direction in ("b", "B"):
if is_ultra and direction == "B" and pos in ("l", "r"):
return re.sub("sp4_v_", "span4_vert_", netname)
n = sp4v_normalize(netname, "b")
if n is not None:
if direction == "b":
if is_ultra and direction == "B" and pos in ("l", "r"):
return re.sub("sp4_v_", "span4_vert_", n)
elif direction == "b":
n = re.sub("_b_", "_t_", n)
n = sp4v_normalize(n)
else:
@ -1194,6 +1194,8 @@ def pos_follow_net(pos, direction, netname, is_ultra):
if direction == "t":
n = re.sub("_t_", "_b_", n)
n = sp12v_normalize(n)
elif direction == "T" and pos in ("l", "r"):
pass
else:
n = re.sub("_t_", "_", n)
n = re.sub("sp12_v_", "span12_vert_", n)
@ -1204,6 +1206,8 @@ def pos_follow_net(pos, direction, netname, is_ultra):
if direction == "b":
n = re.sub("_b_", "_t_", n)
n = sp12v_normalize(n)
elif direction == "B" and pos in ("l", "r"):
pass
else:
n = re.sub("_b_", "_", n)
n = re.sub("sp12_v_", "span12_vert_", n)
@ -1226,8 +1230,10 @@ def pos_follow_net(pos, direction, netname, is_ultra):
m = re.match("span4_horz_([rl])_(\d+)$", netname)
if m:
case, idx = direction + m.group(1), int(m.group(2))
if direction == "L" or direction == "R":
return netname
if direction == "L":
return ultra_span4_horz_normalize(netname, "l")
elif direction == "R":
return ultra_span4_horz_normalize(netname, "r")
if case == "ll":
return "span4_horz_r_%d" % idx
if case == "lr" and idx >= 4:
@ -1316,9 +1322,6 @@ def run_checks_neigh():
# Skip the corners.
if x in (0, ic.max_x) and y in (0, ic.max_y):
continue
# Skip the sides of a 5k device.
if self.is_ultra() and x in (0, ic.max_x):
continue
add_segments((x, y), ic.tile_db(x, y))
if (x, y) in ic.logic_tiles:
all_segments.add((x, y, "lutff_7/cout"))
@ -2344,7 +2347,11 @@ ieren_db = {
( 7, 0, 1, 7, 0, 0),
( 5, 0, 0, 5, 0, 1),
( 6, 0, 0, 6, 0, 1),
( 7, 0, 0, 7, 0, 1)
( 7, 0, 0, 7, 0, 1),
(12, 31, 0, 12, 31, 1),
(12, 0, 0, 12, 0, 1),
(13, 0, 0, 13, 0, 1),
(12, 0, 1, 12, 0, 0)
]
}
@ -4396,6 +4403,29 @@ pinloc_db = {
( "47", 6, 0, 0),
( "48", 7, 0, 0),
],
"5k-uwg30": [
( "A1", 19, 31, 1),
( "A2", 19, 31, 0),
( "A4", 12, 31, 0),
( "A5", 4, 31, 0),
( "B1", 19, 0, 0),
( "B3", 12, 31, 1),
( "B5", 5, 31, 0),
( "C1", 24, 0, 1),
( "C3", 12, 0, 0),
( "C5", 6, 31, 0),
( "D1", 24, 0, 0),
( "D3", 13, 0, 0),
( "D5", 6, 0, 0),
( "E1", 23, 0, 1),
( "E3", 13, 0, 1),
( "E4", 9, 0, 1),
( "E5", 5, 0, 0),
( "F1", 23, 0, 0),
( "F2", 19, 0, 1),
( "F4", 12, 0, 1),
( "F5", 6, 0, 1),
]
}
# This database contains the locations of configuration bits of the DSP tiles
@ -4692,8 +4722,19 @@ extra_cells_db = {
"CLKHFEN": (0, 29, "lutff_7/in_3"),
"CLKHF": (0, 29, "glb_netwk_4"),
"CLKHF_FABRIC": (0, 28, "slf_op_7"),
"TRIM0": (25, 28, "lutff_4/in_0"),
"TRIM1": (25, 28, "lutff_5/in_0"),
"TRIM2": (25, 28, "lutff_6/in_0"),
"TRIM3": (25, 28, "lutff_7/in_0"),
"TRIM4": (25, 29, "lutff_0/in_3"),
"TRIM5": (25, 29, "lutff_1/in_3"),
"TRIM6": (25, 29, "lutff_2/in_3"),
"TRIM7": (25, 29, "lutff_3/in_3"),
"TRIM8": (25, 29, "lutff_4/in_3"),
"TRIM9": (25, 29, "lutff_5/in_3"),
"CLKHF_DIV_1": (0, 16, "CBIT_4"),
"CLKHF_DIV_0": (0, 16, "CBIT_3")
"CLKHF_DIV_0": (0, 16, "CBIT_3"),
"TRIM_EN": (0, 16, "CBIT_5")
},
("LFOSC", (25, 31, 1)) : {
"CLKLFPU": (25, 29, "lutff_0/in_1"),
@ -4862,6 +4903,10 @@ extra_cells_db = {
"SOE": (0, 20, "slf_op_5"),
"SPIIRQ": (0, 20, "slf_op_2"),
"SPIWKUP": (0, 20, "slf_op_3"),
"SPI_ENABLE_0": (7, 0, "cbit2usealt_in_0"),
"SPI_ENABLE_1": (7, 0, "cbit2usealt_in_1"),
"SPI_ENABLE_2": (6, 0, "cbit2usealt_in_0"),
"SPI_ENABLE_3": (6, 0, "cbit2usealt_in_1"),
},
("SPI", (25, 0, 1)): {
"MCSNO0": (25, 21, "slf_op_2"),
@ -4912,6 +4957,10 @@ extra_cells_db = {
"SOE": (25, 20, "slf_op_5"),
"SPIIRQ": (25, 20, "slf_op_2"),
"SPIWKUP": (25, 20, "slf_op_3"),
"SPI_ENABLE_0": (23, 0, "cbit2usealt_in_0"),
"SPI_ENABLE_1": (24, 0, "cbit2usealt_in_0"),
"SPI_ENABLE_2": (23, 0, "cbit2usealt_in_1"),
"SPI_ENABLE_3": (24, 0, "cbit2usealt_in_1"),
},
("LEDDA_IP", (0, 31, 2)): {
"LEDDADDR0": (0, 28, "lutff_4/in_0"),
@ -4946,8 +4995,6 @@ logictile_8k_db = parse_db(iceboxdb.database_logic_txt, "8k")
logictile_384_db = parse_db(iceboxdb.database_logic_txt, "384")
rambtile_db = parse_db(iceboxdb.database_ramb_txt, "1k")
ramttile_db = parse_db(iceboxdb.database_ramt_txt, "1k")
rambtile_5k_db = parse_db(iceboxdb.database_ramb_5k_txt, "5k")
ramttile_5k_db = parse_db(iceboxdb.database_ramt_5k_txt, "5k")
rambtile_8k_db = parse_db(iceboxdb.database_ramb_8k_txt, "8k")
ramttile_8k_db = parse_db(iceboxdb.database_ramt_8k_txt, "8k")
@ -5044,19 +5091,19 @@ iotile_b_5k_db.append([["B12[2]"], "IpConfig", "cbit2usealt_in_1"])
iotile_b_5k_db.append([["B12[3]"], "IpConfig", "SDA_input_delay"])
iotile_b_5k_db.append([["B15[3]"], "IpConfig", "SDA_output_delay"])
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, dsp0_5k_db, dsp1_5k_db, dsp2_5k_db, dsp3_5k_db, ipcon_5k_db]:
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_8k_db, ramttile_8k_db, dsp0_5k_db, dsp1_5k_db, dsp2_5k_db, dsp3_5k_db, ipcon_5k_db]:
for entry in db:
if entry[1] in ("buffer", "routing"):
entry[2] = netname_normalize(entry[2],
ramb=(db == rambtile_db),
ramt=(db == ramttile_db),
ramb_8k=(db in (rambtile_8k_db, rambtile_5k_db)),
ramt_8k=(db in (ramttile_8k_db, ramttile_5k_db)))
ramb_8k=(db == rambtile_8k_db),
ramt_8k=(db == ramttile_8k_db))
entry[3] = netname_normalize(entry[3],
ramb=(db == rambtile_db),
ramt=(db == ramttile_db),
ramb_8k=(db in (rambtile_8k_db, rambtile_5k_db)),
ramt_8k=(db in (ramttile_8k_db, ramttile_5k_db)))
ramb_8k=(db == rambtile_8k_db),
ramt_8k=(db == ramttile_8k_db))
unique_entries = dict()
while db:
entry = db.pop()

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,7 @@ endif
ifeq ($(DEVICECLASS), 5k)
DEVICE := up5k-sg48
RAM_SUFFIX := _5k
RAM_SUFFIX := _8k
endif
ifeq ($(DEVICECLASS), 8k)
@ -56,14 +56,11 @@ ifneq ($(RAM_SUFFIX),_8k)
cp cached_ramt_8k.txt bitdata_ramt_8k.txt
endif
ifneq ($(RAM_SUFFIX),_5k)
cp cached_ramb_5k.txt bitdata_ramb_5k.txt
cp cached_ramt_5k.txt bitdata_ramt_5k.txt
cp cached_dsp0_5k.txt bitdata_dsp0_5k.txt
cp cached_dsp1_5k.txt bitdata_dsp1_5k.txt
cp cached_dsp2_5k.txt bitdata_dsp2_5k.txt
cp cached_dsp3_5k.txt bitdata_dsp3_5k.txt
cp cached_ipcon_5k.txt bitdata_ipcon_5k.txt
endif
ICEDEVICE=$(DEVICECLASS) python3 database.py
python3 export.py

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -148,7 +148,7 @@ with open("database_ramt.txt", "w") as f:
for entry in read_database("bitdata_ramt.txt", "ramt"):
print("\t".join(entry), file=f)
for device_class in ["5k", "8k"]:
for device_class in ["8k"]:
with open("database_ramb_%s.txt" % (device_class, ), "w") as f:
for entry in read_database("bitdata_ramb_%s.txt" % (device_class, ), "ramb_" + device_class):
print("\t".join(entry), file=f)
@ -163,4 +163,4 @@ for dsp_idx in range(4):
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)
print("\t".join(entry), file=f)

View File

@ -5,7 +5,7 @@ device_class = os.getenv("ICEDEVICE")
with open("../icebox/iceboxdb.py", "w") as f:
files = [ "database_io", "database_logic", "database_ramb", "database_ramt", "database_ipcon_5k"]
for device_class in ["5k", "8k"]:
for device_class in ["8k"]:
files.append("database_ramb_" + device_class)
files.append("database_ramt_" + device_class)
for i in range(4):

View File

@ -43,8 +43,8 @@
("I2C", (25, 31, 0)): {
"I2CIRQ": (25, 30, "slf_op_7"),
"I2CWKUP": (25, 29, "slf_op_5"),
"I2C_ENABLE_0": (19, 31, "cbit2usealt_in_0"),
"I2C_ENABLE_1": (19, 31, "cbit2usealt_in_1"),
"I2C_ENABLE_0": (19, 31, "cbit2usealt_in_1"),
"I2C_ENABLE_1": (19, 31, "cbit2usealt_in_0"),
"SBACKO": (25, 30, "slf_op_6"),
"SBADRI0": (25, 30, "lutff_1/in_0"),
"SBADRI1": (25, 30, "lutff_2/in_0"),

View File

@ -47,6 +47,10 @@
"SOE": (0, 20, "slf_op_5"),
"SPIIRQ": (0, 20, "slf_op_2"),
"SPIWKUP": (0, 20, "slf_op_3"),
"SPI_ENABLE_0": (7, 0, "cbit2usealt_in_0"),
"SPI_ENABLE_1": (7, 0, "cbit2usealt_in_1"),
"SPI_ENABLE_2": (6, 0, "cbit2usealt_in_0"),
"SPI_ENABLE_3": (6, 0, "cbit2usealt_in_1"),
},
("SPI", (25, 0, 1)): {
"MCSNO0": (25, 21, "slf_op_2"),
@ -97,4 +101,8 @@
"SOE": (25, 20, "slf_op_5"),
"SPIIRQ": (25, 20, "slf_op_2"),
"SPIWKUP": (25, 20, "slf_op_3"),
"SPI_ENABLE_0": (23, 0, "cbit2usealt_in_0"),
"SPI_ENABLE_1": (24, 0, "cbit2usealt_in_0"),
"SPI_ENABLE_2": (23, 0, "cbit2usealt_in_1"),
"SPI_ENABLE_3": (24, 0, "cbit2usealt_in_1"),
},

View File

@ -0,0 +1,8 @@
set_io pin_23 23
set_io pin_25 25
set_io pin_23_puen 2
set_io pin_23_wkpuen 3
set_io pin_25_puen 4
set_io pin_25_wkpuen 6

35
icefuzz/tests/sb_io_i3c.v Normal file
View File

@ -0,0 +1,35 @@
module top (
inout pin_23,
inout pin_25,
input pin_23_puen,
input pin_23_wkpuen,
input pin_25_puen,
input pin_25_wkpuen);
(* PULLUP_RESISTOR = "3P3K" *)
SB_IO_I3C #(
.PIN_TYPE(6'b000001),
.PULLUP(1'b1),
.WEAK_PULLUP(1'b1),
.NEG_TRIGGER(1'b0)
) IO_PIN_0 (
.PACKAGE_PIN(pin_23),
.PU_ENB(pin_23_puen),
.WEAK_PU_ENB(pin_23_wkpuen)
) ;
(* PULLUP_RESISTOR = "3P3K" *)
SB_IO_I3C #(
.PIN_TYPE(6'b000001),
.PULLUP(1'b1),
.WEAK_PULLUP(1'b1),
.NEG_TRIGGER(1'b0)
) IO_PIN_1 (
.PACKAGE_PIN(pin_25),
.PU_ENB(pin_25_puen),
.WEAK_PU_ENB(pin_25_wkpuen)
);
endmodule