3d985caa66c234b8ea69593f18eccdbcf7346970
[fleet.git] / src / edu / berkeley / fleet / slipway / box.inc
1   reg have_instruction;
2   reg need_to_read_token;
3   reg need_to_read_data;
4   reg need_to_send_token;
5   reg need_to_send_data;
6   reg parse_instruction;
7   reg do_recycle;
8   reg fire_ok;
9   reg                            kill_only_standing;
10   reg [(`COUNT_BITS-1):0]        kill_count;
11   reg [(`INSTRUCTION_WIDTH-1):0] instruction;
12
13   wire [(`INSTRUCTION_WIDTH-1):0] instr_d2;
14   wire [(`INSTRUCTION_WIDTH-1):0] instr_d0;
15
16   reg kill_r;
17   reg kill_a;
18   reg [(`COUNT_WIDTH-1+1):0] kill_d;
19
20   reg [(`INSTRUCTION_WIDTH-1):0] kinstruction;
21   reg instr_rx;
22   wire instr_ax;
23   reg ifull;
24
25   always @(posedge clk) begin
26     if (!ifull) begin
27       `onread(instr_r, instr_a)
28         ifull = 1;
29         kinstruction = instr_d;
30       end
31     end else begin
32       if (`instruction_is_kill(kinstruction)) begin
33         kill_d = { `instruction_bit_kill_only_standing(kinstruction), `instruction_count(kinstruction) };
34         `onwrite(kill_r, kill_a)
35           ifull = 0;
36         end
37       end else begin
38         `onwrite(instr_rx, instr_ax)
39           ifull = 0;
40         end
41       end
42     end
43   end
44
45   reg recycle_r;
46   wire recycle_r_;
47   assign recycle_r_ = recycle_r;
48   wire recycle_a;
49   wire [(`INSTRUCTION_WIDTH-1):0] recycle_inst;
50   assign recycle_inst = instruction;
51   
52   wire instr_a2_;
53   reg instr_a2;
54   assign instr_a2_ = instr_a2;
55
56   funnel ifunnel(clk, instr_r0, instr_a0, instr_d0,
57                       instr_rx,  instr_ax,  kinstruction,
58                       recycle_r_, recycle_a, recycle_inst);
59
60   fifo4 ififo(clk, instr_r0, instr_a0, instr_d0,
61                    instr_r2, instr_a2_, instr_d2);
62
63   always @(posedge clk) begin
64
65     if (do_recycle) begin
66       `onwrite(recycle_r, recycle_a)
67         do_recycle = 0;
68         have_instruction = 0;
69         parse_instruction = 0;
70       end
71
72     end else if (fire_ok) begin
73       if (need_to_send_data) begin
74         `onwrite(`data_out_r, `data_out_a)
75           need_to_send_data = 0;
76         end
77
78       end else if (need_to_send_token) begin
79         `onwrite(`token_out_r, `token_out_a)
80           need_to_send_token = 0;
81         end
82
83       end else begin
84          fire_ok = 0;
85          case (`instruction_count(instruction))
86                 0: begin end
87                 1: have_instruction = 0;
88           default: `instruction_count(instruction) = `instruction_count(instruction) - 1;
89          endcase
90          if (have_instruction && `instruction_bit_recycle(instruction)) begin
91            do_recycle = 1;
92          end else begin
93            parse_instruction = have_instruction;
94          end
95       end
96
97     end else if (!have_instruction && !parse_instruction) begin
98       `onread(instr_r2, instr_a2)
99         instruction                 = instr_d2;
100         parse_instruction           = 1;
101       end
102
103     end else begin
104       // FIXME: actually don't want to kill partway through an instruction
105       `onread(kill_r, kill_a)
106         kill_only_standing = kill_d[`COUNT_WIDTH];
107         kill_count = kill_count + kill_d[(`COUNT_WIDTH-1):0];
108       end
109
110       if ((parse_instruction || have_instruction) && (kill_count > 0) &&
111           (!kill_only_standing || `instruction_count(instruction)==0))
112       begin
113         kill_count = kill_count - 1;
114         have_instruction = 0;
115         parse_instruction = 0;
116       end
117
118       if (parse_instruction) begin
119         need_to_read_token          = `instruction_bit_tokenin(instruction);
120         need_to_read_data           = `instruction_bit_datain(instruction);
121         `packet_dest(`data_out_d)   = `instruction_bit_dest(instruction);
122         `packet_dest(`token_out_d)  = `instruction_bit_dest(instruction);
123         need_to_send_data           = `instruction_bit_dataout(instruction);
124         need_to_send_token          = `instruction_bit_tokenout(instruction);
125         have_instruction            = 1;
126         parse_instruction           = 0;
127       end
128
129       // return to zero
130       if (!`token_in_r && `token_in_a)  `token_in_a  = 0;
131       if (!`data_in_r  && `data_in_a)   `data_in_a   = 0;
132
133       if (have_instruction &&
134           (!need_to_read_token  || (`token_in_r   && !`token_in_a)) &&
135           (!need_to_read_data   || (`data_in_r    && !`data_in_a))
136          ) begin
137         if (need_to_read_token) begin
138           `token_in_a = 1;
139           need_to_read_token = 0;
140         end
141         if (need_to_read_data) begin
142           `data_in_a = 1;
143           need_to_read_data = 0;
144         end
145         if (`instruction_bit_latch(instruction)) begin
146           `packet_data(`data_out_d) = `data_in_d;
147         end
148         fire_ok = 1;
149       end
150
151     end
152   end