mirror of https://github.com/YosysHQ/icestorm.git
Merge pull request #116 from daveshah1/up5k_misc_fixes
Miscellaneous UltraPlus fixes and improvements
This commit is contained in:
commit
edef5d2465
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
set_io RGB0 A5
|
||||
set_io RGB1 B5
|
||||
set_io RGB2 C5
|
||||
251
icebox/icebox.py
251
icebox/icebox.py
|
|
@ -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()
|
||||
|
|
|
|||
2838
icebox/iceboxdb.py
2838
icebox/iceboxdb.py
File diff suppressed because it is too large
Load Diff
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
Loading…
Reference in New Issue