1 -------------------------------------------------------------------------------     2 -- File       : EthMacTxCsum.vhd     3 -- Company    : SLAC National Accelerator Laboratory     4 -- Created    : 2016-09-08     5 -- Last update: 2017-02-22     6 -------------------------------------------------------------------------------     7 -- Description: TX Checksum Hardware Offloading Engine     8 -- https://docs.google.com/spreadsheets/d/1_1M1keasfq8RLmRYHkO0IlRhMq5YZTgJ7OGrWvkib8I/edit?usp=sharing     9 -------------------------------------------------------------------------------    10 -- This file is part of 'SLAC Firmware Standard Library'.    11 -- It is subject to the license terms in the LICENSE.txt file found in the     12 -- top-level directory of this distribution and at:     13 --    https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.     14 -- No part of 'SLAC Firmware Standard Library', including this file,     15 -- may be copied, modified, propagated, or distributed except according to     16 -- the terms contained in the LICENSE.txt file.    17 -------------------------------------------------------------------------------    20 use ieee.std_logic_1164.
all;
    21 use ieee.std_logic_arith.
all;
    22 use ieee.std_logic_unsigned.
all;
    29  --! @ingroup ethernet_EthMacCore    45       -- Outbound data to MAC    54    constant MAX_FRAME_SIZE_C :  := ite(JUMBO_G, 9000, 1500);
    63    type RegType is record    72       ipv4Csum : slv(15 downto 0);
    74       protCsum : slv(15 downto 0);
    77       len      : slv(15 downto 0);
    82       dbg      : slv(5 downto 0);
    89    constant REG_INIT_C : RegType := (    91       fragDet  => (others => '0'),    92       eofeDet  => (others => '0'),    93       ipv4Det  => (others => '0'),    94       udpDet   => (others => '0'),    95       tcpDet   => (others => '0'),    97       ipv4Len  => (others => (others => '0')),    98       ipv4Csum => (others => '0'),    99       protLen  => (others => (others => '0')),   100       protCsum => (others => '0'),   101       ipv4Hdr  => (others => (others => '0')),   103       len      => (others => '0'),   104       tKeep    => (others => '0'),   105       tData    => (others => '0'),   108       dbg      => (others => '0'),   115    signal r   : RegType := REG_INIT_C;
   116    signal rin : RegType;
   127    signal tranPause : sl;
   133    signal ipv4Len   : slv(15 downto 0);
   134    signal ipv4Csum  : slv(15 downto 0);
   135    signal protLen   : slv(15 downto 0);
   136    signal protCsum  : slv(15 downto 0);
   137    signal tranValid : sl;
   139    -- attribute dont_touch              : string;   140    -- attribute dont_touch of r         : signal is "TRUE";   141    -- attribute dont_touch of fragDet   : signal is "TRUE";   142    -- attribute dont_touch of eofeDet   : signal is "TRUE";   143    -- attribute dont_touch of ipv4Det   : signal is "TRUE";   144    -- attribute dont_touch of udpDet    : signal is "TRUE";   145    -- attribute dont_touch of tcpDet    : signal is "TRUE";   146    -- attribute dont_touch of ipv4Len   : signal is "TRUE";   147    -- attribute dont_touch of ipv4Csum  : signal is "TRUE";   148    -- attribute dont_touch of protLen   : signal is "TRUE";   149    -- attribute dont_touch of protCsum  : signal is "TRUE";   150    -- attribute dont_touch of tranValid : signal is "TRUE";   151    -- attribute dont_touch of mMaster   : signal is "TRUE";   152    -- attribute dont_touch of mSlave    : signal is "TRUE";   168    comb : 
process (eofeDet, 
ethRst, fragDet, 
ipCsumEn, ipv4Csum, ipv4Det,
   169                    ipv4Len, mMaster, protCsum, protLen, r, rxMaster, sSlave,
   172       variable v     : RegType;
   173       variable dummy : slv(1 downto 0);
   175       -- Latch the current value   181       v.dbg     := (others => '0');
   182       v.tKeep   := (others => '0');
   184       if sSlave.tReady = '1' then   188       if txSlave.tReady = '1' then   199          x"0000",                       -- Unused in TX CSUM   202          dummy(0),                      -- Unused in TX CSUM   204          dummy(1),                      -- Unused in TX CSUM   207       -- Pipeline alignment to GetEthMacCsum()   216       -- Check for UDP frame   218          -- Multiple length by 2 to combine UDP length and IPV4 Pseudo Header's length together   221          -- TCP only has IPV4 Pseudo Header's length together   227          ----------------------------------------------------------------------   236             -- Reset accumulators   237             v.ipv4Len(0) := toSlv(20, 16);
   238             v.protLen(0) := (others => '0');
   239             -- Check if ready to move data   240             if (rxMaster.tValid = '1') and (v.sMaster.tValid = '0') and (tranPause = '0') then   244                v.sMaster        := rxMaster;
   248                if (rxMaster.tLast = '1') then   249                   -- Save the EOFE value   251                   -- Write the transaction data   256                      -- Check for EtherType = IPV4 = 0x0800   261                      -- Fill in the IPv4 header checksum   262                      v.ipv4Hdr(0) := rxMaster.tData(119 downto 112);
  -- IPVersion + Header length   263                      v.ipv4Hdr(1) := rxMaster.tData(127 downto 120);
  -- DSCP and ECN        265                      -- Add the IEEE 802.1Q header   267                      v.sMaster.tData(119 downto 112) := x"0" & VID_G(11 downto 8);
   268                      v.sMaster.tData(127 downto 120) := VID_G(7 downto 0);
   271                   v.state := IPV4_HDR0_S;
   274          ----------------------------------------------------------------------   276             -- Check if ready to move data   277             if (rxMaster.tValid = '1') and (v.sMaster.tValid = '0') and (tranPause = '0') then   281                v.sMaster        := rxMaster;
   283                if (rxMaster.tLast = '1') then   284                   -- if IPv4 detected, ETH frame too short    285                   if (r.ipv4Det(0) = '1') then   286                      -- Set the error flag   289                      -- Save the EOFE value   292                   -- Write the transaction data   299                      -- Fill in the IPv4 header checksum   300                      v.ipv4Hdr(4)         := rxMaster.tData(23 downto 16);
  -- IPV4_ID(15 downto 8)   301                      v.ipv4Hdr(5)         := rxMaster.tData(31 downto 24);
  -- IPV4_ID(7 downto 0)   302                      v.ipv4Hdr(6)         := rxMaster.tData(39 downto 32);
  -- Flags(2 downto 0) and Fragment Offsets(12 downto 8)   303                      v.ipv4Hdr(7)         := rxMaster.tData(47 downto 40);
  -- Fragment Offsets(7 downto 0)   304                      v.ipv4Hdr(8)         := rxMaster.tData(55 downto 48);
  -- Time-To-Live   305                      v.ipv4Hdr(9)         := rxMaster.tData(63 downto 56);
  -- Protocol   306                      v.ipv4Hdr(12)        := rxMaster.tData(87 downto 80);
  -- Source IP Address   307                      v.ipv4Hdr(13)        := rxMaster.tData(95 downto 88);
  -- Source IP Address   308                      v.ipv4Hdr(14)        := rxMaster.tData(103 downto 96);
  -- Source IP Address   309                      v.ipv4Hdr(15)        := rxMaster.tData(111 downto 104);
  -- Source IP Address   310                      v.ipv4Hdr(16)        := rxMaster.tData(119 downto 112);
  -- Destination IP Address   311                      v.ipv4Hdr(17)        := rxMaster.tData(127 downto 120);
  -- Destination IP Address       312                      -- Fill in the TCP/UDP checksum   313                      v.tData(63 downto 0) := rxMaster.tData(127 downto 80) & rxMaster.tData(63 downto 56) & x"00";
   314                      v.tKeep(7 downto 0)  := (others => '1');
   316                      -- Check for EtherType = IPV4 = 0x0800   321                      -- Fill in the IPv4 header checksum   322                      v.ipv4Hdr(0)         := rxMaster.tData(23 downto 16);
  -- IPVersion + Header length   323                      v.ipv4Hdr(1)         := rxMaster.tData(31 downto 24);
  -- DSCP and ECN   324                      v.ipv4Hdr(4)         := rxMaster.tData(55 downto 48);
  -- IPV4_ID(15 downto 8)   325                      v.ipv4Hdr(5)         := rxMaster.tData(63 downto 56);
  -- IPV4_ID(7 downto 0)   326                      v.ipv4Hdr(6)         := rxMaster.tData(71 downto 64);
  -- Flags(2 downto 0) and Fragment Offsets(12 downto 8)   327                      v.ipv4Hdr(7)         := rxMaster.tData(79 downto 72);
  -- Fragment Offsets(7 downto 0)   328                      v.ipv4Hdr(8)         := rxMaster.tData(87 downto 80);
  -- Time-To-Live   329                      v.ipv4Hdr(9)         := rxMaster.tData(95 downto 88);
  -- Protocol   330                      v.ipv4Hdr(12)        := rxMaster.tData(119 downto 112);
  -- Source IP Address   331                      v.ipv4Hdr(13)        := rxMaster.tData(127 downto 120);
  -- Source IP Address         332                      -- Fill in the TCP/UDP checksum   333                      v.tData(31 downto 0) := rxMaster.tData(127 downto 119) & rxMaster.tData(95 downto 88) & x"00";
   334                      v.tKeep(3 downto 0)  := (others => '1');
   336                   -- Check for UDP protocol   337                   if (v.ipv4Hdr(9) = UDP_C) then   340                   -- Check for TCP protocol   341                   if (v.ipv4Hdr(9) = TCP_C) then   345                   v.state := IPV4_HDR1_S;
   348          ----------------------------------------------------------------------   350             -- Check if ready to move data   351             if (rxMaster.tValid = '1') and (v.sMaster.tValid = '0') and (tranPause = '0') then   355                v.sMaster        := rxMaster;
   356                -- Fill in the TCP/UDP checksum   361                   -- Fill in the IPv4 header checksum   362                   v.ipv4Hdr(18) := rxMaster.tData(7 downto 0);
  -- Destination IP Address   363                   v.ipv4Hdr(19) := rxMaster.tData(15 downto 8);
  -- Destination IP Address      364                   -- Check for UDP data with inbound length/checksum   365                   if (r.ipv4Det(0) = '1') and (r.udpDet(0) = '1') then   366                      -- Mask off inbound UDP length/checksum   367                      v.tData := rxMaster.tData(127 downto 80) & x"00000000" & rxMaster.tData(47 downto 0);
   369                   -- Track the number of bytes    370                   v.ipv4Len(0) := r.ipv4Len(0) + getTKeep(rxMaster.tKeep) - 2;
   371                   v.protLen(0) := r.protLen(0) + getTKeep(rxMaster.tKeep) - 2;
   373                   -- Fill in the IPv4 header checksum   374                   v.ipv4Hdr(14) := rxMaster.tData(7 downto 0);
  -- Source IP Address   375                   v.ipv4Hdr(15) := rxMaster.tData(15 downto 8);
  -- Source IP Address   376                   v.ipv4Hdr(16) := rxMaster.tData(23 downto 16);
  -- Destination IP Address   377                   v.ipv4Hdr(17) := rxMaster.tData(31 downto 24);
  -- Destination IP Address                  378                   v.ipv4Hdr(18) := rxMaster.tData(39 downto 32);
  -- Destination IP Address   379                   v.ipv4Hdr(19) := rxMaster.tData(47 downto 40);
  -- Destination IP Address      380                   -- Check for UDP data with inbound length/checksum   381                   if (r.ipv4Det(0) = '1') and (r.udpDet(0) = '1') then   382                      -- Mask off inbound UDP length/checksum   383                      v.tData := rxMaster.tData(127 downto 112) & x"00000000" & rxMaster.tData(79 downto 0);
   385                   -- Track the number of bytes    386                   v.ipv4Len(0) := r.ipv4Len(0) + getTKeep(rxMaster.tKeep) - 6;
   387                   v.protLen(0) := r.protLen(0) + getTKeep(rxMaster.tKeep) - 6;
   390                if (rxMaster.tLast = '1') then   391                   -- Save the EOFE value   393                   -- Write the transaction data   402          ----------------------------------------------------------------------   404             -- Check if ready to move data   405             if (rxMaster.tValid = '1') and (v.sMaster.tValid = '0') and (tranPause = '0') then   409                v.sMaster        := rxMaster;
   410                -- Fill in the TCP/UDP checksum   413                -- Check for TCP data with inbound checksum   414                if (r.ipv4Det(0) = '1') and (r.tcpDet(0) = '1') and (r.tcpFlag = '0') then   419                      -- Mask off inbound TCP checksum   420                      v.tData := rxMaster.tData(127 downto 32) & x"0000" & rxMaster.tData(15 downto 0);
   422                      -- Mask off inbound TCP checksum   423                      v.tData := rxMaster.tData(127 downto 64) & x"0000" & rxMaster.tData(47 downto 0);
   426                -- Track the number of bytes    427                v.ipv4Len(0) := r.ipv4Len(0) + getTKeep(rxMaster.tKeep);
   428                v.protLen(0) := r.protLen(0) + getTKeep(rxMaster.tKeep);
   430                if (rxMaster.tLast = '1') or (v.ipv4Len(0) > MAX_FRAME_SIZE_C) then   431                   -- Save the EOFE value   433                   -- Check for overflow   434                   if (rxMaster.tLast = '0') then   437                      -- Write the transaction data   440                      v.state      := BLOWOFF_S;
   442                      -- Write the transaction data   449          ----------------------------------------------------------------------   451             -- Check if ready to move data   452             if (rxMaster.tValid = '1') and (v.sMaster.tValid = '0') then   456                if (rxMaster.tLast = '1') then   461       ----------------------------------------------------------------------   464       -- Fill in the IPv4 header   465       v.ipv4Hdr(2) := v.ipv4Len(0)(15 downto 8);
  -- IPV4_Length(15 downto 8)   466       v.ipv4Hdr(3) := v.ipv4Len(0)(7 downto 0);
  -- IPV4_Length(7 downto 0)           468       -- Wait for the transaction data    469       if (tranValid = '1') and (r.tranRd = '0') then   471          if (mMaster.tValid = '1') and (v.txMaster.tValid = '0') then   475             v.txMaster      := mMaster;
   476             -- Check if not forwarding EOFE frames   481             -- Check the counter size   482             if (r.mvCnt /= 4) then   483                -- Increment the counter   484                v.mvCnt := r.mvCnt + 1;
   486             -- Check for IPv4 checksum/length insertion    487             if (ipv4Det = '1') and (r.mvCnt = 1) then   490                   -- Check if firmware checksum enabled   492                      -- Overwrite the data field   493                      v.txMaster.tData(7 downto 0)   := ipv4Len(15 downto 8);
   494                      v.txMaster.tData(15 downto 8)  := ipv4Len(7 downto 0);
   495                      v.txMaster.tData(71 downto 64) := ipv4Csum(15 downto 8);
   496                      v.txMaster.tData(79 downto 72) := ipv4Csum(7 downto 0);
   498                   -- Check for mismatch between firmware/software IPv4 length   499                   if (ipv4Len(15 downto 8) /= mMaster.tData(7 downto 0)) or (ipv4Len(7 downto 0) /= mMaster.tData(15 downto 8)) then   503                   -- Check for mismatch between firmware/software IPv4 checksum   504                   if (ipv4Csum(15 downto 8) /= mMaster.tData(71 downto 64)) or (ipv4Csum(7 downto 0) /= mMaster.tData(79 downto 72)) then   509                   -- Check if firmware checksum enabled   511                      -- Overwrite the data field   512                      v.txMaster.tData(39 downto 32)   := ipv4Len(15 downto 8);
   513                      v.txMaster.tData(47 downto 40)   := ipv4Len(7 downto 0);
   514                      v.txMaster.tData(103 downto 96)  := ipv4Csum(15 downto 8);
   515                      v.txMaster.tData(111 downto 104) := ipv4Csum(7 downto 0);
   517                   -- Check for mismatch between firmware/software IPv4 length   518                   if (ipv4Len(15 downto 8) /= mMaster.tData(39 downto 32)) or (ipv4Len(7 downto 0) /= mMaster.tData(47 downto 40)) then   522                   -- Check for mismatch between firmware/software IPv4 checksum   523                   if (ipv4Csum(15 downto 8) /= mMaster.tData(103 downto 96)) or (ipv4Csum(7 downto 0) /= mMaster.tData(111 downto 104)) then   529             -- Check for UDP checksum/length insertion and no fragmentation   530             if (ipv4Det = '1') and (udpDet = '1') and (fragDet = '0') and (r.mvCnt = 2) then   533                   -- Check if firmware checksum enabled   535                      -- Overwrite the data field   536                      v.txMaster.tData(55 downto 48) := protLen(15 downto 8);
   537                      v.txMaster.tData(63 downto 56) := protLen(7 downto 0);
   538                      v.txMaster.tData(71 downto 64) := protCsum(15 downto 8);
   539                      v.txMaster.tData(79 downto 72) := protCsum(7 downto 0);
   541                   -- Check for mismatch between firmware/software UDP length   542                   if (protLen(15 downto 8) /= mMaster.tData(55 downto 48)) or (protLen(7 downto 0) /= mMaster.tData(63 downto 56)) then   546                   -- Check for mismatch between firmware/software UDP checksum   547                   if (protCsum(15 downto 8) /= mMaster.tData(71 downto 64)) or (protCsum(7 downto 0) /= mMaster.tData(79 downto 72)) then   552                   -- Check if firmware checksum enabled   554                      -- Overwrite the data field   555                      v.txMaster.tData(87 downto 80)   := protLen(15 downto 8);
   556                      v.txMaster.tData(95 downto 88)   := protLen(7 downto 0);
   557                      v.txMaster.tData(103 downto 96)  := protCsum(15 downto 8);
   558                      v.txMaster.tData(111 downto 104) := protCsum(7 downto 0);
   560                   -- Check for mismatch between firmware/software UDP length   561                   if (protLen(15 downto 8) /= mMaster.tData(87 downto 80)) or (protLen(7 downto 0) /= mMaster.tData(95 downto 88)) then   565                   -- Check for mismatch between firmware/software UDP checksum   566                   if (protCsum(15 downto 8) /= mMaster.tData(103 downto 96)) or (protCsum(7 downto 0) /= mMaster.tData(111 downto 104)) then   572             -- Check for TCP checksum insertion and no fragmentation   573             if (ipv4Det = '1') and (tcpDet = '1') and (fragDet = '0') and (r.mvCnt = 3) then   576                   -- Check if firmware checksum enabled   578                      -- Overwrite the data field   579                      v.txMaster.tData(23 downto 16) := protCsum(15 downto 8);
   580                      v.txMaster.tData(31 downto 24) := protCsum(7 downto 0);
   582                   -- Check for mismatch between firmware/software TCP checksum   583                   if (protCsum(15 downto 8) /= mMaster.tData(23 downto 16)) or (protCsum(7 downto 0) /= mMaster.tData(31 downto 24)) then   588                   -- Check if firmware checksum enabled   590                      -- Overwrite the data field   591                      v.txMaster.tData(55 downto 48) := protCsum(15 downto 8);
   592                      v.txMaster.tData(63 downto 56) := protCsum(7 downto 0);
   594                   -- Check for mismatch between firmware/software TCP checksum   595                   if (protCsum(15 downto 8) /= mMaster.tData(55 downto 48)) or (protCsum(7 downto 0) /= mMaster.tData(63 downto 56)) then   602             if (mMaster.tLast = '1') then   619       -- Register the variable for next clock cycle   623       rxSlave  <= v.rxSlave;
   624       sMaster  <= r.sMaster;
   626       txMaster <= r.txMaster;
   632       if rising_edge(ethClk) then   633          r <= rin after TPD_G;
   639          -- General Configurations   645          -- FIFO configurations   651          -- AXI Stream Port Configurations   677          --Write Ports (wr_clk domain)   679          din
(68)            => r.fragDet
(EMAC_CSUM_PIPELINE_C+1
),
   680          din
(67)            => r.eofeDet
(EMAC_CSUM_PIPELINE_C+1
),
   681          din
(66)            => r.ipv4Det
(EMAC_CSUM_PIPELINE_C+1
),
   682          din
(65)            => r.udpDet
(EMAC_CSUM_PIPELINE_C+1
),
   683          din
(64)            => r.tcpDet
(EMAC_CSUM_PIPELINE_C+1
),
   684          din
(63 downto 48)  => r.ipv4Len
(EMAC_CSUM_PIPELINE_C+1
),
   685          din
(47 downto 32)  => r.ipv4Csum,
   686          din
(31 downto 16)  => r.protLen
(EMAC_CSUM_PIPELINE_C+1
),
   687          din
(15 downto 0)   => r.protCsum,
   689          --Read Ports (rd_clk domain)   696          dout
(63 downto 48) => ipv4Len,
   697          dout
(47 downto 32) => ipv4Csum,
   698          dout
(31 downto 16) => protLen,
   699          dout
(15 downto 0)  => protCsum,
 FIFO_ADDR_WIDTH_Ginteger   range  4 to  48:= 9
 
PIPE_STAGES_Gnatural   range  0 to  16:= 0
 
ADDR_WIDTH_Ginteger   range  4 to  48:= 4
 
out mAxisMasterAxiStreamMasterType  
 
in mAxisSlaveAxiStreamSlaveType  
 
VID_Gslv( 11 downto  0)  := x"001"
 
PIPE_STAGES_Gnatural   range  0 to  16:= 1
 
in rstsl  :=not    RST_POLARITY_G
 
slv( 7 downto  0)  := x"06" TCP_C
 
slv( 15 downto  0)  := x"0008" IPV4_TYPE_C
 
AxiStreamMasterType  :=(tValid  => '0',tData  =>( others => '0'),tStrb  =>( others => '1'),tKeep  =>( others => '1'),tLast  => '0',tDest  =>( others => '0'),tId  =>( others => '0'),tUser  =>( others => '0')) AXI_STREAM_MASTER_INIT_C
 
SLAVE_AXI_CONFIG_GAxiStreamConfigType  :=   AXI_STREAM_CONFIG_INIT_C
 
out sAxisSlaveAxiStreamSlaveType  
 
SLAVE_READY_EN_Gboolean  :=   true
 
in mAxisSlaveAxiStreamSlaveType  
 
slv(   EMAC_CSUM_PIPELINE_C downto  0)   step
 
GEN_SYNC_FIFO_Gboolean  :=   false
 
DATA_WIDTH_Ginteger   range  1 to ( 2** 24):= 16
 
integer  := 0 EMAC_FRAG_BIT_C
 
EthMacCsumAccumType  :=(step  =>( others => '0'),sum1  =>( others =>( others => '0')),sum3  =>( others => '0'),sum5  =>( others => '0')) ETH_MAC_CSUM_ACCUM_INIT_C
 
FULL_THRES_Ginteger   range  1 to ( 2** 24):= 1
 
INT_PIPE_STAGES_Gnatural   range  0 to  16:= 0
 
natural  := 3 EMAC_CSUM_PIPELINE_C
 
in sAxisMasterAxiStreamMasterType  
 
AxiStreamSlaveType  :=(tReady  => '0') AXI_STREAM_SLAVE_INIT_C
 
in sAxisMasterAxiStreamMasterType  
 
integer  := 0 EMAC_EOFE_BIT_C
 
DROP_ERR_PKT_Gboolean  :=   true
 
out sAxisSlaveAxiStreamSlaveType  
 
out mAxisMasterAxiStreamMasterType  
 
out sAxisSlaveAxiStreamSlaveType  
 
array(natural range <> ) of slv( 15 downto  0)   Slv16Array
 
slv( 15 downto  0)  := x"0081" VLAN_TYPE_C
 
in sAxisMasterAxiStreamMasterType  
 
FWFT_EN_Gboolean  :=   false
 
out mAxisMasterAxiStreamMasterType  
 
slv( 7 downto  0)  := x"11" UDP_C
 
in mAxisSlaveAxiStreamSlaveType  
 
CASCADE_SIZE_Ginteger   range  1 to ( 2** 24):= 1
 
USE_BUILT_IN_Gboolean  :=   false
 
array(natural range <> ) of slv( 7 downto  0)   Slv8Array
 
VALID_THOLD_Ginteger   range  0 to ( 2** 24):= 1
 
MASTER_AXI_CONFIG_GAxiStreamConfigType  :=   AXI_STREAM_CONFIG_INIT_C
 
AxiStreamConfigType  :=(TSTRB_EN_C  =>   false,TDATA_BYTES_C  => 16,TDEST_BITS_C  => 8,TID_BITS_C  => 0,TKEEP_MODE_C  =>   TKEEP_COMP_C,TUSER_BITS_C  => 4,TUSER_MODE_C  =>   TUSER_FIRST_LAST_C) EMAC_AXIS_CONFIG_C
 
array(natural range <> ) of EthMacCsumAccumType   EthMacCsumAccumArray