build.dsl: require a dict for extras instead of a stringly array.
Fixes #72.
This commit is contained in:
parent
e4ebe03115
commit
98497b2075
|
@ -47,7 +47,7 @@ class DiffPairs:
|
||||||
|
|
||||||
|
|
||||||
class Subsignal:
|
class Subsignal:
|
||||||
def __init__(self, name, *io, extras=()):
|
def __init__(self, name, *io, extras=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
if not io:
|
if not io:
|
||||||
|
@ -67,25 +67,35 @@ class Subsignal:
|
||||||
raise TypeError("A Subsignal can only be followed by more Subsignals, but "
|
raise TypeError("A Subsignal can only be followed by more Subsignals, but "
|
||||||
"{!r} is followed by {!r}"
|
"{!r} is followed by {!r}"
|
||||||
.format(io[0], c))
|
.format(io[0], c))
|
||||||
self.io = io
|
self.io = io
|
||||||
|
self.extras = {}
|
||||||
|
|
||||||
for c in extras:
|
if extras is not None:
|
||||||
if not isinstance(c, str):
|
if not isinstance(extras, dict):
|
||||||
raise TypeError("Extra constraint must be a string, not {!r}".format(c))
|
raise TypeError("Extra constraints must be a dict, not {!r}"
|
||||||
self.extras = list(extras)
|
.format(extras))
|
||||||
|
for extra_key, extra_value in extras.items():
|
||||||
|
if not isinstance(extra_key, str):
|
||||||
|
raise TypeError("Extra constraint key must be a string, not {!r}"
|
||||||
|
.format(extra_key))
|
||||||
|
if not isinstance(extra_value, str):
|
||||||
|
raise TypeError("Extra constraint value must be a string, not {!r}"
|
||||||
|
.format(extra_value))
|
||||||
|
self.extras[extra_key] = extra_value
|
||||||
|
|
||||||
if isinstance(self.io[0], Subsignal):
|
if isinstance(self.io[0], Subsignal):
|
||||||
for sub in self.io:
|
for sub in self.io:
|
||||||
sub.extras += self.extras
|
sub.extras.update(self.extras)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "(subsignal {} {} {})".format(self.name,
|
return "(subsignal {} {} {})".format(self.name,
|
||||||
" ".join(map(repr, self.io)),
|
" ".join(map(repr, self.io)),
|
||||||
" ".join(self.extras))
|
" ".join("{}={}".format(k, v)
|
||||||
|
for k, v in self.extras.items()))
|
||||||
|
|
||||||
|
|
||||||
class Resource(Subsignal):
|
class Resource(Subsignal):
|
||||||
def __init__(self, name, number, *io, extras=()):
|
def __init__(self, name, number, *io, extras=None):
|
||||||
super().__init__(name, *io, extras=extras)
|
super().__init__(name, *io, extras=extras)
|
||||||
|
|
||||||
self.number = number
|
self.number = number
|
||||||
|
@ -93,4 +103,5 @@ class Resource(Subsignal):
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "(resource {} {} {} {})".format(self.name, self.number,
|
return "(resource {} {} {} {})".format(self.name, self.number,
|
||||||
" ".join(map(repr, self.io)),
|
" ".join(map(repr, self.io)),
|
||||||
" ".join(self.extras))
|
" ".join("{}={}".format(k, v)
|
||||||
|
for k, v in self.extras.items()))
|
||||||
|
|
|
@ -45,7 +45,7 @@ class DiffPairsTestCase(FHDLTestCase):
|
||||||
|
|
||||||
class SubsignalTestCase(FHDLTestCase):
|
class SubsignalTestCase(FHDLTestCase):
|
||||||
def test_basic_pins(self):
|
def test_basic_pins(self):
|
||||||
s = Subsignal("a", Pins("A0"), extras=["IOSTANDARD=LVCMOS33"])
|
s = Subsignal("a", Pins("A0"), extras={"IOSTANDARD": "LVCMOS33"})
|
||||||
self.assertEqual(repr(s), "(subsignal a (pins io A0) IOSTANDARD=LVCMOS33)")
|
self.assertEqual(repr(s), "(subsignal a (pins io A0) IOSTANDARD=LVCMOS33)")
|
||||||
|
|
||||||
def test_basic_diffpairs(self):
|
def test_basic_diffpairs(self):
|
||||||
|
@ -62,11 +62,11 @@ class SubsignalTestCase(FHDLTestCase):
|
||||||
def test_extras(self):
|
def test_extras(self):
|
||||||
s = Subsignal("a",
|
s = Subsignal("a",
|
||||||
Subsignal("b", Pins("A0")),
|
Subsignal("b", Pins("A0")),
|
||||||
Subsignal("c", Pins("A0"), extras=["SLEW=FAST"]),
|
Subsignal("c", Pins("A0"), extras={"SLEW": "FAST"}),
|
||||||
extras=["IOSTANDARD=LVCMOS33"])
|
extras={"IOSTANDARD": "LVCMOS33"})
|
||||||
self.assertEqual(s.extras, ["IOSTANDARD=LVCMOS33"])
|
self.assertEqual(s.extras, {"IOSTANDARD": "LVCMOS33"})
|
||||||
self.assertEqual(s.io[0].extras, ["IOSTANDARD=LVCMOS33"])
|
self.assertEqual(s.io[0].extras, {"IOSTANDARD": "LVCMOS33"})
|
||||||
self.assertEqual(s.io[1].extras, ["SLEW=FAST", "IOSTANDARD=LVCMOS33"])
|
self.assertEqual(s.io[1].extras, {"SLEW": "FAST", "IOSTANDARD": "LVCMOS33"})
|
||||||
|
|
||||||
def test_empty_io(self):
|
def test_empty_io(self):
|
||||||
with self.assertRaises(TypeError, msg="Missing I/O constraints"):
|
with self.assertRaises(TypeError, msg="Missing I/O constraints"):
|
||||||
|
@ -98,8 +98,14 @@ class SubsignalTestCase(FHDLTestCase):
|
||||||
|
|
||||||
def test_wrong_extras(self):
|
def test_wrong_extras(self):
|
||||||
with self.assertRaises(TypeError,
|
with self.assertRaises(TypeError,
|
||||||
msg="Extra constraint must be a string, not (pins io B0)"):
|
msg="Extra constraints must be a dict, not [(pins io B0)]"):
|
||||||
s = Subsignal("a", Pins("A0"), extras=[Pins("B0")])
|
s = Subsignal("a", Pins("A0"), extras=[Pins("B0")])
|
||||||
|
with self.assertRaises(TypeError,
|
||||||
|
msg="Extra constraint key must be a string, not 1"):
|
||||||
|
s = Subsignal("a", Pins("A0"), extras={1: 2})
|
||||||
|
with self.assertRaises(TypeError,
|
||||||
|
msg="Extra constraint value must be a string, not 2"):
|
||||||
|
s = Subsignal("a", Pins("A0"), extras={"1": 2})
|
||||||
|
|
||||||
|
|
||||||
class ResourceTestCase(FHDLTestCase):
|
class ResourceTestCase(FHDLTestCase):
|
||||||
|
@ -107,7 +113,7 @@ class ResourceTestCase(FHDLTestCase):
|
||||||
r = Resource("serial", 0,
|
r = Resource("serial", 0,
|
||||||
Subsignal("tx", Pins("A0", dir="o")),
|
Subsignal("tx", Pins("A0", dir="o")),
|
||||||
Subsignal("rx", Pins("A1", dir="i")),
|
Subsignal("rx", Pins("A1", dir="i")),
|
||||||
extras=["IOSTANDARD=LVCMOS33"])
|
extras={"IOSTANDARD": "LVCMOS33"})
|
||||||
self.assertEqual(repr(r), "(resource serial 0"
|
self.assertEqual(repr(r), "(resource serial 0"
|
||||||
" (subsignal tx (pins o A0) IOSTANDARD=LVCMOS33)"
|
" (subsignal tx (pins o A0) IOSTANDARD=LVCMOS33)"
|
||||||
" (subsignal rx (pins i A1) IOSTANDARD=LVCMOS33)"
|
" (subsignal rx (pins i A1) IOSTANDARD=LVCMOS33)"
|
||||||
|
|
|
@ -66,7 +66,7 @@ class ConstraintManagerTestCase(FHDLTestCase):
|
||||||
self.assertEqual(len(ports), 1)
|
self.assertEqual(len(ports), 1)
|
||||||
|
|
||||||
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
||||||
("user_led_0_io", ["A0"], [])
|
("user_led_0_io", ["A0"], {})
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_request_with_dir(self):
|
def test_request_with_dir(self):
|
||||||
|
@ -90,8 +90,8 @@ class ConstraintManagerTestCase(FHDLTestCase):
|
||||||
(i2c.sda, sda),
|
(i2c.sda, sda),
|
||||||
])
|
])
|
||||||
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
||||||
("i2c_0__scl_io", ["N10"], []),
|
("i2c_0__scl_io", ["N10"], {}),
|
||||||
("i2c_0__sda_io", ["N11"], [])
|
("i2c_0__sda_io", ["N11"], {})
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_request_diffpairs(self):
|
def test_request_diffpairs(self):
|
||||||
|
@ -112,8 +112,8 @@ class ConstraintManagerTestCase(FHDLTestCase):
|
||||||
(clk100, p, n),
|
(clk100, p, n),
|
||||||
])
|
])
|
||||||
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
self.assertEqual(list(self.cm.iter_port_constraints()), [
|
||||||
("clk100_0_p", ["H1"], []),
|
("clk100_0_p", ["H1"], {}),
|
||||||
("clk100_0_n", ["H2"], [])
|
("clk100_0_n", ["H2"], {})
|
||||||
])
|
])
|
||||||
|
|
||||||
def test_add_clock(self):
|
def test_add_clock(self):
|
||||||
|
|
18
nmigen/vendor/ice40_hx1k_blink_evn.py
vendored
18
nmigen/vendor/ice40_hx1k_blink_evn.py
vendored
|
@ -12,15 +12,15 @@ class ICE40HX1KBlinkEVNPlatform(IceBurnProgrammerMixin, LatticeICE40Platform):
|
||||||
("clk3p3", 3.3e6),
|
("clk3p3", 3.3e6),
|
||||||
]
|
]
|
||||||
resources = [
|
resources = [
|
||||||
Resource("clk3p3", 0, Pins("13", dir="i"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("clk3p3", 0, Pins("13", dir="i"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
|
|
||||||
Resource("user_led", 0, Pins("59", dir="o"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("user_led", 0, Pins("59", dir="o"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
Resource("user_led", 1, Pins("56", dir="o"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("user_led", 1, Pins("56", dir="o"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
Resource("user_led", 2, Pins("53", dir="o"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("user_led", 2, Pins("53", dir="o"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
Resource("user_led", 3, Pins("51", dir="o"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("user_led", 3, Pins("51", dir="o"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
|
|
||||||
Resource("user_btn", 0, Pins("60"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("user_btn", 0, Pins("60"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
Resource("user_btn", 1, Pins("57"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("user_btn", 1, Pins("57"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
Resource("user_btn", 2, Pins("54"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("user_btn", 2, Pins("54"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
Resource("user_btn", 3, Pins("52"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("user_btn", 3, Pins("52"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
]
|
]
|
||||||
|
|
18
nmigen/vendor/icestick.py
vendored
18
nmigen/vendor/icestick.py
vendored
|
@ -12,13 +12,13 @@ class ICEStickPlatform(IceStormProgrammerMixin, LatticeICE40Platform):
|
||||||
("clk12", 12e6),
|
("clk12", 12e6),
|
||||||
]
|
]
|
||||||
resources = [
|
resources = [
|
||||||
Resource("clk12", 0, Pins("21", dir="i"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("clk12", 0, Pins("21", dir="i"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
|
|
||||||
Resource("user_led", 0, Pins("99", dir="o"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("user_led", 0, Pins("99", dir="o"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
Resource("user_led", 1, Pins("98", dir="o"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("user_led", 1, Pins("98", dir="o"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
Resource("user_led", 2, Pins("97", dir="o"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("user_led", 2, Pins("97", dir="o"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
Resource("user_led", 3, Pins("96", dir="o"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("user_led", 3, Pins("96", dir="o"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
Resource("user_led", 4, Pins("95", dir="o"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("user_led", 4, Pins("95", dir="o"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
|
|
||||||
Resource("serial", 0,
|
Resource("serial", 0,
|
||||||
Subsignal("rx", Pins("9", dir="i")),
|
Subsignal("rx", Pins("9", dir="i")),
|
||||||
|
@ -28,14 +28,14 @@ class ICEStickPlatform(IceStormProgrammerMixin, LatticeICE40Platform):
|
||||||
Subsignal("dtr", Pins("3", dir="o")),
|
Subsignal("dtr", Pins("3", dir="o")),
|
||||||
Subsignal("dsr", Pins("2", dir="i")),
|
Subsignal("dsr", Pins("2", dir="i")),
|
||||||
Subsignal("dcd", Pins("1", dir="i")),
|
Subsignal("dcd", Pins("1", dir="i")),
|
||||||
extras=["IO_STANDARD=SB_LVTTL", "PULLUP=1"],
|
extras={"IO_STANDARD": "SB_LVTTL", "PULLUP": "1"}
|
||||||
),
|
),
|
||||||
|
|
||||||
Resource("irda", 0,
|
Resource("irda", 0,
|
||||||
Subsignal("rx", Pins("106", dir="i")),
|
Subsignal("rx", Pins("106", dir="i")),
|
||||||
Subsignal("tx", Pins("105", dir="o")),
|
Subsignal("tx", Pins("105", dir="o")),
|
||||||
Subsignal("sd", Pins("107", dir="o")),
|
Subsignal("sd", Pins("107", dir="o")),
|
||||||
extras=["IO_STANDARD=SB_LVCMOS33"]
|
extras={"IO_STANDARD": "SB_LVCMOS33"}
|
||||||
),
|
),
|
||||||
|
|
||||||
Resource("spiflash", 0,
|
Resource("spiflash", 0,
|
||||||
|
@ -43,7 +43,7 @@ class ICEStickPlatform(IceStormProgrammerMixin, LatticeICE40Platform):
|
||||||
Subsignal("clk", Pins("70", dir="o")),
|
Subsignal("clk", Pins("70", dir="o")),
|
||||||
Subsignal("mosi", Pins("67", dir="io")),
|
Subsignal("mosi", Pins("67", dir="io")),
|
||||||
Subsignal("miso", Pins("68", dir="io")),
|
Subsignal("miso", Pins("68", dir="io")),
|
||||||
extras=["IO_STANDARD=SB_LVCMOS33"]
|
extras={"IO_STANDARD": "SB_LVCMOS33"}
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
prog_mode = "flash"
|
prog_mode = "flash"
|
||||||
|
|
12
nmigen/vendor/tinyfpga_bx.py
vendored
12
nmigen/vendor/tinyfpga_bx.py
vendored
|
@ -12,15 +12,15 @@ class TinyFPGABXPlatform(TinyProgrammerMixin, LatticeICE40Platform):
|
||||||
("clk16", 16e6),
|
("clk16", 16e6),
|
||||||
]
|
]
|
||||||
resources = [
|
resources = [
|
||||||
Resource("clk16", 0, Pins("B2", dir="i"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("clk16", 0, Pins("B2", dir="i"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
|
|
||||||
Resource("user_led", 0, Pins("B3", dir="o"), extras=["IO_STANDARD=SB_LVCMOS33"]),
|
Resource("user_led", 0, Pins("B3", dir="o"), extras={"IO_STANDARD": "SB_LVCMOS33"}),
|
||||||
|
|
||||||
Resource("usb", 0,
|
Resource("usb", 0,
|
||||||
Subsignal("d_p", Pins("B4", dir="io")),
|
Subsignal("d_p", Pins("B4", dir="io")),
|
||||||
Subsignal("d_n", Pins("A4", dir="io")),
|
Subsignal("d_n", Pins("A4", dir="io")),
|
||||||
Subsignal("pull_up", Pins("A3", dir="o")),
|
Subsignal("pull_up", Pins("A3", dir="o")),
|
||||||
extras=["IO_STANDARD=SB_LVCMOS33"]
|
extras={"IO_STANDARD": "SB_LVCMOS33"}
|
||||||
),
|
),
|
||||||
|
|
||||||
Resource("spiflash", 0,
|
Resource("spiflash", 0,
|
||||||
|
@ -28,6 +28,6 @@ class TinyFPGABXPlatform(TinyProgrammerMixin, LatticeICE40Platform):
|
||||||
Subsignal("clk", Pins("G7", dir="o")),
|
Subsignal("clk", Pins("G7", dir="o")),
|
||||||
Subsignal("mosi", Pins("G6", dir="io")),
|
Subsignal("mosi", Pins("G6", dir="io")),
|
||||||
Subsignal("miso", Pins("H7", dir="io")),
|
Subsignal("miso", Pins("H7", dir="io")),
|
||||||
extras=["IO_STANDARD=SB_LVCMOS33"]
|
extras={"IO_STANDARD": "SB_LVCMOS33"}
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in a new issue