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

Subversion Repositories s1_core

[/] [s1_core/] [trunk/] [hdl/] [rtl/] [s1_top/] [spc2wbm.v] - Blame information for rev 113

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

Line No. Rev Author Line
1 4 fafa1971
/*
2
 * Bridge from SPARC Core to Wishbone Master
3
 *
4 113 albert.wat
 * (C) 2006-2007 Simply RISC LLP
5 4 fafa1971
 * AUTHOR: Fabrizio Fazzino <fabrizio.fazzino@srisc.com>
6
 *
7
 * LICENSE:
8
 * This is a Free Hardware Design; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * version 2 as published by the Free Software Foundation.
11
 * The above named program is distributed in the hope that it will
12
 * be useful, but WITHOUT ANY WARRANTY; without even the implied
13
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
 * See the GNU General Public License for more details.
15
 *
16
 * DESCRIPTION:
17
 * This block implements a bridge from one SPARC Core of the
18
 * OpenSPARC T1 to a master interface that makes use of the
19
 * Wishbone interconnect protocol.
20
 * For informations about Sun Microsystems' OpenSPARC T1
21
 * refer to the web site http://www.opensparc.net
22
 * For informations about OpenCores' Wishbone interconnect
23
 * please refer to the web site http://www.opencores.org
24
 */
25
 
26
`include "s1_defs.h"
27 113 albert.wat
`define SPC_REGION_HI 4
28
`define SPC_REGION_LO 0
29
`define SPC_REGION_WIDTH (`SPC_REGION_HI-`SPC_REGION_LO+1)
30
`define SPC_INFO_WIDTH (`SPC_REGION_WIDTH+1)
31 4 fafa1971
 
32
module spc2wbm (
33
 
34 99 fafa1971
    /*
35
     * Inputs
36
     */
37 4 fafa1971
 
38 99 fafa1971
    // System inputs
39
    input sys_clock_i,                            // System Clock
40
    input sys_reset_i,                            // System Reset
41
    input[5:0] sys_interrupt_source_i,            // Encoded Interrupt Source
42 4 fafa1971
 
43 99 fafa1971
    // SPARC-side inputs connected to the PCX (Processor-to-Cache Xbar) outputs of the SPARC Core
44 113 albert.wat
    input[`SPC_REGION_WIDTH-1:0] spc_req_i,       // Request Region
45 99 fafa1971
    input spc_atom_i,                             // Atomic Request
46
    input[(`PCX_WIDTH-1):0] spc_packetout_i,      // Outgoing Packet
47 4 fafa1971
 
48 99 fafa1971
    // Wishbone Master interface inputs
49
    input wbm_ack_i,                              // Ack
50
    input[(`WB_DATA_WIDTH-1):0] wbm_data_i,       // Data In
51 4 fafa1971
 
52 99 fafa1971
    /*
53
     * Outputs
54
     */
55 4 fafa1971
 
56 99 fafa1971
    // SPARC-side outputs connected to the CPX (Cache-to-Processor Xbar) inputs of the SPARC Core
57 113 albert.wat
    output logic[4:0] spc_grant_o,                // Grant
58 99 fafa1971
    output reg spc_ready_o,                       // Ready
59
    output reg[`CPX_WIDTH-1:0] spc_packetin_o,    // Incoming Packet
60 4 fafa1971
 
61 99 fafa1971
    // Wishbone Master interface outputs
62
    output reg wbm_cycle_o,                       // Cycle Start
63
    output reg wbm_strobe_o,                      // Strobe Request
64
    output reg wbm_we_o,                          // Write Enable
65
    output reg[`WB_ADDR_WIDTH-1:0] wbm_addr_o,    // Address Bus
66
    output reg[`WB_DATA_WIDTH-1:0] wbm_data_o,    // Data Out
67
    output reg[`WB_DATA_WIDTH/8-1:0] wbm_sel_o    // Select Output
68 4 fafa1971
 
69 99 fafa1971
  );
70
 
71 4 fafa1971
  /*
72 113 albert.wat
   * Packet Structures
73 4 fafa1971
   */
74
 
75 113 albert.wat
  // Processor-to-Cache Xbar request region and atomic info
76
  typedef struct packed {
77
    logic [`SPC_REGION_WIDTH-1:0] region;         // info[5:1] Region
78
    logic                         atomic;         // info[0]   Atomicity
79
  } pcx_info_t;
80 4 fafa1971
 
