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

Subversion Repositories s1_core

[/] [s1_core/] [trunk/] [hdl/] [rtl/] [s1_top/] [spc2wbm.v] - Diff between revs 105 and 113

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 105 Rev 113
Line 1... Line 1...
/*
/*
 * Bridge from SPARC Core to Wishbone Master
 * Bridge from SPARC Core to Wishbone Master
 *
 *
 * (C) 2007 Simply RISC LLP
 * (C) 2006-2007 Simply RISC LLP
 * AUTHOR: Fabrizio Fazzino <fabrizio.fazzino@srisc.com>
 * AUTHOR: Fabrizio Fazzino <fabrizio.fazzino@srisc.com>
 *
 *
 * LICENSE:
 * LICENSE:
 * This is a Free Hardware Design; you can redistribute it and/or
 * This is a Free Hardware Design; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * modify it under the terms of the GNU General Public License
Line 22... Line 22...
 * For informations about OpenCores' Wishbone interconnect
 * For informations about OpenCores' Wishbone interconnect
 * please refer to the web site http://www.opencores.org
 * please refer to the web site http://www.opencores.org
 */
 */
 
 
`include "s1_defs.h"
`include "s1_defs.h"
 
`define SPC_REGION_HI 4
 
`define SPC_REGION_LO 0
 
`define SPC_REGION_WIDTH (`SPC_REGION_HI-`SPC_REGION_LO+1)
 
`define SPC_INFO_WIDTH (`SPC_REGION_WIDTH+1)
 
 
module spc2wbm (
module spc2wbm (
 
 
    /*
    /*
     * Inputs
     * Inputs
Line 35... Line 39...
    input sys_clock_i,                            // System Clock
    input sys_clock_i,                            // System Clock
    input sys_reset_i,                            // System Reset
    input sys_reset_i,                            // System Reset
    input[5:0] sys_interrupt_source_i,            // Encoded Interrupt Source
    input[5:0] sys_interrupt_source_i,            // Encoded Interrupt Source
 
 
    // SPARC-side inputs connected to the PCX (Processor-to-Cache Xbar) outputs of the SPARC Core
    // SPARC-side inputs connected to the PCX (Processor-to-Cache Xbar) outputs of the SPARC Core
    input[4:0] spc_req_i,                         // Request
    input[`SPC_REGION_WIDTH-1:0] spc_req_i,       // Request Region
    input spc_atom_i,                             // Atomic Request
    input spc_atom_i,                             // Atomic Request
    input[(`PCX_WIDTH-1):0] spc_packetout_i,      // Outgoing Packet
    input[(`PCX_WIDTH-1):0] spc_packetout_i,      // Outgoing Packet
 
 
    // Wishbone Master interface inputs
    // Wishbone Master interface inputs
    input wbm_ack_i,                              // Ack
    input wbm_ack_i,                              // Ack
Line 48... Line 52...
    /*
    /*
     * Outputs
     * Outputs
     */
     */
 
 
    // SPARC-side outputs connected to the CPX (Cache-to-Processor Xbar) inputs of the SPARC Core
    // SPARC-side outputs connected to the CPX (Cache-to-Processor Xbar) inputs of the SPARC Core
    output reg[4:0] spc_grant_o,                  // Grant
    output logic[4:0] spc_grant_o,                // Grant
    output reg spc_ready_o,                       // Ready
    output reg spc_ready_o,                       // Ready
    output reg[`CPX_WIDTH-1:0] spc_packetin_o,    // Incoming Packet
    output reg[`CPX_WIDTH-1:0] spc_packetin_o,    // Incoming Packet
    output reg spc_stall_o,                       // Stall Requests
 
    output reg spc_resume_o,                      // Resume Requests
 
 
 
    // Wishbone Master interface outputs
    // Wishbone Master interface outputs
    output reg wbm_cycle_o,                       // Cycle Start
    output reg wbm_cycle_o,                       // Cycle Start
    output reg wbm_strobe_o,                      // Strobe Request
    output reg wbm_strobe_o,                      // Strobe Request
    output reg wbm_we_o,                          // Write Enable
    output reg wbm_we_o,                          // Write Enable
