FOUR-BIT UNIVERSAL SHIFT REGISTER USING ABEL


This assignment to construct a four-bit universal shift register was given to us last qtr. It demonstrates very effectively how ABEL can be used to construct a hierarchical design. We will walk through this example by first stating the problem statement and then following the procedures for the hierarchical design that we have discussed so far.

PROBLEM STATEMENT

Our goal is to design a 4-bit universal shift register. It should implement the following functions specified by it's S2, S1, S0 control inputs: (000) Hold, (001) Circular Right Shift, (010) Circular Shift Left, (011) Logic Shift Right, (100) Logic Shift Left, (101) Arithmetic Shift Right, (110) Arithmetic Shift Left, (111) Parallel Load. Your shift register sub-module should consist of a cell with a single flip-flop and three inputs(DI, SR, and SL). There should also be two control inputs: S0 and S1. When S0 and S1 are (11), DI should be loaded into the flip-flop, for (01) SL should be loaded in, for (10) SR should be loaded in, and for (00) the flip-flop should hold it's current state.

PROBLEM DESIGN

We will implement the design by constructing three ABEL modules namely flipflop, shsubmod and shiftreg.

flipflop

This is the lower most module with inputs D, clk and clr and output Q which is a registered output. This module sets the clk for the Q register and loads the input D into the flip-flop Q.

shsubmod

This sub-module refrences the lower-level module flip-flop and has inputs DI, SR, SL, S0, S1, clr, clk and output OUT. When S0 and S1 are (11), DI is loaded into the flip-flop, when they are (01) SL is loaded in, for (10) SR is loaded in, for (00) the flip-flop holds it's current state i.e. the input of the flip-flop equals its output.

shiftreg

This is the top-most module that refrences shsubmod which in turn refrences flipflop. This module has inputs S2, S1, S0, D0, D1, D2, D3, clr, clk and outputs Q3, Q2, Q1, Q0. It creates 4 instances of the shift-register sub-module performs the Hold, Circular Right Shift, Circular Shift Left, Logic Shift Right, Logic Shift Left, Arithmetic Shift Right, Arithmetic Shift Left and Parallel Load when the control inputs S2, S1, S0 are 000, 001, 010, 011, 100, 101, 110 and 111 respectively.

BUILDING THE LOWER LEVEL ABEL MODULE flipflop

This ABEL module looks much similar to the ABEL modules that we have seen so far. It has the interface declaration for it's input and output signals.

MODULE flipflop

        interface(D,clr,clk -> Q);

TITLE 'flipflop'

"Inputs
 D,clr,clk      pin;

"Outputs
 Q              pin istype 'reg, buffer';

EQUATIONS

        Q.clk = clk;
        Q := D & !clr;


END

Since the lower-level module has the interface declaration for it's inputs and outputs, we must therefore make sure that the interface declaration for this module in shsubmod exactly matches the interface declaration here.

BUILDING THE LOWER LEVEL ABEL MODULE shsubmod

Although this module refrences the lower-level module flipflop, it is still lower-level because it is in turn refrenced by shiftreg. Here is the code:

MODULE shsubmod

        interface(DI,SR,SL,S0,S1,clr,clk -> OUT);

TITLE 'Shift register submodule'

"Inputs
  DI,SR,SL,S0,S1,clr,clk                pin;

"Outputs
  OUT                           pin istype 'com';

"Aliases
  S = [S1,S0];


flipflop interface(D,clr,clk -> Q);
flip functional_block flipflop;

EQUATIONS
   flip.clk = clk;
   flip.clr = clr;

   WHEN (S == 0) THEN 
        flip.D = flip.Q;        
   ELSE WHEN (S == 1) THEN 
        flip.D = SR; 
   ELSE WHEN (S == 2) THEN
        flip.D = SL;
   ELSE WHEN (S == 3) THEN
        flip.D = DI;
   OUT = flip.Q;
        

END

Notice the decalaration for the flipflop module. The interface declaration here exactly corresponds with the interface declaration in the flipflop module. Notice also the use of the functional_block statemet to instantiate the module flipflop and the use of dot extension to refer to inputs and outputs of the instance of this module i.e flip is an instance of the module flipflop and flip.D, flip.clk, flip.clr, and flip.Q refers to the inputs D, clk, clr and output Q of this module. We assign the values to the inputs of lower-level module from the module in which it is instantiated. However, as stated earlier if we have declared default values for the inputs in the lower-level module, it is not necessary to list those inputs in the interface declaration for the lower-level module in the top-level module.

BUILDING THE TOP LEVEL ABEL MODULE shiftreg

This is the top-level module that implements the four-bit universal shift register. To do this, it refrences modules shsubmod and flipflop. Shown below is the ABEL code:

MODULE shiftreg
        
        interface(S2,S1,S0,D0,D1,D2,D3,clr,clk -> Q3,Q2,Q1,Q0);
        
TITLE '4 bit shift register'
"Inputs
 S2,S1,S0,D0,D1,D2,D3,clr,clk           pin;

"Outputs
 Q3,Q2,Q1,Q0            pin istype 'com';

"Aliases
  S = [S2,S1,S0];


shsubmod interface(DI,SR,SL,S0,S1,clr,clk -> OUT);
module0..module3 functional_block shsubmod;

EQUATIONS

        module0.clk = clk;
        module0.clr = clr;
        module1.clk = clk;
        module1.clr = clr;
        module2.clk = clk;
        module2.clr = clr;
        module3.clk = clk;
        module3.clr = clr;
        WHEN (S == 0) THEN {
                module0.S0 = 0;
                module0.S1 = 0;
                module1.S0 = 0;
                module1.S1 = 0;
                module2.S0 = 0;
                module2.S1 = 0;
                module3.S0 = 0;
                module3.S1 = 0;
        }
        ELSE WHEN (S == 1) THEN {
                module0.SR = module1.OUT;
                module1.SR = module2.OUT;
                module2.SR = module3.OUT;
                module3.SR = module0.OUT;
                module0.S0 = 1;
                module0.S1 = 0;
                module1.S0 = 1;
                module1.S1 = 0;
                module2.S0 = 1;
                module2.S1 = 0;
                module3.S0 = 1;
                module3.S1 = 0;
                
                }
        ELSE WHEN (S == 2) THEN {
                module0.SL = module3.OUT;
                module1.SL = module0.OUT;
                module2.SL = module1.OUT;
                module3.SL = module2.OUT;
                module0.S0 = 0;
                module0.S1 = 1;
                module1.S0 = 0;
                module1.S1 = 1;
                module2.S0 = 0;
                module2.S1 = 1;
                module3.S0 = 0;
                module3.S1 = 1;
        }
        ELSE WHEN (S == 3) THEN {
                module0.SR = module1.OUT;
                module1.SR = module2.OUT;
                module2.SR = module3.OUT;
                module3.SR = 0;
                module0.S0 = 1;
                module0.S1 = 0;
                module1.S0 = 1;
                module1.S1 = 0;
                module2.S0 = 1;
                module2.S1 = 0;
                module3.S0 = 1;
                module3.S1 = 0;
        }
        ELSE WHEN (S == 4) THEN {
                module0.SL = 0;
                module1.SL = module0.OUT;
                module2.SL = module1.OUT;
                module3.SL = module2.OUT;
                module0.S0 = 0;
                module0.S1 = 1;
                module1.S0 = 0;
                module1.S1 = 1;
                module2.S0 = 0;
                module2.S1 = 1;
                module3.S0 = 0;
                module3.S1 = 1;
                
        }
        ELSE WHEN (S == 5) THEN {
                module0.SR = module1.OUT;
                module1.SR = module2.OUT;
                module2.SR = module3.OUT;
                module3.SR = module3.OUT;
                module0.S0 = 1;
                module0.S1 = 0;
                module1.S0 = 1;
                module1.S1 = 0;
                module2.S0 = 1;
                module2.S1 = 0;
                module3.S0 = 1;
                module3.S1 = 0;
        }
        ELSE WHEN (S == 6) THEN {
                module0.SL = 0;
                module1.SL = module0.OUT;
                module2.SL = module1.OUT;
                module3.SL = module2.OUT;
                module0.S0 = 0;
                module0.S1 = 1;
                module1.S0 = 0;
                module1.S1 = 1;
                module2.S0 = 0;
                module2.S1 = 1;
                module3.S0 = 0;
                module3.S1 = 1;
        }
        ELSE WHEN (S == 7) THEN {
                module0.DI = D0;
                module1.DI = D1;
                module2.DI = D2;
                module3.DI = D3;
                module0.S0 = 1;
                module0.S1 = 1;
                module1.S0 = 1;
                module1.S1 = 1;
                module2.S0 = 1;
                module2.S1 = 1;
                module3.S0 = 1;
                module3.S1 = 1;
        }
        
        Q0 = module0.OUT;
        Q1 = module1.OUT;
        Q2 = module2.OUT;
        Q3 = module3.OUT;
  

END

Notice in the above code, four instances of the shsubmod module0..module3 has been declared using the functional_block statement and the range operator (..). These instances are then used to refer to the inputs and outputs of the lower-level module shsubmod

Having created our design we can now simulate the design by writing the test fixture and then simulate it using the functional simulator.