Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/nmigen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: fdb99379db27
Choose a base ref
...
head repository: m-labs/nmigen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 29f7a3c6182a
Choose a head ref
  • 1 commit
  • 1 file changed
  • 1 contributor

Commits on Oct 3, 2019

  1. vendor.altera: use buffer primitives (UNTESTED)

    Ravenslofty authored and whitequark committed Oct 3, 2019
    Copy the full SHA
    29f7a3c View commit details
Showing with 317 additions and 20 deletions.
  1. +317 −20 nmigen/vendor/altera.py
337 changes: 317 additions & 20 deletions nmigen/vendor/altera.py
Original file line number Diff line number Diff line change
@@ -130,47 +130,344 @@ def _invert_if(invert, value):
else:
return value

def _add_ff(self, m, xdr, src, dest, clk, kind):
if xdr == 0:
m.d.comb += dest.eq(src)
return

m.submodules["{}_dff_{}_{}".format(pin.name, kind, bit)] += Instance("dff",
i_d=src,
i_clk=clk,
i_clrn=1,
i_prn=1,
o_q=dest
)

# Despite the altiobuf manual saying ENABLE_BUS_HOLD is optional, Quartus requires it to be specified.

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

m = Module()
m.d.comb += pin.i.eq(self._invert_if(invert, port))

ff_i = Signal(pin.width)

if pin.xdr >= 1:
pin.i.attrs["useioff"] = "1"

for bit in range(pin.width):
if pin.xdr <= 1:
clk = pin.i_clk if pin.xdr != 0 else None

self._add_ff(m, pin.xdr, self._invert_if(invert, ff_i[bit]), pin.i[bit], clk, "i")

m.submodules["{}_buf_{}".format(pin.name, bit)] = Instance("altiobuf_in",
p_NUMBER_OF_CHANNELS=1,
p_ENABLE_BUS_HOLD="FALSE",
i_datain=port[bit],
o_dataout=ff_i[bit]
)
else:
m.submodules["{}_buf_{}".format(pin.name, bit)] = Instance("altddio_in",
p_width=1,
i_datain=port[bit],
i_inclock=pin.i_clk,
o_dataout_h=self._invert_if(pin.i0[bit]),
o_dataout_l=self._invert_if(pin.i1[bit]),
)

return m

def get_output(self, pin, port, attrs, invert):
self._check_feature("single-ended output", pin, attrs,
valid_xdrs=(0,), valid_attrs=True)
valid_xdrs=(0,1,2), valid_attrs=True)

m = Module()
m.d.comb += port.eq(self._invert_if(invert, pin.o))

ff_o = Signal(pin.width)

if pin.xdr >= 1:
pin.o.attrs["useioff"] = "1"

for bit in range(pin.width):
if pin.xdr <= 1:
clk = pin.o_clk if pin.xdr != 0 else None

self._add_ff(m, pin.xdr, self._invert_if(invert, pin.o[bit]), ff_o[bit], clk, "o")

m.submodules["{}_buf_{}".format(pin.name, bit)] = Instance("altiobuf_out",
p_NUMBER_OF_CHANNELS=1,
p_ENABLE_BUS_HOLD="FALSE",
i_datain=ff_o[bit],
o_dataout=port[bit]
)
else:
m.submodules["{}_buf_{}".format(pin.name, bit)] = Instance("altddio_out",
p_width=1,
i_datain_h=self._invert_if(invert, pin.o0[bit]),
i_datain_l=self._invert_if(invert, pin.o1[bit]),
i_outclock=pin.o_clk,
o_dataout=port[bit]
)

return m

def get_tristate(self, pin, port, attrs, invert):
self._check_feature("single-ended tristate", pin, attrs,
valid_xdrs=(0,), valid_attrs=True)
valid_xdrs=(0,1,2), valid_attrs=True)

m = Module()
m.submodules += Instance("$tribuf",
p_WIDTH=pin.width,
i_EN=pin.oe,
i_A=self._invert_if(invert, pin.o),
o_Y=port,
)

ff_o = Signal(pin.width)
ff_oe = Signal(pin.width)

if pin.xdr >= 1:
pin.o.attrs["useioff"] = "1"
pin.oe.attrs["useioff"] = "1"

for bit in range(pin.width):
if pin.xdr <= 1:
clk = pin.o_clk if pin.xdr != 0 else None

self._add_ff(m, pin.xdr, self._invert_if(invert, pin.o[bit]), ff_o[bit], clk, "o")
self._add_ff(m, pin.xdr, pin.oe[bit], ff_oe[bit], clk, "oe")

