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: 2423eabc15ac
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: d2d8c2b8bf1b
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Jun 11, 2019

  1. 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.
    whitequark committed Jun 11, 2019
    Copy the full SHA
    58e39f9 View commit details
  2. back.rtlil: mask memory init values.

    This handles both init values that are too wide, which happens if
    their magnitude is too high, or if they're negative.
    
    Fixes #96.
    whitequark committed Jun 11, 2019
    Copy the full SHA
    d2d8c2b View commit details
Showing with 20 additions and 7 deletions.
  1. +2 −1 nmigen/back/rtlil.py
  2. +11 −5 nmigen/hdl/mem.py
  3. +7 −1 nmigen/test/test_hdl_mem.py
3 changes: 2 additions & 1 deletion nmigen/back/rtlil.py
Original file line number Diff line number Diff line change
@@ -729,9 +729,10 @@ def convert_fragment(builder, fragment, hierarchy):
name=memory.name)
addr_bits = bits_for(memory.depth)
data_parts = []
data_mask = (1 << memory.width) - 1
for addr in range(memory.depth):
if addr < len(memory.init):
data = memory.init[addr]
data = memory.init[addr] & data_mask
else:
data = 0
data_parts.append("{:0{}b}".format(data, memory.width))
16 changes: 11 additions & 5 deletions nmigen/hdl/mem.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import operator

from .. import tracer
from .ast import *
from .ir import Elaboratable, Instance
@@ -40,11 +42,15 @@ def init(self, new_init):
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:
8 changes: 7 additions & 1 deletion nmigen/test/test_hdl_mem.py
Original file line number Diff line number Diff line change
@@ -29,11 +29,17 @@ def test_init(self):
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()