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

Revision 26, 60.4 KB checked in by pntsvt00, 13 years ago (diff)

checkpoint: baco con store consecutivi

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