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

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

commit per simulazione di os2wb e Top

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