self.ce = Signal()
self.count = Signal(BV(37, True), reset=-5)
- def do_simulation(self, s, cycle):
- if cycle % 2:
+ def do_simulation(self, s):
+ if s.cycle_counter % 2:
s.wr(self.ce, 0)
else:
s.wr(self.ce, 1)
- print("Cycle: " + str(cycle) + " Count: " + str(s.rd(self.count)))
+ print("Cycle: " + str(s.cycle_counter) + " Count: " + str(s.rd(self.count)))
def get_fragment(self):
sync = [If(self.ce, self.count.eq(self.count + 1))]
--- /dev/null
+from migen.fhdl.structure import *
+from migen.sim.generic import Simulator, TopLevel
+from migen.sim.icarus import Runner
+
+class Mem:
+ def __init__(self):
+ self.a = Signal(BV(12))
+ self.d = Signal(BV(16))
+ p = MemoryPort(self.a, self.d)
+ self.mem = Memory(16, 2**12, p, init=list(range(20)))
+
+ def do_simulation(self, s):
+ if s.cycle_counter >= 0:
+ value = s.rd(self.mem, s.cycle_counter)
+ print(value)
+ if value == 10:
+ s.interrupt = True
+
+ def get_fragment(self):
+ return Fragment(memories=[self.mem], sim=[self.do_simulation])
+
+def main():
+ dut = Mem()
+ sim = Simulator(dut.get_fragment(), Runner())
+ sim.run()
+
+main()
self.pads | other.pads,
self.sim + other.sim)
- def call_sim(self, simulator, cycle):
+ def call_sim(self, simulator):
for s in self.sim:
- s(simulator, cycle)
+ s(simulator)
rst_signal=rst_signal,
return_ns=True)
- self.cycle_counter = 0
+ self.cycle_counter = -1
self.interrupt = False
self.sim_runner = sim_runner
self.ipc.accept()
reply = self.ipc.recv()
assert(isinstance(reply, MessageTick))
- self.fragment.call_sim(self, -1)
+ self.fragment.call_sim(self)
def run(self, ncycles=-1):
+ self.interrupt = False
counter = 0
while not self.interrupt and (ncycles < 0 or counter < ncycles):
+ self.cycle_counter += 1
+ counter += 1
self.ipc.send(MessageGo())
reply = self.ipc.recv()
assert(isinstance(reply, MessageTick))
- self.fragment.call_sim(self, self.cycle_counter)
- self.cycle_counter += 1
- counter += 1
+ self.fragment.call_sim(self)
- def rd(self, signal):
+ def rd(self, item, index=0):
name = self.top_level.top_name + "." \
+ self.top_level.dut_name + "." \
- + self.namespace.get_name(signal)
- self.ipc.send(MessageRead(name))
+ + self.namespace.get_name(item)
+ self.ipc.send(MessageRead(name, Int32(index)))
reply = self.ipc.recv()
assert(isinstance(reply, MessageReadReply))
- nbits = signal.bv.width
+ if isinstance(item, Memory):
+ signed = False
+ nbits = item.width
+ else:
+ signed = item.bv.signed
+ nbits = item.bv.width
value = reply.value & (2**nbits - 1)
- if signal.bv.signed and (value & 2**(nbits - 1)):
+ if signed and (value & 2**(nbits - 1)):
value -= 2**nbits
return value
- def wr(self, signal, value):
+ def wr(self, item, value, index=0):
name = self.top_level.top_name + "." \
+ self.top_level.dut_name + "." \
- + self.namespace.get_name(signal)
+ + self.namespace.get_name(item)
+ if isinstance(item, Memory):
+ nbits = item.width
+ else:
+ nbits = item.bv.width
if value < 0:
- value += 2**signal.bv.width
- assert(value >= 0 and value < 2**signal.bv.width)
- self.ipc.send(MessageWrite(name, value))
+ value += 2**nbits
+ assert(value >= 0 and value < 2**nbits)
+ self.ipc.send(MessageWrite(name, Int32(index), value))
# Message classes
#
+class Int32(int):
+ pass
+
class Message:
def __init__(self, *pvalues):
for parameter, value in zip(self.parameters, pvalues):
class MessageWrite(Message):
code = 2
- parameters = [(str, "name"), (int, "value")]
+ parameters = [(str, "name"), (Int32, "index"), (int, "value")]
class MessageRead(Message):
code = 3
- parameters = [(str, "name")]
+ parameters = [(str, "name"), (Int32, "index")]
class MessageReadReply(Message):
code = 4
p.append(0)
return p
+def _pack_int32(v):
+ return [
+ v & 0xff,
+ (v & 0xff00) >> 8,
+ (v & 0xff0000) >> 16,
+ (v & 0xff000000) >> 24
+ ]
+
def _pack(message):
r = [message.code]
for t, p in message.parameters:
r += _pack_int(value)
elif t == str:
r += _pack_str(value)
+ elif t == Int32:
+ r += _pack_int32(value)
else:
raise TypeError
return bytes(r)
# Unpacking
#
-def _unpack_int(i):
+def _unpack_int(i, nchunks=None):
v = 0
power = 1
- nchunks = next(i)
+ if nchunks is None:
+ nchunks = next(i)
for j in range(nchunks):
v += power*next(i)
power *= 256
v = _unpack_int(i)
elif t == str:
v = _unpack_str(i)
+ elif t == Int32:
+ v = _unpack_int(i, 4)
else:
raise TypeError
pvalues.append(v)
char *name;
int nchunks;
unsigned char *chunks;
+ unsigned int index;
name = &buffer[i];
i += strlen(name) + 1;
- assert(i < l);
+ assert((i+4) < l);
+ index = buffer[i] | buffer[i+1] << 8 | buffer[i+2] << 16 | buffer[i+3] << 24;
+ i += 4;
nchunks = buffer[i++];
assert(i + nchunks == l);
chunks = (unsigned char *)&buffer[i];
- return sc->h_write(name, nchunks, chunks, sc->user);
+ return sc->h_write(name, index, nchunks, chunks, sc->user);
}
case MESSAGE_READ: {
char *name;
+ unsigned int index;
name = &buffer[i];
i += strlen(name) + 1;
- assert(i == l);
+ assert((i+4) == l);
+ index = buffer[i] | buffer[i+1] << 8 | buffer[i+2] << 16 | buffer[i+3] << 24;
- return sc->h_read(name, sc->user);
+ return sc->h_read(name, index, sc->user);
}
default:
return 0;
struct ipc_softc;
typedef int(*go_handler)(void *);
-typedef int(*write_handler)(char *, int, const unsigned char *, void *);
-typedef int(*read_handler)(char *, void *);
+typedef int(*write_handler)(char *, int, int, const unsigned char *, void *);
+typedef int(*read_handler)(char *, int, void *);
struct ipc_softc *ipc_connect(const char *sockaddr,
go_handler h_go, write_handler h_write, read_handler h_read, void *user);
.low = 0
};
-static int h_write(char *name, int nchunks, const unsigned char *chunks, void *user)
+static int h_write(char *name, int index, int nchunks, const unsigned char *chunks, void *user)
{
vpiHandle item;
s_vpi_vecval vector[64];
fprintf(stderr, "Attempted to write non-existing signal %s\n", name);
return 0;
}
+ if(vpi_get(vpiType, item) == vpiMemory)
+ item = vpi_handle_by_index(item, index);
+ else
+ assert(index == 0);
assert(nchunks <= 255);
for(i=0;i<64;i++) {
return 1;
}
-static int h_read(char *name, void *user)
+static int h_read(char *name, int index, void *user)
{
struct migensim_softc *sc = (struct migensim_softc *)user;
vpiHandle item;
fprintf(stderr, "Attempted to read non-existing signal %s\n", name);
return 0;
}
+ if(vpi_get(vpiType, item) == vpiMemory)
+ item = vpi_handle_by_index(item, index);
+ else
+ assert(index == 0);
value.format = vpiVectorVal;
vpi_get_value(item, &value);