further cleanup of MarinaTest
[fleet.git] / src / edu / berkeley / fleet / marina / MarinaPacket.java
1 package edu.berkeley.fleet.marina;
2 /* -*- tab-width: 4 -*- */
3 import com.sun.electric.tool.simulation.test.*;
4 import edu.berkeley.fleet.api.Dock;
5 import edu.berkeley.fleet.api.Instruction;
6
7 /**
8  * This class encapsulates a "packet" -- a data item in flight plus
9  * its tokenhood and path.
10  *
11  * This should be the only class that knows how to turn a packet into
12  * its constituent parts and vice versa.
13  */
14 public class MarinaPacket {
15
16     public static final int PATH_WIDTH   = 14;
17     public static final int WORD_WIDTH   = 37;
18     public static final int PACKET_WIDTH = PATH_WIDTH+WORD_WIDTH+1;
19
20     public final BitVector data;
21     public final boolean tokenhood;
22     public final BitVector path;
23     private final boolean is_instruction;
24
25     public static final BitVector null_path = new BitVector(PATH_WIDTH, "null_path");
26     public static final BitVector null_word = new BitVector(WORD_WIDTH, "null_word");
27     static {
28         null_path.set(0, PATH_WIDTH, false);
29         null_word.set(0, WORD_WIDTH, false);
30     }
31
32     /** "parse" a token from the raw bits in the north proper stopper */
33     public MarinaPacket(BitVector singleBitVector) {
34         MarinaUtils.expectLength(singleBitVector,PACKET_WIDTH);
35         this.data = new BitVector(WORD_WIDTH, "marina packet data");
36         this.path = new BitVector(PATH_WIDTH, "marina packet path");
37         this.tokenhood = !singleBitVector.get(0);
38         this.is_instruction = false;
39         for(int i=0; i<PATH_WIDTH; i++) path.set(i, singleBitVector.get(i+1));
40         for(int i=0; i<WORD_WIDTH; i++) data.set(i, singleBitVector.get(i+PATH_WIDTH+1));
41     }
42
43     /** manually assemble a packet */
44     public MarinaPacket(BitVector data, boolean tokenhood, BitVector path) {
45         MarinaUtils.expectLength(data, WORD_WIDTH);
46         MarinaUtils.expectLength(path, PATH_WIDTH);
47         this.data = data;
48         this.tokenhood = tokenhood;
49         this.path = path;
50         this.is_instruction = false;
51     }
52
53     /** another constructor which uses an all-zeroes path, for convenience */
54     public MarinaPacket(Instruction inst) {
55         Marina marina = (Marina)inst.dock.getShip().getFleet();
56         BitVector instr = MarinaUtils.berkToSun(marina.encodeInstruction(marina.getOnlyDock(), inst));
57         MarinaUtils.expectLength(instr, MarinaPacket.WORD_WIDTH);
58         
59         //
60         // Due to what Ivan calls "geometric inconvenience", incoming
61         // bit 19 is dropped, and all the higher bits are shifted
62         // downward by one position.  So we have to compensate for
63         // this by inserting a bogus bit at position #19.
64         //
65         BitVector pad = new BitVector(1, "pad");
66         pad.setFromLong(0);
67         this.data = instr.get(0, 18).cat(pad).cat(instr.get(18,18));
68         this.path = null_path;
69         this.tokenhood = false;
70         this.is_instruction = true;
71     }
72
73     /** convert a packet into a single BitVector, suitable for insertion in the north proper stopper */
74     public BitVector toSingleBitVector() {
75         BitVector bv = new BitVector(PACKET_WIDTH, "marina packet");
76         bv.set(0, !tokenhood);
77         for(int i=0; i<PATH_WIDTH; i++) bv.set(i+1,            path.get(i));
78         for(int i=0; i<WORD_WIDTH; i++) bv.set(i+PATH_WIDTH+1, data.get(i));
79         return bv;
80     }
81
82     public String toString() {
83         return
84             "tokenhood="+(tokenhood ? "token" : "data")
85             + ", path["+PATH_WIDTH+":1]=" + path.bitReverse().getState()
86             + ", data["+WORD_WIDTH+":1]=" +
87             (is_instruction
88              ? (data.get(19,18).bitReverse().getState()+"_"+data.get(0,18).bitReverse().getState())
89              : data.bitReverse().getState());
90     }
91 }