-- Model Name : Cone Model -- Author : Zainalabedin Navabi -- Last Updated : 09 / 15 / 1996 -- This document is © copyrighted by the Author.

    
    
    USE STD.TEXTIO.ALL;
    PACKAGE dg_utils IS
        TYPE cbit IS ('N', '0', '1', 'P');
        TYPE cbit_2d IS ARRAY (cbit,cbit) OF cbit;
        TYPE cbit_1d IS ARRAY (cbit) OF cbit;
        TYPE cbit_vector IS ARRAY (NATURAL RANGE <>) OF cbit;
        
        FUNCTION resolve (a:cbit_vector) RETURN cbit;
        SUBTYPE node IS resolve cbit;
        FUNCTION "NAND" (a,b :cbit) RETURN cbit;
        FUNCTION "AND" (a,b :cbit) RETURN cbit;
        FUNCTION "NOT" (a :cbit) RETURN cbit;
        PROCEDURE reporting (CONSTANT i : INTEGER);
    END dg_utils;
    --
    PACKAGE BODY dg_utils IS
        FUNCTION "NAND" (a,b: cbit) RETURN cbit IS
            VARIABLE result :cbit;
        BEGIN
            IF a='1' AND b='1' THEN
                result :='0';
            ELSE
                result :='1';
            END IF;
            RETURN result;
        END "NAND";
    
        FUNCTION "NOT" (a: cbit) RETURN cbit IS
            VARIABLE result :cbit;
        BEGIN
            IF a='1' THEN
                result :='0';
            ELSE
                result :='1';
            END IF;
            RETURN result;
        END "NOT";
    
        FUNCTION "AND" (a,b: cbit) RETURN cbit IS
            VARIABLE result :cbit;
        BEGIN
            IF a='1' AND b='1' THEN
                result :='1';
            ELSE
                result :='0';
            END IF;
            RETURN result;
        END "AND";
    
        FUNCTION resolve (a :cbit_vector) RETURN cbit IS
            VARIABLE result : cbit := 'N';
        BEGIN
            FOR i IN a'RANGE LOOP
                IF a(i) = 'P' THEN
                    result := 'P';
                    EXIT;
                ELSIF a(i) = '1' THEN
                    result := '1';
                ELSIF a(i) = '0' THEN
                    result := '0';
                END IF;
            END LOOP;
            RETURN result;
        END resolve;
    
        PROCEDURE reporting (CONSTANT i : INTEGER) IS
          FILE cones : TEXT OPEN APPEND_MODE IS "cone.dat";
          VARIABLE l : LINE;
          CONSTANT s1 : STRING := "Gate number: ";
          CONSTANT s2 : STRING := " is part of cone triggered at: ";
        BEGIN
          WRITE (l, s1);
          WRITE (l, i);
          WRITE (l, s2);
          WRITE (l, NOW, RIGHT, 8, NS);
          WRITELINE (cones, l);
        END;
    END dg_utils;
    
    






    
    USE WORK.dg_utils.ALL;
    ENTITY nand2 IS
        GENERIC (id :INTEGER; tplh, tphl :TIME);
        PORT (a,b,c :INOUT node);
    END nand2;
    
    ARCHITECTURE cone OF nand2 IS
    BEGIN
      a <= 'N';
      b <= 'N';
      c <= 'N';
      PROCESS
      BEGIN
        IF (a'EVENT OR b'EVENT) AND (a /= 'P') AND (b /= 'P') THEN
          c <= a NAND b;
          WAIT FOR id * 1 FS;
        ELSIF c'EVENT AND c = 'P' THEN
          a <= 'P', 'N' AFTER 1 FS;
          b <= 'P', 'N' AFTER 1 FS;
          WAIT FOR id * 1 FS;
          reporting (id);
        END IF;
        WAIT ON a, b, c;
      END PROCESS;
    END cone;
    
    






    
    USE WORK.dg_utils.ALL;
    ENTITY fulladder IS
        PORT (a, b, c, s, co : INOUT node);
    END fulladder;
    
    ARCHITECTURE dg_nand OF fulladder IS
      COMPONENT nand2 PORT (a,b,c :INOUT node); END COMPONENT;
      SIGNAL im1,im2,im3,im4,im5,im6,im7,im8,im9 : node;
      FOR ALL : nand2 USE ENTITY WORK.nand2(cone) GENERIC MAP (0, 4 NS, 5 NS);
    BEGIN
      g01: nand2 PORT MAP (a,b,im1);
      g02: nand2 PORT MAP (a,im1,im2);
      g03: nand2 PORT MAP (im1,b,im3);
      g04: nand2 PORT MAP (im2,im3,im4);
      g05: nand2 PORT MAP (im4,c,im5);
      g06: nand2 PORT MAP (im4,im5,im6);
      g07: nand2 PORT MAP (im5,c,im7);
      g08: nand2 PORT MAP (im6,im7,s);
      g09: nand2 PORT MAP (a,b,im8);
      g10: nand2 PORT MAP (im4,c,im9);
      g11: nand2 PORT MAP (im9,im8,co);
    END dg_nand;
    
    USE WORK.dg_utils.ALL;
    CONFIGURATION test1 OF fulladder IS
        FOR dg_nand
            FOR g01:nand2
                GENERIC MAP (id => 1);
            END FOR;
            FOR g02:nand2
                GENERIC MAP (id => 2);
            END FOR;
            FOR g03:nand2
                GENERIC MAP (id => 3);
            END FOR;
            FOR g04:nand2
                GENERIC MAP (id => 4);
            END FOR;
            FOR g05:nand2
                GENERIC MAP (id => 5);
            END FOR;
            FOR g06:nand2
                GENERIC MAP (id => 6);
            END FOR;
            FOR g07:nand2
                GENERIC MAP (id => 7);
            END FOR;
            FOR g08:nand2
                GENERIC MAP (id => 8);
            END FOR;
            FOR g09:nand2
                GENERIC MAP (id => 9);
            END FOR;
            FOR g10:nand2
                GENERIC MAP (id => 10);
            END FOR;
            FOR g11:nand2
                GENERIC MAP (id => 11);
            END FOR;
        END FOR;
    END test1;
    
    






    
    
    USE WORK.dg_utils.ALL;
    ENTITY cone_test_bench IS
    END cone_test_bench;
    
    ARCHITECTURE input_output OF cone_test_bench IS
        COMPONENT fulladder PORT (a, b, c, s, co :INOUT node);
        END COMPONENT;
        FOR d1 : fulladder USE CONFIGURATION WORK.test1;
        SIGNAL a, b, c, s, co : node;
    
    BEGIN
        d1: fulladder PORT MAP (a,b,c, s, co);
        a1: a <= '0' AFTER 0100 NS, '1' AFTER 0200 NS, '0' AFTER 0300 NS,
                 '1' AFTER 0400 NS, '0' AFTER 0500 NS, '1' AFTER 0600 NS,
                 'N' AFTER 2100 NS,
                 '0' AFTER 3000 NS, '1' AFTER 3100 NS,
                 'N' AFTER 3500 NS;
    
        b1: b <= '0' AFTER 0200 NS, '1' AFTER 0400 NS, '0' AFTER 0600 NS,
                 '1' AFTER 0800 NS, '0' AFTER 1000 NS, '1' AFTER 1200 NS,
                 'N' AFTER 2100 NS,
                 '0' AFTER 3000 NS, '1' AFTER 3200 NS,
                 'N' AFTER 3500 NS;
    
        c1: c <= '0' AFTER 0300 NS, '1' AFTER 0600 NS, '0' AFTER 0900 NS,
                 '1' AFTER 1200 NS, '0' AFTER 1500 NS, '1' AFTER 1800 NS,
                 'N' AFTER 2100 NS,
                 '0' AFTER 3000 NS, '1' AFTER 3300 NS,
                 'N' AFTER 3500 NS;
    
        s  <= 'N', 'P' AFTER 2200 NS, 'N' AFTER 2200.1 NS;
        co <= 'N', 'P' AFTER 3600 NS, 'N' AFTER 3600.1 NS;
    END input_output;
    
    
    






    
    
    
    --REPORT FILE:
    Gate number: 1 is part of cone triggered at: 2200.000001 ns
    Gate number: 2 is part of cone triggered at: 2200.000002 ns
    Gate number: 3 is part of cone triggered at: 2200.000003 ns
    Gate number: 4 is part of cone triggered at: 2200.000004 ns
    Gate number: 5 is part of cone triggered at: 2200.000005 ns
    Gate number: 6 is part of cone triggered at: 2200.000006 ns
    Gate number: 7 is part of cone triggered at: 2200.000007 ns
    Gate number: 8 is part of cone triggered at: 2200.000008 ns
    Gate number: 1 is part of cone triggered at: 3600.000001 ns
    Gate number: 2 is part of cone triggered at: 3600.000002 ns
    Gate number: 3 is part of cone triggered at: 3600.000003 ns
    Gate number: 4 is part of cone triggered at: 3600.000004 ns
    Gate number: 9 is part of cone triggered at: 3600.000009 ns
    Gate number: 10 is part of cone triggered at: 3600.00001 ns
    Gate number: 11 is part of cone triggered at: 3600.000011 ns
    
    
    
    --LIST FILE:
             fs  delta a b c s co 
              0     +0 N N N N  N 
      100000000     +0 0 N N N  N 
      100000000     +2 0 N N N  1 
      100000000     +4 0 N N 1  1 
      200000000     +0 1 0 N 1  1 
      300000000     +0 0 0 0 1  1 
      400000000     +0 1 1 0 1  1 
      500000000     +0 0 1 0 1  1 
      500000000     +2 0 1 0 1  0 
      600000000     +0 1 0 1 1  0 
      600000000     +2 1 0 1 1  1 
      800000000     +0 1 1 1 1  1 
      900000000     +0 1 1 0 1  1 
      900000000     +2 1 1 0 0  1 
     1000000000     +0 1 0 0 0  1 
     1000000000     +2 1 0 0 0  0 
     1200000000     +0 1 1 1 0  0 
     1200000000     +2 1 1 1 1  1 
     1500000000     +0 1 1 0 1  1 
     1800000000     +0 1 1 1 1  1 
     2100000000     +0 N N N 1  1 
     2100000000     +2 N N N 0  0 
     2200000000     +0 N N N P  0 
     2200000000     +2 N N P P  0 
     2200000000     +4 P P P P  0 
     2200000001     +0 N N N P  0 
     2200100098     +0 N N N 0  0 
     3000000000     +0 0 0 0 0  0 
     3100000000     +0 1 0 0 0  0 
     3200000000     +0 1 1 0 0  0 
     3200000000     +2 1 1 0 0  1 
     3300000000     +0 1 1 1 0  1 
     3300000000     +2 1 1 1 1  1 
     3500000000     +0 N N N 1  1 
     3500000000     +2 N N N 0  0 
     3600000000     +0 N N N 0  P 
     3600000000     +2 P P P 0  P 
     3600000001     +0 N N N 0  P 
     3600100098     +0 N N N 0  0