81 113 albert.wat
  // Processor-to-Cache Xbar request packet type (PCX payload 124-bit)
82
  typedef struct packed {
83
    logic                                 valid;         // pcx[123]       Packet Valid
84
    logic [`PCX_RQ_HI-`PCX_RQ_LO:0] request_type;  // pcx[122:118]   Request Type (LOAD_/IMISS_/STORE_/CAS1_/CAS2_/SWAP_/STRLOAD_/STRST_/STQ_/INT_/FWD_/RSVD_RQ FWD_RPY)
85
    logic                           noncache_rnw;  // pcx[117]       Non-Cacheable, or ReadNotWrite
86
    logic [`PCX_CP_HI-`PCX_CP_LO:0] cpu_id;        // pcx[116:114]   CPU ID
87
    logic [`PCX_TH_HI-`PCX_TH_LO:0] thread_id;     // pcx[113:112]   Thread ID
88
    logic [`PCX_BF_HI-`PCX_BF_LO:0] buffer_id;     // pcx[111:109]   Buffer ID
89
    logic [`PCX_WY_HI-`PCX_WY_LO:0] l1way_packetid;// pcx[108:107]   L1 Way Replaced, or Packet ID
90
    logic [`PCX_SZ_HI-`PCX_SZ_LO:0] access_size;   // pcx{106:104]   Access Size (PCX_SZ_1B/_2B/_4B/_8B/16B), or Error Field
91
    logic [`PCX_AD_HI-`PCX_AD_LO:0] address;       // pcx[103:64]    Address
92
    logic [`PCX_DA_HI-`PCX_DA_LO:0] store_data;    // pcx[63:0]      Store Data
93
  } pcx_packet_t;
94 4 fafa1971
 
95 113 albert.wat
  // Cache-to-Processor Xbar return packet type (CPX payload 145-bit)
96
  typedef struct packed {
97
    logic                             valid;       // cpx[144]     Packet Valid
98
    logic [`CPX_RQ_HI-`CPX_RQ_LO:0]   return_type; // cpx[143:140] Return Type (LOAD_/INV_/INT_/TEST_/FP_/IFILL_/ERR_/STRLOAD_/FWD_RQ_/FWD_RPY_/RSVD_RET ST_/AT_/STRST_ACK EVICT_REQ)
99
    logic [`CPX_ERR_HI-`CPX_ERR_LO:0] error;       // cpx[139:137] Error
100
    logic                             noncache_rnw;// cpx[136]     Non-Cacheable, or ReadNotWrite
101
    logic [`CPX_TH_HI-`CPX_TH_LO:0]   thread_id;   // cpx[135:134] Thread ID
102
    logic [`CPX_IN_HI-`CPX_IN_LO:0]   intsrc_etc;  // cpx[133:128] Interrupt Source, or Way Replaced, or Buffer ID, or Packet ID, or Invalidates, etc.
103
    logic [`CPX_DA_HI-`CPX_DA_LO:0]   load_data;   // cpx[127:0]   Load Data
104
  } cpx_packet_t;
105 4 fafa1971
 
106
  /*
107 113 albert.wat
   * Useful Function
108 4 fafa1971
   */
109
 
