Clean up and document interfaces for Adam
authorrkao <rkao>
Thu, 21 Aug 2008 17:54:38 +0000 (17:54 +0000)
committerrkao <rkao>
Thu, 21 Aug 2008 17:54:38 +0000 (17:54 +0000)
testCode/com/sun/vlsi/chips/marina/test/MarinaTest.java
testCode/com/sun/vlsi/chips/marina/test/MarinaUtils.java
testCode/com/sun/vlsi/chips/marina/test/ProperStopper.java

index 95ed095..7e6a714 100644 (file)
@@ -80,18 +80,6 @@ public class MarinaTest {
        System.out.println("Test took: "+(endTime-startTime)/1000.0+"  sec");
        }
     
-       private void doOneTest(int testNum) {
-        prln("MarinaTest: performing test: "+testNum);
-        masterClear();
-        resetAfterMasterClear();
-        
-               switch (testNum) {
-               case 0:                 stopToStopOneItem();               break;
-               default:
-                       fatal(true, "Test number: "+testNum+" doesn't exist.");
-                       break;
-               }
-       }
        // Tell user what we're about to do
        private static void reportTask(MarinaUtils.CmdArgs args) {
                System.out.println("Begin testing Marina");
@@ -112,7 +100,6 @@ public class MarinaTest {
                fatal(true, "unrecognized CmdArgs.Mode");
                return;
         }
-
        }
        
        private static void standAlone(String[] args) {
@@ -235,83 +222,6 @@ public class MarinaTest {
        }
        return ans;
     }
