replace DATAWIDTH with WORDWIDTH
[fleet.git] / ships / Counter.ship
1 ship: Counter
2
3 == Ports ===========================================================
4 data  in:   in1
5 data  in:   in2
6 data  in:   inOp
7   constant REPEAT_C1_V1: 0
8   constant REPEAT_C1_V2: 1
9   constant REPEAT_C2_V1: 2
10   constant REPEAT_C2_V2: 3
11   constant PASS_C1_V1:   4
12   constant PASS_C1_V2:   5
13   constant PASS_C2_V1:   6
14   constant PASS_C2_V2:   7
15   constant DROP_C1_V1:   8
16   constant DROP_C1_V2:   9
17   constant DROP_C2_V1:   10
18   constant DROP_C2_V2:   11
19   constant COUNT:        12
20 data  out:  out
21
22 == Fleeterpreter ====================================================
23 public void service() { }
24
25 == FleetSim ==============================================================
26
27 == FPGA ==============================================================
28
29   reg [`WORDWIDTH-1:0] temp;
30   initial temp   = {`WORDWIDTH{1'b1}};
31   reg     full;
32   initial full = 0;
33   wire    op_count;  assign op_count  = inOp_d==12;
34   wire    op_repeat; assign op_repeat = inOp_d[3:2]==0;
35   wire    op_pass;   assign op_pass   = inOp_d[3:2]==1;
36   wire    op_drop;   assign op_drop   = inOp_d[3:2]==2;
37   wire    op_c1;     assign op_c1     = (op_repeat || op_pass || op_drop) && !inOp_d[1];
38   wire    op_c2;     assign op_c2     = (op_repeat || op_pass || op_drop) &&  inOp_d[1];
39   wire    op_v1;     assign op_v1     = (op_repeat || op_pass || op_drop) && !inOp_d[0];
40   wire    op_v2;     assign op_v2     = (op_repeat || op_pass || op_drop) &&  inOp_d[0];
41   assign  out_d_ = op_v1 ? in1_d : op_v2 ? in2_d : temp;
42
43   // FIXME: REPEAT with a count of zero will not work properly
44
45   always @(posedge clk) begin
46     if (!rst) begin
47       `reset
48       full <= 0;
49     end else begin
50       `flush
51       `cleanup
52       if (`inOp_empty)         full   <= 0;
53       if (`out_draining) begin
54         if (op_count) temp   <= temp - in2_d;
55         else          temp   <= temp - 1;
56         if (op_pass && op_v1) `drain_in1
57         if (op_pass && op_v2) `drain_in2
58       end else if (`inOp_full) begin
59         if (!full) begin
60           if (op_count && `in1_full && `in2_full) begin
61             temp  <= in1_d[`WORDWIDTH-1:0] - in2_d[`WORDWIDTH-1:0];
62             `drain_in1
63             full  <= 1;
64           end else if (op_c1 && `in1_full) begin
65             temp  <= in1_d[`WORDWIDTH-1:0]-1;
66             `drain_in1
67             full  <= 1;
68           end else if (op_c2 && `in2_full) begin
69             temp  <= in2_d[`WORDWIDTH-1:0]-1;
70             `drain_in2
71             full  <= 1;
72           end
73         end else if (temp[`WORDWIDTH-1]) begin
74           full <= 0;
75           `drain_inOp
76           if (op_count) begin
77             `drain_in2
78           end else if (op_repeat && op_v1) begin
79             `drain_in1
80           end else if (op_repeat && op_v2) begin
81             `drain_in2
82           end
83         end else if (`out_empty) begin
84           if (op_count) begin
85             `fill_out
86           end else if (op_v1 && `in1_full) begin
87             if (op_drop)    begin `drain_in1 temp <= temp-1; end
88             else            `fill_out
89           end else if (op_v2 && `in2_full) begin
90             if (op_drop)    begin `drain_in2 temp <= temp-1; end
91             else            `fill_out
92           end
93         end
94       end
95     end
96   end
97
98 == Test =================================================================
99
100 #ship counter : Counter
101 #ship debug   : Debug
102
103 #expect 6
104 #expect 3
105 #expect 0
106 #expect 2
107 #expect 1
108 #expect 0
109 #expect 2
110 #expect 2
111 #expect 2
112 #expect 2
113 #expect 9
114 #expect 9
115 #expect 9
116
117 debug.in:
118   set ilc=*;
119   recv, deliver;
120
121 counter.in1:
122   set word=9;
123   deliver;
124   set word=3;
125   deliver;
126   set word=4;
127   deliver;
128   set word=3;
129   deliver;
130
131 counter.in2:
132   set word=3;
133   deliver;
134   set word=1;
135   deliver;
136   set word=2;
137   deliver;
138   set word=9;
139   deliver;
140
141 counter.inOp:
142   set word=12;
143   deliver;
144   deliver;
145   set word=1;
146   deliver;
147   deliver;
148
149 counter.out:
150   set ilc=*;
151   collect, send to debug.in;
152
153
154 == Contributors =========================================================
155 Adam Megacz <megacz@cs.berkeley.edu>