Merge pull request #144 from mithro/nextpnr-migen-update
Integrate latest migen changes for lattice/icestorm.
This commit is contained in:
commit
291843ee76
|
@ -86,15 +86,27 @@ class LatticeiCE40AsyncResetSynchronizer:
|
|||
class LatticeiCE40TristateImpl(Module):
|
||||
def __init__(self, io, o, oe, i):
|
||||
nbits, sign = value_bits_sign(io)
|
||||
for bit in range(nbits):
|
||||
if nbits == 1:
|
||||
# If `io` is an expression like `port[x]`, it is not legal to index further
|
||||
# into it if it is only 1 bit wide.
|
||||
self.specials += \
|
||||
Instance("SB_IO",
|
||||
p_PIN_TYPE=C(0b101001, 6),
|
||||
io_PACKAGE_PIN=io[bit],
|
||||
io_PACKAGE_PIN=io,
|
||||
i_OUTPUT_ENABLE=oe,
|
||||
i_D_OUT_0=o[bit],
|
||||
o_D_IN_0=i[bit],
|
||||
i_D_OUT_0=o,
|
||||
o_D_IN_0=i,
|
||||
)
|
||||
else:
|
||||
for bit in range(nbits):
|
||||
self.specials += \
|
||||
Instance("SB_IO",
|
||||
p_PIN_TYPE=C(0b101001, 6),
|
||||
io_PACKAGE_PIN=io[bit],
|
||||
i_OUTPUT_ENABLE=oe,
|
||||
i_D_OUT_0=o[bit],
|
||||
o_D_IN_0=i[bit],
|
||||
)
|
||||
|
||||
|
||||
class LatticeiCE40Tristate(Module):
|
||||
|
|
|
@ -12,29 +12,27 @@ from litex.build import tools
|
|||
from litex.build.lattice import common
|
||||
|
||||
|
||||
def _format_constraint(c):
|
||||
pass
|
||||
|
||||
|
||||
def _format_pcf(signame, pin, others, resname):
|
||||
return "set_io " + signame + " " + pin + "\n"
|
||||
|
||||
|
||||
def _build_pcf(named_sc, named_pc):
|
||||
r = ""
|
||||
for sig, pins, others, resname in named_sc:
|
||||
if len(pins) > 1:
|
||||
for i, p in enumerate(pins):
|
||||
r += _format_pcf(sig + "[" + str(i) + "]", p, others, resname)
|
||||
for bit, pin in enumerate(pins):
|
||||
r += "set_io {}[{}] {}\n".format(sig, bit, pin)
|
||||
else:
|
||||
r += _format_pcf(sig, pins[0], others, resname)
|
||||
r += "set_io {} {}\n".format(sig, pins[0])
|
||||
if named_pc:
|
||||
r += "\n" + "\n\n".join(named_pc)
|
||||
return r
|
||||
|
||||
|
||||
def _build_script(source, build_template, build_name, pnr_pkg_opts,
|
||||
icetime_pkg_opts, freq_constraint):
|
||||
def _build_pre_pack(vns, freq_cstrs):
|
||||
r = ""
|
||||
for sig in freq_cstrs:
|
||||
r += """ctx.addClock("{}", {})\n""".format(vns.get_name(sig), freq_cstrs[sig])
|
||||
return r
|
||||
|
||||
|
||||
def _build_script(source, build_template, build_name, **kwargs):
|
||||
if sys.platform in ("win32", "cygwin"):
|
||||
script_ext = ".bat"
|
||||
build_script_contents = "@echo off\nrem Autogenerated by Migen\n\n"
|
||||
|
@ -47,10 +45,8 @@ def _build_script(source, build_template, build_name, pnr_pkg_opts,
|
|||
for s in build_template:
|
||||
s_fail = s + "{fail_stmt}\n" # Required so Windows scripts fail early.
|
||||
build_script_contents += s_fail.format(build_name=build_name,
|
||||
pnr_pkg_opts=pnr_pkg_opts,
|
||||
icetime_pkg_opts=icetime_pkg_opts,
|
||||
freq_constraint=freq_constraint,
|
||||
fail_stmt=fail_stmt)
|
||||
fail_stmt=fail_stmt,
|
||||
**kwargs)
|
||||
|
||||
build_script_file = "build_" + build_name + script_ext
|
||||
tools.write_to_file(build_script_file, build_script_contents,
|
||||
|
@ -101,7 +97,7 @@ class LatticeIceStormToolchain:
|
|||
self.yosys_template = [
|
||||
"{read_files}",
|
||||
"attrmap -tocase keep -imap keep=\"true\" keep=1 -imap keep=\"false\" keep=0 -remove keep=0",
|
||||
"synth_ice40 -top top -blif {build_name}.blif",
|
||||
"synth_ice40 -top {build_name} -blif {build_name}.blif",
|
||||
]
|
||||
|
||||
self.build_template = [
|
||||
|
@ -114,12 +110,12 @@ class LatticeIceStormToolchain:
|
|||
self.nextpnr_yosys_template = [
|
||||
"{read_files}",
|
||||
"attrmap -tocase keep -imap keep=\"true\" keep=1 -imap keep=\"false\" keep=0 -remove keep=0",
|
||||
"synth_ice40 -top top -json {build_name}.json",
|
||||
"synth_ice40 {synth_opts} -top {build_name} -json {build_name}.json",
|
||||
]
|
||||
|
||||
self.nextpnr_build_template = [
|
||||
"yosys -q -l {build_name}.rpt {build_name}.ys",
|
||||
"nextpnr-ice40 {pnr_pkg_opts} --pcf {build_name}.pcf --json {build_name}.json --asc {build_name}.txt --freq {freq_constraint}",
|
||||
"nextpnr-ice40 {pnr_pkg_opts} --pcf {build_name}.pcf --json {build_name}.json --asc {build_name}.txt --pre-pack {build_name}_pre_pack.py",
|
||||
"icepack {build_name}.txt {build_name}.bin"
|
||||
]
|
||||
|
||||
|
@ -127,7 +123,7 @@ class LatticeIceStormToolchain:
|
|||
|
||||
# platform.device should be of the form "ice40-{lp384, hx1k, etc}-{tq144, etc}"
|
||||
def build(self, platform, fragment, build_dir="build", build_name="top",
|
||||
toolchain_path=None, use_nextpnr=True, run=True, **kwargs):
|
||||
toolchain_path=None, use_nextpnr=True, synth_opts="", run=True, **kwargs):
|
||||
os.makedirs(build_dir, exist_ok=True)
|
||||
cwd = os.getcwd()
|
||||
os.chdir(build_dir)
|
||||
|
@ -146,7 +142,8 @@ class LatticeIceStormToolchain:
|
|||
else:
|
||||
chosen_yosys_template = self.yosys_template
|
||||
ys_contents = "\n".join(_.format(build_name=build_name,
|
||||
read_files=self.gen_read_files(platform, v_file))
|
||||
read_files=self.gen_read_files(platform, v_file),
|
||||
synth_opts=synth_opts)
|
||||
for _ in chosen_yosys_template)
|
||||
|
||||
ys_name = build_name + ".ys"
|
||||
|
@ -161,6 +158,13 @@ class LatticeIceStormToolchain:
|
|||
pnr_pkg_opts = "-d " + self.get_size_string(series_size) + \
|
||||
" -P " + package
|
||||
icetime_pkg_opts = "-P " + package + " -d " + series_size
|
||||
|
||||
if use_nextpnr:
|
||||
tools.write_to_file(build_name + "_pre_pack.py",
|
||||
_build_pre_pack(v_output.ns, self.freq_constraints))
|
||||
# icetime can only handle a single global constraint, so we test against the fastest
|
||||
# clock; though imprecise, if the global design satisfies the fastest clock, we can
|
||||
# be sure all other constraints are satisfied.
|
||||
freq_constraint = str(max(self.freq_constraints.values(),
|
||||
default=0.0))
|
||||
|
||||
|
@ -168,8 +172,12 @@ class LatticeIceStormToolchain:
|
|||
chosen_build_template = self.nextpnr_build_template
|
||||
else:
|
||||
chosen_build_template = self.build_template
|
||||
script = _build_script(False, chosen_build_template, build_name,
|
||||
pnr_pkg_opts, icetime_pkg_opts, freq_constraint)
|
||||
script = _build_script(source=False,
|
||||
build_template=chosen_build_template,
|
||||
build_name=build_name,
|
||||
pnr_pkg_opts=pnr_pkg_opts,
|
||||
icetime_pkg_opts=icetime_pkg_opts,
|
||||
freq_constraint=freq_constraint)
|
||||
|
||||
if run:
|
||||
_run_script(script)
|
||||
|
@ -190,7 +198,9 @@ class LatticeIceStormToolchain:
|
|||
"hx1k": ["vq100", "cb132", "tq144"],
|
||||
"lp8k": ["cm81", "cm81:4k", "cm121", "cm121:4k", "cm225",
|
||||
"cm225:4k"],
|
||||
"hx8k": ["cb132", "cb132:4k", "tq144:4k", "cm225", "ct256"],
|
||||
"hx8k": ["bg121", "bg121:4k", "cb132", "cb132:4k", "cm121",
|
||||
"cm121:4k", "cm225", "cm225:4k", "cm81", "cm81:4k",
|
||||
"ct256", "tq144:4k"],
|
||||
"up3k": ["sg48", "uwg30"],
|
||||
"up5k": ["sg48", "uwg30"],
|
||||
}
|
||||
|
@ -219,11 +229,6 @@ class LatticeIceStormToolchain:
|
|||
filename))
|
||||
return "\n".join(read_files)
|
||||
|
||||
# icetime can only handle a single global constraint. Pending more
|
||||
# finely-tuned analysis features in arachne-pnr and IceStorm, save
|
||||
# all the constraints in a dictionary and test against the fastest clk.
|
||||
# Though imprecise, if the global design satisfies the fastest clock,
|
||||
# we can be sure all other constraints are satisfied.
|
||||
def add_period_constraint(self, platform, clk, period):
|
||||
new_freq = 1000.0/period
|
||||
|
||||
|
|
Loading…
Reference in New Issue