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

Subversion Repositories sparc64soc

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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