====== Array, loops and selection ====== Complex datapath designs are often designed with array of simpler cells. The following example show how to create array of simple cells and connect them using loop constructs in ACT. import "adder.act"; defproc adder8b ( bool? a[8],b[8],ci; bool! s[8],co) { bool c[9]; fulladder fa[8]; c[0] = ci; co = c[8]; ( i : 8 : fa[i](a[i], b[i], c[i], s[i], c[i+1]);) } The statement ''fulladder fa[8];'' creates an array with 8 instances of full adder and the carry chain between adders is connected by bool array ''c''. The statement ''(i:8: ….)'' implements a loop with index ''i'' and its value runs from 0 to 7. Here are different ways of writing the same loop using another variant of signal connection. (i : 8 : fa[i].a=a[i]; fa[i].b=b[i]; fa[i].ci=c[i]; fa[i].s=s[i]; fa[i].co=fa[i+1].ci; ) (i : 8 : fa[i](.a=a[i], .b=b[i], .ci=c[i], .s=s[i], .co=fa[i+1].ci) ) An instance of this adder is then created in a separate file as: import “adder8b.act”; adder8b fa8; ====== Script for simulating large array in prsim ====== As you can see, the number of input/output increases significantly with each new bit added to the adder. The 8-bit adder has 17 boolean inputs and 9 boolean outputs. To simplify the process of assigning inputs and observing outputs, a group of nodes can be combined as a virtual node using keyword ''vector'' in prsim. An example simulation script to combine nodes and simulate in prsim is shown below: initialize set fa8.ci 0 vector fa fa8.a[7] fa8.a[6] fa8.a[5] fa8.a[4] fa8.a[3] fa8.a[2] fa8.a[1] fa8.a[0] vector fb fa8.b[7] fa8.b[6] fa8.b[5] fa8.b[4] fa8.b[3] fa8.b[2] fa8.b[1] fa8.b[0] vector fs fa8.co fa8.s[7] fa8.s[6] fa8.s[5] fa8.s[4] fa8.s[3] fa8.s[2] fa8.s[1] fa8.s[0] vset fa 10 vset fb 12 cycle vget fa vget fb vget fs vset fa 255 vset fb 121 cycle vget fa vget fb vget fs Here, command ''vector fa fa8.a[7] … fa8.a[0]'' is used to combine 8 bits of input ''a'' as vector ''fa''. The command ''vset'' and ''vget'' are used to set and get values for the vector. ====== Selection ====== The example below shows how selection statement is used for conditional execution. import "gates.act"; defproc select (bool x0[8], x1[8]; bool y[8], z[8]) { ( i : 8 : [ (i%2) = 0 -> x0[i] = y[i]; x1[i] = z[i]; [] (i%2) = 1 -> x0[i] = z[i]; x1[i] = y[i]; ] ) } Depending on the value of index ''i'', input ''x0''/''x1'' are assigned to output ''y'' or ''z''. If ''i'' is even, ''x0'' is assigned to ''y'' and ''x1'' is assigned to ''z''. If ''i'' is odd, ''x0'' is assigned to ''z'' and ''x1'' is assigned to ''y''. ====== Checking library dependencies ====== For a hierarchical design with many imported libraries, it could be useful to get dependency information and see if all the libraries are present in the directories where ACT can find them. The command ''adepend'' is used to check dependencies. $ adepend adder8b.act adder8b.act: adder.act gates.act Here, running adepend on ''adderb8.act'' shows that it depends on the ''adder.act'' and ''gates.act''.