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

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

checkpoint: la DDR effettua l'init

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