home *** CD-ROM | disk | FTP | other *** search
/ Unix System Administration Handbook 1997 October / usah_oct97.iso / rfc / 1900s / rfc1936.txt < prev    next >
Text File  |  1996-04-07  |  37KB  |  1,180 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7. Network Working Group                                           J. Touch
  8. Request For Comments: 1936                                     B. Parham
  9. Category: Informational                                              ISI
  10.                                                               April 1996
  11.  
  12.  
  13.              Implementing the Internet Checksum in Hardware
  14.  
  15. Status of This Memo
  16.  
  17.    This memo provides information for the Internet community.  This memo
  18.    does not specify an Internet standard of any kind.  Distribution of
  19.    this memo is unlimited.
  20.  
  21. Abstract
  22.  
  23.    This memo presents a techniques for efficiently implementing the
  24.    Internet Checksum in hardware. It includes PLD code for programming a
  25.    single, low cost part to perform checksumming at 1.26 Gbps.
  26.  
  27. Introduction
  28.  
  29.    The Internet Checksum is used in various Internet protocols to check
  30.    for data corruption in headers (e.g., IP) [4] and packet bodies (e.g,
  31.    UDP, TCP) [5][6]. Efficient software implementation of this checksum
  32.    has been addressed in previous RFCs [1][2][3][7].
  33.  
  34.    Efficient software implementations of the Internet Checksum algorithm
  35.    are often embedded in data copying operations ([1], Section 2). This
  36.    copy operation is increasingly being performed by dedicated direct
  37.    memory access (DMA) hardware. As a result, DMA hardware designs are
  38.    beginning to incorporate dedicated hardware to compute the Internet
  39.    Checksum during the data transfer.
  40.  
  41.    This note presents the architecture of an efficient, pipelined
  42.    Internet Checksum mechanism, suitable for inclusion in DMA hardware
  43.    [8]. This design can be implemented in a relatively inexpensive
  44.    programmable logic device (PLD) (1995 cost of $40), and is capable of
  45.    supporting 1.26 Gbps transfer rates, at 26 ns per 32-bit word.
  46.    Appendix A provides the pseudocode for such a device. This design has
  47.    been implemented in the PC-ATOMIC host interface hardware [8]. We
  48.    believe this design is of general use to the Internet community.
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58. Touch & Parham               Informational                      [Page 1]
  59.  
  60. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  61.  
  62.  
  63.    The remainder of this document is organized as follows:
  64.  
  65.             Review of the Internet Checksum
  66.             One's Complement vs. Two's Complement Addition
  67.             Interfaces
  68.             Summary
  69.             Appendix A - PLD source code
  70.  
  71.  
  72.  
  73.  
  74.  
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114. Touch & Parham               Informational                      [Page 2]
  115.  
  116. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  117.  
  118.  
  119. A Review of the Internet Checksum
  120.  
  121.    The Internet Checksum is used for detecting corruption in a block of
  122.    data [1]. It is initialized to zero, and computed as the complement
  123.    of the ones-complement sum of the data, taken in 16-bit units. A
  124.    subsequent checksum of the data and checksum together should generate
  125.    a zero checksum if no errors are detected.
  126.  
  127.    The checksum allows [1]:
  128.  
  129.             - byte order "independence"
  130.                     reordered output is equivalent to reordered input
  131.             - 16-bit word-order independence
  132.                     reordering 16-bit words preserves the output
  133.             - incremental computation
  134.             - deferred carries
  135.             - parallel summation
  136.                     a result of deferred carries, incremental
  137.                     computation, and 16-bit word order independence
  138.  
  139.    This note describes an implementation that computes two partial
  140.    checksums in parallel, over the odd and even 16-bit half-words of
  141.    32-bit data. The result is a pair of partial checksums (odd and
  142.    even), which can be combined, and the result inverted to generate the
  143.    true Internet Checksum. This technique is related to the long-word
  144.    parallel summation used in efficient software implementations [1].
  145.  
  146.             +------------------+     +------------------+
  147.             |  high half-word  |     |  low half-word   |
  148.             | ones-complement  |     | ones-complement  |
  149.             | partial checksum |     | partial checksum |
  150.             +------------------+     +------------------+
  151.                                 \   /
  152.                                   * (ones-complement sum)
  153.                                   |
  154.                          +------------------+
  155.                          | partial checksum |
  156.                          +------------------+
  157.                                   |
  158.                                   * (ones-complement negative)
  159.                                   |
  160.                         +-------------------+
  161.                         |       final       |
  162.                         | Internet Checksum |
  163.                         +-------------------+
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170. Touch & Parham               Informational                      [Page 3]
  171.  
  172. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  173.  
  174.  
  175. One's Complement vs. Two's Complement Addition
  176.  
  177.    The Internet Checksum is composed of a ones-complement lookahead
  178.    adder and a bit-wise inverter. A ones-complement adder can be built
  179.    either using twos-complement components, or natively.
  180.  
  181.    A twos-complement implementation of a ones-complement adder requires
  182.    either two twos-complement adders, or two cycles per add. The sum is
  183.    performed, then the high-bit carry-out is propagated to the carry-in,
  184.    and a second sum is performed. (ones-complement addition is {+1s} and
  185.    twos-complement is {+2s})
  186.  
  187.             a {+1s} b == (a {+2s} b) + carry(a {+2s} b)
  188.  
  189.             e.g.,
  190.                     halfword16 a,b;
  191.                     word32 c;
  192.                     a {+1s} b == r
  193.             such that:
  194.                     c = a {+2s} b;                          # sum value
  195.                     r = (c & 0xFFFF) {+2s} (c >> 16);       # sum carry
  196.  
  197.    Bits of a twos-complement lookahead adder are progressively more
  198.    complex in carry lookahead. (OR the contents of each row, where terms
  199.    are AND'd or XOR'd {^})
  200.  
  201.             4-bit carry-lookahead 2's complement adder:
  202.                     a,b : input data
  203.                     p   : carry propagate, where pi = ai*bi = (ai)(bi)
  204.                     g   : carry generate, where gi = ai + bi
  205.  
  206.             Out0 := a0 ^ b0 ^ ci
  207.  
  208.             Out1 := a1 ^ b1 ^ (cip0     + g0)
  209.  
  210.             Out2 := a2 ^ b2 ^ (cip0p1   + g0p1   + g1)
  211.  
  212.             Out3 := a3 ^ b3 ^ (cip0p1p2 + g0p1p2 + g1p2 + g2)
  213.  
  214.             Cout := cip0p1p2p3 + g0p1p2p3 + g1p2p3 + g2p3 + g3
  215.  
  216.    The true ones-complement lookahead adder recognizes that the carry-
  217.    wrap of the twos-complement addition is equivalent to a toroidal
  218.    carry-lookahead. Bits of a ones-complement lookahead adder are all
  219.    the same complexity, that of the high-bit of a twos-complement
  220.    lookahead adder. Thus the ones-complement sum (and thus the Internet
  221.    Checksum) is bit-position independent. We replace `ci' with the `co'
  222.    expression and reduce. (OR terms in each row pair).
  223.  
  224.  
  225.  
  226. Touch & Parham               Informational                      [Page 4]
  227.  
  228. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  229.  
  230.  
  231.             4-bit carry-lookahead 1's complement ring adder:
  232.  
  233.             Out0 = a0 ^ b0 ^ (g3       + g2p3     + g1p2p3   + g0p1p2p3)
  234.  
  235.             Out1 = a1 ^ b1 ^ (g3p0     + g2p3p0   + g1p2p3p0 + g0)
  236.  
  237.             Out2 = a2 ^ b2 ^ (g3p0p1   + g2p3p0p1 + g1       + g0p1)
  238.  
  239.             Out3 = a3 ^ b3 ^ (g3p0p1p2 + g2       + g1p2     + g0p1p2)
  240.  
  241.    A hardware implementation can use this toroidal design directly,
  242.    together with conventional twos-complement fast-adder internal
  243.    components, to perform a pipelined ones-complement adder [8].
  244.  
  245.    A VLSI implementation could use any full-lookahead adder, adapted to
  246.    be toroidal and bit-equivalent, as above. In our PLD implementation,
  247.    we implement the adders via 2- and 3-bit full-lookahead sub-
  248.    components. The adder components are chained in a ring via carry bit
  249.    registers.  This relies on delayed carry-propagation to implement a
  250.    carry pipeline between the fast-adder stages.
  251.  
  252.             Full-lookahead adders in a toroidal pipeline
  253.  
  254.          +-+-+-+   +-+-+-+   +-+-+   +-+-+-+   +-+-+-+   +-+-+
  255.          |i|i|i|   |i|i|i|   |i|i|   |i|i|i|   |i|i|i|   |i|i|
  256.          |F|E|D|   |C|B|A|   |9|8|   |7|6|5|   |4|3|2|   |1|0|
  257.          +-+-+-+   +-+-+-+   +-+-+   +-+-+-+   +-+-+-+   +-+-+
  258.            "+"       "+"      "+"      "+"       "+"      "+"
  259.          +-+-+-+   +-+-+-+   +-+-+   +-+-+-+   +-+-+-+   +-+-+
  260.          |s|s|s|   |s|s|s|   |s|s|   |s|s|s|   |s|s|s|   |s|s|
  261.          |F|E|D|   |C|B|A|   |9|8|   |7|6|5|   |4|3|2|   |1|0|
  262.          +-+-+-+   +-+-+-+   +-+-+   +-+-+-+   +-+-+-+   +-+-+
  263.          v     |   v     |   v   |   v     |   v     |   v   |   +--+
  264.          |     ^   |     ^   |   ^   |     ^   |     ^   |   ^   v  |
  265.          |      +-+       +-+     +-+       +-+       +-+     +-+   |
  266.          |      |c|       |c|     |c|       |c|       |c|     |c|   |
  267.          |      |5|       |4|     |3|       |2|       |1|     |0|   |
  268.          |      +-+       +-+     +-+       +-+       +-+     +-+   |
  269.          +----------------------------------------------------------+
  270.  
  271.    Implementation of fast-adders in PLD hardware is currently limited to
  272.    3-bits, because an i-bit adder requires 4+2^i product terms, and
  273.    current PLDs support only 16 product terms.  The resulting device
  274.    takes at most 5 "idle" clock periods for the carries to propagate
  275.    through the accumulation pipeline.
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282. Touch & Parham               Informational                      [Page 5]
  283.  
  284. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  285.  
  286.  
  287. Interfaces
  288.  
  289.    The above device has been installed in a VL-Bus PC host interface
  290.    card [8]. It has a hardware and software interface, defined as
  291.    follows.
  292.  
  293.  Hardware Interface
  294.  
  295.    The Internet Checksum hardware appears as a single-port 32-bit
  296.    register, with clock and control signals [8]:
  297.  
  298.                    +----------------------+
  299.             CLR--->|                      |
  300.             OE---->|  32-bit register as  |
  301.             CLK--->|  2 adjacent 16-bit   |<---/---> 32-bit data bus
  302.             ICLK-->| ones-complement sums |
  303.             ADD--->|                      |
  304.                    +----------------------+
  305.  
  306.             CLR    = zero the register
  307.             OE     = write the register onto the data bus
  308.             CLK    = clock to cycle the pipeline operation
  309.             ICLK   = input data latch clock
  310.             ADD    = initiating an add of latched input data
  311.  
  312.    CLR causes the contents of the checksum register and input latch to
  313.    be zeroed. There is no explicit load; a CLR followed by a write of
  314.    the load value to a dummy location is equivalent.
  315.  
  316.    The OE causes the register to be written to the data bus, or tri-
  317.    stated.
  318.  
  319.    The CLK causes the pipeline to operate. If no new input data is
  320.    latched to be added (via ICLK, ADD), a virtual "zero" is summed into
  321.    the register, to permit the pipeline to empty.
  322.  
  323.    The ICLK (transparently) latches the value on the data bus to be
  324.    latched internally, to be summed into the accumulator on the next ADD
  325.    signal. The ADD signal causes the latched input data (ICLK) to be
  326.    accumulated into the checksum pipeline. ADD and ICLK are commonly
  327.    tied together. One 32-bit data value can be latched and accumulated
  328.    into the pipeline adder every 26-ns clock, assuming data is stable
  329.    when the ADD/ICLK signal occurs.
  330.  
  331.    The internal 32-bit register is organized as two 16-bit ones-
  332.    complement sums, over the even and odd 16-bit words of the data
  333.    stream. To compute the Internet Checksum from this quantity, ones-
  334.    complement add the halves together, and invert the result.
  335.  
  336.  
  337.  
  338. Touch & Parham               Informational                      [Page 6]
  339.  
  340. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  341.  
  342.  
  343.  Software Interface
  344.  
  345.    The device is used as a memory-mapped register. The register is read
  346.    by performing a read on its equivalent memory location.
  347.  
  348.    The device is controlled via an external memory-mapped register. Bits
  349.    in this control register clear the device (set/clear the CLR line),
  350.    and enable and disable the device (set/clear the ADD line). The CLR
  351.    line can alternatively be mapped to a memory write, e.g., such that
  352.    reading the location is a non-destructive read of the checksum
  353.    register, and a write of any value clears the checksum register. The
  354.    enable/disable control must be stored in an external register.
  355.  
  356.    The device is designed to operate in background during memory
  357.    transfers (either DMA or programmed I/O). Once enabled, all transfers
  358.    across that bus are summed into the checksum register. The checksum
  359.    is available 5 clocks after the last enabled data accumulation. This
  360.    delay is often hidden by memory access mechanisms and bus
  361.    arbitration.  If required, "stall" instructions can be executed for
  362.    the appropriate delay.
  363.  
  364.    For the following example, we assume that the device is located at
  365.    CKSUMLOC. We assume that reading that location reads the checksum
  366.    register, and writing any value to that location clears the register.
  367.    The control register is located at CTLLOC, and the checksum
  368.    enable/disable bit is CKSUMBIT, where 1 is enabled, and 0 is
  369.    disabled.  To perform a checksum, a programmer would clear the
  370.    register, (optionally initialize the checksum), initiate a series of
  371.    transfers, and use the result:
  372.  
  373.             /******* initialization *******/
  374.             *(CTLLOC) &= ~((ctlsize)(CKSUMBIT));     /* disable sum */
  375.             (word32)(*(CKSUMLOC)) = 0;               /* clear reg   */
  376.             *(CTLLOC) |= CKSUMBIT;                   /* enable sum  */
  377.             { (optional) write initial value to a dummy location }
  378.  
  379.             /***** perform a transfer *****/
  380.             { do one or more DMA or PIO transfers - read or write }
  381.  
  382.             /***** gather the results *****/
  383.             *(CTLLOC) &= ~((ctlsize)(CKSUMBIT));     /* disable sum  */
  384.             sum = (word32)(*(CKSUMLOC));             /* read sum     */
  385.             sum = (sum & 0xFFFF) + (sum >> 16);      /* fold halves  */
  386.             sum = (sum & 0xFFFF) + (sum >> 16);      /* add in carry */
  387.             ipcksum = (halfword16)(~(sum & 0xFFFF)); /* 1's negative */
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394. Touch & Parham               Informational                      [Page 7]
  395.  
  396. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  397.  
  398.  
  399. Summary
  400.  
  401.    This note describes the design of a hardware Internet Checksum that
  402.    can be implemented in an inexpensive PLD, achieving 1.26 Gbps. This
  403.    design has been implemented in the PC-ATOMIC host interface hardware
  404.    [8]. We believe this design is of general use to the Internet
  405.    community.
  406.  
  407. Security Considerations
  408.  
  409.    Security considerations are not addressed here. The Internet Checksum
  410.    is not intended as a security measure.
  411.  
  412. Acknowledgements
  413.  
  414.    The authors would like to thank the members of the "High-Performance
  415.    Computing and Communications", notably Mike Carlton, and "Advanced
  416.    Systems" Divisions at ISI for their assistance in the development of
  417.    the hardware, and this memo.
  418.  
  419. References
  420.  
  421.    [1] Braden, R., Borman, D., and Partridge, C., "Computing the
  422.        Internet Checksum," Network Working Group RFC-1071, ISI, Cray
  423.        Research, and BBN Labs, Sept. 1988.
  424.  
  425.    [2] Mallory, T., and Kullberg, A., "Incremental Updating of the
  426.        Internet Checksum," Network Working Group RFC-1141, BBN Comm.,
  427.        Jan. 1990.
  428.  
  429.    [3] Plummer, W., "TCP Checksum Function Design," IEN-45, BBN, 1978,
  430.        included as an appendix in RFC-1071.
  431.  
  432.    [4] Postel, Jon, "Internet Protocol," Network Working Group RFC-
  433.        791/STD-5, ISI, Sept. 1981.
  434.  
  435.    [5] Postel, Jon, "User Datagram Protocol," Network Working Group
  436.        RFC-768/STD-6, ISI, Aug. 1980.
  437.  
  438.    [6] Postel, Jon, "Transmission Control Protocol," Network Working
  439.        Group RFC-793/STD-7, ISI, Sept. 1981.
  440.  
  441.    [7] Rijsinghani, A., "Computation of the Internet Checksum via
  442.        Incremental Update," Network Working Group RFC-1624, Digital
  443.        Equipment Corp., May 1994.
  444.  
  445.    [8] Touch, J., "PC-ATOMIC", ISI Tech. Report. SR-95-407, June 1995.
  446.  
  447.  
  448.  
  449.  
  450. Touch & Parham               Informational                      [Page 8]
  451.  
  452. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  453.  
  454.  
  455. Authors' Addresses
  456.  
  457.    Joe Touch
  458.    University of Southern California/Information Sciences Institute
  459.    4676 Admiralty Way
  460.    Marina del Rey, CA 90292-6695
  461.    USA
  462.    Phone: +1 310-822-1511 x151
  463.    Fax:   +1 310-823-6714
  464.    URL:   http://www.isi.edu/~touch
  465.    EMail: touch@isi.edu
  466.  
  467.  
  468.    Bruce Parham
  469.    University of Southern California/Information Sciences Institute
  470.    4676 Admiralty Way
  471.    Marina del Rey, CA 90292-6695
  472.    USA
  473.    Phone: +1 310-822-1511 x101
  474.    Fax:   +1 310-823-6714
  475.    EMail: bparham@isi.edu
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.  
  487.  
  488.  
  489.  
  490.  
  491.  
  492.  
  493.  
  494.  
  495.  
  496.  
  497.  
  498.  
  499.  
  500.  
  501.  
  502.  
  503.  
  504.  
  505.  
  506. Touch & Parham               Informational                      [Page 9]
  507.  
  508. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  509.  
  510.  
  511. Appendix A: PLD source code
  512.  
  513. The following is the PLD source code for an AMD MACH-435 PLD. The
  514. MACH-435 is composed of 8 22V10-equivalent PLD blocks, connected by a
  515. configurable internal matrix.
  516.  
  517.  
  518. ---- (PLD source code follows) ----
  519.  
  520. TITLE    PC-ATOMIC IP Sum Accelerator - 1-clock 2- and 3-bit 26 ns version
  521. PATTERN  ip_sum
  522. REVISION 1.01
  523. AUTHOR   J. Touch & B. Parham
  524. COMPANY  USC/ISI
  525. DATE     06/21/94
  526.  
  527. CHIP    ip_sum          MACH435
  528.  
  529. ; accumulates in 1 clock (1 level of logic)
  530. ;
  531. ; resources allocated to reduce fitting time
  532. ;
  533. ; uses an input register "dl" to latch the data bus values on rising edge
  534. ; accumulates a hi/lo ones-complement sum in register "q"
  535. ; the input and output are accessed via bidirectional pins "dq"
  536. ;
  537. ; uses 2 groups of 6 carry bit registers "cy"
  538. ;
  539. ; use 3-bit full-adders with carry lookahead (settles in 6 clocks)
  540. ; group 16 bits as      [000102 030405 0607 080910 111213 1415]
  541. ;                       [161718 192021 2223 242526 272829 3031]
  542. ;
  543. ; locking the pins down speeds up fitting and is designed to force
  544. ; 4-bit components into single "segments" of the PLD.
  545. ; we could have indicated the same thing via:
  546. ;       GROUP MACH_SEG_A        dq[6..0]
  547. ;       GROUP MACH_SEG_B        dq[14..8]
  548. ;       GROUP MACH_SEG_C        dq[22..16]
  549. ;       GROUP MACH_SEG_D        dq[30..24]
  550.  
  551. ;
  552. ; control pins:
  553. ;
  554. PIN     20      clk             ; adder clock
  555. PIN     62      ip_add          ; add current data to sum
  556. PIN     83      ip_sum_ena      ; output current sum
  557. PIN     41      ip_clr          ; clear current sum
  558. PIN 23  ip_dclk                 ; input data latch (tied to clk, or not)
  559.  
  560.  
  561.  
  562. Touch & Parham               Informational                     [Page 10]
  563.  
  564. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  565.  
  566.  
  567. ;
  568. ; dq are data bus pins
  569. ; dl is the input register
  570. ;
  571. PIN     [9..3]          dq[6..0] IPAIR dl[6..0]         ; IO port
  572. PIN     [18..12]        dq[14..8] IPAIR dl[14..8]       ; IO port
  573. PIN     [30..24]        dq[22..16] IPAIR dl[22..16]     ; IO port
  574. PIN     [39..33]        dq[30..24] IPAIR dl[30..24]     ; IO port
  575. PIN     ?       dq[31,23,15,7] IPAIR dl[31,23,15,7]     ; IO port
  576.  
  577. ;
  578. ; q  is the partial checksum register
  579. ; dl is the input register
  580. ; dq are the data bus pins
  581. ;
  582. NODE    ?       q[31..0] OPAIR dq[31..0]        ; internal data in reg
  583. NODE    ?       dl[31..0] REG                   ; input reg
  584.  
  585. ;
  586. ; cy are the carry register bits
  587. ;
  588. NODE    ?       cy[31,29,26,23,21,18,15,13,10,7,5,2] REG
  589.                                                 ;1-bit internal carry bits
  590.  
  591. EQUATIONS
  592.  
  593. ;
  594. ; .trst is the tri-state control, 0 means these are always inputs
  595. ;
  596. ip_add.trst             = 0
  597. ip_clr.trst             = 0
  598. ip_sum_ena.trst         = 0
  599.  
  600. ;
  601. ; grab data to the input register on every clock (irrelevant if invalid)
  602. ;
  603. dl[31..0].clkf          = ip_dclk       ; grab data all the time
  604.         ; don't use setf, rstf, or trst for dl
  605.         ; we want dl to map to input registers, not internal cells
  606.         ; besides, input registers don't need setf, rstf, or trst
  607.  
  608. ;
  609. ; control of the checksum register
  610. ;
  611. dq[31..0].clkf          = clk                   ; clk clocks everything
  612. dq[31..0].setf          = gnd                   ; never preset registers
  613. dq[31..0].rstf          = ip_clr                ; clear on reset
  614. dq[31..0].trst          = ip_sum_ena            ; ena outputs sum - read
  615.  
  616.  
  617.  
  618. Touch & Parham               Informational                     [Page 11]
  619.  
  620. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  621.  
  622.  
  623. ;
  624. ; control for the carry register
  625. ;
  626. cy[31,29,26,23,21,18,15,13,10,7,5,2].clkf       = clk
  627. cy[31,29,26,23,21,18,15,13,10,7,5,2].setf       = gnd    ; never preset
  628. cy[31,29,26,23,21,18,15,13,10,7,5,2].rstf       = ip_clr ; clear on reset
  629.  
  630. ;
  631. ; INPUT DATA LATCH
  632. ; nothing fancy here - grab all inputs when ip_add signal is high
  633. ; i.e., grab data in input register
  634. ;
  635. dl[31..0]             := dq[31..0]
  636.  
  637. ;
  638. ; COMBINATORIAL ADDER
  639. ;
  640. ; built as a series of 2-bit and 3-bit (carry-lookahead) full-adders
  641. ; with carries sent to the carry register "pipeline"
  642. ;
  643. ; sum[n] are sum bits
  644. ; cy[m] are carry bits
  645. ; ":+:" is XOR
  646.  
  647. ;
  648. ; SUM[0] = (A0 :+: B0 :+: CARRY_IN)
  649. ;
  650. ; CY[0] = ((A0 * B0) + ((A0 :+: B0) * CARRY_IN))
  651. ;
  652. ; actually, the latter can be rewritten as
  653. ;
  654. ; CY[0] = ((A0 * B0) + ((A0 + B0) * CARRY_IN))
  655. ;
  656. ; because the XOR won't be invalidated by the AND case, since the
  657. ; result is always 1 from the first term then anyway
  658. ; this helps reduce the number of XOR terms required, which are
  659. ; a limited resource in PLDs
  660. ;
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674. Touch & Parham               Informational                     [Page 12]
  675.  
  676. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  677.  
  678.  
  679. ; SUM THE LOW-ORDER WORD
  680. ;
  681.  
  682. ;
  683. ; the first 5 bits [0..4] of the low-order word
  684. ;
  685. q[0]    := (q[0] :+: (ip_add * dl[0]) :+: cy[15])
  686.  
  687. q[1]    := (q[1] :+: (ip_add * dl[1]) :+:
  688.         ((ip_add *
  689.                 (q[0] * dl[0] +
  690.                 dl[0] * cy[15])) +
  691.         (q[0] * cy[15])))
  692.  
  693. q[2]    := (q[2] :+: (ip_add * dl[2]) :+:
  694.         ((ip_add *
  695.                 (q[1] * dl[1] +
  696.                  q[1] *  q[0] *  dl[0] +
  697.                 dl[1] *  q[0] *  dl[0] +
  698.                  q[1] * dl[0] * cy[15] +
  699.                 dl[1] * dl[0] * cy[15] +
  700.                 dl[1] *  q[0] * cy[15])) +
  701.         (q[1] * q[0] * cy[15])))
  702.  
  703. cy[2]   := ((ip_add *
  704.                 (q[2] * dl[2] +
  705.                  q[2] *  q[1] * dl[1] +
  706.                 dl[2] *  q[1] * dl[1] +
  707.                  q[2] *  q[1] *  q[0] *  dl[0] +
  708.                  q[2] * dl[1] *  q[0] *  dl[0] +
  709.                 dl[2] *  q[1] *  q[0] *  dl[0] +
  710.                 dl[2] * dl[1] *  q[0] *  dl[0] +
  711.                  q[2] *  q[1] * dl[0] * cy[15] +
  712.                  q[2] * dl[1] *  q[0] * cy[15] +
  713.                  q[2] * dl[1] * dl[0] * cy[15] +
  714.                 dl[2] *  q[1] *  q[0] * cy[15] +
  715.                 dl[2] *  q[1] * dl[0] * cy[15] +
  716.                 dl[2] * dl[1] *  q[0] * cy[15] +
  717.                 dl[2] * dl[1] * dl[0] * cy[15])) +
  718.         (q[2] * q[1] * q[0] * cy[15]))
  719.  
  720. q[3]    := (q[3] :+: (ip_add * dl[3]) :+: cy[2])
  721.  
  722. q[4]    := (q[4] :+: (ip_add * dl[4]) :+:
  723.         ((ip_add *
  724.                 (q[3] * dl[3] +
  725.                 dl[3] * cy[2])) +
  726.         (q[3] * cy[2])))
  727.  
  728.  
  729.  
  730. Touch & Parham               Informational                     [Page 13]
  731.  
  732. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  733.  
  734.  
  735. ;
  736. ; the next 3 bits [5..7] of the low-order word
  737. ;
  738. q[5]    := (q[5] :+: (ip_add * dl[5]) :+:
  739.         ((ip_add *
  740.                 (q[4] * dl[4] +
  741.                  q[4] *  q[3] * dl[3] +
  742.                 dl[4] *  q[3] * dl[3] +
  743.                  q[4] * dl[3] * cy[2] +
  744.                 dl[4] * dl[3] * cy[2] +
  745.                 dl[4] *  q[3] * cy[2])) +
  746.         (q[4] * q[3] * cy[2])))
  747.  
  748. cy[5]   := ((ip_add * (
  749.                  q[5] * dl[5] +
  750.                  q[5] *  q[4] * dl[4] +
  751.                 dl[5] *  q[4] * dl[4] +
  752.                  q[5] *  q[4] *  q[3] * dl[3] +
  753.                  q[5] * dl[4] *  q[3] * dl[3] +
  754.                 dl[5] *  q[4] *  q[3] * dl[3] +
  755.                 dl[5] * dl[4] *  q[3] * dl[3] +
  756.                  q[5] *  q[4] * dl[3] * cy[2] +
  757.                  q[5] * dl[4] *  q[3] * cy[2] +
  758.                  q[5] * dl[4] * dl[3] * cy[2] +
  759.                 dl[5] *  q[4] *  q[3] * cy[2] +
  760.                 dl[5] *  q[4] * dl[3] * cy[2] +
  761.                 dl[5] * dl[4] *  q[3] * cy[2] +
  762.                 dl[5] * dl[4] * dl[3] * cy[2])) +
  763.         (q[5] * q[4] * q[3] * cy[2]))
  764.  
  765. q[6]    := (q[6] :+: (ip_add * dl[6]) :+: cy[5])
  766.  
  767. q[7]    := (q[7] :+: (ip_add * dl[7]) :+:
  768.         ((ip_add *
  769.                 (q[6] * dl[6] +
  770.                 dl[6] * cy[5])) +
  771.         (q[6] * cy[5])))
  772.  
  773. cy[7]   := ((ip_add *
  774.                 (q[7] * dl[7] +
  775.                  q[7] *  q[6] * dl[6] +
  776.                 dl[7] *  q[6] * dl[6] +
  777.                  q[7] * dl[6] * cy[5] +
  778.                 dl[7] * dl[6] * cy[5] +
  779.                 dl[7] *  q[6] * cy[5])) +
  780.         (q[7] * q[6] * cy[5]))
  781.  
  782.  
  783.  
  784.  
  785.  
  786. Touch & Parham               Informational                     [Page 14]
  787.  
  788. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  789.  
  790.  
  791. ;
  792. ; the next 5 bits [8..12] of the low-order word
  793. ;
  794. q[8]    := (q[8] :+: (ip_add * dl[8]) :+: cy[7])
  795.  
  796. q[9]    := (q[9] :+: (ip_add * dl[9]) :+:
  797.         ((ip_add *
  798.                 (q[8] * dl[8] +
  799.                 dl[8] * cy[7])) +
  800.         (q[8] * cy[7])))
  801.  
  802. q[10]   := (q[10] :+: (ip_add * dl[10]) :+:
  803.         ((ip_add *
  804.                 (q[9] * dl[9] +
  805.                  q[9] *  q[8] * dl[8] +
  806.                 dl[9] *  q[8] * dl[8] +
  807.                  q[9] * dl[8] * cy[7] +
  808.                 dl[9] * dl[8] * cy[7] +
  809.                 dl[9] *  q[8] * cy[7])) +
  810.         (q[9] * q[8] * cy[7])))
  811.  
  812. cy[10]  := ((ip_add *
  813.                 (q[10] * dl[10] +
  814.                  q[10] *  q[9] * dl[9] +
  815.                 dl[10] *  q[9] * dl[9] +
  816.                  q[10] *  q[9] *  q[8] * dl[8] +
  817.                  q[10] * dl[9] *  q[8] * dl[8] +
  818.                 dl[10] *  q[9] *  q[8] * dl[8] +
  819.                 dl[10] * dl[9] *  q[8] * dl[8] +
  820.                  q[10] *  q[9] * dl[8] * cy[7] +
  821.                  q[10] * dl[9] *  q[8] * cy[7] +
  822.                  q[10] * dl[9] * dl[8] * cy[7] +
  823.                 dl[10] *  q[9] *  q[8] * cy[7] +
  824.                 dl[10] *  q[9] * dl[8] * cy[7] +
  825.                 dl[10] * dl[9] *  q[8] * cy[7] +
  826.                 dl[10] * dl[9] * dl[8] * cy[7])) +
  827.         (q[10] * q[9] * q[8] * cy[7]))
  828.  
  829. q[11]   := (q[11] :+: (ip_add * dl[11]) :+: cy[10])
  830.  
  831. q[12]   := (q[12] :+: (ip_add * dl[12]) :+:
  832.         ((ip_add *
  833.                 (q[11] * dl[11] +
  834.                 dl[11] * cy[10])) +
  835.         (q[11] * cy[10])))
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842. Touch & Parham               Informational                     [Page 15]
  843.  
  844. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  845.  
  846.  
  847. ;
  848. ; the final 3 bits [13..15] of the low-order word
  849. ;
  850. q[13]   := (q[13] :+: (ip_add * dl[13]) :+:
  851.         ((ip_add *
  852.                 (q[12] * dl[12] +
  853.                  q[12] *  q[11] * dl[11] +
  854.                 dl[12] *  q[11] * dl[11] +
  855.                  q[12] * dl[11] * cy[10] +
  856.                 dl[12] * dl[11] * cy[10] +
  857.                 dl[12] *  q[11] * cy[10])) +
  858.         (q[12] * q[11] * cy[10])))
  859.  
  860. cy[13]  := ((ip_add * (
  861.                  q[13] * dl[13] +
  862.                  q[13] *  q[12] * dl[12] +
  863.                 dl[13] *  q[12] * dl[12] +
  864.                  q[13] *  q[12] *  q[11] * dl[11] +
  865.                  q[13] * dl[12] *  q[11] * dl[11] +
  866.                 dl[13] *  q[12] *  q[11] * dl[11] +
  867.                 dl[13] * dl[12] *  q[11] * dl[11] +
  868.                  q[13] *  q[12] * dl[11] * cy[10] +
  869.                  q[13] * dl[12] *  q[11] * cy[10] +
  870.                  q[13] * dl[12] * dl[11] * cy[10] +
  871.                 dl[13] *  q[12] *  q[11] * cy[10] +
  872.                 dl[13] *  q[12] * dl[11] * cy[10] +
  873.                 dl[13] * dl[12] *  q[11] * cy[10] +
  874.                 dl[13] * dl[12] * dl[11] * cy[10])) +
  875.         (q[13] * q[12] *  q[11] * cy[10]))
  876.  
  877. q[14]   := (q[14] :+: (ip_add * dl[14]) :+: cy[13])
  878.  
  879. q[15]   := (q[15] :+: (ip_add * dl[15]) :+:
  880.         ((ip_add *
  881.                 (q[14] * dl[14] +
  882.                 dl[14] * cy[13])) +
  883.         (q[14] * cy[13])))
  884.  
  885. cy[15]  := ((ip_add *
  886.                 (q[15] * dl[15] +
  887.                  q[15] *  q[14] * dl[14] +
  888.                 dl[15] *  q[14] * dl[14] +
  889.                  q[15] * dl[14] * cy[13] +
  890.                 dl[15] * dl[14] * cy[13] +
  891.                 dl[15] *  q[14] * cy[13])) +
  892.         (q[15] * q[14] * cy[13]))
  893.  
  894.  
  895.  
  896.  
  897.  
  898. Touch & Parham               Informational                     [Page 16]
  899.  
  900. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  901.  
  902.  
  903. ; SUM THE HIGH-ORDER WORD
  904. ;
  905.  
  906. ;
  907. ; the first 5 bits [16..20] of the high-order word
  908. ;
  909. q[16]   := (q[16] :+: (ip_add * dl[16]) :+: cy[31])
  910.  
  911. q[17]   := (q[17] :+: (ip_add * dl[17]) :+:
  912.         ((ip_add *
  913.                 (q[16] * dl[16] +
  914.                 dl[16] * cy[31])) +
  915.         (q[16] * cy[31])))
  916.  
  917. q[18]   := (q[18] :+: (ip_add * dl[18]) :+:
  918.         ((ip_add *
  919.                 (q[17] * dl[17] +
  920.                  q[17] *  q[16] * dl[16] +
  921.                 dl[17] *  q[16] * dl[16] +
  922.                  q[17] * dl[16] * cy[31] +
  923.                 dl[17] * dl[16] * cy[31] +
  924.                 dl[17] *  q[16] * cy[31])) +
  925.         (q[17] * q[16] * cy[31])))
  926.  
  927. cy[18]  := ((ip_add *
  928.                 (q[18] * dl[18] +
  929.                  q[18] *  q[17] * dl[17] +
  930.                 dl[18] *  q[17] * dl[17] +
  931.                  q[18] *  q[17] *  q[16] * dl[16] +
  932.                  q[18] * dl[17] *  q[16] * dl[16] +
  933.                 dl[18] *  q[17] *  q[16] * dl[16] +
  934.                 dl[18] * dl[17] *  q[16] * dl[16] +
  935.                  q[18] *  q[17] * dl[16] * cy[31] +
  936.                  q[18] * dl[17] *  q[16] * cy[31] +
  937.                  q[18] * dl[17] * dl[16] * cy[31] +
  938.                 dl[18] *  q[17] *  q[16] * cy[31] +
  939.                 dl[18] *  q[17] * dl[16] * cy[31] +
  940.                 dl[18] * dl[17] *  q[16] * cy[31] +
  941.                 dl[18] * dl[17] * dl[16] * cy[31])) +
  942.         (q[18] * q[17] * q[16] * cy[31]))
  943.  
  944. q[19]   := (q[19] :+: (ip_add * dl[19]) :+: cy[18])
  945.  
  946. q[20]   := (q[20] :+: (ip_add * dl[20]) :+:
  947.         ((ip_add *
  948.                 (q[19] * dl[19] +
  949.                 dl[19] * cy[18])) +
  950.         (q[19] * cy[18])))
  951.  
  952.  
  953.  
  954. Touch & Parham               Informational                     [Page 17]
  955.  
  956. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  957.  
  958.  
  959. ;
  960. ; the next 3 bits [21..23] of the high-order word
  961. ;
  962. q[21]   := (q[21] :+: (ip_add * dl[21]) :+:
  963.         ((ip_add *
  964.                 (q[20] * dl[20] +
  965.                  q[20] *  q[19] * dl[19] +
  966.                 dl[20] *  q[19] * dl[19] +
  967.                  q[20] * dl[19] * cy[18] +
  968.                 dl[20] * dl[19] * cy[18] +
  969.                 dl[20] *  q[19] * cy[18])) +
  970.         (q[20] * q[19] * cy[18])))
  971.  
  972. cy[21]  := ((ip_add * (
  973.                  q[21] * dl[21] +
  974.                  q[21] *  q[20] * dl[20] +
  975.                 dl[21] *  q[20] * dl[20] +
  976.                  q[21] *  q[20] *  q[19] * dl[19] +
  977.                  q[21] * dl[20] *  q[19] * dl[19] +
  978.                 dl[21] *  q[20] *  q[19] * dl[19] +
  979.                 dl[21] * dl[20] *  q[19] * dl[19] +
  980.                  q[21] *  q[20] * dl[19] * cy[18] +
  981.                  q[21] * dl[20] *  q[19] * cy[18] +
  982.                  q[21] * dl[20] * dl[19] * cy[18] +
  983.                 dl[21] *  q[20] *  q[19] * cy[18] +
  984.                 dl[21] *  q[20] * dl[19] * cy[18] +
  985.                 dl[21] * dl[20] *  q[19] * cy[18] +
  986.                 dl[21] * dl[20] * dl[19] * cy[18])) +
  987.         (q[21] * q[20] * q[19] * cy[18]))
  988.  
  989. q[22]   := (q[22] :+: (ip_add * dl[22]) :+: cy[21])
  990.  
  991. q[23]   := (q[23] :+: (ip_add * dl[23]) :+:
  992.         ((ip_add *
  993.                 (q[22] * dl[22] +
  994.                 dl[22] * cy[21])) +
  995.         (q[22] * cy[21])))
  996.  
  997. cy[23]  := ((ip_add *
  998.                 (q[23] * dl[23] +
  999.                  q[23] *  q[22] * dl[22] +
  1000.                 dl[23] *  q[22] * dl[22] +
  1001.                  q[23] * dl[22] * cy[21] +
  1002.                 dl[23] * dl[22] * cy[21] +
  1003.                 dl[23] *  q[22] * cy[21])) +
  1004.         (q[23] * q[22] * cy[21]))
  1005.  
  1006.  
  1007.  
  1008.  
  1009.  
  1010. Touch & Parham               Informational                     [Page 18]
  1011.  
  1012. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  1013.  
  1014.  
  1015. ;
  1016. ; the next 5 bits [24..28] of the high-order word
  1017. ;
  1018. q[24]   := (q[24] :+: (ip_add * dl[24]) :+: cy[23])
  1019.  
  1020. q[25]   := (q[25] :+: (ip_add * dl[25]) :+:
  1021.         ((ip_add *
  1022.                 (q[24] * dl[24] +
  1023.                 dl[24] * cy[23])) +
  1024.         (q[24] * cy[23])))
  1025.  
  1026. q[26]   := (q[26] :+: (ip_add * dl[26]) :+:
  1027.         ((ip_add *
  1028.                 (q[25] * dl[25] +
  1029.                  q[25] *  q[24] * dl[24] +
  1030.                 dl[25] *  q[24] * dl[24] +
  1031.                  q[25] * dl[24] * cy[23] +
  1032.                 dl[25] * dl[24] * cy[23] +
  1033.                 dl[25] *  q[24] * cy[23])) +
  1034.         (q[25] * q[24] * cy[23])))
  1035.  
  1036. cy[26]  := ((ip_add *
  1037.                 (q[26] * dl[26] +
  1038.                  q[26] *  q[25] * dl[25] +
  1039.                 dl[26] *  q[25] * dl[25] +
  1040.                  q[26] *  q[25] *  q[24] * dl[24] +
  1041.                  q[26] * dl[25] *  q[24] * dl[24] +
  1042.                 dl[26] *  q[25] *  q[24] * dl[24] +
  1043.                 dl[26] * dl[25] *  q[24] * dl[24] +
  1044.                  q[26] *  q[25] * dl[24] * cy[23] +
  1045.                  q[26] * dl[25] *  q[24] * cy[23] +
  1046.                  q[26] * dl[25] * dl[24] * cy[23] +
  1047.                 dl[26] *  q[25] *  q[24] * cy[23] +
  1048.                 dl[26] *  q[25] * dl[24] * cy[23] +
  1049.                 dl[26] * dl[25] *  q[24] * cy[23] +
  1050.                 dl[26] * dl[25] * dl[24] * cy[23])) +
  1051.         (q[26] * q[25] * q[24] * cy[23]))
  1052.  
  1053. q[27]   := (q[27] :+: (ip_add * dl[27]) :+: cy[26])
  1054.  
  1055. q[28]   := (q[28] :+: (ip_add * dl[28]) :+:
  1056.         ((ip_add *
  1057.                 (q[27] * dl[27] +
  1058.                 dl[27] * cy[26])) +
  1059.         (q[27] * cy[26])))
  1060.  
  1061.  
  1062.  
  1063.  
  1064.  
  1065.  
  1066. Touch & Parham               Informational                     [Page 19]
  1067.  
  1068. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  1069.  
  1070.  
  1071. ;
  1072. ; the final 3 bits [29..31] of the high-order word
  1073. ;
  1074. q[29]   := (q[29] :+: (ip_add * dl[29]) :+:
  1075.         ((ip_add *
  1076.                 (q[28] * dl[28] +
  1077.                  q[28] *  q[27] * dl[27] +
  1078.                 dl[28] *  q[27] * dl[27] +
  1079.                  q[28] * dl[27] * cy[26] +
  1080.                 dl[28] * dl[27] * cy[26] +
  1081.                 dl[28] *  q[27] * cy[26])) +
  1082.         (q[28] * q[27] * cy[26])))
  1083.  
  1084. cy[29]  := ((ip_add * (
  1085.                  q[29] * dl[29] +
  1086.                  q[29] *  q[28] * dl[28] +
  1087.                 dl[29] *  q[28] * dl[28] +
  1088.                  q[29] *  q[28] *  q[27] * dl[27] +
  1089.                  q[29] * dl[28] *  q[27] * dl[27] +
  1090.                 dl[29] *  q[28] *  q[27] * dl[27] +
  1091.                 dl[29] * dl[28] *  q[27] * dl[27] +
  1092.                  q[29] *  q[28] * dl[27] * cy[26] +
  1093.                  q[29] * dl[28] *  q[27] * cy[26] +
  1094.                  q[29] * dl[28] * dl[27] * cy[26] +
  1095.                 dl[29] *  q[28] *  q[27] * cy[26] +
  1096.                 dl[29] *  q[28] * dl[27] * cy[26] +
  1097.                 dl[29] * dl[28] *  q[27] * cy[26] +
  1098.                 dl[29] * dl[28] * dl[27] * cy[26])) +
  1099.         (q[29] * q[28] * q[27] * cy[26]))
  1100.  
  1101. q[30]   := (q[30] :+: (ip_add * dl[30]) :+: cy[29])
  1102.  
  1103. q[31]   := (q[31] :+: (ip_add * dl[31]) :+:
  1104.         ((ip_add *
  1105.                 (q[30] * dl[30] +
  1106.                 dl[30] * cy[29])) +
  1107.         (q[30] * cy[29])))
  1108.  
  1109. cy[31]  := ((ip_add *
  1110.                 (q[31] * dl[31] +
  1111.                  q[31] *  q[30] * dl[30] +
  1112.                 dl[31] *  q[30] * dl[30] +
  1113.                  q[31] * dl[30] * cy[29] +
  1114.                 dl[31] * dl[30] * cy[29] +
  1115.                 dl[31] *  q[30] * cy[29])) +
  1116.         (q[31] * q[30] * cy[29]))
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122. Touch & Parham               Informational                     [Page 20]
  1123.  
  1124. RFC 1936    Implementing the Internet Checksum in Hardware    April 1996
  1125.  
  1126.  
  1127. ;
  1128. ; output nodes onto output pins (pending enable..)
  1129. ;
  1130. dq[0]   := {q[0]}
  1131. dq[1]   := {q[1]}
  1132. dq[2]   := {q[2]}
  1133. dq[3]   := {q[3]}
  1134. dq[4]   := {q[4]}
  1135. dq[5]   := {q[5]}
  1136. dq[6]   := {q[6]}
  1137. dq[7]   := {q[7]}
  1138. dq[8]   := {q[8]}
  1139. dq[9]   := {q[9]}
  1140. dq[10]  := {q[10]}
  1141. dq[11]  := {q[11]}
  1142. dq[12]  := {q[12]}
  1143. dq[13]  := {q[13]}
  1144. dq[14]  := {q[14]}
  1145. dq[15]  := {q[15]}
  1146.  
  1147. dq[16]  := {q[16]}
  1148. dq[17]  := {q[17]}
  1149. dq[18]  := {q[18]}
  1150. dq[19]  := {q[19]}
  1151. dq[20]  := {q[20]}
  1152. dq[21]  := {q[21]}
  1153. dq[22]  := {q[22]}
  1154. dq[23]  := {q[23]}
  1155. dq[24]  := {q[24]}
  1156. dq[25]  := {q[25]}
  1157. dq[26]  := {q[26]}
  1158. dq[27]  := {q[27]}
  1159. dq[28]  := {q[28]}
  1160. dq[29]  := {q[29]}
  1161. dq[30]  := {q[30]}
  1162. dq[31]  := {q[31]}
  1163.  
  1164. ;
  1165. ; end.
  1166. ;
  1167.  
  1168.  
  1169.  
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178. Touch & Parham               Informational                     [Page 21]
  1179.  
  1180.