import "primitives/core.futil";
import "primitives/memories/comb.futil";
component main() -> () {
cells {
@external out = comb_mem_d1(32, 1, 3);
val_1 = std_reg(32);
incr_1 = std_add(32);
val_2 = std_reg(32);
incr_2 = std_add(32);
val_3 = std_reg(32);
incr_3 = std_add(32);
loop = std_reg(3);
a = std_add(3);
ls = std_lt(3);
val = std_reg(32);
ac = std_add(32);
add_0 = std_add(32);
add_1 = std_add(32);
}
wires {
group calc_val_1 {
incr_1.left = val_1.out;
incr_1.right = 32'd1;
val_1.in = incr_1.out;
val_1.write_en = 1'd1;
calc_val_1[done] = val_1.done;
}
group calc_val_2 {
incr_2.left = val_2.out;
incr_2.right = 32'd2;
val_2.in = incr_2.out;
val_2.write_en = 1'd1;
calc_val_2[done] = val_2.done;
}
group calc_val_3 {
incr_3.left = val_3.out;
incr_3.right = 32'd3;
val_3.in = incr_3.out;
val_3.write_en = 1'd1;
calc_val_3[done] = val_3.done;
}
group accm {
add_0.left = val_1.out;
add_0.right = val_2.out;
add_1.left = add_0.out;
add_1.right = val_3.out;
ac.left = val.out;
ac.right = add_1.out;
val.in = ac.out;
val.write_en = 1'd1;
accm[done] = val.done;
}
group incr_loop {
a.left = loop.out;
a.right = 3'd1;
loop.in = a.out;
loop.write_en = 1'd1;
incr_loop[done] = loop.done;
}
group reg_to_mem {
out.write_en = 1'd1;
out.write_data = val.out;
out.addr0 = 3'd0;
reg_to_mem[done] = out.done;
}
comb group cond {
ls.left = loop.out;
ls.right = 3'd3;
}
}
control {
seq {
par {
// thread A
while ls.out with cond {
calc_val_1;
@sync(1);
@sync(2);
}
// thread B
while ls.out with cond {
calc_val_2;
@sync(1);
incr_loop;
@sync(2);
}
// thread C
while ls.out with cond {
calc_val_3;
@sync(1);
accm;
@sync(2);
}
}
reg_to_mem;
}
}
}