Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
language:impl [2020/05/02 13:36]
rajit
language:impl [2023/04/09 18:06] (current)
rajit [Overrides]
Line 10: Line 10:
 implementation of a data or channel type. The most straightforward implementation of a data or channel type. The most straightforward
 mechanism to specify a channel is to say that it is the implementation mechanism to specify a channel is to say that it is the implementation
-of a built-in data type. In the example above, the channel+of a built-in data type. In the example in the [[language:types2|previous section]], the channel
 ''e1of2'' is defined to be an implementation of a ''e1of2'' is defined to be an implementation of a
 ''chan(bool)''. The implementation has additional port parameters, ''chan(bool)''. The implementation has additional port parameters,
Line 20: Line 20:
 When a type implements another one, the new type can be used in places When a type implements another one, the new type can be used in places
 the old type was used. While this is superficially similar to the old type was used. While this is superficially similar to
-subtyping in programming languages, it is better viewed as a +subtyping in programming languages, it is better viewed as an 
-refinement relationship. So, if type ''tA'' implements type+implementation relationship. So, if type ''tA'' implements type
 ''tB'', then ''tA'' has a more detailed description of the ''tB'', then ''tA'' has a more detailed description of the
 implementation compared to ''tB''. Type ''tB'' is the implementation compared to ''tB''. Type ''tB'' is the
Line 37: Line 37:
 equivalent to each other. equivalent to each other.
  
-A more interesting option is to use refinement between two +A more interesting option is to use the implementation relationship 
-user-defined types. Refinement is used to create related versions of+between two user-defined types. This option is used to create related versions of
 an existing type. If type ''foo'' implements ''bar'', then the an existing type. If type ''foo'' implements ''bar'', then the
 basic rule is that one can use ''foo'' instances in all the same basic rule is that one can use ''foo'' instances in all the same
Line 45: Line 45:
 detail below. detail below.
  
-==== Refinement ====+==== Aspects of the implementation relation ====
  
 When a user defined type implements another, there are several items When a user defined type implements another, there are several items
Line 59: Line 59:
 port list. As an illustration, consider: port list. As an illustration, consider:
  
-<code>+<code act>
 defproc type1 (bool a, b) { ... } defproc type1 (bool a, b) { ... }
 defproc type2 <: type1 (bool c) { ... } defproc type2 <: type1 (bool c) { ... }
Line 72: Line 72:
 the port list example above. the port list example above.
  
-<code>+<code act>
 template<pint N> template<pint N>
 defproc type1 (bool a, b) { ... } defproc type1 (bool a, b) { ... }
Line 82: Line 82:
 However, we can also define ''type2'' in the following manner: However, we can also define ''type2'' in the following manner:
  
-<code>+<code act>
 template<pint N> template<pint N>
 defproc type1 (bool a, b) { ... } defproc type1 (bool a, b) { ... }
Line 103: Line 103:
 as follows: as follows:
  
-<code>+<code act>
 type2<5> x; type2<5> x;
 // x.N, x.M are both accessible! // x.N, x.M are both accessible!
Line 113: Line 113:
 the instance the instance
  
-<code>+<code act>
 type2<5,7> x; type2<5,7> x;
 // x.M=5, x.N=7 // x.M=5, x.N=7
 </code> </code>
  
-would set ''N'' (the new template parameter) to ''5'', and +would set ''M'' (the new template parameter) to ''5'', and 
-''M'' (the parent, still definable parameter) to ''7''. Finally,+''N'' (the parent, still definable parameter) to ''7''. Finally,
 the following would be an error: the following would be an error:
  
-<code>+<code act>
 template<pint N> defproc type1 (bool a, b) { ... } template<pint N> defproc type1 (bool a, b) { ... }
 template<pint N> defproc type2 <: type1 (bool c) { ... } template<pint N> defproc type2 <: type1 (bool c) { ... }
 +</code>
 +<code>
 -[ERROR]-> Duplicate meta-parameter name in port list: `N' -[ERROR]-> Duplicate meta-parameter name in port list: `N'
            Conflict occurs due to parent type: type1            Conflict occurs due to parent type: type1
Line 134: Line 136:
 consider the following example:  consider the following example: 
  
