/* Layout of a systolic array: x1 xm ↓ ↓ y1 → □ → ... → □ → y1' ↓ ↓ ... ... ↓ ↓ yn → □ → ... → □ → yn' ↓ ↓ x1' xm' g(m,f) : y,x1,...,xm -> x1',...,xm',y' constructs a single row of size m. h(n,m,f) : y1,...,yn,x1,...,xm -> x1',...,xm',yn',...,y1' constructs an array of size nxm. f is the function computed by each cell, which must take exactly two inputs and yield exactly two outputs. */ g(1,f) = f; g(m,f) = (f, r(m-1)) : (_, g(m-1,f)); h(1,m,f) = g(m,f); h(n,m,f) = (r(n+m) <: (!,r(n-1),s(m), (_,s(n-1),r(m) : g(m,f)))) : (h(n-1,m,f), _); // route n inputs r(1) = _; r(n) = _,r(n-1); // skip n inputs s(1) = !; s(n) = !,s(n-1); // sample cell function f = + <: _,_; //process = g(3,f); process = h(2,3,f);