CSE370 Synario/ABEL Tutorial

Schematics are not the only way to specify digital logic. In modern design tools, it is also possible to specify the logic textually and have it automatically converted into logic gates or programmable logic. The Synario tool suite supports three different hardware description languages (HDLs): ABEL, Verilog, and VHDL. We will be using ABEL which is the oldest of the three and the only one designed specifically for programmable logic devices.

Lets go back to the Synario Project Navigator and start up a new project. Then lets add a new source file but this time we'll select "ABEL-HDL Module" rather than "Schematic" or "Verilog Test Fixture".


We'll be prompted for the module name, the file name, and the title of our file. Frequently, the module and file name are the same. However, the file name will be appended with the .abl extension. The title should be descriptive and help us remember the function of the module.


After we click "OK", two things happen. An ABEL file is included as a new source to our project (notice the "A" in the icon for the source file in the snapshot below) and a text editor window is opened containing a template file for our module.



The Text Editor allows us to enter a textual specification of the logic we want in our module. In this case, we'll specify the calendar subsystem we used as an example in lecture. Recall that the input is the month and a flag specifying whether the year is leap or not. The output is an indication of how many days are in the month.

First, we must enter a specification for the inputs and outputs.

MODULE a5

 interface (m8, m4, m2, m1, leap -> d28, d29, d30, d31);

TITLE 'calendar subsystem'; 

"Inputs
m8, m4, m2, m1, leap pin; 

"Outputs
d28, d29, d30, d31 pin istype 'com';