m.submodules["{}_buf_{}".format(pin.name, bit)] = Instance("altiobuf_out",
p_NUMBER_OF_CHANNELS=1,
p_ENABLE_BUS_HOLD="FALSE",
p_USE_OE="TRUE",
i_datain=ff_o[bit],
i_oe=ff_oe[bit],
o_dataout=port[bit]
)
else:
m.submodules["{}_buf_{}".format(pin.name, bit)] = Instance("altddio_out",
p_width=1,
p_oe_reg="REGISTERED",
i_datain_h=self._invert_if(invert, pin.o0[bit]),
i_datain_l=self._invert_if(invert, pin.o1[bit]),
i_outclock=pin.o_clk,
i_oe=pin.oe[bit],
o_dataout=port[bit]
)

return m

def get_input_output(self, pin, port, attrs, invert):
self._check_feature("single-ended input/output", pin, attrs,
valid_xdrs=(0,), valid_attrs=True)
valid_xdrs=(0,1,2), valid_attrs=True)

m = Module()
m.submodules += Instance("$tribuf",
p_WIDTH=pin.width,
i_EN=pin.oe,
i_A=self._invert_if(invert, pin.o),
o_Y=port,
)
m.d.comb += pin.i.eq(self._invert_if(invert, port))

ff_i = Signal(pin.width)
ff_o = Signal(pin.width)
ff_oe = Signal(pin.width)

if pin.xdr >= 1:
pin.i.attrs["useioff"] = "1"
pin.o.attrs["useioff"] = "1"
pin.oe.attrs["useioff"] = "1"

for bit in range(pin.width):
if pin.xdr <= 1:
iclk = pin.i_clk if pin.xdr != 0 else None
oclk = pin.o_clk if pin.xdr != 0 else None

self._add_ff(m, pin.xdr, self._invert_if(invert, ff_i[bit]), pin.i[bit], iclk, "i")
self._add_ff(m, pin.xdr, self._invert_if(invert, pin.o[bit]), ff_o[bit], oclk, "o")
self._add_ff(m, pin.xdr, pin.oe[bit], ff_oe[bit], oclk, "oe")

m.submodules["{}_buf_{}".format(pin.name, bit)] = Instance("altiobuf_bidir",
p_NUMBER_OF_CHANNELS=1,
p_ENABLE_BUS_HOLD="FALSE",
i_datain=ff_o[bit],
i_oe=ff_oe[bit],
o_dataout=ff_i[bit],
io_dataio=port[bit]
)
else:
out_high = Signal()
out_low = Signal()

m.submodules["{}_buf_{}".format(pin.name, bit)] = Instance("altddio_bidir",
p_width=1,
p_oe_reg="REGISTERED",
i_datain_h=self._invert_if(invert, pin.o0[bit]),
i_datain_l=self._invert_if(invert, pin.o1[bit]),
i_inclock=pin.i_clk,
i_outclock=pin.o_clk,
o_dataout_h=out_high,
o_dataout_l=out_low,
io_padio=port[bit]
)

m.d.comb += pin.i0.eq(self._invert_if(invert, out_high))
m.d.comb += pin.i1.eq(self._invert_if(invert, out_low))

return m

def get_diff_input(self, pin, p_port, n_port, attrs, invert):
self._check_feature("differential input", pin, attrs,
valid_xdrs=(0,1,2), valid_attrs=True)
m = Module()

ff_i = Signal(pin.width)

if pin.xdr >= 1:
pin.i.attrs["useioff"] = "1"

for bit in range(pin.width):
m.submodules["{}_buf_{}".format(pin.name, bit)] = Instance("altiobuf_in",
p_NUMBER_OF_CHANNELS=1,
p_ENABLE_BUS_HOLD="FALSE",
p_USE_DIFFERENTIAL_MODE="TRUE",
i_datain=p_port[bit],
i_datain_b=n_port[bit],
o_dataout=ff_i[bit]
)

if pin.xdr <= 1:
clk = pin.i_clk if pin.xdr != 0 else None

self._add_ff(m, pin.xdr, self._invert_if(invert, ff_i[bit]), pin.i[bit], clk, "i")

else:
m.submodules["{}_ddr_{}".format(pin.name, bit)] = Instance("altddio_in",
p_width=1,
i_datain=self._invert_if(invert, ff_i[bit]),
i_inclock=pin.i_clk,
o_dataout_h=pin.i0[bit],
o_dataout_l=pin.i1[bit],
)

return m

def get_diff_output(self, pin, p_port, n_port, attrs, invert):
self._check_feature("differential output", pin, attrs,
valid_xdrs=(0,1,2), valid_attrs=True)
m = Module()

ff_o = Signal(pin.width)

if pin.xdr == 1:
pin.o.attrs["useioff"] = "1"

