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

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

eliminato baco store consecutivi. esegue correttamente il codice

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