Line 16... |
Line 16... |
// You should have received a copy of the GNU General Public
|
// You should have received a copy of the GNU General Public
|
// License along with this work; if not, write to the Free Software
|
// License along with this work; if not, write to the Free Software
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
//
|
//
|
// ========== Copyright Header End ============================================
|
// ========== Copyright Header End ============================================
|
|
`ifdef SIMPLY_RISC_TWEAKS
|
|
`define SIMPLY_RISC_SCANIN .si(0)
|
|
`else
|
|
`define SIMPLY_RISC_SCANIN .si()
|
|
`endif
|
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
/*
|
/*
|
// Module Name: sparc_ifu_ifqdp
|
// Module Name: sparc_ifu_ifqdp
|
// Description:
|
// Description:
|
// The IFQ is the icache fill queue. This communicates between the
|
// The IFQ is the icache fill queue. This communicates between the
|
Line 28... |
Line 33... |
*/
|
*/
|
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
// Global header file includes
|
// Global header file includes
|
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
|
|
/*
|
`include "ifu.h"
|
/* ========== Copyright Header Begin ==========================================
|
|
*
|
|
* OpenSPARC T1 Processor File: ifu.h
|
|
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
|
|
*
|
|
* The above named program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public
|
|
* License version 2 as published by the Free Software Foundation.
|
|
*
|
|
* The above named program is distributed in the hope that it will be
|
|
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public
|
|
* License along with this work; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* ========== Copyright Header End ============================================
|
|
*/
|
|
////////////////////////////////////////////////////////////////////////
|
|
/*
|
|
//
|
|
// Module Name: ifu.h
|
|
// Description:
|
|
// All ifu defines
|
|
*/
|
|
|
|
//--------------------------------------------
|
|
// Icache Values in IFU::ICD/ICV/ICT/FDP/IFQDP
|
|
//--------------------------------------------
|
|
// Set Values
|
|
|
|
// IC_IDX_HI = log(icache_size/4ways) - 1
|
|
|
|
|
|
// !!IMPORTANT!! a change to IC_LINE_SZ will mean a change to the code as
|
|
// well. Unfortunately this has not been properly parametrized.
|
|
// Changing the IC_LINE_SZ param alone is *not* enough.
|
|
|
|
|
|
// !!IMPORTANT!! a change to IC_TAG_HI will mean a change to the code as
|
|
// well. Changing the IC_TAG_HI param alone is *not* enough to
|
|
// change the PA range.
|
|
// highest bit of PA
|
|
|
|
|
|
|
|
// Derived Values
|
|
// 4095
|
|
|
|
|
|
// number of entries - 1 = 511
|
|
|
|
|
|
// 12
|
|
|
|
|
|
// 28
|
|
|
|
|
|
// 7
|
|
|
|
|
|
// tags for all 4 ways + parity
|
|
// 116
|
|
|
|
|
|
// 115
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// For thread scheduler in IFU::DTU::SWL
|
|
//----------------------------------------------------------------------
|
|
// thread states: (thr_state[4:0])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// thread configuration register bit fields
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------
|
|
// For MIL fsm in IFU::IFQ
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------
|
|
// Interrupt Block
|
|
//---------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-------------------------------------
|
|
// IFQ
|
|
//-------------------------------------
|
|
// valid bit plus ifill
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//`ifdef SPARC_L2_64B
|
|
|
|
|
|
//`else
|
|
//`define BANK_ID_HI 8
|
|
//`define BANK_ID_LO 7
|
|
//`endif
|
|
|
|
//`define CPX_INV_PA_HI 116
|
|
//`define CPX_INV_PA_LO 112
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------
|
|
// IFU Traps
|
|
//----------------------------------------
|
|
// precise
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// disrupting
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//`define MILFSM_NULL 4'b0000
|
//`define MILFSM_NULL 4'b0000
|
//`define MILFSM_WAIT 4'b1000
|
//`define MILFSM_WAIT 4'b1000
|
//`define MILFSM_REQ 4'b1100
|
//`define MILFSM_REQ 4'b1100
|
//`define MILFSM_FILL0 4'b1001
|
//`define MILFSM_FILL0 4'b1001
|
Line 329... |
Line 155... |
//ic_wrreq_i2 = 1'b0;
|
//ic_wrreq_i2 = 1'b0;
|
// orphan_chld = 1'b0;
|
// orphan_chld = 1'b0;
|
next_state[1:0] = 2'b0;
|
next_state[1:0] = 2'b0;
|
if (ifc_fsm_err_thisthr | ifc_fsm_imiss_thisthr_s)
|
if (ifc_fsm_err_thisthr | ifc_fsm_imiss_thisthr_s)
|
begin
|
begin
|
next_state[3] = 1'b1;
|
next_state[`MIL_V] = 1'b1;
|
if (ifc_fsm_milhit_s & ~ifc_fsm_err_thisthr)
|
if (ifc_fsm_milhit_s & ~ifc_fsm_err_thisthr)
|
next_state[2] = 1'b0; // MILFSM_WAIT
|
next_state[`MIL_R] = 1'b0; // MILFSM_WAIT
|
else
|
else
|
next_state[2] = 1'b1; // MILFSM_REQ;
|
next_state[`MIL_R] = 1'b1; // MILFSM_REQ;
|
end
|
end
|
else
|
else
|
next_state = milstate;
|
next_state = milstate;
|
end // case: begin...
|
end // case: begin...
|
|
|
Line 354... |
Line 180... |
begin
|
begin
|
// we invalidate the icache on detecting an error
|
// we invalidate the icache on detecting an error
|
// only if this wasn't an MIL hit as well. If it
|
// only if this wasn't an MIL hit as well. If it
|
// was an MIL we would have gone to the wait state
|
// was an MIL we would have gone to the wait state
|
// already and it is too late to invalidate the cache
|
// already and it is too late to invalidate the cache
|
next_state = 4'b1000;
|
next_state = `MILFSM_WAIT;
|
// orphan_chld = 1'b0;
|
// orphan_chld = 1'b0;
|
end
|
end
|
// else if ((cancel_mil | ifc_fsm_can_thisthr) &
|
// else if ((cancel_mil | ifc_fsm_can_thisthr) &
|
// ~milchld_valid & ~ifc_fsm_hiton_thismil_s)
|
// ~milchld_valid & ~ifc_fsm_hiton_thismil_s)
|
// begin
|
// begin
|
Line 377... |
Line 203... |
if (ifc_fsm_fill_thisthr_i2)
|
if (ifc_fsm_fill_thisthr_i2)
|
begin
|
begin
|
// ic_wrreq_i2 = 1'b1;
|
// ic_wrreq_i2 = 1'b1;
|
if (ifd_ifc_4bpkt_i2 & ifqadv_i2) // 4B ifill from IOB
|
if (ifd_ifc_4bpkt_i2 & ifqadv_i2) // 4B ifill from IOB
|
// don't want to advance too quickly and get fasle compl
|
// don't want to advance too quickly and get fasle compl
|
next_state = 4'b0000;
|
next_state = `MILFSM_NULL;
|
else if (~ifd_ifc_4bpkt_i2)
|
else if (~ifd_ifc_4bpkt_i2)
|
next_state = 4'b1001;
|
next_state = `MILFSM_FILL0;
|
else
|
else
|
next_state = milstate;
|
next_state = milstate;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
Line 395... |
Line 221... |
4'b1001: // fill0
|
4'b1001: // fill0
|
begin
|
begin
|
// orphan_chld = 1'b0;
|
// orphan_chld = 1'b0;
|
if (ifc_fsm_wr_complete_f)
|
if (ifc_fsm_wr_complete_f)
|
begin
|
begin
|
next_state = 4'b1011;
|
next_state = `MILFSM_FILL1;
|
//ic_wrreq_i2 = 1'b1;
|
//ic_wrreq_i2 = 1'b1;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
next_state = milstate;
|
next_state = milstate;
|
Line 415... |
Line 241... |
begin
|
begin
|
//ic_wrreq_i2 = 1'b0;
|
//ic_wrreq_i2 = 1'b0;
|
// if (delay_mil | ifc_fsm_imiss_thisthr_s)
|
// if (delay_mil | ifc_fsm_imiss_thisthr_s)
|
// next_state = `MILFSM_REQ;
|
// next_state = `MILFSM_REQ;
|
// else
|
// else
|
next_state = 4'b0000;
|
next_state = `MILFSM_NULL;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
//ic_wrreq_i2 = 1'b1;
|
//ic_wrreq_i2 = 1'b1;
|
next_state = milstate;
|
next_state = milstate;
|
Line 428... |
Line 254... |
|
|
default:
|
default:
|
begin
|
begin
|
// synopsys translate_off
|
// synopsys translate_off
|
// 0in <fire -message "MILSTATE, Error: SPARC/IFU/MILFSM: unknown state!"
|
// 0in <fire -message "MILSTATE, Error: SPARC/IFU/MILFSM: unknown state!"
|
|
`ifdef DEFINE_0IN
|
|
`else
|
if ($time > (4* 1))
|
if ($time > (4* `CMP_CLK_PERIOD))
|
begin
|
begin
|
|
`ifdef MODELSIM
|
|
|
|
|
|
|
$display ("MILSTATE",
|
$display ("MILSTATE",
|
"Error: SPARC/IFU/MILFSM: unknown state! %b\n",milstate);
|
"Error: SPARC/IFU/MILFSM: unknown state! %b\n",milstate);
|
|
`else
|
|
$error ("MILSTATE",
|
|
"Error: SPARC/IFU/MILFSM: unknown state! %b\n",milstate);
|
|
`endif
|
end
|
end
|
|
`endif
|
// synopsys translate_on
|
// synopsys translate_on
|
next_state = milstate;
|
next_state = milstate;
|
//ic_wrreq_i2 = 1'b0;
|
//ic_wrreq_i2 = 1'b0;
|
// orphan_chld = 1'b0;
|
// orphan_chld = 1'b0;
|
end // case: default
|
end // case: default
|
endcase // casex(milstate)
|
endcase // casex(milstate)
|
end // always @ (...
|
end // always @ (...
|
|
|
|
|
// MIL state reg
|
// MIL state reg
|
dffr #(4) milst_reg(.din (next_state[3:0]),
|
dffr_s #(4) milst_reg(.din (next_state[3:0]),
|
.q (milstate[3:0]),
|
.q (milstate[3:0]),
|
.clk (clk),
|
.clk (clk),
|
.rst (reset),
|
.rst (reset),
|
.se (se), .si(), .so());
|
.se (se), `SIMPLY_RISC_SCANIN, .so());
|
|
|
// Cancel - Delay state machine
|
// Cancel - Delay state machine
|
// -- not used anymore
|
// -- not used anymore
|
// C D
|
// C D
|
// 0 0 - null
|
// 0 0 - null
|
Line 469... |
Line 295... |
|
|
// assign cancel_next = (ifc_fsm_can_thisthr |
|
// assign cancel_next = (ifc_fsm_can_thisthr |
|
// cancel_mil) & next_state[`MIL_V]; // reset wins
|
// cancel_mil) & next_state[`MIL_V]; // reset wins
|
|
|
assign cancel_next = (ifc_fsm_can_thisthr | cancel_mil) &
|
assign cancel_next = (ifc_fsm_can_thisthr | cancel_mil) &
|
(milstate[3] | ifc_fsm_imiss_thisthr_s |
|
(milstate[`MIL_V] | ifc_fsm_imiss_thisthr_s |
|
ifc_fsm_err_thisthr); // reset wins
|
ifc_fsm_err_thisthr); // reset wins
|
|
|
dffr #(1) can_ff(.din (cancel_next),
|
dffr_s #(1) can_ff(.din (cancel_next),
|
.q (cancel_mil),
|
.q (cancel_mil),
|
.clk (clk),
|
.clk (clk),
|
.rst (reset),
|
.rst (reset),
|
.se (se), .si(), .so());
|
.se (se), `SIMPLY_RISC_SCANIN, .so());
|
|
|
// track if we need to send out an error request
|
// track if we need to send out an error request
|
assign err_pending_next = (ifc_fsm_err_thisthr &
|
assign err_pending_next = (ifc_fsm_err_thisthr &
|
(milstate[2] | ~milstate[3]) |
|
(milstate[`MIL_R] | ~milstate[`MIL_V]) |
|
// err_pending & next_state[`MIL_V]) &
|
// err_pending & next_state[`MIL_V]) &
|
err_pending & milstate[3]) &
|
err_pending & milstate[`MIL_V]) &
|
~ifc_fsm_pcxaccept_thisthr;
|
~ifc_fsm_pcxaccept_thisthr;
|
// & ~ifc_fsm_can_thisthr;
|
// & ~ifc_fsm_can_thisthr;
|
|
|
dffr #(1) err_ff(.din (err_pending_next),
|
dffr_s #(1) err_ff(.din (err_pending_next),
|
.q (err_pending),
|
.q (err_pending),
|
.clk (clk),
|
.clk (clk),
|
.rst (reset), .se(se), .si(), .so());
|
.rst (reset), .se(se), `SIMPLY_RISC_SCANIN, .so());
|
assign fsm_ifc_errreq = err_pending;
|
assign fsm_ifc_errreq = err_pending;
|
|
|
// Track secondary hits
|
// Track secondary hits
|
assign next_milchld[2] = ifc_fsm_hiton_thismil_s | // hit on MIL by
|
assign next_milchld[2] = ifc_fsm_hiton_thismil_s | // hit on MIL by
|
// someone else
|
// someone else
|
fsm_ifc_milchld[2] & milstate[3]; // reset
|
fsm_ifc_milchld[2] & milstate[`MIL_V]; // reset
|
|
|
assign next_milchld[1:0] = ifc_fsm_hiton_thismil_s ? fcl_ifq_thr_s1 :
|
assign next_milchld[1:0] = ifc_fsm_hiton_thismil_s ? fcl_ifq_thr_s1 :
|
fsm_ifc_milchld[1:0];
|
fsm_ifc_milchld[1:0];
|
|
|
dffr #(3) milchld_reg(.din (next_milchld),
|
dffr_s #(3) milchld_reg(.din (next_milchld),
|
.clk (clk),
|
.clk (clk),
|
.rst (reset),
|
.rst (reset),
|
.q (local_milchld),
|
.q (local_milchld),
|
.se (se), .si(), .so());
|
.se (se), `SIMPLY_RISC_SCANIN, .so());
|
|
|
assign fsm_ifc_milchld[2] = local_milchld[2] & milstate[3];
|
assign fsm_ifc_milchld[2] = local_milchld[2] & milstate[`MIL_V];
|
assign fsm_ifc_milchld[1:0] = local_milchld[1:0];
|
assign fsm_ifc_milchld[1:0] = local_milchld[1:0];
|
|
|
assign milchld_valid = local_milchld[2] & milstate[3];
|
assign milchld_valid = local_milchld[2] & milstate[`MIL_V];
|
|
|
// assign fsm_ifc_addrbit4_i2 = milstate[`MIL_F];
|
// assign fsm_ifc_addrbit4_i2 = milstate[`MIL_F];
|
assign fsm_ifc_addrbit4_i2 = milstate[0] & milstate[3] &
|
assign fsm_ifc_addrbit4_i2 = milstate[`MIL_F] & milstate[`MIL_V] &
|
(milstate[1] | ifc_fsm_wr_complete_f);
|
(milstate[`MIL_A] | ifc_fsm_wr_complete_f);
|
|
|
// determine if we want to fill from the first pkt or second pkt
|
// determine if we want to fill from the first pkt or second pkt
|
assign fill_this16b = ~(milstate[0] ^ ifc_fsm_miladdr4) |
|
assign fill_this16b = ~(milstate[`MIL_F] ^ ifc_fsm_miladdr4) |
|
ifd_ifc_4bpkt_i2;
|
ifd_ifc_4bpkt_i2;
|
|
|
// write to thread inst reg (TIR)
|
// write to thread inst reg (TIR)
|
// assign fsm_ifc_wrt_tir = (next_state[`MIL_F]) & ~cancel_mil &
|
// assign fsm_ifc_wrt_tir = (next_state[`MIL_F]) & ~cancel_mil &
|
// ifc_fsm_fill_thisthr_i2;
|
// ifc_fsm_fill_thisthr_i2;
|
assign fsm_ifc_wrt_tir = (milstate[3] & ~milstate[2]) &
|
assign fsm_ifc_wrt_tir = (milstate[`MIL_V] & ~milstate[`MIL_R]) &
|
~(cancel_mil | ifc_fsm_can_thisthr) &
|
~(cancel_mil | ifc_fsm_can_thisthr) &
|
ifc_fsm_fill_thisthr_i2 &
|
ifc_fsm_fill_thisthr_i2 &
|
fill_this16b;
|
fill_this16b;
|
|
|
// write to Icache
|
// write to Icache
|
// assign fsm_ifc_wrreq_i2 = ic_wrreq_i2;
|
// assign fsm_ifc_wrreq_i2 = ic_wrreq_i2;
|
assign valid_i2 = milstate[3] & ~fsm_ifc_thr_ready;
|
assign valid_i2 = milstate[`MIL_V] & ~fsm_ifc_thr_ready;
|
|
|
dff vld_ff(.din (valid_i2),
|
dff_s vld_ff(.din (valid_i2),
|
.q (valid_d1),
|
.q (valid_d1),
|
.clk (clk),
|
.clk (clk),
|
.se (se), .si(), .so());
|
.se (se), `SIMPLY_RISC_SCANIN, .so());
|
|
|
// signal thread completion
|
// signal thread completion
|
assign fsm_ifc_thr_ready = milstate[3] & milstate[0] &
|
assign fsm_ifc_thr_ready = milstate[`MIL_V] & milstate[`MIL_F] &
|
milstate[1] & ifc_fsm_wr_complete_f |
|
milstate[`MIL_A] & ifc_fsm_wr_complete_f |
|
~milstate[3] & valid_d1;
|
~milstate[`MIL_V] & valid_d1;
|
|
|
// predict ready assuming 2nd ifill happens in the next cycle
|
// predict ready assuming 2nd ifill happens in the next cycle
|
assign fsm_ifc_pred_rdy = milstate[3] & milstate[0] &
|
assign fsm_ifc_pred_rdy = milstate[`MIL_V] & milstate[`MIL_F] &
|
(ifc_fsm_wr_complete_f |
|
(ifc_fsm_wr_complete_f |
|
milstate[1]); // & ifc_fsm_fill_thisthr_i2
|
milstate[`MIL_A]); // & ifc_fsm_fill_thisthr_i2
|
|
|
// set compare valid for mil hit signal
|
// set compare valid for mil hit signal
|
assign fsm_ifc_comp_valid = milstate[3] & // valid entry
|
assign fsm_ifc_comp_valid = milstate[`MIL_V] & // valid entry
|
~milstate[0] & // not f0 or f1
|
~milstate[`MIL_F] & // not f0 or f1
|
~milchld_valid; // no chld already
|
~milchld_valid; // no chld already
|
|
|
assign fsm_ifc_mil_valid = milstate[3];
|
assign fsm_ifc_mil_valid = milstate[`MIL_V];
|
assign fsm_ifc_mil_cancel = cancel_mil;
|
assign fsm_ifc_mil_cancel = cancel_mil;
|
|
|
// In the request state or if we need to send an error invalidate,
|
// In the request state or if we need to send an error invalidate,
|
// ask for bus from LSU.
|
// ask for bus from LSU.
|
// assign fsm_ifc_pcxreq = (milstate[`MIL_V] & milstate[`MIL_R] |
|
// assign fsm_ifc_pcxreq = (milstate[`MIL_V] & milstate[`MIL_R] |
|
Line 566... |
Line 392... |
// assign fsm_ifc_pcxreq = (milstate[`MIL_V] & milstate[`MIL_R] &
|
// assign fsm_ifc_pcxreq = (milstate[`MIL_V] & milstate[`MIL_R] &
|
// ~ifc_fsm_pcxaccept_thisthr &
|
// ~ifc_fsm_pcxaccept_thisthr &
|
// (milchld_valid | ~cancel_mil));
|
// (milchld_valid | ~cancel_mil));
|
|
|
// removed pcx_accept from critical path
|
// removed pcx_accept from critical path
|
assign fsm_ifc_pcxreq = milstate[3] & milstate[2];
|
assign fsm_ifc_pcxreq = milstate[`MIL_V] & milstate[`MIL_R];
|
|
|
assign fsm_ifc_milstate = milstate;
|
assign fsm_ifc_milstate = milstate;
|
|
|
|
|
endmodule
|
endmodule
|