sim: keep track of unreferenced items
authorRobert Jordens <jordens@gmail.com>
Fri, 20 Mar 2015 21:10:40 +0000 (15:10 -0600)
committerSebastien Bourdeauducq <sb@m-labs.hk>
Sat, 21 Mar 2015 09:02:10 +0000 (10:02 +0100)
* items that are never referenced in any statements do not end up in the
namespace or in the verilog

* this memorizes items if they can not be found in the namespace and keeps
track of their values

migen/sim/generic.py

index b290405bfaf07019a8832e5f1cba79190e786c57..2977cf9d8293b03967a4b0876c6cefba27072316 100644 (file)
@@ -103,6 +103,7 @@ class Simulator:
 
                self.sim_functions = fragment.sim
                self.active_sim_functions = set(f for f in fragment.sim if not hasattr(f, "passive") or not f.passive)
+               self.unreferenced = {}
 
        def run(self, ncycles=None):
                counter = 0
@@ -140,28 +141,43 @@ class Simulator:
                                except KeyError:
                                        pass
 
+       def get_unreferenced(self, item, index):
+               try:
+                       return self.unreferenced[(item, index)]
+               except KeyError:
+                       if isinstance(item, Memory):
+                               try:
+                                       init = item.init[index]
+                               except (TypeError, IndexError):
+                                       init = 0
+                       else:
+                               init = item.reset
+                       self.unreferenced[(item, index)] = init
+                       return init
+
        def rd(self, item, index=0):
-               name = self.top_level.top_name + "." \
-                 + self.top_level.dut_name + "." \
-                 + self.namespace.get_name(item)
-               self.ipc.send(MessageRead(name, Int32(index)))
-               reply = self.ipc.recv()
-               assert(isinstance(reply, MessageReadReply))
+               try:
+                       name = self.top_level.top_name + "." \
+                         + self.top_level.dut_name + "." \
+                         + self.namespace.get_name(item)
+                       self.ipc.send(MessageRead(name, Int32(index)))
+                       reply = self.ipc.recv()
+                       assert(isinstance(reply, MessageReadReply))
+                       value = reply.value
+               except KeyError:
+                       value = self.get_unreferenced(item, index)
                if isinstance(item, Memory):
                        signed = False
                        nbits = item.width
                else:
                        signed = item.signed
                        nbits = flen(item)
-               value = reply.value & (2**nbits - 1)
+               value = value & (2**nbits - 1)
                if signed and (value & 2**(nbits - 1)):
                        value -= 2**nbits
                return value
 
        def wr(self, item, value, index=0):
-               name = self.top_level.top_name + "." \
-                 + self.top_level.dut_name + "." \
-                 + self.namespace.get_name(item)
                if isinstance(item, Memory):
                        nbits = item.width
                else:
@@ -169,7 +185,13 @@ class Simulator:
                if value < 0:
                        value += 2**nbits
                assert(value >= 0 and value < 2**nbits)
-               self.ipc.send(MessageWrite(name, Int32(index), value))
+               try:
+                       name = self.top_level.top_name + "." \
+                         + self.top_level.dut_name + "." \
+                         + self.namespace.get_name(item)
+                       self.ipc.send(MessageWrite(name, Int32(index), value))
+               except KeyError:
+                       self.unreferenced[(item, index)] = value
 
        def __del__(self):
                if hasattr(self, "ipc"):