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

Revision 36, 60.6 KB checked in by pntsvt00, 13 years ago (diff)

modificati i file per la compilazione. boot.s linkato a 0xFFF0000020

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