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/migen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 4fe888702d94
Choose a base ref
...
head repository: m-labs/migen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 14b1da401838
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Mar 21, 2015

  1. sim: keep track of unreferenced items

    * 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
    jordens authored and sbourdeauducq committed Mar 21, 2015
    Copy the full SHA
    5f045b7 View commit details
  2. test_actor: add unittests for SimActor

    * also implicitly tests for the access of signals during simulation that are
    not referenced in any statements
    
    * before, if the busy signal is never used, it is stripped
      and could not be accessed in simulation
    jordens authored and sbourdeauducq committed Mar 21, 2015
    Copy the full SHA
    14b1da4 View commit details
Showing with 98 additions and 11 deletions.
  1. +33 −11 migen/sim/generic.py
  2. +65 −0 migen/test/test_actor.py
44 changes: 33 additions & 11 deletions migen/sim/generic.py
Original file line number Diff line number Diff line change
@@ -103,6 +103,7 @@ def __init__(self, fragment, top_level=None, sim_runner=None, sockaddr="simsocke

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,36 +141,57 @@ def continue_simulation():
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:
nbits = flen(item)
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"):
65 changes: 65 additions & 0 deletions migen/test/test_actor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import unittest

from migen.fhdl.std import *
from migen.flow.actor import *
from migen.flow.transactions import *
from migen.flow.network import *
from migen.actorlib.sim import *

from migen.test.support import SimCase, SimBench

def source_gen(sent):
for i in range(10):
yield Token("source", {"value": i})
sent.append(i)

class SimSource(SimActor):
def __init__(self):
self.source = Source([("value", 32)])
self.sent = []
SimActor.__init__(self, source_gen(self.sent))

def sink_gen(received):
while True:
t = Token("sink")
yield t
received.append(t.value["value"])

class SimSink(SimActor):
def __init__(self):
self.sink = Sink([("value", 32)])
self.received = []
SimActor.__init__(self, sink_gen(self.received))

class SourceSinkCase(SimCase, unittest.TestCase):
class TestBench(SimBench):
def __init__(self):
self.source = SimSource()
self.sink = SimSink()
g = DataFlowGraph()
g.add_connection(self.source, self.sink)
self.submodules.comp = CompositeActor(g)

def do_simulation(self, selfp):
if self.source.token_exchanger.done:
raise StopSimulation

def test_equal(self):
self.run_with(lambda tb, tbp: None)
self.assertEqual(self.tb.source.sent, self.tb.sink.received)

class SourceSinkDirectCase(SimCase, unittest.TestCase):
class TestBench(SimBench):
def __init__(self):
self.source = SimSource()
self.sink = SimSink()
self.submodules += self.source, self.sink
self.comb += self.sink.sink.connect(self.source.source)

def do_simulation(self, selfp):
if self.source.token_exchanger.done:
raise StopSimulation

def test_equal(self):
self.run_with(lambda tb, tbp: None)
self.assertEqual(self.tb.source.sent, self.tb.sink.received)