MODULE adder24 
TITLE '24-bit adder' 
" 
"                               Notes 
"This design is a 24-bit adder with output registers.  It implements the  
"Lattice macro F3ADD in Abel macro's.  Propagate/generate are implemented 
"with simple Boolean equations.  Three levels are required.  The challenge 
"in going beyond 24 bits is the 16-input limit imposed by the Lattice  
"architecture on the number of inputs to the equation for the highest order  
"carry in.  Nodes are preserved to guide the fitter in keeping the desired  
"three levels:  one level to calculate the propagate/generate, a second level  
"to calculate the carries into the adders, and finally a third level to do  
"the addition and supply the setup time for the registers.  Lattime 3.0  
"reports that an ispLSI2096-125 can do this 24-bit add at 46.3MHz and an 
"ispLSI2128-100 at 37.0MHz.  Additional test vectors can easily be added  
"at the end of this source file to further confirm correct operation. 
 
DECLARATIONS 
 
"Constant declarations 
        X, C, Z, H, L = .X., .C., .Z., 1, 0; 
 
"Lattice property declarations 
        pLSI PROPERTY 'part ispLSI2096-125LQ128'; 
        pLSI PROPERTY 'isp on';         " Reserve the isp pins 
        pLSI PROPERTY 'clk ck clk0';    " Assign clk0 pin to the system clock 
        pLSI PROPERTY 'output_form SIM';" Output the simulation data 
         
        pLSI PROPERTY 'preserve p2_n';  " Tell the fitter which nets I want 
        pLSI PROPERTY 'preserve p5_n';  "    preserved during logic reduction. 
        pLSI PROPERTY 'preserve p8_n';  "    Thus, the logic is broken into 
        pLSI PROPERTY 'preserve p11_n'; "    3 levels just the way I want it. 
        pLSI PROPERTY 'preserve p14_n'; 
        pLSI PROPERTY 'preserve p17_n'; " These are the active-low propagates. 
        pLSI PROPERTY 'preserve p20_n'; 
        pLSI PROPERTY 'preserve g2';    " Next are the active-high generates. 
        pLSI PROPERTY 'preserve g5'; 
        pLSI PROPERTY 'preserve g8'; 
        pLSI PROPERTY 'preserve g11'; 
        pLSI PROPERTY 'preserve g14'; 
        pLSI PROPERTY 'preserve g17'; 
        pLSI PROPERTY 'preserve g20'; 
        pLSI PROPERTY 'preserve cin3';  " Next are the carry-in's, whose 
        pLSI PROPERTY 'preserve cin6';  "    equations form the 2nd level of 
        pLSI PROPERTY 'preserve cin9';  "    logic. 
        pLSI PROPERTY 'preserve cin12';  
        pLSI PROPERTY 'preserve cin15'; 
        pLSI PROPERTY 'preserve cin18'; 
        pLSI PROPERTY 'preserve cin21'; 
        pLSI PROPERTY 'LXOR2 q_d0';     " Tell the fitter that I want the 
        pLSI PROPERTY 'LXOR2 q_d1';     "    2-input XOR's used at the inputs 
        pLSI PROPERTY 'LXOR2 q_d2';     "    to the D-flipflops in the 
        pLSI PROPERTY 'LXOR2 q_d3';     "    in the macrocells. 
        pLSI PROPERTY 'LXOR2 q_d4'; 
        pLSI PROPERTY 'LXOR2 q_d5'; 
        pLSI PROPERTY 'LXOR2 q_d6'; 
        pLSI PROPERTY 'LXOR2 q_d7'; 
        pLSI PROPERTY 'LXOR2 q_d8'; 
        pLSI PROPERTY 'LXOR2 q_d9'; 
        pLSI PROPERTY 'LXOR2 q_d10'; 
        pLSI PROPERTY 'LXOR2 q_d11'; 
        pLSI PROPERTY 'LXOR2 q_d12'; 
        pLSI PROPERTY 'LXOR2 q_d13'; 
        pLSI PROPERTY 'LXOR2 q_d14'; 
        pLSI PROPERTY 'LXOR2 q_d15'; 
        pLSI PROPERTY 'LXOR2 q_d16'; 
        pLSI PROPERTY 'LXOR2 q_d17'; 
        pLSI PROPERTY 'LXOR2 q_d18'; 
        pLSI PROPERTY 'LXOR2 q_d19'; 
        pLSI PROPERTY 'LXOR2 q_d20'; 
        pLSI PROPERTY 'LXOR2 q_d21'; 
        pLSI PROPERTY 'LXOR2 q_d22'; 
        pLSI PROPERTY 'LXOR2 q_d23'; 
        pLSI PROPERTY 'ecp q_d0  pa_q_d0'; " End-point of time-critical path 
        pLSI PROPERTY 'ecp q_d1  pa_q_d1'; 
        pLSI PROPERTY 'ecp q_d2  pa_q_d2'; 
        pLSI PROPERTY 'ecp q_d3  pa_q_d3'; 
        pLSI PROPERTY 'ecp q_d4  pa_q_d4'; 
        pLSI PROPERTY 'ecp q_d5  pa_q_d5'; 
        pLSI PROPERTY 'ecp q_d6  pa_q_d6'; 
        pLSI PROPERTY 'ecp q_d7  pa_q_d7'; 
        pLSI PROPERTY 'ecp q_d8  pa_q_d8'; 
        pLSI PROPERTY 'ecp q_d9  pa_q_d9'; 
        pLSI PROPERTY 'ecp q_d10 pa_q_d10'; 
        pLSI PROPERTY 'ecp q_d11 pa_q_d11'; 
        pLSI PROPERTY 'ecp q_d12 pa_q_d12'; 
        pLSI PROPERTY 'ecp q_d13 pa_q_d13'; 
        pLSI PROPERTY 'ecp q_d14 pa_q_d14'; 
        pLSI PROPERTY 'ecp q_d15 pa_q_d15'; 
        pLSI PROPERTY 'ecp q_d16 pa_q_d16'; 
        pLSI PROPERTY 'ecp q_d17 pa_q_d17'; 
        pLSI PROPERTY 'ecp q_d18 pa_q_d18'; 
        pLSI PROPERTY 'ecp q_d19 pa_q_d19'; 
        pLSI PROPERTY 'ecp q_d20 pa_q_d20'; 
        pLSI PROPERTY 'ecp q_d21 pa_q_d21'; 
        pLSI PROPERTY 'ecp q_d22 pa_q_d22'; 
        pLSI PROPERTY 'ecp q_d23 pa_q_d23'; 
        pLSI PROPERTY 'CRIT q0';        " Can bypass the output routing pool, 
        pLSI PROPERTY 'CRIT q1';        "    since the pins are unlocked. 
        pLSI PROPERTY 'CRIT q2'; 
        pLSI PROPERTY 'CRIT q3'; 
        pLSI PROPERTY 'CRIT q4'; 
        pLSI PROPERTY 'CRIT q5'; 
        pLSI PROPERTY 'CRIT q6'; 
        pLSI PROPERTY 'CRIT q7'; 
        pLSI PROPERTY 'CRIT q8'; 
        pLSI PROPERTY 'CRIT q9'; 
        pLSI PROPERTY 'CRIT q10'; 
        pLSI PROPERTY 'CRIT q11'; 
        pLSI PROPERTY 'CRIT q12'; 
        pLSI PROPERTY 'CRIT q13'; 
        pLSI PROPERTY 'CRIT q14'; 
        pLSI PROPERTY 'CRIT q15'; 
        pLSI PROPERTY 'CRIT q16'; 
        pLSI PROPERTY 'CRIT q17'; 
        pLSI PROPERTY 'CRIT q18'; 
        pLSI PROPERTY 'CRIT q19'; 
        pLSI PROPERTY 'CRIT q20'; 
        pLSI PROPERTY 'CRIT q21'; 
        pLSI PROPERTY 'CRIT q22'; 
        pLSI PROPERTY 'CRIT q23'; 
         
