Invoking memories.
Closed this issue · 4 comments
This is a blocker for progress in #369.
Before Invoke
, we used memories in a component with the go-done interface in the following manner:
component foo
(go: 1, clk: 1, x_read_data: 32, x_done: 1)
->
(done: 1, x_addr0: 1, x_write_data: 32, x_write_en: 1) { ... }
main() -> () {
...
comp_foo = foo;
x = std_mem_d1(32, 1, 1);
...
group run_foo {
// Read from `x`.
x.addr0 = comp_foo.x_addr0;
comp_add0.x_read_data = x.read_data;
// Write to `x`
x.write_data = comp_foo.x_write_data;
x.write_en = comp_foo.x_write_en;
comp_foo.x_done = x.done;
comp_foo.go = 1'd1;
run_foo[done] = comp_foo.done;
}
}
To transition to Invoke
, the input wires for a memory read is trivial:
invoke comp_foo(x_read_data = x.read_data, x_addr0 = x.addr0)();
So, how do we write to x
?
invoke comp_foo(..., x.write_en = x_write_en, x.write_data = x_write_data)(); // Flip-flop CompPort, ThisPort
This is what seems to be discussed in the original Invoke issue. This would mean changing our current implementation in Dahlia and calyx-py to use PortDef
s instead of CompVar
s for both parameters and arguments (which makes sense, since we're using ThisPort
s) (fixed in #383 , Dahlia #347).
Invokable memories do seem like a good idea. An idea we've discussed elsewhere, but I've lost track of where, is somehow supporting multiple "methods" for components. You'd be able to invoke a memory in two different ways, somehow: like invoke my_mem.read(addr, data)
and invoke my_mem.write(addr, data)
. Perhaps we don't have to go all that way (which would be quite a refactoring!) just to get this effect, but thought I'd mention it here as one possible, high-effort option.
@cgyurgyik patiently pointed out to me that I had misunderstood the issue and the above comment is completely irrelevant and should be ignored. 😇
From today's discussion: Don't use Port
s for component port definitions. Just use Strings.
Dahlia frontend support in Dahlia #349.