Differences

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

Link to this comparison view

Next revision
Previous revision
intro_example:inverter [2020/04/29 14:25]
rajit created
intro_example:inverter [2022/05/13 09:15] (current)
rajit
Line 4: Line 4:
  
 An inverter is a very simple process that has a one-bit digital input and one bit digital output. The following specifies a process that corresponds to one inverter. An inverter is a very simple process that has a one-bit digital input and one bit digital output. The following specifies a process that corresponds to one inverter.
-<code>+<code act>
 defproc inverter (bool? i; bool! o) defproc inverter (bool? i; bool! o)
  
Line 14: Line 14:
 </code> </code>
  
 +Let's start with the statements
 +<code act>
 + i -> o-
 +~i -> o+
 +</code>
 +
 +These statements are two //production rules.// ([[language:langs:prs|prs documentation]]). If you have designed asynchronous circuits, then this terminology should be familiar. A production rule behaves in the following way:
 +   * The left hand side is a Boolean expression
 +   * The right hand side is a signal transition
 +   * There is an arrow between the two
 +   * If the left hand side is true, then (after some delay) the right hand side is executed eventually
 +The ''~'' symbol is used to indicate negation; the ''+'' means set the signal high; the ''-'' means set the signal low. 
 +
 +In this example, the variables ''i'' and ''o'' are Booleans. It should be clear that the combination of those two rules corresponds to an inverter.
 +
 +The left hand side for ''o+'' is the Boolean expression for the pull-up network for ''o''; the left hand side for ''o-'' is the Boolean expression for the pull-down network for ''o''.
 +
 +This is a combinational gate, which means either the pull-up or pull-down network is always conducting (alternatively, the OR of the Boolean expressions for the pull-up and pull-down is always true). In this case, the pull-up and pull-down networks are complements of each other, so you only need specify one. The ''=>'' arrow can be used so that one rule can be used to specify both the pull-up and pull-down network as follows:
 +
 +<code act>
 +defproc inverter (bool? i; bool! o)
 +
 +  prs {
 +    i => o-
 +  }
 +
 +</code>
 +
 +The ''prs { ... }'' specifies the production rule body for the process. There are other bodies that can also be included, and they use different keywords instead of ''prs'' but the same basic structure.
 +
 +The entire process is wrapped in the process definition. ''defproc'' is used to define a process. Here, we name the process ''inverter''. The signals ''i'' and ''o'' are in the //port list// for the process, which means they can be accessed from outside the process. They are declared as ''bool''s (Booleans), and the ''?'' means that ''i'' is an input, and the ''!'' means that ''o'' is an output.
 +
 +This fragment of ACT simply defines a process named ''inverter''. To actually create an inverter, we have to instantiate the process. The ''defproc'' can be viewed as defining the inverter type. We can use ''inverter'' just like we used ''bool'', and create an inverter called ''inv'' using the following:
 +<code act>
 +inverter inv;
 +</code>
 +
 +Next, we can simulate the inverter using a production-rule simulator. We have provided ''[[tools:prsim|prsim]]'' for production rule simulation as part of the ACT tools.
 +
 +===== Simulating with prsim =====
 +
 +The complete example is:
 +
 +<code act>
 +defproc inverter (bool? i; bool! o)
 +
 +  prs {
 +    i => o-
 +  }
 +
 +
 +inverter inv;
 +</code>
 +
 +
 +If the file above is called ''test_inv.act'', a production rule file can be created from the ACT file by:
 +
 +<code>
 +% aflat test_inv.act > test_inv.prs
 +</code>
 +
 +The output file is the following:
 +
 +<code>
 +"inv.i"->"inv.out"-
 +~"inv.i"->"inv.out"+
 +</code>
 +
 +Note that ACT uses ''.'' (like standard programming languages) as a separator between the name of the instance and internal nodes within it. (Note that magic, irsim use ''/'' as a separator; Xyce uses colon).
 +
 +If the file is saved as ''test_inv.prs'', it can be simulated using the production rule simulator called ''[[tools:prsim|prsim]]''
 +
 +<code>
 +% prsim test_inv.prs    
 +
 +(Prsim) initialize 
 +(Prsim) watch inv.i
 +(Prsim) watch inv.o
 +(Prsim) status X
 +(Prsim) set inv.i 0
 +(Prsim) cycle
 +(Prsim) set inv.i 1
 +(Prsim) cycle
 +</code>
 +
 +''prsim'' will check if the production rules being run are stable (i.e. hazard/glitch-free) and non-interfering (i.e. that pull-up and pull-down networks are not on simultaneously). It doesn't check all possible delay configurations, but just reports errors if it observes unstable or interfering production rules while the simulation is running. Try ''help'' as a ''prsim'' command to see the range of commands supported by ''prsim.''
 +
 +One of the useful features of ''prsim'' is that it can automatically randomize the delays of production rule firings. To do this, use
 +
 +<code>
 +(Prsim) random
 +</code>
 +
 +After this command, all delays are randomized. This is a useful test to see if your production rules are stable and non-interfering. If ''prsim'' finds that a production rule is unstable, it sets its output to ''X'' (for undefined). These ''X''s can propagate through the circuit.