"Input declarations 
        ck              pin    ;        " The sum is clocked into a register. 
        cin0            pin    ;        " This is the 24-bit adder's carry-in.  
        a0              pin    ;        " One set of 24 bits to be added 
        a1              pin    ; 
        a2              pin    ; 
        a3              pin    ; 
        a4              pin    ; 
        a5              pin    ; 
        a6              pin    ; 
        a7              pin    ; 
        a8              pin    ; 
        a9              pin    ; 
        a10             pin    ; 
        a11             pin    ; 
        a12             pin    ; 
        a13             pin    ; 
        a14             pin    ; 
        a15             pin    ; 
        a16             pin    ; 
        a17             pin    ; 
        a18             pin    ; 
        a19             pin    ; 
        a20             pin    ; 
        a21             pin    ; 
        a22             pin    ; 
        a23             pin    ; 
        b0              pin    ;        " The other 24 bits to be added 
        b1              pin    ; 
        b2              pin    ; 
        b3              pin    ; 
        b4              pin    ; 
        b5              pin    ; 
        b6              pin    ; 
        b7              pin    ; 
        b8              pin    ; 
        b9              pin    ; 
        b10             pin    ; 
        b11             pin    ; 
        b12             pin    ; 
        b13             pin    ; 
        b14             pin    ; 
        b15             pin    ; 
        b16             pin    ; 
        b17             pin    ; 
        b18             pin    ; 
        b19             pin    ; 
        b20             pin    ; 
        b21             pin    ; 
        b22             pin    ; 
        b23             pin    ; 
