Skip to content

Commit 99948cd

Browse files
committed
build.plat: use lib.io.*Buffer in default platform.
1 parent d94c979 commit 99948cd

File tree

2 files changed

+85
-46
lines changed

2 files changed

+85
-46
lines changed

amaranth/build/plat.py

Lines changed: 67 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from ..hdl._ir import IOBufferInstance, Design
1313
from ..hdl._xfrm import DomainLowerer
1414
from ..lib.cdc import ResetSynchronizer
15+
from ..lib import io
1516
from ..back import rtlil, verilog
1617
from .res import *
1718
from .run import *
@@ -162,8 +163,7 @@ def add_pin_fragment(pin, pin_fragment):
162163
if pin.dir == "io":
163164
add_pin_fragment(pin, self.get_diff_input_output(pin, port, attrs, invert))
164165

165-
ports = [(None, signal, None) for signal in self.iter_ports()]
166-
fragment = Design(fragment, ports, hierarchy=(name,))
166+
fragment = Design(fragment, [], hierarchy=(name,))
167167
return self.toolchain_prepare(fragment, name, **kwargs)
168168

169169
@abstractmethod
@@ -201,63 +201,87 @@ def _invert_if(invert, value):
201201
return value
202202

203203
def get_input(self, pin, port, attrs, invert):
204-
self._check_feature("single-ended input", pin, attrs,
205-
valid_xdrs=(0,), valid_attrs=None)
204+
self._check_feature("input", pin, attrs,
205+
valid_xdrs=(0, 1, 2), valid_attrs=True)
206206

207207
m = Module()
208-
m.d.comb += pin.i.eq(self._invert_if(invert, port))
208+
if pin.xdr == 0:
209+
m.submodules.buf = buf = io.Buffer(io.Direction.Input, port)
210+
m.d.comb += pin.i.eq(buf.i)
211+
elif pin.xdr == 1:
212+
m.domains.input = cd_input = ClockDomain(reset_less=True)
213+
m.submodules.buf = buf = io.FFBuffer(io.Direction.Input, port, i_domain="input")
214+
m.d.comb += pin.i.eq(buf.i)
215+
m.d.comb += cd_input.clk.eq(pin.i_clk)
216+
elif pin.xdr == 2:
217+
m.domains.input = cd_input = ClockDomain(reset_less=True)
218+
m.submodules.buf = buf = io.DDRBuffer(io.Direction.Input, port, i_domain="input")
219+
m.d.comb += pin.i0.eq(buf.i[0])
220+
m.d.comb += pin.i1.eq(buf.i[1])
221+
m.d.comb += cd_input.clk.eq(pin.i_clk)
209222
return m
210223

211224
def get_output(self, pin, port, attrs, invert):
212-
self._check_feature("single-ended output", pin, attrs,
213-
valid_xdrs=(0,), valid_attrs=None)
225+
self._check_feature("output", pin, attrs,
226+
valid_xdrs=(0, 1, 2), valid_attrs=True)
214227

215228
m = Module()
216-
m.d.comb += port.eq(self._invert_if(invert, pin.o))
229+
if pin.xdr == 0:
230+
m.submodules.buf = buf = io.Buffer(io.Direction.Output, port)
231+
m.d.comb += buf.o.eq(pin.o)
232+
elif pin.xdr == 1:
233+
m.domains.output = cd_output = ClockDomain(reset_less=True)
234+
m.submodules.buf = buf = io.FFBuffer(io.Direction.Output, port, o_domain="output")
235+
m.d.comb += buf.o.eq(pin.o)
236+
m.d.comb += cd_output.clk.eq(pin.o_clk)
237+
elif pin.xdr == 2:
238+
m.domains.output = cd_output = ClockDomain(reset_less=True)
239+
m.submodules.buf = buf = io.DDRBuffer(io.Direction.Output, port, o_domain="output")
240+
m.d.comb += buf.o[0].eq(pin.o0)
241+
m.d.comb += buf.o[1].eq(pin.o1)
242+
m.d.comb += cd_output.clk.eq(pin.o_clk)
243+
if pin.dir == "oe":
244+
m.d.comb += buf.oe.eq(pin.oe)
217245
return m
218246

219-
def get_tristate(self, pin, port, attrs, invert):
220-
self._check_feature("single-ended tristate", pin, attrs,
221-
valid_xdrs=(0,), valid_attrs=None)
222-
223-
m = Module()
224-
m.submodules += IOBufferInstance(
225-
port=port,
226-
o=self._invert_if(invert, pin.o),
227-
oe=pin.oe,
228-
)
229-
return m
247+
get_tristate = get_output
230248

231249
def get_input_output(self, pin, port, attrs, invert):
232250
self._check_feature("single-ended input/output", pin, attrs,
233-
valid_xdrs=(0,), valid_attrs=None)
251+
valid_xdrs=(0, 1, 2), valid_attrs=True)
234252