"Aliases
month = [m8, m4, m2, m1];
days = [d28, d29, d30, d31];
The portion of the file shown above specifies the interface of the module (inputs -> outputs) and the pins. We specify the type of the outputs (you'll see why this matters later on) by using the istype keyword. In this case, we have combinational logic so our outputs are of type 'com'. Note that in ABEL, any line that starts with a double-quote (") is a comment line (that is, the rest of the line after the quote is ignored - you do not need to close the quote). Therefore, the words "Inputs" and "Outputs" are not of any significance to ABEL. We also include some aliases that group a collection of signals under one name so that we can refer to the entire group as a unit.

ABEL allows us to enter a specification for the logic in many different ways. We'll go through a few in this tutorial. First, lets start with the truth-table method.


The truth table is specified by listing all the input combinations we care about and their corresponding inputs. Notice how the number of bits must match precisely with the specification given at the beginning of the truth table (5 inputs, month (4) and leap (1) -> 4 outputs, days (4) ) The month inputs alias allowed us to use decimal numbers for the month rather than binary values (this is why the order of the month inputs in the alias statement was important - high order bit to low order bit). Note also the use of .X. to specify a don't care input. This tells the ABEL compilers that for any value of that particular input the output values should be the same. Finally, note that we did not list all the possible input combinations. The presence of the .X.s gave ABEL a hint that it should use the input combinations not listed as don't care conditions. However, in general, ABEL does not do this. To ensure that ABEL takes advantage of this sort of don't care information you can declare an output to be istype 'dc, com'.

We are now ready to compile our specification and see what the result is. Synario keeps track of all the steps required in compilation. Select the ABEL source in the "Sources" sub-window and then double-click on "Reduced Equations" in the "Process" sub-window of the navigator.


The resulting file is a5.eq1 and it contains, among other things, the following equations for our four outputs:

Equations:

d28 = ( !m8 & !m4 &  m2 & !m1 & !leap);
d29 = ( !m8 & !m4 &  m2 & !m1 &  leap);
d30 = ( !m8 &  m4 & !m1
      #  m8 & !m4 &  m1); 
d31 = (  m8 & !m2 & !m1
      #  m8 & !m4 & !m1
      # !m8 &  m1);
We can now use this module as we would have used any module specified with the schematics editor. This includes simulating the circuit and using it as a sub-circuit of a larger design. We'll see how to turn an ABEL module into a schematic editor symbol in just a bit. Right now, lets turn to some other ways of specifying combinational logic in ABEL. Instead of using a truth-table we could have written equations of each of the outputs directly. ABEL will still minimize them for us. We could replace the truth table block with:
EQUATIONS

d28 = ( !m8 & !m4 &  m2 & !m1 & !leap);
d29 = ( !m8 & !m4 &  m2 & !m1 &  leap);
d30 = ( !m8 &  m4 & !m2 & !m1 # !m8 &  m4 & m2 & !m1
      #  m8 & !m4 & !m2 &  m1 #  m8 & !m4 & m2 &  m1);
d31 = ( !m8 & !m4 & !m2 &  m1 # !m8 & !m4 & m2 &  m1 
      # !m8 &  m4 & !m2 &  m1 # !m8 &  m4 & m2 &  m1
      #  m8 & !m4 & !m2 & !m1 #  m8 & !m4 & m2 & !m1
      #  m8 &  m4 & !m2 & !m1)
The resulting minimized equations are the same as before. ABEL performs two-level minimization for us. Yet another way of specifying our logic function is to use programming language constructs such as:
EQUATIONS

WHEN (month == 2) THEN {         "if its February
   WHEN (leap == 1) THEN         "and its a leap year
      days = [0,1,0,0];          "then its 29 days
   ELSE
      days = [1,0,0,0];          "otherwise its 28 days
   }
ELSE {
   WHEN ( (month == 4) # (month == 6)
        # (month == 9) # (month == 11) ) THEN
      days = [0,0,1,0];          "cases where its 30 days
   ELSE 
      days = [0,0,0,1];          "31 days for others regardless of month
   }

The resulting minimized equations are not exactly the same as before. The reason for this is that we are now asking for the output to be [0,0,0,1] for all cases besides 2, 4, 6, 9, and 11. This yields the following:
Equations:

d28 = ( !leap & !m1 & m2 & !m4 & !m8);
d29 = (  leap & !m1 & m2 & !m4 & !m8);
d30 = ( !m1 &  m4 & !m8
      #  m1 & !m4 &  m8); 
d31 = ( !m2 & !m4 & !m8
      #  m4 &  m8
      #  m1 & !m8
      # !m1 &  m8);

Note that although the equations for d28, d29, and d30 are the same, the equation for d31 is quite different (in fact, it includes 0, 13, 14, and 15). In order to get the same equations as before we need to specify that we don't care what the values are for 0, 13, 14, and 15. We can do this as follows:
EQUATIONS

WHEN (month == 2) THEN {                    "if its February
   WHEN (leap == 1) THEN                    "and its a leap year 
      days = [0,1,0,0];                     "then its 29 days
   ELSE
      days = [1,0,0,0];                     "otherwise its 28 days
   }
ELSE {
   WHEN ( (month == 4) # (month == 6)
        # (month == 9) # (month == 11) ) THEN
      days = [0,0,1,0];                     "cases where its 30 days
   ELSE WHEN ( (month == 1) # (month == 3) # (month == 5)
             # (month == 7) # (month == 8) # (month == 10)
             # (month == 12) ) THEN 
      days = [0,0,0,1];                     "cases where its 31 days
   ELSE
      days = [.X.,.X.,.X.,.X.];             "don't care about others
   }
You should now verify that the equations are in fact the same (as they should be since the same information was provided).

These are the three basic mechanisms for specifying combinational logic in ABEL: truth table, equations, when-then-else. You can see more detailed explanations of these in the ABEL-HDL on-line manual available by selecting "ABEL HDL Language" in the "Help" menu of the Synario text editor you used to enter your ABEL files. You should give this manual a quick scan.

Now, we will turn to the task of using ABEL module as sub-module in a larger design. To do this, lets go back to our four-bit adder from the past homework assignment. We are going to redo the assignment using equations in ABEL rather than a schematic. Open a new project and create a new ABEL source and enter the following:

MODULE fa

 interface (a, b, cin -> sum, cout);

TITLE 'full adder';

 a, b, cin pin;
 sum, cout pin istype 'com';

EQUATIONS

 sum = a $ b $ cin;       " & is for AND
 cout = a & b         " # is for OR
      # b & cin       " $ is for XOR
      # a & cin;      " ! is for NOT
                          " see manual for others and precedence

END
The equations derived from this specification from this are:
Equations:

sum = (  a & !b & !cin
      # !a &  b & !cin
      # !a & !b &  cin
      #  a &  b &  cin); 

cout = (a & b
       # b & cin
       # a & cin);
This exactly what we would expect. Now lets make a symbol that includes this ABEL file for the specification of its functionality. To do this lets begin by starting yet another new project with a schematic source. The schematic editor will start up with an empty sheet. We will now enter the top-level design of the four-bit adder and then link it to the full-adder ABEL code as a sub-module. Begin by selecting "New Block Symbol ..." from the "Add" menu. Enter the following to specify the full-adder sub-module:


After clicking on the "Run" button, you'll be able to place the shell of the full-adder module (note that we have not yet attached any functionality to this module). If the cursor does not change to let you place the module, you can always select it again by picking it out of the symbol library when you select "Symbol..." from the "Add" menu.

Construct a schematic diagram that looks like the following:


There are two new elements in this schematic. The down pointing arrow (to signify a connection to 0 or ground) and the flat top labeled VCC (to signify a connection to 1 or a high-voltage). The way you obtain these symbols is a bit strange. You add a net name to a wire that is precisely GND (or VCC), however, for the symbol to appear rather than just the name, the wire must be vertical and unconnected at the bottom (top) for GND (VCC). GND and VCC are really "Global Nets" in the Synario vocabulary, that is, they are predefined. By adding the net name GND or VCC to one of your wires, you are connecting it (by name) to logic 0 or 1, respectively. The reason to do this is that sometimes you may want a value permanently tied to 0 or 1. In this case, because you may just want to simulate all combinations of a0, a1, a2, a3 against a fixed value of [0, 0, 0, 1] for [b3, b2, b1, b0].

After you save your schematic, you'll notice that the project navigator window now shows that a sub-module of unknown type is being used in this project. It is now time to attach a source file to this sub-module definition. You can do that by selecting the sub-module in question (indicated by a question mark) in the "Sources" sub-window of the project navigator and then selecting "Import..." from the "Source" menu.


You can now select the ABEL file we previously defined for the full adder module. The question mark should disappear and the project navigator will look like this:


The next step is to select the top-level schematic and compile it to see what equations are derived from the fact that we've tied the b inputs to 0 and 1. The result is as follows:

Equations:

GND = (0);
VCC = (1);
These signify that we have only defined the value of two nets in this schematic (actually, they were defined globally, but we are using them in the schematic), GND and VCC.

We could now create a new "Verilog Test Fixture" source and simulate this design. Recall that we only have the a inputs, the b inputs have been tied to 0 or 1 and thus should not appear in our simulation test fixture. This is the same process as in the previous tutorial and will not repeat it here.

If we ever change our ABEL file for the full adder module, we need to make sure that the change is reflected in the schematics that may use it. This is especially the case when we change the inputs or outputs of the module and may need to add/remove connections to it in the schematic.

We have one more step to complete. We need to choose a target device with which to implement our four-bit adder. To do so, we select the virtual device and double-click on it. This causes the following window to pop-up:


We'll select the "Standard PLD" "E0320" whose logic diagram is attached at the end of this tutorial. The E0320 is a common PAL that allows us up to 10 inputs and 8 outputs. Each output function can have up to 8 product terms (any 8 product terms of up to 10 input variables) and there is no sharing of terms between outputs. The logic between the OR gate collecting the 8 product terms and the output will be explained later in the quarter. The project navigator window now reflects this choice and shows a whole new suite of options in the "Processes" sub-window. These include steps required to make the design fit onto the available resources (making sure each equation is no more than 8 product terms) which is called "fitting" and the process required to create the "fuse map" for the part. The "fuse map" is the set of instructions required by a PLD programmer so that it can break the connections that are not require in the part by this particular design. We won't concern ourselves with the details of the programming process but we do need to make sure our design fits into the part we selected.


If we now double-click on the pre-fit and post-fit equations we'll see the following results (note that the post-fit and pre-fit equations are the same because we did not have pre-fit equations with more than 8 product terms):

Equations:

cout = ( a3 & a2 & a1 & a0
       # a3 & a2 & a1 & cin);

s3 = (  a3 & !a2
     #  a3 & !a1
     #  a3 & !a0 & !cin
     # !a3 &  a2 & a1 & a0
     # !a3 &  a2 & a1 & cin);

s2 = (  a2 & !a1
     # !a2 &  a1 & a0
     # !a2 &  a1 & cin
     #  a2 & !a0 & !cin); 

s1 = ( !a1 &  a0
     # !a1 &  cin
     #  a1 & !a0 & !cin);

s0 = (  a0 &  cin
     # !a0 & !cin);
Note that the b inputs to not appear anywhere. The equations for cout shows that they have been taken into account, however. The cout output will be true when the a input is 15 or it is 14 and there is a carry-in. This is because the b inputs were tied to the value 1. Therefore, there is a carry out for 15+1+0, 15+1+1, and 14+1+1 just as we would have expected.

By double-clicking on "Chip Report" in the "Processes" sub-window, we can see how the pins of the chip will be assigned to our inputs and outputs and compare this against the logic diagram of the E0320. The chip report shows the following:

E0320

                         +---------\       /---------+
                         |          \     /          |
                         |           -----           |
                      a3 |  1                    20  | Vcc 
                         |                           |
                      a2 |  2                    19  | 
                         |                           |
                      a1 |  3                    18  | 
                         |                           |
                      a0 |  4                    17  | 
                         |                           |
                     cin |  5                    16  | s0 
                         |                           |
                         |  6                    15  | s1 
                         |                           |
                         |  7                    14  | s2 
                         |                           |
                         |  8                    13  | s3 
                         |                           |
                         |  9                    12  | cout 
                         |                           |
                     GND | 10                    11  | 
                         |                           |
                         |                           |
                         '---------------------------' 


E0320 Resource Allocations:
---------------------------------------------------------------------- 

        Device        | Resource  |   Design    |
       Resources      | Available | Requirement | Unused
======================|===========|=============|==============
                      |           |             |
Input Pins:           |           |             |
          Input:      |     10    |      5      |    5 ( 50 %)
Output Pins:          |           |             |
          In/Out:     |      8    |      5      |    3 ( 37 %)
          Output:     |      -    |      -      |    -
Buried Nodes:         |           |             |
          Input Reg:  |      -    |      -      |    -
          Pin Reg:    |      8    |      0      |    8 (100 %)
          Buried Reg: |      -    |      -      |    -


E0320 Product Terms Distribution:
-----------------------------------------------------------------------
            Signal               |    Pin   | Terms | Terms | Terms
             Name                | Assigned | Used  |  Max  | Unused
=================================|==========|=======|=======|=======
cout                             |   12     |   2   |   8   |   6
s3                               |   13     |   5   |   8   |   3
s2                               |   14     |   4   |   8   |   4
s1                               |   15     |   3   |   8   |   5
s0                               |   16     |   2   |   8   |   6
 
==== List of Inputs/Feedbacks ====

Signal Name                              | Pin      | Pin Type
=========================================|==========|=========
a3                                       |    1     | CLK/IN
a2                                       |    2     | INPUT
a1                                       |    3     | INPUT
a0                                       |    4     | INPUT
cin                                      |    5     | INPUT


E0320 Unused Resources:
--------------------------------------------------------------------- 

Pin    |  Pin   |   Product   | Flip-flop
Number |  Type  |   Terms     |   Type
=======|========|=============|==========
    6  |  INPUT |      -      |    - 
    7  |  INPUT |      -      |    - 
    8  |  INPUT |      -      |    - 
    9  |  INPUT |      -      |    - 
   11  |  INPUT |      -      |    - 
   17  |  BIDIR | NORMAL 8    |    D
   18  |  BIDIR | NORMAL 8    |    D
   19  |  BIDIR | NORMAL 8    |    D
Not all of this will make sense yet, but you should scan through this feedback and see what does make sense to you at this point. Had the design not fit because an equation required more than 8 product terms, we would now have to split some of our equations so that it could be made to fit. To do this, of course, we require more inputs and outputs and product terms. This process may also need to be iterated as we change schematics and try new decompositions.

You have now completed the Synario/ABEL tutorial.


Comments to: cse370-webmaster@cs.washington.edu (Last Update: )