1
2
3
4
5 module cf #(
6 parameter PC = 8,
7 parameter OP = 3,
8 parameter TAG = 4,
9 parameter DATA = 32
10 ) (
11 input wire clk,
12 input wire rstn,
13
14 input wire [PC-1:0] pc,
15 input wire [OP+4*TAG-1:0] disp_bus0,
16 input wire [OP+4*TAG-1:0] disp_bus1,
17 input wire cdb_a_except,
18 input wire [TAG-1:0] cdb_a_id,
19 input wire [DATA-1:0] cdb_a_data,
20 input wire cdb_m_except,
21 input wire [TAG-1:0] cdb_m_id,
22 input wire [DATA-1:0] cdb_m_data,
23 input wire cdb_l_except,
24 input wire [TAG-1:0] cdb_l_id,
25 input wire [DATA-1:0] cdb_l_data,
26 input wire cdb_s_except,
27 input wire [TAG-1:0] cdb_s_id,
28
29 output reg exception,
30 output reg [PC-1:0] comp_pc,
31 output reg clean,
32 output reg cf_val,
33 output reg [TAG-1:0] cf_addr,
34 output reg [DATA-1:0] cf_data
35 );
36
37 localparam RUN = 3'b000,
38 EXCEPT = 3'b001,
39 CLEAN0 = 3'b100,
40 CLEAN1 = 3'b101,
41 CLEAN2 = 3'b110,
42 CLEAN3 = 3'b111,
43 CLEAN = 3'b011;
44 localparam DEPTH = 32;
45 localparam R0 = 4'd4,
46 R1 = 4'd5,
47 R2 = 4'd6,
48 R3 = 4'd7,
49 A0 = 4'd8,
50 A1 = 4'd9,
51 M0 = 4'd10,
52 M1 = 4'd11,
53 L0 = 4'd12,
54 L1 = 4'd13,
55 S0 = 4'd14,
56 S1 = 4'd15;
57
58 reg exceptionN, exception_nextN;
59 reg [4:0] insert, insert_next, insertN, insert_1N;
60 reg [4:0] complete, complete_next, completeN;
61 reg [1:0] comp_update;
62
63
64 reg [3+PC+2*TAG+DATA-1:0] cfile[DEPTH-1:0];
65 reg [3+PC+2*TAG+DATA-1:0] cfileN[DEPTH-1:0];
66 reg [3+PC+2*TAG+DATA-1:0] cfile_nextN[DEPTH-1:0];
67
68 reg [DATA-1:0] srfile[3:0];
69 reg [DATA-1:0] srfile_next[3:0];
70 reg [DATA-1:0] srfileN[3:0];
71 reg [2:0] state, state_next, stateN;
72
73
74 reg [PC-1:0] pcN;
75 reg [OP+4*TAG-1:0] disp_bus0N;
76 reg [OP+4*TAG-1:0] disp_bus1N;
77 reg cdb_a_exceptN;
78 reg [TAG-1:0] cdb_a_idN;
79 reg [DATA-1:0] cdb_a_dataN;
80 reg cdb_m_exceptN;
81 reg [TAG-1:0] cdb_m_idN;
82 reg [DATA-1:0] cdb_m_dataN;
83 reg cdb_l_exceptN;
84 reg [TAG-1:0] cdb_l_idN;
85 reg [DATA-1:0] cdb_l_dataN;
86 reg cdb_s_exceptN;
87 reg [TAG-1:0] cdb_s_idN;
88
89 reg [TAG-1:0] disp0_rsvN;
90 reg [TAG-1:0] disp0_dstN;
91 reg [TAG-1:0] disp1_rsvN;
92 reg [TAG-1:0] disp1_dstN;
93 reg ins0_val;
94 reg ins0_exp;
95 reg ins0_comp;
96 reg [PC-1:0] ins0_pc;
97 reg [TAG-1:0] ins0_rsv;
98 reg [TAG-1:0] ins0_dst;
99 reg [DATA-1:0] ins0_data;
100 reg ins1_val;
101 reg ins1_exp;
102 reg ins1_comp;
103 reg [PC-1:0] ins1_pc;
104 reg [TAG-1:0] ins1_rsv;
105 reg [TAG-1:0] ins1_dst;
106 reg [DATA-1:0] ins1_data;
107 reg comp0_val;
108 reg comp0_exp;
109 reg comp0_comp;
110 reg [PC-1:0] comp0_pc;
111 reg [TAG-1:0] comp0_rsv;
112 reg [TAG-1:0] comp0_dst;
113 reg [DATA-1:0] comp0_data;
114 reg comp1_val;
115 reg comp1_exp;
116 reg comp1_comp;
117 reg [PC-1:0] comp1_pc;
118 reg [TAG-1:0] comp1_rsv;
119 reg [TAG-1:0] comp1_dst;
120 reg [DATA-1:0] comp1_data;
121 reg comp2_val;
122 reg comp2_exp;
123 reg comp2_comp;
124 reg [PC-1:0] comp2_pc;
125 reg [TAG-1:0] comp2_rsv;
126 reg [TAG-1:0] comp2_dst;
127 reg [DATA-1:0] comp2_data;
128 reg update_valN;
129 reg update_expN;
130 reg update_compN;
131 reg [PC-1:0] update_pcN;
132 reg [TAG-1:0] update_rsvN;
133 reg [TAG-1:0] update_dstN;
134 reg [DATA-1:0] update_dataN;
135
136 integer i, j, k;
137
138 always @* begin : CF_POS_PHASE
139 { ins0_val,
140 ins0_exp,
141 ins0_comp,
142 ins0_pc,
143 ins0_rsv,
144 ins0_dst,
145 ins0_data } = cfile[insert];
146 { ins1_val,
147 ins1_exp,
148 ins1_comp,
149 ins1_pc,
150 ins1_rsv,
151 ins1_dst,
152 ins1_data } = cfile[insert+8'd1];
153
154 { comp0_val,
155 comp0_exp,
156 comp0_comp,
157 comp0_pc,
158 comp0_rsv,
159 comp0_dst,
160 comp0_data } = cfile[complete];
161 { comp1_val,
162 comp1_exp,
163 comp1_comp,
164 comp1_pc,
165 comp1_rsv,
166 comp1_dst,
167 comp1_data } = cfile[complete+8'd1];
168 { comp2_val,
169 comp2_exp,
170 comp2_comp,
171 comp2_pc,
172 comp2_rsv,
173 comp2_dst,
174 comp2_data } = cfile[complete+8'd2];
175
176
177 insert_next = ( |ins0_rsv && |ins1_rsv ) ? insert + 5'd2
178 : ( |ins0_rsv ) ? insert + 5'd1
179 : insert;
180
181
182
183
184
185
186 if ( comp0_comp && !comp0_exp
187 && ( comp1_comp && !comp1_exp )
188 && ( comp2_comp && !( comp2_rsv[3:2] == 2'b11 && comp2_exp ) ) ) begin
189 complete_next = complete + 5'd2;
190 comp_update = 2'b11;
191 end
192 else if ( comp0_comp && !comp0_exp
193 && ( comp1_comp && !( comp1_rsv[3:2] == 2'b11 && comp1_exp ) ) ) begin
194 complete_next = complete + 5'd1;
195 comp_update = 2'b01;
196 end
197 else begin
198 complete_next = complete;
199 comp_update = 2'b00;
200 end
201
202 for ( j = 0; j < 4; j = j+1 ) begin
203 if ( comp_update[1] && comp2_comp && comp2_dst == (R0 + j) ) begin
204 srfile_next[j] = comp1_data;
205 end
206 else if ( comp_update[0] && comp1_comp && comp1_dst == (R0 + j) ) begin
207 srfile_next[j] = comp0_data;
208 end
209 else if ( comp0_comp && comp0_dst == (R0 + j) ) begin
210 srfile_next[j] = comp0_data;
211 end
212 else begin
213 srfile_next[j] = srfile[j];
214 end
215 end
216
217
218
219 case ( stateN )
220 RUN: state_next = ( exception ) ? EXCEPT : RUN;
221 EXCEPT: state_next = ( comp0_exp || ( comp1_rsv[3:2] == 2'b11 && comp1_exp ) ) ? CLEAN0 : EXCEPT;
222 CLEAN0: state_next = CLEAN1;
223 CLEAN1: state_next = CLEAN2;
224 CLEAN2: state_next = CLEAN3;
225 CLEAN3: state_next = CLEAN;
226 CLEAN: state_next = CLEAN;
227 endcase
228 end
229
230 always @( negedge clk or negedge rstn ) begin : CF_NEG_LATCHES
231 if ( !rstn ) begin
232 insertN <= 5'd0;
233 completeN <= 5'd0;
234 exceptionN <= 1'b0;
235 stateN <= RUN;
236
237 pcN <= {PC{1'b0}};
238 disp_bus0N <= {OP+4*TAG{1'b0}};
239 disp_bus1N <= {OP+4*TAG{1'b0}};
240 cdb_a_exceptN <= 1'b0;
241 cdb_a_idN <= {TAG{1'b0}};
242 cdb_a_dataN <= {DATA{1'b0}};
243 cdb_m_exceptN <= 1'b0;
244 cdb_m_idN <= {TAG{1'b0}};
245 cdb_m_dataN <= {DATA{1'b0}};
246 cdb_l_exceptN <= 1'b0;
247 cdb_l_idN <= {TAG{1'b0}};
248 cdb_l_dataN <= {DATA{1'b0}};
249 cdb_s_exceptN <= 1'b0;
250 cdb_s_idN <= {TAG{1'b0}};
251
252 for ( i=0; i<DEPTH; i=i+1 ) begin
253 cfileN[i] <= {PC+2*TAG+DATA+2{1'b0}};
254 end
255
256 for ( i=0; i<4; i=i+1 ) begin
257 srfileN[i] <= {DATA{1'b0}};
258 end
259 end
260 else begin
261 if ( !clk ) begin
262 insertN <= insert_next;
263 completeN <= complete_next;
264 exceptionN <= exception;
265 stateN <= state_next;
266
267 pcN <= pc;
268 disp_bus0N <= disp_bus0;
269 disp_bus1N <= disp_bus1;
270 cdb_a_exceptN <= cdb_a_except;
271 cdb_a_idN <= cdb_a_id;
272 cdb_a_dataN <= cdb_a_data;
273 cdb_m_exceptN <= cdb_m_except;
274 cdb_m_idN <= cdb_m_id;
275 cdb_m_dataN <= cdb_m_data;
276 cdb_l_exceptN <= cdb_l_except;
277 cdb_l_idN <= cdb_l_id;
278 cdb_l_dataN <= cdb_l_data;
279 cdb_s_exceptN <= cdb_s_except;
280 cdb_s_idN <= cdb_s_id;
281
282 for ( i=0; i<DEPTH; i=i+1 ) begin
283 cfileN[i] <= cfile[i];
284 end
285
286 for ( i=0; i<4; i=i+1 ) begin
287 srfileN[i] <= srfile_next[i];
288 end
289 end
290 end
291 end
292
293 integer iN, jN;
294
295 always @* begin : CF_NEG_PHASE
296 exception_nextN = exceptionN || cdb_a_except || cdb_m_except || cdb_l_except || cdb_s_except;
297
298 disp0_rsvN = disp_bus0N[OP+4*TAG-1:OP+3*TAG];
299 disp0_dstN = disp_bus0N[3*TAG-1:2*TAG];
300 disp1_rsvN = disp_bus1N[OP+4*TAG-1:OP+3*TAG];
301 disp1_dstN = disp_bus1N[3*TAG-1:2*TAG];
302
303 insert_1N = insertN + 5'd1;
304
305
306 for ( jN = 0; jN < DEPTH; jN = jN+1 ) begin
307 { update_valN,
308 update_expN,
309 update_compN,
310 update_pcN,
311 update_rsvN,
312 update_dstN,
313 update_dataN } = cfileN[jN];
314
315
316 if ( jN == insertN && |disp0_rsvN ) begin
317 cfile_nextN[jN] = { 1'b1,
318 1'b0,
319 1'b0,
320 pcN,
321 disp0_rsvN,
322 disp0_dstN,
323 32'd0 };
324 end
325 else if ( jN == insert_1N && |disp1_rsvN ) begin
326 cfile_nextN[jN] = { 1'b1,
327 1'b0,
328 1'b0,
329 pcN + {{PC-1{1'b0}},1'b1},
330 disp1_rsvN,
331 disp1_dstN,
332 32'd0 };
333 end
334 else if ( update_valN && !update_expN && !update_compN ) begin
335 case ( update_rsvN )
336 A0:
337 begin
338 if ( cdb_a_idN == A0 ) begin
339 cfile_nextN[jN] = { update_valN,
340 cdb_a_exceptN,
341 1'b1,
342 update_pcN,
343 update_rsvN,
344 update_dstN,
345 cdb_a_data };
346 end
347 else begin
348 cfile_nextN[jN] = cfileN[jN];
349 end
350 end
351
352 A1:
353 begin
354 if ( cdb_a_idN == A1 ) begin
355 cfile_nextN[jN] = { update_valN,
356 cdb_a_exceptN,
357 1'b1,
358 update_pcN,
359 update_rsvN,
360 update_dstN,
361 cdb_a_data };
362 end
363 else begin
364 cfile_nextN[jN] = cfileN[jN];
365 end
366 end
367
368 M0:
369 begin
370 if ( cdb_m_idN == M0 ) begin
371 cfile_nextN[jN] = { update_valN,
372 cdb_m_exceptN,
373 1'b1,
374 update_pcN,
375 update_rsvN,
376 update_dstN,
377 cdb_m_data };
378 end
379 else begin
380 cfile_nextN[jN] = cfileN[jN];
381 end
382 end
383
384 M1:
385 begin
386 if ( cdb_m_idN == M1 ) begin
387 cfile_nextN[jN] = { update_valN,
388 cdb_m_exceptN,
389 1'b1,
390 update_pcN,
391 update_rsvN,
392 update_dstN,
393 cdb_m_data };
394 end
395 else begin
396 cfile_nextN[jN] = cfileN[jN];
397 end
398 end
399
400 L0:
401 begin
402 if ( cdb_l_idN == L0 ) begin
403 cfile_nextN[jN] = { update_valN,
404 cdb_l_exceptN,
405 1'b1,
406 update_pcN,
407 update_rsvN,
408 update_dstN,
409 cdb_l_data };
410 end
411 else begin
412 cfile_nextN[jN] = cfileN[jN];
413 end
414 end
415
416 L1:
417 begin
418 if ( cdb_l_idN == L1 ) begin
419 cfile_nextN[jN] = { update_valN,
420 cdb_l_exceptN,
421 1'b1,
422 update_pcN,
423 update_rsvN,
424 update_dstN,
425 cdb_l_data };
426 end
427 else begin
428 cfile_nextN[jN] = cfileN[jN];
429 end
430 end
431
432 S0:
433 begin
434 if ( cdb_s_idN == S0 ) begin
435 cfile_nextN[jN] = { update_valN,
436 cdb_s_exceptN,
437 1'b1,
438 update_pcN,
439 update_rsvN,
440 update_dstN,
441 {DATA{1'b0}} };
442 end
443 else begin
444 cfile_nextN[jN] = cfileN[jN];
445 end
446 end
447
448 S1:
449 begin
450 if ( cdb_s_idN == S1 ) begin
451 cfile_nextN[jN] = { update_valN,
452 cdb_s_exceptN,
453 1'b1,
454 update_pcN,
455 update_rsvN,
456 update_dstN,
457 {DATA{1'b0}} };
458 end
459 else begin
460 cfile_nextN[jN] = cfileN[jN];
461 end
462 end
463
464 default:
465 $display ( "%t: INVALID cfile entry %h (rsv = %h)\n", $time,
466 cfileN[jN], update_rsvN );
467 endcase
468 end
469 else begin
470 cfile_nextN[jN] = cfileN[jN];
471 end
472 end
473 end
474
475
476 always @( posedge clk or negedge rstn ) begin : CF_POS_LATCHES
477 if ( !rstn ) begin
478 state <= RUN;
479
480 insert <= 5'd0;
481 complete <= 5'd0;
482
483 exception <= 1'b0;
484 comp_pc <= {PC{1'b0}};
485 clean <= 1'b0;
486 cf_val <= 1'b0;
487 cf_addr <= {TAG{1'b0}};
488 cf_data <= {DATA{1'b0}};
489
490 for ( iN=0; iN<DEPTH; iN=iN+1 ) begin
491 cfile[iN] <= {PC+2*TAG+DATA+3{1'b0}};
492 end
493
494 for ( iN=0; iN<4; iN=iN+1 ) begin
495 srfile[iN] <= {DATA{1'b0}};
496 end
497 end
498 else begin
499 if ( clk ) begin
500 state <= stateN;
501 insert <= insertN;
502 complete <= completeN;
503 exception <= exception_nextN;
504 comp_pc <= cfileN[completeN][PC+2*TAG+DATA-1:2*TAG+DATA];
505
506 case ( stateN )
507 RUN,
508 EXCEPT:
509 begin
510 clean <= 1'b0;
511 cf_val <= 1'b0;
512 cf_addr <= {TAG{1'b0}};
513 cf_data <= {DATA{1'b0}};
514 end
515
516 CLEAN0:
517 begin
518 clean <= 1'b0;
519 cf_val <= 1'b1;
520 cf_addr <= R0;
521 cf_data <= srfileN[0];
522 end
523
524 CLEAN1:
525 begin
526 clean <= 1'b0;
527 cf_val <= 1'b1;
528 cf_addr <= R1;
529 cf_data <= srfileN[1];
530 end
531
532 CLEAN2:
533 begin
534 clean <= 1'b0;
535 cf_val <= 1'b1;
536 cf_addr <= R2;
537 cf_data <= srfileN[2];
538 end
539
540 CLEAN3:
541 begin
542 clean <= 1'b0;
543 cf_val <= 1'b1;
544 cf_addr <= R3;
545 cf_data <= srfileN[3];
546 end
547
548 CLEAN:
549 begin
550 clean <= 1'b1;
551 cf_val <= 1'b0;
552 cf_addr <= {TAG{1'b0}};
553 cf_data <= {DATA{1'b0}};
554 end
555
556 endcase
557
558
559 for ( iN=0; iN<DEPTH; iN=iN+1 ) begin
560 cfile[iN] <= cfile_nextN[iN];
561
562
563
564
565
566
567
568 end
569
570
571 for ( iN=0; iN<4; iN=iN+1 ) begin
572 srfile[iN] <= srfileN[iN];
573 end
574 end
575 end
576 end
577
578 endmodule
579