Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 20 additions & 16 deletions chipflow_lib/platforms/silicon.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,34 @@


class SiliconPlatformPort(io.PortLike):
def __init__(self, name, direction, width, *, invert=False):
def __init__(self, name, pad_type, width, *, invert=False):
if not isinstance(name, str):
raise TypeError(f"Name must be a string, not {name!r}")
if not (isinstance(width, int) and width >= 0):
raise TypeError(f"Width must be a non-negative integer, not {width!r}")
if not isinstance(invert, bool):
raise TypeError(f"'invert' must be a bool, not {invert!r}")

self._direction = io.Direction(direction)
# `clk` is used for clock tree synthesis, but treated as `i` in frontend
if pad_type in ("i", "clk"):
direction = io.Direction.Input
elif pad_type in ("o", "oe"):
direction = io.Direction.Output
elif pad_type == "io":
direction = io.Direction.Bidir
else:
assert False

self._direction = direction
self._invert = invert

self._i = self._o = self._oe = None
if self._direction in (io.Direction.Input, io.Direction.Bidir):
self._i = Signal(width, name=f"{name}__i")
if self._direction in (io.Direction.Output, io.Direction.Bidir):
self._o = Signal(width, name=f"{name}__o")
self._oe = Signal(width, name=f"{name}__oe")
if pad_type != "o":
self._oe = Signal(width, name=f"{name}__oe")

@property
def i(self):
Expand All @@ -52,7 +63,7 @@ def o(self):
@property
def oe(self):
if self._oe is None:
raise AttributeError("SiliconPlatformPort with input direction does not have an "
raise AttributeError("SiliconPlatformPort does not have an "
"output enable signal")
return self._oe

Expand Down Expand Up @@ -129,7 +140,8 @@ def elaborate(self, platform):
m.d.comb += i_inv.eq(self.port.i)
if self.direction in (io.Direction.Output, io.Direction.Bidir):
m.d.comb += self.port.o.eq(o_inv)
m.d.comb += self.port.oe.eq(self.oe)
if self.port._oe is not None:
m.d.comb += self.port.oe.eq(self.oe)

return m

Expand Down Expand Up @@ -174,17 +186,8 @@ def request(self, name):
raise NameError(f"Pad `{name}` has already been requested")

pad_type = self._pads[name]["type"]
# `clk` is used for clock tree synthesis, but treated as `i` in frontend
if pad_type in ("i", "clk"):
direction = io.Direction.Input
elif pad_type in ("o", "oe"):
direction = io.Direction.Output
elif pad_type == "io":
direction = io.Direction.Bidir
else:
assert False

self._ports[name] = port = SiliconPlatformPort(name, direction, 1)
self._ports[name] = port = SiliconPlatformPort(name, pad_type, 1)
return port

def get_io_buffer(self, buffer):
Expand Down Expand Up @@ -235,7 +238,8 @@ def _prepare(self, elaboratable, name="top"):
ports.append((f"io${port_name}$i", port.i, PortDirection.Input))
if port.direction in (io.Direction.Output, io.Direction.Bidir):
ports.append((f"io${port_name}$o", port.o, PortDirection.Output))
ports.append((f"io${port_name}$oe", port.oe, PortDirection.Output))
if port._oe is not None:
ports.append((f"io${port_name}$oe", port.oe, PortDirection.Output))

# Prepare design for RTLIL conversion.
return fragment.prepare(ports)
Expand Down