for bit in range(pin.width):
m.submodules["{}_buf_{}".format(pin.name, bit)] = Instance("altiobuf_out",
p_NUMBER_OF_CHANNELS=1,
p_ENABLE_BUS_HOLD="FALSE",
p_USE_DIFFERENTIAL_MODE="TRUE",
i_datain=ff_o[bit],
o_dataout=p_port[bit],
o_dataout_b=n_port[bit]
)

if pin.xdr <= 1:
clk = pin.o_clk if pin.xdr != 0 else None

self._add_ff(m, pin.xdr, self._invert_if(invert, pin.o[bit]), ff_o[bit], pin.o_clk, "o")
else:
m.submodules["{}_ddr_{}".format(pin.name, bit)] = Instance("altddio_out",
p_width=1,
i_datain_h=self._invert_if(invert, pin.o0[bit]),
i_datain_l=self._invert_if(invert, pin.o1[bit]),
i_outclock=pin.o_clk,
o_dataout=ff_o[bit],
)

return m

# TODO: support differential IO
def get_diff_tristate(self, pin, p_port, n_port, attrs, invert):
self._check_feature("differential tristate", pin, attrs,
valid_xdrs=(0,1,2), valid_attrs=True)
m = Module()

ff_o = Signal(pin.width)
ff_oe = Signal(pin.width)

if pin.xdr == 1:
pin.o.attrs["useioff"] = "1"
pin.oe.attrs["useioff"] = "1"

for bit in range(pin.width):
m.submodules["{}_buf_{}".format(pin.name, bit)] = Instance("altiobuf_out",
p_NUMBER_OF_CHANNELS=1,
p_ENABLE_BUS_HOLD="FALSE",
p_USE_DIFFERENTIAL_MODE="TRUE",
p_USE_OE="TRUE",
i_datain=ff_o[bit],
i_oe=ff_oe[bit],
o_dataout=p_port[bit],
o_dataout_b=n_port[bit]
)

if pin.xdr <= 1:
clk = pin.o_clk if pin.xdr != 0 else None

self._add_ff(m, pin.xdr, self._invert_if(invert, pin.o[bit]), ff_o[bit], clk, "o")
self._add_ff(m, pin.xdr, pin.oe[bit], ff_oe[bit], clk, "oe")
else:
self._add_ff(m, pin.xdr, pin.oe[bit], ff_oe[bit], clk, "oe")

m.submodules["{}_ddr_{}".format(pin.name, bit)] = Instance("altddio_out",
p_width=1,
i_datain_h=self._invert_if(invert, pin.o0[bit]),
i_datain_l=self._invert_if(invert, pin.o1[bit]),
i_outclock=pin.o_clk,
o_dataout=ff_o[bit],
)

return m

def get_diff_input_output(self, pin, p_port, n_port, attrs, invert):
self._check_feature("differential input/output", pin, attrs,
valid_xdrs=(0,1,2), valid_attrs=True)
m = Module()

ff_i = Signal(pin.width)
ff_o = Signal(pin.width)
ff_oe = Signal(pin.width)

if pin.xdr == 1:
pin.i.attrs["useioff"] = "1"
pin.o.attrs["useioff"] = "1"
pin.oe.attrs["useioff"] = "1"

for bit in range(pin.width):
m.submodules["{}_buf_{}".format(pin.name, bit)] = Instance("altiobuf_bidir",
p_NUMBER_OF_CHANNELS=1,
p_ENABLE_BUS_HOLD="FALSE",
p_USE_DIFFERENTIAL_MODE="TRUE",
i_datain=ff_o[bit],
i_oe=ff_oe[bit],
o_dataout=ff_i[bit],
io_dataio=p_port[bit],
io_dataio_b=n_port[bit]
)

if pin.xdr <= 1:
iclk = pin.i_clk if pin.xdr != 0 else None
oclk = pin.o_clk if pin.xdr != 0 else None

self._add_ff(m, pin.xdr, self._invert_if(invert, ff_i[bit]), pin.i[bit], iclk, "i")
self._add_ff(m, pin.xdr, self._invert_if(invert, pin.o[bit]), ff_o[bit], oclk, "o")
self._add_ff(m, pin.xdr, pin.oe[bit], ff_oe[bit], oclk, "oe")
else:
m.submodules["{}_ddr_i_{}".format(pin.name, bit)] = Instance("altddio_in",
p_width=1,
i_datain=self._invert_if(invert, ff_i[bit]),
i_inclock=pin.i_clk,
o_dataout_h=pin.i0[bit],
o_dataout_l=pin.i1[bit],
)

m.submodules["{}_ddr_o_{}".format(pin.name, bit)] = Instance("altddio_out",
p_width=1,
i_datain_h=self._invert_if(invert, pin.o0[bit]),
i_datain_l=self._invert_if(invert, pin.o1[bit]),
i_outclock=pin.o_clk,
o_dataout=ff_o[bit],
)

return m