vendor.fpga.lattice_ice40: instantiate SB_IO and apply extras.
The PULLUP and PULLUP_RESISTOR extras are representable in the PCF file. The IO_STANDARD extra, however, can only be an SB_IO parameter.
This commit is contained in:
parent
c6a0761b3a
commit
dc17d06fe9
|
@ -111,10 +111,10 @@ class ConstraintManager:
|
||||||
phys = subsignal.io[0]
|
phys = subsignal.io[0]
|
||||||
pin = Pin(len(phys), dir, xdr, name=name)
|
pin = Pin(len(phys), dir, xdr, name=name)
|
||||||
if isinstance(phys, Pins):
|
if isinstance(phys, Pins):
|
||||||
port = Signal(pin.width, name="{}_io".format(pin.name))
|
port = Signal(pin.width, name="{}__io".format(pin.name))
|
||||||
if isinstance(phys, DiffPairs):
|
if isinstance(phys, DiffPairs):
|
||||||
port = (Signal(pin.width, name="{}_p".format(pin.name)),
|
port = (Signal(pin.width, name="{}__p".format(pin.name)),
|
||||||
Signal(pin.width, name="{}_n".format(pin.name)))
|
Signal(pin.width, name="{}__n".format(pin.name)))
|
||||||
self._ports.append((subsignal, pin, port))
|
self._ports.append((subsignal, pin, port))
|
||||||
return pin
|
return pin
|
||||||
else:
|
else:
|
||||||
|
@ -173,9 +173,9 @@ class ConstraintManager:
|
||||||
"it has been requested as a tristate buffer"
|
"it has been requested as a tristate buffer"
|
||||||
.format(name, number))
|
.format(name, number))
|
||||||
if isinstance(resource.io[0], Pins):
|
if isinstance(resource.io[0], Pins):
|
||||||
port_name = "{}_io".format(pin.name)
|
port_name = "{}__io".format(pin.name)
|
||||||
elif isinstance(resource.io[0], DiffPairs):
|
elif isinstance(resource.io[0], DiffPairs):
|
||||||
port_name = "{}_p".format(pin.name)
|
port_name = "{}__p".format(pin.name)
|
||||||
else:
|
else:
|
||||||
assert False
|
assert False
|
||||||
yield (port_name, period)
|
yield (port_name, period)
|
||||||
|
|
|
@ -66,7 +66,7 @@ class ConstraintManagerTestCase(FHDLTestCase):
|
||||||
self.assertEqual(len(ports), 1)
|
self.assertEqual(len(ports), 1)
|
||||||
|
|
||||||
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
||||||
("user_led_0_io", ["A0"], {})
|
("user_led_0__io", ["A0"], {})
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_request_with_dir(self):
|
def test_request_with_dir(self):
|
||||||
|
@ -82,7 +82,7 @@ class ConstraintManagerTestCase(FHDLTestCase):
|
||||||
ports = list(self.cm.iter_ports())
|
ports = list(self.cm.iter_ports())
|
||||||
self.assertEqual(len(ports), 2)
|
self.assertEqual(len(ports), 2)
|
||||||
scl, sda = ports
|
scl, sda = ports
|
||||||
self.assertEqual(ports[1].name, "i2c_0__sda_io")
|
self.assertEqual(ports[1].name, "i2c_0__sda__io")
|
||||||
self.assertEqual(ports[1].nbits, 1)
|
self.assertEqual(ports[1].nbits, 1)
|
||||||
|
|
||||||
self.assertEqual(list(self.cm.iter_single_ended_pins()), [
|
self.assertEqual(list(self.cm.iter_single_ended_pins()), [
|
||||||
|
@ -90,8 +90,8 @@ class ConstraintManagerTestCase(FHDLTestCase):
|
||||||
(i2c.sda, sda, {}),
|
(i2c.sda, sda, {}),
|
||||||
])
|
])
|
||||||
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
||||||
("i2c_0__scl_io", ["N10"], {}),
|
("i2c_0__scl__io", ["N10"], {}),
|
||||||
("i2c_0__sda_io", ["N11"], {})
|
("i2c_0__sda__io", ["N11"], {})
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_request_diffpairs(self):
|
def test_request_diffpairs(self):
|
||||||
|
@ -103,23 +103,23 @@ class ConstraintManagerTestCase(FHDLTestCase):
|
||||||
ports = list(self.cm.iter_ports())
|
ports = list(self.cm.iter_ports())
|
||||||
self.assertEqual(len(ports), 2)
|
self.assertEqual(len(ports), 2)
|
||||||
p, n = ports
|
p, n = ports
|
||||||
self.assertEqual(p.name, "clk100_0_p")
|
self.assertEqual(p.name, "clk100_0__p")
|
||||||
self.assertEqual(p.nbits, clk100.width)
|
self.assertEqual(p.nbits, clk100.width)
|
||||||
self.assertEqual(n.name, "clk100_0_n")
|
self.assertEqual(n.name, "clk100_0__n")
|
||||||
self.assertEqual(n.nbits, clk100.width)
|
self.assertEqual(n.nbits, clk100.width)
|
||||||
|
|
||||||
self.assertEqual(list(self.cm.iter_differential_pins()), [
|
self.assertEqual(list(self.cm.iter_differential_pins()), [
|
||||||
(clk100, p, n, {}),
|
(clk100, p, n, {}),
|
||||||
])
|
])
|
||||||
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
||||||
("clk100_0_p", ["H1"], {}),
|
("clk100_0__p", ["H1"], {}),
|
||||||
("clk100_0_n", ["H2"], {}),
|
("clk100_0__n", ["H2"], {}),
|
||||||
])
|
])
|
||||||
self.assertEqual(list(self.cm.iter_port_constraints(diff_pins="p")), [
|
self.assertEqual(list(self.cm.iter_port_constraints(diff_pins="p")), [
|
||||||
("clk100_0_p", ["H1"], {}),
|
("clk100_0__p", ["H1"], {}),
|
||||||
])
|
])
|
||||||
self.assertEqual(list(self.cm.iter_port_constraints(diff_pins="n")), [
|
self.assertEqual(list(self.cm.iter_port_constraints(diff_pins="n")), [
|
||||||
("clk100_0_n", ["H2"], {}),
|
("clk100_0__n", ["H2"], {}),
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_add_clock(self):
|
def test_add_clock(self):
|
||||||
|
@ -130,8 +130,8 @@ class ConstraintManagerTestCase(FHDLTestCase):
|
||||||
clk100 = self.cm.request("clk100", 0)
|
clk100 = self.cm.request("clk100", 0)
|
||||||
clk50 = self.cm.request("clk50", 0, dir="i")
|
clk50 = self.cm.request("clk50", 0, dir="i")
|
||||||
self.assertEqual(list(sorted(self.cm.iter_clock_constraints())), [
|
self.assertEqual(list(sorted(self.cm.iter_clock_constraints())), [
|
||||||
("clk100_0_p", 10e6),
|
("clk100_0__p", 10e6),
|
||||||
("clk50_0_io", 5e6)
|
("clk50_0__io", 5e6)
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_wrong_resources(self):
|
def test_wrong_resources(self):
|
||||||
|
|
35
nmigen/vendor/fpga/lattice_ice40.py
vendored
35
nmigen/vendor/fpga/lattice_ice40.py
vendored
|
@ -3,6 +3,9 @@ import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
from ...hdl.ast import *
|
||||||
|
from ...hdl.dsl import *
|
||||||
|
from ...hdl.ir import *
|
||||||
from ...build import *
|
from ...build import *
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,6 +107,38 @@ class LatticeICE40Platform(TemplatedPlatform):
|
||||||
"""
|
"""
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def _get_io_buffer(self, port, extras, fn):
|
||||||
|
m = Module()
|
||||||
|
for bit in range(len(port)):
|
||||||
|
m.submodules += Instance("SB_IO",
|
||||||
|
("io", "PACKAGE_PIN", port[bit]),
|
||||||
|
*fn(bit),
|
||||||
|
*(("p", key, value) for key, value in extras.items()))
|
||||||
|
return m
|
||||||
|
|
||||||
|
def get_input(self, pin, port, extras):
|
||||||
|
return self._get_io_buffer(port, extras, lambda bit: [
|
||||||
|
# PIN_NO_OUTPUT|PIN_INPUT
|
||||||
|
("p", "PIN_TYPE", 0b0000_01),
|
||||||
|
("o", "D_IN_0", pin.i[bit]),
|
||||||
|
])
|
||||||
|
|
||||||
|
def get_output(self, pin, port, extras):
|
||||||
|
return self._get_io_buffer(port, extras, lambda bit: [
|
||||||
|
# PIN_OUTPUT|PIN_INPUT_REGISTERED
|
||||||
|
("p", "PIN_TYPE", 0b0110_00),
|
||||||
|
("i", "D_OUT_0", pin.o[bit]),
|
||||||
|
])
|
||||||
|
|
||||||
|
def get_tristate(self, pin, port, extras):
|
||||||
|
return self._get_io_buffer(port, extras, lambda bit: [
|
||||||
|
# PIN_OUTPUT_TRISTATE|PIN_INPUT_REGISTERED
|
||||||
|
("p", "PIN_TYPE", 0b1010_00),
|
||||||
|
("o", "D_IN_0", pin.i[bit]),
|
||||||
|
("i", "D_OUT_0", pin.o[bit]),
|
||||||
|
("i", "OUTPUT_ENABLE", pin.oe),
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
class IceStormProgrammerMixin:
|
class IceStormProgrammerMixin:
|
||||||
def toolchain_program(self, products, name, *, mode=None):
|
def toolchain_program(self, products, name, *, mode=None):
|
||||||
|
|
Loading…
Reference in a new issue