235253
m = Module()
236-
i = Signal.like(pin.i)
237-
m.submodules += IOBufferInstance(
238-
port=port,
239-
i=i,
240-
o=self._invert_if(invert, pin.o),
241-
oe=pin.oe,
242-
)
243-
m.d.comb += pin.i.eq(self._invert_if(invert, i))
254+
if pin.xdr == 0:
255+
m.submodules.buf = buf = io.Buffer(io.Direction.Bidir, port)
256+
m.d.comb += pin.i.eq(buf.i)
257+
m.d.comb += buf.o.eq(pin.o)
258+
m.d.comb += buf.oe.eq(pin.oe)
259+
elif pin.xdr == 1:
260+
m.domains.input = cd_input = ClockDomain(reset_less=True)
261+
m.domains.output = cd_output = ClockDomain(reset_less=True)
262+
m.submodules.buf = buf = io.FFBuffer(io.Direction.Bidir, port, i_domain="input", o_domain="output")
263+
m.d.comb += pin.i.eq(buf.i)
264+
m.d.comb += buf.o.eq(pin.o)
265+
m.d.comb += buf.oe.eq(pin.oe)
266+
m.d.comb += cd_input.clk.eq(pin.i_clk)
267+
m.d.comb += cd_output.clk.eq(pin.o_clk)
268+
elif pin.xdr == 2:
269+
m.domains.input = cd_input = ClockDomain(reset_less=True)
270+
m.domains.output = cd_output = ClockDomain(reset_less=True)
271+
m.submodules.buf = buf = io.DDRBuffer(io.Direction.Bidir, port, i_domain="input", o_domain="output")
272+
m.d.comb += pin.i0.eq(buf.i[0])
273+
m.d.comb += pin.i1.eq(buf.i[1])
274+
m.d.comb += buf.o[0].eq(pin.o0)
275+
m.d.comb += buf.o[1].eq(pin.o1)
276+
m.d.comb += buf.oe.eq(pin.oe)
277+
m.d.comb += cd_input.clk.eq(pin.i_clk)
278+
m.d.comb += cd_output.clk.eq(pin.o_clk)
244279
return m
245280

246-
def get_diff_input(self, pin, port, attrs, invert):
247-
self._check_feature("differential input", pin, attrs,
248-
valid_xdrs=(), valid_attrs=None)
249-
250-
def get_diff_output(self, pin, port, attrs, invert):
251-
self._check_feature("differential output", pin, attrs,
252-
valid_xdrs=(), valid_attrs=None)
253-
254-
def get_diff_tristate(self, pin, port, attrs, invert):
255-
self._check_feature("differential tristate", pin, attrs,
256-
valid_xdrs=(), valid_attrs=None)
257-
258-
def get_diff_input_output(self, pin, port, attrs, invert):
259-
self._check_feature("differential input/output", pin, attrs,
260-
valid_xdrs=(), valid_attrs=None)
281+
get_diff_input = get_input
282+
get_diff_output = get_output
283+
get_diff_tristate = get_tristate
284+
get_diff_input_output = get_input_output
261285

262286

263287
class TemplatedPlatform(Platform):

amaranth/build/res.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ class PortGroup:
1818
pass
1919

2020

21+
class PortMetadata:
22+
def __init__(self, name, attrs):
23+
self.name = name
24+
self.attrs = attrs
25+
26+
2127
class ResourceManager:
2228
def __init__(self, resources, connectors):
2329
self.resources = OrderedDict()
@@ -133,12 +139,21 @@ def resolve(resource, dir, xdr, path, attrs):
133139
direction = phys.dir
134140
if isinstance(phys, Pins):
135141
phys_names = phys.names
136-
io = IOPort(len(phys), name="__".join(path) + "__io")
142+
io = IOPort(len(phys), name="__".join(path) + "__io", metadata=[
143+
PortMetadata(name, attrs)
144+
for name in phys.names
145+
])
137146
port = SingleEndedPort(io, invert=phys.invert, direction=direction)
138147
if isinstance(phys, DiffPairs):
139148
phys_names = []
140-
p = IOPort(len(phys), name="__".join(path) + "__p")
141-
n = IOPort(len(phys), name="__".join(path) + "__n")
149+
p = IOPort(len(phys), name="__".join(path) + "__p", metadata=[
150+
PortMetadata(name, attrs)
151+
for name in phys.p.names
152+
])
153+
n = IOPort(len(phys), name="__".join(path) + "__n", metadata=[
154+
PortMetadata(name, attrs)
155+
for name in phys.n.names
156+
])
142157
if not self.should_skip_port_component(None, attrs, "p"):
143158
phys_names += phys.p.names
144159
if not self.should_skip_port_component(None, attrs, "n"):

0 commit comments

Comments
 (0)