OpenCores
URL https://opencores.org/ocsvn/sparc64soc/sparc64soc/trunk

Subversion Repositories sparc64soc

[/] [sparc64soc/] [trunk/] [os2wb/] [os2wb.v] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.