lkolbly / ripstop

Apache License 2.0
0 stars 0 forks source link

Extern module instantiation #33

Open lkolbly opened 1 year ago

lkolbly commented 1 year ago

The user might want to instantiate a module which is defined outside of their code. For example, this can be a high-cost alternative to #9 if the user uses the external module to instantiate memories or something:

extern module ram16x16(bits<16> addr, bits<16> din, bit wen) -> (bits<16> dout);

module foo() -> () {
    instantiate ram16x16 as ram;
    ram.addr[t] = ...;
}

If the user does this, they should still be able to simulate it when running in Python, perhaps something like this:

module.step({"foo.ram.dout": 5})

or perhaps by specifying an object that gets passed into the module, for example:

class Ram:
    def __init__(self, memory):
        self.memory = memory;
        self.prev_addr = 0

    def step(self, args):
        addr = self.prev_addr
        self.prev_addr = args["addr"]
        return {"dout": self.memory[addr]}

however we end up doing it, we'll need to support combinatorial modules, so being able to set y[t] = f(t[-1]) doesn't quite cover every case (in fact, this is something that the simulation is lacking at a broader scale too).

lkolbly commented 1 year ago

This is partially done, we have to also consider the case of two external modules connected circularly, e.g.:

instantiate foo as a;
instantiate bar as b;

a.x[t] = b.y[t];
b.x[t] = a.y[t];

which is, of course, legal (as long as one of foo or bar breaks the combinatorial cycle), but necessitates that we split the simulation into separate "update" and "clock" steps and call "update" on each module until the system stabilizes.