adjust ships to use fill/drain/full/empty macros
[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 full;
40   initial full = 0;
41
42   reg [5:0] shamt;
43   initial shamt = 0;
44
45   wire shamt_eq;
46   assign shamt_eq = (shamt[5:0] == (inAmount_d[5:0]));
47
48   always @(posedge clk) begin
49     if (!rst) begin
50       `reset
51       full <= 0;
52     end else begin
53       `flush
54       `cleanup
55       if (`in_full && `inAmount_full && `out_empty) begin
56         if (!full) begin
57           out_d <= { 1'b0, in_d };
58           shamt <= 0;
59           full  <= 1;
60         end else if (!shamt_eq) begin
61           out_d <= { out_d[0], out_d[0], out_d[`DATAWIDTH-1:1] };
62           shamt <= shamt+1;
63         end else begin
64           `drain_in
65           `drain_inAmount
66           `fill_out
67           full <= 0;
68         end
69       end
70     end
71   end
72
73 == Test ==============================================================
74
75
76 // expected output
77 #expect 2
78 #expect 0
79 #expect -0x1000000000
80 #expect 1
81 #expect 44627559471
82 #expect 0
83
84
85 // ships required in order to run this code
86 #ship debug        : Debug
87 #ship rotator      : Rotator
88
89 debug.in: set ilc=*;  recv, deliver;
90
91 rotator.in:
92    set word=1;
93    deliver;
94    set word=1;
95    deliver;
96    set word=21615257152;
97    deliver;
98 rotator.inAmount:
99    set word=36;
100    deliver;
101    set word=1;
102    deliver;
103    set word=17;
104    deliver;
105 rotator.out:
106    set olc=3;
107    [Rq] collect, send to debug.in;
108    [Rq] set flags a=c, b=b;
109    [Rq] [!a] set word=0;
110    [Rq] [a]  set word=1;
111    [Rq] send to debug.in;
112    tail;
113
114
115
116 == Contributors =========================================================
117 Amir Kamil <kamil@cs.berkeley.edu>
118 Adam Megacz <megacz@cs.berkeley.edu>