"Output declarations     
        q0              pin     istype 'com'; 
        q1              pin     istype 'com'; 
        q2              pin     istype 'com'; 
        q3              pin     istype 'com'; 
        q4              pin     istype 'com'; 
        q5              pin     istype 'com'; 
        q6              pin     istype 'com'; 
        q7              pin     istype 'com'; 
        q8              pin     istype 'com'; 
        q9              pin     istype 'com'; 
        q10             pin     istype 'com'; 
        q11             pin     istype 'com'; 
        q12             pin     istype 'com'; 
        q13             pin     istype 'com'; 
        q14             pin     istype 'com'; 
        q15             pin     istype 'com'; 
        q16             pin     istype 'com'; 
        q17             pin     istype 'com'; 
        q18             pin     istype 'com'; 
        q19             pin     istype 'com'; 
        q20             pin     istype 'com'; 
        q21             pin     istype 'com'; 
        q22             pin     istype 'com'; 
        q23             pin     istype 'com'; 
"Node declarations 
        p2_n,                           " The active-low propagates 
        p5_n, 
        p8_n, 
        p11_n, 
        p14_n, 
        p17_n, 
        p20_n, 
        g2,                             " The active-high generates 
        g5, 
        g8, 
        g11, 
        g14, 
        g17, 
        g20, 
        cin3,                           " The carry-in's 
        cin6, 
        cin9, 
        cin12, 
        cin15, 
        cin18, 
        cin21           node    istype 'com';       
        q_d23..q_d0     node    istype 'com, XOR';    " Tell Abel:  keep XOR's      
        q_q23..q_q0     node    istype 'reg_d, keep'; " Don't reduce out q_q's 
"Set declarations used with the test vectors 
        A       = [a23..a0]; 
        B       = [b23..b0]; 
        Q       = [q23..q0]; 
