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]
|
||||
pin = Pin(len(phys), dir, xdr, name=name)
|
||||
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):
|
||||
port = (Signal(pin.width, name="{}_p".format(pin.name)),
|
||||
Signal(pin.width, name="{}_n".format(pin.name)))
|
||||
port = (Signal(pin.width, name="{}__p".format(pin.name)),
|
||||
Signal(pin.width, name="{}__n".format(pin.name)))
|
||||
self._ports.append((subsignal, pin, port))
|
||||
return pin
|
||||
else:
|
||||
|
@ -173,9 +173,9 @@ class ConstraintManager:
|
|||
"it has been requested as a tristate buffer"
|
||||
.format(name, number))
|
||||
if isinstance(resource.io[0], Pins):
|
||||
port_name = "{}_io".format(pin.name)
|
||||
port_name = "{}__io".format(pin.name)
|
||||
elif isinstance(resource.io[0], DiffPairs):
|
||||
port_name = "{}_p".format(pin.name)
|
||||
port_name = "{}__p".format(pin.name)
|
||||
else:
|
||||
assert False
|
||||
yield (port_name, period)
|
||||
|
|
|
@ -66,7 +66,7 @@ class ConstraintManagerTestCase(FHDLTestCase):
|
|||
self.assertEqual(len(ports), 1)
|
||||
|
||||
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
||||
("user_led_0_io", ["A0"], {})
|
||||
("user_led_0__io", ["A0"], {})
|
||||
])
|
||||
|
||||
def test_request_with_dir(self):
|
||||
|
@ -82,7 +82,7 @@ class ConstraintManagerTestCase(FHDLTestCase):
|
|||
ports = list(self.cm.iter_ports())
|
||||
self.assertEqual(len(ports), 2)
|
||||
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(list(self.cm.iter_single_ended_pins()), [
|
||||
|
@ -90,8 +90,8 @@ class ConstraintManagerTestCase(FHDLTestCase):
|
|||
(i2c.sda, sda, {}),
|
||||
])
|
||||
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
||||
("i2c_0__scl_io", ["N10"], {}),
|
||||
("i2c_0__sda_io", ["N11"], {})
|
||||
("i2c_0__scl__io", ["N10"], {}),
|
||||
("i2c_0__sda__io", ["N11"], {})
|
||||
])
|
||||
|
||||
def test_request_diffpairs(self):
|
||||
|
@ -103,23 +103,23 @@ class ConstraintManagerTestCase(FHDLTestCase):
|
|||
ports = list(self.cm.iter_ports())
|
||||
self.assertEqual(len(ports), 2)
|
||||
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(n.name, "clk100_0_n")
|
||||
self.assertEqual(n.name, "clk100_0__n")
|
||||
self.assertEqual(n.nbits, clk100.width)
|
||||
|
||||
self.assertEqual(list(self.cm.iter_differential_pins()), [
|
||||
(clk100, p, n, {}),
|
||||
])
|
||||
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
||||
("clk100_0_p", ["H1"], {}),
|
||||
("clk100_0_n", ["H2"], {}),
|
||||
("clk100_0__p", ["H1"], {}),
|
||||
("clk100_0__n", ["H2"], {}),
|
||||
])
|
||||
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")), [
|
||||
("clk100_0_n", ["H2"], {}),
|
||||
("clk100_0__n", ["H2"], {}),
|
||||
])
|
||||
|
||||
def test_add_clock(self):
|
||||
|
@ -130,8 +130,8 @@ class ConstraintManagerTestCase(FHDLTestCase):
|
|||
clk100 = self.cm.request("clk100", 0)
|
||||
clk50 = self.cm.request("clk50", 0, dir="i")
|
||||
self.assertEqual(list(sorted(self.cm.iter_clock_constraints())), [
|
||||
("clk100_0_p", 10e6),
|
||||
("clk50_0_io", 5e6)
|
||||
("clk100_0__p", 10e6),
|
||||
("clk50_0__io", 5e6)
|
||||
])
|
||||
|
||||
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 tempfile
|
||||
|
||||
from ...hdl.ast import *
|
||||
from ...hdl.dsl import *
|
||||
from ...hdl.ir 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:
|
||||
def toolchain_program(self, products, name, *, mode=None):
|
||||
|
|
Loading…
Reference in a new issue