1
2
3
4
5 module dispatch #(
6 parameter OP = 3,
7 parameter TAG = 4,
8 parameter ADDR = 32
9 ) (
10 input wire clk,
11 input wire rstn,
12
13 input wire [OP+3*TAG+ADDR-1:0] inst0,
14 input wire [OP+3*TAG+ADDR-1:0] inst1,
15 output reg [1:0] inst_pop,
16
17 input wire [TAG-1:0] cdb_a_id,
18 input wire cdb_a_except,
19 input wire [TAG-1:0] cdb_m_id,
20 input wire cdb_m_except,
21 input wire [TAG-1:0] cdb_l_id,
22 input wire cdb_l_except,
23 input wire [TAG-1:0] cdb_s_id,
24 input wire cdb_s_except,
25
26 input wire [7:0] regstat_busy,
27 input wire [4*TAG-1:0] regstat_remap,
28
29 output reg [OP+4*TAG+ADDR-1:0] disp_bus0,
30 output reg [OP+4*TAG+ADDR-1:0] disp_bus1
31 );
32
33 localparam STALL_STALL = 2'b00,
34 STALL_POP = 2'b01,
35 POP_STALL = 2'b10,
36 POP_POP = 2'b11;
37
38
39 localparam STOR = 3'b111,
40 LOAD = 3'b110,
41 FDIV = 3'b101,
42 FMUL = 3'b100,
43 FSUB = 3'b011,
44 FADD = 3'b010;
45
46
47 localparam R0 = 4'd4,
48 R1 = 4'd5,
49 R2 = 4'd6,
50 R3 = 4'd7,
51 A0 = 4'd8,
52 A1 = 4'd9,
53 M0 = 4'd10,
54 M1 = 4'd11,
55 L0 = 4'd12,
56 L1 = 4'd13,
57 S0 = 4'd14,
58 S1 = 4'd15;
59
60 reg [TAG-1:0] cdb_a_idN;
61 reg [TAG-1:0] cdb_m_idN;
62 reg [TAG-1:0] cdb_l_idN;
63 reg [TAG-1:0] cdb_s_idN;
64 reg cdb_a_exceptN;
65 reg cdb_m_exceptN;
66 reg cdb_l_exceptN;
67 reg cdb_s_exceptN;
68 reg exception, exceptionN;
69
70 reg dependN;
71 reg depend_nextN;
72 reg [4*TAG-1:0] regstat_remapN;
73 reg [3:0] cdb_free;
74 reg [4*TAG-1:0] cdb_tags;
75 reg [TAG-1:0] map01, map02, map11, map12;
76
77 reg [OP+3*TAG+ADDR-1:0] inst0_pop;
78 reg [OP+3*TAG+ADDR-1:0] inst1_pop;
79
80 reg [OP-1:0] op0_next, op1_next;
81 reg [TAG-1:0] rsv0_next, rsv1_next;
82 reg [TAG-1:0] dst0_next, dst1_next;
83 reg [TAG-1:0] src01_next, src02_next;
84 reg [TAG-1:0] src11_next, src12_next;
85 reg [7:0] disp_busyN;
86 reg [OP-1:0] op0N, op1N;
87 reg [TAG-1:0] rsv0N, rsv1N;
88 reg [TAG-1:0] dst0N, dst1N;
89 reg [TAG-1:0] src01N, src02N;
90 reg [TAG-1:0] src11N, src12N;
91 reg [ADDR-1:0] addr0N, addr1N;
92 reg [OP-1:0] op0_nextN, op1_nextN;
93 reg [TAG-1:0] rsv0_nextN, rsv1_nextN;
94 reg [TAG-1:0] dst0_nextN, dst1_nextN;
95 reg [TAG-1:0] src01_nextN, src02_nextN;
96 reg [TAG-1:0] src11_nextN, src12_nextN;
97 reg [ADDR-1:0] addr0_nextN, addr1_nextN;
98
99
100 always @* begin : DISP_POS_LOGIC
101
102 case (inst_pop)
103 POP_POP:
104 begin
105 inst0_pop = inst0;
106 inst1_pop = inst1;
107 end
108
109 POP_STALL:
110 begin
111 inst0_pop = disp_bus0[OP+3*TAG+ADDR-1:0];
112 inst1_pop = inst0;
113 end
114
115 STALL_POP:
116 begin
117 inst0_pop = disp_bus1[OP+3*TAG+ADDR-1:0];
118 inst1_pop = inst0;
119 end
120
121 STALL_STALL:
122 begin
123 inst0_pop = disp_bus0[OP+3*TAG+ADDR-1:0];
124 inst1_pop = disp_bus1[OP+3*TAG+ADDR-1:0];
125 end
126 endcase
127
128
129 {op0_nextN,
130 dst0_nextN,
131 src01_nextN,
132 src02_nextN,
133 addr0_nextN} = inst0_pop;
134 {op1_nextN,
135 dst1_nextN,
136 src11_nextN,
137 src12_nextN,
138 addr1_nextN} = inst1_pop;
139
140
141 disp_busyN = regstat_busy;
142
143 rsv0_nextN = {TAG{1'b0}};
144 case ( op0_nextN )
145 FADD, FSUB:
146 begin
147 if ( !regstat_busy[A0-8] ) begin
148 rsv0_nextN = A0;
149 disp_busyN[A0-8] = 1'b1;
150 end
151 else if ( !regstat_busy[A1-8] ) begin
152 rsv0_nextN = A1;
153 disp_busyN[A1-8] = 1'b1;
154 end
155 end
156
157 FMUL, FDIV:
158 begin
159 if ( !regstat_busy[M0-8] ) begin
160 rsv0_nextN = M0;
161 disp_busyN[M0-8] = 1'b1;
162 end
163 else if ( !regstat_busy[M1-8] ) begin
164 rsv0_nextN = M1;
165 disp_busyN[M1-8] = 1'b1;
166 end
167 end
168
169 LOAD:
170 begin
171 if ( !regstat_busy[L0-8] ) begin
172 rsv0_nextN = L0;
173 disp_busyN[L0-8] = 1'b1;
174 end
175 else if ( !regstat_busy[L1-8] ) begin
176 rsv0_nextN = L1;
177 disp_busyN[L1-8] = 1'b1;
178 end
179 end
180
181 STOR:
182 begin
183 if ( !regstat_busy[S0-8] ) begin
184 rsv0_nextN = S0;
185 disp_busyN[S0-8] = 1'b1;
186 end
187 else if ( !regstat_busy[S1-8] ) begin
188 rsv0_nextN = S1;
189 disp_busyN[S1-8] = 1'b1;
190 end
191 end
192
193 default:
194 begin
195 $display( "NOP OPCODE - %b", op0_nextN );
196 rsv0_nextN = {TAG{1'b0}};
197 end
198 endcase
199
200
201 depend_nextN = ( src11_nextN == dst0_nextN ) || ( src12_nextN == dst0_nextN );
202
203
204 rsv1_nextN = {TAG{1'b0}};
205 if ( !( ~|rsv0_nextN && depend_nextN ) ) begin
206 case ( op1_nextN )
207 FADD, FSUB:
208 begin
209 if ( !disp_busyN[A0-8] ) begin
210 rsv1_nextN = A0;
211 end
212 else if ( !disp_busyN[A1-8] ) begin
213 rsv1_nextN = A1;
214 end
215 end
216
217 FMUL, FDIV:
218 begin
219 if ( !disp_busyN[M0-8] ) begin
220 rsv1_nextN = M0;
221 end
222 else if ( !disp_busyN[M1-8] ) begin
223 rsv1_nextN = M1;
224 end
225 end
226
227 LOAD:
228 begin
229 if ( !disp_busyN[L0-8] ) begin
230 rsv1_nextN = L0;
231 end
232 else if ( !disp_busyN[L1-8] ) begin
233 rsv1_nextN = L1;
234 end
235 end
236
237 STOR:
238 begin
239 if ( !disp_busyN[S0-8] ) begin
240 rsv1_nextN = S0;
241 end
242 else if ( !disp_busyN[S1-8] ) begin
243 rsv1_nextN = S1;
244 end
245 end
246
247 default:
248 begin
249 $display( "NOP OPCODE - %b", op1_nextN );
250 rsv1_nextN = {TAG{1'b0}};
251 end
252 endcase
253 end
254 end
255
256
257 always @* begin : DISP_NEG_LATCH
258 if ( !rstn ) begin
259 exceptionN <= 1'b0;
260 dependN <= 1'b0;
261
262 rsv0N <= {TAG{1'b0}};
263 op0N <= {OP{1'b0}};
264 dst0N <= {TAG{1'b0}};
265 src01N <= {TAG{1'b0}};
266 src02N <= {TAG{1'b0}};
267 addr0N <= {ADDR{1'b0}};
268
269 rsv1N <= {TAG{1'b0}};
270 op1N <= {OP{1'b0}};
271 dst1N <= {TAG{1'b0}};
272 src11N <= {TAG{1'b0}};
273 src12N <= {TAG{1'b0}};
274 addr1N <= {ADDR{1'b0}};
275
276 regstat_remapN <= {4*TAG{1'b0}};
277
278 cdb_a_idN <= {TAG{1'b0}};
279 cdb_a_exceptN <= 1'b0;
280 cdb_m_idN <= {TAG{1'b0}};
281 cdb_m_exceptN <= 1'b0;
282 cdb_l_idN <= {TAG{1'b0}};
283 cdb_l_exceptN <= 1'b0;
284 cdb_s_idN <= {TAG{1'b0}};
285 end
286 else begin
287 if ( !clk ) begin
288 exceptionN <= exception;
289 dependN <= depend_nextN;
290
291 rsv0N <= rsv0_nextN;
292 op0N <= op0_nextN;
293 dst0N <= dst0_nextN;
294 src01N <= src01_nextN;
295 src02N <= src02_nextN;
296 addr0N <= addr0_nextN;
297
298 rsv1N <= rsv1_nextN;
299 op1N <= op1_nextN;
300 dst1N <= dst1_nextN;
301 src11N <= src11_nextN;
302 src12N <= src12_nextN;
303 addr1N <= addr1_nextN;
304
305 regstat_remapN <= regstat_remap;
306
307 cdb_a_idN <= cdb_a_id;
308 cdb_a_exceptN <= cdb_a_except;
309 cdb_m_idN <= cdb_m_id;
310 cdb_m_exceptN <= cdb_m_except;
311 cdb_l_idN <= cdb_l_id;
312 cdb_l_exceptN <= cdb_l_except;
313 cdb_s_idN <= cdb_s_id;
314 cdb_s_exceptN <= cdb_s_except;
315 end
316 end
317 end
318
319
320 always @* begin : DISP_NEG_LOGIC
321 op0_next = op0N;
322 op1_next = op1N;
323 dst0_next = dst0N;
324 dst1_next = dst1N;
325
326
327 cdb_free = { |cdb_s_idN, |cdb_l_idN, |cdb_m_idN, |cdb_a_idN };
328 cdb_tags = { cdb_s_idN, cdb_l_idN, cdb_m_idN, cdb_a_idN };
329
330
331 map01 = regstat_remapN[src01N[1:0]*TAG +: TAG];
332 map02 = regstat_remapN[src02N[1:0]*TAG +: TAG];
333 map11 = regstat_remapN[src11N[1:0]*TAG +: TAG];
334 map12 = regstat_remapN[src12N[1:0]*TAG +: TAG];
335
336
337 if ( ~|rsv0N ) begin
338 case ( op0N )
339 FADD, FSUB:
340 begin
341 rsv0_next = ( cdb_free[0] ) ? cdb_a_idN : {TAG{1'b0}};
342 cdb_free = cdb_free & 4'b1110;
343 end
344
345 FMUL, FDIV:
346 begin
347 rsv0_next = ( cdb_free[1] ) ? cdb_m_idN : {TAG{1'b0}};
348 cdb_free = cdb_free & 4'b1101;
349 end
350
351 LOAD:
352 begin
353 rsv0_next = ( cdb_free[2] ) ? cdb_l_idN : {TAG{1'b0}};
354 cdb_free = cdb_free & 4'b1011;
355 end
356
357 STOR:
358 begin
359 rsv0_next = ( cdb_free[3] ) ? cdb_s_idN : {TAG{1'b0}};
360 cdb_free = cdb_free & 4'b0111;
361 end
362
363 default:
364 begin
365 rsv0_next = {TAG{1'b0}};
366 end
367 endcase
368 end
369 else begin
370 rsv0_next = rsv0N;
371 end
372
373
374
375 src01_next = ( |rsv0_next && |map01 && map01 != cdb_tags[map01[2:1]] ) ? map01 : src01N;
376 src02_next = ( |rsv0_next && |map02 && map02 != cdb_tags[map02[2:1]] ) ? map02 : src02N;
377
378
379
380 if ( ~|rsv1N && ( !dependN || |rsv0N ) ) begin
381 case ( op0N )
382 FADD, FSUB:
383 rsv1_next = ( cdb_free[0] ) ? cdb_a_idN : {TAG{1'b0}};
384
385 FMUL, FDIV:
386 rsv1_next = ( cdb_free[1] ) ? cdb_m_idN : {TAG{1'b0}};
387
388 LOAD:
389 rsv1_next = ( cdb_free[2] ) ? cdb_l_idN : {TAG{1'b0}};
390
391 STOR:
392 rsv1_next = ( cdb_free[3] ) ? cdb_s_idN : {TAG{1'b0}};
393
394 default:
395 rsv1_next = {TAG{1'b0}};
396 endcase
397 end
398 else begin
399 rsv1_next = rsv1N;
400 end
401
402
403
404 src11_next = ( |rsv1_next && src11N == dst0N && op0N != STOR ) ? rsv0_next
405 : ( |rsv1_next && |map11 && map11 != cdb_tags[map11[2:1]] ) ? map11
406 : src11N;
407 src12_next = ( |rsv1_next && src12N == dst0N && op0N != STOR ) ? rsv0_next
408 : ( |rsv1_next && |map12 && map12 != cdb_tags[map12[2:1]] ) ? map12
409 : src12N;
410 end
411
412
413 always @* begin : DISP_POS_LATCH
414 if ( !rstn ) begin
415 exception <= 1'b0;
416 inst_pop <= 2'b11;
417 disp_bus0 <= {OP+4*TAG+ADDR{1'b0}};
418 disp_bus1 <= {OP+4*TAG+ADDR{1'b0}};
419 end
420 else begin
421 if ( clk ) begin
422 if ( exceptionN || cdb_a_exceptN || cdb_m_exceptN || cdb_l_exceptN ) begin
423 exception <= 1'b1;
424 inst_pop <= 2'b00;
425 disp_bus0 <= {{TAG{1'b0}},
426 op0_next,
427 dst0_next,
428 src01_next,
429 src02_next,
430 addr0N};
431 disp_bus1 <= {{TAG{1'b0}},
432 op1_next,
433 dst1_next,
434 src11_next,
435 src12_next,
436 addr1N};
437 end
438 else begin
439 exception <= 1'b0;
440 inst_pop <= { (|rsv1_next || ~|op1_next), (|rsv0_next || ~|op0_next) };
441 disp_bus0 <= {rsv0_next,
442 op0_next,
443 dst0_next,
444 src01_next,
445 src02_next,
446 addr0N};
447 disp_bus1 <= {rsv1_next,
448 op1_next,
449 dst1_next,
450 src11_next,
451 src12_next,
452 addr1N};
453 end
454 end
455 end
456 end
457
458 endmodule
459