"Macro declaration to implement most of the Lattice F3ADD macro (not the XOR)  
        add0_mac MACRO (cin, b0) 
                {          (?cin & !?b0    #    !?cin & ?b0)}; 
        add1_mac MACRO (cin, a0, b0, b1) 
                {          (          !?a0 &        !?b0 &  ?b1  
                            # !?cin & !?a0 &                ?b1  
                            # !?cin &               !?b0 &  ?b1 
                            #          ?a0 &         ?b0 & !?b1 
                            #  ?cin &  ?a0 &               !?b1 
                            #  ?cin &                ?b0 & !?b1)}; 
        add2_mac MACRO (cin, a0, b0, a1, b1, b2) 
                {          (                 !?a1 &        !?b1 &  ?b2 
                            #         !?a0 &        !?b0 & !?b1 &  ?b2       
                            # !?cin & !?a0 &               !?b1 &  ?b2       
                            # !?cin &               !?b0 & !?b1 &  ?b2       
                            #         !?a0 & !?a1 & !?b0 &         ?b2       
                            # !?cin & !?a0 & !?a1 &                ?b2       
                            # !?cin &        !?a1 & !?b0 &         ?b2       
                            #                 ?a1 &         ?b1 & !?b2       
                            #          ?a0 &         ?b0 &  ?b1 & !?b2       
                            #  ?cin &  ?a0 &                ?b1 & !?b2       
                            #  ?cin &                ?b0 &  ?b1 & !?b2       
                            #          ?a0 &  ?a1 &  ?b0 &        !?b2       
                            #  ?cin &  ?a0 &  ?a1 &               !?b2       
                            #  ?cin &         ?a1 &  ?b0 &        !?b2)}; 
        prop_mac MACRO (a0, a1, a2, b0, b1, b2)  
                {!?a0 & !?b0 # !?a1 & !?b1 # !?a2 & !?b2}; 
        genr_mac MACRO (a0, a1, a2, b0, b1, b2) 
                {  ?a2 & ?b2 
                 # ?a2 & ?a1 & ?b1        
                 # ?a2 & ?a1 & ?a0 & ?b0 
                 # ?a2 & ?b1 & ?a0 & ?b0 
                 # ?b2 & ?a1 & ?b1        
                 # ?b2 & ?a1 & ?a0 & ?b0 
                 # ?b2 & ?b1 & ?a0 & ?b0}; 
 
EQUATIONS 
 
p2_n    = prop_mac (a0,  a1,  a2,  b0,  b1,  b2); " Propagates and generates 
p5_n    = prop_mac (a3,  a4,  a5,  b3,  b4,  b5); "    form the first level 
p8_n    = prop_mac (a6,  a7,  a8,  b6,  b7,  b8); "    of logic. 
p11_n   = prop_mac (a9,  a10, a11, b9,  b10, b11); 
p14_n   = prop_mac (a12, a13, a14, b12, b13, b14); 
p17_n   = prop_mac (a15, a16, a17, b15, b16, b17); 
p20_n   = prop_mac (a18, a19, a20, b18, b19, b20); 
g2      = genr_mac (a0,  a1,  a2,  b0,  b1,  b2); 
g5      = genr_mac (a3,  a4,  a5,  b3,  b4,  b5); 
g8      = genr_mac (a6,  a7,  a8,  b6,  b7,  b8); 
g11     = genr_mac (a9,  a10, a11, b9,  b10, b11); 
g14     = genr_mac (a12, a13, a14, b12, b13, b14); 
g17     = genr_mac (a15, a16, a17, b15, b16, b17); 
g20     = genr_mac (a18, a19, a20, b18, b19, b20); 
cin3    =  g2                                     " Carry-in's form the 
        # !p2_n  &  cin0;                         "    2nd level. 
cin6    =  g5 
        # !p5_n  &  g2 
        # !p5_n  & !p2_n  &  cin0; 
cin9    =  g8 
        # !p8_n  &  g5 
        # !p8_n  & !p5_n  &  g2 
        # !p8_n  & !p5_n  & !p2_n  &  cin0; 
cin12   =  g11 
        # !p11_n &  g8 
        # !p11_n & !p8_n  &  g5 
        # !p11_n & !p8_n  & !p5_n  &  g2 
        # !p11_n & !p8_n  & !p5_n  & !p2_n  &  cin0; 
cin15   =  g14 
        # !p14_n &  g11 
        # !p14_n & !p11_n &  g8 
        # !p14_n & !p11_n & !p8_n  &  g5 
        # !p14_n & !p11_n & !p8_n  & !p5_n  &  g2 
        # !p14_n & !p11_n & !p8_n  & !p5_n  & !p2_n &  cin0; 
cin18   =  g17 
        # !p17_n &  g14 
        # !p17_n & !p14_n &  g11 
        # !p17_n & !p14_n & !p11_n &  g8 
        # !p17_n & !p14_n & !p11_n & !p8_n  &  g5 
        # !p17_n & !p14_n & !p11_n & !p8_n  & !p5_n &  g2 
        # !p17_n & !p14_n & !p11_n & !p8_n  & !p5_n & !p2_n &  cin0; 
cin21   =  g20 
        # !p20_n &  g17 
        # !p20_n & !p17_n &  g14 
        # !p20_n & !p17_n & !p14_n &  g11 
        # !p20_n & !p17_n & !p14_n & !p11_n &  g8 
        # !p20_n & !p17_n & !p14_n & !p11_n & !p8_n &  g5 
        # !p20_n & !p17_n & !p14_n & !p11_n & !p8_n & !p5_n &  g2 
        # !p20_n & !p17_n & !p14_n & !p11_n & !p8_n & !p5_n & !p2_n & cin0; 
q_d0    = a0  $ add0_mac (cin0,  b0);             " Use the carry-in's in the 
q_d1    = a1  $ add1_mac (cin0,  a0,  b0,  b1);   "    third level of logic. 
q_d2    = a2  $ add2_mac (cin0,  a0,  b0,  a1,  b1,  b2);  
q_d3    = a3  $ add0_mac (cin3,  b3);  
q_d4    = a4  $ add1_mac (cin3,  a3,  b3,  b4);  
q_d5    = a5  $ add2_mac (cin3,  a3,  b3,  a4,  b4,  b5);  
q_d6    = a6  $ add0_mac (cin6,  b6);  
q_d7    = a7  $ add1_mac (cin6,  a6,  b6,  b7);  
q_d8    = a8  $ add2_mac (cin6,  a6,  b6,  a7,  b7,  b8);  
q_d9    = a9  $ add0_mac (cin9,  b9);  
q_d10   = a10 $ add1_mac (cin9,  a9,  b9,  b10);  
q_d11   = a11 $ add2_mac (cin9,  a9,  b9,  a10, b10, b11);  
q_d12   = a12 $ add0_mac (cin12, b12);  
q_d13   = a13 $ add1_mac (cin12, a12, b12, b13);  
q_d14   = a14 $ add2_mac (cin12, a12, b12, a13, b13, b14);  
q_d15   = a15 $ add0_mac (cin15, b15);  
q_d16   = a16 $ add1_mac (cin15, a15, b15, b16);  
q_d17   = a17 $ add2_mac (cin15, a15, b15, a16, b16, b17);  
q_d18   = a18 $ add0_mac (cin18, b18);  
q_d19   = a19 $ add1_mac (cin18, a18, b18, b19);  
q_d20   = a20 $ add2_mac (cin18, a18, b18, a19, b19, b20);  
q_d21   = a21 $ add0_mac (cin21, b21);  
q_d22   = a22 $ add1_mac (cin21, a21, b21, b22);  
q_d23   = a23 $ add2_mac (cin21, a21, b21, a22, b22, b23); 
[q_q23..q_q0].d   = [q_d23..q_d0];                " Assign the D-inputs 
[q_q23..q_q0].clk =  ck;                          " Assign macrocells' clock 
[q23..q0]         = [q_q23..q_q0].q;              " Assign flipflop outputs 
 
TEST_VECTORS 
([ck, cin0,         A,         B] -> [        Q]); 
 [ C,   L ,   2189753,   7116568] -> [  9306321];  
 [ C,   L ,  15189753,         7] -> [ 15189760]; 
 [ C,   L ,   2306525,  13693475] -> [ 16000000]; 
 [ C,   L ,   2306525,  14470691] -> [        0]; " sum is 2**16 
 [ C,   L ,   2306525,  14470696] -> [        5]; " sum is 2**16 + 5 
 [ C,   H ,   2306524,  14470696] -> [        5]; " sum is still 2**16 + 5 
 [ C,   L ,  16777216,         0] -> [        0]; " (2**16) + 0   
 [ C,   L ,         0,         0] -> [        0];  
 [ C,   H ,         0,         0] -> [        1];  
 [ C,   L ,  16777216,  16777216] -> [        0]; " (2**16) + (2**16)   
 [ C,   L ,  16777216,         8] -> [        8]; " ((2**16) + 8) rollover   
 [ C,   L ,  16777215,         1] -> [        0]; " ((2**16 - 1) + 1)  
 [ C,   L ,  14777215,  15436787] -> [ 13436786]; " big rollover 
  
 [ C,   L ,   7116568,   2189753] -> [  9306321]; " This block demonstrates 
 [ C,   H ,   7116568,   2189753] -> [  9306322]; "   commutative property 
 [ C,   L ,         7,  15189753] -> [ 15189760]; 
 [ C,   L ,  13693475,   2306525] -> [ 16000000]; 
 [ C,   L ,  14470691,   2306525] -> [        0]; " sum is 2**16 
 [ C,   L ,  14470696,   2306525] -> [        5]; " sum is 2**16 + 5 
 [ C,   L ,  16777216,  16777216] -> [        0]; " (2**16) + (2**16)   
 [ C,   H ,  14470696,   2306524] -> [        5]; " sum is still 2**16 + 5 
 [ C,   L ,         0,         0] -> [        0];  
 [ C,   H ,         0,         0] -> [        1];  
 [ C,   L ,         0,  16777216] -> [        0]; " 0 + (2**16)  
 [ C,   L ,         8,  16777216] -> [        8]; " (8 + (2**16)) rollover 
 [ C,   L ,         1,  16777215] -> [        0]; " (1 + (2**16 - 1)) 
 [ C,   L ,  15436787,  14777215] -> [ 13436786]; " big rollover 
 
END adder24;
