0049ab88e879a979d75ff8ee897f825870b2790f
[fleet.git] / ships / Rotator.ship
1 ship: Rotator
2
3 == Ports ===========================================================
4 in:   in
5 in:   inAmount
6
7 out:  out
8
9   
10 == TeX ==============================================================
11
12 The Rotator performs bitwise rotations of words.  When a value is
13 present at both {\tt in} and {\tt inAmount}, both values are consumed,
14 the value {\tt in} is rotated {\it towards the least significant bit}
15 by {\tt inAmount} bits and emitted at {\tt out}.
16
17 The output is undefined if {\tt inAmount} is greater than or equal to
18 the number of bits in a word.
19
20
21 == Fleeterpreter ====================================================
22
23 public void service() {
24   if (box_inAmount.dataReadyForShip() && box_in.dataReadyForShip() && box_out.readyForDataFromShip()) {
25     long amount = box_inAmount.removeDataForShip();
26     long data   = box_in.removeDataForShip();
27     long mask = ~((-1L) << getInterpreter().getWordWidth());
28     data = data & mask;
29     box_out.addDataFromShip(((data << amount) | (data >> (getInterpreter().getWordWidth()-amount))) & mask);
30   }
31 }
32
33
34 == FPGA ==============================================================
35
36   reg [(`DATAWIDTH):0] out_d;
37   assign out_d_ = out_d;
38
39   reg [5:0] shamt;
40   initial shamt = 0;
41
42   wire shamt_eq;
43   assign shamt_eq = (shamt[5:0] == (inAmount_d[5:0]));
44
45   always @(posedge clk) begin
46     if (!rst) begin
47       `reset
48     end else begin
49       `flush
50       if (!in_r_       && in_a && !inAmount_r)       in_a        <= 0;
51       if (!inAmount_r_ && inAmount_a) inAmount_a  <= 0;
52       if (out_r        && out_a)      out_r       <= 0;
53       if (in_r && !in_a && inAmount_r && !inAmount_a && !out_r && !out_a) begin
54         in_a  <= 1;
55         out_d <= { 1'b0, in_d };
56         shamt <= 0;
57       end else if (in_a && inAmount_r && !inAmount_a && !out_r && !out_a) begin
58         if (!shamt_eq) begin
59            out_d <= { out_d[0], out_d[0], out_d[`DATAWIDTH-1:1] };
60            shamt <= shamt+1;
61         end else begin
62            inAmount_a <= 1;
63            out_r <= 1;
64         end
65       end
66     end
67   end
68
69 == Test ==============================================================
70
71
72 // expected output
73 #expect 2
74 #expect 0
75 #expect -0x1000000000
76 #expect 1
77 #expect 44627559471
78 #expect 0
79
80
81 // ships required in order to run this code
82 #ship debug        : Debug
83 #ship rotator      : Rotator
84
85 debug.in: set ilc=*;  recv, deliver;
86
87 rotator.in:
88    set word=1;
89    deliver;
90    set word=1;
91    deliver;
92    set word=21615257152;
93    deliver;
94 rotator.inAmount:
95    set word=36;
96    deliver;
97    set word=1;
98    deliver;
99    set word=17;
100    deliver;
101 rotator.out:
102    set olc=3;
103    [Rq] collect, send to debug.in;
104    [Rq] set flags a=c, b=b;
105    [Rq] [!a] set word=0;
106    [Rq] [a]  set word=1;
107    [Rq] send to debug.in;
108    tail;
109
110
111
112 == Contributors =========================================================
113 Amir Kamil <kamil@cs.berkeley.edu>
114 Adam Megacz <megacz@cs.berkeley.edu>