lots of changes to Marina test code, mostly for scan chain counters
[fleet.git] / ships / Rotator.ship
index c9b5790..74cb3f1 100644 (file)
@@ -11,7 +11,7 @@ out:  out
 
 The Rotator performs bitwise rotations of words.  When a value is
 present at both {\tt in} and {\tt inAmount}, both values are consumed,
-the value {\tt in} is rotated {\it towards the most significant bit}
+the value {\tt in} is rotated {\it towards the least significant bit}
 by {\tt inAmount} bits and emitted at {\tt out}.
 
 The output is undefined if {\tt inAmount} is greater than or equal to
@@ -24,49 +24,94 @@ public void service() {
   if (box_inAmount.dataReadyForShip() && box_in.dataReadyForShip() && box_out.readyForDataFromShip()) {
     long amount = box_inAmount.removeDataForShip();
     long data   = box_in.removeDataForShip();
-    long mask = ~((-1L) << getInterpreter().getWordSize());
+    long mask = ~((-1L) << getInterpreter().getWordWidth());
     data = data & mask;
-    box_out.addDataFromShip(((data << amount) | (data >> (getInterpreter().getWordSize()-amount))) & mask);
+    long res = ((data >> amount) | (data << (getInterpreter().getWordWidth()-amount))) & mask;
+    box_out.addDataFromShip(res, (res & (1L << (getInterpreter().getWordWidth()-1)))!=0);
   }
 }
 
 
 == FPGA ==============================================================
 
-  wire [`DATAWIDTH*2-1:0] double;
-  assign double = { in_d[`DATAWIDTH-1:0], in_d[`DATAWIDTH-1:0] };
+  reg [(`WORDWIDTH):0] out_d;
+  assign out_d_ = out_d;
+
+  reg full;
+  initial full = 0;
+
+  reg [5:0] shamt;
+  initial shamt = 0;
+
+  wire shamt_eq;
+  assign shamt_eq = (shamt[5:0] == (inAmount_d[5:0]));
 
   always @(posedge clk) begin
-    if (!rst) begin
+    if (rst) begin
       `reset
+      full <= 0;
     end else begin
-      if (!in_r        && in_a)       in_a    <= 0;
-      if (!inAmount_r  && inAmount_a) inAmount_a  <= 0;
-      if (out_r        && out_a)      out_r   <= 0;
-      if (in_r && !in_a && inAmount_r && !inAmount_a && !out_r && !out_a) begin
-        in_a <= 1;
-        inAmount_a <= 1;
-        out_r <= 1;
-        out_d <= double >> (`DATAWIDTH - inAmount_d);
+      `cleanup
+      if (`in_full && `inAmount_full && `out_empty) begin
+        if (!full) begin
+          out_d <= { 1'b0, in_d };
+          shamt <= 0;
+          full  <= 1;
+        end else if (!shamt_eq) begin
+          out_d <= { out_d[0], out_d[0], out_d[`WORDWIDTH-1:1] };
+          shamt <= shamt+1;
+        end else begin
+          `drain_in
+          `drain_inAmount
+          `fill_out
+          full <= 0;
+        end
       end
     end
   end
 
 == Test ==============================================================
 
+
 // expected output
 #expect 2
+#expect 0
+#expect -0x1000000000
+#expect 1
 #expect 44627559471
+#expect 0
 
 
 // ships required in order to run this code
 #ship debug        : Debug
 #ship rotator      : Rotator
 
-rotator.in:         literal 1; deliver; literal 21615257152;  deliver;
-rotator.inAmount:   literal 1; deliver; literal 20;           deliver;
-rotator.out:        [*] take, sendto debug.in;
-debug.in:           [*] take, deliver;
+debug.in: set ilc=*;  recv, deliver;
+
+rotator.in:
+   set word=1;
+   deliver;
+   set word=1;
+   deliver;
+   set word=21615257152;
+   deliver;
+rotator.inAmount:
+   set word=36;
+   deliver;
+   set word=1;
+   deliver;
+   set word=17;
+   deliver;
+rotator.out:
+   set olc=3;
+   head;
+   collect, send to debug.in;
+   set flags a=c, b=b;
+   [!a] set word=0;
+   [a]  set word=1;
+   send to debug.in;
+   tail;
+
 
 
 == Contributors =========================================================