hdl.ast, back.rtlil: add source locations to anonymous wires.
authorwhitequark <whitequark@whitequark.org>
Sat, 3 Aug 2019 12:44:52 +0000 (12:44 +0000)
committerwhitequark <whitequark@whitequark.org>
Sat, 3 Aug 2019 12:51:57 +0000 (12:51 +0000)
This might help with propagation of locations through optimizer
passes, since not all of them take care to preserve cells at all,
but usually wires stay intact when possible.

Also fixes incorrect source location on value.part().

nmigen/back/rtlil.py
nmigen/hdl/ast.py

index 4f6592ef5ff08eaa9196f3ad002ad3d4e935c094..55d15d93f23a2a27f22d53dac68cfed089bdbcfd 100644 (file)
@@ -227,12 +227,14 @@ class _SyncBuilder(_ProxiedBuilder):
 
 
 def src(src_loc):
+    if src_loc is None:
+        return None
     file, line = src_loc
     return "{}:{}".format(file, line)
 
 
 def srcs(src_locs):
-    return "|".join(sorted(map(src, src_locs)))
+    return "|".join(sorted(filter(lambda x: x, map(src, src_locs))))
 
 
 class LegalizeValue(Exception):
@@ -402,7 +404,7 @@ class _RHSValueCompiler(_ValueCompiler):
             return self.s.anys[value]
 
         res_bits, res_sign = value.shape()
-        res = self.s.rtlil.wire(width=res_bits)
+        res = self.s.rtlil.wire(width=res_bits, src=src(value.src_loc))
         self.s.rtlil.cell("$anyconst", ports={
             "\\Y": res,
         }, params={
@@ -416,7 +418,7 @@ class _RHSValueCompiler(_ValueCompiler):
             return self.s.anys[value]
 
         res_bits, res_sign = value.shape()
-        res = self.s.rtlil.wire(width=res_bits)
+        res = self.s.rtlil.wire(width=res_bits, src=src(value.src_loc))
         self.s.rtlil.cell("$anyseq", ports={
             "\\Y": res,
         }, params={
@@ -433,7 +435,7 @@ class _RHSValueCompiler(_ValueCompiler):
         arg, = value.operands
         arg_bits, arg_sign = arg.shape()
         res_bits, res_sign = value.shape()
-        res = self.s.rtlil.wire(width=res_bits)
+        res = self.s.rtlil.wire(width=res_bits, src=src(value.src_loc))
         self.s.rtlil.cell(self.operator_map[(1, value.op)], ports={
             "\\A": self(arg),
             "\\Y": res,
@@ -452,7 +454,7 @@ class _RHSValueCompiler(_ValueCompiler):
         if new_bits <= value_bits:
             return self(ast.Slice(value, 0, new_bits))
 
-        res = self.s.rtlil.wire(width=new_bits)
+        res = self.s.rtlil.wire(width=new_bits, src=src(value.src_loc))
         self.s.rtlil.cell("$pos", ports={
             "\\A": self(value),
             "\\Y": res,
@@ -476,7 +478,7 @@ class _RHSValueCompiler(_ValueCompiler):
             lhs_wire = self.match_shape(lhs, lhs_bits, lhs_sign)
             rhs_wire = self.match_shape(rhs, rhs_bits, rhs_sign)
         res_bits, res_sign = value.shape()
-        res = self.s.rtlil.wire(width=res_bits)
+        res = self.s.rtlil.wire(width=res_bits, src=src(value.src_loc))
         self.s.rtlil.cell(self.operator_map[(2, value.op)], ports={
             "\\A": lhs_wire,
             "\\B": rhs_wire,
@@ -498,7 +500,7 @@ class _RHSValueCompiler(_ValueCompiler):
         val1_bits = val0_bits = res_bits = max(val1_bits, val0_bits, res_bits)
         val1_wire = self.match_shape(val1, val1_bits, val1_sign)
         val0_wire = self.match_shape(val0, val0_bits, val0_sign)
-        res = self.s.rtlil.wire(width=res_bits)
+        res = self.s.rtlil.wire(width=res_bits, src=src(value.src_loc))
         self.s.rtlil.cell("$mux", ports={
             "\\A": val0_wire,
             "\\B": val1_wire,
@@ -524,7 +526,7 @@ class _RHSValueCompiler(_ValueCompiler):
         if isinstance(value, (ast.Signal, ast.Slice, ast.Cat)):
             sigspec = self(value)
         else:
-            sigspec = self.s.rtlil.wire(len(value))
+            sigspec = self.s.rtlil.wire(len(value), src=src(value.src_loc))
             self.s.rtlil.connect(sigspec, self(value))
         return sigspec
 
@@ -533,7 +535,7 @@ class _RHSValueCompiler(_ValueCompiler):
         lhs_bits, lhs_sign = lhs.shape()
         rhs_bits, rhs_sign = rhs.shape()
         res_bits, res_sign = value.shape()
-        res = self.s.rtlil.wire(width=res_bits)
+        res = self.s.rtlil.wire(width=res_bits, src=src(value.src_loc))
         # Note: Verilog's x[o+:w] construct produces a $shiftx cell, not a $shift cell.
         # However, Migen's semantics defines the out-of-range bits to be zero, so it is correct
         # to use a $shift cell here instead, even though it produces less idiomatic Verilog.
index 85310c1e00322e8709cd3a762dcaa85364359e74..b1d1a7e9484a695c8554fba8429662994a23d2de 100644 (file)
@@ -163,7 +163,7 @@ class Value(metaclass=ABCMeta):
         Part, out
             Selected part of the ``Value``
         """
-        return Part(self, offset, width)
+        return Part(self, offset, width, src_loc_at=1)
 
     def eq(self, value):
         """Assignment.