110 113 albert.wat
   function automatic logic[`WB_DATA_WIDTH/8-1:0] pcxsize2wbmsel(logic [`PCX_SZ_HI-`PCX_SZ_LO:0] access_size, logic [`PCX_AD_HI-`PCX_AD_LO:0] address);
111
     case(access_size)
112
       `PCX_SZ_1B: return (1'b1    << address[2:0]);
113
       `PCX_SZ_2B: return (2'b11   << (address[2:1] << 1));
114
       `PCX_SZ_4B: return (4'b1111 << (address[2] << 2));
115
       `PCX_SZ_8B: return 8'b11111111;
116
       `PCX_SZ_16B: return 8'b11111111;  // Requires a 2nd access
117
       default: return 8'b00000000;
118
     endcase // case (access_size)
119
   endfunction
120 4 fafa1971
 
121 113 albert.wat
// synopsys translate_off
122
`ifdef SIMPLY_RISC_DEBUG
123 4 fafa1971
 
124 113 albert.wat
  task automatic print_pcx_packet(pcx_info_t _pcx_info, pcx_packet_t _pcx_packet);
125
    string str_region, str_type, str_size;
126
    case(_pcx_info.region)
127
      5'b00001: str_region = "RAM_Bank_0";
128
      5'b00010: str_region = "RAM_Bank_1";
129
      5'b00100: str_region = "RAM_Bank_2";
130
      5'b01000: str_region = "RAM Bank_3";
131
      5'b10000: str_region = "IO_Block";
132
      default:  str_region = "Unknown";
133
    endcase
134
    case(_pcx_packet.request_type)
135
      `LOAD_RQ:    str_type = "LOAD_RQ";
136
      `IMISS_RQ:   str_type = "IMISS_RQ";
137
      `STORE_RQ:   str_type = "STORE_RQ";
138
      `CAS1_RQ:    str_type = "CAS1_RQ";
139
      `CAS2_RQ:    str_type = "CAS2_RQ";
140
      `SWAP_RQ:    str_type = "SWAP_RQ";
141
      `STRLOAD_RQ: str_type = "STRLOAD_RQ";
142
      `STRST_RQ:   str_type = "STRST_RQ";
143
      `STQ_RQ:     str_type = "STQ_RQ";
144
      `INT_RQ:     str_type = "INT_RQ";
145
      `FWD_RQ:     str_type = "FWD_RQ";
146
      `FWD_RPY:    str_type = "FWD_RPY";
147
      `RSVD_RQ:    str_type = "RSVD_RQ";
148
      default:     str_type = "Unknown";
149
          endcase
150
    case(_pcx_packet.access_size)
151
      `PCX_SZ_1B:  str_size = "1B";
152
      `PCX_SZ_2B:  str_size = "2B";
153
      `PCX_SZ_4B:  str_size = "4B";
154
      `PCX_SZ_8B:  str_size = "8B";
155
      `PCX_SZ_16B: str_size = "16B";
156
      default:     str_size = "Unknown";
157
    endcase
158
    $display("INFO: PCX: REQUEST Region=%s Atomic=%0d Valid=%0d Type=%s NonCache_RnW=%0d PE=%0d.%0d Buffer=%0d L1Way_Packet=%0d Size=%s Address=0x%016X Store_Data=0x%016X", str_region, _pcx_info.atomic, _pcx_packet.valid, str_type, _pcx_packet.noncache_rnw, _pcx_packet.cpu_id, _pcx_packet.thread_id, _pcx_packet.buffer_id, _pcx_packet.l1way_packetid, str_size, _pcx_packet.address, _pcx_packet.store_data);
159
  endtask
160 4 fafa1971
 
161 113 albert.wat
  task automatic print_cpx_packet(cpx_packet_t _cpx_packet);
162
    string str_type;
163
    case(_cpx_packet.return_type)
164
      `IFILL_RET: str_type = "IFILL_RET";
165
      `LOAD_RET:  str_type = "LOAD_RET";
166
      `ST_ACK:    str_type = "ST_ACK";
167
      default:    str_type = "Unknown";
168
    endcase
169
    $display("INFO: CPX: RETURN Valid=%0d Type=%s Error=%0d NonCache_RnW=%0d Thread=%0d IntSrc_etc=0x%0X Load_Data=%016X", _cpx_packet.valid, str_type, _cpx_packet.error, _cpx_packet.noncache_rnw, _cpx_packet.thread_id, _cpx_packet.intsrc_etc, _cpx_packet.load_data);
170
  endtask
171 4 fafa1971
 
172 51 fafa1971
`endif
173 4 fafa1971
// synopsys translate_on
174
 
175 113 albert.wat
   /*
176
    * Signal declarations
177
    */
178
 
179
   // Delayed signals
180
   logic [`SPC_REGION_WIDTH-1:0] spc_req_dly1;
181
   logic [`SPC_REGION_WIDTH-1:0] spc_req_dly2;
182
   logic                         spc_atom_dly1;
183
   logic                         spc_atom_dly2;
184 4 fafa1971
 
185 113 albert.wat
   // PCX FIFO
186
   logic [`PCX_WIDTH+`SPC_INFO_WIDTH-1:0] pcx_fifo_data_in;
187
   logic [`PCX_WIDTH+`SPC_INFO_WIDTH-1:0] pcx_fifo_data_out;
188
   logic                                  pcx_fifo_read;
189
   logic                                  pcx_fifo_write;
190
   logic                                  pcx_fifo_empty;
191
   logic                                  pcx_fifo_full;
192 4 fafa1971
 
193 113 albert.wat
   // CPX FIFO
194
   logic [`CPX_WIDTH-1:0]                 cpx_fifo_data_in;
195
   logic [`CPX_WIDTH-1:0]                 cpx_fifo_data_out;
196
   logic                                  cpx_fifo_read;
197
   logic                                  cpx_fifo_write;
198
   logic                                  cpx_fifo_empty;
199
   logic                                  cpx_fifo_full;
200 4 fafa1971
 
201 113 albert.wat
   /*
202
    * Tasks
203
    */
204 4 fafa1971
 
205 113 albert.wat
   // wbm_clean
206
   task wbm_clean();
207
     wbm_cycle_o = 1'b0;
208
     wbm_strobe_o = 1'b0;
209
     wbm_we_o     = 1'b0;
210
     wbm_addr_o   = 'h0;
211
     wbm_data_o   = 'h0;
212
     wbm_sel_o    = 'h0;
213
   endtask // wbm_clean
214 4 fafa1971
 
215 113 albert.wat
   /*
216
    * FIFO instances
217
    */
218 4 fafa1971
 
219 113 albert.wat
  simple_fifo #(
220
    .name("pcx_fifo"),
221
    .fifo_depth(4),
222
    .data_width(`PCX_WIDTH+`SPC_INFO_WIDTH)
223
  ) pcx_fifo (
224
    // System inputs
225
    .sys_clock_i(sys_clock_i),
226
    .sys_reset_i(sys_reset_i),
227 4 fafa1971
 
228 113 albert.wat
    // FIFO inputs
229
    .read(pcx_fifo_read),
230
    .write(pcx_fifo_write),
231
    .data_in(pcx_fifo_data_in),
232 4 fafa1971
 
233 113 albert.wat
    // FIFO outputs
234
    .empty(pcx_fifo_empty),
235
    .full(pcx_fifo_full),  // With the depth defined properly there is no need to handle the full condition - And an assertion in the FIFO would fire anyway on overflow
236
    .data_out(pcx_fifo_data_out)
237
  );
238 4 fafa1971
 
239 113 albert.wat
  simple_fifo #(
240
    .name("cpx_fifo"),
241
    .fifo_depth(4),
242
    .data_width(`CPX_WIDTH)
243
  ) cpx_fifo (
244
    // System inputs
245
    .sys_clock_i(sys_clock_i),
246
    .sys_reset_i(sys_reset_i),
247 4 fafa1971
 
248 113 albert.wat
    // FIFO inputs
249
    .read(cpx_fifo_read),
250
    .write(cpx_fifo_write),
251
    .data_in(cpx_fifo_data_in),
252 4 fafa1971
 
253 113 albert.wat
    // FIFO outputs
254
    .empty(cpx_fifo_empty),
255
    .full(cpx_fifo_full),
256
    .data_out(cpx_fifo_data_out)
257
  );
258 4 fafa1971
 
259 113 albert.wat
  /*
260
   * PCX sampling logic:
261
   * - SPC Logic: Drives SPARC Cores signals related with the PCX interface
262
   * - PCX FIFO Write Logic: Drives pcx_fifo_write and pcx_fifo_data_in
263
   */
264 4 fafa1971
 
265 113 albert.wat
  always @(posedge sys_clock_i) begin
266 4 fafa1971
 
267 113 albert.wat
    // Create delayed version of request and atom
268
    if (sys_reset_i == 1) begin
269
      spc_req_dly1 <= 'h0;
270
      spc_req_dly2 <= 'h0;
271
      spc_atom_dly1 <= 1'b0;
272
      spc_atom_dly2 <= 1'b0;
273
    end else begin
274
      spc_req_dly1 <= spc_req_i;
275
      spc_req_dly2 <= spc_req_dly1;
276
      spc_atom_dly1 <= spc_atom_i;
277
      spc_atom_dly2 <= spc_atom_dly1;
278
    end
279 4 fafa1971
 
280 113 albert.wat
    // One cycle delay required to sample into the PCX FIFO
281
    if (sys_reset_i == 1'b1 || |spc_req_dly1 == 1'b0) begin
282
      pcx_fifo_write <= 1'b0;
283
      pcx_fifo_data_in <= 'h0;
284
    end else if (|spc_req_dly1 == 1'b1) begin
285
      pcx_fifo_write <= 1'b1;
286
      pcx_fifo_data_in <= {spc_req_dly1, spc_atom_dly1, spc_packetout_i};
287 4 fafa1971
// synopsys translate_off
288 113 albert.wat
`ifdef SIMPLY_RISC_DEBUG
289
      // Print details of SPARC Core request
290
      print_pcx_packet({spc_req_dly1, spc_atom_dly1}, spc_packetout_i);
291 51 fafa1971
`endif
292 4 fafa1971
// synopsys translate_on
293 113 albert.wat
    end
294 4 fafa1971
 
295 113 albert.wat
  end // always @ (posedge sys_clock_i)
296
 
297
   // Two cycles delay required to return the grant
298
   assign spc_grant_o = spc_req_dly2;
299 4 fafa1971
 
300 113 albert.wat
  /*
301
   * PCX-to-WBM-to-CPX:
302
   * - PCX FIFO Read Logic: Drives pcx_fifo_read and reads pcx_fifo_data_out
303
   * - WBM Logic: Drives all Wishbone signals
304
   * - CPX FIFO Write Logic: Drives cpx_fifo_write and cpx_data_in
305
   */
306 4 fafa1971
 
307 113 albert.wat
   typedef enum logic[3:0] {FSM_WAKEUP, FSM_IDLE, FSM_WBM_BEGIN1, FSM_WBM_END1, FSM_WBM_BEGIN2, FSM_WBM_END2, FSM_WBM_BEGIN3, FSM_WBM_END3, FSM_WBM_BEGIN4, FSM_WBM_END4, FSM_CPX_FIFO_WRITE} fsm_state_t;
308
   fsm_state_t fsm_state;
309
   pcx_info_t   pcx_info;
310
   pcx_packet_t pcx_packet;
311
   cpx_packet_t cpx_packet;
312 4 fafa1971
 
313 113 albert.wat
   always @(posedge sys_clock_i) begin
314
     if (sys_reset_i == 1) begin
315
       // Clear outputs connected to FIFOs
316
       pcx_fifo_read <= 1'b0;
317
       cpx_fifo_write <= 1'b0;
318
       cpx_fifo_data_in <= 'h0;
319
       // Clear Wishbone outputs
320
       wbm_clean();
321
       // Initialize the first FSM state
322
       fsm_state <= FSM_WAKEUP;
323
       // Prepare the wakeup packet for SPARC Core: `CPX_WIDTH'h1700000000000000000000000000000010001;
324
       cpx_packet.valid        <= 1;
325
       cpx_packet.return_type  <= `INT_RET;
326
       cpx_packet.error        <= 0;
327
       cpx_packet.noncache_rnw <= 0;
328
       cpx_packet.thread_id    <= 0;
329
       cpx_packet.intsrc_etc   <= 7'h0;
330
       cpx_packet.load_data    <= 128'h10001;
331
     end else begin
332
       case(fsm_state)
333
         // Send the wakeup packet to the SPARC Core
334
         FSM_WAKEUP: begin
335
           cpx_fifo_write <= 1'b1;
336
           cpx_fifo_data_in <= cpx_packet;
337
           fsm_state <= FSM_IDLE;
338
         end
339
         // Wait for a new request to be available in the PCX FIFO and read it
340
         FSM_IDLE: begin
341
           cpx_fifo_write <= 1'b0;
342
           cpx_fifo_data_in <= 'h0;
343
           if (pcx_fifo_empty != 1'b1) begin
344
             pcx_fifo_read <= 1'b1;
345
             { pcx_info, pcx_packet } <= pcx_fifo_data_out;
346
             fsm_state <= FSM_WBM_BEGIN1;
347
           end
348
         end
349
         // Start a request on the Wishbone bus
350
         FSM_WBM_BEGIN1: begin
351
           if (pcx_info.region == 5'b10000)
352
             pcx_packet.address[3] = 0;  // Smells fishy, I may just load half (64b / 8B / 2instr)
353
           pcx_fifo_read <= 1'b0;
354
           wbm_cycle_o <= 1;
355
           wbm_strobe_o <= 1;
356
           wbm_addr_o <= { pcx_info.region, 19'b0, pcx_packet.address[`PCX_AD_HI-`PCX_AD_LO:3], 3'b000 };
357
           wbm_data_o <= pcx_packet.store_data;
358
           case(pcx_packet.request_type)
359
             `IMISS_RQ: begin
360
               // For instruction miss always read memory
361
               wbm_we_o <= 0;
362
               wbm_sel_o <= 8'b11111111;
363
             end // case: `IMISS_RQ
364
             `LOAD_RQ: begin
365
               // For data load use the provided data
366
               wbm_we_o <= 0;
367
               wbm_sel_o <= pcxsize2wbmsel(pcx_packet.access_size, pcx_packet.address);
368
             end // case: `LOAD_RQ
369
             `STORE_RQ: begin
370
               // For data store use the provided data
371
               wbm_we_o <= 1;
372
               wbm_sel_o <= pcxsize2wbmsel(pcx_packet.access_size, pcx_packet.address);
373
             end // case: `STORE_RQ
374
             default: begin
375
               $fatal(1, "Entered default condition of PCX FSM as request_type=0x%02X", pcx_packet.request_type);
376
               wbm_we_o <= 1;
377
               wbm_sel_o <= 8'b00000000;
378
             end
379
           endcase
380
           fsm_state <= FSM_WBM_END1;
381
         end // case: FSM_WBM_BEGIN1
382
         // Wait for the ack from the Wishbone bus and latch the incoming data
383
         FSM_WBM_END1: begin
384
           if (wbm_ack_i == 1) begin
385
             if (pcx_info.atomic == 0) wbm_cycle_o <= 0;
386
             wbm_strobe_o <= 0;
387
             wbm_we_o <= 0;
388
             wbm_addr_o <= 64'b0;
389
             wbm_data_o <= 64'b0;
390
             wbm_sel_o <= 8'b0;
391 4 fafa1971
 
392 113 albert.wat
            // Encode the CPX return packet and store it in the second FIFO
393
            cpx_packet.valid = 1;
394
            case(pcx_packet.request_type)
395
              `IMISS_RQ: begin
396
                cpx_packet.return_type = `IFILL_RET; // I-Cache Miss
397
              end
398
              `LOAD_RQ: begin
399
                cpx_packet.return_type = `LOAD_RET;  // Load
400
              end
401
              `STORE_RQ: begin
402
                cpx_packet.return_type = `ST_ACK;    // Store
403
              end
404
            endcase
405
            cpx_packet.error = 0;
406
            cpx_packet.noncache_rnw = pcx_packet.noncache_rnw;
407
            cpx_packet.thread_id = pcx_packet.thread_id;
408
            cpx_packet.intsrc_etc = 6'b000100;
409
            if (pcx_packet.address[3] == 0)
410
              cpx_packet.load_data = { wbm_data_i, 64'b0 };
411
            else
412
              cpx_packet.load_data = { 64'b0, wbm_data_i };
413 4 fafa1971
 
414 113 albert.wat
            // See if other 64-bit Wishbone accesses are required
415
            if ( (pcx_packet.request_type == `IMISS_RQ) ||
416
               // Instruction miss directed to RAM expects 256 bits
417
               ( (pcx_packet.request_type == `LOAD_RQ) && (pcx_packet.access_size == `PCX_SZ_16B) )
418
               // Data access of 128 bits
419
               ) begin
420
              fsm_state <= FSM_WBM_BEGIN2;
421
            end else begin
422
              fsm_state <= FSM_CPX_FIFO_WRITE;
423
            end
424 4 fafa1971
 
425 113 albert.wat
          end
426
        end // case: FSM_WBM_END1
427
        // If needed start a second read access to the Wishbone bus
428
        FSM_WBM_BEGIN2: begin
429
 
430
          // Issue a second request on the Wishbone bus
431
          wbm_cycle_o <= 1;
432
          wbm_strobe_o <= 1;
433 51 fafa1971
          wbm_we_o <= 0;
434 113 albert.wat
          wbm_addr_o <= { pcx_info.region, 19'b0, pcx_packet.address[`PCX_AD_HI-`PCX_AD_LO:4], 4'b1000 };  // 2nd doubleword inside the same quadword
435
          wbm_data_o <= 64'b0;
436
          wbm_sel_o <= 8'b11111111;
437 4 fafa1971
 
438 113 albert.wat
          // Unconditional state change
439
          fsm_state <= FSM_WBM_END2;
440 11 fafa1971
 
441 113 albert.wat
        end // case: FSM_WBM_BEGIN2
442 4 fafa1971
 
443 113 albert.wat
        // Latch the second data returning from Wishbone when ready
444
        FSM_WBM_END2: begin
445 11 fafa1971
 
446 113 albert.wat
          // Wait until Wishbone access completes
447
          if (wbm_ack_i == 1) begin
448 11 fafa1971
 
449 113 albert.wat
            // Clear previously modified outputs
450
            if (pcx_info.atomic == 0) wbm_cycle_o <= 0;
451
            wbm_strobe_o <= 0;
452
            wbm_we_o <= 0;
453
            wbm_addr_o <= 64'b0;
454
            wbm_data_o <= 64'b0;
455
            wbm_sel_o <= 8'b0;
456 4 fafa1971
 
457 113 albert.wat
            // Latch the data and set up the return packet for the SPARC Core (this is the second half)
458
            if (pcx_packet.address[3] == 1)
459
              cpx_packet.load_data = { wbm_data_i, cpx_packet.load_data[63:0] };
460
            else
461
              cpx_packet.load_data = { cpx_packet.load_data[127:64], wbm_data_i };
462
 
463 4 fafa1971
// synopsys translate_off
464 113 albert.wat
`ifdef SIMPLY_RISC_DEBUG
465
            // Print details of return packet
466
            print_cpx_packet(cpx_packet);
467 51 fafa1971
`endif
468 4 fafa1971
// synopsys translate_on
469
 
470 113 albert.wat
            // See if two return packets are required or just one - TODO checkme
471
//            if (pcx_packet.request_type == `IMISS_RQ && pcx_info.region == 5'b10000)
472
              fsm_state <= FSM_CPX_FIFO_WRITE;
473
//            else
474
//              fsm_state <= FSM_WBM_BEGIN3;
475 4 fafa1971
 
476 113 albert.wat
          end // else fsm_state <= FSM_WBM_END2;
477
        end // case: FSM_WBM_END2
478 4 fafa1971
 
479 113 albert.wat
        // If needed start a third read access to the Wishbone bus
480
        // In the meanwhile we can return the first 128-bit packet
481
        FSM_WBM_BEGIN3: begin
482 4 fafa1971
 
483 113 albert.wat
          // Issue a third request on the Wishbone bus
484
          wbm_cycle_o <= 1;
485
          wbm_strobe_o <= 1;
486 51 fafa1971
          wbm_we_o <= 0;
487 113 albert.wat
          wbm_addr_o <= { pcx_info.region, 19'b0, pcx_packet.address[`PCX_AD_HI-`PCX_AD_LO:5], 5'b10000 };  // 3nd doubleword inside the same 256-bit data
488 51 fafa1971
          wbm_data_o <= 64'b0;
489 113 albert.wat
          wbm_sel_o <= 8'b11111111;
490 4 fafa1971
 
491 113 albert.wat
          // Unconditional state change
492
          fsm_state <= FSM_WBM_END3;
493 4 fafa1971
 
494 113 albert.wat
        end // case: FSM_WBM_BEGIN3
495 4 fafa1971
 
496 113 albert.wat
        // Latch the second data returning from Wishbone when ready
497
        FSM_WBM_END3: begin
498 4 fafa1971
 
499 113 albert.wat
          // Wait until Wishbone access completes
500
          if (wbm_ack_i == 1) begin
501 4 fafa1971
 
502 113 albert.wat
            // Clear previously modified outputs
503
            if (pcx_info.atomic == 0) wbm_cycle_o <= 0;
504
            wbm_strobe_o <= 0;
505
            wbm_we_o <= 0;
506
            wbm_addr_o <= 64'b0;
507
            wbm_data_o <= 64'b0;
508
            wbm_sel_o <= 8'b0;
509 4 fafa1971
 
510 113 albert.wat
            // Latch the data and set up the return packet for the SPARC Core - TODO CHECKME
511
//            cpx_packet.load_data = { wbm_data_i, 64'b0 };
512 4 fafa1971
 
513 113 albert.wat
            // Jump to next state
514
            fsm_state <= FSM_WBM_BEGIN4;
515 4 fafa1971
 
516 113 albert.wat
          end // else fsm_state <= FSM_WBM_END3; // if (wbm_ack_i == 1)
517
        end // case: FSM_WBM_END3
518 4 fafa1971
 
519 113 albert.wat
        // If needed start a second read access to the Wishbone bus
520
        FSM_WBM_BEGIN4: begin
521 4 fafa1971
 
522 113 albert.wat
          // Issue a fourth request on the Wishbone bus
523
          wbm_cycle_o <= 1;
524
          wbm_strobe_o <= 1;
525 51 fafa1971
          wbm_we_o <= 0;
526 113 albert.wat
          wbm_addr_o <= { pcx_info.region, 19'b0, pcx_packet.address[`PCX_AD_HI-`PCX_AD_LO:5], 5'b11000 };  // 4th doubleword inside the same 256-bit data
527 51 fafa1971
          wbm_data_o <= 64'b0;
528 113 albert.wat
          wbm_sel_o <= 8'b11111111;
529 4 fafa1971
 
530 113 albert.wat
          // Unconditional state change
531
          fsm_state <= FSM_WBM_END4;
532
        end // case: FSM_WBM_BEGIN4
533 4 fafa1971
 
534 113 albert.wat
        // Latch the second data returning from Wishbone when ready
535
        FSM_WBM_END4: begin
536 4 fafa1971
 
537 113 albert.wat
          // Wait until Wishbone access completes
538
          if (wbm_ack_i == 1) begin
539 4 fafa1971
 
540 113 albert.wat
            // Clear previously modified outputs
541
            if (pcx_info.atomic == 0) wbm_cycle_o <= 0;
542
            wbm_strobe_o <= 0;
543
            wbm_we_o <= 0;
544
            wbm_addr_o <= 64'b0;
545
            wbm_data_o <= 64'b0;
546
            wbm_sel_o <= 8'b0;
547 4 fafa1971
 
548 113 albert.wat
            // Latch the data and set up the return packet for the SPARC Core
549
//            cpx_packet.load_data = { 64'h0, wbm_data_i};
550 4 fafa1971
 
551 113 albert.wat
            // Jump to next state
552
            fsm_state <= FSM_CPX_FIFO_WRITE;
553 4 fafa1971
 
554 113 albert.wat
          end // else fsm_state <= FSM_WBM_END4; // if (wbm_ack_i == 1)
555
        end // case: FSM_WBM_END4
556 4 fafa1971
 
557 113 albert.wat
        // We can start returning the packet to the SPARC Core
558
        FSM_CPX_FIFO_WRITE: begin
559 4 fafa1971
 
560 113 albert.wat
          // Write the packet to the CPX FIFO
561
          cpx_fifo_write <= 1'b1;
562
          cpx_fifo_data_in <= cpx_packet;
563 4 fafa1971
 
564 113 albert.wat
          // Unconditional state change
565
          fsm_state <= FSM_IDLE;
566 4 fafa1971
 
567 113 albert.wat
// synopsys translate_off
568
`ifdef SIMPLY_RISC_DEBUG
569
          // Print details of return packet
570
          print_cpx_packet(cpx_packet);
571
`endif
572
// synopsys translate_on
573
        end // case: FSM_CPX_FIFO_WRITE
574 4 fafa1971
 
575 113 albert.wat
       endcase // case (fsm_state)
576
     end
577
   end
578 4 fafa1971
 
579 113 albert.wat
   /*
580
    * CPX FIFO handler
581
    * - SPARC Core Logic: Drives SPARC Core signals related with the CPX interface
582
    * - CPX FIFO Read Logic: Drives cpx_fifo_read and reads cpx_data_out
583
    */
584 4 fafa1971
 
585 113 albert.wat
   typedef enum logic[2:0] {CPX_IDLE, CPX_DRIVE_CORE} cpx_state_t;
586
   cpx_state_t cpx_state;
587
   cpx_packet_t cpx_packet_2;
588 4 fafa1971
 
589 113 albert.wat
   always @(posedge sys_clock_i) begin
590
     if (sys_reset_i == 1) begin
591
       spc_ready_o    <= 0;
592
       spc_packetin_o <= 0;
593
       cpx_fifo_read  <= 1'b0;
594
       cpx_state      <= CPX_IDLE;
595
     end else begin
596
       case (cpx_state)
597
         CPX_IDLE: begin
598
           spc_ready_o <= 0;
599
           spc_packetin_o <= 'h0;
600
           if (cpx_fifo_empty) begin
601
             cpx_fifo_read <= 1'b0;
602
           end else begin
603
             cpx_fifo_read <= 1'b1;
604
             cpx_packet_2 <= cpx_fifo_data_out;
605
             cpx_state <= CPX_DRIVE_CORE;
606
           end
607
         end
608
         CPX_DRIVE_CORE: begin
609
           cpx_fifo_read <= 1'b0;
610
           spc_ready_o <= 1;
611
           spc_packetin_o <= cpx_packet_2;
612
           cpx_state <= CPX_IDLE;
613
         end
614
       endcase // case (cpx_state)
615
     end // else: !if (sys_reset_i == 1)
616
   end // always @ (posedge sys_clock_i)
617 99 fafa1971
 
618 4 fafa1971
endmodule
619
 

powered by: WebSVN 2.1.0

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