-    /** Generate List of BitVectors where Token=true, high 25 data bits  
-     * are alternating ones and zeros, low 12 data bits increment from 
-     * zero, and address is given by random number generator. */
-    private List<BitVector> makeIncrDataRandAdr(int num, Random rand) {
-       List<BitVector> ans = new ArrayList<BitVector>();
-       BitVector dHi = new BitVector(25, "dataHi");
-       BitVector dLo = new BitVector(12, "dataLo");
-       BitVector t = new BitVector("1", "token");
-       BitVector a = new BitVector(14, "addr");
-       dHi.setFromLong(0x00aaaaa);
-       for (int i=0; i<num; i++) {
-               dLo.setFromLong(i);
-               a.setFromLong((long)rand.nextInt());
-               ans.add(dHi.cat(dLo).cat(t).cat(a));
-               dHi = dHi.not();
-       }
-       return ans;
-    }
-    /** Generate List of BitVectors where Token=true, all 37 data bits  
-     * are given by dat, and address is given by addr. */
-    private List<BitVector> makeConstDataConstAdr(int num, long dat, boolean tok, int addr) {
-       List<BitVector> ans = new ArrayList<BitVector>();
-       BitVector d = new BitVector(37, "data");
-       BitVector t = new BitVector(1, "token");
-       BitVector a = new BitVector(14, "addr");
-       d.setFromLong(dat);
-       t.setFromLong(tok ? 0 : 1);
-       a.setFromLong(addr);
-       for (int i=0; i<num; i++) {
-               ans.add(d.cat(t).cat(a));
-       }
-       return ans;
-    }
-
-    /** Generate List of BitVectors where Token=true, the address MSB
-     * is given by addrMsb, all 37 data bits alternate between all ones
-     * and all zeros, and 13 address LSBs alternate between count and
-     * inverted count */
-    private List<BitVector> makeAltCountCountBar(int num, int addrMsb) {
-       List<BitVector> ans = new ArrayList<BitVector>();
-       BitVector d = new BitVector(37, "data");
-       BitVector t = new BitVector("1", "token");
-       BitVector aHi = new BitVector(1, "addrHi");
-       BitVector aLo = new BitVector(13, "addrLo");
-       aHi.setFromLong(addrMsb);
-       for (int i=0; i<num; i++) {
-                       d.setFromLong(0);
-                       aLo.setFromLong(i);
-               if (i%2==1) {
-                       d = d.not();
-                       aLo = aLo.not();
-               }
-               ans.add(d.cat(t).cat(aHi).cat(aLo));
-       }
-       return ans;
-    }
-
-    /** Generate List of BitVectors where Token=true, the address MSB
-     * is given by addrMsb, data bits alternate between 0xaaaa and 0x55555.
-     * 13 address LSBs alternate between 0xaaaa and 0x5555 */
-    private List<BitVector> makeAltAAA555(int num, int addrMsb) {
-       List<BitVector> ans = new ArrayList<BitVector>();
-       BitVector d = new BitVector(37, "data");
-       BitVector t = new BitVector("1", "token");
-       BitVector aHi = new BitVector(1, "addrHi");
-       BitVector aLo = new BitVector(13, "addrLo");
-               d.setFromLong(0xaaaaaaaaaaL);
-       aHi.setFromLong(addrMsb);
-       aLo.setFromLong(0xaaaaaaaa);
-       for (int i=0; i<num; i++) {
-               ans.add(d.cat(t).cat(aHi).cat(aLo));
-               d = d.not();
-               aLo = aLo.not();
-       }
-       return ans;
-    }
-
     private void stopToStop(ProperStopper s1, ProperStopper s2, 
                                List<BitVector> din) {
        prln("Begin stopToStop");
@@ -348,7 +258,6 @@ public class MarinaTest {
      * is then run to allow the burst to flow. */
     private void stopToStopBurst(ProperStopper src, ProperStopper gate, 
                                     ProperStopper dst,
-                                    boolean ctrAChg, boolean ctrBChg,
                                     List<BitVector> din) {
                prln("Begin stopToStopBurst test");
                adjustIndent(2);
@@ -357,8 +266,8 @@ public class MarinaTest {
                gate.stop();
                mar.shiftControl(false, true);
                
-       mar.shiftData();
-       long ctrAStart = mar.counter.getCount();
+//     mar.shiftData();
+//     long ctrAStart = mar.counter.getCount();
                
                src.fillMany(din);
                waitUntilQuiescent();
@@ -372,15 +281,15 @@ public class MarinaTest {
                
                MarinaUtils.compareItemsOrdered(din, dout);
                
-       mar.shiftData();
-        long ctrAEnd = mar.counter.getCount();
-        long deltaA = ctrAEnd - ctrAStart;
-        
-        long sz = din.size();
-        long expectA = ctrAChg ? sz : 0;
-        fatal(deltaA!=expectA, 
-                 "counter A delta wrong: expected delta: "+expectA+
-                 " counter before:"+ctrAStart+" counter after:"+ctrAEnd);
+//     mar.shiftData();
+//        long ctrAEnd = mar.counter.getCount();
+//        long deltaA = ctrAEnd - ctrAStart;
+//        
+//        long sz = din.size();
+//        long expectA = ctrAChg ? sz : 0;
+//        fatal(deltaA!=expectA, 
+//               "counter A delta wrong: expected delta: "+expectA+
+//               " counter before:"+ctrAStart+" counter after:"+ctrAEnd);
         
                
                adjustIndent(-2);
@@ -398,6 +307,17 @@ public class MarinaTest {
        prln("End stopToStopOne");
     }
     
+    private void stopToStopThree(ProperStopper s1, ProperStopper s2, int adr) {
+       prln("Begin stopToStopOne");
+       adjustIndent(2);
+       
+       List<BitVector> din = makeIncrDataConstAdr(3, adr);
+       stopToStop(s1, s2, din);
+
+       adjustIndent(-2);
+       prln("End stopToStopOne");
+    }
+
     private BitVector extractAddr(BitVector dataTokAddr) {
        fatal(dataTokAddr.getNumBits()!=37+1+14, "wrong length for data token addr");
        return dataTokAddr.get((37+1), 14);
@@ -424,219 +344,6 @@ public class MarinaTest {
        }
        return sb.toString();
     }
-    // Items in dIn must be unique
-    private int checkRingData(String ringNm, List<BitVector> dIn, 
-                                  List<BitVector> dOut) {
-       int sz = dIn.size();
-       
-       fatal(dOut.size()!=sz,  ringNm+
-                 " wrong number of items. Expected:"+sz+", got:"+dOut.size()+"\n"+
-                 ringDump(dIn, dOut));
-
-       // it's ok if both input and output are empty
-       if (sz==0) return 0;
-       
-       // find offset
-       BitVector first = dIn.get(0);
-       int offset=0;
-       for (; offset<sz; offset++) {
-               if (dOut.get(offset).equals(first)) break;
-       }
-       fatal(offset==sz, ringNm+" first input item not found in output: "+first.getState()+"\n"+
-                 ringDump(dIn, dOut));
-       
-       prln("Output item offset: "+offset);
-       
-       // compare all items
-       for (int i=0; i<sz; i++) {
-               int outNdx = (i + offset + sz) % sz;
-               BitVector out = dOut.get(outNdx);
-               BitVector in = dIn.get(i);
-               
-               if (!in.equals(out)) {
-                       fatal(true, ringNm+" "+i+"th input item:"+in.getState()+"\n"+
-                         "doesn't match "+outNdx+"th output item: "+out.getState()+"\n"+
-                         ringDump(dIn, dOut));
-               }
-       }
-       return  offset;
-    }
-    // Weaker test because it allows arbitrary re-ordering
-    private void checkUnorderedData(String ringNm, List<BitVector> dIn, 
-                                    List<BitVector> dOut, boolean token) {
-               int sz = dIn.size();
-               
-               fatal(dOut.size()!=sz,  ringNm+
-                     " wrong number of items. Expected:"+sz+", got:"+dOut.size()+"\n"+
-                     ringDump(dIn, dOut));
-               
-               // ignore data bits if token
-               BitVector mask = new BitVector(37+1+14, "mask");
-               mask.setFromLong(token ? 0x7fff : -1L);
-
-               // compare all items
-               for (BitVector  in : dIn) {
-                       boolean found = false;
-                       for (Iterator<BitVector> oIt=dOut.iterator(); oIt.hasNext();) {
-                               BitVector out = oIt.next();
-//                             BitVector im  = in.and(mask);
-//                             BitVector om = out.and(mask);
-//                             prln("Mask: "+mask.getState());
-//                             prln("oMask:"+om.getState());
-//                             prln("iMask:"+im.getState());
-                               
-                               if (in.and(mask).equals(out.and(mask))) {
-                                       oIt.remove();
-                                       found = true;
-                                       break;
-                               }
-                       }
-                       if(!found) {
-                               fatal(true, "Input vector: "+in.getState()+" missing from output.\n"+
-                                           ringDump(dIn, dOut));
-                       }
-               }
-       }
-    
-//    private RingResult throughputVsOccupancy(String ringNm, ProperStopper src, 
-//                                              Counter counter,
-//                                              List<BitVector> items,
-//                                              boolean token,
-//                                              double runTimeNs) {
-//     List<Long> counts = new ArrayList<Long>();
-//     List<Double> currents = new ArrayList<Double>();
-//     List<Double> voltErr = new ArrayList<Double>();
-//     
-//     prln("run all stoppers except the source stopper");
-//     mar.stopper1.run();
-//     mar.stopper2.run();
-//             src.stop();
-//     mar.shiftControl(false, true);
-//     
-//     // pause so we can measure quiescent current
-//     model.waitNS(runTimeNs/2);
-//     model.waitNS(runTimeNs/2);
-//
-//     // count is zero for no items
-//     counts.add((long)0);
-//
-//     List<BitVector> someItems = new ArrayList<BitVector>();
-//     for (int i=0; i<items.size(); i++) {
-//             prln("---------------------------------------------------------");
-//             someItems.add(items.get(i));
-//
-//             prln("Run with "+(i+1)+" items");
-//             src.fillMany(someItems);
-//             src.stop();
-//             mar.shiftControl(false, true);
-//             
-//             prln("Begin current run: "+runTimeNs+" nanoseconds");
-//             adjustIndent(2);
-//             src.run();
-//             mar.shiftControl(false, true);
-//
-//             
-//             model.waitNS(runTimeNs/2);
-//             currents.add(readCurrent());
-//             model.waitNS(runTimeNs/2);
-//
-//             src.stop();
-//             mar.shiftControl(false, true);
-//             adjustIndent(-2);
-//             prln("End current run");
-//             
-//             prln("Begin throughput run: "+runTimeNs+" nanoseconds");
-//             adjustIndent(2);
-//             mar.shiftData();
-//             long beforeCnt = counter.getCount();
-//
-//             src.run();
-//             mar.shiftControl(false, true);
-//
-//             model.waitNS(runTimeNs);
-//             
-//             src.stop();
-//             mar.shiftControl(false, true);
-//
-//             mar.shiftData();
-//             long afterCnt = counter.getCount();
-//             counts.add(afterCnt - beforeCnt);
-//             adjustIndent(-2);
-//             prln("End throughput run");
-//
-//             prln("Check data in Ring");
-//             List<BitVector> dOut = src.drainMany();
-//             checkUnorderedData(ringNm, someItems, dOut, token);
-//     }
-//     
-//     List<Double> thruput = computeThroughput(counts, runTimeNs);
-//     return new RingResult(thruput, currents, voltErr);
-//    }
-//    private void throughput(String resultsFile, boolean constDataAddr, boolean token, Select select) {
-//     final double NS_PER_SEC = 1e9;
-//     final int nbItems = 98;
-//     final double wait = sim() ? 200 : 2 * NS_PER_SEC;
-//
-//     prln("Measure throughput A. Oscillation time="+wait+"ns, max #items="+nbItems);
-//     adjustIndent(2);
-//     List<BitVector> d;
-//     if (constDataAddr) {
-//             d = makeConstDataConstAdr(nbItems, 0, token, 0);
-//     } else {
-//             d = makeAltAAA555(nbItems, 0);
-//     }
-//     RingResult resultA = throughputVsOccupancy("A", mar.stopper1,
-//                                                   mar.counter, d, 
-//                                                   token, wait);
-//     adjustIndent(-2);
-//     prln("throughput A done");
-//
-//     
-//     List<RingResult> results = new ArrayList<RingResult>();
-//     results.add(resultA);
-//     saveThruputResults(resultsFile,
-//                                "number of items, ringA throughput, ringA current, ringA Vdd error,"+
-//                                                " ringB throughput, ringB current, ringB Vdd error",
-//                                select, results);
-//    }
-//    // Run ring A half full to draw max current 
-//    private void maxCurrent() {
-//     final double SEC_TO_NS =  1e9; 
-//     final int nbItems = 50;
-//     final double runTimeNS = 10*SEC_TO_NS;
-//     List<BitVector> aIn = makeAltCountCountBar(nbItems, 0);
-//     prln("Begin: maxCurrent");
-//     mar.stopper2.run();
-//     
-//     prln("Fill first stopper A1");
-//     mar.stopper1.fillMany(aIn);
-//     waitUntilQuiescent();
-//     
-//     mar.shiftData();
-//     long aCnt0 = mar.counter.getCount();
-//     prln("initial a counter="+aCnt0);
-//     
-//     prln("Let rings run for "+runTimeNS+" nanoseconds.");
-//     mar.stopper1.run();
-//     mar.shiftControl(false, true);
-//     
-//     model.waitNS(runTimeNS);
-//     
-//     prln("stop stopper A1");
-//     mar.stopper1.stop();
-//     mar.shiftControl(false, true);
-//     waitUntilQuiescent();
-//     
-//     mar.shiftData();
-//     long aCnt1 = mar.counter.getCount();
-//     prln("final a counter="+aCnt1);
-//     
-//     prln("check ring data");
-//     List<BitVector> aOut = mar.stopper1.drainMany();
-//     
-//     checkRingData("Ring A", aIn, aOut);
-//     prln("Passed: maxCurrent");
-//    }
 
     private int[][] makeIntArray2D(int a, int b) {
        int[][] ans = new int[a][];
@@ -661,6 +368,23 @@ public class MarinaTest {
     private void stopToStopOneItem() {
        stopToStopOne(mar.stopper1, mar.stopper2, -1);
     }
+    private void stopToStopThreeItems() {
+       stopToStopThree(mar.stopper1, mar.stopper2, -1);
+    }
+       private void doOneTest(int testNum) {
+        prln("MarinaTest: performing test: "+testNum);
+        masterClear();
+        resetAfterMasterClear();
+        
+               switch (testNum) {
+               case 0:                 stopToStopOneItem();               break;
+               case 1:                 stopToStopThreeItems();                    break;
+               default:
+                       fatal(true, "Test number: "+testNum+" doesn't exist.");
+                       break;
+               }
+       }
+
 
     //============================ for public use =============================
 
index b1d61ee..747a971 100644 (file)
@@ -11,8 +11,7 @@ public class MarinaUtils {
         * changes from chip to chip.  Here is the current order for Marina
         * as of 14 Aug 2008: 
         *  Block, Fill, Go, Silent, Clear
-        *  The old bit order for Infinity was: Fill, Block, Clear, Silent, Go
-        */
+        *  The old bit order for Infinity was: Fill, Block, Clear, Silent, Go */
     public static enum RingIfc {
         RUN        ("00100"),//("00001"),
         IDLE       ("10000"),//("01000"),
index 7577f81..1bbce01 100644 (file)
@@ -40,33 +40,49 @@ public class ProperStopper {
        cc.shift(reportChain, readEnable, writeEnable);
     }
 
+    private StateWireState boolToState(boolean b) {
+       return b ? StateWireState.FULL : StateWireState.EMPTY;
+    }
+    
+    //-------------------------- public methods ----------------------------
+
+    /** Put stopper in RUN state */
     public void run() {
        cc.setInBits(controlPath, MarinaUtils.RingIfc.RUN.bits());
     }
+    /** Put stopper in IDLE state */
     public void idle() {
        cc.setInBits(controlPath, MarinaUtils.RingIfc.IDLE.bits());
     }
+    /** Put stopper in FILL state */
     public void fill() {
        cc.setInBits(controlPath, MarinaUtils.RingIfc.FILL.bits());
     }
+    /** Put stopper in BLOCK state */
     public void block() {
        cc.setInBits(controlPath, MarinaUtils.RingIfc.BLOCK.bits());
     }
+    /** Put stopper in STOP state */
     public void stop() {
        cc.setInBits(controlPath, MarinaUtils.RingIfc.STOP.bits());
     }
+    /** Put stopper in CLEAR state */
     public void clear() {
        cc.setInBits(controlPath, MarinaUtils.RingIfc.CLEAR.bits());
     }
+    /** Put stopper in SOURCE state */
     public void source() {
        cc.setInBits(controlPath, MarinaUtils.RingIfc.SOURCE.bits());
     }
+    /** Put stopper in STOPSOURCE state */
     public void stopSource() {
        cc.setInBits(controlPath, MarinaUtils.RingIfc.STOPSOURCE.bits());
     }
+    /** Put stopper in SINK state */
     public void sink() {
        cc.setInBits(controlPath, MarinaUtils.RingIfc.SINK.bits());
     }
+    /** Put stopper in STOPSINK state */
     public void stopSink() {
        cc.setInBits(controlPath, MarinaUtils.RingIfc.STOPSINK.bits());
     }
@@ -86,25 +102,24 @@ public class ProperStopper {
        idle();                                 // go = 0
        shiftControl(false, true);
     }
-    
-    private StateWireState boolToState(boolean b) {
-       return b ? StateWireState.FULL : StateWireState.EMPTY;
-    }
-
+    /** get value of the state wire preceeding the fill stage */
     public StateWireState getPrevStateWire() {
        BitVector b = cc.getOutBits(reportPath);
        int n = b.getNumBits(); 
        fatal(n!=4, "Bad number of Stopper report bits: "+n);
        return boolToState(cc.getOutBits(reportPath).get(0));
     }
-    /** The fill wire will be interesting if we doubt that the
+    /** get the value of drain stage fill wire.
+     * The fill wire will be interesting if we doubt that the
      * scan chain works. */
     public boolean getFillWire() {
        return cc.getOutBits(reportPath).get(1);
     }
+    /** get value of state wire between the fill and drain stages */
     public StateWireState getMyStateWire() {
        return boolToState(cc.getOutBits(reportPath).get(2));
     }
+    /** get value of drain stage stopped wire */
     public boolean getStopped() {
        return cc.getOutBits(reportPath).get(3);
     }
@@ -118,7 +133,7 @@ public class ProperStopper {
        sb.append(getStopped()+"\n");
        return sb.toString();
     }
-    
+    /** construct a ProperStopper */
     public ProperStopper(String controlChain, String controlInst, 
                                         String dataChain, String dataInst, 
                             String reportChain, String reportInst, 
@@ -134,7 +149,7 @@ public class ProperStopper {
        this.model = model;
        this.indenter = indenter;
     }
-    
+    /** Reset ProperStopper after the JTAG TRST has been pulsed */
     public void resetAfterMasterClear() {
        BitVector we = new BitVector(2, "write enable");
        BitVector data = new BitVector(37, "data");
@@ -149,7 +164,9 @@ public class ProperStopper {
         cc.setInBits(dataPath, wdta);
     }
     
-    /** You must stop stopper before calling fill.
+    /** Insert one item into the fill stage.
+     * Fill stage must be empty. 
+     * You must stop stopper before calling fill.
      * exit state: idle */
     public void fill(BitVector dta) {
        if (traceFill) prln("Begin fillStopper");
@@ -158,6 +175,12 @@ public class ProperStopper {
        int n = dta.getNumBits();
        fatal(n!=(37+1+14), "fillStopper: wrong num bits: "+n);
        
+       // make sure fill stage is empty
+       shiftReport(true, false);
+       StateWireState myState = getMyStateWire();
+       fatal(myState!=StateWireState.EMPTY, 
+                 "fillStopper: fill stage already full");
+       
        if (traceFill) prln("writing data: "+MarinaUtils.formatDataTokAddr(dta));
        
        idle();                                 // block = 1, go = 0
@@ -168,9 +191,9 @@ public class ProperStopper {
        cc.setInBits(dataPath, wrEn.cat(dta));
        shiftData(false, true);
        
-       fill();                                 // fire = 1
+       fill();                                 // fill = 1
        shiftControl(false, true);
-       idle();                                 // fire = 0
+       idle();                                 // fill = 0
        shiftControl(false, true);
        block();                                // go = 1
        shiftControl(false, true);
@@ -178,17 +201,10 @@ public class ProperStopper {
        shiftControl(false, true);
        
        model.waitNS(5);
-       
-       // make sure fill data was consumed
-       shiftReport(true, false);
 
        // debugging
        if (traceFill) prln(getReportString());
        
-       StateWireState myState = getMyStateWire();
-       fatal(myState!=StateWireState.EMPTY, 
-                 "fillStopper: fill data not consumed");
-       
        // if data chain is shifted in the future, don't write!
        wrEn.setFromLong(0);
        cc.setInBits(dataPath, wrEn.cat(dta));
@@ -196,7 +212,8 @@ public class ProperStopper {
        adjustIndent(-2);
        if (traceFill) prln("End fillStopper");
     }
-    /** You must stop stopper before calling fillMany()
+    /** Insert items from a list, one by one. 
+     * You must stop stopper before calling fillMany()
      * exit state: idle */
     public void fillMany(List<BitVector> data) {
        prln("begin fillMany "+data.size()+" words");
@@ -209,11 +226,18 @@ public class ProperStopper {
        adjustIndent(-2);
        prln("end fillMany");
     }
-    /** drain() will stop cleanly.
+    /** Remove one item from fill stage. Return that item.
+     * An item must be available.
+     * drain() will stop cleanly.
      * exit state: stop */
     public BitVector drain() {
        stop();                                 // all zero, block = 0, go = 0
        shiftControl(false, true);
+       
+       // make sure an item is available
+       shiftReport(true, false);
+       StateWireState myState=getMyStateWire();
+       fatal(myState==StateWireState.EMPTY, "drain: fill stage empty");
 
        shiftData(true, false);
        BitVector ans = getDatTokAdr();
@@ -230,9 +254,17 @@ public class ProperStopper {
        if (traceDrain) prln("drainStopper data: "+MarinaUtils.formatDataTokAddr(ans));
        return ans;
     }
-    /** drainStopperMany() will stop cleanly.
+    /** Remove as many items as possible from the fill stage.
+     * drainStopperMany() will stop cleanly.
      * exit state: stop */
     public List<BitVector> drainMany() {
+       return drainMany(Integer.MAX_VALUE);
+    }
+
+    /** Remove up to maxNbItems items from the fill stage.
+     * drainStopperMany() will stop cleanly.
+     * exit state: stop */
+    public List<BitVector> drainMany(int maxNbItems) {
        prln("begin drainStopperMany");
        adjustIndent(2);
        
@@ -241,12 +273,12 @@ public class ProperStopper {
        int cnt = 0;
        while (true) {
                shiftReport(true, false);
-               MarinaUtils.StateWireState myState=getMyStateWire();
+               StateWireState myState=getMyStateWire();
 
                // debugging
                if (traceDrain) prln(getReportString());
 
-               if (myState==MarinaUtils.StateWireState.EMPTY) break;
+               if (myState==StateWireState.EMPTY || cnt>maxNbItems) break;
                
                if (traceDrain) prln("drainStopperMany: reading word number: "+cnt++);