Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / dmu / rtl / dmu_mmu_tcb_tdc.v
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: dmu_mmu_tcb_tdc.v
// Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved
// 4150 Network Circle, Santa Clara, California 95054, U.S.A.
//
// * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
//
// This 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 program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// For the avoidance of doubt, and except that if any non-GPL license
// choice is available it will apply instead, Sun elects to use only
// the General Public License version 2 (GPLv2) at this time for any
// software where a choice of GPL license versions is made
// available with the language indicating that GPLv2 or any later version
// may be used, or where a choice of which version of the GPL is applied is
// otherwise unspecified.
//
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
// CA 95054 USA or visit www.sun.com if you need additional information or
// have any questions.
//
// ========== Copyright Header End ============================================
module dmu_mmu_tcb_tdc
(
clk, // clock
rst_l, // reset
rcb2tcb_err, // rcb error
rcb2tcb_tag, // rcb tag
rcb2tcb_vld, // rcb valid
tcc2tdc_cld, // tdc cache load
tcc2tdc_req, // tdc request
tcc2tdc_tag, // tdc replacement tag
tcb2tdb_wa, // tdb write address
tcb2tdb_we, // tdb write enable
tcb2tlb_dld, // tlb data load
tcb2tlb_ra, // tlb read address
tcb2tlb_ras, // tlb read address select
tdc2tcc_ack, // tcc acknowledge
tdc2tcc_err, // tcc error
tdc2tmc_dbg, // tmc debug
tdc2tmc_err // tmc errors
);
// ----------------------------------------------------------------------------
// Parameters
// ----------------------------------------------------------------------------
parameter CNT_TST0 = 3'b011,
CNT_TST1 = 3'b110;
parameter IDLE = 2'b00, // state machine states
WAIT = 2'b01,
DATA = 2'b10,
DONE = 2'b11;
// ----------------------------------------------------------------------------
// Ports
// ----------------------------------------------------------------------------
input clk;
input rst_l;
input [`FIRE_DLC_MMU_RCB_ERR_BITS] rcb2tcb_err;
input [`FIRE_DLC_MMU_TAG_PTR_BITS] rcb2tcb_tag;
input rcb2tcb_vld;
input tcc2tdc_cld;
input tcc2tdc_req;
input [`FIRE_DLC_MMU_TAG_PTR_BITS] tcc2tdc_tag;
output [`FIRE_DLC_MMU_TDB_PTR_BITS] tcb2tdb_wa;
output tcb2tdb_we;
output tcb2tlb_dld;
output [`FILE_DLC_MMU_TTE_CNT_BITS] tcb2tlb_ra;
output tcb2tlb_ras;
output tdc2tcc_ack;
output tdc2tcc_err;
output [`FIRE_DBG_DATA_BITS] tdc2tmc_dbg;
output [`FIRE_DLC_MMU_TDC_ERR_BITS] tdc2tmc_err;
// ----------------------------------------------------------------------------
// Variables
// ----------------------------------------------------------------------------
wire [`FIRE_DLC_MMU_TDB_PTR_BITS] tcb2tdb_wa;
wire [`FIRE_DBG_DATA_BITS] tdc2tmc_dbg;
wire [`FIRE_DLC_MMU_RCB_ERR_BITS] tdr_err;
reg tcb2tdb_we;
reg [`FILE_DLC_MMU_TTE_CNT_BITS] tcb2tlb_ra;
reg tcb2tlb_ras;
reg tdc2tcc_ack;
reg [`FIRE_DLC_MMU_TDC_ERR_BITS] tdc2tmc_err;
reg [1:0] state, nxt_state;
reg [`FILE_DLC_MMU_TTE_CNT_BITS] cnt, nxt_cnt;
reg [`FIRE_DLC_MMU_TDC_ERR_BITS] err, nxt_err;
// ----------------------------------------------------------------------------
// Zero In Checkers
// ----------------------------------------------------------------------------
// 0in state_transition -var state -val IDLE -next WAIT
// 0in state_transition -var state -val WAIT -next DATA DONE
// 0in state_transition -var state -val DATA -next DONE IDLE
// 0in state_transition -var state -val DONE -next IDLE
// ----------------------------------------------------------------------------
// Combinational
// ----------------------------------------------------------------------------
// tlb data load
wire tcb2tlb_dld = rcb2tcb_vld;
// tdb write address
assign tcb2tdb_wa = { tcc2tdc_tag, cnt };
// tcc error
wire tdc2tcc_err = |(err | tdr_err) & tdc2tcc_ack;
// tag and tdr errors
wire tag_err = rcb2tcb_vld & (tcc2tdc_tag != rcb2tcb_tag);
assign tdr_err = rcb2tcb_vld ? rcb2tcb_err : 0;
// next state
always @ (state or rcb2tcb_vld or tdr_err or tcc2tdc_cld or tcc2tdc_req or
cnt) begin
case (state) // synopsys parallel_case
IDLE : begin
case (tcc2tdc_req) // synopsys parallel_case
1'b0 : nxt_state = IDLE; // idle
1'b1 : nxt_state = WAIT; // request
endcase
end
WAIT : begin
case ({rcb2tcb_vld, tdr_err[0]}) // synopsys parallel_case
2'b00 : nxt_state = WAIT; // wait for rcb vld
2'b01 : nxt_state = IDLE; // cannot happen
2'b10 : nxt_state = DATA; // rcb vld
2'b11 : nxt_state = DONE; // error
endcase
end
DATA : begin
case (cnt) // synopsys parallel_case
3'b000 : nxt_state = rcb2tcb_vld ? DATA : DONE;
3'b001 : nxt_state = rcb2tcb_vld ? DATA : DONE;
3'b010 : nxt_state = rcb2tcb_vld ? DATA : DONE;
3'b011 : nxt_state = tcc2tdc_cld ? DATA : DONE;
3'b100 : nxt_state = DATA;
3'b101 : nxt_state = DATA;
3'b110 : nxt_state = DATA;
3'b111 : nxt_state = IDLE;
endcase
end
DONE : begin
nxt_state = IDLE;
end
endcase
end
// state machine outputs
always @ (state or tdr_err or tcc2tdc_cld or cnt or err or tag_err) begin
case (state) // synopsys parallel_case
IDLE : begin
tcb2tlb_ras = 0;
tcb2tdb_we = 0;
tdc2tcc_ack = 0;
tdc2tmc_err = err;
nxt_cnt = 0;
nxt_err = 0;
end
WAIT : begin
tcb2tlb_ras = 0;
tcb2tdb_we = 0;
tdc2tcc_ack = tdr_err[0];
tdc2tmc_err = 0;
nxt_cnt = 0;
nxt_err[0] = err[0] | tag_err;
nxt_err[1] = err[1] | (|tdr_err[1:0]);
nxt_err[2] = err[2] | tdr_err[2];
end
DATA : begin
tcb2tlb_ras = tcc2tdc_cld;
tcb2tdb_we = tcc2tdc_cld;
tdc2tcc_ack = tcc2tdc_cld ? (cnt == CNT_TST1) : (cnt == CNT_TST0);
tdc2tmc_err = 0;
nxt_cnt = cnt + 1;
nxt_err = err | tdr_err;
end
DONE : begin
tcb2tlb_ras = 0;
tcb2tdb_we = 0;
tdc2tcc_ack = 0;
tdc2tmc_err = 0;
nxt_cnt = 0;
nxt_err = err;
end
endcase
end
// tlb read address
always @ (cnt) begin
case (cnt) // synopsys parallel_case
3'b000 : tcb2tlb_ra = 3'b110;
3'b001 : tcb2tlb_ra = 3'b101;
3'b010 : tcb2tlb_ra = 3'b100;
3'b011 : tcb2tlb_ra = 3'b011;
3'b100 : tcb2tlb_ra = 3'b100;
3'b101 : tcb2tlb_ra = 3'b101;
3'b110 : tcb2tlb_ra = 3'b110;
3'b111 : tcb2tlb_ra = 3'b111;
endcase
end
// ----------------------------------------------------------------------------
// Debug
// ----------------------------------------------------------------------------
assign tdc2tmc_dbg = {state, cnt, err};
// ----------------------------------------------------------------------------
// Sequential
// ----------------------------------------------------------------------------
always @ (posedge clk) begin
if (!rst_l) begin
cnt <= 0;
err <= 0;
state <= IDLE;
end
else begin
cnt <= nxt_cnt;
err <= nxt_err;
state <= nxt_state;
end
end
endmodule // dmu_mmu_tcb_tdc