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

Subversion Repositories s1_core

[/] [s1_core/] [trunk/] [hdl/] [rtl/] [s1_top/] [os2wb.v] - Blame information for rev 114

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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