Line 64... Line 66...
    output reg[`WB_DATA_WIDTH-1:0] wbm_data_o,    // Data Out
    output reg[`WB_DATA_WIDTH-1:0] wbm_data_o,    // Data Out
    output reg[`WB_DATA_WIDTH/8-1:0] wbm_sel_o    // Select Output
    output reg[`WB_DATA_WIDTH/8-1:0] wbm_sel_o    // Select Output
 
 
  );
  );
 
 
 
 
  /*
 
   * Registers
 
   */
 
 
 
  // Registers to latch requests from SPARC Core to Wishbone Master
 
  reg[3:0] state;
 
  reg[4:0] spc2wbm_region;                                             // Target region number (one-hot encoded)
 
  reg spc2wbm_atomic;                                                  // Request is Atomic
 
  reg[(`PCX_WIDTH-1):0] spc2wbm_packet;                                // Latched Packet
 
 
 
  // Wishbone Master to SPARC Core info used to encode the return packet
 
  reg wbm2spc_valid;                                                   // Valid
 
  reg[(`CPX_RQ_HI-`CPX_RQ_LO):0] wbm2spc_type;                         // Request type
 
  reg wbm2spc_miss;                                                    // L2 Miss
 
  reg[(`CPX_ERR_HI-`CPX_ERR_LO-1):0] wbm2spc_error;                    // Error
 
  reg wbm2spc_nc;                                                      // Non-Cacheable
 
  reg[(`CPX_TH_HI-`CPX_TH_LO):0] wbm2spc_thread;                       // Thread
 
  reg wbm2spc_way_valid;                                               // L2 Way Valid
 
  reg[(`CPX_WY_HI-`CPX_WY_LO):0] wbm2spc_way;                          // Replaced L2 Way
 
  reg wbm2spc_boot_fetch;                                              // Fetch for Boot
 
  reg wbm2spc_atomic;                                                  // Atomic LD/ST or 2nd IFill packet
 
  reg wbm2spc_pfl;                                                     // PFL
 
  reg[(`CPX_DA_HI-`CPX_DA_LO):0] wbm2spc_data;                         // Load Data
 
  reg[6:0] wbm2spc_interrupt_source;                                   // Encoded Interrupt Source
 
  reg wbm2spc_interrupt_new;                                           // New Interrupt Pending
 
 
 
  /*
 
   * Wires
 
   */
 
 
 
  // Decoded SPARC Core to Wishbone Master info
 
  wire spc2wbm_req;                                                     // Request
 
  wire spc2wbm_valid;                                                   // Valid
 
  wire[(`PCX_RQ_HI-`PCX_RQ_LO):0] spc2wbm_type;                         // Request type
 
  wire spc2wbm_nc;                                                      // Non-Cacheable
 
  wire[(`PCX_CP_HI-`PCX_CP_LO):0] spc2wbm_cpu_id;                       // CPU ID
 
  wire[(`PCX_TH_HI-`PCX_TH_LO):0] spc2wbm_thread;                       // Thread
 
  wire spc2wbm_invalidate;                                              // Invalidate all
 
  wire[(`PCX_WY_HI-`PCX_WY_LO):0] spc2wbm_way;                          // Replaced L1 Way
 
  wire[(`PCX_SZ_HI-`PCX_SZ_LO):0] spc2wbm_size;                         // Load/Store size
 
  wire[(`PCX_AD_HI-`PCX_AD_LO):0] spc2wbm_addr;                         // Address
 
  wire[(`PCX_DA_HI-`PCX_DA_LO):0] spc2wbm_data;                         // Store Data
 
 
 
  // Return packets assembled with various fields
 
  wire[`CPX_WIDTH-1:0] wbm2spc_packet;                                  // Incoming Packet
 
 
 
  /*
  /*
   * Encode/decode incoming info
   * Packet Structures
   *
 
   * Legenda: available constants for some of the PCX/CPX fields.
 
   *
 
   * spc2wbm_size (3 bits) is one of:
 
   * - PCX_SZ_1B
 
   * - PCX_SZ_2B
 
   * - PCX_SZ_4B
 
   * - PCX_SZ_8B
 
   * - PCX_SZ_16B (Read accesses only)
 
   *
 
   * spc2wbm_type (5 bits) is one of:
 
   * { LOAD_RQ, IMISS_RQ, STORE_RQ, CAS1_RQ, CAS2_RQ, SWAP_RQ, STRLOAD_RQ, STRST_RQ, STQ_RQ,
 
   *   INT_RQ, FWD_RQ, FWD_RPY, RSVD_RQ }
 
   *
 
   * wbm2spc_type (4 bits) is one of:
 
   * { LOAD_RET, INV_RET, ST_ACK, AT_ACK, INT_RET, TEST_RET, FP_RET, IFILL_RET, EVICT_REQ,
 
   *   ERR_RET, STRLOAD_RET, STRST_ACK, FWD_RQ_RET, FWD_RPY_RET, RSVD_RET }
 
   *
 
   */
   */
 
 
  // Decode info arriving from the SPC side
  // Processor-to-Cache Xbar request region and atomic info
  assign spc2wbm_req = ( spc_req_i[4] | spc_req_i[3] | spc_req_i[2] | spc_req_i[1] | spc_req_i[0] );
  typedef struct packed {
  assign spc2wbm_valid = spc2wbm_packet[`PCX_VLD];
    logic [`SPC_REGION_WIDTH-1:0] region;         // info[5:1] Region
  assign spc2wbm_type = spc2wbm_packet[`PCX_RQ_HI:`PCX_RQ_LO];
    logic                         atomic;         // info[0]   Atomicity
  assign spc2wbm_nc = spc2wbm_packet[`PCX_NC];
  } pcx_info_t;
  assign spc2wbm_cpu_id = spc2wbm_packet[`PCX_CP_HI:`PCX_CP_LO];
 
  assign spc2wbm_thread = spc2wbm_packet[`PCX_TH_HI:`PCX_TH_LO];
  // Processor-to-Cache Xbar request packet type (PCX payload 124-bit)
  assign spc2wbm_invalidate = spc2wbm_packet[`PCX_INVALL];
  typedef struct packed {
  assign spc2wbm_way = spc2wbm_packet[`PCX_WY_HI:`PCX_WY_LO];
    logic                                 valid;         // pcx[123]       Packet Valid
  assign spc2wbm_size = spc2wbm_packet[`PCX_SZ_HI:`PCX_SZ_LO];
    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)
  assign spc2wbm_addr = spc2wbm_packet[`PCX_AD_HI:`PCX_AD_LO];
    logic                           noncache_rnw;  // pcx[117]       Non-Cacheable, or ReadNotWrite
  assign spc2wbm_data = spc2wbm_packet[`PCX_DA_HI:`PCX_DA_LO];
    logic [`PCX_CP_HI-`PCX_CP_LO:0] cpu_id;        // pcx[116:114]   CPU ID
 
    logic [`PCX_TH_HI-`PCX_TH_LO:0] thread_id;     // pcx[113:112]   Thread ID
  // Encode info going to the SPC side assembling return packets
    logic [`PCX_BF_HI-`PCX_BF_LO:0] buffer_id;     // pcx[111:109]   Buffer ID
  assign wbm2spc_packet = { wbm2spc_valid, wbm2spc_type, wbm2spc_miss, wbm2spc_error, wbm2spc_nc, wbm2spc_thread,
    logic [`PCX_WY_HI-`PCX_WY_LO:0] l1way_packetid;// pcx[108:107]   L1 Way Replaced, or Packet ID
    wbm2spc_way_valid, wbm2spc_way, wbm2spc_boot_fetch, wbm2spc_atomic, wbm2spc_pfl, wbm2spc_data };
    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
 
    logic [`PCX_AD_HI-`PCX_AD_LO:0] address;       // pcx[103:64]    Address
 
    logic [`PCX_DA_HI-`PCX_DA_LO:0] store_data;    // pcx[63:0]      Store Data
 
  } pcx_packet_t;
 
 
 
  // Cache-to-Processor Xbar return packet type (CPX payload 145-bit)
 
  typedef struct packed {
 
    logic                             valid;       // cpx[144]     Packet Valid
 
    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)
 
    logic [`CPX_ERR_HI-`CPX_ERR_LO:0] error;       // cpx[139:137] Error
 
    logic                             noncache_rnw;// cpx[136]     Non-Cacheable, or ReadNotWrite
 
    logic [`CPX_TH_HI-`CPX_TH_LO:0]   thread_id;   // cpx[135:134] Thread ID
 
    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.
 
    logic [`CPX_DA_HI-`CPX_DA_LO:0]   load_data;   // cpx[127:0]   Load Data
 
  } cpx_packet_t;
 
 
  /*
  /*
   * State Machine
   * Useful Function
   */
   */
 
 
  always @(posedge sys_clock_i) begin
   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);
 
     case(access_size)
    // Initialization
       `PCX_SZ_1B: return (1'b1    << address[2:0]);
    if(sys_reset_i==1) begin
       `PCX_SZ_2B: return (2'b11   << (address[2:1] << 1));
 
       `PCX_SZ_4B: return (4'b1111 << (address[2] << 2));
      // Clear outputs going to SPARC Core inputs
       `PCX_SZ_8B: return 8'b11111111;
      spc_grant_o <= 5'b00000;
       `PCX_SZ_16B: return 8'b11111111;  // Requires a 2nd access
      spc_ready_o <= 0;
       default: return 8'b00000000;
      spc_packetin_o <= 0;
     endcase // case (access_size)
      spc_stall_o <= 0;
   endfunction
      spc_resume_o <= 0;
 
 
 
      // Clear Wishbone Master interface outputs
// synopsys translate_off
      wbm_cycle_o <= 0;
`ifdef SIMPLY_RISC_DEBUG
      wbm_strobe_o <= 0;
 
      wbm_we_o <= 0;
 
      wbm_addr_o <= 64'b0;
 
      wbm_data_o <= 64'b0;
 
      wbm_sel_o <= 8'b0;
 
 
 
      // Prepare wakeup packet for SPARC Core, the resulting output is
 
      // spc_packetin_o <= `CPX_WIDTH'h1700000000000000000000000000000010001;
 
      wbm2spc_valid <= 1;
 
      wbm2spc_type <= `INT_RET;
 
      wbm2spc_miss <= 0;
 
      wbm2spc_error <= 0;
 
      wbm2spc_nc <= 0;
 
      wbm2spc_thread <= 0;
 
      wbm2spc_way_valid <= 0;
 
      wbm2spc_way <= 0;
 
      wbm2spc_boot_fetch <= 0;
 
      wbm2spc_atomic <= 0;
 
      wbm2spc_pfl <= 0;
 
      wbm2spc_data <= 64'h10001;
 
      wbm2spc_interrupt_source <= 7'h0;
 
      wbm2spc_interrupt_new <= 1'b0;
 
 
 
      // Clear state machine
 
      state <= `STATE_WAKEUP;
 
 
 
    end else begin
 
 
 
      // FSM State 0: STATE_WAKEUP
  task automatic print_pcx_packet(pcx_info_t _pcx_info, pcx_packet_t _pcx_packet);
      // Send to the SPARC Core the wakeup packet
    string str_region, str_type, str_size;
      if(state==`STATE_WAKEUP) begin
    case(_pcx_info.region)
 
      5'b00001: str_region = "RAM_Bank_0";
 
      5'b00010: str_region = "RAM_Bank_1";
 
      5'b00100: str_region = "RAM_Bank_2";
 
      5'b01000: str_region = "RAM Bank_3";
 
      5'b10000: str_region = "IO_Block";
 
      default:  str_region = "Unknown";
 
    endcase
 
    case(_pcx_packet.request_type)
 
      `LOAD_RQ:    str_type = "LOAD_RQ";
 
      `IMISS_RQ:   str_type = "IMISS_RQ";
 
      `STORE_RQ:   str_type = "STORE_RQ";
 
      `CAS1_RQ:    str_type = "CAS1_RQ";
 
      `CAS2_RQ:    str_type = "CAS2_RQ";
 
      `SWAP_RQ:    str_type = "SWAP_RQ";
 
      `STRLOAD_RQ: str_type = "STRLOAD_RQ";
 
      `STRST_RQ:   str_type = "STRST_RQ";
 
      `STQ_RQ:     str_type = "STQ_RQ";
 
      `INT_RQ:     str_type = "INT_RQ";
 
      `FWD_RQ:     str_type = "FWD_RQ";
 
      `FWD_RPY:    str_type = "FWD_RPY";
 
      `RSVD_RQ:    str_type = "RSVD_RQ";
 
      default:     str_type = "Unknown";
 
          endcase
 
    case(_pcx_packet.access_size)
 
      `PCX_SZ_1B:  str_size = "1B";
 
      `PCX_SZ_2B:  str_size = "2B";
 
      `PCX_SZ_4B:  str_size = "4B";
 
      `PCX_SZ_8B:  str_size = "8B";
 
      `PCX_SZ_16B: str_size = "16B";
 
      default:     str_size = "Unknown";
 
    endcase
 
    $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);
 
  endtask
 
 
        // Send wakeup packet
  task automatic print_cpx_packet(cpx_packet_t _cpx_packet);
        spc_ready_o <= 1;
    string str_type;
        spc_packetin_o <= wbm2spc_packet;
    case(_cpx_packet.return_type)
 
      `IFILL_RET: str_type = "IFILL_RET";
 
      `LOAD_RET:  str_type = "LOAD_RET";
 
      `ST_ACK:    str_type = "ST_ACK";
 
      default:    str_type = "Unknown";
 
    endcase
 
    $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);
 
  endtask
 
 
// synopsys translate_off
 
        // Display comment
 
`ifdef DEBUG
 
        $display("INFO: SPC2WBM: SPARC Core to Wishbone Master bridge starting...");
 
        $display("INFO: SPC2WBM: Wakeup packet sent to SPARC Core");
 
`endif
`endif
// synopsys translate_on
// synopsys translate_on
 
 
        // Unconditional state change
   /*
        state <= `STATE_IDLE;
    * Signal declarations
 
    */
      // FSM State 1: STATE_IDLE
 
      // Wait for a request from the SPARC Core
 
      // If available send an interrupt packet to the Core
 
      end else if(state==`STATE_IDLE) begin
 
 
 
        // Check if there's an incoming request
 
        if(spc2wbm_req==1) begin
 
 
 
          // Clear previously modified outputs
 
          spc_ready_o <= 0;
 
          spc_packetin_o <= 0;
 
 
 
          // Stall other requests from the SPARC Core
   // Delayed signals
          spc_stall_o <= 1;
   logic [`SPC_REGION_WIDTH-1:0] spc_req_dly1;
 
   logic [`SPC_REGION_WIDTH-1:0] spc_req_dly2;
 
   logic                         spc_atom_dly1;
 
   logic                         spc_atom_dly2;
 
 
 
   // PCX FIFO
 
   logic [`PCX_WIDTH+`SPC_INFO_WIDTH-1:0] pcx_fifo_data_in;
 
   logic [`PCX_WIDTH+`SPC_INFO_WIDTH-1:0] pcx_fifo_data_out;
 
   logic                                  pcx_fifo_read;
 
   logic                                  pcx_fifo_write;
 
   logic                                  pcx_fifo_empty;
 
   logic                                  pcx_fifo_full;
 
 
 
   // CPX FIFO
 
   logic [`CPX_WIDTH-1:0]                 cpx_fifo_data_in;
 
   logic [`CPX_WIDTH-1:0]                 cpx_fifo_data_out;
 
   logic                                  cpx_fifo_read;
 
   logic                                  cpx_fifo_write;
 
   logic                                  cpx_fifo_empty;
 
   logic                                  cpx_fifo_full;
 
 
          // Latch target region and atomicity
   /*
          spc2wbm_region <= spc_req_i;
    * Tasks
          spc2wbm_atomic <= spc_atom_i;
    */
 
 
          // Jump to next state
   // wbm_clean
          state <= `STATE_REQUEST_LATCHED;
   task wbm_clean();
 
     wbm_cycle_o = 1'b0;
 
     wbm_strobe_o = 1'b0;
 
     wbm_we_o     = 1'b0;
 
     wbm_addr_o   = 'h0;
 
     wbm_data_o   = 'h0;
 
     wbm_sel_o    = 'h0;
 
   endtask // wbm_clean
 
 
        // See if the interrupt vector has changed
   /*
        end else if(sys_interrupt_source_i!=wbm2spc_interrupt_source) begin
    * FIFO instances
 
    */
 
 
          // Set the flag for next cycle
  simple_fifo #(
          wbm2spc_interrupt_new <= 1;
    .name("pcx_fifo"),
 
    .fifo_depth(4),
 
    .data_width(`PCX_WIDTH+`SPC_INFO_WIDTH)
 
  ) pcx_fifo (
 
    // System inputs
 
    .sys_clock_i(sys_clock_i),
 
    .sys_reset_i(sys_reset_i),
 
 
          // Prepare the interrupt packet for the SPARC Core
    // FIFO inputs
          wbm2spc_valid <= 1;
    .read(pcx_fifo_read),
          wbm2spc_type <= `INT_RET;
    .write(pcx_fifo_write),
          wbm2spc_miss <= 0;
    .data_in(pcx_fifo_data_in),
          wbm2spc_error <= 0;
 
          wbm2spc_nc <= 0;
    // FIFO outputs
          wbm2spc_thread <= 0;
    .empty(pcx_fifo_empty),
          wbm2spc_way_valid <= 0;
    .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
          wbm2spc_way <= 0;
    .data_out(pcx_fifo_data_out)
          wbm2spc_boot_fetch <= 0;
  );
          wbm2spc_atomic <= 0;
 
          wbm2spc_pfl <= 0;
 
 
 
        // Next cycle see if there's an int to be forwarded to the Core
  simple_fifo #(
        end else if(wbm2spc_interrupt_source!=6'b000000 && wbm2spc_interrupt_new) begin
    .name("cpx_fifo"),
 
    .fifo_depth(4),
 
    .data_width(`CPX_WIDTH)
 
  ) cpx_fifo (
 
    // System inputs
 
    .sys_clock_i(sys_clock_i),
 
    .sys_reset_i(sys_reset_i),
 
 
          // Clean the flag
    // FIFO inputs
          wbm2spc_interrupt_new <= 0;
    .read(cpx_fifo_read),
 
    .write(cpx_fifo_write),
 
    .data_in(cpx_fifo_data_in),
 
 
 
    // FIFO outputs
 
    .empty(cpx_fifo_empty),
 
    .full(cpx_fifo_full),
 
    .data_out(cpx_fifo_data_out)
 
  );
 
 
          // Send the interrupt packet to the Core
  /*
          spc_ready_o <= 1;
   * PCX sampling logic:
          spc_packetin_o <= wbm2spc_packet;
   * - SPC Logic: Drives SPARC Cores signals related with the PCX interface
 
   * - PCX FIFO Write Logic: Drives pcx_fifo_write and pcx_fifo_data_in
 
   */
 
 
          // Stay in this state
  always @(posedge sys_clock_i) begin
          state <= `STATE_IDLE;
 
 
 
        // Nothing to do, stay idle
    // Create delayed version of request and atom
 
    if (sys_reset_i == 1) begin
 
      spc_req_dly1 <= 'h0;
 
      spc_req_dly2 <= 'h0;
 
      spc_atom_dly1 <= 1'b0;
 
      spc_atom_dly2 <= 1'b0;
        end else begin
        end else begin
 
      spc_req_dly1 <= spc_req_i;
          // Clear previously modified outputs
      spc_req_dly2 <= spc_req_dly1;
          spc_ready_o <= 0;
      spc_atom_dly1 <= spc_atom_i;
          spc_packetin_o <= 0;
      spc_atom_dly2 <= spc_atom_dly1;
 
 
          // Clear stall/resume signals
 
          spc_stall_o <= 0;
 
          spc_resume_o <= 0;
 
 
 
          // Stay in this state
 
          state <= `STATE_IDLE;
 
 
 
        end
        end
 
 
      // FSM State 2: STATE_REQUEST_LATCHED
    // One cycle delay required to sample into the PCX FIFO
      // We've just latched the request
    if (sys_reset_i == 1'b1 || |spc_req_dly1 == 1'b0) begin
      // Now we latch the packet
      pcx_fifo_write <= 1'b0;
      // Start granting the request
      pcx_fifo_data_in <= 'h0;
      end else if(state==`STATE_REQUEST_LATCHED) begin
    end else if (|spc_req_dly1 == 1'b1) begin
 
      pcx_fifo_write <= 1'b1;
        // Latch the incoming packet
      pcx_fifo_data_in <= {spc_req_dly1, spc_atom_dly1, spc_packetout_i};
        spc2wbm_packet <= spc_packetout_i;
 
 
 
        // Grant the request to the SPARC Core
 
        spc_grant_o <= spc2wbm_region;
 
 
 
        // Clear the stall signal
 
        spc_stall_o <= 0;
 
 
 
// synopsys translate_off
// synopsys translate_off
 
`ifdef SIMPLY_RISC_DEBUG
        // Print details of SPARC Core request
        // Print details of SPARC Core request
`ifdef DEBUG
      print_pcx_packet({spc_req_dly1, spc_atom_dly1}, spc_packetout_i);
        $display("INFO: SPC2WBM: *** NEW REQUEST FROM SPARC CORE ***");
 
        if(spc2wbm_region[0]==1) $display("INFO: SPC2WBM: Request to RAM Bank 0");
 
        else if(spc2wbm_region[1]==1) $display("INFO: SPC2WBM: Request to RAM Bank 1");
 
        else if(spc2wbm_region[2]==1) $display("INFO: SPC2WBM: Request to RAM Bank 2");
 
        else if(spc2wbm_region[3]==1) $display("INFO: SPC2WBM: Request to RAM Bank 3");
 
        else if(spc2wbm_region[4]==1) $display("INFO: SPC2WBM: Request targeted to I/O Block");
 
        else $display("INFO: SPC2WBM: Request to target region unknown");
 
        if(spc2wbm_atomic==1) $display("INFO: SPC2WBM: Request is ATOMIC");
 
        else $display("INFO: SPC2WBM: Request is not atomic");
 
`endif
`endif
// synopsys translate_on
// synopsys translate_on
 
    end
 
 
        // Unconditional state change
  end // always @ (posedge sys_clock_i)
        state <= `STATE_PACKET_LATCHED;
 
 
 
      // FSM State 3: STATE_PACKET_LATCHED
   // Two cycles delay required to return the grant
      // The packet has already been latched
   assign spc_grant_o = spc_req_dly2;
      // Decode this packet to build the request for the Wishbone bus
 
      // The grant of the request to the SPARC Core has been completed
 
      end else if(state==`STATE_PACKET_LATCHED) begin
 
 
 
        // Clear previously modified outputs
  /*
        spc_grant_o <= 5'b0;
   * PCX-to-WBM-to-CPX:
 
   * - PCX FIFO Read Logic: Drives pcx_fifo_read and reads pcx_fifo_data_out
 
   * - WBM Logic: Drives all Wishbone signals
 
   * - CPX FIFO Write Logic: Drives cpx_fifo_write and cpx_data_in
 
   */
 
 
 
   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;
 
   fsm_state_t fsm_state;
 
   pcx_info_t   pcx_info;
 
   pcx_packet_t pcx_packet;
 
   cpx_packet_t cpx_packet;
 
 
        // Issue a request on the Wishbone bus
   always @(posedge sys_clock_i) begin
 
     if (sys_reset_i == 1) begin
 
       // Clear outputs connected to FIFOs
 
       pcx_fifo_read <= 1'b0;
 
       cpx_fifo_write <= 1'b0;
 
       cpx_fifo_data_in <= 'h0;
 
       // Clear Wishbone outputs
 
       wbm_clean();
 
       // Initialize the first FSM state
 
       fsm_state <= FSM_WAKEUP;
 
       // Prepare the wakeup packet for SPARC Core: `CPX_WIDTH'h1700000000000000000000000000000010001;
 
       cpx_packet.valid        <= 1;
 
       cpx_packet.return_type  <= `INT_RET;
 
       cpx_packet.error        <= 0;
 
       cpx_packet.noncache_rnw <= 0;
 
       cpx_packet.thread_id    <= 0;
 
       cpx_packet.intsrc_etc   <= 7'h0;
 
       cpx_packet.load_data    <= 128'h10001;
 
     end else begin
 
       case(fsm_state)
 
         // Send the wakeup packet to the SPARC Core
 
         FSM_WAKEUP: begin
 
           cpx_fifo_write <= 1'b1;
 
           cpx_fifo_data_in <= cpx_packet;
 
           fsm_state <= FSM_IDLE;
 
         end
 
         // Wait for a new request to be available in the PCX FIFO and read it
 
         FSM_IDLE: begin
 
           cpx_fifo_write <= 1'b0;
 
           cpx_fifo_data_in <= 'h0;
 
           if (pcx_fifo_empty != 1'b1) begin
 
             pcx_fifo_read <= 1'b1;
 
             { pcx_info, pcx_packet } <= pcx_fifo_data_out;
 
             fsm_state <= FSM_WBM_BEGIN1;
 
           end
 
         end
 
         // Start a request on the Wishbone bus
 
         FSM_WBM_BEGIN1: begin
 
           if (pcx_info.region == 5'b10000)
 
             pcx_packet.address[3] = 0;  // Smells fishy, I may just load half (64b / 8B / 2instr)
 
           pcx_fifo_read <= 1'b0;
        wbm_cycle_o <= 1;
        wbm_cycle_o <= 1;
        wbm_strobe_o <= 1;
        wbm_strobe_o <= 1;
        wbm_addr_o <= { spc2wbm_region, 19'b0, spc2wbm_addr[`PCX_AD_HI-`PCX_AD_LO:3], 3'b000 };
           wbm_addr_o <= { pcx_info.region, 19'b0, pcx_packet.address[`PCX_AD_HI-`PCX_AD_LO:3], 3'b000 };
        wbm_data_o <= spc2wbm_data;
           wbm_data_o <= pcx_packet.store_data;
 
           case(pcx_packet.request_type)
        // Handle write enable and byte select
             `IMISS_RQ: begin
        if(spc2wbm_type==`IMISS_RQ) begin
 
 
 
          // For instruction miss always read memory
          // For instruction miss always read memory
          wbm_we_o <= 0;
          wbm_we_o <= 0;
          if(spc2wbm_region==5'b10000)
 
            // For accesses to SSI ROM only 32 bits are required
 
            wbm_sel_o <= (4'b1111<<(spc2wbm_addr[2]<<2));
 
          else
 
            // For accesses to RAM 256 bits are expected (2 ret packets)
 
            wbm_sel_o <= 8'b11111111;
            wbm_sel_o <= 8'b11111111;
 
             end // case: `IMISS_RQ
        end else if(spc2wbm_type==`LOAD_RQ) begin
             `LOAD_RQ: begin
 
 
          // For data load use the provided data
          // For data load use the provided data
          wbm_we_o <= 0;
          wbm_we_o <= 0;
          case(spc2wbm_size)
               wbm_sel_o <= pcxsize2wbmsel(pcx_packet.access_size, pcx_packet.address);
            `PCX_SZ_1B: wbm_sel_o <= (1'b1<<spc2wbm_addr[2:0]);
             end // case: `LOAD_RQ
            `PCX_SZ_2B: wbm_sel_o <= (2'b11<<(spc2wbm_addr[2:1]<<1));
             `STORE_RQ: begin
            `PCX_SZ_4B: wbm_sel_o <= (4'b1111<<(spc2wbm_addr[2]<<2));
 
            `PCX_SZ_8B: wbm_sel_o <= 8'b11111111;
 
            `PCX_SZ_16B: wbm_sel_o <= 8'b11111111;  // Requires a 2nd access
 
            default: wbm_sel_o <= 8'b00000000;
 
          endcase
 
 
 
        end else if(spc2wbm_type==`STORE_RQ) begin
 
 
 
          // For data store use the provided data
          // For data store use the provided data
          wbm_we_o <= 1;
          wbm_we_o <= 1;
          case(spc2wbm_size)
               wbm_sel_o <= pcxsize2wbmsel(pcx_packet.access_size, pcx_packet.address);
            `PCX_SZ_1B: wbm_sel_o <= (1'b1<<spc2wbm_addr[2:0]);
             end // case: `STORE_RQ
            `PCX_SZ_2B: wbm_sel_o <= (2'b11<<(spc2wbm_addr[2:1]<<1));
             default: begin
            `PCX_SZ_4B: wbm_sel_o <= (4'b1111<<(spc2wbm_addr[2]<<2));
               $fatal(1, "Entered default condition of PCX FSM as request_type=0x%02X", pcx_packet.request_type);
            `PCX_SZ_8B: wbm_sel_o <= 8'b11111111;
 
            `PCX_SZ_16B: wbm_sel_o <= 8'b11111111;  // Requires a 2nd access
 
            default: wbm_sel_o <= 8'b00000000;
 
          endcase
 
 
 
        end else begin
 
 
 
          wbm_we_o <= 1;
          wbm_we_o <= 1;
          wbm_sel_o <= 8'b00000000;
          wbm_sel_o <= 8'b00000000;
 
 
        end
        end
 
 
// synopsys translate_off
 
        // Print details of request packet
 
`ifdef DEBUG
 
        $display("INFO: SPC2WBM: Valid bit is %X", spc2wbm_valid);
 
        case(spc2wbm_type)
 
          `LOAD_RQ: $display("INFO: SPC2WBM: Request of Type LOAD_RQ");
 
          `IMISS_RQ: $display("INFO: SPC2WBM: Request of Type IMISS_RQ");
 
          `STORE_RQ: $display("INFO: SPC2WBM: Request of Type STORE_RQ");
 
          `CAS1_RQ: $display("INFO: SPC2WBM: Request of Type CAS1_RQ");
 
          `CAS2_RQ: $display("INFO: SPC2WBM: Request of Type CAS2_RQ");
 
          `SWAP_RQ: $display("INFO: SPC2WBM: Request of Type SWAP_RQ");
 
          `STRLOAD_RQ: $display("INFO: SPC2WBM: Request of Type STRLOAD_RQ");
 
          `STRST_RQ: $display("INFO: SPC2WBM: Request of Type STRST_RQ");
 
          `STQ_RQ: $display("INFO: SPC2WBM: Request of Type STQ_RQ");
 
          `INT_RQ: $display("INFO: SPC2WBM: Request of Type INT_RQ");
 
          `FWD_RQ: $display("INFO: SPC2WBM: Request of Type FWD_RQ");
 
          `FWD_RPY: $display("INFO: SPC2WBM: Request of Type FWD_RPY");
 
          `RSVD_RQ: $display("INFO: SPC2WBM: Request of Type RSVD_RQ");
 
          default: $display("INFO: SPC2WBM: Request of Type Unknown");
 
        endcase
        endcase
        $display("INFO: SPC2WBM: Non-Cacheable bit is %X", spc2wbm_nc);
           fsm_state <= FSM_WBM_END1;
        $display("INFO: SPC2WBM: CPU-ID is %X", spc2wbm_cpu_id);
         end // case: FSM_WBM_BEGIN1
        $display("INFO: SPC2WBM: Thread is %X", spc2wbm_thread);
         // Wait for the ack from the Wishbone bus and latch the incoming data
        $display("INFO: SPC2WBM: Invalidate All is %X", spc2wbm_invalidate);
         FSM_WBM_END1: begin
        $display("INFO: SPC2WBM: Replaced L1 Way is %X", spc2wbm_way);
 
        case(spc2wbm_size)
 
          `PCX_SZ_1B: $display("INFO: SPC2WBM: Request size is 1 Byte");
 
          `PCX_SZ_2B: $display("INFO: SPC2WBM: Request size is 2 Bytes");
 
          `PCX_SZ_4B: $display("INFO: SPC2WBM: Request size is 4 Bytes");
 
          `PCX_SZ_8B: $display("INFO: SPC2WBM: Request size is 8 Bytes");
 
          `PCX_SZ_16B: $display("INFO: SPC2WBM: Request size is 16 Bytes");
 
          default: $display("INFO: SPC2WBM: Request size is Unknown");
 
        endcase
 
        $display("INFO: SPC2WBM: Address is %X", spc2wbm_addr);
 
        $display("INFO: SPC2WBM: Data is %X", spc2wbm_data);
 
`endif
 
// synopsys translate_on
 
 
 
        // Unconditional state change
 
        state <= `STATE_REQUEST_GRANTED;
 
 
 
      // FSM State 4: STATE_REQUEST_GRANTED
 
      // Wishbone access completed, latch the incoming data
 
      end else if(state==`STATE_REQUEST_GRANTED) begin
 
 
 
        // Wait until Wishbone access completes
 
        if(wbm_ack_i==1) begin
        if(wbm_ack_i==1) begin
 
             if (pcx_info.atomic == 0) wbm_cycle_o <= 0;
          // Clear previously modified outputs
 
          if(spc2wbm_atomic==0) wbm_cycle_o <= 0;
 
          wbm_strobe_o <= 0;
          wbm_strobe_o <= 0;
          wbm_we_o <= 0;
          wbm_we_o <= 0;
          wbm_addr_o <= 64'b0;
          wbm_addr_o <= 64'b0;
          wbm_data_o <= 64'b0;
          wbm_data_o <= 64'b0;
          wbm_sel_o <= 8'b0;
          wbm_sel_o <= 8'b0;
 
 
          // Latch the data and set up the return packet for the SPARC Core
            // Encode the CPX return packet and store it in the second FIFO
          wbm2spc_valid <= 1;
            cpx_packet.valid = 1;
          case(spc2wbm_type)
            case(pcx_packet.request_type)
            `IMISS_RQ: begin
            `IMISS_RQ: begin
              wbm2spc_type <= `IFILL_RET; // I-Cache Miss
                cpx_packet.return_type = `IFILL_RET; // I-Cache Miss
              wbm2spc_atomic <= 0;
 
            end
            end
            `LOAD_RQ: begin
            `LOAD_RQ: begin
              wbm2spc_type <= `LOAD_RET;  // Load
                cpx_packet.return_type = `LOAD_RET;  // Load
              wbm2spc_atomic <= spc2wbm_atomic;
 
            end
            end
            `STORE_RQ: begin
            `STORE_RQ: begin
              wbm2spc_type <= `ST_ACK;    // Store
                cpx_packet.return_type = `ST_ACK;    // Store
              wbm2spc_atomic <= spc2wbm_atomic;
 
            end
            end
          endcase
          endcase
          wbm2spc_miss <= 0;
            cpx_packet.error = 0;
          wbm2spc_error <= 0;
            cpx_packet.noncache_rnw = pcx_packet.noncache_rnw;
          wbm2spc_nc <= spc2wbm_nc;
            cpx_packet.thread_id = pcx_packet.thread_id;
          wbm2spc_thread <= spc2wbm_thread;
            cpx_packet.intsrc_etc = 6'b000100;
          wbm2spc_way_valid <= 0;
            if (pcx_packet.address[3] == 0)
          wbm2spc_way <= 0;
              cpx_packet.load_data = { wbm_data_i, 64'b0 };
          if(spc2wbm_region==5'b10000) wbm2spc_boot_fetch <= 1;
            else
          else wbm2spc_boot_fetch <= 0;
              cpx_packet.load_data = { 64'b0, wbm_data_i };
          wbm2spc_pfl <= 0;
 
          if(spc2wbm_addr[3]==0) wbm2spc_data <= { wbm_data_i, 64'b0 };
 
          else wbm2spc_data <= { 64'b0, wbm_data_i };
 
 
 
          // See if other 64-bit Wishbone accesses are required
          // See if other 64-bit Wishbone accesses are required
          if(
            if ( (pcx_packet.request_type == `IMISS_RQ) ||
              // Instruction miss directed to RAM expects 256 bits
              // Instruction miss directed to RAM expects 256 bits
              ( (spc2wbm_type==`IMISS_RQ)&&(spc2wbm_region!=5'b10000) ) ||
               ( (pcx_packet.request_type == `LOAD_RQ) && (pcx_packet.access_size == `PCX_SZ_16B) )
              // Data access of 128 bits
              // Data access of 128 bits
              ( (spc2wbm_type==`LOAD_RQ)&&(spc2wbm_size==`PCX_SZ_16B) )
               ) begin
            )
              fsm_state <= FSM_WBM_BEGIN2;
            state <= `STATE_ACCESS2_BEGIN;
            end else begin
          else
              fsm_state <= FSM_CPX_FIFO_WRITE;
            state <= `STATE_PACKET_READY;
            end
 
 
        end else state <= `STATE_REQUEST_GRANTED;
 
 
 
      // FSM State 5: STATE_ACCESS2_BEGIN
          end
 
        end // case: FSM_WBM_END1
      // If needed start a second read access to the Wishbone bus
      // If needed start a second read access to the Wishbone bus
      end else if(state==`STATE_ACCESS2_BEGIN) begin
        FSM_WBM_BEGIN2: begin
 
 
        // Issue a second request on the Wishbone bus
        // Issue a second request on the Wishbone bus
        wbm_cycle_o <= 1;
        wbm_cycle_o <= 1;
        wbm_strobe_o <= 1;
        wbm_strobe_o <= 1;
        wbm_we_o <= 0;
        wbm_we_o <= 0;
        wbm_addr_o <= { spc2wbm_region, 19'b0, spc2wbm_addr[`PCX_AD_HI-`PCX_AD_LO:4], 4'b1000 };  // 2nd doubleword inside the same quadword
          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
        wbm_data_o <= 64'b0;
        wbm_data_o <= 64'b0;
        wbm_sel_o <= 8'b11111111;
        wbm_sel_o <= 8'b11111111;
 
 
        // Unconditional state change
        // Unconditional state change
        state <= `STATE_ACCESS2_END;
          fsm_state <= FSM_WBM_END2;
 
 
 
        end // case: FSM_WBM_BEGIN2
 
 
      // FSM State 6: STATE_ACCESS2_END
 
      // Latch the second data returning from Wishbone when ready
      // Latch the second data returning from Wishbone when ready
      end else if(state==`STATE_ACCESS2_END) begin
        FSM_WBM_END2: begin
 
 
        // Wait until Wishbone access completes
        // Wait until Wishbone access completes
        if(wbm_ack_i==1) begin
        if(wbm_ack_i==1) begin
 
 
          // Clear previously modified outputs
          // Clear previously modified outputs
          if(spc2wbm_atomic==0) wbm_cycle_o <= 0;
            if (pcx_info.atomic == 0) wbm_cycle_o <= 0;
          wbm_strobe_o <= 0;
          wbm_strobe_o <= 0;
          wbm_we_o <= 0;
          wbm_we_o <= 0;
          wbm_addr_o <= 64'b0;
          wbm_addr_o <= 64'b0;
          wbm_data_o <= 64'b0;
          wbm_data_o <= 64'b0;
          wbm_sel_o <= 8'b0;
          wbm_sel_o <= 8'b0;
 
 
          // Latch the data and set up the return packet for the SPARC Core
            // Latch the data and set up the return packet for the SPARC Core (this is the second half)
          wbm2spc_data[63:0] <= wbm_data_i;
            if (pcx_packet.address[3] == 1)
 
              cpx_packet.load_data = { wbm_data_i, cpx_packet.load_data[63:0] };
          // See if two return packets are required or just one
 
          if(spc2wbm_type==`IMISS_RQ && spc2wbm_region==5'b10000)
 
            state <= `STATE_PACKET_READY;
 
          else
          else
            state <= `STATE_ACCESS3_BEGIN;
              cpx_packet.load_data = { cpx_packet.load_data[127:64], wbm_data_i };
 
 
 
// synopsys translate_off
 
`ifdef SIMPLY_RISC_DEBUG
 
            // Print details of return packet
 
            print_cpx_packet(cpx_packet);
 
`endif
 
// synopsys translate_on
 
 
 
            // See if two return packets are required or just one - TODO checkme
 
//            if (pcx_packet.request_type == `IMISS_RQ && pcx_info.region == 5'b10000)
 
              fsm_state <= FSM_CPX_FIFO_WRITE;
 
//            else
 
//              fsm_state <= FSM_WBM_BEGIN3;
 
 
        end else state <= `STATE_ACCESS2_END;
          end // else fsm_state <= FSM_WBM_END2;
 
        end // case: FSM_WBM_END2
 
 
      // FSM State 7: STATE_ACCESS3_BEGIN
 
      // If needed start a third read access to the Wishbone bus
      // If needed start a third read access to the Wishbone bus
      // In the meanwhile we can return the first 128-bit packet
      // In the meanwhile we can return the first 128-bit packet
      end else if(state==`STATE_ACCESS3_BEGIN) begin
        FSM_WBM_BEGIN3: begin
 
 
        // Return the packet to the SPARC Core
 
        spc_ready_o <= 1;
 
        spc_packetin_o <= wbm2spc_packet;
 
 
 
        // Issue a third request on the Wishbone bus
        // Issue a third request on the Wishbone bus
        wbm_cycle_o <= 1;
        wbm_cycle_o <= 1;
        wbm_strobe_o <= 1;
        wbm_strobe_o <= 1;
        wbm_we_o <= 0;
        wbm_we_o <= 0;
        wbm_addr_o <= { spc2wbm_region, 19'b0, spc2wbm_addr[`PCX_AD_HI-`PCX_AD_LO:5], 5'b10000 };  // 3nd doubleword inside the same 256-bit data
          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
        wbm_data_o <= 64'b0;
        wbm_data_o <= 64'b0;
        wbm_sel_o <= 8'b11111111;
        wbm_sel_o <= 8'b11111111;
 
 
// synopsys translate_off
 
        // Print details of return packet
 
`ifdef DEBUG
 
        $display("INFO: WBM2SPC: *** RETURN PACKET TO SPARC CORE ***");
 
        $display("INFO: WBM2SPC: Valid bit is %X", wbm2spc_valid);
 
        case(wbm2spc_type)
 
          `IFILL_RET: $display("INFO: WBM2SPC: Return Packet of Type IFILL_RET");
 
          `LOAD_RET: $display("INFO: WBM2SPC: Return Packet of Type LOAD_RET");
 
          `ST_ACK: $display("INFO: WBM2SPC: Return Packet of Type ST_ACK");
 
          default: $display("INFO: WBM2SPC: Return Packet of Type Unknown");
 
        endcase
 
        $display("INFO: WBM2SPC: L2 Miss is %X", wbm2spc_miss);
 
        $display("INFO: WBM2SPC: Error is %X", wbm2spc_error);
 
        $display("INFO: WBM2SPC: Non-Cacheable bit is %X", wbm2spc_nc);
 
        $display("INFO: WBM2SPC: Thread is %X", wbm2spc_thread);
 
        $display("INFO: WBM2SPC: Way Valid is %X", wbm2spc_way_valid);
 
        $display("INFO: WBM2SPC: Replaced L2 Way is %X", wbm2spc_way);
 
        $display("INFO: WBM2SPC: Fetch for Boot is %X", wbm2spc_boot_fetch);
 
        $display("INFO: WBM2SPC: Atomic LD/ST or 2nd IFill Packet is %X", wbm2spc_atomic);
 
        $display("INFO: WBM2SPC: PFL is %X", wbm2spc_pfl);
 
        $display("INFO: WBM2SPC: Data is %X", wbm2spc_data);
 
`endif
 
// synopsys translate_on
 
 
 
        // Unconditional state change
        // Unconditional state change
        state <= `STATE_ACCESS3_END;
          fsm_state <= FSM_WBM_END3;
 
 
      // FSM State 8: STATE_ACCESS3_END
        end // case: FSM_WBM_BEGIN3
      // Latch the second data returning from Wishbone when ready
 
      end else if(state==`STATE_ACCESS3_END) begin
 
 
 
        // Clear previously modified outputs
        // Latch the second data returning from Wishbone when ready
        spc_ready_o <= 0;
        FSM_WBM_END3: begin
 
 
        // Wait until Wishbone access completes
        // Wait until Wishbone access completes
        if(wbm_ack_i==1) begin
        if(wbm_ack_i==1) begin
 
 
          // Clear previously modified outputs
          // Clear previously modified outputs
          if(spc2wbm_atomic==0) wbm_cycle_o <= 0;
            if (pcx_info.atomic == 0) wbm_cycle_o <= 0;
          wbm_strobe_o <= 0;
          wbm_strobe_o <= 0;
          wbm_we_o <= 0;
          wbm_we_o <= 0;
          wbm_addr_o <= 64'b0;
          wbm_addr_o <= 64'b0;
          wbm_data_o <= 64'b0;
          wbm_data_o <= 64'b0;
          wbm_sel_o <= 8'b0;
          wbm_sel_o <= 8'b0;
 
 
          // Latch the data and set up the return packet for the SPARC Core
            // Latch the data and set up the return packet for the SPARC Core - TODO CHECKME
          wbm2spc_data <= { wbm_data_i, 64'b0 };
//            cpx_packet.load_data = { wbm_data_i, 64'b0 };
 
 
          // Jump to next state
          // Jump to next state
          state <= `STATE_ACCESS4_BEGIN;
            fsm_state <= FSM_WBM_BEGIN4;
 
 
        end else state <= `STATE_ACCESS3_END;
          end // else fsm_state <= FSM_WBM_END3; // if (wbm_ack_i == 1)
 
        end // case: FSM_WBM_END3
 
 
      // FSM State 9: STATE_ACCESS4_BEGIN
 
      // If needed start a second read access to the Wishbone bus
      // If needed start a second read access to the Wishbone bus
      end else if(state==`STATE_ACCESS4_BEGIN) begin
        FSM_WBM_BEGIN4: begin
 
 
        // Issue a fourth request on the Wishbone bus
        // Issue a fourth request on the Wishbone bus
        wbm_cycle_o <= 1;
        wbm_cycle_o <= 1;
        wbm_strobe_o <= 1;
        wbm_strobe_o <= 1;
        wbm_we_o <= 0;
        wbm_we_o <= 0;
        wbm_addr_o <= { spc2wbm_region, 19'b0, spc2wbm_addr[`PCX_AD_HI-`PCX_AD_LO:5], 5'b11000 };  // 4th doubleword inside the same 256-bit data
          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
        wbm_data_o <= 64'b0;
        wbm_data_o <= 64'b0;
        wbm_sel_o <= 8'b11111111;
        wbm_sel_o <= 8'b11111111;
 
 
        // Unconditional state change
        // Unconditional state change
        state <= `STATE_ACCESS4_END;
          fsm_state <= FSM_WBM_END4;
 
        end // case: FSM_WBM_BEGIN4
 
 
      // FSM State 10: STATE_ACCESS4_END
 
      // Latch the second data returning from Wishbone when ready
      // Latch the second data returning from Wishbone when ready
      end else if(state==`STATE_ACCESS4_END) begin
        FSM_WBM_END4: begin
 
 
        // Wait until Wishbone access completes
        // Wait until Wishbone access completes
        if(wbm_ack_i==1) begin
        if(wbm_ack_i==1) begin
 
 
          // Clear previously modified outputs
          // Clear previously modified outputs
          if(spc2wbm_atomic==0) wbm_cycle_o <= 0;
            if (pcx_info.atomic == 0) wbm_cycle_o <= 0;
          wbm_strobe_o <= 0;
          wbm_strobe_o <= 0;
          wbm_we_o <= 0;
          wbm_we_o <= 0;
          wbm_addr_o <= 64'b0;
          wbm_addr_o <= 64'b0;
          wbm_data_o <= 64'b0;
          wbm_data_o <= 64'b0;
          wbm_sel_o <= 8'b0;
          wbm_sel_o <= 8'b0;
 
 
          // Latch the data and set up the return packet for the SPARC Core
          // Latch the data and set up the return packet for the SPARC Core
          wbm2spc_atomic <= 1;
//            cpx_packet.load_data = { 64'h0, wbm_data_i};
          wbm2spc_data[63:0] <= wbm_data_i;
 
 
 
          // Jump to next state
          // Jump to next state
          state <= `STATE_PACKET_READY;
            fsm_state <= FSM_CPX_FIFO_WRITE;
 
 
        end else state <= `STATE_ACCESS4_END;
          end // else fsm_state <= FSM_WBM_END4; // if (wbm_ack_i == 1)
 
        end // case: FSM_WBM_END4
 
 
      // FSM State 11: STATE_PACKET_READY
 
      // We can start returning the packet to the SPARC Core
      // We can start returning the packet to the SPARC Core
      end else if(state==`STATE_PACKET_READY) begin
        FSM_CPX_FIFO_WRITE: begin
 
 
        // Return the packet to the SPARC Core
 
        spc_ready_o <= 1;
 
        spc_packetin_o <= wbm2spc_packet;
 
 
 
        // Resume requests
          // Write the packet to the CPX FIFO
        spc_resume_o <= 1;
          cpx_fifo_write <= 1'b1;
 
          cpx_fifo_data_in <= cpx_packet;
 
 
        // Unconditional state change
        // Unconditional state change
        state <= `STATE_IDLE;
          fsm_state <= FSM_IDLE;
 
 
// synopsys translate_off
// synopsys translate_off
 
`ifdef SIMPLY_RISC_DEBUG
        // Print details of return packet
        // Print details of return packet
`ifdef DEBUG
          print_cpx_packet(cpx_packet);
        $display("INFO: WBM2SPC: *** RETURN PACKET TO SPARC CORE ***");
 
        $display("INFO: WBM2SPC: Valid bit is %X", wbm2spc_valid);
 
        case(wbm2spc_type)
 
          `IFILL_RET: $display("INFO: WBM2SPC: Return Packet of Type IFILL_RET");
 
          `LOAD_RET: $display("INFO: WBM2SPC: Return Packet of Type LOAD_RET");
 
          `ST_ACK: $display("INFO: WBM2SPC: Return Packet of Type ST_ACK");
 
          default: $display("INFO: WBM2SPC: Return Packet of Type Unknown");
 
        endcase
 
        $display("INFO: WBM2SPC: L2 Miss is %X", wbm2spc_miss);
 
        $display("INFO: WBM2SPC: Error is %X", wbm2spc_error);
 
        $display("INFO: WBM2SPC: Non-Cacheable bit is %X", wbm2spc_nc);
 
        $display("INFO: WBM2SPC: Thread is %X", wbm2spc_thread);
 
        $display("INFO: WBM2SPC: Way Valid is %X", wbm2spc_way_valid);
 
        $display("INFO: WBM2SPC: Replaced L2 Way is %X", wbm2spc_way);
 
        $display("INFO: WBM2SPC: Fetch for Boot is %X", wbm2spc_boot_fetch);
 
        $display("INFO: WBM2SPC: Atomic LD/ST or 2nd IFill Packet is %X", wbm2spc_atomic);
 
        $display("INFO: WBM2SPC: PFL is %X", wbm2spc_pfl);
 
        $display("INFO: WBM2SPC: Data is %X", wbm2spc_data);
 
`endif
`endif
// synopsys translate_on
// synopsys translate_on
 
        end // case: FSM_CPX_FIFO_WRITE
 
 
 
       endcase // case (fsm_state)
      end
      end
    end
    end
 
 
 
   /*
 
    * CPX FIFO handler
 
    * - SPARC Core Logic: Drives SPARC Core signals related with the CPX interface
 
    * - CPX FIFO Read Logic: Drives cpx_fifo_read and reads cpx_data_out
 
    */
 
 
 
   typedef enum logic[2:0] {CPX_IDLE, CPX_DRIVE_CORE} cpx_state_t;
 
   cpx_state_t cpx_state;
 
   cpx_packet_t cpx_packet_2;
 
 
 
   always @(posedge sys_clock_i) begin
 
     if (sys_reset_i == 1) begin
 
       spc_ready_o    <= 0;
 
       spc_packetin_o <= 0;
 
       cpx_fifo_read  <= 1'b0;
 
       cpx_state      <= CPX_IDLE;
 
     end else begin
 
       case (cpx_state)
 
         CPX_IDLE: begin
 
           spc_ready_o <= 0;
 
           spc_packetin_o <= 'h0;
 
           if (cpx_fifo_empty) begin
 
             cpx_fifo_read <= 1'b0;
 
           end else begin
 
             cpx_fifo_read <= 1'b1;
 
             cpx_packet_2 <= cpx_fifo_data_out;
 
             cpx_state <= CPX_DRIVE_CORE;
 
           end
 
         end
 
         CPX_DRIVE_CORE: begin
 
           cpx_fifo_read <= 1'b0;
 
           spc_ready_o <= 1;
 
           spc_packetin_o <= cpx_packet_2;
 
           cpx_state <= CPX_IDLE;
  end
  end
 
       endcase // case (cpx_state)
 
     end // else: !if (sys_reset_i == 1)
 
   end // always @ (posedge sys_clock_i)
 
 
endmodule
endmodule
 
 
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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