|
CAST and IRSIM
There are manpages for irsim on the student machines. If you want to
learn about all the irsim commands, try man irsim.
Here is an example of a CAST file, with comments explaining the
different parts. The definitions are in the standard library defined
for ECE/CS 314 that you should be familiar with. For 474, you
will be defining gates using production rules so you will not
need the 314 parts library.
/* import standard definitions of two-input NAND, two-input NOR,
inverter, and flops */
import "314/parts.cast";
/* define two-input And using Nand and inverter */
define And2() (node a, b, out)
{
node x; // declare intermediate node
Nand2() (a,b,x); // create two-input nand, output is x
Inv() (x,out); // invert x to get out
}
/* define two-input Or using Nor and inverter */
define Or2() (node a, b, out)
{
node x; // declare intermediate node
Nor2() (a,b,x); // create two-input nor
Inv() (x,out);
}
While this CAST file defines And2 and Or2,
it doesn't create any circuits. Let's say we save this CAST file as
foo.cast, and now want to create a circuit with
combinational logic that computes out = a AND b OR c.
The following file defines this circuit, using the definitions we've
just created:
import "foo.cast"; // get my definitions
node a, b, c; // declare boolean-valued inputs
node out; // declare boolean-valued output
node x; // intermediate node
And2() (a,b,x);
Or2() (x,c,out);
If this were saved in file.cast, running
prs2sim file.cast
generates file.sim and file.al, that can be
simulated with irsim by running:
irsim.sh file.sim file.al
Some commonly used irsim commands can be found here.
We can instantiate a positive edge-triggered flop by saying;
posFLOP() (inputnode, outputnode);
This instantiates a single flop with input inputnode, and
output outputnode. This can be used to create
state-holding elements and to build finite-state machines. Don't
forget to import 314/parts.cast before trying to create a
flop, since this file contains the definitions for
posFLOP.
| Loops |
| |
Let's say we wanted to define a block that took two sets of 8 one-bit
inputs, ANDed the correspond bits of the two inputs, and produced 8
one-bit outputs. A convenient way to group signals together is to use an
array. The definition of this block would look like:
import "314/myparts.cast"; // get my definitions
/* Note the way the array of inputs and outputs is declared. In this
example, node[8] is the type specifying an array of 8 nodes. */
define BlockAnd() (node[8] a,b, out)
{
node[8] x;
Nand2() (a[0],b[0],x[0]);
Inv() (x[0],out[0]);
Nand2() (a[1],b[1],x[1]);
Inv() (x[1],out[1]);
/* this is getting tedious... */
...
Nand2() (a[7],b[7],x[7]);
Inv() (x[7],out[7]);
}
To avoid all this typing, CAST supports a syntactic loop
construct. Using this construct, the same circuit as the one shown
above would be written as:
import "314/myparts.cast"; // get my definitions
/* Note the way the array of inputs and outputs is declared. In this
example, node[8] is the type specifying an array of 8 nodes. */
define BlockAnd() (node[8] a,b, out)
{
node[8] x;
<i:8: Nand2() (a[i],b[i],x[i]); Inv() (x[i],out[i]); >
}
Note that the two ways to describe the BlockAnd result in
identical circuits. The loop construct is just a convenience;
the loop would be expanded out before the circuit is created.
|
|
|
|
|