Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
language:expressions [2022/07/22 15:13] rajit [Functions] |
language:expressions [2024/03/20 07:19] rajit [Operator Precedence] |
||
---|---|---|---|
Line 9: | Line 9: | ||
* The query expression '' | * The query expression '' | ||
* Logical shift operators are ''<<'' | * Logical shift operators are ''<<'' | ||
- | * Bit operations: For a variable '' | + | * Bit operations: For a variable '' |
* Concatenation: | * Concatenation: | ||
Line 18: | Line 18: | ||
* '' | * '' | ||
* '' | * '' | ||
+ | |||
+ | Syntactic replication is also supported for the operators ''&'', | ||
+ | <code act> | ||
+ | (+ i : 3 : p[i] + 2*i) | ||
+ | </ | ||
+ | and is equivalent to | ||
+ | <code act> | ||
+ | p[0] + 2*0 + p[1] + 2*1 + p[2] + 2*2 | ||
+ | </ | ||
===== Parameters and constant expressions ===== | ===== Parameters and constant expressions ===== | ||
- | Parameter expressions are used to compute parameter values ('' | + | Parameter expressions are used to compute parameter values ('' |
+ | In the context of expressions in the ACT language where the entire expression evaluates to a run-time constant, '' | ||
+ | <code act> | ||
+ | pint y = 2; | ||
+ | pint x = int(5.4/y) | ||
+ | </ | ||
+ | will succeed, while | ||
+ | <code act> | ||
+ | int x, y; | ||
+ | chp { | ||
+ | y := 2; | ||
+ | x := int(5.4/y) | ||
+ | } | ||
+ | </ | ||
+ | will report an error. | ||
===== Expressions in CHP ===== | ===== Expressions in CHP ===== | ||
Line 50: | Line 73: | ||
* left shift ''<<'' | * left shift ''<<'' | ||
* For concatenation, | * For concatenation, | ||
+ | |||
+ | While these bit-width rules are nice because you never lose bits, they can have some unexpected consequences. One of the not-so-nice effects of these rules is that, technically, | ||
+ | |||
+ | <code act> | ||
+ | int< | ||
+ | int< | ||
+ | int< | ||
+ | ... | ||
+ | chp { | ||
+ | ... | ||
+ | x := (a + b) + c; | ||
+ | y := a + (b + c); | ||
+ | ... | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Applying the bit-width rules, the expression '' | ||
+ | |||
+ | Another strange example is: | ||
+ | |||
+ | <code act> | ||
+ | ... | ||
+ | chp { | ||
+ | ... | ||
+ | x := x - 1; | ||
+ | y := y + (-1); | ||
+ | ... | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Now the right hand side of the first assignment takes '' | ||
+ | |||
===== Functions ===== | ===== Functions ===== | ||
Line 91: | Line 146: | ||
The first kind of function is typically used when constructing the circuit, and its value can be statically computed during the circuit construction phase. The second kind of function is viewed as CHP, and can be implemented either by inlining the function or through some other approach (e.g. shared, partially shared, etc). | The first kind of function is typically used when constructing the circuit, and its value can be statically computed during the circuit construction phase. The second kind of function is viewed as CHP, and can be implemented either by inlining the function or through some other approach (e.g. shared, partially shared, etc). | ||
- | For example, the following function that takes an '' | + | For example, the following function that takes an '' |
<code act> | <code act> | ||
/* look at the MSB to determine if this is a negative 2's complement integer */ | /* look at the MSB to determine if this is a negative 2's complement integer */ | ||
Line 97: | Line 152: | ||
{ | { | ||
chp { | chp { | ||
- | self := bool(x{7}); | + | self := bool(x{7}) |
} | } | ||
} | } | ||
</ | </ | ||
+ | |||
+ | ===== External Functions ===== | ||
+ | |||
+ | ACT is a hardware description language. However, especially when simulating a design, it is useful to be able to have additional functionality that goes beyond the implemented circuit. For example, a designer may want to test a CHP program by providing it inputs from a test suite that is contained in a file. To do so would require providing an I/O library for ACT. Similarly there may be other additional features one might want for simulation purposes. | ||
+ | |||
+ | Instead of providing specific solutions to a large number of potential use cases, ACT provides a single generic mechanism: the ability to call an // | ||
+ | |||
+ | To define an external function, simply declare the function in ACT without providing a definition. | ||
+ | <code act> | ||
+ | // an external function with parameter arguments | ||
+ | function myextfunc (pint a) : pint; | ||
+ | </ | ||
+ | In this example, function '' | ||
+ | |||
+ | <code act> | ||
+ | // an external function with circuit variable arguments | ||
+ | function myextfunc2 (int< | ||
+ | </ | ||
+ | In this example, function '' | ||
+ | |||
+ | ==== External parameter functions ==== | ||
+ | |||
+ | To implement the external parameter function, you must provide two things: a C implementation with a specific function prototype, and a ACT configuration file that maps the ACT function name to the C function name. | ||
+ | |||
+ | Since '' | ||
+ | |||
+ | <code c> | ||
+ | long myexternimpl (int nargs, long *args) | ||
+ | { | ||
+ | int i; | ||
+ | /* nargs = # of arguments */ | ||
+ | | ||
+ | for (i=0; i < nargs; i++) { | ||
+ | printf (" | ||
+ | } | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | In this example, the function simply prints out the number of arguments and the values passed in, returning a constant value. | ||
+ | |||
+ | The second part is specifying the mapping from the ACT function name to the C function name. Since external functions can be organized in multiple libraries, the way this is specified is the following: | ||
+ | < | ||
+ | begin act | ||
+ | begin extern | ||
+ | string_table libs " | ||
+ | | ||
+ | begin mylib | ||
+ | string path " | ||
+ | string myextfunc " | ||
+ | end | ||
+ | end | ||
+ | end | ||
+ | </ | ||
+ | The specification of the mapping is contained within the '' | ||
+ | |||
+ | The library specifier block contains the path to the shared object library that contains the external function definitions via the '' | ||
+ | |||
+ | Finally, the C file must be compiled as a shared object file, and assembled into a library. For example, on Linux, one might use the following commands to create '' | ||
+ | <code sh> | ||
+ | $ gcc -shared -DPIC -fPIC -c example.c -o example.os | ||
+ | $ gcc -shared -Wl,-x -o libpath.so example.os | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== External circuit functions ==== | ||
+ | |||
+ | External circuit functions are implemented in a similar fashion. Currently, only the ACT simulator ('' | ||
+ | |||
+ | The C implementation of external functions uses a function prototype that includes bit-width specifiers for all the data types. (Currently there is a limit of 64 bits on the bit-width of arguments/ | ||
+ | |||
+ | <code c> | ||
+ | /* this includes the simple external interface datatype used */ | ||
+ | #include < | ||
+ | |||
+ | struct expr_res myexternimpl2 (int nargs, struct expr_res *args) | ||
+ | { | ||
+ | | ||
+ | int i; | ||
+ | /* nargs = # of arguments */ | ||
+ | | ||
+ | for (i=0; i < nargs; i++) { | ||
+ | printf (" | ||
+ | } | ||
+ | | ||
+ | r.v = 4; | ||
+ | | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | The specification of the mapping configuration file is similar to the case of external parameter functions. The only difference is that the outer most '' | ||
+ | |||
+ | An example of file I/O implemented with external functions can be found in the '' | ||
+ | |||
+ | ==== Operator Precedence ==== | ||
+ | |||
+ | The operators have the following precedence, from the highest to lowest: | ||
+ | - '' | ||
+ | - '' | ||
+ | - '' | ||
+ | - ''<<'', | ||
+ | - ''&'' | ||
+ | - '' | ||
+ | - '' | ||
+ | - ''?'' | ||
+ |