|
12 | 12 | from ..hdl._ir import IOBufferInstance, Design
|
13 | 13 | from ..hdl._xfrm import DomainLowerer
|
14 | 14 | from ..lib.cdc import ResetSynchronizer
|
| 15 | +from ..lib import io |
15 | 16 | from ..back import rtlil, verilog
|
16 | 17 | from .res import *
|
17 | 18 | from .run import *
|
@@ -162,8 +163,7 @@ def add_pin_fragment(pin, pin_fragment):
|
162 | 163 | if pin.dir == "io":
|
163 | 164 | add_pin_fragment(pin, self.get_diff_input_output(pin, port, attrs, invert))
|
164 | 165 |
|
165 |
| - ports = [(None, signal, None) for signal in self.iter_ports()] |
166 |
| - fragment = Design(fragment, ports, hierarchy=(name,)) |
| 166 | + fragment = Design(fragment, [], hierarchy=(name,)) |
167 | 167 | return self.toolchain_prepare(fragment, name, **kwargs)
|
168 | 168 |
|
169 | 169 | @abstractmethod
|
@@ -201,63 +201,87 @@ def _invert_if(invert, value):
|
201 | 201 | return value
|
202 | 202 |
|
203 | 203 | 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) |
206 | 206 |
|
207 | 207 | 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) |
209 | 222 | return m
|
210 | 223 |
|
211 | 224 | 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) |
214 | 227 |
|
215 | 228 | 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) |
217 | 245 | return m
|
218 | 246 |
|
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 |
230 | 248 |
|
231 | 249 | def get_input_output(self, pin, port, attrs, invert):
|
232 | 250 | 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) |
234 | 252 |
|
235 | 253 | 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) |
244 | 279 | return m
|
245 | 280 |
|
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 |
261 | 285 |
|
262 | 286 |
|
263 | 287 | class TemplatedPlatform(Platform):
|
|
0 commit comments