Make for loops great again
What's hard to do? (limit 100 words)
for loops are quite cumbersome compared to other languages like C++ or SystemVerilog.
This largely stems from the lack of mut, probably, but it is still a pain every time I need to write a for loop.
Consider an egregious case of building 2 related 2D arrays. In other languages, this would otherwise be a trivial nested for loop with adjacent inner loops. Let's take SystemVerilog as an example, since the focus is on representing synthesizable hardware:
baz_t [J-1:0][I-1:0] foo;
baz_t [K-1:0][I-1:0] bar;
always_comb begin
for (int i = 0; i < I; i++) begin
for (int j = 0; j < J; j++) begin
foo[j][i] = baz_t'(...);
end
for (int k = 0; k < K; k++) begin
bar[k][i] = baz_t'(...);
end
end
end
This takes significantly more thought to write in DSLX (see below).
Current best alternative workaround (limit 100 words)
Two approaches come to mind (just sketched out, may have errors). Neither seems as easy to get right without thinking as the code above.
-
Do all the updates in the inner loop and keep track of multiple layers of the full array accumulator. Something like:
let (foo, bar) = for(i, (foo, bar)): (u32, (baz_t, baz_t)) in range(u32:0, I) { let foo_new = for(j, foo): (u32, baz_t) in range(u32:0, J) { let foo_j = update(foo[j], i, ...); update(foo, j, foo_j) }(foo); let bar_new = for(k, bar): (u32, baz_t) in range(u32:0, K) { let bar_k = update(bar[k], i, ...); update(bar, k, bar_k) }(bar); (foo_new, bar_new) }((zero!<baz_t[J][I]>(), zero!<baz_t[K][I]>())); -
Split this into two outer loops, so you can do the array updates in the same direction as the nested looping:
let foo = for(j, foo): (u32, baz_t) in range(u32:0, J) { let foo_j_new = for (i, foo_j): (u32, baz_t) in range(u32:0, I) { update(foo_j, i, ...) }(foo[j]); update(foo, j, foo_j_new) }(zero!<baz_t[J][I]>()); let bar = for(k, bar): (u32, baz_t) in range(u32:0, K) { let bar_k_new = for (i, bar_k): (u32, baz_t) in range(u32:0, I) { update(bar_k, i, ...) }(bar[k]); update(bar, k, bar_k_new) }(zero!<baz_t[K][I]>());
Your view of the "best case XLS enhancement" (limit 100 words)
Make it easier to write for loops.