source: XOpenSparcT1/trunk/os2wb/os2wb.v @ 6

Revision 6, 59.0 KB checked in by pntsvt00, 13 years ago (diff)

versione iniziale opensparc

Line 
1`timescale 1ns / 1ps
2//////////////////////////////////////////////////////////////////////////////////
3// Company:  (C) Athree, 2009
4// Engineer: Dmitry Rozhdestvenskiy
5// Email dmitry.rozhdestvenskiy@srisc.com dmitryr@a3.spb.ru divx4log@narod.ru
6//
7// Design Name:    Bridge from SPARC Core to Wishbone Master
8// Module Name:    os2wb
9// Project Name:   SPARC SoC single-core
10//
11// LICENSE:
12// This is a Free Hardware Design; you can redistribute it and/or
13// modify it under the terms of the GNU General Public License
14// version 2 as published by the Free Software Foundation.
15// The above named program is distributed in the hope that it will
16// be useful, but WITHOUT ANY WARRANTY; without even the implied
17// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18// See the GNU General Public License for more details.
19//
20//////////////////////////////////////////////////////////////////////////////////
21module os2wb(
22    input              clk,
23    input              rstn,
24   
25    // Core interface
26    input      [  4:0] pcx_req,
27    input              pcx_atom,
28    input      [123:0] pcx_data,
29    output reg [  4:0] pcx_grant,
30    output reg         cpx_ready,
31    output reg [144:0] cpx_packet,
32   
33    // Wishbone master interface
34    input      [ 63:0] wb_data_i,
35    input              wb_ack,
36    output reg         wb_cycle,
37    output reg         wb_strobe,
38    output reg         wb_we,
39    output reg [  7:0] wb_sel,
40    output reg [ 63:0] wb_addr,
41    output reg [ 63:0] wb_data_o,
42   
43    // FPU interface
44    output reg [123:0] fp_pcx,
45    output reg         fp_req,
46    input      [144:0] fp_cpx,
47    input              fp_rdy,
48   
49    // Ethernet interrupt, sensed on posedge, mapped to vector 'd29
50    input              eth_int
51);
52
53reg [123:0] pcx_packet_d;    // Latched incoming PCX packet
54reg [123:0] pcx_packet_2nd;  // Second packet for atomic (CAS)
55reg [  4:0] pcx_req_d;       // Latched request
56reg         pcx_atom_d;      // Latched atomic flasg
57reg [  4:0] state;           // FSM state
58reg [144:0] cpx_packet_1;    // First CPX packet
59reg [144:0] cpx_packet_2;    // Second CPX packet (for atomics and cached IFILLs)
60reg         cpx_two_packet;  // CPX answer is two-packet (!=atomic, SWAP has atomic==0 and answer is two-packet)
61
62reg  [ 3:0] inval_vect0; // Invalidate, instr/data, way
63reg  [ 3:0] inval_vect1; // IFill may cause two D lines invalidation at a time
64
65wire [111:0] store_inv_vec; // Store invalidation vector
66
67assign store_inv_vec[111:91]=0;
68assign store_inv_vec[90:88]=((pcx_packet_d[64+5:64+4]==2'b11) && inval_vect0[3:2]==2'b11) ? {inval_vect0[1:0],1'b1}:3'b000;
69assign store_inv_vec[87:60]=0;
70assign store_inv_vec[59:56]=((pcx_packet_d[64+5:64+4]==2'b10) && inval_vect0[3:2]==2'b11) || ((pcx_packet_d[64+5]==1'b1) && inval_vect0[3:2]==2'b10) ? {inval_vect0[1:0],!inval_vect0[2],inval_vect0[2]}:4'b0000;
71assign store_inv_vec[55:35]=0;
72assign store_inv_vec[34:32]=((pcx_packet_d[64+5:64+4]==2'b01) && inval_vect0[3:2]==2'b11) ? {inval_vect0[1:0],1'b1}:3'b000;
73assign store_inv_vec[31:4]=0;
74assign store_inv_vec[3:0]=((pcx_packet_d[64+5:64+4]==2'b00) && inval_vect0[3:2]==2'b11) || ((pcx_packet_d[64+5]==1'b0) && inval_vect0[3:2]==2'b10) ? {inval_vect0[1:0],!inval_vect0[2],inval_vect0[2]}:4'b0000;
75
76wire [28:0] dcache0_do0;
77wire [28:0] dcache0_do1;
78wire [28:0] dcache1_do0;
79wire [28:0] dcache1_do1;
80wire [28:0] dcache2_do0;
81wire [28:0] dcache2_do1;
82wire [28:0] dcache3_do0;
83wire [28:0] dcache3_do1;
84wire [28:0] icache0_do;
85wire [28:0] icache1_do;
86wire [28:0] icache2_do;
87wire [28:0] icache3_do;
88
89`define TEST_DRAM_1      5'b00000
90`define TEST_DRAM_2      5'b00001
91`define TEST_DRAM_3      5'b00010
92`define TEST_DRAM_4      5'b00011
93`define INIT_DRAM_1      5'b00100
94`define INIT_DRAM_2      5'b00101
95`define WAKEUP           5'b00110
96`define PCX_IDLE         5'b00111
97`define GOT_PCX_REQ      5'b01000
98`define PCX_REQ_2ND      5'b01001
99`define PCX_REQ_STEP1    5'b01010
100`define PCX_REQ_STEP1_1  5'b01011
101`define PCX_REQ_STEP2    5'b01100
102`define PCX_REQ_STEP2_1  5'b01101
103`define PCX_REQ_STEP3    5'b01110
104`define PCX_REQ_STEP3_1  5'b01111
105`define PCX_REQ_STEP4    5'b10000
106`define PCX_REQ_STEP4_1  5'b10001
107`define PCX_BIS          5'b10010
108`define PCX_BIS_1        5'b10011
109`define PCX_BIS_2        5'b10100
110`define CPX_READY_1      5'b10101
111`define CPX_READY_2      5'b10110
112`define PCX_UNKNOWN      5'b11000
113`define PCX_FP_1         5'b11001
114`define PCX_FP_2         5'b11010
115`define FP_WAIT          5'b11011
116`define CPX_FP           5'b11100
117`define CPX_SEND_ETH_IRQ 5'b11101
118`define CPX_INT_VEC_DIS  5'b11110
119`define PCX_REQ_CAS_COMPARE 5'b11111
120
121`define MEM_SIZE         64'h00000000_10000000
122
123`define TEST_DRAM        1
124`define DEBUGGING        1
125
126reg        cache_init;
127wire [3:0] dcache0_hit;
128wire [3:0] dcache1_hit;
129wire [3:0] icache_hit;
130reg        multi_hit;
131reg        multi_hit1;
132reg        eth_int_d;
133reg        eth_int_send;
134reg        eth_int_sent;
135reg  [3:0] cnt;
136
137// PCX channel FIFO
138wire [129:0] pcx_data_fifo;
139wire         pcx_fifo_empty;
140reg  [  4:0] pcx_req_1;
141reg  [  4:0] pcx_req_2;
142reg          pcx_atom_1;
143reg          pcx_atom_2;
144reg          pcx_data_123_d;
145
146always @(posedge clk)
147   begin
148      pcx_req_1<=pcx_req;
149      pcx_atom_1<=pcx_atom;
150      pcx_atom_2<=pcx_atom_1;
151      pcx_req_2<=pcx_atom_1 ? pcx_req_1:5'b0;
152      pcx_grant<=(pcx_req_1 | pcx_req_2);
153      pcx_data_123_d<=pcx_data[123];
154   end
155       
156pcx_fifo pcx_fifo_inst( 
157       // FIFO should be first word fall-through
158       // It has no full flag as the core will send only limited number of requests,
159       // in original design we used it 32 words deep
160       // Just make it deeper if you experience overflow -
161       // you can't just send no grant on full because the core expects immediate
162       // grant for at least two requests for each zone
163    .aclr(!rstn),
164    .clock(clk),
165    .data({pcx_atom_1,pcx_req_1,pcx_data}),
166    .rdreq(fifo_rd),
167    .wrreq((pcx_req_1!=5'b00000 && pcx_data[123]) || (pcx_atom_2 && pcx_data_123_d)), 
168       // Second atomic packet for FPU may be invalid, but should be sent to FPU
169       // so if the first atomic packet is valid we latch both
170    .empty(pcx_fifo_empty),
171    .q(pcx_data_fifo)
172);
173// --------------------------
174
175always @(posedge clk or negedge rstn)
176   if(!rstn)
177      eth_int_send<=0;
178   else
179      begin
180         eth_int_d<=eth_int;
181         if(eth_int && !eth_int_d)
182            eth_int_send<=1;
183         else
184            if(eth_int_sent)
185               eth_int_send<=0;
186      end
187
188reg fifo_rd;
189wire [123:0] pcx_packet;
190assign pcx_packet=pcx_data_fifo[123:0];
191
192always @(posedge clk or negedge rstn)
193   if(rstn==0)
194      begin
195         if(`TEST_DRAM)
196            state<=`TEST_DRAM_1;
197         else
198            state<=`INIT_DRAM_1; // DRAM initialization is mandatory!
199         cpx_ready<=0;
200         fifo_rd<=0;
201         cpx_packet<=145'b0;
202         wb_cycle<=0;
203         wb_strobe<=0;
204         wb_we<=0;
205         wb_sel<=0;
206         wb_addr<=64'b0;
207         wb_data_o<=64'b0;
208         pcx_packet_d<=124'b0;
209         fp_pcx<=124'b0;
210         fp_req<=0;
211      end
212   else
213      case(state)
214         `TEST_DRAM_1:
215            begin
216               wb_cycle<=1;
217               wb_strobe<=1;
218               wb_sel<=8'hFF;
219               wb_we<=1;
220               state<=`TEST_DRAM_2;
221            end
222         `TEST_DRAM_2:
223            if(wb_ack)
224               begin
225                  wb_strobe<=0;
226                  if(wb_addr<`MEM_SIZE-8)
227                     begin
228                        wb_addr[31:0]<=wb_addr[31:0]+8;
229                        wb_data_o<={wb_addr[31:0]+8,wb_addr[31:0]+8};
230                        state<=`TEST_DRAM_1;
231                     end
232                  else
233                     begin
234                        state<=`TEST_DRAM_3;
235                        wb_cycle<=0;
236                        wb_sel<=0;
237                        wb_we<=0;
238                        wb_data_o<=64'b0;
239                        wb_addr<=64'b0;
240                     end
241               end               
242         `TEST_DRAM_3:
243            begin
244               wb_cycle<=1;
245               wb_strobe<=1;
246               wb_sel<=8'hFF;
247               state<=`TEST_DRAM_4;
248            end
249         `TEST_DRAM_4:
250            if(wb_ack)
251               begin
252                  wb_strobe<=0;
253                  if(wb_addr<`MEM_SIZE-8)
254                     begin
255                        if(wb_data_i=={wb_addr[31:0],wb_addr[31:0]})
256                           begin
257                              wb_addr[31:0]<=wb_addr[31:0]+8;
258                              state<=`TEST_DRAM_3;
259                           end
260                     end
261                  else
262                     begin
263                        state<=`INIT_DRAM_1;
264                        wb_cycle<=0;
265                        wb_sel<=0;
266                        wb_we<=0;
267                        wb_data_o<=64'b0;
268                        wb_addr<=64'b0;
269                     end
270               end               
271         `INIT_DRAM_1:
272            begin
273               wb_cycle<=1;
274               wb_strobe<=1;
275               wb_sel<=8'hFF;
276               wb_we<=1;
277               cache_init<=1; // We also init cache directories here
278               state<=`INIT_DRAM_2;
279            end
280         `INIT_DRAM_2:
281            if(wb_ack)
282               begin
283                  wb_strobe<=0;
284                  if(wb_addr<`MEM_SIZE-8)
285                     begin
286                        wb_addr[31:0]<=wb_addr[31:0]+8;
287                        pcx_packet_d[64+11:64+4]<=pcx_packet_d[64+11:64+4]+1; // Address for cachedir init
288                        state<=`INIT_DRAM_1;
289                     end
290                  else
291                     begin
292                        state<=`WAKEUP;
293                        wb_cycle<=0;
294                        wb_sel<=0;
295                        wb_we<=0;
296                        cache_init<=0;
297                        wb_addr<=64'b0;
298                     end
299               end               
300         `WAKEUP:
301            begin
302               cpx_packet<=145'h1700000000000000000000000000000010001;
303               cpx_ready<=1;
304               state<=`PCX_IDLE;
305            end
306         `PCX_IDLE:
307            begin
308               cnt<=0;
309               cpx_packet<=145'b0;
310               cpx_ready<=0;
311               cpx_two_packet<=0;
312               inval_vect0[3]<=0;
313               inval_vect1[3]<=0;
314               multi_hit<=0;
315               multi_hit1<=0;
316               if(eth_int_send)
317                  begin
318                     state<=`CPX_SEND_ETH_IRQ;
319                     eth_int_sent<=1;
320                  end
321               else
322                  if(!pcx_fifo_empty)
323                     begin
324                        pcx_req_d<=pcx_data_fifo[128:124];
325                        pcx_atom_d<=pcx_data_fifo[129];
326                        fifo_rd<=1;
327                        state<=`GOT_PCX_REQ;
328                     end
329            end
330         `GOT_PCX_REQ:
331            begin
332               pcx_packet_d<=pcx_packet;
333               if(`DEBUGGING)
334                  begin
335                     wb_sel[1:0]<=pcx_packet[113:112];
336                     wb_sel[2]<=1;
337                  end
338               if(pcx_packet[103:64]==40'h9800000800 && pcx_packet[122:118]==5'b00001)
339                  begin
340                     state<=`CPX_INT_VEC_DIS;
341                     fifo_rd<=0;
342                  end
343               else
344                  if(pcx_atom_d==0)
345                     begin
346                        fifo_rd<=0;
347                        if(pcx_packet[122:118]==5'b01010) // FP req
348                           begin
349                              state<=`PCX_FP_1;
350                              pcx_packet_2nd[123]<=0;
351                           end
352                        else
353                           state<=`PCX_REQ_STEP1;
354                     end
355                  else
356                     state<=`PCX_REQ_2ND;
357            end
358         `PCX_REQ_2ND:
359            begin
360               pcx_packet_2nd<=pcx_packet; //Latch second packet for atomics
361               if(`DEBUGGING)
362                  if(pcx_fifo_empty)
363                     wb_sel<=8'h67;
364               fifo_rd<=0;
365               if(pcx_packet_d[122:118]==5'b01010) // FP req
366                  state<=`PCX_FP_1;
367               else               
368                  state<=`PCX_REQ_STEP1;
369            end
370         `PCX_REQ_STEP1:
371            begin
372               if(pcx_packet_d[111]==1'b1) // Invalidate request
373                  begin
374                     cpx_packet_1[144]<=1;     // Valid
375                     cpx_packet_1[143:140]<=4'b0100; // Invalidate reply is Store ACK
376                     cpx_packet_1[139]<=1;     // L2 miss
377                     cpx_packet_1[138:137]<=0; // Error
378                     cpx_packet_1[136]<=pcx_packet_d[117]; // Non-cacheble
379                     cpx_packet_1[135:134]<=pcx_packet_d[113:112]; // Thread ID
380                     cpx_packet_1[133:131]<=0; // Way valid
381                     cpx_packet_1[130]<=((pcx_packet_d[122:118]==5'b10000) && (pcx_req_d==5'b10000)) ? 1:0; // Four byte fill
382                     cpx_packet_1[129]<=pcx_atom_d;
383                     cpx_packet_1[128]<=pcx_packet_d[110]; // Prefetch
384                     cpx_packet_1[127:0]<={2'b0,pcx_packet_d[109]/*BIS*/,pcx_packet_d[122:118]==5'b00000 ? 2'b01:2'b10,pcx_packet_d[64+5:64+4],3'b0,pcx_packet_d[64+11:64+6],112'b0};
385                     state<=`CPX_READY_1;
386                  end
387               else
388                  if(pcx_packet_d[122:118]!=5'b01001) // Not INT
389                     begin
390                        wb_cycle<=1'b1;
391                        wb_strobe<=1'b1;
392                        if((pcx_packet_d[122:118]==5'b00000 && !pcx_req_d[4]) || pcx_packet_d[122:118]==5'b00010 || pcx_packet_d[122:118]==5'b00100 || pcx_packet_d[122:118]==5'b00110)
393                           wb_addr<={pcx_req_d,19'b0,pcx_packet_d[103:64+4],4'b0000}; //DRAM load/streamload, CAS and SWAP always use DRAM and load first
394                        else
395                           if(pcx_packet_d[122:118]==5'b10000 && !pcx_req_d[4])
396                              wb_addr<={pcx_req_d,19'b0,pcx_packet_d[103:64+5],5'b00000}; //DRAM ifill
397                           else
398                              if(pcx_packet_d[64+39:64+28]==12'hFFF && pcx_packet_d[64+27:64+24]!=4'b0) // flash remap FFF1->FFF8
399                                 wb_addr<={pcx_req_d,19'b0,pcx_packet_d[103:64+3]+37'h0000E00000,3'b000};
400                              else
401                                 wb_addr<={pcx_req_d,19'b0,pcx_packet_d[103:64+3],3'b000};
402                        wb_data_o<=pcx_packet_d[63:0];
403                        state<=`PCX_REQ_STEP1_1;
404                     end
405                  else
406                     if((pcx_packet_d[12:10]!=3'b000) && !pcx_packet_d[117]) // Not FLUSH int and not this core
407                        state<=`PCX_IDLE; 
408                     else
409                        state<=`CPX_READY_1;
410               case(pcx_packet_d[122:118]) // Packet type
411                  5'b00000://Load
412                     begin
413                        wb_we<=0;
414                        if(!pcx_packet_d[110] && !pcx_packet_d[117])
415                           case(icache_hit)
416                              4'b0000:;
417                              4'b0001:inval_vect0<=4'b1_0_00;
418                              4'b0010:inval_vect0<=4'b1_0_01;
419                              4'b0100:inval_vect0<=4'b1_0_10;
420                              4'b1000:inval_vect0<=4'b1_0_11;
421                              default:multi_hit<=1;
422                           endcase
423                        if(!pcx_req_d[4])
424                           wb_sel<=8'b11111111; // DRAM requests are always 128 bit
425                        else
426                           case(pcx_packet_d[106:104]) //Size
427                              3'b000://Byte
428                                 case(pcx_packet_d[64+2:64])
429                                    3'b000:wb_sel<=8'b10000000;
430                                    3'b001:wb_sel<=8'b01000000;
431                                    3'b010:wb_sel<=8'b00100000;
432                                    3'b011:wb_sel<=8'b00010000;
433                                    3'b100:wb_sel<=8'b00001000;
434                                    3'b101:wb_sel<=8'b00000100;
435                                    3'b110:wb_sel<=8'b00000010;
436                                    3'b111:wb_sel<=8'b00000001;
437                                 endcase
438                              3'b001://Halfword
439                                 case(pcx_packet_d[64+2:64+1])
440                                    2'b00:wb_sel<=8'b11000000;
441                                    2'b01:wb_sel<=8'b00110000;
442                                    2'b10:wb_sel<=8'b00001100;
443                                    2'b11:wb_sel<=8'b00000011;
444                                 endcase
445                              3'b010://Word
446                                 wb_sel<=(pcx_packet_d[64+2]==0) ? 8'b11110000:8'b00001111;
447                              3'b011://Doubleword
448                                 wb_sel<=8'b11111111;
449                              3'b100://Quadword
450                                 wb_sel<=8'b11111111;
451                              3'b111://Cacheline
452                                 wb_sel<=8'b11111111;
453                              default:
454                                 wb_sel<=8'b01011010; // Unreal eye-catching value for debug
455                           endcase
456                     end
457                  5'b00001://Store
458                     begin
459                        wb_we<=1;
460                        case({icache_hit,dcache0_hit})
461                           8'b00000000:;
462                           8'b00000001:inval_vect0<=4'b1_1_00;
463                           8'b00000010:inval_vect0<=4'b1_1_01;
464                           8'b00000100:inval_vect0<=4'b1_1_10;
465                           8'b00001000:inval_vect0<=4'b1_1_11;
466                           8'b00010000:inval_vect0<=4'b1_0_00;
467                           8'b00100000:inval_vect0<=4'b1_0_01;
468                           8'b01000000:inval_vect0<=4'b1_0_10;
469                           8'b10000000:inval_vect0<=4'b1_0_11;
470                           default:multi_hit<=1;
471                        endcase
472                        if(pcx_packet_d[110:109]!=2'b00) //Block (or init) store
473                           wb_sel<=8'b11111111; // Blocks are always 64 bit
474                        else
475                           case(pcx_packet_d[106:104]) //Size
476                              3'b000://Byte
477                                 case(pcx_packet_d[64+2:64])
478                                    3'b000:wb_sel<=8'b10000000;
479                                    3'b001:wb_sel<=8'b01000000;
480                                    3'b010:wb_sel<=8'b00100000;
481                                    3'b011:wb_sel<=8'b00010000;
482                                    3'b100:wb_sel<=8'b00001000;
483                                    3'b101:wb_sel<=8'b00000100;
484                                    3'b110:wb_sel<=8'b00000010;
485                                    3'b111:wb_sel<=8'b00000001;
486                                 endcase
487                              3'b001://Halfword
488                                 case(pcx_packet_d[64+2:64+1])
489                                    2'b00:wb_sel<=8'b11000000;
490                                    2'b01:wb_sel<=8'b00110000;
491                                    2'b10:wb_sel<=8'b00001100;
492                                    2'b11:wb_sel<=8'b00000011;
493                                 endcase
494                              3'b010://Word
495                                 wb_sel<=(pcx_packet_d[64+2]==0) ? 8'b11110000:8'b00001111;
496                              3'b011://Doubleword
497                                 wb_sel<=8'b11111111;
498                              default:
499                                 if(`DEBUGGING)
500                                    wb_sel<=8'b01011010; // Unreal eye-catching value for debug
501                           endcase
502                     end
503                  5'b00010://CAS
504                     begin
505                        wb_we<=0; //Load first
506                        case({icache_hit,dcache0_hit})
507                           8'b00000000:;
508                           8'b00000001:inval_vect0<=4'b1_1_00;
509                           8'b00000010:inval_vect0<=4'b1_1_01;
510                           8'b00000100:inval_vect0<=4'b1_1_10;
511                           8'b00001000:inval_vect0<=4'b1_1_11;
512                           8'b00010000:inval_vect0<=4'b1_0_00;
513                           8'b00100000:inval_vect0<=4'b1_0_01;
514                           8'b01000000:inval_vect0<=4'b1_0_10;
515                           8'b10000000:inval_vect0<=4'b1_0_11;
516                           default:multi_hit<=1;
517                        endcase
518                        wb_sel<=8'b11111111; // CAS loads are as cacheline
519                     end
520                  5'b00100://STRLOAD
521                     begin
522                        wb_we<=0;
523                        wb_sel<=8'b11111111; // Stream loads are always 128 bit
524                     end
525                  5'b00101://STRSTORE
526                     begin
527                        wb_we<=1;
528                        case({icache_hit,dcache0_hit})
529                           8'b00000000:;
530                           8'b00000001:inval_vect0<=4'b1_1_00;
531                           8'b00000010:inval_vect0<=4'b1_1_01;
532                           8'b00000100:inval_vect0<=4'b1_1_10;
533                           8'b00001000:inval_vect0<=4'b1_1_11;
534                           8'b00010000:inval_vect0<=4'b1_0_00;
535                           8'b00100000:inval_vect0<=4'b1_0_01;
536                           8'b01000000:inval_vect0<=4'b1_0_10;
537                           8'b10000000:inval_vect0<=4'b1_0_11;
538                           default:multi_hit<=1;
539                        endcase
540                        case(pcx_packet_d[106:104]) //Size
541                           3'b000://Byte
542                              case(pcx_packet_d[64+2:64])
543                                 3'b000:wb_sel<=8'b10000000;
544                                 3'b001:wb_sel<=8'b01000000;
545                                 3'b010:wb_sel<=8'b00100000;
546                                 3'b011:wb_sel<=8'b00010000;
547                                 3'b100:wb_sel<=8'b00001000;
548                                 3'b101:wb_sel<=8'b00000100;
549                                 3'b110:wb_sel<=8'b00000010;
550                                 3'b111:wb_sel<=8'b00000001;
551                              endcase
552                           3'b001://Halfword
553                              case(pcx_packet_d[64+2:64+1])
554                                 2'b00:wb_sel<=8'b11000000;
555                                 2'b01:wb_sel<=8'b00110000;
556                                 2'b10:wb_sel<=8'b00001100;
557                                 2'b11:wb_sel<=8'b00000011;
558                              endcase
559                           3'b010://Word
560                              wb_sel<=(pcx_packet_d[64+2]==0) ? 8'b11110000:8'b00001111;
561                           3'b011://Doubleword
562                              wb_sel<=8'b11111111;
563                           3'b100://Quadword
564                              wb_sel<=8'b11111111;
565                           3'b111://Cacheline
566                              wb_sel<=8'b11111111;
567                           default:
568                              wb_sel<=8'b01011010; // Unreal eye-catching value for debug
569                        endcase
570                     end
571                  5'b00110://SWAP/LDSTUB
572                     begin
573                        case({icache_hit,dcache0_hit})
574                           8'b00000000:;
575                           8'b00000001:inval_vect0<=4'b1_1_00;
576                           8'b00000010:inval_vect0<=4'b1_1_01;
577                           8'b00000100:inval_vect0<=4'b1_1_10;
578                           8'b00001000:inval_vect0<=4'b1_1_11;
579                           8'b00010000:inval_vect0<=4'b1_0_00;
580                           8'b00100000:inval_vect0<=4'b1_0_01;
581                           8'b01000000:inval_vect0<=4'b1_0_10;
582                           8'b10000000:inval_vect0<=4'b1_0_11;
583                           default:multi_hit<=1;
584                        endcase
585                        wb_we<=0; // Load first, as CAS
586                        wb_sel<=8'b11111111; // SWAP/LDSTUB loads are as cacheline
587                     end
588                  5'b01001://INT
589                     if(pcx_packet_d[117]) // Flush
590                        cpx_packet_1<={9'h171,pcx_packet_d[113:112],11'h0,pcx_packet_d[64+5:64+4],3'b0,pcx_packet_d[64+11:64+6],30'h0,pcx_packet_d[17:0],46'b0,pcx_packet_d[17:0]}; //FLUSH instruction answer
591                     else // Tread-to-thread interrupt
592                        cpx_packet_1<={9'h170,pcx_packet_d[113:112],52'h0,pcx_packet_d[17:0],46'h0,pcx_packet_d[17:0]}; 
593                  //5'b01010: FP1 - processed by separate state
594                  //5'b01011: FP2 - processed by separate state
595                  //5'b01101: FWDREQ - not implemented
596                  //5'b01110: FWDREPL - not implemented
597                  5'b10000://IFILL
598                     begin
599                        wb_we<=0;
600                        if(!pcx_req_d[4]) // not I/O access
601                           begin
602                              case(dcache0_hit)
603                                 4'b0000:;
604                                 4'b0001:inval_vect0<=4'b1_1_00;
605                                 4'b0010:inval_vect0<=4'b1_1_01;
606                                 4'b0100:inval_vect0<=4'b1_1_10;
607                                 4'b1000:inval_vect0<=4'b1_1_11;
608                                 default:multi_hit<=1;
609                              endcase
610                              case(dcache1_hit)
611                                 4'b0000:;
612                                 4'b0001:inval_vect1<=4'b1_1_00;
613                                 4'b0010:inval_vect1<=4'b1_1_01;
614                                 4'b0100:inval_vect1<=4'b1_1_10;
615                                 4'b1000:inval_vect1<=4'b1_1_11;
616                                 default:multi_hit1<=1;
617                              endcase
618                           end
619                        if(pcx_req_d[4]) // I/O access
620                           wb_sel<=(pcx_packet_d[64+2]==0) ? 8'b11110000:8'b00001111;
621                        else
622                           wb_sel<=8'b11111111;
623                     end
624                  default:
625                     begin
626                        wb_we<=0;
627                        wb_sel<=8'b10101010; // Unreal eye-catching value for debug
628                     end
629               endcase
630            end
631         `PCX_REQ_STEP1_1:
632            begin
633               if(wb_ack)
634                  begin
635                     cpx_packet_1[144]<=1;     // Valid
636                     cpx_packet_1[139]<=(pcx_packet_d[122:118]==5'b00000) || (pcx_packet_d[122:118]==5'b10000) ? 1:0;     // L2 always miss on load and ifill
637                     cpx_packet_1[138:137]<=0; // Error
638                     cpx_packet_1[136]<=pcx_packet_d[117] || (pcx_packet_d[122:118]==5'b00001) ? 1:0; // Non-cacheble is set on store too
639                     cpx_packet_1[135:134]<=pcx_packet_d[113:112]; // Thread ID
640                     if((pcx_packet_d[122:118]==5'b00000 && !pcx_packet_d[117] && !pcx_packet_d[110]) || (pcx_packet_d[122:118]==5'b10000)) // Cacheble Load or IFill
641                        cpx_packet_1[133:131]<={inval_vect0[3],inval_vect0[1:0]};
642                     else
643                        cpx_packet_1[133:131]<=3'b000; // Way valid
644                     if(pcx_packet_d[122:118]==5'b00100) // Strload
645                        cpx_packet_1[130]<=pcx_packet_d[106]; // A
646                     else
647                        if(pcx_packet_d[122:118]==5'b00101) // Stream store
648                           cpx_packet_1[130]<=pcx_packet_d[108]; // A
649                        else
650                           cpx_packet_1[130]<=((pcx_packet_d[122:118]==5'b10000) && pcx_req_d[4]) ? 1:0; // Four byte fill
651                     if(pcx_packet_d[122:118]==5'b00100) // Strload
652                        cpx_packet_1[129]<=pcx_packet_d[105]; // B
653                     else     
654                        cpx_packet_1[129]<=pcx_atom_d || (pcx_packet_d[122:118]==5'b00110); // SWAP is single-packet but needs atom in CPX
655                     cpx_packet_1[128]<=pcx_packet_d[110] && pcx_packet_d[122:118]==5'b00000; // Prefetch
656                     cpx_packet_2[144]<=1;     // Valid
657                     cpx_packet_2[139]<=0;     // L2 miss
658                     cpx_packet_2[138:137]<=0; // Error
659                     cpx_packet_2[136]<=pcx_packet_d[117] || (pcx_packet_d[122:118]==5'b00001) ? 1:0; // Non-cacheble is set on store too
660                     cpx_packet_2[135:134]<=pcx_packet_d[113:112]; // Thread ID
661                     if(pcx_packet_d[122:118]==5'b10000) // IFill
662                        cpx_packet_2[133:131]<={inval_vect1[3],inval_vect1[1:0]};
663                     else
664                        cpx_packet_2[133:131]<=3'b000; // Way valid
665                     cpx_packet_2[130]<=0; // Four byte fill
666                     cpx_packet_2[129]<=pcx_atom_d || (pcx_packet_d[122:118]==5'b00110) || ((pcx_packet_d[122:118]==5'b10000) && !pcx_req_d[4]);
667                     cpx_packet_2[128]<=0; // Prefetch
668                     wb_strobe<=0;
669                     wb_sel<=8'b0;
670                     wb_addr<=64'b0;
671                     wb_data_o<=64'b0;
672                     wb_we<=0;
673                     case(pcx_packet_d[122:118]) // Packet type
674                        5'b00000://Load
675                           begin
676                              cpx_packet_1[143:140]<=4'b0000; // Type
677                              if(!pcx_req_d[4])
678                                 begin
679                                    cpx_packet_1[127:0]<={wb_data_i,wb_data_i};   
680                                    state<=`PCX_REQ_STEP2;
681                                 end
682                              else
683                                 case(pcx_packet_d[106:104]) //Size
684                                    3'b000://Byte
685                                       begin
686                                          case(pcx_packet_d[64+2:64])
687                                             3'b000:cpx_packet_1[127:0]<={wb_data_i[63:56],wb_data_i[63:56],wb_data_i[63:56],wb_data_i[63:56],wb_data_i[63:56],wb_data_i[63:56],wb_data_i[63:56],wb_data_i[63:56],wb_data_i[63:56],wb_data_i[63:56],wb_data_i[63:56],wb_data_i[63:56],wb_data_i[63:56],wb_data_i[63:56],wb_data_i[63:56],wb_data_i[63:56]};
688                                             3'b001:cpx_packet_1[127:0]<={wb_data_i[55:48],wb_data_i[55:48],wb_data_i[55:48],wb_data_i[55:48],wb_data_i[55:48],wb_data_i[55:48],wb_data_i[55:48],wb_data_i[55:48],wb_data_i[55:48],wb_data_i[55:48],wb_data_i[55:48],wb_data_i[55:48],wb_data_i[55:48],wb_data_i[55:48],wb_data_i[55:48],wb_data_i[55:48]};
689                                             3'b010:cpx_packet_1[127:0]<={wb_data_i[47:40],wb_data_i[47:40],wb_data_i[47:40],wb_data_i[47:40],wb_data_i[47:40],wb_data_i[47:40],wb_data_i[47:40],wb_data_i[47:40],wb_data_i[47:40],wb_data_i[47:40],wb_data_i[47:40],wb_data_i[47:40],wb_data_i[47:40],wb_data_i[47:40],wb_data_i[47:40],wb_data_i[47:40]};
690                                             3'b011:cpx_packet_1[127:0]<={wb_data_i[39:32],wb_data_i[39:32],wb_data_i[39:32],wb_data_i[39:32],wb_data_i[39:32],wb_data_i[39:32],wb_data_i[39:32],wb_data_i[39:32],wb_data_i[39:32],wb_data_i[39:32],wb_data_i[39:32],wb_data_i[39:32],wb_data_i[39:32],wb_data_i[39:32],wb_data_i[39:32],wb_data_i[39:32]};
691                                             3'b100:cpx_packet_1[127:0]<={wb_data_i[31:24],wb_data_i[31:24],wb_data_i[31:24],wb_data_i[31:24],wb_data_i[31:24],wb_data_i[31:24],wb_data_i[31:24],wb_data_i[31:24],wb_data_i[31:24],wb_data_i[31:24],wb_data_i[31:24],wb_data_i[31:24],wb_data_i[31:24],wb_data_i[31:24],wb_data_i[31:24],wb_data_i[31:24]};
692                                             3'b101:cpx_packet_1[127:0]<={wb_data_i[23:16],wb_data_i[23:16],wb_data_i[23:16],wb_data_i[23:16],wb_data_i[23:16],wb_data_i[23:16],wb_data_i[23:16],wb_data_i[23:16],wb_data_i[23:16],wb_data_i[23:16],wb_data_i[23:16],wb_data_i[23:16],wb_data_i[23:16],wb_data_i[23:16],wb_data_i[23:16],wb_data_i[23:16]};
693                                             3'b110:cpx_packet_1[127:0]<={wb_data_i[15: 8],wb_data_i[15: 8],wb_data_i[15: 8],wb_data_i[15: 8],wb_data_i[15: 8],wb_data_i[15: 8],wb_data_i[15: 8],wb_data_i[15: 8],wb_data_i[15: 8],wb_data_i[15: 8],wb_data_i[15: 8],wb_data_i[15: 8],wb_data_i[15: 8],wb_data_i[15: 8],wb_data_i[15: 8],wb_data_i[15: 8]};
694                                             3'b111:cpx_packet_1[127:0]<={wb_data_i[ 7: 0],wb_data_i[ 7: 0],wb_data_i[ 7: 0],wb_data_i[ 7: 0],wb_data_i[ 7: 0],wb_data_i[ 7: 0],wb_data_i[ 7: 0],wb_data_i[ 7: 0],wb_data_i[ 7: 0],wb_data_i[ 7: 0],wb_data_i[ 7: 0],wb_data_i[ 7: 0],wb_data_i[ 7: 0],wb_data_i[ 7: 0],wb_data_i[ 7: 0],wb_data_i[ 7: 0]};
695                                          endcase                     
696                                          wb_cycle<=0;
697                                          state<=`CPX_READY_1;
698                                       end
699                                    3'b001://Halfword
700                                       begin
701                                          case(pcx_packet_d[64+2:64+1])
702                                             2'b00:cpx_packet_1[127:0]<={wb_data_i[63:48],wb_data_i[63:48],wb_data_i[63:48],wb_data_i[63:48],wb_data_i[63:48],wb_data_i[63:48],wb_data_i[63:48],wb_data_i[63:48]};
703                                             2'b01:cpx_packet_1[127:0]<={wb_data_i[47:32],wb_data_i[47:32],wb_data_i[47:32],wb_data_i[47:32],wb_data_i[47:32],wb_data_i[47:32],wb_data_i[47:32],wb_data_i[47:32]};
704                                             2'b10:cpx_packet_1[127:0]<={wb_data_i[31:16],wb_data_i[31:16],wb_data_i[31:16],wb_data_i[31:16],wb_data_i[31:16],wb_data_i[31:16],wb_data_i[31:16],wb_data_i[31:16]};
705                                             2'b11:cpx_packet_1[127:0]<={wb_data_i[15: 0],wb_data_i[15: 0],wb_data_i[15: 0],wb_data_i[15: 0],wb_data_i[15: 0],wb_data_i[15: 0],wb_data_i[15: 0],wb_data_i[15: 0]};
706                                          endcase                     
707                                          wb_cycle<=0;
708                                          state<=`CPX_READY_1;
709                                       end
710                                    3'b010://Word
711                                       begin
712                                          if(pcx_packet_d[64+2]==0)
713                                             cpx_packet_1[127:0]<={wb_data_i[63:32],wb_data_i[63:32],wb_data_i[63:32],wb_data_i[63:32]};
714                                          else
715                                             cpx_packet_1[127:0]<={wb_data_i[31:0],wb_data_i[31:0],wb_data_i[31:0],wb_data_i[31:0]};
716                                          wb_cycle<=0;
717                                          state<=`CPX_READY_1;
718                                       end
719                                    3'b011://Doubleword
720                                       begin
721                                          cpx_packet_1[127:0]<={wb_data_i,wb_data_i};   
722                                          wb_cycle<=0;
723                                          state<=`CPX_READY_1;
724                                       end
725                                    3'b100://Quadword
726                                       begin
727                                          cpx_packet_1[127:0]<={wb_data_i,wb_data_i};   
728                                          wb_cycle<=0;
729                                          state<=`CPX_READY_1; // 16 byte access to PROM should just duplicate the data
730                                       end
731                                    3'b111://Cacheline
732                                       begin
733                                          cpx_packet_1[127:0]<={wb_data_i,wb_data_i};   
734                                          wb_cycle<=0;
735                                          state<=`CPX_READY_1; // 16 byte access to PROM should just duplicate the data
736                                       end
737                                    default:
738                                       begin
739                                          cpx_packet_1[127:0]<={wb_data_i,wb_data_i};   
740                                          wb_cycle<=0;
741                                          state<=`PCX_UNKNOWN;
742                                       end
743                                 endcase
744                           end
745                        5'b00001://Store
746                           begin
747                              cpx_packet_1[143:140]<=4'b0100; // Type
748                              cpx_packet_1[127:0]<={2'b0,pcx_packet_d[109]/*BIS*/,2'b0,pcx_packet_d[64+5:64+4],3'b0,pcx_packet_d[64+11:64+6],store_inv_vec};
749//                              if((pcx_packet_d[110:109]==2'b01) && (pcx_packet_d[64+5:64]==0) && !inval_vect0[3] && !inval_vect1[3]) // Block init store
750//                                 state<=`PCX_BIS;
751//                              else
752//                                 begin
753                                    wb_cycle<=0;
754                                    state<=`CPX_READY_1;
755//                                 end
756                           end
757                        5'b00010://CAS
758                           begin
759                              cpx_packet_1[143:140]<=4'b0000; // Load return for first packet
760                              cpx_packet_2[143:140]<=4'b0100; // Store ACK for second packet
761                              cpx_packet_2[127:0]<={5'b0,pcx_packet_d[64+5:64+4],3'b0,pcx_packet_d[64+11:64+6],store_inv_vec};
762                              cpx_packet_1[127:0]<={wb_data_i,wb_data_i};
763                              state<=`PCX_REQ_STEP2;
764                           end
765                        5'b00100://STRLOAD
766                           begin
767                              cpx_packet_1[143:140]<=4'b0010; // Type
768                              cpx_packet_1[127:0]<={wb_data_i,wb_data_i};
769                              state<=`PCX_REQ_STEP2;
770                           end
771                        5'b00101://STRSTORE
772                           begin
773                              cpx_packet_1[143:140]<=4'b0110; // Type
774                              cpx_packet_1[127:0]<={5'b0,pcx_packet_d[64+5:64+4],3'b0,pcx_packet_d[64+11:64+6],store_inv_vec};
775                              wb_cycle<=0;
776                              state<=`CPX_READY_1;
777                           end
778                        5'b00110://SWAP/LDSTUB
779                           begin
780                              cpx_packet_1[143:140]<=4'b0000; // Load return for first packet
781                              cpx_packet_2[143:140]<=4'b0100; // Store ACK for second packet
782                              cpx_packet_2[127:0]<={5'b0,pcx_packet_d[64+5:64+4],3'b0,pcx_packet_d[64+11:64+6],store_inv_vec};
783                              cpx_packet_1[127:0]<={wb_data_i,wb_data_i};
784                              state<=`PCX_REQ_STEP2; 
785                           end
786                        5'b10000://IFILL
787                           begin
788                              cpx_packet_1[143:140]<=4'b0001; // Type
789                              cpx_packet_2[143:140]<=4'b0001; // Type
790                              if(pcx_req_d[4]) // I/O access
791                                 begin
792                                    if(pcx_packet_d[64+2]==0)
793                                       cpx_packet_1[127:0]<={wb_data_i[63:32],wb_data_i[63:32],wb_data_i[63:32],wb_data_i[63:32]};
794                                    else
795                                       cpx_packet_1[127:0]<={wb_data_i[31:0],wb_data_i[31:0],wb_data_i[31:0],wb_data_i[31:0]};
796                                    state<=`CPX_READY_1;
797                                    wb_cycle<=0; 
798                                 end
799                              else
800                                 begin
801                                    cpx_packet_1[127:0]<={wb_data_i,wb_data_i};
802                                    state<=`PCX_REQ_STEP2;
803                                 end
804                           end
805                        default:
806                           begin
807                              wb_cycle<=0;
808                              state<=`PCX_UNKNOWN;
809                           end
810                     endcase
811                  end               
812               end
813         `PCX_REQ_STEP2: // IFill, Load/strload, CAS, SWAP, LDSTUB - alwas load
814            begin
815               wb_strobe<=1'b1;
816               if(pcx_packet_d[122:118]==5'b10000)
817                  wb_addr<={pcx_req_d,19'b0,pcx_packet_d[103:64+5],5'b01000};
818               else
819                  wb_addr<={pcx_req_d,19'b0,pcx_packet_d[103:64+4],4'b1000};
820               wb_sel<=8'b11111111; // It is always full width for subsequent IFill and load accesses
821               state<=`PCX_REQ_STEP2_1;
822            end
823         `PCX_REQ_STEP2_1:
824            if(wb_ack==1)
825               begin
826                  wb_strobe<=0;
827                  wb_sel<=8'b0;
828                  wb_addr<=64'b0;
829                  wb_data_o<=64'b0;
830                  wb_we<=0;
831                  cpx_packet_1[63:0]<=wb_data_i;
832                  if((pcx_packet_d[122:118]!=5'b00000) && (pcx_packet_d[122:118]!=5'b00100))
833                     if(pcx_packet_d[122:118]!=5'b00010) // IFill, SWAP
834                        state<=`PCX_REQ_STEP3;
835                     else
836                        state<=`PCX_REQ_CAS_COMPARE; // CAS
837                  else
838                     begin
839                        wb_cycle<=0;
840                        state<=`CPX_READY_1;
841                     end
842               end
843         `PCX_REQ_CAS_COMPARE:
844            begin
845               cpx_two_packet<=1;
846               if(pcx_packet_d[106:104]==3'b010) // 32-bit
847                  case(pcx_packet_d[64+3:64+2])
848                     2'b00:state<=cpx_packet_1[127:96]==pcx_packet_d[63:32] ? `PCX_REQ_STEP3:`CPX_READY_1;
849                     2'b01:state<=cpx_packet_1[95:64]==pcx_packet_d[63:32] ? `PCX_REQ_STEP3:`CPX_READY_1;
850                     2'b10:state<=cpx_packet_1[63:32]==pcx_packet_d[63:32] ? `PCX_REQ_STEP3:`CPX_READY_1;
851                     2'b11:state<=cpx_packet_1[31:0]==pcx_packet_d[63:32] ? `PCX_REQ_STEP3:`CPX_READY_1;
852                  endcase
853               else
854                  if(pcx_packet_d[64+3]==0)
855                     state<=cpx_packet_1[127:64]==pcx_packet_d[63:0] ? `PCX_REQ_STEP3:`CPX_READY_1;
856                  else
857                     state<=cpx_packet_1[63:0]==pcx_packet_d[63:0] ? `PCX_REQ_STEP3:`CPX_READY_1;
858            end
859         `PCX_REQ_STEP3: // 256-bit IFILL; CAS, SWAP and LDSTUB store
860            begin
861               if(pcx_packet_d[122:118]==5'b10000)
862                  wb_addr<={pcx_req_d,19'b0,pcx_packet_d[103:64+5],5'b10000};
863               else
864                  wb_addr<={pcx_req_d,19'b0,pcx_packet_d[103:64+3],3'b000}; // CAS or SWAP save
865               cpx_two_packet<=1;
866               if(pcx_packet_d[122:118]==5'b10000)
867                  wb_we<=0;
868               else
869                  wb_we<=1;
870               wb_strobe<=1'b1;
871               if(pcx_packet_d[122:118]==5'b00010) // CAS
872                  if(pcx_packet_d[106:104]==3'b010)
873                     wb_sel<=(pcx_packet_d[64+2]==0) ? 8'b11110000:8'b00001111;
874                  else
875                     wb_sel<=8'b11111111; //CASX
876               else
877                  if(pcx_packet_d[122:118]==5'b00110) //SWAP or LDSTUB
878                     if(pcx_packet_d[106:104]==3'b000)  //LDSTUB
879                        case(pcx_packet_d[64+2:64])
880                           3'b000:wb_sel<=8'b10000000;
881                           3'b001:wb_sel<=8'b01000000;
882                           3'b010:wb_sel<=8'b00100000;
883                           3'b011:wb_sel<=8'b00010000;
884                           3'b100:wb_sel<=8'b00001000;
885                           3'b101:wb_sel<=8'b00000100;
886                           3'b110:wb_sel<=8'b00000010;
887                           3'b111:wb_sel<=8'b00000001;
888                        endcase
889                     else   
890                        wb_sel<=(pcx_packet_d[64+2]==0) ? 8'b11110000:8'b00001111; ///SWAP is always 32-bit
891                  else
892                     wb_sel<=8'b11111111; // It is always full width for subsequent IFill accesses
893               if(pcx_packet_d[122:118]==5'b00110) //SWAP or LDSTUB
894                  wb_data_o<={pcx_packet_d[63:32],pcx_packet_d[63:32]};
895//                  wb_data_o<=pcx_packet_d[63:0];
896               else
897                  wb_data_o<=pcx_packet_2nd[63:0]; // CAS store second packet data
898//                  if(pcx_packet_d[106:104]==3'b010)
899//                     wb_data_o<={pcx_packet_2nd[63:32],pcx_packet_2nd[63:32]}; // CAS store second packet data
900//                  else
901//                     wb_data_o<=pcx_packet_2nd[63:0];
902               state<=`PCX_REQ_STEP3_1;
903            end
904         `PCX_REQ_STEP3_1:
905            if(wb_ack==1)
906               begin
907                  wb_strobe<=0;
908                  wb_sel<=8'b0;
909                  wb_addr<=64'b0;
910                  wb_we<=0;
911                  wb_data_o<=64'b0;
912                  if(pcx_packet_d[122:118]==5'b10000) // IFill
913                     begin
914                        cpx_packet_2[127:64]<=wb_data_i;
915                        state<=`PCX_REQ_STEP4;
916                     end
917                  else
918                     begin
919                        wb_cycle<=0;
920                        state<=`CPX_READY_1;
921                     end
922               end
923         `PCX_REQ_STEP4: // 256-bit IFILL only
924            begin
925               wb_strobe<=1'b1;
926               wb_addr<={pcx_req_d,19'b0,pcx_packet_d[103:64+5],5'b11000};
927               wb_sel<=8'b11111111; // It is always full width for subsequent accesses
928               state<=`PCX_REQ_STEP4_1;
929            end 
930         `PCX_REQ_STEP4_1:
931            if(wb_ack==1) 
932               begin
933                  wb_cycle<=0;
934                  wb_strobe<=0;
935                  wb_sel<=8'b0;
936                  wb_addr<=64'b0;
937                  wb_we<=0;
938                  cpx_packet_2[63:0]<=wb_data_i;
939                  state<=`CPX_READY_1;
940               end
941         `PCX_BIS: // Block init store
942            begin
943               wb_strobe<=1'b1;
944               wb_we<=1;
945               wb_addr<={pcx_req_d,19'b0,pcx_packet_d[103:64+6],6'b001000};
946               wb_sel<=8'b11111111;
947               wb_data_o<=64'b0;
948               state<=`PCX_BIS_1;
949            end
950         `PCX_BIS_1:
951            if(wb_ack)
952               begin
953                  wb_strobe<=0;
954                  if(wb_addr[39:0]<(pcx_packet_d[64+39:64]+8*7))
955                     state<=`PCX_BIS_2;
956                  else
957                     begin
958                        wb_cycle<=0;
959                        wb_sel<=0;
960                        wb_we<=0;
961                        wb_addr<=64'b0;
962                        state<=`CPX_READY_1;
963                     end
964               end
965         `PCX_BIS_2:
966            begin
967               wb_strobe<=1'b1;
968               wb_addr[5:0]<=wb_addr[5:0]+8;
969               state<=`PCX_BIS_1;
970            end
971         `PCX_FP_1:
972            begin
973               fp_pcx<=pcx_packet_d;
974               fp_req<=1;
975               state<=`PCX_FP_2;
976               if(`DEBUGGING)
977                  begin
978                     wb_addr<=pcx_packet_d[103:64];
979                     wb_data_o<=pcx_packet_d[63:0];
980                     wb_sel<=8'h22;
981                  end
982            end
983         `PCX_FP_2:
984            begin
985               fp_pcx<=pcx_packet_2nd;
986               state<=`FP_WAIT;
987               if(`DEBUGGING)
988                  begin
989                     wb_addr<=pcx_packet_2nd[103:64];
990                     wb_data_o<=pcx_packet_d[63:0];
991                     wb_sel<=8'h23;
992                  end
993            end
994         `FP_WAIT:
995            begin
996               fp_pcx<=124'b0;
997               fp_req<=0;
998               if(fp_rdy)
999                  state<=`CPX_FP;
1000               if(`DEBUGGING)
1001                  wb_sel<=8'h24;
1002            end
1003         `CPX_FP:
1004            if(fp_cpx[144]) // Packet valid
1005               begin               
1006                  cpx_packet_1<=fp_cpx;
1007                  state<=`CPX_READY_1;
1008                  if(`DEBUGGING)
1009                     begin
1010                        wb_addr<=fp_cpx[63:0];
1011                        wb_data_o<=fp_cpx[127:64];
1012                     end
1013               end
1014            else
1015               if(!fp_rdy)
1016                  state<=`FP_WAIT; // Else wait for another one if it is not here still
1017         `CPX_SEND_ETH_IRQ:
1018            begin
1019               cpx_packet_1<=145'h1_7_000_000000000000001D_000000000000_001D;
1020               eth_int_sent<=0;
1021               state<=`CPX_READY_1;
1022            end
1023         `CPX_INT_VEC_DIS:
1024            begin
1025               if(pcx_packet_d[12:10]==3'b000)
1026                  cpx_two_packet<=1; // Send interrupt only if it is for this core
1027               cpx_packet_1[144:140]<=5'b10100;
1028               cpx_packet_1[139:137]<=0;
1029               cpx_packet_1[136]<=1;
1030               cpx_packet_1[135:134]<=pcx_packet_d[113:112]; // Thread ID
1031               cpx_packet_1[133:130]<=0;
1032               cpx_packet_1[129]<=pcx_atom_d;
1033               cpx_packet_1[128]<=0;
1034               cpx_packet_1[127:0]<={5'b0,pcx_packet_d[64+5:64+4],3'b0,pcx_packet_d[64+11:64+6],112'b0};
1035               cpx_packet_2<={9'h170,54'h0,pcx_packet_d[17:0],46'h0,pcx_packet_d[17:0]}; 
1036               state<=`CPX_READY_1;
1037            end
1038         `CPX_READY_1:
1039            begin
1040               cpx_ready<=1;
1041               cpx_packet<=cpx_packet_1;
1042               cnt<=cnt+1;
1043               if(`DEBUGGING)
1044                  if(multi_hit || multi_hit1)
1045                     wb_sel<=8'h11;
1046               if(!cpx_two_packet)
1047                  state<=`PCX_IDLE;
1048               else
1049                  //if(cnt==4'b1111 || pcx_packet_d[103:64]!=40'h9800000800)   
1050                     state<=`CPX_READY_2;
1051            end
1052         `CPX_READY_2:
1053            begin
1054               cpx_ready<=1;
1055               cpx_packet<=cpx_packet_2;
1056               state<=`PCX_IDLE;
1057            end
1058         `PCX_UNKNOWN:
1059            begin
1060               wb_sel<=8'b10100101; // Illegal eye-catching value for debugging
1061               state<=`PCX_IDLE;
1062            end
1063      endcase
1064
1065/* Cache directory checking:
1066  Load:  allocate D if cacheable, check I, invalidate&deallocate if found
1067  Store: check I, invalidate&deallocate if found; check D, invalidate if found
1068  IFill: allocate I if cacheable, check D, invalidate&deallocate if found
1069  SWAP/LDSTUB:  check I, invalidate&deallocate if found; check D, invalidate&deallocate if found
1070  CAS: Like SWAP
1071 
1072  Allocation and querying is made simultaneously at GOT_PCX_REQ
1073     (memory read mode does not matter as long as allocation and invalidation
1074      are never made to the same directory, so if memory is written its output will not be checked)
1075  Invalidation vectors are built during PCX_REQ_STEP1, or Invalidate all ways issued
1076  During PCX_REQ_STEP1_1 directory is deallocated if needed
1077 
1078*/
1079
1080// Directory enable
1081assign dir_en=((state==`GOT_PCX_REQ) || (state==`PCX_REQ_STEP1) || cache_init ||
1082              ((state==`PCX_REQ_STEP1_1) && wb_ack)) ? 1:0;
1083
1084// ICache deallocation flag
1085assign loadstore=((pcx_packet_d[122:118]==5'b00000) && !pcx_packet_d[117] && !pcx_packet_d[110]) || // cacheable load, not prefetch
1086                 (pcx_packet_d[122:118]==5'b00001) || (pcx_packet_d[122:118]==5'b00010) || //  Store, CAS
1087                 (pcx_packet_d[122:118]==5'b00110) || (pcx_packet_d[122:118]==5'b00101); // SWAP/LDSTUB, StrStore
1088
1089// DCache deallocation flag                 
1090assign ifillcas=(pcx_packet_d[122:118]==5'b00110) || (pcx_packet_d[122:118]==5'b00010) || //SWAP, CAS
1091                (pcx_packet_d[122:118]==5'b10000) || (pcx_packet_d[122:118]==5'b00101) || // IFill, StrStore
1092                ((pcx_packet_d[122:118]==5'b00001) && pcx_packet_d[110:109]!=2'b00); // Block (or init) store
1093
1094// DCache allocation flag
1095assign cacheload=(pcx_packet[122:118]==5'b00000) && !pcx_packet[110] && !pcx_packet[117] && !pcx_packet[111];
1096
1097// ICache allocation flag
1098assign cacheifill=(pcx_packet[122:118]==5'b10000) && !pcx_packet[117] && !pcx_packet[111];
1099
1100assign dcache0_alloc=(state==`GOT_PCX_REQ) && (pcx_packet[108:107]==2'b00) && cacheload;
1101assign dcache0_dealloc0=(state==`PCX_REQ_STEP1_1) && (inval_vect0==4'b1_1_00) && ifillcas;
1102assign dcache0_dealloc1=(state==`PCX_REQ_STEP1_1) && (inval_vect1==4'b1_1_00) && ifillcas;
1103
1104assign dcache1_alloc=(state==`GOT_PCX_REQ) && (pcx_packet[108:107]==2'b01) && cacheload;
1105assign dcache1_dealloc0=(state==`PCX_REQ_STEP1_1) && (inval_vect0==4'b1_1_01) && ifillcas;
1106assign dcache1_dealloc1=(state==`PCX_REQ_STEP1_1) && (inval_vect1==4'b1_1_01) && ifillcas;
1107
1108assign dcache2_alloc=(state==`GOT_PCX_REQ) && (pcx_packet[108:107]==2'b10) && cacheload;
1109assign dcache2_dealloc0=(state==`PCX_REQ_STEP1_1) && (inval_vect0==4'b1_1_10) && ifillcas;
1110assign dcache2_dealloc1=(state==`PCX_REQ_STEP1_1) && (inval_vect1==4'b1_1_10) && ifillcas;
1111
1112assign dcache3_alloc=(state==`GOT_PCX_REQ) && (pcx_packet[108:107]==2'b11) && cacheload;
1113assign dcache3_dealloc0=(state==`PCX_REQ_STEP1_1) && (inval_vect0==4'b1_1_11) && ifillcas;
1114assign dcache3_dealloc1=(state==`PCX_REQ_STEP1_1) && (inval_vect1==4'b1_1_11) && ifillcas;
1115
1116assign icache0_alloc=(state==`GOT_PCX_REQ) && (pcx_packet[108:107]==2'b00) && cacheifill;
1117assign icache0_dealloc=(state==`PCX_REQ_STEP1_1) && (inval_vect0==4'b1_0_00) && loadstore;
1118
1119assign icache1_alloc=(state==`GOT_PCX_REQ) && (pcx_packet[108:107]==2'b01) && cacheifill;
1120assign icache1_dealloc=(state==`PCX_REQ_STEP1_1) && (inval_vect0==4'b1_0_01) && loadstore;
1121
1122assign icache2_alloc=(state==`GOT_PCX_REQ) && (pcx_packet[108:107]==2'b10) && cacheifill;
1123assign icache2_dealloc=(state==`PCX_REQ_STEP1_1) && (inval_vect0==4'b1_0_10) && loadstore;
1124
1125assign icache3_alloc=(state==`GOT_PCX_REQ) && (pcx_packet[108:107]==2'b11) && cacheifill;
1126assign icache3_dealloc=(state==`PCX_REQ_STEP1_1) && (inval_vect0==4'b1_0_11) && loadstore;
1127
1128assign dcache_inval_all=(state==`PCX_REQ_STEP1) && pcx_packet_d[111] && pcx_packet_d[122:118]==5'b00000;
1129assign icache_inval_all=(state==`PCX_REQ_STEP1) && pcx_packet_d[111] && pcx_packet_d[122:118]==5'b10000;
1130
1131`define INVAL_TAG 29'h10000000
1132
1133// DCache least address bit for first bank
1134// it should be 0 for IFill (1 is hardcoded for second bank)
1135assign dcache_la=(state==`GOT_PCX_REQ) ? (pcx_packet[122:118]==5'b10000 ? 1'b0:pcx_packet[64+4]):
1136                 (pcx_packet_d[122:118]==5'b10000 ? 1'b0:pcx_packet_d[64+4]);
1137
1138wire [ 6:0] dcache_index;
1139wire [28:0] dcache_data;
1140assign dcache_index=(state==`GOT_PCX_REQ) ? pcx_packet[64+10:64+5]:pcx_packet_d[64+10:64+5];
1141assign dcache_data=(state==`GOT_PCX_REQ) ? pcx_packet[64+39:64+11]:`INVAL_TAG;
1142
1143cachedir dcache0 (
1144   .clock(clk),
1145   .enable(dir_en),
1146   .wren_a(dcache0_alloc || dcache0_dealloc0 || dcache_inval_all || cache_init),
1147   .address_a({1'b0,dcache_index,dcache_la}),
1148   .data_a(dcache_data),
1149   .q_a(dcache0_do0),
1150 
1151   .wren_b(dcache0_dealloc1),
1152   .address_b({1'b0,dcache_index,1'b1}),
1153   .data_b(`INVAL_TAG),
1154   .q_b(dcache0_do1) 
1155);
1156
1157cachedir dcache1 (
1158   .clock(clk),
1159   .enable(dir_en),
1160   .wren_a(dcache1_alloc || dcache1_dealloc0 || dcache_inval_all || cache_init),
1161   .address_a({1'b0,dcache_index,dcache_la}),
1162   .data_a(dcache_data),
1163   .q_a(dcache1_do0),
1164   
1165   .wren_b(dcache1_dealloc1),
1166   .address_b({1'b0,dcache_index,1'b1}),
1167   .data_b(`INVAL_TAG),
1168   .q_b(dcache1_do1) 
1169);
1170
1171cachedir dcache2 (
1172   .clock(clk),
1173   .enable(dir_en),
1174   .wren_a(dcache2_alloc || dcache2_dealloc0 || dcache_inval_all || cache_init),
1175   .address_a({1'b0,dcache_index,dcache_la}),
1176   .data_a(dcache_data),
1177   .q_a(dcache2_do0),
1178   
1179   .wren_b(dcache2_dealloc1),
1180   .address_b({1'b0,dcache_index,1'b1}),
1181   .data_b(`INVAL_TAG),
1182   .q_b(dcache2_do1) 
1183);
1184
1185cachedir dcache3 (
1186   .clock(clk),
1187   .enable(dir_en),
1188   .wren_a(dcache3_alloc || dcache3_dealloc0 || dcache_inval_all || cache_init),
1189   .address_a({1'b0,dcache_index,dcache_la}),
1190   .data_a(dcache_data),
1191   .q_a(dcache3_do0),
1192   
1193   .wren_b(dcache3_dealloc1),
1194   .address_b({1'b0,dcache_index,1'b1}),
1195   .data_b(`INVAL_TAG),
1196   .q_b(dcache3_do1) 
1197);
1198
1199assign dcache0_hit={dcache3_do0==pcx_packet_d[64+39:64+11],
1200                    dcache2_do0==pcx_packet_d[64+39:64+11],
1201                    dcache1_do0==pcx_packet_d[64+39:64+11],
1202                    dcache0_do0==pcx_packet_d[64+39:64+11]};
1203assign dcache1_hit={dcache3_do1==pcx_packet_d[64+39:64+11],
1204                    dcache2_do1==pcx_packet_d[64+39:64+11],
1205                    dcache1_do1==pcx_packet_d[64+39:64+11],
1206                    dcache0_do1==pcx_packet_d[64+39:64+11]};
1207
1208wire [ 6:0] icache_index;
1209wire [28:0] icache_data;
1210assign icache_index=(state==`GOT_PCX_REQ) ? pcx_packet[64+11:64+5]:pcx_packet_d[64+11:64+5];
1211assign icache_data=(state==`GOT_PCX_REQ) ? {pcx_packet[64+39:64+12],1'b0}:`INVAL_TAG;
1212
1213cachedir icache01 (
1214   .clock(clk),
1215   .enable(dir_en),
1216   .wren_a(icache0_alloc || icache0_dealloc || icache_inval_all || cache_init),
1217   .address_a({1'b0,icache_index}),
1218   .data_a(icache_data),
1219   .q_a(icache0_do),
1220   
1221   .wren_b(icache1_alloc || icache1_dealloc || icache_inval_all || cache_init),
1222   .address_b({1'b1,icache_index}),
1223   .data_b(icache_data),
1224   .q_b(icache1_do) 
1225);
1226
1227cachedir icache23 (
1228   .clock(clk),
1229   .enable(dir_en),
1230   .wren_a(icache2_alloc || icache2_dealloc || icache_inval_all || cache_init),
1231   .address_a({1'b0,icache_index}),
1232   .data_a(icache_data),
1233   .q_a(icache2_do),
1234   
1235   .wren_b(icache3_alloc || icache3_dealloc || icache_inval_all || cache_init),
1236   .address_b({1'b1,icache_index}),
1237   .data_b(icache_data),
1238   .q_b(icache3_do) 
1239);
1240
1241assign icache_hit={icache3_do[28:1]==pcx_packet_d[64+39:64+12],
1242                   icache2_do[28:1]==pcx_packet_d[64+39:64+12],
1243                   icache1_do[28:1]==pcx_packet_d[64+39:64+12],
1244                   icache0_do[28:1]==pcx_packet_d[64+39:64+12]};
1245
1246/*
1247               case(pcx_packet_d[122:118]) // Packet type
1248                  5'b00000://Load
1249                  5'b00001://Store
1250                  5'b00010://CAS
1251                  5'b00100://STRLOAD
1252                  5'b00101://STRSTORE
1253                  5'b00110://SWAP
1254                  5'b01001://INT
1255                  //5'b01010://FP1
1256                  //5'b01011://FP2
1257                  //5'b01101://FWDREQ
1258                  //5'b01110://FWDREPL
1259                  5'b10000://IFILL
1260               endcase
1261*/
1262endmodule
Note: See TracBrowser for help on using the repository browser.