-<code>+<code act>
 defproc buffer (e1of2? l, e1of2! r) defproc buffer (e1of2? l, e1of2! r)
 { {
Line 149: Line 151:
 define a specific implementation as follows: define a specific implementation as follows:
  
-<code>+<code act>
 defproc wchb <: buffer () defproc wchb <: buffer ()
 { {
Line 167: Line 169:
 specification for a buffer at the CHP level of abstraction would be: specification for a buffer at the CHP level of abstraction would be:
  
-<code>+<code act>
 defproc buffer (chan?(bool) l, chan!(bool) r) defproc buffer (chan?(bool) l, chan!(bool) r)
 { {
Line 191: Line 193:
 implementation of the original. The syntax for this is shown below: implementation of the original. The syntax for this is shown below:
  
-<code>+<code act>
 defproc wchb <: buffer() defproc wchb <: buffer()
 +{ e1of2 l, r; } // override block +{ e1of2 l, r; } // override block
Line 210: Line 212:
 only syntax permited is of the form within an override block is only syntax permited is of the form within an override block is
  
-<code>+<code act>
 +{ +{
     type list-of-ids;     type list-of-ids;
Line 217: Line 219:
 </code> </code>
  
-The identifiers cannot contain array specifiers, and the types canot +The identifiers cannot contain array specifiers, and the types  
-have any direction flags. The identifier names must match names in the+cannot have any direction flags. Furthermore, the types must also 
 +be user-defined types. The identifier names must match names in the
 parent type (either in the port list or in the body of the type). If parent type (either in the port list or in the body of the type). If
 the original identifier was declared as an array, the entire array the original identifier was declared as an array, the entire array
Line 224: Line 227:
 inherited by the overridden type. inherited by the overridden type.
  
-Implemetation relations introduced should be handled with care. For+Implementation relations introduced should be handled with care. For
 example, suppose one has two definitions of a buffer: one using the example, suppose one has two definitions of a buffer: one using the
 CHP language, and the other using the PRS language (as above), and CHP language, and the other using the PRS language (as above), and
Line 235: Line 238:
 between such variables is unspecified by the implementation between such variables is unspecified by the implementation
 relationship. relationship.
- 
-**XXX: test this** 
  
 An additional complication arises if the process ''wchb'' ends up An additional complication arises if the process ''wchb'' ends up
Line 244: Line 245:
 representation of the Boolean variable. representation of the Boolean variable.
  
 +=== Overriding conditional instances and templated types ===
  
 +An instance created in a type definition may be created only under certain circumstances. 
 +This can occur in templated types, where template parameters can affect the instances within the type.
 +The override block has the simple syntax shown above. However, to account for conditional instances,
 +the override block directives implicitly check if the instance exists before applying the override. (Note that
 +ACT does not permit different types for the same instance name under different conditions.)
  
 +When a type is being overridden by another, the new implementation may have additional template parameters.
 +The override syntax above requires the complete list of template parameters to be specified. Instead, we also
 +provide a single extension override syntax
  
-===== The ptype ===== +<code act> 
- ++{ 
-**XXX: this section not yet implemented** +    type<param1,param2,...,paramN>+ id  // single ID only 
- +    ... 
-The special ''ptype'' meta-parameter type is used to pass in types + }
-into a process definitionThese types can be used to build a process +
-using other processes as building blocksThe syntax for using a +
-''ptype'' is the following: +
- +
-<code> +
-ptype(foo) x;+
 </code> </code>
- +The ''+'' indicates that these are //extra// template parameter(s) that should be added to the existing ones that have already been specified for the instance ''id'' in the original type definition.
-This says that ''x'' is a variable that is a type, with the +
-constraint that ''x'' must satisfy the type signature specified by +
-''foo''. In other words, ''x'' is guaranteed to support all the +
-operations supported by type ''foo''.  +
- +
-''ptype'' parameters can also be used in templates. Consider the +
-following example: +
- +
-<code> +
-// A constructor for a datapath with W-bit ripple connections, and +
-// where each component has M inputs and one output +
- +
-// A skeleton +
-template<pint W, pint M> +
-defproc bitslice (e1of2? rin[W]; e1of2! rout[W];  +
-                  e1of2? in[M]; e1of2! out) { } +
- +
-// the constructor +
-template<pint N, pint M, pint W, ptype(bitslice<W,M>) t> +
-defproc build_dpath (e1of2? rin[W]; e1of2! rout[W];  +
-                     e1of2? in[M*N]; e1of2! out[N]) +
-+
-   t x[N]; +
- +
-   // ripple connections +
-   (;i:N-1: x[i].rout=x[i+1].rin); +
-   x[0].rin=rin; +
-   x[N-1].rout=rout;    +
- +
-   // i/o connections +
-   (;i:N: x[i].in[i*M..(i+1)*M-1] = in[i*M..(i+1)*M-1]; +
-          x[i].out=out[i] ) +
-+
- +
-// A one-bit adder +
-defproc onebit (e1of2? in[2], rin[1]; e1of2! out, rout[1]) { ... } +
- +
-defproc ripple_adder (e1of2? a[32], b[32], cin; e1of2! out[32], cout) +
-+
-    build_dpath<32,2,1,onebit> dp; +
- +
-    (; i : 32 : dp.in[2*i] = a[i]; dp.in[2*i+1] = b[i]); +
-    dp.out = out; +
-    dp.rin[0] = cin; +
-    dp.rout[0] = cout +
-+
-</code> +
- +
- +
- +
- +
- +