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

Revision 10, 58.0 KB checked in by pntsvt00, 14 years ago (diff)

versione sintetizzabile

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