From: whitequark Date: Tue, 11 Jun 2019 03:38:44 +0000 (+0000) Subject: hdl.mem: coerce memory init values to integers. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=14c60a071a565b2da62bba14ad5d369540b80e3f;p=nmigen.git hdl.mem: coerce memory init values to integers. The coercion is carefully chosen to accept (other than normal ints) instances of e.g. np.int64, but reject instances of e.g. float. See https://stackoverflow.com/a/48940855/254415 for details. Fixes #93. --- diff --git a/nmigen/hdl/mem.py b/nmigen/hdl/mem.py index 076d284..b07018e 100644 --- a/nmigen/hdl/mem.py +++ b/nmigen/hdl/mem.py @@ -1,3 +1,5 @@ +import operator + from .. import tracer from .ast import * from .ir import Elaboratable, Instance @@ -40,11 +42,15 @@ class Memory: raise ValueError("Memory initialization value count exceed memory depth ({} > {})" .format(len(self.init), self.depth)) - for addr in range(len(self._array)): - if addr < len(self._init): - self._array[addr].reset = self._init[addr] - else: - self._array[addr].reset = 0 + try: + for addr in range(len(self._array)): + if addr < len(self._init): + self._array[addr].reset = operator.index(self._init[addr]) + else: + self._array[addr].reset = 0 + except TypeError as e: + raise TypeError("Memory initialization value at address {:x}: {}" + .format(addr, e)) from None def read_port(self, domain="sync", synchronous=True, transparent=True): if not synchronous and not transparent: diff --git a/nmigen/test/test_hdl_mem.py b/nmigen/test/test_hdl_mem.py index 0b37d48..9bbe762 100644 --- a/nmigen/test/test_hdl_mem.py +++ b/nmigen/test/test_hdl_mem.py @@ -29,11 +29,17 @@ class MemoryTestCase(FHDLTestCase): m = Memory(width=8, depth=4, init=range(4)) self.assertEqual(m.init, [0, 1, 2, 3]) - def test_init_wrong(self): + def test_init_wrong_count(self): with self.assertRaises(ValueError, msg="Memory initialization value count exceed memory depth (8 > 4)"): m = Memory(width=8, depth=4, init=range(8)) + def test_init_wrong_type(self): + with self.assertRaises(TypeError, + msg="Memory initialization value at address 1: " + "'str' object cannot be interpreted as an integer"): + m = Memory(width=8, depth=4, init=[1, "0"]) + def test_read_port_transparent(self): mem = Memory(width=8, depth=4) rdport = mem.read_port()