self.names = names.split()
if dir not in ("i", "o", "io"):
- raise TypeError("Direction must be one of \"i\", \"o\" or \"io\", not {!r}"
+ raise TypeError("Direction must be one of \"i\", \"o\", \"oe\", or \"io\", not {!r}"
.format(dir))
self.dir = dir
add_pin_fragment(pin, self.get_input(pin, port, extras))
if pin.dir == "o":
add_pin_fragment(pin, self.get_output(pin, port, extras))
+ if pin.dir == "oe":
+ add_pin_fragment(pin, self.get_tristate(pin, port, extras))
if pin.dir == "io":
- add_pin_fragment(pin, self.get_input(pin, port, extras))
+ add_pin_fragment(pin, self.get_input_output(pin, port, extras))
for pin, p_port, n_port, extras in self.iter_differential_pins():
if pin.dir == "i":
add_pin_fragment(pin, self.get_diff_input(pin, p_port, n_port))
if pin.dir == "o":
add_pin_fragment(pin, self.get_diff_output(pin, p_port, n_port))
- if pin.dir == "io":
+ if pin.dir == "oe":
add_pin_fragment(pin, self.get_diff_tristate(pin, p_port, n_port))
+ if pin.dir == "io":
+ add_pin_fragment(pin, self.get_diff_input_output(pin, p_port, n_port))
return self.toolchain_prepare(fragment, name, **kwargs)
self._check_feature("single-ended tristate", pin, extras,
valid_xdrs=(0,), valid_extras=None)
+ m = Module()
+ m.submodules += Instance("$tribuf",
+ p_WIDTH=pin.width,
+ i_EN=pin.oe,
+ i_A=pin.o,
+ o_Y=port,
+ )
+ return m
+
+ def get_input_output(self, pin, port, extras):
+ self._check_feature("single-ended input/output", pin, extras,
+ valid_xdrs=(0,), valid_extras=None)
+
m = Module()
m.submodules += Instance("$tribuf",
p_WIDTH=pin.width,
self._check_feature("differential tristate", pin, extras,
valid_xdrs=(), valid_extras=None)
+ def get_diff_input_output(self, pin, p_port, n_port, extras):
+ self._check_feature("differential input/output", pin, extras,
+ valid_xdrs=(), valid_extras=None)
+
class TemplatedPlatform(Platform):
file_templates = abstractproperty()
dir = subsignal.io[0].dir
if xdr is None:
xdr = 0
- if dir not in ("i", "o", "io", "-"):
- raise TypeError("Direction must be one of \"i\", \"o\", \"io\", or \"-\", "
- "not {!r}"
+ if dir not in ("i", "o", "oe", "io", "-"):
+ raise TypeError("Direction must be one of \"i\", \"o\", \"oe\", \"io\", "
+ "or \"-\", not {!r}"
.format(dir))
if dir != subsignal.io[0].dir and not (subsignal.io[0].dir == "io" or dir == "-"):
raise ValueError("Direction of {!r} cannot be changed from \"{}\" to \"{}\"; "
- "direction can be changed from \"io\" to \"i\", from \"io\""
- "to \"o\", or from anything to \"-\""
+ "direction can be changed from \"io\" to \"i\", \"o\", or "
+ "\"oe\", or from anything to \"-\""
.format(subsignal.io[0], subsignal.io[0].dir, dir))
if not isinstance(xdr, int) or xdr < 0:
raise ValueError("Data rate of {!r} must be a non-negative integer, not {!r}"
def test_wrong_dir(self):
with self.assertRaises(TypeError,
- msg="Direction must be one of \"i\", \"o\" or \"io\", not 'wrong'"):
+ msg="Direction must be one of \"i\", \"o\", \"oe\", or \"io\", not 'wrong'"):
p = Pins("A0 A1", dir="wrong")
def test_wrong_request_with_dir(self):
with self.assertRaises(TypeError,
- msg="Direction must be one of \"i\", \"o\", \"io\", or \"-\", not 'wrong'"):
+ msg="Direction must be one of \"i\", \"o\", \"oe\", \"io\", or \"-\", "
+ "not 'wrong'"):
user_led = self.cm.request("user_led", 0, dir="wrong")
def test_wrong_request_with_dir_io(self):
with self.assertRaises(ValueError,
msg="Direction of (pins o A0) cannot be changed from \"o\" to \"i\"; direction "
- "can be changed from \"io\" to \"i\", from \"io\"to \"o\", or from anything "
+ "can be changed from \"io\" to \"i\", \"o\", or \"oe\", or from anything "
"to \"-\""):
user_led = self.cm.request("user_led", 0, dir="i")
from ...build import *
-__all__ = ["LatticeICE40Platform", "IceStormProgrammerMixin", "IceBurnProgrammerMixin", "TinyProgrammerMixin"]
+__all__ = ["LatticeICE40Platform",
+ "IceStormProgrammerMixin", "IceBurnProgrammerMixin", "TinyProgrammerMixin"]
class LatticeICE40Platform(TemplatedPlatform):
return self._get_io_buffer(port, extras, lambda bit: [
# PIN_OUTPUT_TRISTATE|PIN_INPUT_REGISTERED
("p", "PIN_TYPE", 0b1010_00),
+ ("i", "D_OUT_0", pin.o[bit]),
+ ("i", "OUTPUT_ENABLE", pin.oe),
+ ])
+
+ def get_input_output(self, pin, port, extras):
+ self._check_feature("single-ended input/output", pin, extras,
+ valid_xdrs=(0,), valid_extras=True)
+ return self._get_io_buffer(port, extras, lambda bit: [
+ # PIN_OUTPUT_TRISTATE|PIN_INPUT
+ ("p", "PIN_TYPE", 0b1010_01),
("o", "D_IN_0", pin.i[bit]),
("i", "D_OUT_0", pin.o[bit]),
("i", "OUTPUT_ENABLE", pin.oe),